Repository navigation
Conversation
A dotfiles-managed config.toml (or herdr directory) is a symlink, and setup refused it with 'Too many levels of symbolic links'. Resolve the config file and directory links first, then run the fd-pinned flow on the real file: stage, rename and back up beside the target, keep the link, and keep generated assets and the lock beside the configured path. Dangling and looping links are refused before any write.
|
The latest updates on your projects. Learn more about Vercel for GitHub. |
A loop or a non-directory in a directory along the link target returned raw ELOOP/ENOTDIR. Map both to the existing 'loops' and 'points at missing' refusals, naming the configured path. Cover a config link into a linked directory and a target basename other than config.toml.
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #129.
tsk setup herdr(and--check) failed withToo many levels of symbolic linkswhen~/.config/herdr/config.tomlis a symlink, as dotfiles managers create.What changed
src/setup.rs: newfollow_links/resolve_configresolve the config directory link, then the config file link (relative, absolute, chained), before the existing fd-pinned flow runs.Dir(dir_unix.rs/dir_windows.rs) is unchanged, so the state-dir andtsk-pluginshardening stays as it was.herdr config check, atomic rename, backup → beside the real file (the link is never replaced)tsk-plugins/and.tsk-setup.lock→ beside the configured path (so a file link doesn't put generated assets into the dotfiles repo)HERDR_CONFIG_PATH); Herdr follows the link itself--checkon a dangling or looping link exits non-zero with empty stdout. The installers read stdout= boundwith stderr discarded, so they treat it as unbound. No change to the probe's shape.std::fs, so it runs on both platforms. Known limit (F-4, deliberate): Windows still refuses a reparse-point/symlinked ancestor directory of the resolved paths through the hardened reparse check, so a linked file whose target sits under a linked directory is refused there. Follow-up if someone reports it.config.toml -> loopdir/config.toml,loopdir -> loopdir) used to return a rawToo many levels of symbolic links. It now returnsHerdr config symlink … loops; fix the link. A regular file along the target (ENOTDIR) now returns… points at missing …. All threefollow_linkscall sites name the configured path.Judgment call to review: following a symlinked
herdr/directory (GNU stow folds directories this way) reverses two cases of the oldsymlink_config_and_parent_and_assets_are_refusedtest. Those two moved to the new tests; the asset, scripts, root, base, and lock symlink refusals still hold (symlinked_assets_and_lock_are_refused). With a directory link,tsk-plugins/lands in the linked directory, because that is the config directory.Tests
tests/setup_safety.rs:symlinked_config_is_edited_through_the_link(absolute, relative../outside/dotfiles/config.toml, chained): the link is kept, the target is edited, there is one backup beside the target and none beside the link, assets and lock stay beside the link, no staging files are left over,--checksaysbound, and a rerun makes no new backupsymlinked_config_directory_is_followedconfig_link_into_a_linked_directory_edits_the_real_directory(F-7/F-8):config.toml -> ../outside/dotlink/<name>,dotlink -> dotfiles[/v2], for bothconfig.tomlandherdr.toml. Both links are kept, the real file is edited, and staging and the backup land in the real directory (not through the link).--checkgoesunbound→bound. It fails whenfollow_links(dir)is replaced withdir.to_path_buf()(cannot open directory …/dotlink (symlinks refused)). The backup is still namedconfig.toml.tsk-backup-*for aherdr.tomltarget, matching the documented name.dangling_or_looping_config_link_is_refused_without_writes(dangling, self, pair, loop dir along the target, regular file along the target); with the loop mapping removed, it fails with the raw ELOOP: setup and--checkboth refused, zero host calls, nothing writtensrc/setup/tests.rs: a cross-platformrun_attest with a symlinked file (on Windows it skips if the symlink privilege is missing), plus afollow_linksunit testtests/cli_setup_agent.rs: the--checkassertion now expectsboundfor a linked config and a refusal for a dangling oneresolve_configstubbed to identity, the three new integration tests fail, two of them with the tsk setup herdr fails when herdr config is a symlink #129 message (cannot open …/config.toml (symlinks/non-directories refused): Too many levels of symbolic links (os error 62)). Fix restored, all green.cargo fmt --check && cargo clippy --all-targets -- -D warnings && cargo testgreen;cargo clippy --all-targets --target x86_64-pc-windows-gnu -- -D warningsgreen;site/ npm test0 failures.Docs:
cli.md(setup herdr),install.md(backup bullet),packaging/README.md(setup contract + review-scope note),CHANGELOG.mdUnreleased → Fixed.Before / after
Both binaries are release builds: before =
origin/main39e3a8e, after = this branch. They ran against the realherdr 0.9.3with full isolation (HOME,XDG_CONFIG_HOME,XDG_STATE_HOME,HERDR_SOCKET_PATH=<nonexistent>,TSK_STATE_DIR,HERDR_CONFIG_PATHunset). The scenario is/tmp/tsk-t211-scenario.sh:~/.config/herdr/config.tomlis a symlink todotfiles/herdr/config.toml. Herdr's plugin registry was written only inside the isolated roots.Before (
/tmp/tsk-t211-before):After (
/tmp/tsk-t211-after):How to test
Herdr tabs (already running, workspace
w9D): tabbeforeand tabaftereach show the scenario output above, and each shell is idle. To rerun, press↑thenEnterin either tab. That rerunssh /tmp/tsk-t211-scenario.sh before|after, which rebuilds fresh isolated roots each time.What to look for:
before: all three commands printToo many levels of symbolic linksand exit 1, and the dotfiles config has noherdr-tsklines.after:unbound, then setup succeeds with the backup underdotfiles/herdr/, thenbound. The link is still a link, and the dotfiles config now has bothherdr-tsk.*commands.From any shell (throwaway roots under
/tmp; never touches~/.tskor your Herdr):Edge cases by hand (after binary):
The binaries stay at
/tmp/tsk-t211-beforeand/tmp/tsk-t211-afterfor reruns.