diff options
Diffstat (limited to 'remote')
| -rwxr-xr-x | remote/sbb-remote | 42 |
1 files changed, 39 insertions, 3 deletions
diff --git a/remote/sbb-remote b/remote/sbb-remote index ace4fb9..15c0fec 100755 --- a/remote/sbb-remote +++ b/remote/sbb-remote @@ -41,7 +41,7 @@ import time import tomllib import urllib.request -VERSION = "0.11.0" +VERSION = "0.12.0" DEFAULTS = { "state_dir": "/var/lib/sb-builder", "repo_dir": "/var/lib/sbopkg/SBo-danix", @@ -63,7 +63,7 @@ JOB_ID = re.compile(r"^\d{8}-\d{6}-[a-z]+(-[a-z]+)*(-\d+)?$") PKG = re.compile(r"^[^/]+/([^/]+)/\1\.SlackBuild$") PKGNAME = re.compile(r"^[A-Za-z0-9._+-]+$") VERSION_ARG = re.compile(r"^[A-Za-z0-9._+-]{1,64}$") -ACTIONS = ("build", "rebuild", "update", "remove") +ACTIONS = ("build", "rebuild", "update", "remove", "prune") PRESET = "/usr/libexec/gpg-preset-passphrase" ITEM = re.compile(r"^[A-Za-z0-9._+-]+/[A-Za-z0-9._+-]+$") # category/pkg LOG_TAIL = 512 * 1024 # bytes of the log returned; the failure is at the end @@ -126,6 +126,27 @@ def kind_sbshadow(cfg, args): return ["sbshadow", _flag(args)], {} +def _prunable(cfg): + """Built items (slackrepo's packages table) whose SlackBuild is gone from the tree.""" + db = sqlite3.connect(f"file:{cfg['slackrepo_db']}?mode=ro", uri=True) + try: + items = [i for (i,) in db.execute("select distinct itemid from packages order by itemid")] + finally: + db.close() + return [i for i in items if ITEM.match(i) and not i.startswith("-") and not os.path.isfile( + os.path.join(cfg["repo_dir"], i, os.path.basename(i) + ".SlackBuild"))] + + +def _results_since(cfg, start): + """{itemid: result} of the slackrepo items that finished since start.""" + db = sqlite3.connect(f"file:{cfg['slackrepo_db']}?mode=ro", uri=True) + try: + return dict(db.execute("select itemid, result from buildresults" + " where cast(time as integer) >= ?", (int(start),))) + finally: + db.close() + + def kind_slackrepo(cfg, args): if not args or args[0] not in ACTIONS: raise Error(f"slackrepo: action must be one of {', '.join(ACTIONS)}") @@ -141,7 +162,14 @@ def kind_slackrepo(cfg, args): raise Error(f"slackrepo: no such package: {p}") if p not in pkgs: pkgs.append(p) - if not pkgs and action != "update": + if action == "prune": + if pkgs: + raise Error("slackrepo: prune takes no packages") + pkgs = _prunable(cfg) # computed here, never named by the GUI + if not pkgs: + raise Error("slackrepo: nothing to prune") + action = "remove" + elif not pkgs and action != "update": raise Error(f"slackrepo: {action} needs at least one package") argv = ["slackrepo", f"--repo={cfg['slackrepo_repo']}", action] if "--preview" in opts: @@ -360,6 +388,13 @@ def cmd_run(cfg, jid=None): rc = p.wait() meta.update(end=time.time(), exit=rc, status="ok" if rc == 0 else "killed" if rc == -signal.SIGTERM else "failed") + if signs(meta["kind"], meta["args"]): + # slackrepo exits 0 whatever its items did: their results tell + results = _try(lambda: _results_since(cfg, meta["start"])) + if results is not None: + meta["results"] = results + if rc == 0 and set(results.values()) & {"failed", "aborted", "bad"}: + meta["status"] = "failed" write_meta(d, meta) return None @@ -502,6 +537,7 @@ def cmd_stats(cfg): "slackpkg": _slackpkg(), "packages": _try(lambda: _packages(cfg)), "orphans": _try(lambda: _orphans(cfg)), + "prunable": _try(lambda: len(_prunable(cfg))), "sync": {o: _try(lambda o=o: int(_git(cfg, "log", "-1", "--format=%ct", "--", o + "/"))) for o in cfg["overlays"]}, "slackrepo": _try(lambda: _slackrepo(cfg)), |
