diff options
Diffstat (limited to 'scripts/obs/lib/__init__.py')
-rw-r--r-- | scripts/obs/lib/__init__.py | 145 |
1 files changed, 145 insertions, 0 deletions
diff --git a/scripts/obs/lib/__init__.py b/scripts/obs/lib/__init__.py new file mode 100644 index 0000000..193c248 --- /dev/null +++ b/scripts/obs/lib/__init__.py @@ -0,0 +1,145 @@ +#!/usr/bin/env python3 +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright 2022 sysmocom - s.f.m.c. GmbH <info@sysmocom.de> +import importlib +import os +import shutil +import subprocess +import sys +import tempfile +import lib.config + +cmds_verbose = False + + +def add_shared_arguments(parser): + parser.add_argument("-f", "--feed", help="package feed (default: nightly)", + metavar="FEED", default="nightly", + choices=lib.config.feeds) + parser.add_argument("-d", "--docker", + help="run in docker to avoid installing required pkgs", + action="store_true") + parser.add_argument("-g", "--git-fetch", + help="fetch already cloned git repositories", + action="store_true") + parser.add_argument("-m", "--meta", action="store_true", + help="build a meta package (e.g. osmocom-nightly)") + parser.add_argument("-c", "--conflict-version", nargs="?", + help="Of the generated source packages, all Osmocom" + " packages (not e.g. open5gs, see lib/config.py" + " for full list) depend on a meta-package such as" + " osmocom-nightly, osmocom-latest, osmocom-2021q1" + " etc. These meta-packages conflict with each" + " other to ensure that one does not mix e.g." + " latest and nightly packages by accident." + " With this -c argument, it is possible to let" + " these packages depend on a meta-package of a" + " specific version. This is used for nightly and" + " 20YYqX packages to ensure they are not mixed" + " from different build dates (ABI compatibility" + " is only on latest).") + parser.add_argument("-v", "--verbose", action="store_true", + help="always print shell commands and their output," + " instead of only printing them on error") + + +def set_cmds_verbose(new_val): + global cmds_verbose + cmds_verbose = new_val + + +def check_required_programs(): + ok = True + + for program in lib.config.required_programs: + if not shutil.which(program): + print(f"ERROR: missing program: {program}") + ok = False + + for module in lib.config.required_python_modules: + if not importlib.find_loader(module): + print(f"ERROR: missing python3 module: {module}") + ok = False + + if not ok: + print("Either install them or use the -d argument to run in docker") + exit(1) + + +def check_package(package): + if package in lib.config.projects_osmocom: + return + if package in lib.config.projects_other: + return + + print(f"ERROR: unknown package: {package}") + print("See packages_osmocom and packages_other in obs/lib/config.py") + exit(1) + + +def exit_error_cmd(completed, error_msg): + """ :param completed: return from run_cmd() below """ + print() + print(f"ERROR: {error_msg}") + print() + print(f"*** command ***\n{completed.args}\n") + print(f"*** returncode ***\n{completed.returncode}\n") + print(f"*** output ***\n{completed.output}") + print("*** python trace ***") + raise RuntimeError("shell command related error, find details right above" + " this python trace") + + +def run_cmd(cmd, check=True, *args, **kwargs): + """ Like subprocess.run, but has check=True and text=True by default and + allows capturing the output while displaying it at the same time. By + default the output is hidden unless there's an error, with -v the + output gets written to stdout. + :returns: subprocess.CompletedProcess instance, but with combined + stdout + stderr written to ret.output + :param check: stop with error if exit code is not 0 """ + global cmds_verbose + + if cmds_verbose: + print(f"+ {cmd}") + + with tempfile.TemporaryFile(encoding="utf8", mode="w+") as output_buf: + p = subprocess.Popen(cmd, stdout=subprocess.PIPE, + stderr=subprocess.STDOUT, text=True, bufsize=1, + *args, **kwargs) + + while True: + out = p.stdout.read(1) + if out == "" and p.poll() is not None: + break + if out != "": + output_buf.write(out) + if cmds_verbose: + sys.stdout.write(out) + sys.stdout.flush() + + output_buf.seek(0) + setattr(p, "output", output_buf.read()) + + if p.returncode == 0 or not check: + return p + + exit_error_cmd(p, "command failed unexpectedly") + + +def remove_temp(): + run_cmd(["rm", "-rf", lib.config.path_temp]) + + +def remove_cache_extra_files(): + """ dpkg-buildpackage outputs all files to the top dir of the package + dir, so it will always put them in _cache when building e.g. the debian + source package of _cache/libosmocore. Clear all extra files from _cache + that don't belog to the git repositories which we actually want to + cache. """ + run_cmd(["find", lib.config.path_cache, "-maxdepth", "1", "-type", "f", + "-delete"]) + + +def get_output_path(project): + return f"{lib.config.path_temp}/srcpkgs/{os.path.basename(project)}" |