blob: 838166a187fdf281ccb7d9aa6ef8f7f14f6689af [file] [log] [blame]
"""Implementation of the rules to expose a REPL."""
load("//python:py_binary.bzl", _py_binary = "py_binary")
def _generate_repl_main_impl(ctx):
stub_repo = ctx.attr.stub.label.repo_name or ctx.workspace_name
stub_path = "/".join([stub_repo, ctx.file.stub.short_path])
out = ctx.actions.declare_file(ctx.label.name + ".py")
# Point the generated main file at the stub.
ctx.actions.expand_template(
template = ctx.file._template,
output = out,
substitutions = {
"%stub_path%": stub_path,
},
)
return [DefaultInfo(files = depset([out]))]
_generate_repl_main = rule(
implementation = _generate_repl_main_impl,
attrs = {
"stub": attr.label(
mandatory = True,
allow_single_file = True,
doc = ("The stub responsible for actually invoking the final shell. " +
"See the \"Customizing the REPL\" docs for details."),
),
"_template": attr.label(
default = "//python/private:repl_template.py",
allow_single_file = True,
doc = "The template to use for generating `out`.",
),
},
doc = """\
Generates a "main" script for a py_binary target that starts a Python REPL.
The template is designed to take care of the majority of the logic. The user
customizes the exact shell that will be started via the stub. The stub is a
simple shell script that imports the desired shell and then executes it.
The target's name is used for the output filename (with a .py extension).
""",
)
def py_repl_binary(name, stub, deps = [], data = [], **kwargs):
"""A py_binary target that executes a REPL when run.
The stub is the script that ultimately decides which shell the REPL will run.
It can be as simple as this:
import code
code.interact()
Or it can load something like IPython instead.
Args:
name: Name of the generated py_binary target.
stub: The script that invokes the shell.
deps: The dependencies of the py_binary.
data: The runtime dependencies of the py_binary.
**kwargs: Forwarded to the py_binary.
"""
_generate_repl_main(
name = "%s_py" % name,
stub = stub,
)
_py_binary(
name = name,
srcs = [
":%s_py" % name,
],
main = "%s_py.py" % name,
data = data + [
stub,
],
deps = deps + [
"//python/runfiles",
],
**kwargs
)