summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLars Wirzenius <liw@liw.fi>2021-07-22 07:18:11 +0000
committerLars Wirzenius <liw@liw.fi>2021-07-22 07:18:11 +0000
commit0ec7e2c81cb5d28edf944770c3a5f7f54dded0b6 (patch)
tree7aafb4ca62254eec4581d3abc505171fbbe98b97
parent3a221ccb34a1dd551614762c445f49bea87594f2 (diff)
parentfdab0cb57408fadf831147003c7bd2a873c5b84d (diff)
downloadsummain-rs-0ec7e2c81cb5d28edf944770c3a5f7f54dded0b6.tar.gz
Merge branch 'devendor' into 'main'
chore: use lib/runcmd from Subplot, drop vendored copy See merge request larswirzenius/summain!25
-rw-r--r--subplot/runcmd.py252
-rw-r--r--subplot/runcmd.yaml83
-rw-r--r--summain.md4
3 files changed, 2 insertions, 337 deletions
diff --git a/subplot/runcmd.py b/subplot/runcmd.py
deleted file mode 100644
index a2564c6..0000000
--- a/subplot/runcmd.py
+++ /dev/null
@@ -1,252 +0,0 @@
-import logging
-import os
-import re
-import shlex
-import subprocess
-
-
-#
-# Helper functions.
-#
-
-# Get exit code or other stored data about the latest command run by
-# runcmd_run.
-
-
-def _runcmd_get(ctx, name):
- ns = ctx.declare("_runcmd")
- return ns[name]
-
-
-def runcmd_get_exit_code(ctx):
- return _runcmd_get(ctx, "exit")
-
-
-def runcmd_get_stdout(ctx):
- return _runcmd_get(ctx, "stdout")
-
-
-def runcmd_get_stdout_raw(ctx):
- return _runcmd_get(ctx, "stdout.raw")
-
-
-def runcmd_get_stderr(ctx):
- return _runcmd_get(ctx, "stderr")
-
-
-def runcmd_get_stderr_raw(ctx):
- return _runcmd_get(ctx, "stderr.raw")
-
-
-def runcmd_get_argv(ctx):
- return _runcmd_get(ctx, "argv")
-
-
-# Run a command, given an argv and other arguments for subprocess.Popen.
-#
-# This is meant to be a helper function, not bound directly to a step. The
-# stdout, stderr, and exit code are stored in the "_runcmd" namespace in the
-# ctx context.
-def runcmd_run(ctx, argv, **kwargs):
- ns = ctx.declare("_runcmd")
-
- # The Subplot Python template empties os.environ at startup, modulo a small
- # number of variables with carefully chosen values. Here, we don't need to
- # care about what those variables are, but we do need to not overwrite
- # them, so we just add anything in the env keyword argument, if any, to
- # os.environ.
- env = dict(os.environ)
- for key, arg in kwargs.pop("env", {}).items():
- env[key] = arg
-
- pp = ns.get("path-prefix")
- if pp:
- env["PATH"] = pp + ":" + env["PATH"]
-
- logging.debug(f"runcmd_run")
- logging.debug(f" argv: {argv}")
- logging.debug(f" env: {env}")
- p = subprocess.Popen(
- argv, stdout=subprocess.PIPE, stderr=subprocess.PIPE, env=env, **kwargs
- )
- stdout, stderr = p.communicate("")
- ns["argv"] = argv
- ns["stdout.raw"] = stdout
- ns["stderr.raw"] = stderr
- ns["stdout"] = stdout.decode("utf-8")
- ns["stderr"] = stderr.decode("utf-8")
- ns["exit"] = p.returncode
- logging.debug(f" ctx: {ctx}")
- logging.debug(f" ns: {ns}")
-
-
-# Step: prepend srcdir to PATH whenever runcmd runs a command.
-def runcmd_helper_srcdir_path(ctx):
- srcdir = globals()["srcdir"]
- runcmd_prepend_to_path(ctx, srcdir)
-
-
-# Step: This creates a helper script.
-def runcmd_helper_script(ctx, filename=None):
- get_file = globals()["get_file"]
- with open(filename, "wb") as f:
- f.write(get_file(filename))
-
-
-#
-# Step functions for running commands.
-#
-
-
-def runcmd_prepend_to_path(ctx, dirname=None):
- ns = ctx.declare("_runcmd")
- pp = ns.get("path-prefix", "")
- if pp:
- pp = f"{pp}:{dirname}"
- else:
- pp = dirname
- ns["path-prefix"] = pp
-
-
-def runcmd_step(ctx, argv0=None, args=None):
- runcmd_try_to_run(ctx, argv0=argv0, args=args)
- runcmd_exit_code_is_zero(ctx)
-
-
-def runcmd_try_to_run(ctx, argv0=None, args=None):
- argv = [shlex.quote(argv0)] + shlex.split(args)
- runcmd_run(ctx, argv)
-
-
-#
-# Step functions for examining exit codes.
-#
-
-
-def runcmd_exit_code_is_zero(ctx):
- runcmd_exit_code_is(ctx, exit=0)
-
-
-def runcmd_exit_code_is(ctx, exit=None):
- assert_eq = globals()["assert_eq"]
- assert_eq(runcmd_get_exit_code(ctx), int(exit))
-
-
-def runcmd_exit_code_is_nonzero(ctx):
- runcmd_exit_code_is_not(ctx, exit=0)
-
-
-def runcmd_exit_code_is_not(ctx, exit=None):
- assert_ne = globals()["assert_ne"]
- assert_ne(runcmd_get_exit_code(ctx), int(exit))
-
-
-#
-# Step functions and helpers for examining output in various ways.
-#
-
-
-def runcmd_stdout_is(ctx, text=None):
- _runcmd_output_is(runcmd_get_stdout(ctx), text)
-
-
-def runcmd_stdout_isnt(ctx, text=None):
- _runcmd_output_isnt(runcmd_get_stdout(ctx), text)
-
-
-def runcmd_stderr_is(ctx, text=None):
- _runcmd_output_is(runcmd_get_stderr(ctx), text)
-
-
-def runcmd_stderr_isnt(ctx, text=None):
- _runcmd_output_isnt(runcmd_get_stderr(ctx), text)
-
-
-def _runcmd_output_is(actual, wanted):
- assert_eq = globals()["assert_eq"]
- wanted = bytes(wanted, "utf8").decode("unicode_escape")
- logging.debug("_runcmd_output_is:")
- logging.debug(f" actual: {actual!r}")
- logging.debug(f" wanted: {wanted!r}")
- assert_eq(actual, wanted)
-
-
-def _runcmd_output_isnt(actual, wanted):
- assert_ne = globals()["assert_ne"]
- wanted = bytes(wanted, "utf8").decode("unicode_escape")
- logging.debug("_runcmd_output_isnt:")
- logging.debug(f" actual: {actual!r}")
- logging.debug(f" wanted: {wanted!r}")
- assert_ne(actual, wanted)
-
-
-def runcmd_stdout_contains(ctx, text=None):
- _runcmd_output_contains(runcmd_get_stdout(ctx), text)
-
-
-def runcmd_stdout_doesnt_contain(ctx, text=None):
- _runcmd_output_doesnt_contain(runcmd_get_stdout(ctx), text)
-
-
-def runcmd_stderr_contains(ctx, text=None):
- _runcmd_output_contains(runcmd_get_stderr(ctx), text)
-
-
-def runcmd_stderr_doesnt_contain(ctx, text=None):
- _runcmd_output_doesnt_contain(runcmd_get_stderr(ctx), text)
-
-
-def _runcmd_output_contains(actual, wanted):
- assert_eq = globals()["assert_eq"]
- wanted = bytes(wanted, "utf8").decode("unicode_escape")
- logging.debug("_runcmd_output_contains:")
- logging.debug(f" actual: {actual!r}")
- logging.debug(f" wanted: {wanted!r}")
- assert_eq(wanted in actual, True)
-
-
-def _runcmd_output_doesnt_contain(actual, wanted):
- assert_ne = globals()["assert_ne"]
- wanted = bytes(wanted, "utf8").decode("unicode_escape")
- logging.debug("_runcmd_output_doesnt_contain:")
- logging.debug(f" actual: {actual!r}")
- logging.debug(f" wanted: {wanted!r}")
- assert_ne(wanted in actual, True)
-
-
-def runcmd_stdout_matches_regex(ctx, regex=None):
- _runcmd_output_matches_regex(runcmd_get_stdout(ctx), regex)
-
-
-def runcmd_stdout_doesnt_match_regex(ctx, regex=None):
- _runcmd_output_doesnt_match_regex(runcmd_get_stdout(ctx), regex)
-
-
-def runcmd_stderr_matches_regex(ctx, regex=None):
- _runcmd_output_matches_regex(runcmd_get_stderr(ctx), regex)
-
-
-def runcmd_stderr_doesnt_match_regex(ctx, regex=None):
- _runcmd_output_doesnt_match_regex(runcmd_get_stderr(ctx), regex)
-
-
-def _runcmd_output_matches_regex(actual, regex):
- assert_ne = globals()["assert_ne"]
- r = re.compile(regex)
- m = r.search(actual)
- logging.debug("_runcmd_output_matches_regex:")
- logging.debug(f" actual: {actual!r}")
- logging.debug(f" regex: {regex!r}")
- logging.debug(f" match: {m}")
- assert_ne(m, None)
-
-
-def _runcmd_output_doesnt_match_regex(actual, regex):
- assert_eq = globals()["assert_eq"]
- r = re.compile(regex)
- m = r.search(actual)
- logging.debug("_runcmd_output_doesnt_match_regex:")
- logging.debug(f" actual: {actual!r}")
- logging.debug(f" regex: {regex!r}")
- logging.debug(f" match: {m}")
- assert_eq(m, None)
diff --git a/subplot/runcmd.yaml b/subplot/runcmd.yaml
deleted file mode 100644
index 48dde90..0000000
--- a/subplot/runcmd.yaml
+++ /dev/null
@@ -1,83 +0,0 @@
-# Steps to run commands.
-
-- given: helper script {filename} for runcmd
- function: runcmd_helper_script
-
-- given: srcdir is in the PATH
- function: runcmd_helper_srcdir_path
-
-- when: I run (?P<argv0>\S+)(?P<args>.*)
- regex: true
- function: runcmd_step
-
-- when: I try to run (?P<argv0>\S+)(?P<args>.*)
- regex: true
- function: runcmd_try_to_run
-
-# Steps to examine exit code of latest command.
-
-- then: exit code is {exit}
- function: runcmd_exit_code_is
-
-- then: exit code is not {exit}
- function: runcmd_exit_code_is_not
-
-- then: command is successful
- function: runcmd_exit_code_is_zero
-
-- then: command fails
- function: runcmd_exit_code_is_nonzero
-
-# Steps to examine stdout/stderr for exact content.
-
-- then: stdout is exactly "(?P<text>.*)"
- regex: true
- function: runcmd_stdout_is
-
-- then: "stdout isn't exactly \"(?P<text>.*)\""
- regex: true
- function: runcmd_stdout_isnt
-
-- then: stderr is exactly "(?P<text>.*)"
- regex: true
- function: runcmd_stderr_is
-
-- then: "stderr isn't exactly \"(?P<text>.*)\""
- regex: true
- function: runcmd_stderr_isnt
-
-# Steps to examine stdout/stderr for sub-strings.
-
-- then: stdout contains "(?P<text>.*)"
- regex: true
- function: runcmd_stdout_contains
-
-- then: "stdout doesn't contain \"(?P<text>.*)\""
- regex: true
- function: runcmd_stdout_doesnt_contain
-
-- then: stderr contains "(?P<text>.*)"
- regex: true
- function: runcmd_stderr_contains
-
-- then: "stderr doesn't contain \"(?P<text>.*)\""
- regex: true
- function: runcmd_stderr_doesnt_contain
-
-# Steps to match stdout/stderr against regular expressions.
-
-- then: stdout matches regex (?P<regex>.*)
- regex: true
- function: runcmd_stdout_matches_regex
-
-- then: stdout doesn't match regex (?P<regex>.*)
- regex: true
- function: runcmd_stdout_doesnt_match_regex
-
-- then: stderr matches regex (?P<regex>.*)
- regex: true
- function: runcmd_stderr_matches_regex
-
-- then: stderr doesn't match regex (?P<regex>.*)
- regex: true
- function: runcmd_stderr_doesnt_match_regex
diff --git a/summain.md b/summain.md
index 47acba4..f326358 100644
--- a/summain.md
+++ b/summain.md
@@ -264,8 +264,8 @@ author: Lars Wirzenius
template: python
bindings:
- subplot/summain.yaml
- - subplot/runcmd.yaml
+ - lib/runcmd.yaml
functions:
- subplot/summain.py
- - subplot/runcmd.py
+ - lib/runcmd.py
...