Answer prose round 1: List gives direct descents only, the library and CLI lines name their verbs, the template line explains its values, the geo line says which places ship, and the README's pointer rule reads in one pass

This commit is contained in:
2026-10-12 18:03:05 +02:00
committed by Lillem4n
parent 143311270c
commit 1a5b632b90
2 changed files with 39 additions and 36 deletions
+35 -32
View File
@@ -16,39 +16,41 @@ and any release may change what a seed draws, so pin one exact version
### Added ### Added
- The CLI, `fejkdata`, renders exactly the template on its stdin and adds nothing: `echo - The CLI, `fejkdata`, renders exactly the template on its stdin and adds nothing:
'{/sv_SE.person} hihi' | fejkdata` prints e.g. `Sara Eriksson hihi`. `--seed` makes a `echo '{/sv_SE.person} hihi' | fejkdata` prints e.g. `Sara Eriksson hihi`. `--seed`
run reproducible for one version and data, `-n` repeats it, `--list` prints every repeats a run's output while the version and data stay the same, `-n` renders the
path, and `--data-path` layers a directory of your own data over the shipped set, or template that many times, and `--list` prints the paths the data offers.
alone with `--no-shipped-data`. `--format json|ndjson|csv|sql` writes a record's `--data-path` layers a directory of your own data over the shipped set, and
columns, one record per row. It exits `0` on success, `1` on a runtime error such as `--no-shipped-data` loads that directory alone. `--format json|ndjson|csv|sql` writes
data that fails to load, and `2` on misuse. a record's columns, one record per row. The CLI exits `0` on success, `1` on a runtime
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. - 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, and `New` loads the modules `WithDataFS` names and the folders `WithDataPath` names, and
fails, naming `WithDataFS`, where neither is given; `WithSeed` makes its draws fails, naming `WithDataFS`, where neither is given. `WithSeed` makes its draws
reproducible for one version and data. `Fake` renders a path, `FakeTemplate` and repeat while the version and data stay the same. `Fake` renders a path, and
`NewTemplate` a template, `FakeRecord`, `FakeRecordTemplate` and `NewRecordTemplate` a `FakeTemplate` and `NewTemplate` render a template. `FakeRecord`, `FakeRecordTemplate`
record, whose columns `JSON`, `CSVHeader`, `CSVLine` and `SQLInsert` write as the CLI and `NewRecordTemplate` render a record, whose `JSON`, `CSVHeader`, `CSVLine` and
does, and `FakeStruct` fills a struct's `fake:"…"` tagged fields. `List` gives every `SQLInsert` methods write its columns as the CLI does. `FakeStruct` fills a struct's
path `Fake` renders, and `IsTemplate` tells an inline template from a path. Data that `fake:"…"` tagged fields. `List` gives the paths `Fake` renders, direct descents only,
fails to load gives an error matching `ErrLoad`, and a record with no fields one and `IsTemplate` tells an inline template from a path. Data that fails to load gives
matching `ErrNoColumns`. an error matching `ErrLoad`, and a record with no fields gives one matching
`ErrNoColumns`.
- Package `github.com/larvit/fejkdata/cli` is the `fejkdata` command: - Package `github.com/larvit/fejkdata/cli` is the `fejkdata` command:
`cli.Main(modules...)` runs it over the modules given, so `cli.Main(modules...)` runs it over the modules given, so
`cli.Main(append(data.Modules(), mydata)...)` builds a CLI carrying your own data. `cli.Main(append(data.Modules(), mydata)...)` builds a CLI carrying your own data.
That CLI names itself by the file it runs from, and its `--version` prints its own That CLI names itself by the file it runs from, and its `--version` prints its own
module's version before fejkdata's. module's version before fejkdata's.
- The template language ([Data - The template language
format](https://github.com/larvit/fejkdata/blob/v0.1.0/README.md#data-format)). A node ([Data format](https://github.com/larvit/fejkdata/blob/v0.1.0/README.md#data-format)).
is a string, a choice, a template, a table, a number or a boolean. A format string's Every value in a data file is a string, a choice, a template, a table, a number or a
`{…}` tokens read sibling fields, references from the data root, the file's folder or boolean. A `{…}` token reads a sibling field, a name, or a reference from the data
the folder above (`{/sv_SE.person.last}`, `{.x}`, `{..x}`), builtins and names. Every root, the file's folder or the folder above (`{/sv_SE.person.last}`, `{.x}`, `{..x}`),
`{…}` draws afresh, and a name is the one way to keep a pick: `{/sv_SE.person as or it calls a builtin. Every `{…}` draws afresh, and a name is the one way to keep a
p}{p.first} {p.last}` is one person. The builtins draw check digits (`luhn`, `mod11`, pick: `{/sv_SE.person as p}{p.first} {p.last}` is one person. The builtins draw check
`ean`), samples (`digits`, `int`, `float`, `uuid`, `ulid`, `iban`, `date`, `time` and digits (`luhn`, `mod11`, `ean`), samples (`digits`, `int`, `float`, `uuid`, `ulid`,
more), a counter (`seq`), arithmetic (`calc`) and transforms (`lowercase`, `iban`, `date`, `time` and more), a counter (`seq`), arithmetic (`calc`) and
`uppercase`, `ascii`). `New` refuses data that breaks the grammar, could mean two transforms (`lowercase`, `uppercase`, `ascii`). `New` refuses data that breaks the
things or cannot render a valid value. grammar, could mean two things or cannot render a valid value.
- Records ([Records](https://github.com/larvit/fejkdata/blob/v0.1.0/README.md#records)): - Records ([Records](https://github.com/larvit/fejkdata/blob/v0.1.0/README.md#records)):
a template seen as columns. A column is a string unless it declares a `datatype`, a template seen as columns. A column is a string unless it declares a `datatype`,
`integer`, `number` or `boolean`, and a `null` item draws it as null. `integer`, `number` or `boolean`, and a `null` item draws it as null.
@@ -84,9 +86,10 @@ and any release may change what a seed draws, so pin one exact version
- `geo.SE` and `geo.US`: five linked tables per country, `region`, `municipality`, - `geo.SE` and `geo.US`: five linked tables per country, `region`, `municipality`,
`locality`, `postal-code` and `street`, weighted by population and address counts `locality`, `postal-code` and `street`, weighted by population and address counts
and built from SCB, GeoNames, Trafikverket NVDB, the US Census Bureau and Wikidata, and built from SCB, GeoNames, Trafikverket NVDB, the US Census Bureau and Wikidata,
and an `address` record drawing a street and postal code inside one locality, which and an `address` record that draws a street and a postal code inside one
`sv_SE.address` and `en_US.address` print. Every Swedish postort the import can locality; `sv_SE.address` and `en_US.address` print it. Every Swedish postort
place ships with all its streets. Of the US incorporated places that hold most of (postal town) the import can place ships with all its streets. A US place ships
some postal code's land, every state capital but Honolulu, every place of 100,000 or only if it is incorporated and holds most of some postal code's land. Of those
more and a population-weighted tenth of them ship, each with a quarter of its places, every state capital but Honolulu ships, as does every place of 100,000
streets, at least ten. people or more and a tenth of all of them drawn by population. Each US place
carries a quarter of its streets, at least ten.
+4 -4
View File
@@ -415,10 +415,10 @@ type Address struct {
`FakeStruct` fills a struct through a pointer: each exported field tagged `fake:"…"` is `FakeStruct` fills a struct through a pointer: each exported field tagged `fake:"…"` is
a column of one record, its tag a path or an inline template — told apart by a column of one record, its tag a path or an inline template — told apart by
`IsTemplate` — and its Go type the column's `IsTemplate` — and its Go type the column's
[datatype](#datatype): a string, bool, integer or float kind, or a pointer to one, [datatype](#datatype): a string, bool, integer or float kind, or a pointer to one. A
which a column that can be null requires and a [`null`](#null) item leaves nil. An integer stays within int64 whatever its column that can be null needs a pointer, which a [`null`](#null) item leaves nil. An
kind, and a value the kind cannot hold, such as `{int(0,300)}` in a `uint8`, is refused integer stays within int64 whatever its kind, and a value the kind cannot hold, such as
naming a kind that holds it. The tags are a record's columns, so they share its `{int(0,300)}` in a `uint8`, is refused naming a kind that holds it. The tags are a record's columns, so they share its
[names](#names): `First` tagged `{/sv_SE.person as p}{p.first}` and `Sex` tagged `{p.sex}` [names](#names): `First` tagged `{/sv_SE.person as p}{p.first}` and `Sex` tagged `{p.sex}`
describe one person, while two path tags into `sv_SE.person` are two draws. The fields an describe one person, while two path tags into `sv_SE.person` are two draws. The fields an
embedded struct promotes are columns of the same record; a named struct field, or a embedded struct promotes are columns of the same record; a named struct field, or a