From edd7dd01038612c6e578005c0817e10e541dacb7 Mon Sep 17 00:00:00 2001 From: Reid 'arrdem' McKenzie Date: Sun, 29 Aug 2021 19:46:49 -0600 Subject: [PATCH] Get an interpreter from toolchains This patch teaches Zapp how to read Python toolchains to get an interpreter, rather than hard-coding "python3" somewhat opaquely. This enables the use of hermetic or otherwise selected interpreters. Fixes #2 --- example/BUILD | 29 ++++++++++++++++++++++++++++- example/WORKSPACE | 2 ++ zapp/zapp.bzl | 26 +++++++++++++++++++++----- 3 files changed, 51 insertions(+), 6 deletions(-) diff --git a/example/BUILD b/example/BUILD index 0a69732..ea782f1 100644 --- a/example/BUILD +++ b/example/BUILD @@ -3,12 +3,39 @@ load("@rules_zapp//zapp:zapp.bzl", "zapp_test", ) -load("@rules_python//python:defs.bzl", "py_library") +load("@rules_python//python:defs.bzl", + "py_library", + "py_runtime_pair" +) load("@my_deps//:requirements.bzl", py_requirement="requirement", ) +# Configuring a Python runtime + +py_runtime( + name = "python3_runtime", + files = [], + interpreter_path = "/usr/bin/python3", + python_version = "PY3", + visibility = ["//visibility:public"], +) + +py_runtime_pair( + name = "python_runtime", + py2_runtime = None, + py3_runtime = ":python3_runtime", +) + +toolchain( + name = "python3_toolchain", + toolchain = ":python_runtime", + toolchain_type = "@bazel_tools//tools/python:toolchain_type", +) + +# Zapp examples & tests + zapp_test( name = "hello_script", main = "hello.py", diff --git a/example/WORKSPACE b/example/WORKSPACE index 164c6e3..b94de19 100644 --- a/example/WORKSPACE +++ b/example/WORKSPACE @@ -29,6 +29,8 @@ git_repository( tag = "0.3.0", ) +register_toolchains("//:python3_toolchain") + # git_repository( # name = "rules_zapp", # remote = "https://github.com/arrdem/rules_zapp.git", diff --git a/zapp/zapp.bzl b/zapp/zapp.bzl index 913109f..71d220f 100644 --- a/zapp/zapp.bzl +++ b/zapp/zapp.bzl @@ -121,10 +121,20 @@ def _zapp_impl(ctx): # Write the list to the manifest file manifest_file = ctx.actions.declare_file(ctx.label.name + ".zapp-manifest.json") + + # Figure out the Python 3 toolchain to use + runtime = ctx.toolchains["@bazel_tools//tools/python:toolchain_type"].py3_runtime + if runtime.interpreter_path: + py3 = runtime.interpreter_path + elif runtime.interpreter: + py3 = runtime.interpreter.path + else: + fail("No Python 3 toolchain available") + ctx.actions.write( output = manifest_file, content = json.encode({ - "shebang": ctx.attr.shebang, + "shebang": ctx.attr.shebang.replace("%py3%", py3), "sources": {d: {"hashes": [], "source": s} for d, s in sources_map.items()}, "zip_safe": ctx.attr.zip_safe, "prelude_points": ctx.attr.prelude_points, @@ -172,7 +182,7 @@ _zapp_attrs = { executable = True, cfg = "host", ), - "shebang": attr.string(default = "/usr/bin/env python3"), + "shebang": attr.string(default = "/usr/bin/env %py3%"), "zip_safe": attr.bool(default = True), "root_import": attr.bool(default = False), } @@ -181,6 +191,9 @@ _zapp = rule( attrs = _zapp_attrs, executable = True, implementation = _zapp_impl, + toolchains = [ + "@bazel_tools//tools/python:toolchain_type", + ] ) @@ -193,7 +206,7 @@ def zapp_binary(name, test=False, compiler=None, zip_safe=True, - rule=_zapp, + _rule=_zapp, **kwargs): """A self-contained, single-file Python program, with a .zapp file extension. @@ -240,7 +253,7 @@ def zapp_binary(name, **kwargs ) - rule( + _rule( name = name, src = name + ".lib", compiler = compiler, @@ -256,10 +269,13 @@ _zapp_test = rule( attrs = _zapp_attrs, test = True, implementation = _zapp_impl, + toolchains = [ + "@bazel_tools//tools/python:toolchain_type", + ] ) def zapp_test(name, **kwargs): """Same as zapp_binary, just sets the test=True bit.""" - zapp_binary(name, rule=_zapp_test, **kwargs) + zapp_binary(name, _rule=_zapp_test, **kwargs)