blob: beb0ecbc726071e235299c7d898246a4b7df3ddc [file]
"""Bespoke rules_testing subject for the Java compilation action"""
load("@rules_testing//lib:truth.bzl", "subjects", "truth")
load("@rules_testing//lib:util.bzl", "TestingAspectInfo")
def _new_javac_action_subject(env, target, output):
action_subject = env.expect.that_target(target).action_generating(output)
self = struct(
actual = action_subject.actual,
parsed_flags = _parse_flags(action_subject.actual.argv),
meta = truth.expect(env).meta.derive(
"Javac",
format_str_kwargs = {
"name": target.label.name,
"package": target.label.package,
"bin_path": target[TestingAspectInfo].bin_path,
},
),
)
public = struct(
direct_dependencies = lambda: _create_subject_for_flag("--direct_dependencies", self.parsed_flags, self.meta),
javacopts = lambda: _create_subject_for_flag("--javacopts", self.parsed_flags, self.meta),
jar = lambda: _create_subject_for_flag("-jar", self.parsed_flags, self.meta),
# An unset --strict_java_deps is equivalent to "OFF".
strict_java_deps = lambda: _create_subject_for_flag("--strict_java_deps", self.parsed_flags, self.meta, default = ["OFF"]),
sources = lambda: _create_subject_for_flag("--sources", self.parsed_flags, self.meta),
executable_file_name = lambda: subjects.str(action_subject.actual.argv[0], self.meta),
inputs = action_subject.inputs,
argv = action_subject.argv,
mnemonic = action_subject.mnemonic,
)
return public
def _parse_flags(argv):
flag_values = {}
current_flag_name = None
for idx, arg in enumerate(argv):
if idx == 0:
continue # java command
if current_flag_name == "--javacopts" and arg == "--":
current_flag_name = None
continue
if arg.startswith("-") and current_flag_name != "--javacopts":
if "=" in arg:
parts = arg.split("=", 1)
flag_values.setdefault(parts[0], []).append(parts[1])
current_flag_name = None
else:
flag_values.setdefault(arg, [])
current_flag_name = arg
else:
if not current_flag_name:
fail("No preceding flag for value:", arg, "at index:", idx, "\nargv:\n", argv)
flag_values[current_flag_name].append(arg)
return flag_values
def _create_subject_for_flag(flag_name, parsed_flags, meta, default = None):
"""Helper to create a collection subject for a given flag."""
return subjects.collection(parsed_flags.get(flag_name, default), meta.derive(flag_name), format = True)
javac_action_subject = struct(
of = _new_javac_action_subject,
parse_flags = _parse_flags, # exposed for testing this method itself
)