Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
177 changes: 112 additions & 65 deletions scala/private/rule_impls.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -590,74 +590,97 @@ def _jar_path_based_on_java_bin(ctx):
jar_path = java_bin.rpartition("/")[0] + "/jar"
return jar_path

def _write_executable(ctx, rjars, main_class, jvm_flags, wrapper, use_jacoco):
template = ctx.attr._java_stub_template.files.to_list()[0]

jvm_flags = " ".join(
[ctx.expand_location(f, ctx.attr.data) for f in jvm_flags],
)

javabin = "export REAL_EXTERNAL_JAVA_BIN=${JAVABIN};JAVABIN=%s/%s" % (
_runfiles_root(ctx),
wrapper.short_path,
)

if use_jacoco and _coverage_replacements_provider.is_enabled(ctx):
classpath = ":".join(
["${RUNPATH}%s" % (j.short_path) for j in rjars.to_list() + ctx.files._jacocorunner + ctx.files._lcov_merger],
)
jacoco_metadata_file = ctx.actions.declare_file(
"%s.jacoco_metadata.txt" % ctx.attr.name,
sibling = ctx.outputs.executable,
def _write_executable(ctx, executable, rjars, main_class, jvm_flags, wrapper, use_jacoco):
if (_is_windows(ctx)):
classpath = ";".join(
[("external/%s" % (j.short_path[3:]) if j.short_path.startswith("../") else j.short_path) for j in rjars.to_list()],
)
ctx.actions.write(jacoco_metadata_file, "\n".join([
jar.short_path.replace("../", "external/")
for jar in rjars
]))
ctx.actions.expand_template(
template = template,
output = ctx.outputs.executable,
substitutions = {
"%classpath%": classpath,
"%javabin%": javabin,
"%jarbin%": _jar_path_based_on_java_bin(ctx),
"%jvm_flags%": jvm_flags,
"%needs_runfiles%": "",
"%runfiles_manifest_only%": "",
"%workspace_prefix%": ctx.workspace_name + "/",
"%java_start_class%": "com.google.testing.coverage.JacocoCoverageRunner",
"%set_jacoco_metadata%": "export JACOCO_METADATA_JAR=\"$JAVA_RUNFILES/{}/{}\"".format(ctx.workspace_name, jacoco_metadata_file.short_path),
"%set_jacoco_main_class%": """export JACOCO_MAIN_CLASS={}""".format(main_class),
"%set_jacoco_java_runfiles_root%": """export JACOCO_JAVA_RUNFILES_ROOT=$JAVA_RUNFILES/{}/""".format(ctx.workspace_name),
},
is_executable = True,
jvm_flags_str = ";".join(jvm_flags)
java_for_exe = "%s/%s" % (ctx.workspace_name, str(ctx.attr._java_runtime[java_common.JavaRuntimeInfo].java_executable_exec_path))

ctx.actions.run(
outputs = [executable],
inputs = [],
executable = ctx.attr._exe.files_to_run.executable,
arguments = [executable.path, ctx.workspace_name, java_for_exe, main_class, classpath, jvm_flags_str],
mnemonic = "ExeLauncher",
progress_message = "Creating exe launcher",
)
return [jacoco_metadata_file]
return []
else:
# RUNPATH is defined here:
# https://github.com/bazelbuild/bazel/blob/0.4.5/src/main/java/com/google/devtools/build/lib/bazel/rules/java/java_stub_template.txt#L227
classpath = ":".join(
["${RUNPATH}%s" % (j.short_path) for j in rjars.to_list()],
template = ctx.attr._java_stub_template.files.to_list()[0]

jvm_flags = " ".join(
[ctx.expand_location(f, ctx.attr.data) for f in jvm_flags],
)
ctx.actions.expand_template(
template = template,
output = ctx.outputs.executable,
substitutions = {
"%classpath%": classpath,
"%java_start_class%": main_class,
"%javabin%": javabin,
"%jarbin%": _jar_path_based_on_java_bin(ctx),
"%jvm_flags%": jvm_flags,
"%needs_runfiles%": "",
"%runfiles_manifest_only%": "",
"%set_jacoco_metadata%": "",
"%set_jacoco_main_class%": "",
"%set_jacoco_java_runfiles_root%": "",
"%workspace_prefix%": ctx.workspace_name + "/",
},
is_executable = True,

javabin = "export REAL_EXTERNAL_JAVA_BIN=${JAVABIN};JAVABIN=%s/%s" % (
_runfiles_root(ctx),
wrapper.short_path,
)
return []

if use_jacoco and _coverage_replacements_provider.is_enabled(ctx):
classpath = ":".join(
["${RUNPATH}%s" % (j.short_path) for j in rjars.to_list() + ctx.files._jacocorunner + ctx.files._lcov_merger],
)
jacoco_metadata_file = ctx.actions.declare_file(
"%s.jacoco_metadata.txt" % ctx.attr.name,
sibling = executable,
)
ctx.actions.write(jacoco_metadata_file, "\n".join([
jar.short_path.replace("../", "external/")
for jar in rjars
]))
ctx.actions.expand_template(
template = template,
output = executable,
substitutions = {
"%classpath%": classpath,
"%javabin%": javabin,
"%jarbin%": _jar_path_based_on_java_bin(ctx),
"%jvm_flags%": jvm_flags,
"%needs_runfiles%": "",
"%runfiles_manifest_only%": "",
"%workspace_prefix%": ctx.workspace_name + "/",
"%java_start_class%": "com.google.testing.coverage.JacocoCoverageRunner",
"%set_jacoco_metadata%": "export JACOCO_METADATA_JAR=\"$JAVA_RUNFILES/{}/{}\"".format(ctx.workspace_name, jacoco_metadata_file.short_path),
"%set_jacoco_main_class%": """export JACOCO_MAIN_CLASS={}""".format(main_class),
"%set_jacoco_java_runfiles_root%": """export JACOCO_JAVA_RUNFILES_ROOT=$JAVA_RUNFILES/{}/""".format(ctx.workspace_name),
},
is_executable = True,
)
return [jacoco_metadata_file]
else:
# RUNPATH is defined here:
# https://github.com/bazelbuild/bazel/blob/0.4.5/src/main/java/com/google/devtools/build/lib/bazel/rules/java/java_stub_template.txt#L227
classpath = ":".join(
["${RUNPATH}%s" % (j.short_path) for j in rjars.to_list()],
)
ctx.actions.expand_template(
template = template,
output = executable,
substitutions = {
"%classpath%": classpath,
"%java_start_class%": main_class,
"%javabin%": javabin,
"%jarbin%": _jar_path_based_on_java_bin(ctx),
"%jvm_flags%": jvm_flags,
"%needs_runfiles%": "",
"%runfiles_manifest_only%": "",
"%set_jacoco_metadata%": "",
"%set_jacoco_main_class%": "",
"%set_jacoco_java_runfiles_root%": "",
"%workspace_prefix%": ctx.workspace_name + "/",
},
is_executable = True,
)
return []

def _declare_executable(ctx):
if (_is_windows(ctx)):
return ctx.actions.declare_file("%s.exe" % ctx.label.name)
else:
return ctx.actions.declare_file(ctx.label.name)

def _collect_runtime_jars(dep_targets):
runtime_jars = []
Expand Down Expand Up @@ -848,6 +871,7 @@ def scala_macro_library_impl(ctx):
# Common code shared by all scala binary implementations.
def _scala_binary_common(
ctx,
executable,
cjars,
rjars,
transitive_compile_time_jars,
Expand Down Expand Up @@ -876,7 +900,7 @@ def _scala_binary_common(

runfiles = ctx.runfiles(
transitive_files = depset(
[ctx.outputs.executable, java_wrapper] + ctx.files._java_runtime,
[executable, java_wrapper] + ctx.files._java_runtime,
transitive = [rjars],
),
collect_data = True,
Expand All @@ -898,8 +922,9 @@ def _scala_binary_common(
java_provider = create_java_provider(scalaattr, transitive_compile_time_jars)

return struct(
executable = executable,
coverage = outputs.coverage,
files = depset([ctx.outputs.executable, ctx.outputs.jar]),
files = depset([executable, ctx.outputs.jar]),
instrumented_files = outputs.coverage.instrumented_files,
providers = [java_provider, jars2labels] + outputs.coverage.providers,
runfiles = runfiles,
Expand Down Expand Up @@ -950,8 +975,12 @@ def scala_binary_impl(ctx):
(cjars, transitive_rjars) = (jars.compile_jars, jars.transitive_runtime_jars)

wrapper = _write_java_wrapper(ctx, "", "")

executable = _declare_executable(ctx)

out = _scala_binary_common(
ctx,
executable,
cjars,
transitive_rjars,
jars.transitive_compile_jars,
Expand All @@ -966,6 +995,7 @@ def scala_binary_impl(ctx):
)
_write_executable(
ctx = ctx,
executable = executable,
jvm_flags = ctx.attr.jvm_flags,
main_class = ctx.attr.main_class,
rjars = out.transitive_rjars,
Expand All @@ -989,6 +1019,9 @@ def scala_repl_impl(ctx):
(cjars, transitive_rjars) = (jars.compile_jars, jars.transitive_runtime_jars)

args = " ".join(ctx.attr.scalacopts)

executable = _declare_executable(ctx)

wrapper = _write_java_wrapper(
ctx,
args,
Expand All @@ -1010,6 +1043,7 @@ trap finish EXIT

out = _scala_binary_common(
ctx,
executable,
cjars,
transitive_rjars,
jars.transitive_compile_jars,
Expand All @@ -1024,6 +1058,7 @@ trap finish EXIT
)
_write_executable(
ctx = ctx,
executable = executable,
jvm_flags = ["-Dscala.usejavacp=true"] + ctx.attr.jvm_flags,
main_class = "scala.tools.nsc.MainGenericRunner",
rjars = out.transitive_rjars,
Expand Down Expand Up @@ -1086,10 +1121,13 @@ def scala_test_impl(ctx):
"-C io.bazel.rules.scala.JUnitXmlReporter ",
])

executable = _declare_executable(ctx)

# main_class almost has to be "org.scalatest.tools.Runner" due to args....
wrapper = _write_java_wrapper(ctx, args, "")
out = _scala_binary_common(
ctx,
executable,
cjars,
transitive_rjars,
transitive_compile_jars,
Expand Down Expand Up @@ -1117,6 +1155,7 @@ def scala_test_impl(ctx):

coverage_runfiles.extend(_write_executable(
ctx = ctx,
executable = executable,
jvm_flags = ctx.attr.jvm_flags,
main_class = ctx.attr.main_class,
rjars = rjars,
Expand All @@ -1125,6 +1164,7 @@ def scala_test_impl(ctx):
))

return struct(
executable = executable,
files = out.files,
instrumented_files = out.instrumented_files,
providers = out.providers,
Expand Down Expand Up @@ -1202,9 +1242,12 @@ def scala_junit_test_impl(ctx):
ctx.attr._hamcrest,
]

executable = _declare_executable(ctx)

wrapper = _write_java_wrapper(ctx, "", "")
out = _scala_binary_common(
ctx,
executable,
cjars,
transitive_rjars,
jars.transitive_compile_jars,
Expand Down Expand Up @@ -1237,6 +1280,7 @@ def scala_junit_test_impl(ctx):
]
_write_executable(
ctx = ctx,
executable = executable,
jvm_flags = launcherJvmFlags + ctx.attr.jvm_flags,
main_class = "com.google.testing.junit.runner.BazelTestRunner",
rjars = out.transitive_rjars,
Expand Down Expand Up @@ -1293,3 +1337,6 @@ def _jacoco_offline_instrument(ctx, input_jar):

def _jacoco_offline_instrument_format_each(in_out_pair):
return (["%s=%s" % (in_out_pair[0].path, in_out_pair[1].path)])

def _is_windows(ctx):
return ctx.configuration.host_path_separator == ";"
20 changes: 19 additions & 1 deletion scala/scala.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,11 @@ _implicit_deps = {
"@io_bazel_rules_scala//src/java/io/bazel/rulesscala/scalac",
),
),
"_exe": attr.label(
executable = True,
cfg = "host",
default = Label("@io_bazel_rules_scala//src/java/io/bazel/rulesscala/exe:exe"),
),
}

# Single dep to allow IDEs to pickup all the implicit dependencies.
Expand Down Expand Up @@ -472,6 +477,14 @@ def scala_repositories(
server_urls = maven_servers,
)

_scala_maven_import_external(
name = "io_bazel_rules_scala_guava",
artifact = "com.google.guava:guava:21.0",
jar_sha256 = "972139718abc8a4893fa78cba8cf7b2c903f35c97aaf44fa3031b0669948b480",
licenses = ["notice"],
server_urls = maven_servers,
)

_scala_maven_import_external(
name = "io_bazel_rules_scala_org_jacoco_org_jacoco_core",
artifact = "org.jacoco:org.jacoco.core:0.7.5.201505241946",
Expand All @@ -487,7 +500,7 @@ def scala_repositories(
licenses = ["notice"],
server_urls = maven_servers,
)

# Using this and not the bazel regular one due to issue when classpath is too long
# until https://github.com/bazelbuild/bazel/issues/6955 is resolved
if native.existing_rule("java_stub_template") == None:
Expand Down Expand Up @@ -538,6 +551,11 @@ def scala_repositories(
actual = "@io_bazel_rules_scala_scala_parser_combinators",
)

native.bind(
name = "io_bazel_rules_scala/dependency/scala/guava",
actual = "@io_bazel_rules_scala_guava",
)

def _sanitize_string_for_usage(s):
res_array = []
for idx in range(len(s)):
Expand Down
24 changes: 24 additions & 0 deletions src/java/io/bazel/rulesscala/exe/BUILD
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
java_library(
name = "exe-lib",
srcs = [
"LauncherFileWriter.java",
"LaunchInfo.java",
],
deps = [
"@bazel_tools//tools/java/runfiles:runfiles",
"//external:io_bazel_rules_scala/dependency/scala/guava",
],
visibility = ["//visibility:public"],
)

java_binary(
name = "exe",
main_class = "io.bazel.rulesscala.exe.LauncherFileWriter",
visibility = ["//visibility:public"],
runtime_deps = [
":exe-lib",
],
data = [
"@bazel_tools//tools/launcher:launcher",
],
)
Loading