diff --git a/tools/base/base_command.py b/tools/base/base_command.py new file mode 100644 index 0000000000000..41cd5675da16f --- /dev/null +++ b/tools/base/base_command.py @@ -0,0 +1,13 @@ +#!/usr/bin/env python3 + +import sys + +from __UPSTREAM_PACKAGE__ import main as upstream_main + + +def main(*args: str) -> int: + return upstream_main(*args) + + +if __name__ == "__main__": + sys.exit(main(*sys.argv[1:])) diff --git a/tools/base/envoy_python.bzl b/tools/base/envoy_python.bzl index 2a5946da7e512..3af2b50323834 100644 --- a/tools/base/envoy_python.bzl +++ b/tools/base/envoy_python.bzl @@ -34,7 +34,8 @@ def envoy_py_library( deps = [], data = [], visibility = ["//visibility:public"], - envoy_prefix = ""): + envoy_prefix = "", + test = True): _parts = name.split(".") package = ".".join(_parts[:-1]) name = _parts[-1] @@ -46,15 +47,16 @@ def envoy_py_library( data = data, visibility = visibility, ) - - envoy_py_test(name, package, visibility, envoy_prefix = envoy_prefix) + if test: + envoy_py_test(name, package, visibility, envoy_prefix = envoy_prefix) def envoy_py_binary( name = None, deps = [], data = [], visibility = ["//visibility:public"], - envoy_prefix = "@envoy"): + envoy_prefix = "@envoy", + test = True): _parts = name.split(".") package = ".".join(_parts[:-1]) name = _parts[-1] @@ -67,4 +69,60 @@ def envoy_py_binary( visibility = visibility, ) - envoy_py_test(name, package, visibility, envoy_prefix = envoy_prefix) + if test: + envoy_py_test(name, package, visibility, envoy_prefix = envoy_prefix) + +def envoy_py_script( + name, + entry_point, + deps = [], + data = [], + visibility = ["//visibility:public"], + envoy_prefix = "@envoy"): + """This generates a `py_binary` from an entry_point in a python package + + Currently, the actual entrypoint callable is hard-coded to `main`. + + For example, if you wish to make use of a `console_script` in an upstream + package that resolves as `envoy.code_format.python.command.main` from a + package named `envoy.code_format.python`, you can use this macro as + follows: + + ```skylark + + envoy_py_script( + name = "tools.code_format.python", + entry_point = "envoy.code_format.python.command", + deps = [requirement("envoy.code_format.python")], + ``` + + You will then be able to use the console script from bazel. + + Separate args to be passed to the console_script with `--`, eg: + + ```console + + $ bazel run //tools/code_format:python -- -h + ``` + + """ + py_file = "%s.py" % name.split(".")[-1] + output = "$(@D)/%s" % py_file + template_rule = "%s//tools/base:base_command.py" % envoy_prefix + template = "$(location %s)" % template_rule + + native.genrule( + name = "py_script_%s" % py_file, + cmd = "sed s/__UPSTREAM_PACKAGE__/%s/ %s > \"%s\"" % (entry_point, template, output), + tools = [template_rule], + outs = [py_file], + ) + + envoy_py_binary( + name = name, + deps = deps, + data = data, + visibility = visibility, + envoy_prefix = envoy_prefix, + test = False, + )