You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit dd5ffca
Browse filesBrowse the repository at this point in the historyBrowse files
recipe: a recipe can build on a preset, on the command line and on the batch screen
extends: preset:<id> names a preset and with: fills its parameters, written
the way the flags take them. The preset's targets come first and the file's
own after them, so the file is the same run as "tfg preset eject" with the
extra targets typed under it, byte for byte - PR5 in a second form, and a
guard runs both roads and compares the files. A target whose id the preset
already uses is refused at the file's own line, with without extends is
refused, and extends names a preset and nothing else yet. A file with
extends and no targets of its own is legal: it is a preset run committed
to a repository. The owner's three decisions, in
docs/EXTENDS-WITH-2026-09-22.md: the window in the same change, the
recipe hash of the file as written, the clash addressed at the file's
target.
The recipe package cannot expand a preset - the layer rule lets preset
import recipe and not the other way - so reading such a file is two steps
with the expansion between them. recipe.ExtensionOf says what the file
builds on, recipe.ParseExtending reads it with the expansion in front of
its targets, and preset.ReadRecipe joins the two; a guard holds cli and
gui to reading files through that door. The merge is at the raw level,
before validation, so every rule about targets runs once where it lives,
and a refusal about the file's target carries its position in the file,
not in the merged list. recipe.CheckBase holds every preset to
contributing a version and targets and nothing else, asked of each
registered preset by a guard before any recipe builds on one.
Refusals from the preset side become recipe problems addressed to extends
or with.<name>, in four parts - which found a refused value arriving with
no remedy, now carried from the declaration. The manifest records the
preset under run.preset as a --preset run does, validate --json carries
the same block, and the batch screen gains a section: a switch, the
preset, and its parameters drawn from the declaration the preset screen
already draws. Parity 122 of 130. Five guards, nine mutations, one more
stored screen.
Noticed on the way and recorded as O231, not changed: the batch screen's
label switch starts off while the other two surfaces have the label on.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Copy file name to clipboardExpand all lines: README.md
+32-2Lines changed: 32 additions & 2 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -428,6 +428,8 @@ tfg generate fixtures.yaml
428
428
|`seed`| the number that makes a run repeatable. Same seed, same bytes |
429
429
|`defaults.label`| write the self describing label inside each file. Default `true`|
430
430
|`targets`| the list of things to produce. See below |
431
+
|`extends`| a preset to build on, as `preset:size-boundaries`. Its files come first and your `targets` are added after them. See [Building on a preset](#building-on-a-preset)|
432
+
|`with`| the preset's parameters, written the way the flags take them: `limit: 5mb`, `spread: 1B,1kb,1mb`, `format: png`. One left out stands in from its default, and the manifest says so |
431
433
|`output.dir`| where the files and the manifest go. A relative path is read from the directory you run in, not from the one the recipe sits in |
// The second sentence names both roads, because since 2026-09-22 a
280
+
// recipe file can build on the preset too - and beside a file the flag
281
+
// does not exist either, the file's with section is where the value goes.
273
282
fmt.Fprintf(errOut,
274
-
"tfg: --%s is a parameter of the preset %s, so it only exists beside it. Add --preset %s, or drop --%s.\n",
275
-
name, owner, owner, name)
283
+
"tfg: --%s is a parameter of the preset %s, so it only exists beside it. Add --preset %s, put %s under with: in a recipe that extends it, or drop --%s.\n",
Copy file name to clipboardExpand all lines: internal/cli/presetcmd.go
+5-2Lines changed: 5 additions & 2 deletions
Original file line number
Diff line number
Diff line change
@@ -241,8 +241,11 @@ func describePreset(e *preset.Expansion, b budget, out io.Writer) {
241
241
fmt.Fprintf(out, " - %s\n", c)
242
242
}
243
243
}
244
-
fmt.Fprintf(out, "\nRun \"tfg preset eject %s\" for the recipe, or \"tfg generate --preset %s\" to produce the files.\n",
245
-
p.ID, p.ID)
244
+
// Three roads to the same set, and all three are named: the third
245
+
// arrived on 2026-09-22 and a setting nobody knows they can reach is a
246
+
// setting that is not there.
247
+
fmt.Fprintf(out, "\nRun \"tfg preset eject %s\" for the recipe, \"tfg generate --preset %s\" to produce the files, or write \"extends: preset:%s\" in a recipe of your own.\n",
248
+
p.ID, p.ID, p.ID)
246
249
}
247
250
248
251
funcpresetEject(args []string, out, errOut io.Writer) int {
0 commit comments