Files
Austin Horstman 0560d64401 generators: replace mkImpureConfigMerger targets atomically
The merge overwrote the target in place with `cat "$tmp" > path`, so a
crash mid-write could leave a truncated file, and an application that
saved its config while activation ran had that change silently
overwritten.

Snapshot the existing file, write the merged result to a temporary
file next to the resolved target, copy the existing mode (or apply
`mode` or the umask for a new file), and rename it into place. The
snapshot keeps the configured file name inside a temporary directory,
so a reader that detects the format from the extension still
recognizes it, even through a symlink to a differently named file.
Symlinked targets are written through and stay symlinks; a dangling
symlink creates its target, as the hand-written mergers this helper
replaced did. Activation fails without writing if the content, the
mode, or the symlink target changed since the snapshot, and refuses
targets inside the Nix store. A target that cannot be renamed over,
such as a file bind-mounted by impermanence, is written in place
instead. Temporary files are cleaned up by a trap scoped to a
subshell, since activation owns the top-level EXIT trap; this also
keeps the merge's shell variables out of the activation script.

The change check is not a lock: a write between the final check and
the rename is still lost. The documentation says so, along with the
attributes a rename does not preserve.

This follows the approach programs.vscode uses for its mutable user
settings.
2026-10-02 10:30:05 -05:00
..
2025-05-07 10:34:18 -05:00
2026-09-22 16:00:21 -05:00
2026-06-19 10:00:25 -05:00