Skip to content

Commit 031e73c

Browse files
sdtwiggittaiz
authored andcommitted
Restructure scala provider, add JavaProvider (bazel-contrib#227)
* Restructure scala provider, add JavaProvider The key change is that the scala provider has been completely restructured to match the structure of the JavaProvider. It no longer tracks exports separately but instead has the following fields: * outputs = contains all the outputs generated by the current rule (nothing or ijar and class_jar); however, no rules here actually use it. * compile_jars = contains all the jars dependent rules should compile with. Thus, ijar and exports.compile_jars * transitive_runtime_jars = contains all the jars needed to handle this target at runtime. Thus, class_jar plus (deps + exports + runtime_deps).transitive_runtime_jars The created java provider (used by dependent native java rules) uses just compile_jars and transitive_runtime_jars. In general, this change was seamless. The major exception is if you were specifically relying on only exports being re-exported by specifically gen_scrooge_srcjar. Beforehand, any jars produced by direct dependencies were not being exported to dependents but now they are. Note that, if you were using scrooge_scala_library instead, nothing should change. Other changes: * Use depset instead of set. (set docs already say set should be considered deprecated and just points to depset anyway) * Tests amended to exploit that JavaProvider is properly constructed. Note that things are still a little strange until Bazel releases incorporate some fixes to JavaProvider and native provider rules. Generally, only deps for java_library and java_binary work at the moment. * Using JavaProvider, requires Bazel 0.5.2 Remove scala_exports_to_java Prefer using JavaProvider over scala provider (can probably avoid using scala provider completely?) * update minimum bazel version to 0.5.2
1 parent d511625 commit 031e73c

File tree

5 files changed

+115
-130
lines changed

5 files changed

+115
-130
lines changed

.travis.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ os:
1212

1313
env:
1414
- V=HEAD
15-
- V=0.4.5
15+
- V=0.5.2
1616

1717
before_install:
1818
- |

jmh/jmh.bzl

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,8 +66,7 @@ def _scala_construct_runtime_classpath(deps):
6666
java_targets = [d.java for d in deps if hasattr(d, "java")]
6767
files = []
6868
for scala in scala_targets:
69-
files += list(scala.transitive_runtime_deps)
70-
files += list(scala.transitive_runtime_exports)
69+
files += list(scala.transitive_runtime_jars)
7170
for java in java_targets:
7271
files += list(java.transitive_runtime_deps)
7372
return files

scala/scala.bzl

Lines changed: 80 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -149,8 +149,7 @@ def _collect_plugin_paths(plugins):
149149
return paths
150150

151151

152-
def _compile(ctx, _jars, dep_srcjars, buildijar):
153-
jars = _jars
152+
def _compile(ctx, cjars, dep_srcjars, buildijar):
154153
ijar_output_path = ""
155154
ijar_cmd_path = ""
156155
if buildijar:
@@ -165,7 +164,7 @@ def _compile(ctx, _jars, dep_srcjars, buildijar):
165164
plugins = _collect_plugin_paths(ctx.attr.plugins)
166165
plugin_arg = ",".join(list(plugins))
167166

168-
compiler_classpath = ":".join([j.path for j in jars])
167+
compiler_classpath = ":".join([j.path for j in cjars])
169168

170169
scalac_args = """
171170
Classpath: {cp}
@@ -222,7 +221,7 @@ SourceJars: {srcjars}
222221
# _jdk added manually since _java doesn't currently setup runfiles
223222
# _scalac, as a java_binary, should already have it in its runfiles; however,
224223
# adding does ensure _java not orphaned if _scalac ever was not a java_binary
225-
ins = (list(jars) +
224+
ins = (list(cjars) +
226225
list(dep_srcjars) +
227226
list(srcjars) +
228227
list(sources) +
@@ -355,32 +354,20 @@ def collect_srcjars(targets):
355354

356355
def _collect_jars(targets):
357356
"""Compute the runtime and compile-time dependencies from the given targets""" # noqa
358-
compile_jars = set()
359-
runtime_jars = set()
357+
compile_jars = depset()
358+
runtime_jars = depset()
360359
for target in targets:
361-
found = False
362-
if hasattr(target, "scala"):
363-
if hasattr(target.scala.outputs, "ijar"):
364-
compile_jars += [target.scala.outputs.ijar]
365-
compile_jars += target.scala.transitive_compile_exports
366-
runtime_jars += target.scala.transitive_runtime_deps
367-
runtime_jars += target.scala.transitive_runtime_exports
368-
found = True
369-
if hasattr(target, "java"):
370-
# see JavaSkylarkApiProvider.java,
371-
# this is just the compile-time deps
372-
# this should be improved in bazel 0.1.5 to get outputs.ijar
373-
# compile_jars += [output.ijar for output in target.java.outputs.jars]
374-
compile_jars += target.java.transitive_deps
375-
runtime_jars += target.java.transitive_runtime_deps
376-
found = True
377-
if not found:
360+
if java_common.provider in target:
361+
java_provider = target[java_common.provider]
362+
compile_jars += java_provider.compile_jars
363+
runtime_jars += java_provider.transitive_runtime_jars
364+
else:
378365
# support http_file pointed at a jar. http_jar uses ijar,
379366
# which breaks scala macros
380-
runtime_jars += target.files
381367
compile_jars += target.files
368+
runtime_jars += target.files
382369

383-
return struct(compiletime = compile_jars, runtime = runtime_jars)
370+
return struct(compile_jars = compile_jars, transitive_runtime_jars = runtime_jars)
384371

385372
# Extract very common code out from dependency analysis into single place
386373
# automatically adds dependency on scala-library and scala-reflect
@@ -389,42 +376,67 @@ def _collect_jars_from_common_ctx(ctx, extra_deps = [], extra_runtime_deps = [])
389376
# Get jars from deps
390377
auto_deps = [ctx.attr._scalalib, ctx.attr._scalareflect]
391378
deps_jars = _collect_jars(ctx.attr.deps + auto_deps + extra_deps)
392-
(cjars, rjars) = (deps_jars.compiletime, deps_jars.runtime)
393-
rjars += _collect_jars(ctx.attr.runtime_deps + extra_runtime_deps).runtime
394-
return struct(compiletime = cjars, runtime = rjars)
379+
(cjars, transitive_rjars) = (deps_jars.compile_jars, deps_jars.transitive_runtime_jars)
380+
transitive_rjars += _collect_jars(
381+
ctx.attr.runtime_deps + extra_runtime_deps).transitive_runtime_jars
382+
return struct(compile_jars = cjars, transitive_runtime_jars = transitive_rjars)
395383

396384
def _lib(ctx, non_macro_lib):
385+
# Build up information from dependency-like attributes
386+
397387
# This will be used to pick up srcjars from non-scala library
398388
# targets (like thrift code generation)
399389
srcjars = collect_srcjars(ctx.attr.deps)
400390
jars = _collect_jars_from_common_ctx(ctx)
401-
(cjars, rjars) = (jars.compiletime, jars.runtime)
391+
(cjars, transitive_rjars) = (jars.compile_jars, jars.transitive_runtime_jars)
402392

403393
write_manifest(ctx)
404394
outputs = _compile_or_empty(ctx, cjars, srcjars, non_macro_lib)
405395

406-
rjars += [ctx.outputs.jar]
396+
transitive_rjars += [ctx.outputs.jar]
407397

408-
_build_deployable(ctx, rjars)
409-
rule_outputs = struct(ijar=outputs.ijar, class_jar=outputs.class_jar, deploy_jar=ctx.outputs.deploy_jar)
398+
_build_deployable(ctx, transitive_rjars)
410399

411-
texp = _collect_jars(ctx.attr.exports)
412-
scalaattr = struct(outputs=rule_outputs,
413-
transitive_runtime_deps=rjars,
414-
transitive_compile_exports=texp.compiletime,
415-
transitive_runtime_exports=texp.runtime
416-
)
400+
# Now, need to setup providers for dependents
401+
# Notice that transitive_rjars just carries over from dependency analysis
402+
# but cjars 'resets' between cjars and next_cjars
403+
next_cjars = depset([outputs.ijar]) # use ijar, if available, for future compiles
417404

418-
# Note that rjars already transitive so don't really
419-
# need to use transitive_files with _get_all_runfiles
405+
# Using transitive_files since transitive_rjars a depset and avoiding linearization
420406
runfiles = ctx.runfiles(
421-
files=list(rjars),
422-
collect_data=True)
407+
transitive_files = transitive_rjars,
408+
collect_data = True,
409+
)
410+
411+
# Add information from exports (is key that AFTER all build actions/runfiles analysis)
412+
# Since after, will not show up in deploy_jar or old jars runfiles
413+
# Notice that compile_jars is intentionally transitive for exports
414+
exports_jars = _collect_jars(ctx.attr.exports)
415+
next_cjars += exports_jars.compile_jars
416+
transitive_rjars += exports_jars.transitive_runtime_jars
417+
418+
rule_outputs = struct(
419+
ijar = outputs.ijar,
420+
class_jar = outputs.class_jar,
421+
deploy_jar = ctx.outputs.deploy_jar,
422+
)
423+
# Note that, internally, rules only care about compile_jars and transitive_runtime_jars
424+
# in a similar manner as the java_library and JavaProvider
425+
scalaattr = struct(
426+
outputs = rule_outputs,
427+
compile_jars = next_cjars,
428+
transitive_runtime_jars = transitive_rjars,
429+
)
430+
java_provider = java_common.create_provider(
431+
compile_time_jars = scalaattr.compile_jars,
432+
runtime_jars = scalaattr.transitive_runtime_jars,
433+
)
423434

424435
return struct(
425-
files=set([ctx.outputs.jar]), # Here is the default output
426-
scala=scalaattr,
427-
runfiles=runfiles,
436+
files = depset([ctx.outputs.jar]), # Here is the default output
437+
scala = scalaattr,
438+
providers = [java_provider],
439+
runfiles = runfiles,
428440
# This is a free monoid given to the graph for the purpose of
429441
# extensibility. This is necessary when one wants to create
430442
# new targets which want to leverage a scala_library. For example,
@@ -470,39 +482,39 @@ def _scala_binary_common(ctx, cjars, rjars):
470482
class_jar=outputs.class_jar,
471483
deploy_jar=ctx.outputs.deploy_jar,
472484
)
473-
scalaattr = struct(outputs = rule_outputs,
474-
transitive_runtime_deps = rjars,
475-
transitive_compile_exports = set(),
476-
transitive_runtime_exports = set()
477-
)
485+
scalaattr = struct(
486+
outputs = rule_outputs,
487+
compile_jars = depset([outputs.class_jar]),
488+
transitive_runtime_jars = rjars,
489+
)
478490
return struct(
479491
files=set([ctx.outputs.executable]),
480492
scala = scalaattr,
481493
runfiles=runfiles)
482494

483495
def _scala_binary_impl(ctx):
484496
jars = _collect_jars_from_common_ctx(ctx)
485-
(cjars, rjars) = (jars.compiletime, jars.runtime)
486-
rjars += [ctx.outputs.jar]
497+
(cjars, transitive_rjars) = (jars.compile_jars, jars.transitive_runtime_jars)
498+
transitive_rjars += [ctx.outputs.jar]
487499

488500
_write_launcher(
489501
ctx = ctx,
490-
rjars = rjars,
502+
rjars = transitive_rjars,
491503
main_class = ctx.attr.main_class,
492504
jvm_flags = ctx.attr.jvm_flags,
493505
)
494-
return _scala_binary_common(ctx, cjars, rjars)
506+
return _scala_binary_common(ctx, cjars, transitive_rjars)
495507

496508
def _scala_repl_impl(ctx):
497509
# need scala-compiler for MainGenericRunner below
498510
jars = _collect_jars_from_common_ctx(ctx, extra_runtime_deps = [ctx.attr._scalacompiler])
499-
(cjars, rjars) = (jars.compiletime, jars.runtime)
500-
rjars += [ctx.outputs.jar]
511+
(cjars, transitive_rjars) = (jars.compile_jars, jars.transitive_runtime_jars)
512+
transitive_rjars += [ctx.outputs.jar]
501513

502514
args = " ".join(ctx.attr.scalacopts)
503515
_write_launcher(
504516
ctx = ctx,
505-
rjars = rjars,
517+
rjars = transitive_rjars,
506518
main_class = "scala.tools.nsc.MainGenericRunner",
507519
jvm_flags = ["-Dscala.usejavacp=true"] + ctx.attr.jvm_flags,
508520
args = args,
@@ -522,7 +534,7 @@ trap finish EXIT
522534
""",
523535
)
524536

525-
return _scala_binary_common(ctx, cjars, rjars)
537+
return _scala_binary_common(ctx, cjars, transitive_rjars)
526538

527539
def _scala_test_impl(ctx):
528540
if len(ctx.attr.suites) != 0:
@@ -532,14 +544,14 @@ def _scala_test_impl(ctx):
532544
jars = _collect_jars_from_common_ctx(ctx,
533545
extra_runtime_deps = [ctx.attr._scalatest_reporter, ctx.attr._scalatest_runner],
534546
)
535-
(cjars, rjars) = (jars.compiletime, jars.runtime)
547+
(cjars, transitive_rjars) = (jars.compile_jars, jars.transitive_runtime_jars)
536548
# _scalatest is an http_jar, so its compile jar is run through ijar
537549
# however, contains macros, so need to handle separately
538-
scalatest_jars = _collect_jars([ctx.attr._scalatest]).runtime
550+
scalatest_jars = _collect_jars([ctx.attr._scalatest]).transitive_runtime_jars
539551
cjars += scalatest_jars
540-
rjars += scalatest_jars
552+
transitive_rjars += scalatest_jars
541553

542-
rjars += [ctx.outputs.jar]
554+
transitive_rjars += [ctx.outputs.jar]
543555

544556
args = " ".join([
545557
"-R \"{path}\"".format(path=ctx.outputs.jar.short_path),
@@ -549,12 +561,12 @@ def _scala_test_impl(ctx):
549561
# main_class almost has to be "org.scalatest.tools.Runner" due to args....
550562
_write_launcher(
551563
ctx = ctx,
552-
rjars = rjars,
564+
rjars = transitive_rjars,
553565
main_class = ctx.attr.main_class,
554566
jvm_flags = ctx.attr.jvm_flags,
555567
args = args,
556568
)
557-
return _scala_binary_common(ctx, cjars, rjars)
569+
return _scala_binary_common(ctx, cjars, transitive_rjars)
558570

559571
def _gen_test_suite_flags_based_on_prefixes_and_suffixes(ctx, archive):
560572
return struct(testSuiteFlag = "-Dbazel.test_suite=io.bazel.rulesscala.test_discovery.DiscoveredTestSuite",
@@ -569,20 +581,20 @@ def _scala_junit_test_impl(ctx):
569581
jars = _collect_jars_from_common_ctx(ctx,
570582
extra_deps = [ctx.attr._junit, ctx.attr._hamcrest, ctx.attr._suite, ctx.attr._bazel_test_runner],
571583
)
572-
(cjars, rjars) = (jars.compiletime, jars.runtime)
584+
(cjars, transitive_rjars) = (jars.compile_jars, jars.transitive_runtime_jars)
573585

574-
rjars += [ctx.outputs.jar]
586+
transitive_rjars += [ctx.outputs.jar]
575587

576588
test_suite = _gen_test_suite_flags_based_on_prefixes_and_suffixes(ctx, ctx.outputs.jar)
577589
launcherJvmFlags = ["-ea", test_suite.archiveFlag, test_suite.prefixesFlag, test_suite.suffixesFlag, test_suite.printFlag, test_suite.testSuiteFlag]
578590
_write_launcher(
579591
ctx = ctx,
580-
rjars = rjars,
592+
rjars = transitive_rjars,
581593
main_class = "com.google.testing.junit.runner.BazelTestRunner",
582594
jvm_flags = launcherJvmFlags + ctx.attr.jvm_flags,
583595
)
584596

585-
return _scala_binary_common(ctx, cjars, rjars)
597+
return _scala_binary_common(ctx, cjars, transitive_rjars)
586598

587599
_launcher_template = {
588600
"_java_stub_template": attr.label(default=Label("@java_stub_template//file")),
@@ -786,18 +798,6 @@ def scala_repositories():
786798

787799
native.bind(name = "io_bazel_rules_scala/dependency/scalatest/scalatest", actual = "@scalatest//jar")
788800

789-
def scala_export_to_java(name, exports, runtime_deps):
790-
jars = []
791-
for target in exports:
792-
jars.append("{}_deploy.jar".format(target))
793-
794-
native.java_import(
795-
name = name,
796-
# these are the outputs of the scala_library targets
797-
jars = jars,
798-
runtime_deps = ["//external:io_bazel_rules_scala/dependency/scala/scala_library"] + runtime_deps
799-
)
800-
801801
def _sanitize_string_for_usage(s):
802802
res_array = []
803803
for c in s:

test/BUILD

Lines changed: 13 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ load("//scala:scala.bzl",
55
"scala_library",
66
"scala_test",
77
"scala_macro_library",
8-
"scala_export_to_java",
98
"scala_repl",
109
"scala_test_suite",
1110
"scala_library_suite",
@@ -19,41 +18,28 @@ java_binary(
1918
name = "JavaBinary",
2019
srcs = ["JavaBinary.java"],
2120
main_class = "scala.test.JavaBinary",
22-
deps = [":lib_import"],
23-
)
24-
25-
# TODO(bazel-team): Allow java rules to depend directly on scala_library.
26-
# For now, we have to use a java_import proxy.
27-
java_import(
28-
name = "lib_import",
29-
# these are the outputs of the scala_library targets
30-
jars = [
31-
":HelloLib_deploy.jar",
32-
"OtherLib_deploy.jar",
33-
"Exported_deploy.jar",
34-
"Runtime_deploy.jar",
21+
deps = [
22+
":HelloLib",
23+
":OtherLib",
24+
":Exported",
25+
":Runtime",
3526
],
3627
runtime_deps = [
37-
"OtherJavaLib",
28+
":OtherJavaLib",
3829
"@scala//:scala-library",
39-
],
40-
)
41-
42-
scala_export_to_java(
43-
name = "lib_import_2",
44-
exports = [":HelloLib",
45-
"OtherLib",
46-
"Exported",
47-
"Runtime",
48-
],
49-
runtime_deps = ["OtherJavaLib"],
30+
]
5031
)
5132

5233
java_binary(
5334
name = "JavaBinary2",
5435
srcs = ["JavaBinary.java"],
5536
main_class = "scala.test.JavaBinary",
56-
deps = [":lib_import_2"],
37+
deps = [
38+
":HelloLib",
39+
":OtherLib",
40+
":Exported",
41+
":Runtime",
42+
],
5743
)
5844

5945
scala_binary(

0 commit comments

Comments
 (0)