Skip to content

Commit 0b2bd39

Browse files
authored
Single-jar pack_sources should conform to Bazel behavior (#1378)
Single-jar pack_sources should conform to Bazel behaviour
1 parent a148a3a commit 0b2bd39

File tree

4 files changed

+144
-12
lines changed

4 files changed

+144
-12
lines changed

scala/private/phases/phase_compile.bzl

+27-11
Original file line numberDiff line numberDiff line change
@@ -308,17 +308,33 @@ def _create_scala_compilation_provider(ctx, ijar, source_jar, deps_providers):
308308
neverlink = ctx.attr.neverlink,
309309
)
310310

311-
def _pack_source_jar(ctx, scala_srcs, in_srcjars):
312-
output_jar = ctx.outputs.jar
313-
source_jar_name = output_jar.basename[:-len(output_jar.extension)] + "-src.jar"
314-
output_source_jar = ctx.actions.declare_file(source_jar_name, sibling = output_jar)
315-
return java_common.pack_sources(
316-
ctx.actions,
317-
output_source_jar = output_source_jar,
318-
sources = scala_srcs,
319-
source_jars = in_srcjars,
320-
java_toolchain = find_java_toolchain(ctx, ctx.attr._java_toolchain),
321-
)
311+
def _pack_source_jar(ctx, scala_srcs, input_srcjars):
312+
# https://github.com/bazelbuild/bazel/blob/ff6c0333e4f957bb9f7ab5401b01dbf3e9b515b1/src/main/java/com/google/devtools/build/lib/rules/java/JavaInfoBuildHelper.java#L180-L183
313+
# java_common.pack_sources checks for no srcs and only a single input jar
314+
# if so, it checks that output_source_jar is null
315+
# passing that, it will return the input source jar directly
316+
# However, pack_sources will FAIL if both output_source_jar and
317+
# the deprecated output_jar field are BOTH null
318+
# Therefore, we can return the single input jar ourselves
319+
if not scala_srcs and len(input_srcjars) == 1:
320+
return input_srcjars[0]
321+
else:
322+
output_jar = ctx.outputs.jar
323+
without_ext = output_jar.basename
324+
if output_jar.extension:
325+
ext_len = len("." + output_jar.extension)
326+
without_ext = output_jar.basename[:-ext_len]
327+
source_jar_name = without_ext + "-src.jar"
328+
329+
output_source_jar = ctx.actions.declare_file(source_jar_name, sibling = output_jar)
330+
331+
return java_common.pack_sources(
332+
ctx.actions,
333+
output_source_jar = output_source_jar,
334+
sources = scala_srcs,
335+
source_jars = input_srcjars,
336+
java_toolchain = find_java_toolchain(ctx, ctx.attr._java_toolchain),
337+
)
322338

323339
def _try_to_compile_java_jar(
324340
ctx,
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,47 @@
11
load("//scala:scala.bzl", "scala_library")
2+
load(":pack_sources_test.bzl", "pack_sources_test_suite")
23

34
#TODO the way it SHOULD work (but isn't currently) is that
45
# the source_jar target should make available a compiled jar,
56
# and use_source_jar should depend on that internally
67

78
scala_library(
89
name = "source_jar",
9-
# SourceJar1.jar was created by:
10+
# SourceJar1.srcjar was created by:
1011
# jar -cfM test/src/main/scala/scalarules/test/srcjars/SourceJar1.srcjar \
1112
# test/src/main/scala/scalarules/test/srcjars/SourceJar1.scala
1213
srcs = ["SourceJar1.srcjar"],
1314
)
1415

16+
scala_library(
17+
name = "source_jar_no_expect_java_output",
18+
srcs = ["SourceJar1.srcjar"],
19+
expect_java_output = False,
20+
)
21+
22+
scala_library(
23+
name = "multi_source_jar",
24+
# SourceJar2.srcjar was created the same way as SourceJar1.srcjar, i.e. by:
25+
# jar -cfM test/src/main/scala/scalarules/test/srcjars/SourceJar2.srcjar \
26+
# test/src/main/scala/scalarules/test/srcjars/SourceJar2.scala
27+
srcs = [
28+
"SourceJar1.srcjar",
29+
"SourceJar2.srcjar",
30+
],
31+
)
32+
33+
scala_library(
34+
name = "mixed_source_jar",
35+
srcs = [
36+
"SourceJar1.srcjar",
37+
"SourceJar2.scala",
38+
],
39+
)
40+
1541
scala_library(
1642
name = "use_source_jar",
1743
srcs = ["SourceJar2.scala"],
1844
deps = [":source_jar"],
1945
)
46+
47+
pack_sources_test_suite(name = "pack_sources_test")
Binary file not shown.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
load("@bazel_skylib//lib:unittest.bzl", "analysistest", "asserts")
2+
load("@bazel_skylib//lib:new_sets.bzl", "sets")
3+
4+
# Tests and documents the functionality of phase_compile.bzl's _pack_source_jar
5+
6+
def _source_jar_test_impl(ctx):
7+
env = analysistest.begin(ctx)
8+
9+
target_under_test = analysistest.target_under_test(env)
10+
11+
srcjar_names = sets.make(
12+
[j.basename for j in target_under_test[JavaInfo].source_jars],
13+
)
14+
15+
expected_names = sets.make(ctx.attr.expected_basenames)
16+
17+
asserts.set_equals(env, expected = expected_names, actual = srcjar_names)
18+
19+
return analysistest.end(env)
20+
21+
def _make_source_jar_test():
22+
return analysistest.make(
23+
impl = _source_jar_test_impl,
24+
attrs = {
25+
"expected_basenames": attr.string_list(
26+
mandatory = True,
27+
allow_empty = True,
28+
),
29+
},
30+
)
31+
32+
source_jar_test = _make_source_jar_test()
33+
34+
def pack_sources_test_suite(name):
35+
source_jar_test(
36+
name = "single_source_jar_test",
37+
target_under_test = ":source_jar",
38+
39+
# In line with Bazel's java_common.pack_sources,
40+
# We return the initial .srcjar file since there are no source files
41+
# Not sure where the second -src.jar comes from, maybe due to java rules
42+
# It can be removed by adding the target attr expect_java_output = False
43+
expected_basenames = [
44+
"SourceJar1.srcjar",
45+
"source_jar_java-src.jar",
46+
],
47+
)
48+
source_jar_test(
49+
name = "single_source_jar_no_java_output_test",
50+
target_under_test = ":source_jar_no_expect_java_output",
51+
expected_basenames = [
52+
"SourceJar1.srcjar",
53+
],
54+
)
55+
source_jar_test(
56+
name = "multi_source_jar_test",
57+
target_under_test = ":multi_source_jar",
58+
expected_basenames = [
59+
"multi_source_jar-src.jar",
60+
"multi_source_jar_java-src.jar",
61+
],
62+
)
63+
source_jar_test(
64+
name = "mixed_source_jar_test",
65+
target_under_test = ":mixed_source_jar",
66+
expected_basenames = [
67+
"mixed_source_jar-src.jar",
68+
"mixed_source_jar_java-src.jar",
69+
],
70+
)
71+
source_jar_test(
72+
name = "source_jar_with_srcs_test",
73+
target_under_test = ":use_source_jar",
74+
expected_basenames = [
75+
"use_source_jar-src.jar",
76+
],
77+
)
78+
79+
native.test_suite(
80+
name = name,
81+
tests = [
82+
":single_source_jar_test",
83+
":single_source_jar_no_java_output_test",
84+
":multi_source_jar_test",
85+
":mixed_source_jar_test",
86+
":source_jar_with_srcs_test",
87+
],
88+
)

0 commit comments

Comments
 (0)