Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Separate coverage #972

Merged
merged 8 commits into from
Jan 31, 2020
Merged
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
69 changes: 2 additions & 67 deletions scala/private/phases/phase_compile.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,7 @@
#
# DOCUMENT THIS
#
load("@bazel_skylib//lib:dicts.bzl", "dicts")
load("@bazel_tools//tools/jdk:toolchain_utils.bzl", "find_java_runtime_toolchain", "find_java_toolchain")
load(
"@io_bazel_rules_scala//scala/private:coverage_replacements_provider.bzl",
_coverage_replacements_provider = "coverage_replacements_provider",
)
load(
"@io_bazel_rules_scala//scala/private:paths.bzl",
_get_files_with_extension = "get_files_with_extension",
Expand All @@ -23,13 +18,6 @@ load(
)
load(":resources.bzl", _resource_paths = "paths")

_empty_coverage_struct = struct(
external = struct(
replacements = {},
),
providers_dict = {},
)

def phase_compile_binary(ctx, p):
args = struct(
buildijar = False,
Expand Down Expand Up @@ -163,13 +151,12 @@ def _phase_compile(

# TODO: simplify the return values and use provider
return struct(
coverage = out.coverage.external,
files = depset(out.full_jars),
rjars = depset(out.full_jars, transitive = [rjars]),
merged_provider = out.merged_provider,
external_providers = dicts.add(out.coverage.providers_dict, {
external_providers = {
"JavaInfo": out.merged_provider,
}),
},
)

def _compile_or_empty(
Expand All @@ -193,7 +180,6 @@ def _compile_or_empty(

# no need to build ijar when empty
return struct(
coverage = _empty_coverage_struct,
full_jars = [ctx.outputs.jar],
merged_provider = scala_compilation_provider,
)
Expand Down Expand Up @@ -264,15 +250,12 @@ def _compile_or_empty(
if java_jar:
full_jars += [java_jar.jar]

coverage = _jacoco_offline_instrument(ctx, ctx.outputs.jar)

if java_jar:
merged_provider = java_common.merge([scala_compilation_provider, java_jar.java_compilation_provider])
else:
merged_provider = scala_compilation_provider

return struct(
coverage = coverage,
full_jars = full_jars,
merged_provider = merged_provider,
)
Expand Down Expand Up @@ -338,54 +321,6 @@ def _pack_source_jar(ctx, scala_srcs, in_srcjars):
host_javabase = find_java_runtime_toolchain(ctx, ctx.attr._host_javabase),
)

def _jacoco_offline_instrument(ctx, input_jar):
if not ctx.configuration.coverage_enabled or not hasattr(ctx.attr, "_code_coverage_instrumentation_worker"):
return _empty_coverage_struct

output_jar = ctx.actions.declare_file(
"{}-offline.jar".format(input_jar.basename.split(".")[0]),
)
in_out_pairs = [
(input_jar, output_jar),
]

args = ctx.actions.args()
args.add_all(in_out_pairs, map_each = _jacoco_offline_instrument_format_each)
args.set_param_file_format("multiline")
args.use_param_file("@%s", use_always = True)

ctx.actions.run(
mnemonic = "JacocoInstrumenter",
inputs = [in_out_pair[0] for in_out_pair in in_out_pairs],
outputs = [in_out_pair[1] for in_out_pair in in_out_pairs],
executable = ctx.attr._code_coverage_instrumentation_worker.files_to_run,
execution_requirements = {"supports-workers": "1"},
arguments = [args],
)

replacements = {i: o for (i, o) in in_out_pairs}
provider = _coverage_replacements_provider.create(
replacements = replacements,
)
instrumented_files_provider = coverage_common.instrumented_files_info(
ctx,
source_attributes = ["srcs"],
dependency_attributes = _coverage_replacements_provider.dependency_attributes,
extensions = ["scala", "java"],
)
return struct(
external = struct(
replacements = replacements,
),
providers_dict = {
"_CoverageReplacements": provider,
"InstrumentedFilesInfo": instrumented_files_provider,
},
)

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

def _try_to_compile_java_jar(
ctx,
scala_output,
Expand Down
76 changes: 76 additions & 0 deletions scala/private/phases/phase_coverage.bzl
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
#
# PHASE: coverage
#
# DOCUMENT THIS
#

load(
"@io_bazel_rules_scala//scala/private:coverage_replacements_provider.bzl",
_coverage_replacements_provider = "coverage_replacements_provider",
)

def phase_coverage_library(ctx, p):
args = struct(
srcjars = p.collect_srcjars,
)
return _phase_coverage_default(ctx, p, args)

def phase_coverage_common(ctx, p):
return _phase_coverage_default(ctx, p)

def _phase_coverage_default(ctx, p, _args = struct()):
return _phase_coverage(
ctx,
p,
_args.srcjars if hasattr(_args, "srcjars") else depset(),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this sounds like a bug in rules_scala that we don't support srcjars for binary rules.
In any case this is in no way a call for action on this PR. Just an observation.

)

def _phase_coverage(ctx, p, srcjars):
if len(ctx.files.srcs) + len(srcjars.to_list()) == 0 or not ctx.configuration.coverage_enabled:
return struct(
replacements = {},
external_providers = {},
)
else:
input_jar = ctx.outputs.jar
output_jar = ctx.actions.declare_file(
"{}-offline.jar".format(input_jar.basename.split(".")[0]),
)
in_out_pairs = [
(input_jar, output_jar),
]

args = ctx.actions.args()
args.add_all(in_out_pairs, map_each = _jacoco_offline_instrument_format_each)
args.set_param_file_format("multiline")
args.use_param_file("@%s", use_always = True)

ctx.actions.run(
mnemonic = "JacocoInstrumenter",
inputs = [in_out_pair[0] for in_out_pair in in_out_pairs],
outputs = [in_out_pair[1] for in_out_pair in in_out_pairs],
executable = ctx.attr._code_coverage_instrumentation_worker.files_to_run,
execution_requirements = {"supports-workers": "1"},
arguments = [args],
)

replacements = {i: o for (i, o) in in_out_pairs}
provider = _coverage_replacements_provider.create(
replacements = replacements,
)
instrumented_files_provider = coverage_common.instrumented_files_info(
ctx,
source_attributes = ["srcs"],
dependency_attributes = _coverage_replacements_provider.dependency_attributes,
extensions = ["scala", "java"],
)
return struct(
replacements = replacements,
external_providers = {
"_CoverageReplacements": provider,
"InstrumentedFilesInfo": instrumented_files_provider,
},
)

def _jacoco_offline_instrument_format_each(in_out_pair):
return (["%s=%s" % (in_out_pair[0].path, in_out_pair[1].path)])
2 changes: 1 addition & 1 deletion scala/private/phases/phase_coverage_runfiles.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ def phase_coverage_runfiles(ctx, p):
if ctx.configuration.coverage_enabled and _coverage_replacements_provider.is_enabled(ctx):
coverage_replacements = _coverage_replacements_provider.from_ctx(
ctx,
base = p.compile.coverage.replacements,
base = p.coverage.replacements,
).replacements

rjars = depset([
Expand Down
9 changes: 9 additions & 0 deletions scala/private/phases/phases.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,11 @@ load(
_phase_runfiles_library = "phase_runfiles_library",
_phase_runfiles_scalatest = "phase_runfiles_scalatest",
)
load(
"@io_bazel_rules_scala//scala/private:phases/phase_coverage.bzl",
_phase_coverage_common = "phase_coverage_common",
_phase_coverage_library = "phase_coverage_library",
)
load("@io_bazel_rules_scala//scala/private:phases/phase_default_info.bzl", _phase_default_info = "phase_default_info")
load("@io_bazel_rules_scala//scala/private:phases/phase_scalac_provider.bzl", _phase_scalac_provider = "phase_scalac_provider")
load("@io_bazel_rules_scala//scala/private:phases/phase_write_manifest.bzl", _phase_write_manifest = "phase_write_manifest")
Expand Down Expand Up @@ -85,6 +90,10 @@ phase_merge_jars = _phase_merge_jars
# jvm_flags
phase_jvm_flags = _phase_jvm_flags

# coverage
phase_coverage_library = _phase_coverage_library
phase_coverage_common = _phase_coverage_common

# coverage_runfiles
phase_coverage_runfiles = _phase_coverage_runfiles

Expand Down
4 changes: 0 additions & 4 deletions scala/private/rule_impls.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,6 @@
"""Rules for supporting the Scala language."""

load("@bazel_skylib//lib:paths.bzl", "paths")
load(
"@io_bazel_rules_scala//scala/private:coverage_replacements_provider.bzl",
_coverage_replacements_provider = "coverage_replacements_provider",
)
load(
":common.bzl",
_collect_plugin_paths = "collect_plugin_paths",
Expand Down
2 changes: 2 additions & 0 deletions scala/private/rules/scala_binary.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ load(
"extras_phases",
"phase_collect_jars_common",
"phase_compile_binary",
"phase_coverage_common",
"phase_declare_executable",
"phase_default_info",
"phase_java_wrapper_common",
Expand All @@ -39,6 +40,7 @@ def _scala_binary_impl(ctx):
("declare_executable", phase_declare_executable),
# no need to build an ijar for an executable
("compile", phase_compile_binary),
("coverage", phase_coverage_common),
("merge_jars", phase_merge_jars),
("runfiles", phase_runfiles_common),
("write_executable", phase_write_executable_common),
Expand Down
2 changes: 2 additions & 0 deletions scala/private/rules/scala_junit_test.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ load(
"extras_phases",
"phase_collect_jars_junit_test",
"phase_compile_junit_test",
"phase_coverage_common",
"phase_declare_executable",
"phase_default_info",
"phase_java_wrapper_common",
Expand Down Expand Up @@ -43,6 +44,7 @@ def _scala_junit_test_impl(ctx):
("declare_executable", phase_declare_executable),
# no need to build an ijar for an executable
("compile", phase_compile_junit_test),
("coverage", phase_coverage_common),
("merge_jars", phase_merge_jars),
("runfiles", phase_runfiles_common),
("jvm_flags", phase_jvm_flags),
Expand Down
4 changes: 4 additions & 0 deletions scala/private/rules/scala_library.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ load(
"phase_compile_library",
"phase_compile_library_for_plugin_bootstrapping",
"phase_compile_macro_library",
"phase_coverage_common",
"phase_coverage_library",
"phase_default_info",
"phase_merge_jars",
"phase_runfiles_library",
Expand Down Expand Up @@ -63,6 +65,7 @@ def _scala_library_impl(ctx):
("unused_deps_checker", phase_unused_deps_checker),
("collect_jars", phase_collect_jars_common),
("compile", phase_compile_library),
("coverage", phase_coverage_library),
("merge_jars", phase_merge_jars),
("runfiles", phase_runfiles_library),
("collect_exports_jars", phase_collect_exports_jars),
Expand Down Expand Up @@ -194,6 +197,7 @@ def _scala_macro_library_impl(ctx):
("unused_deps_checker", phase_unused_deps_checker),
("collect_jars", phase_collect_jars_macro_library),
("compile", phase_compile_macro_library),
("coverage", phase_coverage_common),
("merge_jars", phase_merge_jars),
("runfiles", phase_runfiles_library),
("collect_exports_jars", phase_collect_exports_jars),
Expand Down
2 changes: 2 additions & 0 deletions scala/private/rules/scala_repl.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ load(
"extras_phases",
"phase_collect_jars_repl",
"phase_compile_repl",
"phase_coverage_common",
"phase_declare_executable",
"phase_default_info",
"phase_java_wrapper_repl",
Expand All @@ -40,6 +41,7 @@ def _scala_repl_impl(ctx):
("declare_executable", phase_declare_executable),
# no need to build an ijar for an executable
("compile", phase_compile_repl),
("coverage", phase_coverage_common),
("merge_jars", phase_merge_jars),
("runfiles", phase_runfiles_common),
("write_executable", phase_write_executable_repl),
Expand Down
2 changes: 2 additions & 0 deletions scala/private/rules/scala_test.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ load(
"extras_phases",
"phase_collect_jars_scalatest",
"phase_compile_scalatest",
"phase_coverage_common",
"phase_coverage_runfiles",
"phase_declare_executable",
"phase_default_info",
Expand All @@ -40,6 +41,7 @@ def _scala_test_impl(ctx):
("declare_executable", phase_declare_executable),
# no need to build an ijar for an executable
("compile", phase_compile_scalatest),
("coverage", phase_coverage_common),
("merge_jars", phase_merge_jars),
("runfiles", phase_runfiles_scalatest),
("coverage_runfiles", phase_coverage_runfiles),
Expand Down