diff --git a/scala/jars_to_labels.bzl b/scala/jars_to_labels.bzl new file mode 100644 index 000000000..edde520e5 --- /dev/null +++ b/scala/jars_to_labels.bzl @@ -0,0 +1,3 @@ +JarsToLabelsInfo = provider(fields = [ + "jars_to_labels", # dict of path of a jar to a label +]) diff --git a/scala/private/common.bzl b/scala/private/common.bzl index e32a93f6d..cd4bd7b9c 100644 --- a/scala/private/common.bzl +++ b/scala/private/common.bzl @@ -1,3 +1,7 @@ +load("@io_bazel_rules_scala//scala:jars_to_labels.bzl", "JarsToLabelsInfo") + +_empty_jars2labels = JarsToLabelsInfo(jars_to_labels = {}) + def write_manifest(ctx): main_class = getattr(ctx.attr, "main_class", None) write_manifest_file(ctx.actions, ctx.outputs.manifest, main_class) @@ -42,7 +46,7 @@ def _collect_jars_when_dependency_analyzer_is_off(dep_targets): return struct( compile_jars = depset(transitive = compile_jars), transitive_runtime_jars = depset(transitive = runtime_jars), - jars2labels = {}, + jars2labels = _empty_jars2labels, transitive_compile_jars = depset()) def _collect_jars_when_dependency_analyzer_is_on(dep_targets): @@ -62,6 +66,7 @@ def _collect_jars_when_dependency_analyzer_is_on(dep_targets): compile_jars.append(current_dep_compile_jars) transitive_compile_jars.append(current_dep_transitive_compile_jars) + add_labels_of_jars_to(jars2labels, dep_target, current_dep_transitive_compile_jars.to_list(), current_dep_compile_jars.to_list()) @@ -71,7 +76,7 @@ def _collect_jars_when_dependency_analyzer_is_on(dep_targets): return struct( compile_jars = depset(transitive = compile_jars), transitive_runtime_jars = depset(transitive = runtime_jars), - jars2labels = jars2labels, + jars2labels = JarsToLabelsInfo(jars_to_labels = jars2labels), transitive_compile_jars = depset(transitive = transitive_compile_jars)) # When import mavan_jar's for scala macros we have to use the jar:file requirement @@ -91,33 +96,23 @@ def filter_not_sources(deps): def add_labels_of_jars_to(jars2labels, dependency, all_jars, direct_jars): for jar in direct_jars: - _add_label_of_direct_jar_to(jars2labels, dependency, jar) + jars2labels[jar.path] = dependency.label for jar in all_jars: - _add_label_of_indirect_jar_to(jars2labels, dependency, jar) - -def _add_label_of_direct_jar_to(jars2labels, dependency, jar): - jars2labels[jar.path] = dependency.label - -def _add_label_of_indirect_jar_to(jars2labels, dependency, jar): - if _label_already_exists(jars2labels, jar): - return - - # skylark exposes only labels of direct dependencies. - # to get labels of indirect dependencies we collect them from the providers transitively - if _provider_of_dependency_contains_label_of(dependency, jar): - jars2labels[jar.path] = dependency.jars_to_labels[jar.path] + path = jar.path + if path not in jars2labels: + # skylark exposes only labels of direct dependencies. + # to get labels of indirect dependencies we collect them from the providers transitively + label = _provider_of_dependency_label_of(dependency, path) + if label == None: + label = "Unknown label of file {jar_path} which came from {dependency_label}".format( + jar_path = path, dependency_label = dependency.label) + jars2labels[path] = label + +def _provider_of_dependency_label_of(dependency, path): + if JarsToLabelsInfo in dependency: + return dependency[JarsToLabelsInfo].jars_to_labels.get(path) else: - jars2labels[ - jar. - path] = "Unknown label of file {jar_path} which came from {dependency_label}".format( - jar_path = jar.path, dependency_label = dependency.label) - -def _label_already_exists(jars2labels, jar): - return jar.path in jars2labels - -def _provider_of_dependency_contains_label_of(dependency, jar): - return hasattr(dependency, - "jars_to_labels") and jar.path in dependency.jars_to_labels + return None # TODO this seems to have limited value now that JavaInfo has everything def create_java_provider(scalaattr, transitive_compile_time_jars): diff --git a/scala/private/rule_impls.bzl b/scala/private/rule_impls.bzl index 57be73ba9..b512e43ec 100644 --- a/scala/private/rule_impls.bzl +++ b/scala/private/rule_impls.bzl @@ -24,6 +24,7 @@ load( "not_sources_jar", "write_manifest", ) +load("@io_bazel_rules_scala//scala:jars_to_labels.bzl", "JarsToLabelsInfo") _java_extension = ".java" _scala_extension = ".scala" @@ -509,7 +510,7 @@ def _lib(ctx, non_macro_lib): write_manifest(ctx) outputs = _compile_or_empty(ctx, ctx.outputs.manifest, cjars, srcjars, non_macro_lib, jars.transitive_compile_jars, - jars.jars2labels, []) + jars.jars2labels.jars_to_labels, []) transitive_rjars = depset(outputs.full_jars, transitive = [transitive_rjars]) @@ -543,7 +544,7 @@ def _lib(ctx, non_macro_lib): return struct( files = depset([ctx.outputs.jar]), # Here is the default output scala = scalaattr, - providers = [java_provider], + providers = [java_provider, jars.jars2labels], runfiles = runfiles, jars_to_labels = jars.jars2labels, ) @@ -564,7 +565,8 @@ def _scala_binary_common(ctx, implicit_junit_deps_needed_for_java_compilation = []): write_manifest(ctx) outputs = _compile_or_empty(ctx, ctx.outputs.manifest, cjars, depset(), False, - transitive_compile_time_jars, jars2labels, + transitive_compile_time_jars, + jars2labels.jars_to_labels, implicit_junit_deps_needed_for_java_compilation ) # no need to build an ijar for an executable rjars = depset(outputs.full_jars, transitive = [rjars]) @@ -590,11 +592,10 @@ def _scala_binary_common(ctx, return struct( files = depset([ctx.outputs.executable, ctx.outputs.jar]), - providers = [java_provider], + providers = [java_provider, jars2labels], scala = scalaattr, transitive_rjars = rjars, #calling rules need this for the classpath in the launcher - jars_to_labels = jars2labels, runfiles = runfiles) def scala_binary_impl(ctx): @@ -683,8 +684,10 @@ def scala_test_impl(ctx): transitive_compile_jars = depset( transitive = [scalatest_jars, transitive_compile_jars]) scalatest_jars_list = scalatest_jars.to_list() - add_labels_of_jars_to(jars_to_labels, ctx.attr._scalatest, - scalatest_jars_list, scalatest_jars_list) + j2l = jars_to_labels.jars_to_labels + add_labels_of_jars_to(j2l, ctx.attr._scalatest, scalatest_jars_list, + scalatest_jars_list) + jars_to_labels = JarsToLabelsInfo(jars_to_labels = j2l) args = " ".join([ "-R \"{path}\"".format(path = ctx.outputs.jar.short_path), diff --git a/scala/scala_import.bzl b/scala/scala_import.bzl index ea0763e00..ffb0bab67 100644 --- a/scala/scala_import.bzl +++ b/scala/scala_import.bzl @@ -1,3 +1,5 @@ +load("@io_bazel_rules_scala//scala:jars_to_labels.bzl", "JarsToLabelsInfo") + #intellij part is tested manually, tread lightly when changing there #if you change make sure to manually re-import an intellij project and see imports #are resolved (not red) and clickable @@ -20,12 +22,12 @@ def _scala_import_impl(ctx): return struct( scala = struct(outputs = struct(jars = intellij_metadata), ), - jars_to_labels = jars2labels, providers = [ _create_provider(current_jars, transitive_runtime_jars, jars, exports, ctx.attr.neverlink), DefaultInfo(files = current_jars, ), + JarsToLabelsInfo(jars_to_labels = jars2labels), ], ) @@ -96,15 +98,12 @@ def _collect(deps): def _collect_labels(deps, jars2labels): for dep_target in deps: + if JarsToLabelsInfo in dep_target: + jars2labels.update(dep_target[JarsToLabelsInfo].jars_to_labels) + #scala_library doesn't add labels to the direct dependency itself java_provider = dep_target[JavaInfo] - _transitively_accumulate_labels(dep_target, java_provider, jars2labels) - -def _transitively_accumulate_labels(dep_target, java_provider, jars2labels): - if hasattr(dep_target, "jars_to_labels"): - jars2labels.update(dep_target.jars_to_labels) - #scala_library doesn't add labels to the direct dependency itself - for jar in java_provider.compile_jars.to_list(): - jars2labels[jar.path] = dep_target.label + for jar in java_provider.compile_jars.to_list(): + jars2labels[jar.path] = dep_target.label def _collect_runtime(runtime_deps): jar_deps = []