Skip to content

Commit

Permalink
Migrating command rule to rules_task (#203)
Browse files Browse the repository at this point in the history
* Migrating command rule to rules_task

* Support and test capturing stdin

* Support and test handling CLI_ARGS

* Support interrupting task and exiting cleanly

* remove multirun module
  • Loading branch information
mvgijssel authored Apr 21, 2023
1 parent fcd780a commit cf19677
Show file tree
Hide file tree
Showing 26 changed files with 174 additions and 582 deletions.
8 changes: 5 additions & 3 deletions BUILD.bazel
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
load("//tools/command:command.bzl", "command")
load("@bazel_skylib//rules:common_settings.bzl", "bool_flag")
load("@npm//:defs.bzl", "npm_link_all_packages")
load("@npm//:prettier/package_json.bzl", prettier_bin = "bin")
load("@rules_task//:defs.bzl", "cmd", "task")

package(default_visibility = ["//visibility:public"])

Expand Down Expand Up @@ -41,9 +41,11 @@ prettier_bin.prettier_binary(
name = "prettier_bin",
)

command(
task(
name = "prettier",
command_src = ":prettier_bin",
cmds = [
cmd.executable(":prettier_bin"),
],
cwd = "{{ os.environ.get('BUILD_WORKING_DIRECTORY', os.getcwd()) }}",
env = {
"BAZEL_BINDIR": ".",
Expand Down
11 changes: 0 additions & 11 deletions MODULE.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,6 @@ bazel_dep(name = "bazel_skylib", version = "1.4.1")
# ------------------------------------ rules_pkg ------------------------------------ #
bazel_dep(name = "rules_pkg", version = "0.9.0")

# ------------------------------------ rules_multirun ------------------------------------ #
bazel_dep(name = "rules_multirun", version = "0.6.0")

# ------------------------------------ rules_task ------------------------------------ #
bazel_dep(name = "rules_task", version = "0.1.0")
local_path_override(
Expand Down Expand Up @@ -121,11 +118,3 @@ pip.parse(
requirements_lock = "//tools/black:requirements.lock",
)
use_repo(pip, "black-requirements")

# ------------------------------------ command ------------------------------------ #
pip.parse(
name = "command-requirements",
python_interpreter_target = "@python_interpreter//:python",
requirements_lock = "@setup//tools/command:requirements.lock",
)
use_repo(pip, "command-requirements")
3 changes: 1 addition & 2 deletions hypervisor/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
# load("//tools/packer:defs.bzl", "packer_image")
# load("//tools/pyinfra:defs.bzl", "pyinfra_run")
# load("//tools/vagrant:defs.bzl", "qcow_to_vagrant_box")
# load("//tools/bazel:defs.bzl", "runner_binary")
# load("@rules_python//python:pip.bzl", "compile_pip_requirements")

# compile_pip_requirements(
Expand Down Expand Up @@ -48,7 +47,7 @@
# tags = ["no-cache"],
# )

# # runner_binary(
# # task(
# # name = "kitchen",
# # out = "kitchen.sh",
# # cmd = """
Expand Down
34 changes: 21 additions & 13 deletions infrastructure/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
load("//tools/command:command.bzl", "command")
load("@rules_task//:defs.bzl", "cmd", "task")
load("@rules_python//python:pip.bzl", "compile_pip_requirements")
load("@infrastructure-requirements//:requirements.bzl", "requirement")

Expand All @@ -11,9 +11,14 @@ compile_pip_requirements(
requirements_txt = "requirements.lock",
)

command(
task(
name = "pulumi",
command_src = "//tools/pulumi",
cmds = [
cmd.shell(
cmd.executable("//tools/pulumi"),
"$CLI_ARGS",
),
],
cwd = "{{ os.environ.get('BUILD_WORKING_DIRECTORY', os.getcwd()) }}",
env = {
"PULUMI_PYTHON_CMD": "python",
Expand All @@ -25,17 +30,20 @@ command(
],
)

command(
task(
name = "provisioner-deploy",
args = [
"up",
"--stack",
"dev",
"--diff",
"--color",
"always",
"--yes",
cmds = [
"unset BUILD_WORKING_DIRECTORY",
cmd.shell(
cmd.executable(":pulumi"),
"up",
"--stack",
"mvgijssel/provisioner/dev",
"--diff",
"--color",
"always",
"--yes",
),
],
command_src = ":pulumi",
cwd = "{{ os.environ['BUILD_WORKSPACE_DIRECTORY'] }}/infrastructure/stacks/provisioner",
)
30 changes: 16 additions & 14 deletions occupancy_component/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
load("@rules_python//python:pip.bzl", "compile_pip_requirements")
load("@occupancy_component//:requirements.bzl", "requirement")
load("//tools/pytest:pytest.bzl", "py_pytest_test")
load("//tools/command:command.bzl", "command")
load("@rules_task//:defs.bzl", "cmd", "task")

compile_pip_requirements(
name = "requirements",
Expand Down Expand Up @@ -38,27 +38,29 @@ py_pytest_test(
],
)

command(
task(
name = "tilt",
command_src = "@tilt_arm64//:tilt_binary",
cwd = "{{ os.path.dirname(runfiles_path('$(rlocationpath :Tiltfile)')) }}",
cmds = [
cmd.shell(
cmd.executable("@tilt_arm64//:tilt_binary"),
"$CLI_ARGS",
),
],
cwd = "{{ os.environ['BUILD_WORKSPACE_DIRECTORY'] }}/occupancy_component",
data = [
":Tiltfile",
":docker-compose.yml",
"//tools/tilt:post_build/Tiltfile",
],
)

# TODO: can we also remove attached volumes when doing "down"?
command(
task(
name = "dev",
after_cmd = """
subprocess.run([cmd, "down"])
""",
args = [
"up",
"--port",
"10350",
cmds = [
"$tilt up --port 10350",
{"defer": "$tilt down"},
],
command_src = ":tilt",
env = {
"tilt": cmd.executable(":tilt"),
},
)
6 changes: 3 additions & 3 deletions rules/rules_task/defs.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -326,8 +326,8 @@ def _task_rule_prep(kwargs, testonly = False):

py_binary(
name = runner_name,
main = "//:runner.py",
srcs = ["//:runner.py"],
main = "@rules_task//:runner.py",
srcs = ["@rules_task//:runner.py"],
testonly = testonly,
deps = [
requirement("bazel-runfiles"),
Expand Down Expand Up @@ -488,7 +488,7 @@ def py_binary_cmd(name, code):

expand_template(
name = main_name,
template = "//:py_binary_cmd_main.tpl.py",
template = "@rules_task//:py_binary_cmd_main.tpl.py",
out = main_name_file,
substitutions = {
"{{python_code}}": code,
Expand Down
28 changes: 19 additions & 9 deletions rules/rules_task/runner.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import runfiles
import jinja2
import sys
import signal

r = runfiles.Create()
environment = jinja2.Environment(undefined=jinja2.StrictUndefined)
Expand All @@ -25,7 +26,8 @@ def jinja_render_string(string):


def main() -> None:
_, instructions_file = sys.argv
_, instructions_file, *cli_args = sys.argv
cli_args = " ".join(cli_args)

# Making sure the current Python executable is in front of the PATH
# so python based cmds can use this Python as well.
Expand Down Expand Up @@ -81,14 +83,22 @@ def main() -> None:
bash_cmd += cmd + "\n"

bash_cmd = jinja_render_string(bash_cmd)

result = subprocess.run(["bash", "-c", bash_cmd], capture_output=True)

sys.stdout.write(result.stdout.decode("utf-8"))
sys.stderr.write(result.stderr.decode("utf-8"))

if result.returncode != 0:
sys.exit(result.returncode)
cmd_env = os.environ.copy()
cmd_env["CLI_ARGS"] = cli_args

cmd = ["bash", "-c", bash_cmd]

try:
process = subprocess.Popen(
cmd,
env=cmd_env,
)
process.wait()
except KeyboardInterrupt:
process.send_signal(signal.SIGINT)
process.wait()

sys.exit(process.returncode)


if __name__ == "__main__":
Expand Down
26 changes: 26 additions & 0 deletions rules/rules_task/tests/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,30 @@ task(
],
)

task(
name = "cli_args",
cmds = [
"echo $CLI_ARGS",
],
)

task(
name = "cat",
cmds = [
"cat",
],
)

task(
name = "capture_stdin",
cmds = [
"echo 'hello from stdin' | $other_cmd",
],
env = {
"other_cmd": cmd.executable(":cat"),
},
)

task_test(
name = "task_test_test",
cmds = [
Expand All @@ -178,6 +202,8 @@ py_test(
] + ["$(location :%s)" % x for x in ["test.py"]],
data = [
":broken",
":capture_stdin",
":cli_args",
":cwd",
":cwd_jinja",
":defer",
Expand Down
16 changes: 14 additions & 2 deletions rules/rules_task/tests/test.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@ def _runfiles_path(path):
return p


def _run_task(name):
def _run_task(name, args=[]):
binary = _runfiles_path(os.path.join(os.environ["WORKSPACE_NAME"], "tests", name))
return subprocess.run([binary], capture_output=True)
return subprocess.run([binary] + args, capture_output=True)


def _get_output(name):
Expand Down Expand Up @@ -102,3 +102,15 @@ def test_defer():
result = _run_task("defer")
assert result.returncode == 2
assert result.stdout.strip() == b"first\nsecond\nfirst defer\nsecond defer"


def test_cli_args():
result = _run_task("cli_args", ["get", "this", "value", "back"])
assert result.returncode == 0
assert result.stdout.strip() == b"get this value back"


def test_capture_stdin():
result = _run_task("capture_stdin")
assert result.returncode == 0
assert result.stdout.strip() == b"hello from stdin"
Empty file removed tools/bazel/BUILD.bazel
Empty file.
90 changes: 0 additions & 90 deletions tools/bazel/defs.bzl

This file was deleted.

Loading

0 comments on commit cf19677

Please sign in to comment.