From d923f21fab51fd759ced190f1f2ec1d26680420a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?= Date: Tue, 25 Jan 2022 14:52:19 +0000 Subject: [PATCH] WIP: rules/python: Add PYTHON_COVERAGE_TARGET This resolves #14436 by adding a new environment variable that will perform the coverage label resolution inside the python_stub_template directly, which resolves the python coverage tool by label rather than path. Currently this resolves the path in the runfiles directory by guessing the path the label should resolve to - this of course does not work in general, even just defining an alias breaks it. Since labels appear to only be resolved in the analysis phase, there does not seem to be an easy way around this, however. This is a draft, showing the behavior I would like - suggestions on how to correctly implement this would be appreciated. Co-authored-by: Bradley Burns --- .../bazel/rules/python/python_stub_template.txt | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/google/devtools/build/lib/bazel/rules/python/python_stub_template.txt b/src/main/java/com/google/devtools/build/lib/bazel/rules/python/python_stub_template.txt index 1bc9e295d62c2b..eb59c65305da94 100644 --- a/src/main/java/com/google/devtools/build/lib/bazel/rules/python/python_stub_template.txt +++ b/src/main/java/com/google/devtools/build/lib/bazel/rules/python/python_stub_template.txt @@ -281,6 +281,17 @@ def Deduplicate(items): seen.add(it) yield it +def target_to_filepath(build_target, module_space): + # TODO (tlater): Find a way to properly resolve this at execution + # time, rather than relying on label syntax matching up to a + # specific location in runfiles. + build_target = build_target.replace("@","/") + build_target = build_target.replace("//","/") + build_target = build_target.replace(":", "/") + + coverage_entry_point = f"{module_space}{build_target}.py" + return coverage_entry_point + def ExecuteFile(python_program, main_filename, args, env, module_space, coverage_tool=None, workspace=None): """Executes the given python file using the various environment settings. @@ -400,12 +411,14 @@ def Main(): # COVERAGE_DIR is set iff the instrumentation is configured for the # file and coverage is enabled. if os.environ.get('COVERAGE_DIR'): - if 'PYTHON_COVERAGE' in os.environ: + if 'PYTHON_COVERAGE_TARGET' in os.environ: + cov_tool = target_to_filepath(os.environ.get('PYTHON_COVERAGE_TARGET'), module_space) + elif 'PYTHON_COVERAGE' in os.environ: cov_tool = os.environ.get('PYTHON_COVERAGE') else: raise EnvironmentError( 'No python coverage tool set, ' - 'set PYTHON_COVERAGE ' + 'set PYTHON_COVERAGE or PYTHON_COVERAGE_TARGET ' 'to configure the coverage tool' )