From 8ea46d33fc03e916efd8463ac6cd3d122eb19796 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?= Date: Fri, 11 Nov 2022 00:04:22 +0000 Subject: [PATCH 1/2] WIP: Add python+coverage example Currently WIP because: - `$(location)` and `$(rootpath)` make vars aren't working correctly - This is what we tried to fix with the `PYTHON_COVERAGE_TARGET` variable, which was ultimately not accepted. See also next point. - Does not use the new toolchain feature that supports adding coveragepy directly to the python toolchain - Added together with the new coveragepy support in bazelbuild/bazel#15590, and is probably better to use than the `$(rootpath)` and `pip_install` solution we're showing here - While I'd love to rewrite the blog post to show this instead, I'd need a bit more time for that - Python imports are wonky - For some reason, the sibling module can only be imported under a parent `python` module. I confirmed this by looking through `PYTHON_PATH` - Seems to be a Bazel regression? Strangely nobody is complaining about this yet, we should probably raise an issue - Not tested in remote execution - No access to an engflow setup to test this right this instant - Since we're not using a toolchain (and even if we were we're using `pip_install`), this requires a python on the host, so there's a decent chance it won't work - Requires bumping Bazel to a version with bazelbuild/bazel#15590 merged, which currently is only available in prereleases --- .bazelversion | 2 +- WORKSPACE | 32 ++++++++++++++++++-------------- python/BUILD | 40 ++++++++++++++++++++++++++++++++++++++++ python/__init__.py | 0 python/example.py | 10 ++++++++++ python/requirements.txt | 1 + python/test_example.py | 19 +++++++++++++++++++ 7 files changed, 89 insertions(+), 15 deletions(-) create mode 100644 python/BUILD create mode 100644 python/__init__.py create mode 100644 python/example.py create mode 100644 python/requirements.txt create mode 100644 python/test_example.py diff --git a/.bazelversion b/.bazelversion index 91ff5727..35113600 100644 --- a/.bazelversion +++ b/.bazelversion @@ -1 +1 @@ -5.2.0 +6.0.0-pre.20221020.1 diff --git a/WORKSPACE b/WORKSPACE index 6de581b6..59e380e4 100644 --- a/WORKSPACE +++ b/WORKSPACE @@ -4,6 +4,24 @@ load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_file") load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") load("@bazel_tools//tools/build_defs/repo:git.bzl", "git_repository") +http_archive( + name = "rules_python", + sha256 = "8c8fe44ef0a9afc256d1e75ad5f448bb59b81aba149b8958f02f7b3a98f5d9b4", + strip_prefix = "rules_python-0.13.0", + url = "https://github.com/bazelbuild/rules_python/archive/refs/tags/0.13.0.tar.gz", +) + +load("@rules_python//python:pip.bzl", "pip_parse") + +pip_parse( + name = "coveragepy", + requirements = "//python:requirements.txt", +) + +load("@coveragepy//:requirements.bzl", "install_deps") + +install_deps() + # Some file dependencies http_file( name = "emacs", @@ -167,17 +185,3 @@ load("@io_bazel_rules_go//go:deps.bzl", "go_register_toolchains", "go_rules_depe go_rules_dependencies() go_register_toolchains(version = "1.19.3") - -http_archive( - name = "io_bazel_rules_kotlin", - sha256 = "a57591404423a52bd6b18ebba7979e8cd2243534736c5c94d35c89718ea38f94", - urls = ["https://github.com/bazelbuild/rules_kotlin/releases/download/v1.6.0/rules_kotlin_release.tgz"], -) - -load("@io_bazel_rules_kotlin//kotlin:repositories.bzl", "kotlin_repositories") - -kotlin_repositories() - -load("@io_bazel_rules_kotlin//kotlin:core.bzl", "kt_register_toolchains") - -kt_register_toolchains() \ No newline at end of file diff --git a/python/BUILD b/python/BUILD new file mode 100644 index 00000000..49f74822 --- /dev/null +++ b/python/BUILD @@ -0,0 +1,40 @@ +"""Example of a python build/test with coverage. +""" + +load("@coveragepy//:requirements.bzl", "entry_point") + +alias( + name = "python_coverage_tools", + actual = entry_point("coverage"), +) + +py_library( + name = "example", + srcs = [ + "__init__.py", + "example.py", + ], +) + +py_test( + name = "test_example", + size = "small", + srcs = ["test_example.py"], + env = { + # In theory this should be `$(execpath :python_coverage_tool)`, + # + # however this will not resolve correctly as Bazel will + # resolve this relative to the runfiles directory. Instead, we + # just manually specify the path in the runfiles directory the + # coverage tools will be placed in. + # + # For a better solution involving setting the coverage tool in + # the toolchain, see + # https://github.com/bazelbuild/bazel/pull/15590 + "PYTHON_COVERAGE": "coveragepy_coverage/rules_python_wheel_entry_point_coverage", + }, + deps = [ + ":example", + ":python_coverage_tools", + ], +) diff --git a/python/__init__.py b/python/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/python/example.py b/python/example.py new file mode 100644 index 00000000..f04da4f7 --- /dev/null +++ b/python/example.py @@ -0,0 +1,10 @@ +def fizzbuzz(i: int) -> str: + if i % 3 == 0: + if i % 5 == 0: + return "FizzBuzz" + else: + return "Fizz" + elif i % 5 == 0: + return "Buzz" + else: + return str(i) diff --git a/python/requirements.txt b/python/requirements.txt new file mode 100644 index 00000000..c7d8bf33 --- /dev/null +++ b/python/requirements.txt @@ -0,0 +1 @@ +coverage==6.5.0 diff --git a/python/test_example.py b/python/test_example.py new file mode 100644 index 00000000..7a08e34f --- /dev/null +++ b/python/test_example.py @@ -0,0 +1,19 @@ +import unittest + +# Bazel seems to be setting the PYTHON_PATH wrong, resulting in a +# parent "python" module. This might be a regression. +from python.example import fizzbuzz + + +class ExampleTest(unittest.TestCase): + def test_fizzbuzz(self): + self.assertEqual(fizzbuzz(1), "1") + self.assertEqual(fizzbuzz(2), "2") + self.assertEqual(fizzbuzz(3), "Fizz") + self.assertEqual(fizzbuzz(4), "4") + self.assertEqual(fizzbuzz(5), "Buzz") + self.assertEqual(fizzbuzz(15), "FizzBuzz") + + +if __name__ == "__main__": + unittest.main() From fd15fee98491512577f16125b1144fcbec1f765d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?= Date: Fri, 11 Nov 2022 02:10:20 +0000 Subject: [PATCH 2/2] Add remote coverage config --- .bazelrc | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.bazelrc b/.bazelrc index 82be45bc..61bc37f2 100644 --- a/.bazelrc +++ b/.bazelrc @@ -19,6 +19,12 @@ build:engflow_common --java_language_version=11 build:without_bytes --experimental_remote_download_outputs=minimal +build:remote_coverage --strategy=CoverageReport=local,remote +build:remote_coverage --combined_report=lcov +build:remote_coverage --nocache_test_results +build:remote_coverage --experimental_split_coverage_postprocessing +build:remote_coverage --experimental_fetch_all_coverage_outputs + # Options for a private EngFlow cluster. # - Change "10.0.0.10:8080" to the actual cluster IP and port. # - You'll also need to set flags for your authentication method.