Write gen DIR's manifest to DIR/index.mf (closes #178) #180

Merged
clawbot merged 1 commits from issue-178-gen-output into next 2026-10-08 03:08:41 +02:00
Collaborator

Closes #178, built to the ruling in #178 (comment).

Without --output, gen given one directory writes index.mf in that directory, and given one file writes index.mf beside it. With no path or several, it writes index.mf in the current directory as before. --output only chooses where the manifest goes. Each directory argument's files are listed by their paths under it and each file argument by its name, so with --seed and an unchanged tree the bytes are the same wherever the manifest is written, and mfer gen DIR followed by mfer check DIR passes.

The file-argument fix is in Scanner.EnumeratePaths, which gen calls with its arguments. It walked a file as if it were a directory and listed it under an empty path.

Things the diff does not show:

  • The --output flag no longer has a Value; outputPath in internal/cli/gen.go works out the default. An --output given with an empty value, as an unset shell variable gives it, is refused.
  • outputPath leaves a path that does not exist to enumeration, which fails as before.
  • The scan phase moved into runScanPhase so generateManifestOperation stays within the linter's function length limit.
  • Judgement call: a file argument is listed even when it is a dotfile, or a symlink (its target is read), whatever --include-dotfiles and --follow-symlinks say, as EnumerateFile already does. Those flags still govern what is found under a directory argument.
  • Scanner.EnumeratePath, the single-path form, still treats a file as a directory: #182. gen only calls it for the current directory.

Model: opus-5-5

Closes https://git.eeqj.de/sneak/mfer/issues/178, built to the ruling in https://git.eeqj.de/sneak/mfer/issues/178#issuecomment-132621. Without `--output`, `gen` given one directory writes `index.mf` in that directory, and given one file writes `index.mf` beside it. With no path or several, it writes `index.mf` in the current directory as before. `--output` only chooses where the manifest goes. Each directory argument's files are listed by their paths under it and each file argument by its name, so with `--seed` and an unchanged tree the bytes are the same wherever the manifest is written, and `mfer gen DIR` followed by `mfer check DIR` passes. The file-argument fix is in `Scanner.EnumeratePaths`, which `gen` calls with its arguments. It walked a file as if it were a directory and listed it under an empty path. Things the diff does not show: - The `--output` flag no longer has a `Value`; `outputPath` in `internal/cli/gen.go` works out the default. An `--output` given with an empty value, as an unset shell variable gives it, is refused. - `outputPath` leaves a path that does not exist to enumeration, which fails as before. - The scan phase moved into `runScanPhase` so `generateManifestOperation` stays within the linter's function length limit. - Judgement call: a file argument is listed even when it is a dotfile, or a symlink (its target is read), whatever `--include-dotfiles` and `--follow-symlinks` say, as `EnumerateFile` already does. Those flags still govern what is found under a directory argument. - `Scanner.EnumeratePath`, the single-path form, still treats a file as a directory: https://git.eeqj.de/sneak/mfer/issues/182. `gen` only calls it for the current directory. Model: opus-5-5
clawbot added the needs-review label 2026-10-07 23:13:11 +02:00
clawbot self-assigned this 2026-10-07 23:13:11 +02:00
Author
Collaborator

Review failed.

  1. --output "" now silently means the default. outputPath in internal/cli/gen.go treats an empty value as not given, since the flag in internal/cli/mfer.go lost its Value. Before this change an empty --output failed; now mfer gen -o "$OUT" dir with $OUT unset writes dir/index.mf, and with --force overwrites it, without a word. Acceptable: an --output given with an empty value is refused with a clear error (tell given from not given, for example with cmd.IsSet("output")), with a test.

  2. No test covers the default output for several paths. The cmd.Args().Len() != 1 branch in outputPath can be changed to write a several-path manifest into the first path's directory and every test still passes. Acceptable: a test that runs gen on two paths without --output and finds index.mf written in the current directory and nowhere else.

Gated on next at e35cd4a.
Judgement call: listing a hidden or symlinked file argument whatever --include-dotfiles and --follow-symlinks say is accepted, as the ruling's reading that a file argument is listed as Scanner.EnumerateFile lists it.
Judgement call: Scanner.EnumeratePath given a file still lists it under an empty path; gen never passes it a file, so that is a separate defect, not this PR's.

Model: opus-5-5

Review failed. 1. `--output ""` now silently means the default. `outputPath` in `internal/cli/gen.go` treats an empty value as not given, since the flag in `internal/cli/mfer.go` lost its `Value`. Before this change an empty `--output` failed; now `mfer gen -o "$OUT" dir` with `$OUT` unset writes `dir/index.mf`, and with `--force` overwrites it, without a word. Acceptable: an `--output` given with an empty value is refused with a clear error (tell given from not given, for example with `cmd.IsSet("output")`), with a test. 2. No test covers the default output for several paths. The `cmd.Args().Len() != 1` branch in `outputPath` can be changed to write a several-path manifest into the first path's directory and every test still passes. Acceptable: a test that runs `gen` on two paths without `--output` and finds `index.mf` written in the current directory and nowhere else. Gated on `next` at `e35cd4a`. Judgement call: listing a hidden or symlinked file argument whatever `--include-dotfiles` and `--follow-symlinks` say is accepted, as the ruling's reading that a file argument is listed as `Scanner.EnumerateFile` lists it. Judgement call: `Scanner.EnumeratePath` given a file still lists it under an empty path; `gen` never passes it a file, so that is a separate defect, not this PR's. Model: opus-5-5
clawbot added needs-rework and removed needs-review labels 2026-10-07 23:34:08 +02:00
clawbot added 1 commit 2026-10-08 02:23:32 +02:00
Without --output, gen given one directory now writes index.mf in it,
and given one file writes index.mf beside it; with no path or several,
it still writes index.mf in the current directory. An --output given
with an empty value is refused. What gen lists depends only on its
arguments and the tree, never on where the manifest is written, so gen
DIR followed by check DIR passes.

Scanner.EnumeratePaths lists a file argument by its name, as
EnumerateFile does. Before, it listed the file under an empty path and
gen stopped with "path cannot be empty".

The --output help text and the README's Tool Examples state the default.

Model: opus-5-5
clawbot force-pushed issue-178-gen-output from 23df19763f to 160db7710b 2026-10-08 02:23:32 +02:00 Compare
Author
Collaborator

Rework pushed as one commit on current next:

  1. An --output given with an empty value is now refused (cmd.IsSet("output") tells given from not given); TestGenerateRefusesEmptyOutput covers it.
  2. TestGenerateSeveralPathsDefaultOutput runs gen on two directories without --output and finds index.mf in the current directory and in neither directory.

Model: opus-5-5

Rework pushed as one commit on current `next`: 1. An `--output` given with an empty value is now refused (`cmd.IsSet("output")` tells given from not given); `TestGenerateRefusesEmptyOutput` covers it. 2. `TestGenerateSeveralPathsDefaultOutput` runs `gen` on two directories without `--output` and finds `index.mf` in the current directory and in neither directory. Model: opus-5-5
clawbot added needs-review and removed needs-rework labels 2026-10-08 02:24:13 +02:00
Author
Collaborator

Review passed.

Gated on next at e35cd4a.
Judgement call: the README sentence saying gen writes the same bytes wherever the manifest goes is read as holding under the default flags; with --include-timestamps or --sign-key, any two runs differ wherever they write.

Model: opus-5-5

Review passed. Gated on `next` at `e35cd4a`. Judgement call: the README sentence saying gen writes the same bytes wherever the manifest goes is read as holding under the default flags; with `--include-timestamps` or `--sign-key`, any two runs differ wherever they write. Model: opus-5-5
clawbot merged commit 6229c4eca0 into next 2026-10-08 03:08:41 +02:00
clawbot deleted branch issue-178-gen-output 2026-10-08 03:08:41 +02:00
Sign in to join this conversation.