Answer prose round 1: the seed advice says to log a new seed in the error, the doc and the README alike, the changelog says each run takes a new seed, New's failures read in one pass, and the concurrency lines say who draws
This commit is contained in:
+4
-4
@@ -18,8 +18,8 @@ and any release may change what a seed draws, so pin one exact version
|
||||
|
||||
- The CLI, `fejkdata`, renders exactly the template on its stdin and adds nothing:
|
||||
`echo '{/sv_SE.person} hihi' | fejkdata` prints e.g. `Sara Eriksson hihi`. `--seed`
|
||||
repeats a run's output while the version and data stay the same, and without it the
|
||||
CLI seeds from the system; `-n` renders the template that many times, and `--list`
|
||||
repeats a run's output while the version and data stay the same, and without it each
|
||||
run takes a new seed; `-n` renders the template that many times, and `--list`
|
||||
prints the paths the data offers.
|
||||
`--data-path` layers a directory of your own data over the shipped set, and
|
||||
`--no-shipped-data` loads that directory alone. `--format json|ndjson|csv|sql` writes
|
||||
@@ -27,8 +27,8 @@ and any release may change what a seed draws, so pin one exact version
|
||||
error such as data that fails to load, and `2` on misuse.
|
||||
- The library, `github.com/larvit/fejkdata`, for Go 1.22 or later on a 64-bit target.
|
||||
`New` loads the modules `WithDataFS` names and the folders `WithDataPath` names, drawing
|
||||
from the seed `WithSeed` gives. It fails naming `WithSeed` where no seed is given, and
|
||||
`WithDataFS` where neither option names the data. The same seed repeats the draws
|
||||
from the seed `WithSeed` gives. Without a seed, `New` fails and names `WithSeed`;
|
||||
without data, it fails and names `WithDataFS`. The same seed repeats the draws
|
||||
while the version and data stay the same. `Fake` renders a path, and `FakeTemplate`
|
||||
and `NewTemplate` render a template. `FakeRecord`, `FakeRecordTemplate` and
|
||||
`NewRecordTemplate` render a record, whose `JSON`, `CSVHeader`, `CSVLine` and
|
||||
|
||||
@@ -360,7 +360,7 @@ ok, err := fejkdata.IsTemplate(arg) // an inline template by its shape, el
|
||||
|
||||
| Option | |
|
||||
|--------|--|
|
||||
| `WithSeed(n)` | required; same seed, version and data: identical sequence. `WithSeed(s)` with `s := rand.Uint64()`, from `math/rand/v2`, takes a new seed each run; log `s` to replay a run |
|
||||
| `WithSeed(n)` | required; the same seed, version and data give the same sequence. For a new seed each run, set `n := rand.Uint64()` (`math/rand/v2`), and log `n` to replay the run |
|
||||
| `WithDataPath(dir)` | layer a directory; repeat to layer several, the last wins a clash |
|
||||
| `WithDataFS(modules...)` | layer modules in order, each an `fs.FS`: a shipped package's `Modules()...`, or your own `embed.FS`; `WithDataFS()` loads none |
|
||||
|
||||
@@ -372,7 +372,7 @@ links all of them. Two locales, with `enus` from `github.com/larvit/fejkdata/dat
|
||||
are `WithDataFS(append(svse.Modules(), enus.Modules()...)...)`. To stand in your
|
||||
own places, pass the locale's `FS` alone beside a tree providing `geo.SE.address`, a record
|
||||
with a `format` and the columns `sv_SE.address` reads, `street`, `street-number`,
|
||||
`postal-code` and `locality`: `WithDataFS(svse.FS, myPlaces)`. `New` fails where no `WithSeed` gives the seed, or no
|
||||
`postal-code` and `locality`: `WithDataFS(svse.FS, myPlaces)`. `New` fails where no
|
||||
`WithDataFS` or `WithDataPath` names the data to load.
|
||||
|
||||
`New` refuses data that breaks the grammar, could mean two things or cannot render a valid
|
||||
@@ -431,8 +431,8 @@ error on every later call; a `datatype` in a tag other than the one its Go type
|
||||
refused, naming that type.
|
||||
|
||||
A `*Generator` is safe for concurrent use; a sequence is reproducible only
|
||||
when drawn from one goroutine. Changing how a value is composed shifts the
|
||||
stream for that value and everything drawn after it.
|
||||
when drawn from one goroutine. Editing a template shifts what it draws, and
|
||||
everything drawn after it.
|
||||
|
||||
### Your own CLI
|
||||
|
||||
@@ -459,10 +459,11 @@ func main() { os.Exit(cli.Main(append(data.Modules(), mydata)...)) }
|
||||
The embed's folders are the paths: `//go:embed acme` serves `acme/customer.json` as
|
||||
`{/acme.customer}`. Add `*.tsv` to the embed where your data holds a table. The CLI loads
|
||||
its data only when it runs. To catch broken data at `go test`, call
|
||||
`fejkdata.New(fejkdata.WithDataFS(...), fejkdata.WithSeed(1))` over the same modules, and render each path once:
|
||||
a module with an index checks a category only when a call first reaches it. The CLI takes `fejkdata`'s flags
|
||||
and exit codes, and names itself by the file it runs from in its help and errors. `--no-shipped-data` leaves out the modules passed to `Main`, and
|
||||
`--version` prints your module's version beside the fejkdata version it is built with.
|
||||
`fejkdata.New(fejkdata.WithDataFS(...), fejkdata.WithSeed(1))` over the same modules, and
|
||||
render each path once: a module with an index checks a category only when a call first
|
||||
reaches it. The CLI takes `fejkdata`'s flags and exit codes, and names itself by the file
|
||||
it runs from in its help and errors. `--no-shipped-data` leaves out the modules passed to
|
||||
`Main`, and `--version` prints your module's version beside the fejkdata version it is built with.
|
||||
|
||||
## Data format
|
||||
|
||||
|
||||
+4
-4
@@ -36,7 +36,7 @@ type config struct {
|
||||
seeded bool
|
||||
sources []datafiles.Source
|
||||
nilModules error
|
||||
// dataGiven is whether an option named the data to load, though it may name none.
|
||||
// dataGiven is whether a data option was passed, even WithDataFS(), which loads none.
|
||||
dataGiven bool
|
||||
}
|
||||
|
||||
@@ -44,8 +44,8 @@ type config struct {
|
||||
type Option func(*config)
|
||||
|
||||
// WithSeed seeds the generator, as [New] requires: two generators with the same seed,
|
||||
// version and data emit identical sequences. WithSeed(rand.Uint64()), with math/rand/v2,
|
||||
// takes a new seed each run.
|
||||
// version and data emit identical sequences. For a new seed each run, set
|
||||
// seed := rand.Uint64() (math/rand/v2), and log it to replay the run.
|
||||
func WithSeed(seed uint64) Option {
|
||||
return func(c *config) { c.seed, c.seeded = seed, true }
|
||||
}
|
||||
@@ -75,7 +75,7 @@ func WithDataFS(modules ...fs.FS) Option {
|
||||
}
|
||||
}
|
||||
|
||||
var errNoSeed = errors.New(`fejkdata: no seed: add fejkdata.WithSeed(n) to repeat a run's output, or WithSeed(rand.Uint64()) (import "math/rand/v2") for a new seed each run`)
|
||||
var errNoSeed = errors.New(`fejkdata: no seed: add fejkdata.WithSeed(n), where the same n repeats a run's output; for a new seed each run, set n := rand.Uint64() (import "math/rand/v2") and log n to replay the run`)
|
||||
|
||||
var errNoData = errors.New(`fejkdata: no data: add fejkdata.WithDataFS(data.Modules()...) (import "github.com/larvit/fejkdata/data") for all shipped data, WithDataFS/WithDataPath for your own, or WithDataFS() for none`)
|
||||
|
||||
|
||||
@@ -11,8 +11,8 @@ import (
|
||||
// Template is an inline template compiled, referenced and validated against a
|
||||
// generator's loaded data once, ready to render many times with [Template.Fake].
|
||||
// It is safe for concurrent use: Fake serializes on its generator's lock, so a
|
||||
// sequence is reproducible only when a generator — and its templates — are
|
||||
// drawn from one goroutine.
|
||||
// sequence is reproducible only when one goroutine makes every draw from a generator
|
||||
// and its templates.
|
||||
type Template struct {
|
||||
g *Generator
|
||||
n node
|
||||
|
||||
Reference in New Issue
Block a user