Skip to content

Commit 27aaff7

Browse files
authored
Provide arguments to JacocoInstrumenter without using delimiter (#1252)
Currently files provided as arguments for JacocoInstrumenter are separated by '='. That leads to problems if files or target names contain '=' in names.
1 parent 3d22381 commit 27aaff7

File tree

13 files changed

+132
-22
lines changed

13 files changed

+132
-22
lines changed

examples/testing/multi_frameworks_toolchain/BUILD

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ declare_deps_provider(
5656
deps_id = "specs2_junit_classpath",
5757
visibility = ["//visibility:public"],
5858
deps = [
59+
"@io_bazel_rules_scala//scala:bazel_test_runner_deploy",
5960
"@io_bazel_rules_scala_org_specs2_specs2_junit",
6061
],
6162
)

scala/private/phases/phase_coverage.bzl

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -36,26 +36,24 @@ def _phase_coverage(ctx, p, srcjars):
3636
output_jar = ctx.actions.declare_file(
3737
"{}-offline.jar".format(input_jar.basename.split(".")[0]),
3838
)
39-
srcs_paths = [src.path for src in ctx.files.srcs]
40-
records = [
41-
(input_jar, output_jar, srcs_paths),
42-
]
4339

4440
args = ctx.actions.args()
45-
args.add_all(records, map_each = _jacoco_offline_instrument_format_each)
4641
args.set_param_file_format("multiline")
4742
args.use_param_file("@%s", use_always = True)
43+
args.add(input_jar)
44+
args.add(output_jar)
45+
args.add_all(ctx.files.srcs)
4846

4947
ctx.actions.run(
5048
mnemonic = "JacocoInstrumenter",
51-
inputs = [record[0] for record in records],
52-
outputs = [record[1] for record in records],
49+
inputs = [input_jar],
50+
outputs = [output_jar],
5351
executable = ctx.attr._code_coverage_instrumentation_worker.files_to_run,
5452
execution_requirements = {"supports-workers": "1"},
5553
arguments = [args],
5654
)
5755

58-
replacements = {i: o for (i, o, _) in records}
56+
replacements = {input_jar: output_jar}
5957
provider = _coverage_replacements_provider.create(
6058
replacements = replacements,
6159
)
@@ -72,6 +70,3 @@ def _phase_coverage(ctx, p, srcjars):
7270
"InstrumentedFilesInfo": instrumented_files_provider,
7371
},
7472
)
75-
76-
def _jacoco_offline_instrument_format_each(records):
77-
return (["%s=%s=%s" % (records[0].path, records[1].path, ",".join(records[2]))])

src/java/io/bazel/rulesscala/coverage/instrumenter/JacocoInstrumenter.java

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import io.bazel.rulesscala.worker.Worker;
66
import java.io.BufferedInputStream;
77
import java.io.BufferedOutputStream;
8+
import java.io.UnsupportedEncodingException;
89
import java.nio.file.FileSystem;
910
import java.nio.file.FileSystems;
1011
import java.nio.file.FileVisitResult;
@@ -17,6 +18,10 @@
1718
import java.nio.file.attribute.BasicFileAttributes;
1819
import org.jacoco.core.instr.Instrumenter;
1920
import org.jacoco.core.runtime.OfflineInstrumentationAccessGenerator;
21+
import java.net.URLDecoder;
22+
import java.util.Arrays;
23+
import java.util.List;
24+
import java.util.stream.Collectors;
2025

2126
public final class JacocoInstrumenter implements Worker.Interface {
2227

@@ -27,19 +32,17 @@ public static void main(String[] args) throws Exception {
2732
@Override
2833
public void work(String[] args) throws Exception {
2934
Instrumenter jacoco = new Instrumenter(new OfflineInstrumentationAccessGenerator());
30-
for (String arg : args) {
31-
processArg(jacoco, arg);
32-
}
35+
processArg(jacoco, args);
3336
}
3437

35-
private void processArg(Instrumenter jacoco, String arg) throws Exception {
36-
String[] parts = arg.split("=");
37-
if (parts.length != 3) {
38-
throw new Exception("expected `in_path=out_path=srcs` form for argument: " + arg);
38+
private void processArg(Instrumenter jacoco, String[] args) throws Exception {
39+
if (args.length < 3) {
40+
throw new Exception("expected format `in_path out_path src1 src2 ... srcN` for arguments: " + Arrays.asList(args));
3941
}
40-
Path inPath = Paths.get(parts[0]);
41-
Path outPath = Paths.get(parts[1]);
42-
String srcs = parts[2];
42+
43+
Path inPath = Paths.get(args[0]);
44+
Path outPath = Paths.get(args[1]);
45+
String[] srcs = Arrays.copyOfRange(args, 2, args.length);
4346

4447
// Use a directory for coverage metadata that is unique to each built jar. Avoids
4548
// multiple threads performing read/write/delete actions on the instrumented classes directory.
@@ -73,7 +76,7 @@ private void processArg(Instrumenter jacoco, String arg) throws Exception {
7376
Path pathsForCoverage = instrumentedClassesDirectory.resolve("-paths-for-coverage.txt");
7477
Files.write(
7578
pathsForCoverage,
76-
srcs.replace(",", "\n").getBytes(java.nio.charset.StandardCharsets.UTF_8)
79+
String.join("\n", srcs).getBytes(java.nio.charset.StandardCharsets.UTF_8)
7780
);
7881

7982
jarCreator.addEntry(instrumentedClassesDirectory.relativize(pathsForCoverage).toString(), pathsForCoverage);
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package coverage_filename_encoding
2+
3+
object A1 {
4+
def a1(flag: Boolean): String =
5+
if (flag) "B1"
6+
else sys.error("oh noes")
7+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
load("//scala:scala.bzl", "scala_library", "scala_specs2_junit_test")
2+
3+
scala_specs2_junit_test(
4+
name = "name-with-equals",
5+
size = "small",
6+
srcs = ["Test.scala"],
7+
prefixes = ["Test"],
8+
deps = [
9+
"a1%3D=%3D%2Bagg",
10+
],
11+
)
12+
13+
scala_library(
14+
name = "a1%3D=%3D%2Bagg",
15+
srcs = [
16+
"A1.scala",
17+
],
18+
deps = [
19+
],
20+
)
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
package coverage_filename_encoding
2+
3+
import org.specs2.mutable.SpecWithJUnit
4+
import org.specs2.specification.Scope
5+
6+
class Test extends SpecWithJUnit {
7+
"testA1" in new Scope {
8+
A1.a1(true) must_!= 1
9+
}
10+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
SF:test/coverage_filename_encoding/A1.scala
2+
FN:-1,coverage_filename_encoding/A1$::<clinit> ()V
3+
FN:3,coverage_filename_encoding/A1$::<init> ()V
4+
FN:5,coverage_filename_encoding/A1$::a1 (Z)Ljava/lang/String;
5+
FN:-1,coverage_filename_encoding/A1::a1 (Z)Ljava/lang/String;
6+
FNDA:1,coverage_filename_encoding/A1$::<clinit> ()V
7+
FNDA:1,coverage_filename_encoding/A1$::<init> ()V
8+
FNDA:1,coverage_filename_encoding/A1$::a1 (Z)Ljava/lang/String;
9+
FNDA:0,coverage_filename_encoding/A1::a1 (Z)Ljava/lang/String;
10+
FNF:4
11+
FNH:3
12+
BA:5,2
13+
BRF:1
14+
BRH:1
15+
DA:3,1
16+
DA:5,4
17+
DA:6,1
18+
DA:7,4
19+
LH:4
20+
LF:4
21+
end_of_record

test/coverage_specs2_with_junit/BUILD

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ scala_specs2_junit_test(
1111
":a2",
1212
":b1",
1313
":d1",
14+
":e1",
1415
],
1516
)
1617

@@ -64,3 +65,15 @@ scala_library(
6465
"D1.scala",
6566
],
6667
)
68+
69+
scala_library(
70+
name = "e1",
71+
srcs = [
72+
"A1.scala",
73+
"D1.scala",
74+
"E1.scala",
75+
],
76+
deps = [
77+
":b1",
78+
],
79+
)
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
package coverage_specs2_with_junit
2+
3+
object E1 {
4+
def e1(input: String): String =
5+
input.reverse
6+
}

test/coverage_specs2_with_junit/TestWithSpecs2WithJUnit.scala

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,4 +15,8 @@ class TestWithSpecs2WithJUnit extends SpecWithJUnit {
1515
"testD1" in new Scope {
1616
D1.veryLongFunctionNameIsHereAaaaaaaaa()
1717
}
18+
19+
"testE1" in new Scope {
20+
E1.e1("test")
21+
}
1822
}

0 commit comments

Comments
 (0)