Skip to content

Commit c7a142b

Browse files
committed
POC
1 parent 1f45950 commit c7a142b

14 files changed

+117
-93
lines changed

examples/bzlmod/.coveragerc

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
[report]
2+
include_namespace_packages=True
3+
skip_covered = True
4+
[run]
5+
relative_files = True
6+
branch = True

examples/bzlmod/BUILD.bazel

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@ build_test(
8787

8888
my_cool_toolchain(
8989
name = "cool_prod_linux_runner",
90+
coverage_rc = ".coveragerc",
9091
)
9192

9293
toolchain(

examples/bzlmod/MODULE.bazel

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,10 @@ python.toolchain(
3636
configure_coverage_tool = True,
3737
python_version = "3.10",
3838
)
39+
python.converage(
40+
name = "coverage",
41+
coveragerc = "coverage.rc",
42+
)
3943

4044
# You only need to load this repositories if you are using multiple Python versions.
4145
# See the tests folder for various examples on using multiple Python versions.

examples/bzlmod/test_toolchain.bzl

Lines changed: 0 additions & 54 deletions
This file was deleted.

python/BUILD.bazel

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -342,6 +342,6 @@ current_py_toolchain(
342342
)
343343

344344
toolchain_type(
345-
name = "test_runner_toolchain_type",
345+
name = "py_test_toolchain_type",
346346
visibility = ["//visibility:public"],
347347
)

python/private/common/py_binary_rule_bazel.bzl

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,12 +39,11 @@ _PY_TEST_ATTRS = {
3939
}
4040

4141
def _py_binary_impl(ctx):
42-
_, providers = py_executable_bazel_impl(
42+
return py_executable_bazel_impl(
4343
ctx = ctx,
4444
is_test = False,
4545
inherited_environment = [],
4646
)
47-
return providers
4847

4948
py_binary = create_executable_rule(
5049
implementation = _py_binary_impl,

python/private/common/py_executable.bzl

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,7 @@ Valid values are:
140140
allow_none = True,
141141
)
142142

143-
def py_executable_base_impl(ctx, *, semantics, is_test, inherited_environment = []):
143+
def py_executable_base_impl(ctx, *, semantics, is_test, inherited_environment = [], coverage_rc):
144144
"""Base rule implementation for a Python executable.
145145
146146
Google and Bazel call this common base and apply customizations using the
@@ -246,6 +246,7 @@ def py_executable_base_impl(ctx, *, semantics, is_test, inherited_environment =
246246
inherited_environment = inherited_environment,
247247
semantics = semantics,
248248
output_groups = exec_result.output_groups,
249+
coverage_rc = coverage_rc,
249250
)
250251

251252
def _get_build_info(ctx, cc_toolchain):
@@ -789,6 +790,7 @@ def _create_providers(
789790
inherited_environment,
790791
runtime_details,
791792
output_groups,
793+
coverage_rc,
792794
semantics):
793795
"""Creates the providers an executable should return.
794796
@@ -816,29 +818,26 @@ def _create_providers(
816818
Returns:
817819
A list of modern providers.
818820
"""
819-
default_runfiles = _py_builtins.make_runfiles_respect_legacy_external_runfiles(
820-
ctx,
821-
runfiles_details.default_runfiles,
822-
)
823-
data_runfiles = _py_builtins.make_runfiles_respect_legacy_external_runfiles(
824-
ctx,
825-
runfiles_details.data_runfiles,
826-
)
827-
binary_info = struct(
828-
files = default_outputs,
829-
default_runfiles = default_runfiles,
830-
data_runfiles = data_runfiles,
831-
executable = executable,
832-
)
821+
if coverage_rc:
822+
extra_test_env = {"COVERAGE_RC": coverage_rc.files.to_list()[0].path}
823+
default_runfiles = default_runfiles.merge(ctx.runfiles(files = coverage_rc.files.to_list()))
824+
else:
825+
extra_test_env = {}
833826
providers = [
834827
DefaultInfo(
835828
executable = executable,
836829
files = default_outputs,
837-
default_runfiles = default_runfiles,
838-
data_runfiles = data_runfiles,
830+
default_runfiles = _py_builtins.make_runfiles_respect_legacy_external_runfiles(
831+
ctx,
832+
runfiles_details.default_runfiles,
833+
),
834+
data_runfiles = _py_builtins.make_runfiles_respect_legacy_external_runfiles(
835+
ctx,
836+
runfiles_details.data_runfiles,
837+
),
839838
),
840839
create_instrumented_files_info(ctx),
841-
_create_run_environment_info(ctx, inherited_environment),
840+
_create_run_environment_info(ctx, inherited_environment, extra_test_env),
842841
PyExecutableInfo(
843842
main = main_py,
844843
runfiles_without_exe = runfiles_details.runfiles_without_exe,
@@ -905,9 +904,9 @@ def _create_providers(
905904
runtime_details = runtime_details,
906905
)
907906
providers.extend(extra_providers)
908-
return binary_info, providers
907+
return providers
909908

910-
def _create_run_environment_info(ctx, inherited_environment):
909+
def _create_run_environment_info(ctx, inherited_environment, extra_test_env):
911910
expanded_env = {}
912911
for key, value in ctx.attr.env.items():
913912
expanded_env[key] = _py_builtins.expand_location_and_make_variables(
@@ -916,6 +915,7 @@ def _create_run_environment_info(ctx, inherited_environment):
916915
expression = value,
917916
targets = ctx.attr.data,
918917
)
918+
expanded_env.update(extra_test_env)
919919
return RunEnvironmentInfo(
920920
environment = expanded_env,
921921
inherited_environment = inherited_environment,

python/private/common/py_executable_bazel.bzl

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,13 +101,14 @@ def create_executable_rule(*, attrs, **kwargs):
101101
**kwargs
102102
)
103103

104-
def py_executable_bazel_impl(ctx, *, is_test, inherited_environment):
104+
def py_executable_bazel_impl(ctx, *, is_test, inherited_environment, coverage_rc = None):
105105
"""Common code for executables for Bazel."""
106106
return py_executable_base_impl(
107107
ctx = ctx,
108108
semantics = create_binary_semantics_bazel(),
109109
is_test = is_test,
110110
inherited_environment = inherited_environment,
111+
coverage_rc = coverage_rc,
111112
)
112113

113114
def create_binary_semantics_bazel():

python/private/common/py_test_rule_bazel.bzl

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,12 @@
1616
load("@bazel_skylib//lib:dicts.bzl", "dicts")
1717
load(":attributes.bzl", "AGNOSTIC_TEST_ATTRS")
1818
load(":common.bzl", "maybe_add_test_execution_info")
19-
load("//python/private:py_executable_info.bzl", "PyExecutableInfo")
2019
load(
2120
":py_executable_bazel.bzl",
2221
"create_executable_rule",
2322
"py_executable_bazel_impl",
2423
)
24+
load("//python/private:toolchain_types.bzl", "PY_TEST_TOOLCHAIN_TYPE")
2525

2626
_BAZEL_PY_TEST_ATTRS = {
2727
# This *might* be a magic attribute to help C++ coverage work. There's no
@@ -39,28 +39,28 @@ _BAZEL_PY_TEST_ATTRS = {
3939
executable = True,
4040
),
4141
}
42-
_PY_TEST_TOOLCHAIN_TYPE = "@rules_python//python:test_runner_toolchain_type"
4342

4443
def _py_test_impl(ctx):
45-
binary_info, providers = py_executable_bazel_impl(
44+
py_test_toolchain = ctx.exec_groups["test"].toolchains[PY_TEST_TOOLCHAIN_TYPE]
45+
if py_test_toolchain:
46+
coverage_rc = py_test_toolchain.py_test_info.coverage_rc
47+
else:
48+
coverage_rc = None
49+
providers = py_executable_bazel_impl(
4650
ctx = ctx,
4751
is_test = True,
4852
inherited_environment = ctx.attr.env_inherit,
53+
coverage_rc = coverage_rc,
4954
)
5055
maybe_add_test_execution_info(providers, ctx)
51-
py_test_toolchain = ctx.exec_groups["test"].toolchains[_PY_TEST_TOOLCHAIN_TYPE]
52-
if not py_test_toolchain:
53-
return providers
54-
_ = providers.pop(0)
55-
test_providers = py_test_toolchain.py_test_info.get_runner.func(ctx, binary_info)
56-
providers.extend(test_providers)
56+
5757
return providers
5858

5959
py_test = create_executable_rule(
6060
implementation = _py_test_impl,
6161
attrs = dicts.add(AGNOSTIC_TEST_ATTRS, _BAZEL_PY_TEST_ATTRS),
6262
test = True,
6363
exec_groups = {
64-
"test": exec_group(toolchains = [config_common.toolchain_type(_PY_TEST_TOOLCHAIN_TYPE, mandatory = False)]),
64+
"test": exec_group(toolchains = [config_common.toolchain_type(PY_TEST_TOOLCHAIN_TYPE, mandatory = False)]),
6565
},
6666
)

python/private/py_test_toolchain.bzl

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
"""
2+
Simple toolchain which overrides env and exec requirements.
3+
"""
4+
5+
PytestProvider = provider(
6+
fields = [
7+
"coverage_rc",
8+
],
9+
)
10+
11+
def _py_test_toolchain_impl(ctx):
12+
return [
13+
platform_common.ToolchainInfo(
14+
py_test_info = PytestProvider(
15+
coverage_rc = ctx.attr.coverage_rc,
16+
),
17+
),
18+
]
19+
20+
py_test_toolchain = rule(
21+
implementation = _py_test_toolchain_impl,
22+
attrs = {
23+
"coverage_rc": attr.label(
24+
allow_single_file = True,
25+
),
26+
},
27+
)

0 commit comments

Comments
 (0)