summaryrefslogtreecommitdiff
path: root/src/lib/action.source.sh
diff options
context:
space:
mode:
authorPaul Buetow <paul@buetow.org>2026-06-17 21:45:40 +0300
committerPaul Buetow <paul@buetow.org>2026-06-17 21:45:40 +0300
commiteb8cbbbcb9a613757ac4440246c43ebba6758afe (patch)
tree08ecc67cbc3d265d1e0379ba965017c06ca3a790 /src/lib/action.source.sh
parent25aff490d739290602b28bdc53936dd3ea6ed939 (diff)
ln0 make --clean remove leftover staging directories
The --clean action deleted DIST_DIR but left behind the staging/backup directories the generation pipeline creates as siblings of DIST_DIR (.shuriken.<basename>.staging.* / .backup.*). Users expect --clean to remove all generation output, so extend it to also delete those. Cleanup runs after the validate_clean_dist_dir safety guard (8n0), so a dangerous DIST_DIR still aborts before any deletion. It only matches shuriken's own basename-specific staging/backup prefixes (the exact mktemp templates from config.staging.source.sh), uses nullglob so a missing match never expands to a literal pattern, and only removes directories. Unrelated dotfiles in the parent are never touched. Update test_clean to assert the staging/backup dirs are removed while unrelated entries survive, and document the behavior in the CLI usage text and README. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Diffstat (limited to 'src/lib/action.source.sh')
-rw-r--r--src/lib/action.source.sh44
1 files changed, 44 insertions, 0 deletions
diff --git a/src/lib/action.source.sh b/src/lib/action.source.sh
index 425e009..4ff5d68 100644
--- a/src/lib/action.source.sh
+++ b/src/lib/action.source.sh
@@ -98,6 +98,44 @@ log_configured_action() {
log_verbose "Effective force generation setting: $SHURIKEN_FORCE_GENERATE"
}
+# Remove leftover generation staging/backup directories for DIST_DIR (ln0).
+#
+# The generation pipeline (config.staging.source.sh) stages output in sibling
+# directories of DIST_DIR named via mktemp templates
+# ".shuriken.<basename>.staging.XXXXXX" and ".shuriken.<basename>.backup.XXXXXX"
+# in DIST_DIR's parent. A crash or kill can leave these behind, so --clean
+# removes them too -- otherwise "clean" would not actually clean all generation
+# output (Principle of Least Astonishment).
+#
+# Safety: callers MUST run validate_clean_dist_dir first so a dangerous DIST_DIR
+# aborts before any deletion. We only match shuriken's own, basename-specific
+# staging/backup prefixes (never a loose ".shuriken.*" or arbitrary dotfiles),
+# derive the parent exactly as the staging code does (dirname "$DIST_DIR"), and
+# use nullglob so a missing match never expands to a literal pattern to rm.
+clean_generation_staging_artifacts() {
+ local final_base final_parent artifact
+ local -a artifacts=()
+
+ final_base=$(basename "$DIST_DIR")
+ final_parent=$(dirname "$DIST_DIR")
+
+ # nullglob: a non-matching glob expands to nothing rather than to the
+ # literal pattern, so we never accidentally rm a path called "*".
+ shopt -s nullglob
+ artifacts=(
+ "$final_parent/.shuriken.$final_base.staging."*
+ "$final_parent/.shuriken.$final_base.backup."*
+ )
+ shopt -u nullglob
+
+ for artifact in "${artifacts[@]}"; do
+ if [ -d "$artifact" ]; then
+ log_info "Cleaning leftover staging directory $artifact"
+ rm -rf "$artifact"
+ fi
+ done
+}
+
run_configured_action() {
local rc_file
local -i status=0
@@ -135,6 +173,12 @@ run_configured_action() {
else
log_verbose "Output directory does not exist: $DIST_DIR"
fi
+
+ # Also remove any leftover staging/backup directories that the
+ # generation pipeline created as siblings of DIST_DIR. This stays
+ # behind the validate_clean_dist_dir guard above (so a dangerous
+ # DIST_DIR aborts before any deletion).
+ clean_generation_staging_artifacts
;;
--generate)
validate_generation_config