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
This commit is contained in:
Reid 'arrdem' McKenzie 2021-08-29 19:46:49 -06:00
parent e5ff423318
commit edd7dd0103
3 changed files with 51 additions and 6 deletions

View file

@ -3,12 +3,39 @@ load("@rules_zapp//zapp:zapp.bzl",
"zapp_test", "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", load("@my_deps//:requirements.bzl",
py_requirement="requirement", 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( zapp_test(
name = "hello_script", name = "hello_script",
main = "hello.py", main = "hello.py",

View file

@ -29,6 +29,8 @@ git_repository(
tag = "0.3.0", tag = "0.3.0",
) )
register_toolchains("//:python3_toolchain")
# git_repository( # git_repository(
# name = "rules_zapp", # name = "rules_zapp",
# remote = "https://github.com/arrdem/rules_zapp.git", # remote = "https://github.com/arrdem/rules_zapp.git",

View file

@ -121,10 +121,20 @@ def _zapp_impl(ctx):
# Write the list to the manifest file # Write the list to the manifest file
manifest_file = ctx.actions.declare_file(ctx.label.name + ".zapp-manifest.json") 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( ctx.actions.write(
output = manifest_file, output = manifest_file,
content = json.encode({ 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()}, "sources": {d: {"hashes": [], "source": s} for d, s in sources_map.items()},
"zip_safe": ctx.attr.zip_safe, "zip_safe": ctx.attr.zip_safe,
"prelude_points": ctx.attr.prelude_points, "prelude_points": ctx.attr.prelude_points,
@ -172,7 +182,7 @@ _zapp_attrs = {
executable = True, executable = True,
cfg = "host", cfg = "host",
), ),
"shebang": attr.string(default = "/usr/bin/env python3"), "shebang": attr.string(default = "/usr/bin/env %py3%"),
"zip_safe": attr.bool(default = True), "zip_safe": attr.bool(default = True),
"root_import": attr.bool(default = False), "root_import": attr.bool(default = False),
} }
@ -181,6 +191,9 @@ _zapp = rule(
attrs = _zapp_attrs, attrs = _zapp_attrs,
executable = True, executable = True,
implementation = _zapp_impl, implementation = _zapp_impl,
toolchains = [
"@bazel_tools//tools/python:toolchain_type",
]
) )
@ -193,7 +206,7 @@ def zapp_binary(name,
test=False, test=False,
compiler=None, compiler=None,
zip_safe=True, zip_safe=True,
rule=_zapp, _rule=_zapp,
**kwargs): **kwargs):
"""A self-contained, single-file Python program, with a .zapp file extension. """A self-contained, single-file Python program, with a .zapp file extension.
@ -240,7 +253,7 @@ def zapp_binary(name,
**kwargs **kwargs
) )
rule( _rule(
name = name, name = name,
src = name + ".lib", src = name + ".lib",
compiler = compiler, compiler = compiler,
@ -256,10 +269,13 @@ _zapp_test = rule(
attrs = _zapp_attrs, attrs = _zapp_attrs,
test = True, test = True,
implementation = _zapp_impl, implementation = _zapp_impl,
toolchains = [
"@bazel_tools//tools/python:toolchain_type",
]
) )
def zapp_test(name, **kwargs): def zapp_test(name, **kwargs):
"""Same as zapp_binary, just sets the test=True bit.""" """Same as zapp_binary, just sets the test=True bit."""
zapp_binary(name, rule=_zapp_test, **kwargs) zapp_binary(name, _rule=_zapp_test, **kwargs)