Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,14 @@ help: ## Show this help
install: ## Install devflow to PREFIX (~/.local by default)
@mkdir -p $(BINDIR) $(LIBDIR)
@cp -R lib templates skills config docker $(LIBDIR)/
@rm -f $(LIBDIR)/devflow-bin
@cp bin/devflow $(LIBDIR)/devflow-bin
@chmod 755 $(LIBDIR)/devflow-bin
@# rm -f BEFORE the redirect: if $(BINDIR)/devflow is a leftover `make link` SYMLINK,
@# `printf > symlink` follows it and overwrites the TARGET (the source bin/devflow),
@# gutting the checkout while leaving the symlink in place. Removing it first makes
@# install REPLACE the symlink with a real launcher (idempotent + symlink-safe).
@rm -f $(BINDIR)/devflow
@printf '#!/usr/bin/env bash\nexport DEVFLOW_ROOT="%s"\nexec "%s/devflow-bin" "$$@"\n' \
"$(LIBDIR)" "$(LIBDIR)" > $(BINDIR)/devflow
@chmod 755 $(BINDIR)/devflow
Expand Down
20 changes: 20 additions & 0 deletions tests/unit/init.bats
Original file line number Diff line number Diff line change
Expand Up @@ -88,3 +88,23 @@ teardown() {
assert_output --partial "Skip"
refute_output --partial "Added"
}

# ── make install: symlink-safe (regression for the write-through-symlink bug) ──

@test "make install replaces a leftover 'make link' symlink instead of writing through it" {
local prefix="${BATS_TEST_TMPDIR}/prefix"
mkdir -p "$prefix/bin"
# sentinel standing in for the source bin/devflow a leftover symlink would point at
local sentinel="${BATS_TEST_TMPDIR}/source-bin-devflow"
printf 'FULL SOURCE SCRIPT — must not be overwritten\n' > "$sentinel"
ln -sf "$sentinel" "$prefix/bin/devflow" # leftover `make link` symlink

run make -C "$DEVFLOW_ROOT" install PREFIX="$prefix"
assert_success

# BINDIR/devflow must be a REAL launcher now, not the symlink...
[ ! -L "$prefix/bin/devflow" ] || fail "BINDIR/devflow is still a symlink (wrote through it)"
# ...and the symlink target (stand-in for the source checkout) must be UNTOUCHED
run cat "$sentinel"
assert_output --partial "FULL SOURCE SCRIPT"
}
Loading