From b9f9ef564a49e233ab1df91b714f2148ab3fbfef Mon Sep 17 00:00:00 2001 From: David Given Date: Sat, 21 Sep 2024 00:22:52 +0200 Subject: [PATCH 1/2] Update ab. --- build/_progress.py | 5 +++ build/ab.mk | 8 ++++- build/ab.py | 81 +++++++++++++++++++++++++++++++--------------- 3 files changed, 67 insertions(+), 27 deletions(-) create mode 100644 build/_progress.py diff --git a/build/_progress.py b/build/_progress.py new file mode 100644 index 0000000..c930f0b --- /dev/null +++ b/build/_progress.py @@ -0,0 +1,5 @@ +import sys + +(_, current, max) = sys.argv +percent = int(100 * float(current) / float(max)) +print(f"[{percent:>3}%]") diff --git a/build/ab.mk b/build/ab.mk index a80c83e..177d0ed 100644 --- a/build/ab.mk +++ b/build/ab.mk @@ -28,9 +28,15 @@ ifeq ($(OS), Windows_NT) endif EXT ?= +ifeq ($(PROGRESSINFO),) +rulecount := $(shell test -f $(OBJ)/build.mk && $(MAKE) -n $(MAKECMDGOALS) PROGRESSINFO=XXXPROGRESSINFOXXX | grep XXXPROGRESSINFOXXX | wc -l) +ruleindex := 1 +PROGRESSINFO = "$(shell $(PYTHON) build/_progress.py $(ruleindex) $(rulecount))$(eval ruleindex := $(shell expr $(ruleindex) + 1))" +endif + include $(OBJ)/build.mk -MAKEFLAGS += -r -j$(nprocs) +MAKEFLAGS += -r -j$(shell nproc) .DELETE_ON_ERROR: .PHONY: update-ab diff --git a/build/ab.py b/build/ab.py index 71287e5..d10e7da 100644 --- a/build/ab.py +++ b/build/ab.py @@ -16,6 +16,7 @@ import inspect import string import sys +import hashlib verbose = False quiet = False @@ -131,6 +132,12 @@ def wrapper(*, name=None, replaces=None, **kwargs): return wrapper +def _isiterable(xs): + return isinstance(xs, Iterable) and not isinstance( + xs, (str, bytes, bytearray) + ) + + class Target: def __init__(self, cwd, name): if verbose: @@ -166,7 +173,7 @@ def format_field(self, value, format_spec): return "" if type(value) == str: return value - if isinstance(value, (set, tuple)): + if _isiterable(value): value = list(value) if type(value) != list: value = [value] @@ -210,9 +217,23 @@ def materialise(self, replacing=False): # Actually call the callback. cwdStack.append(self.cwd) - self.callback( - **{k: self.args[k] for k in self.binding.arguments.keys()} - ) + if "kwargs" in self.binding.arguments.keys(): + # If the caller wants kwargs, return all arguments except the standard ones. + cbargs = { + k: v for k, v in self.args.items() if k not in {"dir"} + } + else: + # Otherwise, just call the callback with the ones it asks for. + cbargs = {} + for k in self.binding.arguments.keys(): + if k != "kwargs": + try: + cbargs[k] = self.args[k] + except KeyError: + error( + f"invocation of {self} failed because {k} isn't an argument" + ) + self.callback(**cbargs) cwdStack.pop() except BaseException as e: print(f"Error materialising {self}: {self.callback}") @@ -308,9 +329,7 @@ class Targets: def convert(value, target): if not value: return [] - assert isinstance( - value, (list, tuple) - ), "cannot convert non-list to Targets" + assert _isiterable(value), "cannot convert non-list to Targets" return [target.targetof(x) for x in flatten(value)] @@ -334,7 +353,7 @@ def loadbuildfile(filename): def flatten(items): def generate(xs): for x in xs: - if isinstance(x, Iterable) and not isinstance(x, (str, bytes)): + if _isiterable(x): yield from generate(x) else: yield x @@ -343,15 +362,13 @@ def generate(xs): def targetnamesof(items): - if not isinstance(items, (list, tuple, set)): - error("argument of filenamesof is not a list/tuple/set") + assert _isiterable(items), "argument of filenamesof is not a collection" return [t.name for t in items] def filenamesof(items): - if not isinstance(items, (list, tuple, set)): - error("argument of filenamesof is not a list/tuple/set") + assert _isiterable(items), "argument of filenamesof is not a collection" def generate(xs): for x in xs: @@ -371,9 +388,12 @@ def filenameof(x): return xs[0] -def emit(*args): - outputFp.write(" ".join(args)) - outputFp.write("\n") +def emit(*args, into=None): + s = " ".join(args) + "\n" + if into is not None: + into += [s] + else: + outputFp.write(s) def emit_rule(name, ins, outs, cmds=[], label=None): @@ -382,26 +402,35 @@ def emit_rule(name, ins, outs, cmds=[], label=None): nonobjs = [f for f in fouts if not f.startswith("$(OBJ)")] emit("") + + lines = [] if nonobjs: - emit("clean::") - emit("\t$(hide) rm -f", *nonobjs) + emit("clean::", into=lines) + emit("\t$(hide) rm -f", *nonobjs, into=lines) - emit(".PHONY:", name) + emit(".PHONY:", name, into=lines) if outs: - emit(name, ":", *fouts) - if cmds: - emit(*fouts, "&:", *fins) - else: - emit(*fouts, ":", *fins) + emit(name, ":", *fouts, into=lines) + emit(*fouts, "&:", *fins, "\x01", into=lines) if label: - emit("\t$(hide)", "$(ECHO)", label) + emit("\t$(hide)", "$(ECHO) $(PROGRESSINFO) ", label, into=lines) for c in cmds: - emit("\t$(hide)", c) + emit("\t$(hide)", c, into=lines) else: assert len(cmds) == 0, "rules with no outputs cannot have commands" - emit(name, ":", *fins) + emit(name, ":", *fins, into=lines) + + cmd = "".join(lines) + hash = hashlib.sha1(bytes(cmd, "utf-8")).hexdigest() + outputFp.write(cmd.replace("\x01", f"$(OBJ)/.hashes/{hash}")) + + if outs: + emit(f"$(OBJ)/.hashes/{hash}:") + emit( + f"\t$(hide) mkdir -p $(OBJ)/.hashes && touch $(OBJ)/.hashes/{hash}" + ) emit("") From fb25f7572b5e705b656c2dded66e39b0127bb5b9 Mon Sep 17 00:00:00 2001 From: David Given Date: Sat, 21 Sep 2024 00:26:49 +0200 Subject: [PATCH 2/2] Update github scripts. --- .github/workflows/ccpp.yml | 4 ++-- .github/workflows/release.yml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ccpp.yml b/.github/workflows/ccpp.yml index 14980fb..17637ae 100644 --- a/.github/workflows/ccpp.yml +++ b/.github/workflows/ccpp.yml @@ -10,7 +10,7 @@ jobs: build-linux: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v1 + - uses: actions/checkout@v4 with: fetch-depth: 1 - name: apt @@ -26,7 +26,7 @@ jobs: run: PATH=$PATH:$HOME/bin make - name: Upload build artifacts - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v4 with: name: ${{ github.event.repository.name }}.${{ github.sha }} path: | diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 9b0c057..2ce3b25 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -13,7 +13,7 @@ jobs: build-linux: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: fetch-depth: 1