Skip to content

Make the symlink action idempotent, matching its advertised ln -sf semantics - #599

Open
joahg wants to merge 1 commit into
cashapp:masterfrom
joahg:joah/idempotent-symlink
Open

Make the symlink action idempotent, matching its advertised ln -sf semantics#599
joahg wants to merge 1 commit into
cashapp:masterfrom
joahg:joah/idempotent-symlink

Conversation

@joahg

@joahg joahg commented Aug 5, 2026

Copy link
Copy Markdown

Context: #597 — composing agent-skills-style content packages from existing Hermit primitives.

SymlinkAction.String() reports the action as ln -sf, but Apply() calls os.Symlink directly, which fails with file exists on any subsequent run. This makes symlink actions in on activate triggers unusable across repeated activations without a delete workaround that relies on undocumented action ordering.

Apply now follows ln -sf semantics: an existing symlink already pointing at the source is left alone, an existing symlink or regular file is replaced, and a directory at the destination is refused with an error (as ln -sf does, and to avoid destroying user data).

Tested with go test ./... and golangci-lint run.

SymlinkAction.String() reports the action as "ln -sf", but Apply()
calls os.Symlink directly, which fails with "file exists" on any
subsequent run. This makes symlink actions in "on activate" triggers
unusable across repeated activations without a delete workaround.

Apply now follows ln -sf semantics: an existing symlink already pointing
at the source is left alone, an existing symlink or regular file is
replaced, and a directory at the destination is refused with an error
(as ln -sf does, and to avoid destroying user data).

Buzz-Message: buzz://message?channel=573ff355-6c19-422d-b425-112853d0ec7e&id=16f5b666c0976829a1985868753407c7b20b393d89f99a8b39106be9fe6a1514
Amp-Thread-ID: https://ampcode.com/threads/T-019fce27-e59e-727c-b6d3-cdeeba894a4e
Co-authored-by: Amp <amp@ampcode.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant