Skip to content

Commit d921053

Browse files
authored
Simplify scalac worker args format (#1230)
* Get rid of join in starlark * Remove defaults handling for values which are always passed * Move plugins formatting to ScalacWorker next to plugin params * Move validation from CompileOptions next to others in ScalacWorker * Formatting * Add test for CompilerOptions args file parsing * Remove not required interfaces from CompileOptions.Args * Java naming
1 parent 50f3057 commit d921053

File tree

6 files changed

+207
-227
lines changed

6 files changed

+207
-227
lines changed

scala/private/rule_impls.bzl

Lines changed: 15 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,7 @@
1515

1616
load("@bazel_skylib//lib:paths.bzl", "paths")
1717
load("@bazel_tools//tools/jdk:toolchain_utils.bzl", "find_java_runtime_toolchain", "find_java_toolchain")
18-
load(
19-
":common.bzl",
20-
_collect_plugin_paths = "collect_plugin_paths",
21-
)
18+
load(":common.bzl", _collect_plugin_paths = "collect_plugin_paths")
2219
load(":resources.bzl", _resource_paths = "paths")
2320

2421
def expand_location(ctx, flags):
@@ -85,28 +82,28 @@ def compile_scala(
8582
args.add("--StatsfileOutput", statsfile)
8683
args.add("--EnableDiagnosticsReport", enable_diagnostics_report)
8784
args.add("--DiagnosticsFile", diagnosticsfile)
88-
args.add_joined("--Classpath", compiler_classpath_jars, join_with = ctx.configuration.host_path_separator)
89-
args.add_joined("--ClasspathResourceSrcs", classpath_resources, join_with = ",")
90-
args.add_joined("--Files", sources, join_with = ",")
91-
args.add_joined("--Plugins", plugins, join_with = ",")
92-
args.add_joined("--ResourceTargets", [p[0] for p in resource_paths], join_with = ",")
93-
args.add_joined("--ResourceSources", [p[1] for p in resource_paths], join_with = ",")
94-
args.add_joined("--ResourceJars", resource_jars, join_with = ",")
95-
args.add_joined("--ScalacOpts", scalacopts, join_with = ":::")
96-
args.add_joined("--SourceJars", all_srcjars, join_with = ",")
85+
args.add_all("--Classpath", compiler_classpath_jars)
86+
args.add_all("--ClasspathResourceSrcs", classpath_resources)
87+
args.add_all("--Files", sources)
88+
args.add_all("--Plugins", plugins)
89+
args.add_all("--ResourceTargets", [p[0] for p in resource_paths])
90+
args.add_all("--ResourceSources", [p[1] for p in resource_paths])
91+
args.add_all("--ResourceJars", resource_jars)
92+
args.add_all("--ScalacOpts", scalacopts)
93+
args.add_all("--SourceJars", all_srcjars)
9794

9895
if dependency_info.need_direct_info:
9996
if dependency_info.need_direct_jars:
100-
args.add_joined("--DirectJars", cjars, join_with = ",")
97+
args.add_all("--DirectJars", cjars)
10198
if dependency_info.need_direct_targets:
102-
args.add_joined("--DirectTargets", [labels[j.path] for j in cjars.to_list()], join_with = ",")
99+
args.add_all("--DirectTargets", [labels[j.path] for j in cjars.to_list()])
103100

104101
if dependency_info.need_indirect_info:
105-
args.add_joined("--IndirectJars", transitive_compile_jars, join_with = ",")
106-
args.add_joined("--IndirectTargets", [labels[j.path] for j in transitive_compile_jars.to_list()], join_with = ",")
102+
args.add_all("--IndirectJars", transitive_compile_jars)
103+
args.add_all("--IndirectTargets", [labels[j.path] for j in transitive_compile_jars.to_list()])
107104

108105
if dependency_info.unused_deps_mode != "off":
109-
args.add_joined("--UnusedDepsIgnoredTargets", unused_dependency_checker_ignored_targets, join_with = ",")
106+
args.add_all("--UnusedDepsIgnoredTargets", unused_dependency_checker_ignored_targets)
110107

111108
outs = [output, statsfile, diagnosticsfile]
112109

src/java/io/bazel/rulesscala/scalac/BUILD

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
load("@rules_java//java:defs.bzl", "java_binary")
1+
load("@rules_java//java:defs.bzl", "java_binary", "java_test")
22

33
java_binary(
44
name = "scalac",
@@ -27,8 +27,14 @@ filegroup(
2727
"CompileOptions.java",
2828
"ProtoReporter.java",
2929
"ReportableMainClass.java",
30-
"Resource.java",
3130
"ScalacWorker.java",
3231
],
3332
visibility = ["//visibility:public"],
3433
)
34+
35+
java_test(
36+
name = "CompileOptionsTest",
37+
srcs = ["CompileOptionsTest.java"],
38+
test_class = "io.bazel.rulesscala.scalac.CompileOptionsTest",
39+
deps = [":scalac"],
40+
)
Lines changed: 97 additions & 176 deletions
Original file line numberDiff line numberDiff line change
@@ -1,185 +1,106 @@
11
package io.bazel.rulesscala.scalac;
22

3-
import java.util.ArrayList;
4-
import java.util.HashMap;
5-
import java.util.List;
3+
import java.util.Arrays;
4+
import java.util.LinkedHashMap;
65
import java.util.Map;
76

87
public class CompileOptions {
9-
public final String outputName;
10-
public final String manifestPath;
11-
public final String[] scalaOpts;
12-
public final boolean printCompileTime;
13-
public final boolean expectJavaOutput;
14-
public final String[] pluginArgs;
15-
public final String classpath;
16-
public final String[] files;
17-
public final String[] sourceJars;
18-
public final String[] javaFiles;
19-
public final List<Resource> resourceFiles;
20-
public final String[] resourceJars;
21-
public final String[] classpathResourceFiles;
22-
public final String[] directJars;
23-
public final String[] directTargets;
24-
public final String[] unusedDepsIgnoredTargets;
25-
public final String[] indirectJars;
26-
public final String[] indirectTargets;
27-
public final String strictDepsMode;
28-
public final String unusedDependencyCheckerMode;
29-
public final String currentTarget;
30-
public final String statsfile;
31-
public final String dependencyTrackingMethod;
32-
public final String diagnosticsFile;
33-
public final boolean enableDiagnosticsReport;
34-
35-
public CompileOptions(List<String> args) {
36-
Map<String, String> argMap = buildArgMap(args);
37-
38-
outputName = getOrError(argMap, "JarOutput", "Missing required arg JarOutput");
39-
manifestPath = getOrError(argMap, "Manifest", "Missing required arg Manifest");
40-
41-
scalaOpts = getTripleColonList(argMap, "ScalacOpts");
42-
printCompileTime = booleanGetOrFalse(argMap, "PrintCompileTime");
43-
expectJavaOutput = booleanGetOrTrue(argMap, "ExpectJavaOutput");
44-
pluginArgs = buildPluginArgs(getOrEmpty(argMap, "Plugins"));
45-
classpath = getOrError(argMap, "Classpath", "Must supply the classpath arg");
46-
files = getCommaList(argMap, "Files");
47-
48-
javaFiles = getCommaList(argMap, "JavaFiles");
49-
50-
if (!expectJavaOutput && javaFiles.length != 0) {
51-
throw new RuntimeException("Cannot hava java source files when no expected java output");
52-
}
53-
54-
sourceJars = getCommaList(argMap, "SourceJars");
55-
resourceFiles = getResources(argMap);
56-
resourceJars = getCommaList(argMap, "ResourceJars");
57-
classpathResourceFiles = getCommaList(argMap, "ClasspathResourceSrcs");
58-
59-
directJars = getCommaList(argMap, "DirectJars");
60-
directTargets = getCommaList(argMap, "DirectTargets");
61-
unusedDepsIgnoredTargets = getCommaList(argMap, "UnusedDepsIgnoredTargets");
62-
indirectJars = getCommaList(argMap, "IndirectJars");
63-
indirectTargets = getCommaList(argMap, "IndirectTargets");
64-
65-
strictDepsMode = getOrElse(argMap, "StrictDepsMode", "off");
66-
unusedDependencyCheckerMode = getOrElse(argMap, "UnusedDependencyCheckerMode", "off");
67-
currentTarget = getOrElse(argMap, "CurrentTarget", "NA");
68-
dependencyTrackingMethod = getOrElse(argMap, "DependencyTrackingMethod", "high-level");
69-
70-
statsfile = getOrError(argMap, "StatsfileOutput", "Missing required arg StatsfileOutput");
71-
enableDiagnosticsReport = booleanGetOrFalse(argMap, "EnableDiagnosticsReport");
72-
diagnosticsFile = getOrError(argMap, "DiagnosticsFile", "Missing required arg DiagnosticsFile");
73-
}
74-
75-
private static List<Resource> getResources(Map<String, String> args) {
76-
String[] targets = getCommaList(args, "ResourceTargets");
77-
String[] sources = getCommaList(args, "ResourceSources");
78-
79-
if (targets.length != sources.length)
80-
throw new RuntimeException(
81-
String.format(
82-
"mismatch in resources: targets: %s sources: %s",
83-
getOrEmpty(args, "ResourceTargets"), getOrEmpty(args, "ResourceSources")));
84-
85-
List<Resource> resources = new ArrayList<Resource>();
86-
for (int idx = 0; idx < targets.length; idx++) {
87-
resources.add(new Resource(targets[idx], sources[idx]));
88-
}
89-
return resources;
90-
}
91-
92-
private static Map<String, String> buildArgMap(List<String> lines) {
93-
Map<String, String> args = new HashMap<>();
94-
for (int i = 0; i < lines.size(); i += 2) {
95-
args.put(lines.get(i).substring(2), lines.get(i + 1));
96-
}
97-
return args;
98-
}
99-
100-
protected static String[] getTripleColonList(Map<String, String> m, String k) {
101-
if (m.containsKey(k)) {
102-
String v = m.get(k);
103-
if ("".equals(v)) {
104-
return new String[] {};
105-
} else {
106-
return v.split(":::");
107-
}
108-
} else {
109-
return new String[] {};
110-
}
111-
}
112-
113-
private static String[] getCommaList(Map<String, String> m, String k) {
114-
if (m.containsKey(k)) {
115-
String v = m.get(k);
116-
if ("".equals(v)) {
117-
return new String[] {};
118-
} else {
119-
return v.split(",");
120-
}
121-
} else {
122-
return new String[] {};
123-
}
124-
}
125-
126-
private static String getOrEmpty(Map<String, String> m, String k) {
127-
return getOrElse(m, k, "");
128-
}
129-
130-
private static String getOrElse(Map<String, String> attrs, String key, String defaultValue) {
131-
if (attrs.containsKey(key)) {
132-
return attrs.get(key);
133-
} else {
134-
return defaultValue;
135-
}
136-
}
137-
138-
private static String getOrError(Map<String, String> m, String k, String errorMessage) {
139-
if (m.containsKey(k)) {
140-
return m.get(k);
141-
} else {
142-
throw new RuntimeException(errorMessage);
143-
}
144-
}
145-
146-
private static boolean booleanGetOrFalse(Map<String, String> m, String k) {
147-
if (m.containsKey(k)) {
148-
String v = m.get(k);
149-
if (v.trim().equals("True") || v.trim().equals("true")) {
150-
return true;
151-
}
152-
}
153-
return false;
154-
}
155-
156-
private static boolean booleanGetOrTrue(Map<String, String> m, String k) {
157-
if (m.containsKey(k)) {
158-
String v = m.get(k);
159-
if (v.trim().equals("False") || v.trim().equals("false")) {
160-
return false;
161-
}
162-
}
163-
return true;
164-
}
165-
166-
public static String[] buildPluginArgs(String packedPlugins) {
167-
String[] pluginElements = packedPlugins.split(",");
168-
int numPlugins = 0;
169-
for (int i = 0; i < pluginElements.length; i++) {
170-
if (pluginElements[i].length() > 0) {
171-
numPlugins += 1;
172-
}
8+
public final String outputName;
9+
public final String manifestPath;
10+
public final String[] scalaOpts;
11+
public final boolean printCompileTime;
12+
public final boolean expectJavaOutput;
13+
public final String[] plugins;
14+
public final String[] classpath;
15+
public final String[] files;
16+
public final String[] sourceJars;
17+
public final String[] javaFiles;
18+
public final String[] resourceSources;
19+
public final String[] resourceTargets;
20+
public final String[] resourceJars;
21+
public final String[] classpathResourceFiles;
22+
public final String[] directJars;
23+
public final String[] directTargets;
24+
public final String[] unusedDepsIgnoredTargets;
25+
public final String[] indirectJars;
26+
public final String[] indirectTargets;
27+
public final String strictDepsMode;
28+
public final String unusedDependencyCheckerMode;
29+
public final String currentTarget;
30+
public final String statsfile;
31+
public final String dependencyTrackingMethod;
32+
public final String diagnosticsFile;
33+
public final boolean enableDiagnosticsReport;
34+
35+
public CompileOptions(String[] lines) {
36+
Args args = new Args(lines);
37+
38+
outputName = args.getSingleOrError("JarOutput");
39+
manifestPath = args.getSingleOrError("Manifest");
40+
41+
scalaOpts = args.getOrEmpty("ScalacOpts");
42+
printCompileTime = Boolean.parseBoolean(args.getSingleOrError("PrintCompileTime"));
43+
expectJavaOutput = Boolean.parseBoolean(args.getSingleOrError("ExpectJavaOutput"));
44+
plugins = args.getOrEmpty("Plugins");
45+
classpath = args.getOrEmpty("Classpath");
46+
files = args.getOrEmpty("Files");
47+
sourceJars = args.getOrEmpty("SourceJars");
48+
javaFiles = args.getOrEmpty("JavaFiles");
49+
50+
resourceSources = args.getOrEmpty("ResourceSources");
51+
resourceTargets = args.getOrEmpty("ResourceTargets");
52+
resourceJars = args.getOrEmpty("ResourceJars");
53+
classpathResourceFiles = args.getOrEmpty("ClasspathResourceSrcs");
54+
55+
directJars = args.getOrEmpty("DirectJars");
56+
directTargets = args.getOrEmpty("DirectTargets");
57+
unusedDepsIgnoredTargets = args.getOrEmpty("UnusedDepsIgnoredTargets");
58+
indirectJars = args.getOrEmpty("IndirectJars");
59+
indirectTargets = args.getOrEmpty("IndirectTargets");
60+
61+
strictDepsMode = args.getSingleOrError("StrictDepsMode");
62+
unusedDependencyCheckerMode = args.getSingleOrError("UnusedDependencyCheckerMode");
63+
currentTarget = args.getSingleOrError("CurrentTarget");
64+
dependencyTrackingMethod = args.getSingleOrError("DependencyTrackingMethod");
65+
66+
statsfile = args.getSingleOrError("StatsfileOutput");
67+
enableDiagnosticsReport = Boolean.parseBoolean(args.getSingleOrError("EnableDiagnosticsReport"));
68+
diagnosticsFile = args.getSingleOrError("DiagnosticsFile");
17369
}
17470

175-
String[] result = new String[numPlugins];
176-
int idx = 0;
177-
for (int i = 0; i < pluginElements.length; i++) {
178-
if (pluginElements[i].length() > 0) {
179-
result[idx] = "-Xplugin:" + pluginElements[i];
180-
idx += 1;
181-
}
71+
static final class Args {
72+
73+
private static final String[] EMPTY = new String[]{};
74+
private final Map<String, String[]> index = new LinkedHashMap<>();
75+
76+
Args(String[] lines) {
77+
int opt = 0;
78+
for (int i = 1, n = lines.length; i <= n; i++) {
79+
if (i == n || lines[i].startsWith("--")) {
80+
index.put(
81+
lines[opt].substring(2),
82+
Arrays.copyOfRange(lines, opt + 1, i)
83+
);
84+
opt = i;
85+
}
86+
}
87+
}
88+
89+
String[] getOrEmpty(String k) {
90+
return index.getOrDefault(k, EMPTY);
91+
}
92+
93+
String getSingleOrError(String k) {
94+
if (index.containsKey(k)) {
95+
String[] v = index.get(k);
96+
if (v.length == 1) {
97+
return v[0];
98+
} else {
99+
throw new RuntimeException(k + " expected to contain single value but got " + Arrays.toString(v));
100+
}
101+
} else {
102+
throw new RuntimeException("Missing required arg " + k);
103+
}
104+
}
182105
}
183-
return result;
184-
}
185106
}

0 commit comments

Comments
 (0)