Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,14 @@ because it turns other people's test suites red.

### Added

- **Generate into the same folder again.** A run into an output directory
that already holds an earlier run is added beside it: every name of the run,
its manifest's too, gets a number, such as `files-2_0001.pdf` and
`manifest-2.json`, and nothing already there changes. In the window this is
Add beside earlier runs under the output directory, on unless you turn it
off. On the command line it is `--number-if-taken`. When the number would
make a name too long for a file name, the run is refused with code `5`.

- **Drop a folder or a file onto the window.** A folder dropped onto Single
batch, Presets or Several batches becomes the output directory. On the Tools
screen it goes into the box of the chosen tool when the tool takes that
Expand Down
9 changes: 9 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -368,6 +368,7 @@ tfg generate --format txt --size 1mb settings come from the flags
| `--name <template>` | name template, for example `invoice_{index:04}.txt` |
| `--send-as <name>` | the name to give the file to your system, when it is one no disk stores, such as `../climbed_out.jpg`. The file keeps its own name and the manifest carries this one |
| `--out <dir>` | directory to write into. Default `.` |
| `--number-if-taken` | when `--out` already holds an earlier run, add this one beside it: every name of the run, its manifest's too, gets a number such as `-2`, and nothing already there changes. Without it such a run is refused with code `5`. A name the number would make too long for a file name is refused with the same code |
| `--seed <n>` | run seed. The same seed gives the same bytes |
| `--set <k>=<v>` | a format setting, repeatable: `--set width=1920 --set height=1080` |
| `--damage <name>` | break the files on purpose, repeatable and applied in order. Run `tfg damage` for the list |
Expand Down Expand Up @@ -830,6 +831,14 @@ tool, the same as picking it with Choose... Drop one at a time. Something the
box cannot take is refused with a sentence under the box, and the box keeps
what it had.

You can generate into the same output directory again and again. A run into a
directory that already holds an earlier run is added beside it: every name of
the run, its manifest's too, gets a number, such as `files-2_0001.pdf` and
`manifest-2.json`, and nothing already there changes. The switch for this, Add
beside earlier runs, sits under the output directory and stays on unless you
turn it off. With it off, such a run is refused, the same as on the command line
without `--number-if-taken`.

<p>
<img src=".github/window-presets.png" width="49%" alt="The Presets screen of the window, with the list of presets open">
<img src=".github/window-settings.png" width="49%" alt="One batch of log files in the window, with the settings the log format takes">
Expand Down
7 changes: 7 additions & 0 deletions internal/cli/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -390,6 +390,13 @@ func classifyReading(err error) (int, bool) {
if errors.As(err, &inProgress) {
return ExitIO, true
}
// A directory whose earlier run gives this one a number too long for one
// of its names. The same row again: the name was fine, the directory is
// what will not have it.
var numberTooLong *engine.NumberTooLongError
if errors.As(err, &numberTooLong) {
return ExitIO, true
}
// A manifest we cannot read is a reading failure, not a bug in the tool.
// Falling through to RUNTIME would tell CI to file a report against us for
// a file somebody handed in.
Expand Down
18 changes: 12 additions & 6 deletions internal/cli/generate.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ type generateOpts struct {
clean bool
dryRun bool
asJSON bool
// numberIfTaken is --number-if-taken, engine.Options.NumberIfTaken.
numberIfTaken bool
// The flags a person may write more than once, in one piece rather than
// two fields. They are one thing on the screen and one thing in a recipe -
// what was stated repeatedly - and grouping them is what moving state out
Expand All @@ -57,6 +59,9 @@ func generateFlagSet(errOut io.Writer, g *generateOpts) (*flag.FlagSet, func(io.
fs.StringVar(&g.boundary, "boundary", "", "three files around a limit: one byte under it, the limit itself, one byte over")
fs.IntVar(&g.count, "count", 1, "how many files to produce")
fs.StringVar(&g.outDir, "out", ".", "directory to write into")
fs.BoolVar(&g.numberIfTaken, "number-if-taken", false, "when --out already holds names this run would write, an earlier run's manifest above all, "+
"give every name of this run a number such as -2 rather than stopping. Nothing already there is changed. "+
"Without it such a run stops with exit code 5")
fs.StringVar(&g.name, "name", "", "name template, for example invoice_{index:04}.txt")
fs.StringVar(&g.notes.SendAs, "send-as", "", "the name to give the file to your system under, when it is one no disk stores, for example ../climbed_out.jpg. "+
"The file keeps its own name here and the manifest carries this one")
Expand Down Expand Up @@ -158,12 +163,13 @@ func generate(ctx context.Context, args []string, out, errOut io.Writer) int {
given := flagsGiven(fs)

opt := engine.Options{
OutDir: g.outDir,
Seed: g.seed,
DryRun: g.dryRun,
Command: "tfg " + strings.Join(args2(args), " "),
ManifestName: defaultManifestName,
Memory: memory.Memory,
OutDir: g.outDir,
Seed: g.seed,
DryRun: g.dryRun,
Command: "tfg " + strings.Join(args2(args), " "),
ManifestName: defaultManifestName,
Memory: memory.Memory,
NumberIfTaken: g.numberIfTaken,
}

var (
Expand Down
31 changes: 20 additions & 11 deletions internal/engine/engine.go
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,12 @@ type Options struct {
Preset *manifest.Preset
// ManifestName is the file the manifest lands in, relative to OutDir.
ManifestName string
// NumberIfTaken lets a run into a directory that already holds names it
// would write - an earlier run's manifest above all - take a number on
// every name, its manifest's too, rather than be refused. Off, the run is
// refused as it always was. See numbering.go, and Result.Number for the
// number it took.
NumberIfTaken bool

// AvailableBytes reports the free space at a path. It is injected so a
// test can describe a small disk without owning one - and so that a test
Expand Down Expand Up @@ -197,11 +203,20 @@ type Result struct {

// RunNotes is what the run says about itself rather than about a file:
// the memory of the machine could not be read, a file was written past
// the memory setting. Not in the manifest, which describes files - these
// describe the machine the run happened on, and a manifest that changed
// with the machine would record something other than the files beside it.
// the memory setting, the names took a number. Not in the manifest, which
// describes files - these describe the machine and the directory the run
// happened in, and a manifest that changed with them would record
// something other than the files beside it. A numbered name needs no note
// there either: the manifest lists the names as they are on the disk.
RunNotes []core.Said

// Number is the number every name of this run carries, its manifest's
// among them, when Options.NumberIfTaken found the directory holding names
// the run would write - and 0 when the names are the ones planned. The
// files of the plan were renamed to carry it, and SaveRecord saves the
// manifest under it.
Number int

// Hold is what this run was worked out to hold at its end, against what
// its memory setting gives it (PredictHold), before its first byte. A
// window says it after a preview and after a run, and the command line
Expand Down Expand Up @@ -509,17 +524,11 @@ func Run(ctx context.Context, files []PlannedFile, opt Options) (*Result, error)
m := newManifest(opt)
res := &Result{Manifest: m}

// Whether this run may start at all is settled before anything is written
// and before a dry run returns. A dry run exists to count and show before
// the disk is touched, so reporting success for a run that refuses to
// start on the very next line answers the wrong question.
record, err := PredictRecord(ctx, files, opt)
// Whether this run may start at all, and under which names - see mayStart.
opt, err := res.mayStart(ctx, files, opt)
if err != nil {
return res, err
}
if err := preflight(ctx, files, opt, record); err != nil {
return res, err
}
limits := opt.memoryLimits()
res.noteMemory(limits)
res.Hold = predictHold(len(files), limits)
Expand Down
Loading
Loading