[rtems-central commit] util: Add function to run commands
Sebastian Huber
sebh at rtems.org
Wed Mar 10 09:02:05 UTC 2021
Module: rtems-central
Branch: master
Commit: 5277664d16385f35b25f8862c3971988e42dd798
Changeset: http://git.rtems.org/rtems-central/commit/?id=5277664d16385f35b25f8862c3971988e42dd798
Author: Sebastian Huber <sebastian.huber at embedded-brains.de>
Date: Mon Mar 8 17:06:49 2021 +0100
util: Add function to run commands
---
rtems_spec_to_x.py | 25 +++++--------------------
rtemsspec/tests/test_util.py | 20 ++++++++++++++++++--
rtemsspec/util.py | 37 +++++++++++++++++++++++++++++++++++--
3 files changed, 58 insertions(+), 24 deletions(-)
diff --git a/rtems_spec_to_x.py b/rtems_spec_to_x.py
index 06653cf..10ccc78 100755
--- a/rtems_spec_to_x.py
+++ b/rtems_spec_to_x.py
@@ -25,10 +25,9 @@
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
+import logging
import os
import string
-import subprocess
-from typing import List
import rtemsspec.applconfig
import rtemsspec.build
@@ -39,21 +38,6 @@ import rtemsspec.util
import rtemsspec.validation
-def _run_command(args: List[str], cwd: str) -> int:
- task = subprocess.Popen(args,
- stdout=subprocess.PIPE,
- stderr=subprocess.STDOUT,
- cwd=cwd)
- assert task.stdout is not None
- while True:
- line = task.stdout.readline()
- if line:
- print(line.decode("utf-8").strip())
- elif task.poll() is not None:
- break
- return task.wait()
-
-
def _run_pre_qualified_only_build(config: dict, item_cache: ItemCache) -> None:
files = rtemsspec.build.gather_files(config, item_cache)
source_dir = config["source-directory"]
@@ -63,11 +47,11 @@ def _run_pre_qualified_only_build(config: dict, item_cache: ItemCache) -> None:
content = string.Template(config["config-ini"]).substitute(config)
config_ini.write(content)
specs = os.path.relpath(os.path.join(source_dir, "spec"), workspace_dir)
- _run_command([
+ rtemsspec.util.run_command([
"./waf", "configure", "--rtems-specs", specs, "--rtems-top-group",
"/build/grp"
], workspace_dir)
- _run_command(["./waf"], workspace_dir)
+ rtemsspec.util.run_command(["./waf"], workspace_dir)
def _run_pre_qualified_doxygen(config: dict) -> None:
@@ -84,11 +68,12 @@ def _run_pre_qualified_doxygen(config: dict) -> None:
content = Template(doxyfile_template.read()).substitute(doxyfile_vars)
with open(os.path.join(workspace_dir, "Doxyfile"), "w") as doxyfile:
doxyfile.write(content)
- _run_command(["doxygen"], workspace_dir)
+ rtemsspec.util.run_command(["doxygen"], workspace_dir)
def main() -> None:
""" Generates glossaries of terms according to the configuration. """
+ logging.basicConfig(level="DEBUG")
config = rtemsspec.util.load_config("config.yml")
item_cache = ItemCache(config["spec"])
rtemsspec.glossary.generate(config["glossary"], item_cache)
diff --git a/rtemsspec/tests/test_util.py b/rtemsspec/tests/test_util.py
index c85e683..7affd79 100644
--- a/rtemsspec/tests/test_util.py
+++ b/rtemsspec/tests/test_util.py
@@ -1,7 +1,7 @@
# SPDX-License-Identifier: BSD-2-Clause
""" Unit tests for the rtemsspec.util module. """
-# Copyright (C) 2020 embedded brains GmbH (http://www.embedded-brains.de)
+# Copyright (C) 2020, 2021 embedded brains GmbH (http://www.embedded-brains.de)
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
@@ -25,8 +25,10 @@
# POSSIBILITY OF SUCH DAMAGE.
import os
+import logging
-from rtemsspec.util import copy_files, load_config
+from rtemsspec.util import copy_files, load_config, run_command
+from rtemsspec.tests.util import get_and_clear_log
def test_copy_files(tmpdir):
@@ -43,3 +45,17 @@ def test_load_config():
config = load_config(filename)
assert config["a"] == "b"
assert config["c"] == "d"
+
+
+def test_run(caplog):
+ caplog.set_level(logging.DEBUG)
+ status = run_command(["echo", "A"])
+ assert status == 0
+ assert get_and_clear_log(caplog) == """INFO run in '.': 'echo' 'A'
+DEBUG A"""
+ stdout = []
+ status = run_command(["echo", "A"], stdout=stdout)
+ assert status == 0
+ assert stdout[0].strip() == "A"
+ status = run_command(["sleep", "0.1"])
+ assert status == 0
diff --git a/rtemsspec/util.py b/rtemsspec/util.py
index d2403cd..bf07b5f 100644
--- a/rtemsspec/util.py
+++ b/rtemsspec/util.py
@@ -1,7 +1,7 @@
# SPDX-License-Identifier: BSD-2-Clause
""" This module provides utility functions. """
-# Copyright (C) 2020 embedded brains GmbH (http://www.embedded-brains.de)
+# Copyright (C) 2020, 2021 embedded brains GmbH (http://www.embedded-brains.de)
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
@@ -24,9 +24,11 @@
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
+import logging
import os
import shutil
-from typing import Any, List
+import subprocess
+from typing import Any, List, Optional
import yaml
@@ -63,3 +65,34 @@ def load_config(config_filename: str) -> Any:
IncludeLoader.add_constructor("!include", IncludeLoader.include)
with open(config_filename, "r") as config_file:
return yaml.load(config_file.read(), Loader=IncludeLoader)
+
+
+def run_command(args: List[str],
+ cwd: str = ".",
+ stdout: Optional[List[str]] = None,
+ env=None) -> int:
+ """
+ Runs the command in a subprocess in the working directory and environment.
+
+ Optionally, the standard output of the subprocess is returned. Returns the
+ exit status of the subprocess.
+ """
+ logging.info("run in '%s': %s", cwd, " ".join(f"'{arg}'" for arg in args))
+ task = subprocess.Popen(args,
+ stdin=subprocess.PIPE,
+ stdout=subprocess.PIPE,
+ stderr=subprocess.STDOUT,
+ cwd=cwd,
+ env=env)
+ assert task.stdout is not None
+ while True:
+ raw_line = task.stdout.readline()
+ if raw_line:
+ line = raw_line.decode("utf-8").rstrip()
+ if stdout is None:
+ logging.debug("%s", line)
+ else:
+ stdout.append(line)
+ elif task.poll() is not None:
+ break
+ return task.wait()
More information about the vc
mailing list