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

Implement buildTargetScalaMainClasses #36

Merged
merged 40 commits into from
Feb 4, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
3dc670d
Init
magda-aug Jan 19, 2021
784c1bb
Fix resolving target options
magda-aug Jan 20, 2021
df5e842
Fix variable name
magda-aug Jan 20, 2021
e48a09b
Change access
magda-aug Jan 20, 2021
017ef70
Fix formatting
magda-aug Jan 20, 2021
7622ec1
Fix formatting
magda-aug Jan 20, 2021
b1e0124
Read arguments
magda-aug Jan 20, 2021
4c94579
Upgrade bsp-testkit
magda-aug Jan 21, 2021
127984b
Add empty test
magda-aug Jan 21, 2021
dcb0882
Fix formatting
magda-aug Jan 21, 2021
7e1750b
Move constants
magda-aug Jan 21, 2021
b9d7637
Merge branch 'dev' into scala-mainclasses-2
magda-aug Jan 21, 2021
2bac873
Fix
magda-aug Jan 21, 2021
63c37e0
Add more data to test
magda-aug Jan 21, 2021
64bc27a
Add package name
magda-aug Jan 21, 2021
88e4eed
Move targetRulesResolver to constructor
magda-aug Jan 27, 2021
69728f0
return Completable Future instead of null
magda-aug Jan 27, 2021
fdc6cae
Extract method
magda-aug Jan 27, 2021
db9ea50
Extract isAttributeSpecifiedAndHasGivenName
magda-aug Jan 27, 2021
cc6214b
Call buildServerImpl
magda-aug Jan 27, 2021
8815911
Pass compiler options and args to test
magda-aug Jan 27, 2021
94c2441
Fix tests
magda-aug Jan 27, 2021
bf55173
Fix tests
magda-aug Jan 27, 2021
b41b805
Add more args to test
magda-aug Jan 28, 2021
5db976f
Read also jvm flags
magda-aug Jan 28, 2021
2b88327
Move to constants
magda-aug Jan 28, 2021
b5bd604
Read only jvm flags
magda-aug Feb 2, 2021
7ae79f3
Merge branch 'dev' into scala-mainclasses-2
magda-aug Feb 2, 2021
3f63924
fix formatting
magda-aug Feb 2, 2021
d1b1e76
unify naming
magda-aug Feb 2, 2021
e0a6707
use helper method
magda-aug Feb 2, 2021
09443e5
remove duplicate methods
magda-aug Feb 2, 2021
8e23255
Add more test cases
magda-aug Feb 3, 2021
0089ae3
revert
magda-aug Feb 3, 2021
83a4f34
Add test case
magda-aug Feb 3, 2021
847d335
target without args test case
magda-aug Feb 3, 2021
20b982d
increase timeout
magda-aug Feb 4, 2021
8b801e3
add test case without jvm flags
magda-aug Feb 4, 2021
0ce672b
increase timeout
magda-aug Feb 4, 2021
f6d595d
increase timeout
magda-aug Feb 4, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 =
abrams27 marked this conversation as resolved.
Show resolved Hide resolved
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