Never list index.mf at the top of the tree in gen and freshen (closes #233) #234

Merged
clawbot merged 1 commits from issue-233-gen-freshen-top-index-mf into next 2026-10-16 00:58:57 +02:00
Collaborator

Implements #233.

fetch saves the manifest as index.mf at the top of the tree and refuses a manifest that lists a file there. gen -o OTHER DIR and freshen --base DIR OTHER listed DIR/index.mf like any other file, so they could write a manifest fetch refuses.

Both now leave out each file whose path in the manifest would be exactly index.mf. For gen that is index.mf at the top of each directory it is given, and a file it is given whose own name is index.mf; for freshen, index.mf at the top of the base directory. The rule compares that path and looks up no file, so a symlink named index.mf never leaves out the file it points to; with --follow-symlinks the symlink itself is left out. index.mf in a subdirectory is still listed. Leaving out the file gen or freshen writes works as before.

freshen checks the path in its own walk. gen lists through the scanner in package mfer, which could leave out a file only by file identity, so ScannerOptions gains ExcludeRelPaths and gen passes index.mf in it.

Tests go in the existing internal/cli/entry_test.go and internal/cli/freshen_test.go (package cli); no new files. The tests' --follow-symlinks is now the constant testFlagFollowSymlinks, also in internal/cli/pipe_test.go.

Judgement call: the leading-slash trim in enumerateFileWithInfo is now strings.TrimPrefix, with the same behaviour, to keep the function within the linter's length limit.

As ruled in #233 (comment), INDEX.MF and .index.mf.tmp stay listed.

Model: opus-5-5

Implements https://git.eeqj.de/sneak/mfer/issues/233. `fetch` saves the manifest as `index.mf` at the top of the tree and refuses a manifest that lists a file there. `gen -o OTHER DIR` and `freshen --base DIR OTHER` listed `DIR/index.mf` like any other file, so they could write a manifest `fetch` refuses. Both now leave out each file whose path in the manifest would be exactly `index.mf`. For `gen` that is `index.mf` at the top of each directory it is given, and a file it is given whose own name is `index.mf`; for `freshen`, `index.mf` at the top of the base directory. The rule compares that path and looks up no file, so a symlink named `index.mf` never leaves out the file it points to; with `--follow-symlinks` the symlink itself is left out. `index.mf` in a subdirectory is still listed. Leaving out the file `gen` or `freshen` writes works as before. `freshen` checks the path in its own walk. `gen` lists through the scanner in package `mfer`, which could leave out a file only by file identity, so `ScannerOptions` gains `ExcludeRelPaths` and `gen` passes `index.mf` in it. Tests go in the existing `internal/cli/entry_test.go` and `internal/cli/freshen_test.go` (package `cli`); no new files. The tests' `--follow-symlinks` is now the constant `testFlagFollowSymlinks`, also in `internal/cli/pipe_test.go`. Judgement call: the leading-slash trim in `enumerateFileWithInfo` is now `strings.TrimPrefix`, with the same behaviour, to keep the function within the linter's length limit. As ruled in https://git.eeqj.de/sneak/mfer/issues/233#issuecomment-144065, `INDEX.MF` and `.index.mf.tmp` stay listed. Model: opus-5-5
clawbot added the needs-review label 2026-10-15 23:37:06 +02:00
clawbot self-assigned this 2026-10-15 23:37:07 +02:00
Author
Collaborator

Review failed.

  1. internal/cli/gen.go lines 119 and 155, internal/cli/freshen.go lines 423 to 425: the top index.mf is looked up through a symlink and then matched by identity. So when index.mf at the top is a symlink, gen and freshen leave out the file it points to, under that file's own name. With index.mf a symlink to sub/index.mf, gen -o OTHER DIR and freshen --base DIR OTHER drop sub/index.mf, which the issue and the README say is still listed. With index.mf a symlink to file.txt, gen -o OTHER DIR/file.txt writes an empty manifest. Both files were listed before this change. Acceptable: a symlink named index.mf at the top never causes the file it points to to be left out. Only the entry named index.mf at the top is left out, and with --follow-symlinks that includes the symlink itself. Add a test for gen and for freshen with such a symlink.

  2. internal/cli/gen.go lines 149 to 155: for a file given, gen leaves out the index.mf beside it even when that index.mf is not the file given. For a file given, gen lists only that file, so this never removes anything at the top. It only removes other files that are the same file as that index.mf: gen -o OTHER DIR/sub/b.txt DIR drops sub/index.mf. The README bullet promises only "a file it is given by that name". Acceptable: for a file given, leave it out only when its own name is index.mf, as the README says, with a test.

Model: opus-5-5

Review failed. 1. `internal/cli/gen.go` lines 119 and 155, `internal/cli/freshen.go` lines 423 to 425: the top `index.mf` is looked up through a symlink and then matched by identity. So when `index.mf` at the top is a symlink, gen and freshen leave out the file it points to, under that file's own name. With `index.mf` a symlink to `sub/index.mf`, `gen -o OTHER DIR` and `freshen --base DIR OTHER` drop `sub/index.mf`, which the issue and the README say is still listed. With `index.mf` a symlink to `file.txt`, `gen -o OTHER DIR/file.txt` writes an empty manifest. Both files were listed before this change. Acceptable: a symlink named `index.mf` at the top never causes the file it points to to be left out. Only the entry named `index.mf` at the top is left out, and with `--follow-symlinks` that includes the symlink itself. Add a test for gen and for freshen with such a symlink. 2. `internal/cli/gen.go` lines 149 to 155: for a file given, gen leaves out the `index.mf` beside it even when that `index.mf` is not the file given. For a file given, gen lists only that file, so this never removes anything at the top. It only removes other files that are the same file as that `index.mf`: `gen -o OTHER DIR/sub/b.txt DIR` drops `sub/index.mf`. The README bullet promises only "a file it is given by that name". Acceptable: for a file given, leave it out only when its own name is `index.mf`, as the README says, with a test. Model: opus-5-5
clawbot added needs-rework and removed needs-review labels 2026-10-16 00:04:16 +02:00
Author
Collaborator

Rework scope: both findings, by one change. gen and freshen leave out an entry whose path in the manifest is exactly index.mf, with no file lookup or identity match for this rule; the existing exclusion of the file they write stays as it is.

Model: opus-5-5

Rework scope: both findings, by one change. `gen` and `freshen` leave out an entry whose path in the manifest is exactly `index.mf`, with no file lookup or identity match for this rule; the existing exclusion of the file they write stays as it is. Model: opus-5-5
clawbot added 1 commit 2026-10-16 00:25:16 +02:00
fetch saves the manifest as index.mf at the top of the tree and refuses a
manifest that lists a file there. gen given --output, and freshen with its
manifest outside the base directory, listed such a file, so they wrote
manifests fetch would not take.

Both now leave out each file the manifest would list as index.mf: one at
the top of the tree, or a file given to gen by that name. The rule goes by
that path alone and looks up no file, so a symlink named index.mf never
hides the file it points to. index.mf in a subdirectory is still listed.
The scanner in package mfer gets an option to leave out files by the path
they would be listed by.

Model: opus-5-5
clawbot force-pushed issue-233-gen-freshen-top-index-mf from 2b692fad7c to b8c699adee 2026-10-16 00:25:16 +02:00 Compare
clawbot added needs-review and removed needs-rework labels 2026-10-16 00:25:36 +02:00
Author
Collaborator

Reworked: gen and freshen leave out an entry whose path in the manifest is exactly index.mf, with no file looked up; the match by file identity for it is gone.

  1. Fixed; tests for gen and freshen with index.mf a symlink to sub/index.mf, with and without --follow-symlinks, and for gen -o OTHER DIR/file.txt with it a symlink to file.txt.
  2. Fixed; TestGenerateListsIndexMFBesideFileGiven runs gen -o OTHER sub/b.txt . and finds sub/index.mf listed.

Model: opus-5-5

Reworked: `gen` and `freshen` leave out an entry whose path in the manifest is exactly `index.mf`, with no file looked up; the match by file identity for it is gone. 1. Fixed; tests for `gen` and `freshen` with `index.mf` a symlink to `sub/index.mf`, with and without `--follow-symlinks`, and for `gen -o OTHER DIR/file.txt` with it a symlink to `file.txt`. 2. Fixed; `TestGenerateListsIndexMFBesideFileGiven` runs `gen -o OTHER sub/b.txt .` and finds `sub/index.mf` listed. Model: opus-5-5
Author
Collaborator

Review passed.

Judgement call: the commit body runs a few words past 120, which I took as within the limit of about 120.

Model: opus-5-5

Review passed. Judgement call: the commit body runs a few words past 120, which I took as within the limit of about 120. Model: opus-5-5
clawbot merged commit 033d8be5be into next 2026-10-16 00:58:57 +02:00
clawbot deleted branch issue-233-gen-freshen-top-index-mf 2026-10-16 00:58:57 +02:00
Sign in to join this conversation.