Skip to content
This repository has been archived by the owner on Aug 5, 2024. It is now read-only.

Commit

Permalink
Implement buildTargetScalaMainClasses (#36)
Browse files Browse the repository at this point in the history
* Init

* Fix resolving target options

* Fix variable name

* Change access

* Fix formatting

* Fix formatting

* Read arguments

* Upgrade bsp-testkit

* Add empty test

* Fix formatting

* Move constants

* Fix

* Add more data to test

* Add package name

* Move targetRulesResolver to constructor

* return Completable Future instead of null

* Extract method

* Extract isAttributeSpecifiedAndHasGivenName

* Call buildServerImpl

* Pass compiler options and args to test

* Fix tests

* Fix tests

* Add more args to test

* Read also jvm flags

* Move to constants

* Read only jvm flags

* fix formatting

* unify naming

* use helper method

* remove duplicate methods

* Add more test cases

* revert

* Add test case

* target without args test case

* increase timeout

* add test case without jvm flags

* increase timeout

* increase timeout
  • Loading branch information
magda-aug authored Feb 4, 2021
1 parent 9be3db1 commit f591b4c
Show file tree
Hide file tree
Showing 14 changed files with 170 additions and 28 deletions.
5 changes: 5 additions & 0 deletions sample-repo/example/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,11 @@ filegroup(
scala_binary(
name = "example",
srcs = ["Example.scala"],
args = [
"arg1",
"arg2",
],
jvm_flags = ["-Xms2G -Xmx5G"],
main_class = "example.Example",
resources = [":resources"],
visibility = ["//visibility:public"],
Expand Down
8 changes: 8 additions & 0 deletions sample-repo/target_without_args/BUILD
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
load("@io_bazel_rules_scala//scala:scala.bzl", "scala_binary")

scala_binary(
name = "binary",
srcs = ["Example.scala"],
jvm_flags = ["-Xms2G -Xmx5G"],
main_class = "example.Example",
)
7 changes: 7 additions & 0 deletions sample-repo/target_without_args/Example.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package target_without_args

import java.util.ArrayList

object Example {
def main(args: Array[String]): Unit = {}
}
11 changes: 11 additions & 0 deletions sample-repo/target_without_jvm_flags/BUILD
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
load("@io_bazel_rules_scala//scala:scala.bzl", "scala_binary")

scala_binary(
name = "binary",
srcs = ["Example.scala"],
args = [
"arg1",
"arg2",
],
main_class = "example.Example",
)
7 changes: 7 additions & 0 deletions sample-repo/target_without_jvm_flags/Example.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package target_without_jvm_flags

import java.util.ArrayList

object Example {
def main(args: Array[String]): Unit = {}
}
6 changes: 6 additions & 0 deletions sample-repo/target_without_main_class/BUILD
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
load("@io_bazel_rules_scala//scala:scala.bzl", "scala_library")

scala_library(
name = "library",
srcs = ["Example.scala"],
)
3 changes: 3 additions & 0 deletions sample-repo/target_without_main_class/Example.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
package target_without_main_class

object Example {}
4 changes: 4 additions & 0 deletions src/main/java/org/jetbrains/bsp/bazel/commons/Constants.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@ public class Constants {
public static final String JAVA_EXTENSION = ".java";
public static final String KOTLIN_EXTENSION = ".kt";

public static final String MAIN_CLASS_ATTR_NAME = "main_class";
public static final String ARGS_ATTR_NAME = "args";
public static final String JVM_FLAGS_ATTR_NAME = "jvm_flags";

public static final List<String> FILE_EXTENSIONS =
ImmutableList.of(
SCALA_EXTENSION,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,11 @@ public CompletableFuture<WorkspaceBuildTargetsResult> workspaceBuildTargets() {
return buildServer.workspaceBuildTargets();
}

@Override
public CompletableFuture<Object> workspaceReload() {
return buildServer.workspaceReload();
}

@Override
public CompletableFuture<SourcesResult> buildTargetSources(SourcesParams params) {
return buildServer.buildTargetSources(params);
Expand Down Expand Up @@ -112,11 +117,6 @@ public CompletableFuture<CleanCacheResult> buildTargetCleanCache(CleanCacheParam
return buildServer.buildTargetCleanCache(params);
}

@Override
public CompletableFuture<Object> workspaceReload() {
return buildServer.workspaceReload();
}

@Override
public CompletableFuture<ScalacOptionsResult> buildTargetScalacOptions(
ScalacOptionsParams params) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,12 @@ public CompletableFuture<WorkspaceBuildTargetsResult> workspaceBuildTargets() {
return buildServerService.workspaceBuildTargets();
}

@Override
public CompletableFuture<Object> workspaceReload() {
// TODO
return CompletableFuture.completedFuture(null);
}

@Override
public CompletableFuture<SourcesResult> buildTargetSources(SourcesParams sourcesParams) {
return serverRequestHelpers.executeCommand(
Expand Down Expand Up @@ -110,9 +116,4 @@ public CompletableFuture<CleanCacheResult> buildTargetCleanCache(
return serverRequestHelpers.executeCommand(
() -> buildServerService.buildTargetCleanCache(cleanCacheParams));
}

@Override
public CompletableFuture<Object> workspaceReload() {
return CompletableFuture.completedFuture(null);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ public CompletableFuture<ScalaTestClassesResult> buildTargetScalaTestClasses(
@Override
public CompletableFuture<ScalaMainClassesResult> buildTargetScalaMainClasses(
ScalaMainClassesParams scalaMainClassesParams) {
return scalaBuildServerService.buildTargetScalaMainClasses(scalaMainClassesParams);
return serverRequestHelpers.executeCommand(
() -> scalaBuildServerService.buildTargetScalaMainClasses(scalaMainClassesParams));
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package org.jetbrains.bsp.bazel.server.bsp.services;

import ch.epfl.scala.bsp4j.BuildTargetIdentifier;
import ch.epfl.scala.bsp4j.ScalaMainClass;
import ch.epfl.scala.bsp4j.ScalaMainClassesItem;
import ch.epfl.scala.bsp4j.ScalaMainClassesParams;
import ch.epfl.scala.bsp4j.ScalaMainClassesResult;
import ch.epfl.scala.bsp4j.ScalaTestClassesItem;
Expand All @@ -12,10 +14,9 @@
import com.google.common.collect.ImmutableList;
import com.google.devtools.build.lib.query2.proto.proto2api.Build;
import com.google.devtools.build.lib.query2.proto.proto2api.Build.Attribute;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.eclipse.lsp4j.jsonrpc.messages.Either;
import org.eclipse.lsp4j.jsonrpc.messages.ResponseError;
import org.jetbrains.bsp.bazel.commons.Constants;
Expand All @@ -27,25 +28,29 @@

public class ScalaBuildServerService {

private static final String SCALA_COMPILER_OPTIONS_NAME = "scalacopts";
private static final String SCALA_COMPILER_OPTIONS_ATTR_NAME = "scalacopts";
private static final List<String> SCALA_LANGUAGES_IDS =
ImmutableList.of(Constants.SCALAC, Constants.JAVAC);

private static final String SCALA_TEST_RULE_CLASS_NAME = "scala_test";

private final TargetsLanguageOptionsResolver<ScalacOptionsItem> targetsLanguageOptionsResolver;
private final TargetRulesResolver<ScalaMainClassesItem> targetsScalaMainClassesRulesResolver;
private final TargetRulesResolver<ScalaTestClassesItem> targetsScalaTestClassesRulesResolver;

public ScalaBuildServerService(BazelData bazelData, BazelRunner bazelRunner) {
this.targetsLanguageOptionsResolver =
TargetsLanguageOptionsResolver.<ScalacOptionsItem>builder()
.bazelData(bazelData)
.bazelRunner(bazelRunner)
.compilerOptionsName(SCALA_COMPILER_OPTIONS_NAME)
.compilerOptionsName(SCALA_COMPILER_OPTIONS_ATTR_NAME)
.languagesIds(SCALA_LANGUAGES_IDS)
.resultItemsCollector(ScalacOptionsItem::new)
.build();

this.targetsScalaMainClassesRulesResolver =
TargetRulesResolver.withBazelRunnerAndMapper(bazelRunner, this::mapRuleToMainClassesItem);

this.targetsScalaTestClassesRulesResolver =
TargetRulesResolver.withBazelRunnerAndFilterAndMapper(
bazelRunner, this::isScalaTestRule, this::mapRuleToTestClassesItem);
Expand All @@ -63,11 +68,7 @@ private ScalaTestClassesItem mapRuleToTestClassesItem(Build.Rule rule) {
}

private List<String> getTestMainClasses(Build.Rule rule) {
return rule.getAttributeList().stream()
.filter(
attribute ->
TargetsUtils.isAttributeSpecifiedAndHasGivenName(
attribute, Constants.SCALA_TEST_MAIN_CLASSES_ATTRIBUTE_NAME))
return getAttribute(rule, Constants.SCALA_TEST_MAIN_CLASSES_ATTRIBUTE_NAME)
.map(Attribute::getStringValue)
.collect(Collectors.toList());
}
Expand All @@ -77,8 +78,8 @@ public Either<ResponseError, ScalacOptionsResult> buildTargetScalacOptions(
List<ScalacOptionsItem> resultItems =
targetsLanguageOptionsResolver.getResultItemsForTargets(scalacOptionsParams.getTargets());

ScalacOptionsResult javacOptionsResult = new ScalacOptionsResult(resultItems);
return Either.forRight(javacOptionsResult);
ScalacOptionsResult scalacOptionsResult = new ScalacOptionsResult(resultItems);
return Either.forRight(scalacOptionsResult);
}

public Either<ResponseError, ScalaTestClassesResult> buildTargetScalaTestClasses(
Expand All @@ -92,10 +93,53 @@ public Either<ResponseError, ScalaTestClassesResult> buildTargetScalaTestClasses
return Either.forRight(scalaTestClassesResult);
}

public CompletableFuture<ScalaMainClassesResult> buildTargetScalaMainClasses(
public Either<ResponseError, ScalaMainClassesResult> buildTargetScalaMainClasses(
ScalaMainClassesParams scalaMainClassesParams) {
System.out.printf("DWH: Got buildTargetScalaMainClasses: %s%n", scalaMainClassesParams);
// TODO(illicitonion): Populate
return CompletableFuture.completedFuture(new ScalaMainClassesResult(new ArrayList<>()));

List<ScalaMainClassesItem> resultItems =
targetsScalaMainClassesRulesResolver.getItemsForTargets(
scalaMainClassesParams.getTargets());

ScalaMainClassesResult result =
new ScalaMainClassesResult(
resultItems.stream()
.filter(item -> !item.getClasses().isEmpty())
.collect(Collectors.toList()));

return Either.forRight(result);
}

private ScalaMainClassesItem mapRuleToMainClassesItem(Build.Rule rule) {
BuildTargetIdentifier targetId = new BuildTargetIdentifier(rule.getName());
List<ScalaMainClass> mainClasses = collectMainClasses(rule);
return new ScalaMainClassesItem(targetId, mainClasses);
}

private List<ScalaMainClass> collectMainClasses(Build.Rule rule) {
List<String> targetOptions =
collectAttributesFromStringListValues(rule, Constants.JVM_FLAGS_ATTR_NAME);
List<String> mainClassesNames =
collectAttributesFromStringValues(rule, Constants.MAIN_CLASS_ATTR_NAME);
List<String> arguments = collectAttributesFromStringListValues(rule, Constants.ARGS_ATTR_NAME);
return mainClassesNames.stream()
.map(mainClassName -> new ScalaMainClass(mainClassName, arguments, targetOptions))
.collect(Collectors.toList());
}

private List<String> collectAttributesFromStringListValues(Build.Rule rule, String attrName) {
return getAttribute(rule, attrName)
.flatMap(attr -> attr.getStringListValueList().stream())
.collect(Collectors.toList());
}

private List<String> collectAttributesFromStringValues(Build.Rule rule, String attrName) {
return getAttribute(rule, attrName)
.map(Build.Attribute::getStringValue)
.collect(Collectors.toList());
}

private Stream<Build.Attribute> getAttribute(Build.Rule rule, String name) {
return rule.getAttributeList().stream()
.filter(attr -> TargetsUtils.isAttributeSpecifiedAndHasGivenName(attr, name));
}
}
6 changes: 6 additions & 0 deletions src/test/java/org/jetbrains/bsp/bazel/BazelBspServerTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,12 @@ private List<BazelBspServerSingleTest> getTestsToRun() {
client.testDependencySourcesResults(
BazelBspServerTestData.EXPECTED_BUILD_TARGETS,
BazelBspServerTestData.EXPECTED_DEPENDENCIES)),
new BazelBspServerSingleTest(
"Scala main classes",
() ->
client.testScalaMainClasses(
BazelBspServerTestData.SCALA_MAIN_CLASSES_PARAMS,
BazelBspServerTestData.EXPECTED_SCALA_MAIN_CLASSES)),
new BazelBspServerSingleTest(
"Scala test classes",
() ->
Expand Down
43 changes: 41 additions & 2 deletions src/test/java/org/jetbrains/bsp/bazel/BazelBspServerTestData.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@
import ch.epfl.scala.bsp4j.InverseSourcesResult;
import ch.epfl.scala.bsp4j.ResourcesItem;
import ch.epfl.scala.bsp4j.ResourcesResult;
import ch.epfl.scala.bsp4j.ScalaMainClass;
import ch.epfl.scala.bsp4j.ScalaMainClassesItem;
import ch.epfl.scala.bsp4j.ScalaMainClassesParams;
import ch.epfl.scala.bsp4j.ScalaMainClassesResult;
import ch.epfl.scala.bsp4j.ScalaTestClassesItem;
import ch.epfl.scala.bsp4j.ScalaTestClassesParams;
import ch.epfl.scala.bsp4j.ScalaTestClassesResult;
Expand All @@ -19,6 +23,7 @@
import ch.epfl.scala.bsp4j.WorkspaceBuildTargetsResult;
import com.google.common.collect.ImmutableList;
import java.time.Duration;
import java.util.Collections;
import java.util.List;
import org.jetbrains.bsp.bazel.commons.Constants;

Expand All @@ -37,9 +42,15 @@ class BazelBspServerTestData {
new BuildTargetIdentifier("//dep/deeper:deeper");
private static final BuildTargetIdentifier ID_4 =
new BuildTargetIdentifier("//example:example-test");
private static final BuildTargetIdentifier ID_5 =
new BuildTargetIdentifier("//target_without_main_class:library");
private static final BuildTargetIdentifier ID_6 =
new BuildTargetIdentifier("//target_without_args:binary");
private static final BuildTargetIdentifier ID_7 =
new BuildTargetIdentifier("//target_without_jvm_flags:binary");

static final Duration TEST_CLIENT_TIMEOUT_IN_MINUTES = Duration.ofMinutes(4);
static final Integer TEST_EXECUTION_TIMEOUT_IN_MINUTES = 15;
static final Duration TEST_CLIENT_TIMEOUT_IN_MINUTES = Duration.ofMinutes(6);
static final Integer TEST_EXECUTION_TIMEOUT_IN_MINUTES = 25;

static final String WORKSPACE_FULL_PATH = WORKSPACE_DIR_PATH + "/" + SAMPLE_REPO_PATH;

Expand Down Expand Up @@ -110,6 +121,34 @@ class BazelBspServerTestData {
static final InverseSourcesResult EXPECTED_INVERSE_SOURCES =
new InverseSourcesResult(ImmutableList.of(ID_2));

static final ScalaMainClassesParams SCALA_MAIN_CLASSES_PARAMS =
new ScalaMainClassesParams(ImmutableList.of(ID_1, ID_5, ID_6, ID_7));

static final ScalaMainClassesResult EXPECTED_SCALA_MAIN_CLASSES =
new ScalaMainClassesResult(
ImmutableList.of(
new ScalaMainClassesItem(
ID_1,
Collections.singletonList(
new ScalaMainClass(
"example.Example",
ImmutableList.of("arg1", "arg2"),
ImmutableList.of("-Xms2G -Xmx5G")))),
new ScalaMainClassesItem(
ID_6,
Collections.singletonList(
new ScalaMainClass(
"example.Example",
ImmutableList.of(),
ImmutableList.of("-Xms2G -Xmx5G")))),
new ScalaMainClassesItem(
ID_7,
Collections.singletonList(
new ScalaMainClass(
"example.Example",
ImmutableList.of("arg1", "arg2"),
ImmutableList.of())))));

static final ScalaTestClassesParams SCALA_TEST_CLASSES_PARAMS =
new ScalaTestClassesParams(ImmutableList.of(ID_1, ID_4));

Expand Down

0 comments on commit f591b4c

Please sign in to comment.