Commitd0f9618bRecorded22 Sep 2026Repositorydocket
docket wrapper: tolerate a concurrent move of the shadowing (sigil args), refuse anything else
Message
Two docket commands started together can both see args.sgb and race to move it; the loser's mv failed and set -e killed a command whose load path was already clean. The move now tolerates exactly that case (the file is gone) and dies loudly if the file is still in the load path.
Tested: fresh build, four concurrent 'docket fold' calls, all rc=0 with identical output. With the aside directory made read-only, the command refuses naming the file and t-de026a (rc=1).
Changed
docket | 11 +++++++++--
1 file changed, 9 insertions(+), 2 deletions(-)Diff
docketmodified
@@ -48,8 +48,15 @@ unshadow_cli_modules() {
48
for f in "$lib/args.sgb" "$lib/args.sgb.sgci" "$lib/args.json" "$lib/args.sgs"; do 49
[[ -e $f ]] || continue 50
mkdir -p "$aside"−51
mv -f "$f" "$aside/"−52
moved="$moved ${f##*/}"+51
# Two docket commands started together can both see the file and race to+52
# move it. The loser's mv fails, and under `set -e' that would kill a+53
# command over a file that is already where it should be. Tolerate exactly+54
# that case -- the file is gone from the load path -- and nothing else.+55
if mv -f "$f" "$aside/" 2>/dev/null; then+56
moved="$moved ${f##*/}"+57
elif [[ -e $f ]]; then+58
die "could not move $f out of the load path (t-de026a workaround)"+59
fi 60
done 61
if [[ -n $moved ]]; then 62
echo "docket: moved (sigil args) out of build/dev/lib into ${aside##*/}/ --$moved" >&2