Skip to content

fix(config): preserve symlinked config.json on atomic save#193

Open
FunJim wants to merge 1 commit into
TomBadash:masterfrom
FunJim:fix/preserve-symlinked-config
Open

fix(config): preserve symlinked config.json on atomic save#193
FunJim wants to merge 1 commit into
TomBadash:masterfrom
FunJim:fix/preserve-symlinked-config

Conversation

@FunJim
Copy link
Copy Markdown

@FunJim FunJim commented May 31, 2026

Summary

  • When ~/Library/Application Support/Mouser/config.json (or the Linux equivalent) is a symlink — typically managed via GNU stow into a dotfiles repo — save_config was clobbering the symlink with a regular file on every save.
  • Root cause: os.replace(tmp_path, CONFIG_FILE) calls rename(2), which by POSIX semantics replaces the symlink itself rather than following it.
  • Fix: resolve CONFIG_FILE via os.path.realpath() and place the tempfile in the resolved target's directory, so the atomic rename updates the link's target in place. For regular files the realpath equals the original path, so behavior is unchanged.

Test plan

  • python -m unittest discover -s tests — 499 tests pass
  • New tests in tests/test_config.py cover regular file, stowed symlink, and dangling symlink cases
  • Manually verified with a GNU stow-managed config on macOS

When config.json is a symlink (e.g. managed by GNU stow into a dotfiles
repo), os.replace(tmp_path, CONFIG_FILE) overwrote the link itself with
a regular file — rename(2) operates on the path, not the symlink target.
Resolve CONFIG_FILE via os.path.realpath() and place the tempfile next
to the resolved target so the atomic rename updates the link's target
in place. Covers regular-file, stowed-symlink, and dangling-symlink
cases via new tests in test_config.py.
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