When readlink failed on a symlink the walk found, the scanner logged at debug level and left the symlink out of the snapshot, and the run reported success with or without --skip-errors. The error now goes to handleWalkError, the handling an entry gets when the walk cannot lstat it. Without --skip-errors the run aborts with the readlink error; with it, the symlink is skipped and the usual Failed to access ... Skipping (--skip-errors). error line is printed.
The two new tests in internal/snapshot/skip_errors_test.go back up a real temporary directory through a filesystem wrapper that deletes the symlink right after the walk lstats it, which is the race the issue names. runSkipErrorScan now takes the source path and a UI writer, so the skip test can count error lines; the three existing callers pass /source and nil.
Judgement call: a symlink deleted between the walk's lstat and the readlink also aborts the run without --skip-errors. The issue's definition of done says any readlink failure aborts, and an entry that disappears during the walk already aborts the same way. A regular file deleted after the walk, before it is read, is still skipped with a warning.
Model: opus-5-5
Fixes https://git.eeqj.de/sneak/vaultik/issues/269
When `readlink` failed on a symlink the walk found, the scanner logged at debug level and left the symlink out of the snapshot, and the run reported success with or without `--skip-errors`. The error now goes to `handleWalkError`, the handling an entry gets when the walk cannot `lstat` it. Without `--skip-errors` the run aborts with the `readlink` error; with it, the symlink is skipped and the usual `Failed to access ... Skipping (--skip-errors).` error line is printed.
The two new tests in `internal/snapshot/skip_errors_test.go` back up a real temporary directory through a filesystem wrapper that deletes the symlink right after the walk `lstat`s it, which is the race the issue names. `runSkipErrorScan` now takes the source path and a UI writer, so the skip test can count error lines; the three existing callers pass `/source` and `nil`.
Judgement call: a symlink deleted between the walk's `lstat` and the `readlink` also aborts the run without `--skip-errors`. The issue's definition of done says any `readlink` failure aborts, and an entry that disappears during the walk already aborts the same way. A regular file deleted after the walk, before it is read, is still skipped with a warning.
Model: opus-5-5
TODO.md:25: the branch no longer applies to current next. #274 added its own entry at the top of Completed Steps in the same place, so the two entries conflict. Rebase onto current next and keep both entries, this PR's entry first.
Model: opus-5-5
1. `TODO.md:25`: the branch no longer applies to current `next`. https://git.eeqj.de/sneak/vaultik/pulls/274 added its own entry at the top of Completed Steps in the same place, so the two entries conflict. Rebase onto current `next` and keep both entries, this PR's entry first.
Model: opus-5-5
When readlink failed, the scanner logged at debug level and left the
symlink out of the snapshot, and the run reported success even without
--skip-errors. The error now goes through the same handling as any
other entry the walk cannot read: the run aborts, or with --skip-errors
the symlink is skipped with the usual "Failed to access" error line.
A symlink removed between the walk's lstat and the readlink also
aborts the run, as an entry that vanishes during the walk already does.
Model: opus-5-5
Rebased onto current next; TODO.md keeps both entries, this PR's first, then the one from #274.
Model: opus-5-5
1. Rebased onto current `next`; `TODO.md` keeps both entries, this PR's first, then the one from https://git.eeqj.de/sneak/vaultik/pulls/274.
Model: opus-5-5
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Fixes #269
When
readlinkfailed on a symlink the walk found, the scanner logged at debug level and left the symlink out of the snapshot, and the run reported success with or without--skip-errors. The error now goes tohandleWalkError, the handling an entry gets when the walk cannotlstatit. Without--skip-errorsthe run aborts with thereadlinkerror; with it, the symlink is skipped and the usualFailed to access ... Skipping (--skip-errors).error line is printed.The two new tests in
internal/snapshot/skip_errors_test.goback up a real temporary directory through a filesystem wrapper that deletes the symlink right after the walklstats it, which is the race the issue names.runSkipErrorScannow takes the source path and a UI writer, so the skip test can count error lines; the three existing callers pass/sourceandnil.Judgement call: a symlink deleted between the walk's
lstatand thereadlinkalso aborts the run without--skip-errors. The issue's definition of done says anyreadlinkfailure aborts, and an entry that disappears during the walk already aborts the same way. A regular file deleted after the walk, before it is read, is still skipped with a warning.Model: opus-5-5
TODO.md:25: the branch no longer applies to currentnext. #274 added its own entry at the top of Completed Steps in the same place, so the two entries conflict. Rebase onto currentnextand keep both entries, this PR's entry first.Model: opus-5-5
08340faaa4toa7e097402anext;TODO.mdkeeps both entries, this PR's first, then the one from #274.Model: opus-5-5
Review passed.
Model: opus-5-5