Skip to content

feat(path): plan and write reviewed PATH edits with backups - #155

Merged
ado11231 merged 1 commit into
ado11231:masterfrom
sharmis-tp:issue-148-path-edits
Oct 28, 2026
Merged

ado11231 merged 1 commit into
ado11231:masterfrom
sharmis-tp:issue-148-path-edits

Conversation

@sharmis-tp

Copy link
Copy Markdown
Contributor

Closes #148

The neet-core side of reviewed PATH edits, as agreed in the issue. The Settings diff review comes in a follow-up PR.

What it does

  • New path::edit module. plan takes a Listing and the requested Remove(i) / Move(i, First | Last) changes and returns each shell file's text before and after. It is pure: file text comes in through a closure.
  • Origin::Line: the folder is taken out of its line in place, and the other folders stay. If only $PATH is left, the whole line goes. If nothing would be left, the change is refused.
  • Only lines neet can fully read are changed: PATH= or export PATH=, with an optional double-quoted value and comment, holding only full paths, $HOME/${HOME}/~ (~ only without quotes), and $PATH/${PATH}. neet refuses $(...), backticks, &&, ;, single quotes, other variables, path=(...), continued lines, and lines inside an if, a loop, a function, or brackets.
  • Moves take the folder out of its line and add export PATH="<folder>:$PATH" (or "$PATH:<folder>") at the end of the # >>> neet >>> block in ~/.zshrc, through a new zsh::append shared with Configure. Moves from bash or fish files are refused, because only zsh reads .zshrc.
  • Origin::Tool, Origin::System, and Origin::Unknown are refused, so mise, brew shellenv, and /etc/paths are never changed.
  • Every copy of a folder points at the first line that names it. A removal that would also take away a copy you keep is refused, unless another line still adds that folder.
  • prepare opens the files with dotfiles::change::Edit::begin, so view-only files and chezmoi work as they do for Dotfiles. write runs change::check on each new text first and writes nothing if a check fails. Then it writes each file through Edit::finish, with its backup in ~/.local/state/neet/backups/dotfiles, so Dotfiles can restore it.

Checks

  • cargo fmt --all --check
  • cargo clippy --workspace --all-targets --all-features -- -D warnings
  • cargo test --workspace --all-features: run on Linux in Docker as a non-root user with zsh installed. 9 new tests pass. The only failures are the same 12 macOS-only tests (osascript, defaults, launchctl, getconf) that also fail on master there.
  • cargo check --workspace --all-targets --all-features --locked with Rust 1.88
  • The tests cover: lines with several folders, removing a line left with only $PATH, refusing $(...), backticks, conditionals, ;, other variables, quotes, arrays, continued lines and if/function blocks, refusing tools, system lists and unknown origins, moves into a new or existing neet block, a broken block, moves from bash files, repeated copies, lines that changed after the listing, backups and restore through Dotfiles, and writing nothing after a failed zsh -n or a file changed after review.

Notes

  • The diff is larger than the 200-line commit guideline (about 440 lines of code and 320 of tests). I can split it into two commits, the planner and then prepare/write, if you prefer.
  • docs/ARCHITECTURE.md: one table row now lists path/. It needs your approval. I left SAFETY.md and FEATURES.md alone, because Shell PATH stays view-only until the Settings PR.
  • Question: moving a folder that was added in .zshenv or .zprofile into the .zshrc block means only interactive shells get it. Should those moves be refused, or shown as a warning in the review?

@ado11231

Copy link
Copy Markdown
Owner

Thanks a lot for this, it's really well done. The planner follows exactly what was agreed in #148, the "when in doubt, refuse" approach is just right for editing people's shell files, and going through Edit::begin/finish means backups and restore work for free. The tests are great too.

Regarding your questions:

  • One commit or two: one is totally fine here, no need to split.

  • ARCHITECTURE.md: the path/ row is approved, thanks for leaving SAFETY/FEATURES for the Settings PR.

  • Moves from .zshenv / .zprofile: let's refuse those for now, the same as bash/fish files. .zshenv is also read by scripts and editors, so moving a folder into .zshrc could quietly break them. We can add a warning later if people ask for it. This can go in the Settings PR, no need to change this one.

  • plan is described as pure, but source() calls shell_lines(home), which reads from disk. It could go through the read closure instead.

  • Moving two copies of the same folder writes it twice in the block ("/a:/a:$PATH").

Merging now. Thank you! :)

@ado11231
ado11231 merged commit fb82a11 into ado11231:master Oct 28, 2026
9 checks passed
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.

feat(path): reviewed PATH edits with backups

2 participants