Answer product-owner round 1: the Versioning table names the data packages, the README pairs each locale with its geo module, WithDataFS refuses a nil module, errNoData says New was given no data, and three changelog lines the move made false are true again

This commit is contained in:
2026-10-10 13:28:42 +02:00
committed by Lillem4n
parent 854d4d69ae
commit e6e7b804e1
3 changed files with 18 additions and 8 deletions
+5 -5
View File
@@ -41,8 +41,8 @@ replacement, and each removed path, column or flag.
where it does nothing; a name nothing reads; a repeated item, which counts as written; a where it does nothing; a name nothing reads; a repeated item, which counts as written; a
weight of `0`, which is never drawn; a `repeat` or count of `0`, which renders nothing; weight of `0`, which is never drawn; a `repeat` or count of `0`, which renders nothing;
`+5`, `05` and `-0`; and a reference into the category it sits in. A rows file no `+5`, `05` and `-0`; and a reference into the category it sits in. A rows file no
category names is ignored. `New` with no data loads, and renders templates that read category names is ignored. `New(WithDataFS())` loads no data, and renders templates that
none. The CLI's `-n` takes `0`; `--list` ignores `--repeat`, `--separator`, `--format` read none. The CLI's `-n` takes `0`; `--list` ignores `--repeat`, `--separator`, `--format`
and `--table`, and `--table` is ignored without `--format sql`. and `--table`, and `--table` is ignored without `--format sql`.
- Table categories: a category JSON naming a `rows` TSV beside it, with the options - Table categories: a category JSON naming a `rows` TSV beside it, with the options
`key`, `name`, `weight` and `parent`; a path selects a row by key or name, `key`, `name`, `weight` and `parent`; a path selects a row by key or name,
@@ -92,8 +92,8 @@ replacement, and each removed path, column or flag.
and built from SCB, GeoNames, Trafikverket NVDB and the US Census Bureau, and an and built from SCB, GeoNames, Trafikverket NVDB and the US Census Bureau, and an
`address` record binding one locality and drawing its street and postal code inside `address` record binding one locality and drawing its street and postal code inside
it. `sv_SE.address` and `en_US.address` bind those records once, so it. `sv_SE.address` and `en_US.address` bind those records once, so
`en_US.address.street` no longer carries `name` and `suffix`, and a locale folder `en_US.address.street` no longer carries `name` and `suffix`, and a locale's `address`
loads only beside `geo`. reads its country's `geo` module.
- `{date(from,to,'layout')}` and `{time('layout')}`: a second between two days, or - `{date(from,to,'layout')}` and `{time('layout')}`: a second between two days, or
within one, in a single-quoted Go layout, drawn in UTC; `from` may equal `to`. within one, in a single-quoted Go layout, drawn in UTC; `from` may equal `to`.
`sv_SE.date`, `en_US.date`, `sv_SE.time` and `en_US.time` render through them, so `sv_SE.date`, `en_US.date`, `sv_SE.time` and `en_US.time` render through them, so
@@ -135,6 +135,6 @@ replacement, and each removed path, column or flag.
- A data source whose root holds a `.fejkdata.json` manifest with an `index` loads each - A data source whose root holds a `.fejkdata.json` manifest with an `index` loads each
category on the first call reaching it, as each shipped module does. Data failing to load, category on the first call reaching it, as each shipped module does. Data failing to load,
in `New` or on that first call, gives an error matching `ErrLoad`, and the CLI exits 1. in `New` or on that first call, gives an error matching `ErrLoad`, and the CLI exits 1.
A source without an index loads in `New`, with the shipped categories it reads. Every A source without an index loads in `New`, with the indexed categories it reads. Every
other shipped category loads on the first call reaching it, so one your replacement other shipped category loads on the first call reaching it, so one your replacement
breaks fails there. breaks fails there.
+3 -1
View File
@@ -361,7 +361,8 @@ ok, err := fejkdata.IsTemplate(arg) // an inline template by its shape, el
`data.Modules()` is every shipped module, and links all of them into your program. To link `data.Modules()` is every shipped module, and links all of them into your program. To link
only the ones you read, pass each package's `FS` with the modules its manifest reads: only the ones you read, pass each package's `FS` with the modules its manifest reads:
`WithDataFS(sv_SE.FS, SE.FS)` from `github.com/larvit/fejkdata/data/sv_SE` and `WithDataFS(sv_SE.FS, SE.FS)` from `github.com/larvit/fejkdata/data/sv_SE` and
`github.com/larvit/fejkdata/data/geo/SE`. `New` fails where no `WithDataFS` or `github.com/larvit/fejkdata/data/geo/SE`, or `en_US.FS` with `US.FS` from
`github.com/larvit/fejkdata/data/geo/US`; `misc` reads none. `New` fails where no `WithDataFS` or
`WithDataPath` names the data to load. `WithDataPath` names the data to load.
`New` refuses data that breaks the grammar, could mean two things or cannot render a valid `New` refuses data that breaks the grammar, could mean two things or cannot render a valid
@@ -898,6 +899,7 @@ and regenerate seeded fixtures and expected values when you raise that version.
| Data format | a fence: a spelling a load rejects that it accepted, in a category or a manifest; a template option, since it reserves a field name | a builtin | | Data format | a fence: a spelling a load rejects that it accepted, in a category or a manifest; a template option, since it reserves a field name | a builtin |
| CLI | remove or rename a flag, or change its default; change what an exit code means; change the framing a `--format` writes (header, quoting, statement shape), the `--list` layout, or what an error names | a flag, a format | | CLI | remove or rename a flag, or change its default; change what an exit code means; change the framing a `--format` writes (header, quoting, statement shape), the `--list` layout, or what an error names | a flag, a format |
| Library | change or remove an exported name; raise the lowest supported Go | an exported name, a `With…` option | | Library | change or remove an exported name; raise the lowest supported Go | an exported name, a `With…` option |
| Data packages | rename or remove a package; move a category to another package; add a module to a package's `reads` | a package |
A patch changes no row of this table: performance, docs, or a fix inside a promised A patch changes no row of this table: performance, docs, or a fix inside a promised
behaviour that adds or removes no value and changes no path, format or spelling. behaviour that adds or removes no value and changes no path, format or spelling.
+10 -2
View File
@@ -37,6 +37,7 @@ type config struct {
seed uint64 seed uint64
seeded bool seeded bool
sources []datafiles.Source sources []datafiles.Source
err error
// given is whether an option named the data to load, though it may name none. // given is whether an option named the data to load, though it may name none.
given bool given bool
} }
@@ -64,14 +65,18 @@ func WithDataPath(dir string) Option {
// with none loads no data. // with none loads no data.
func WithDataFS(modules ...fs.FS) Option { func WithDataFS(modules ...fs.FS) Option {
return func(c *config) { return func(c *config) {
for _, fsys := range modules { for i, fsys := range modules {
if fsys == nil {
c.err = fmt.Errorf("fejkdata: WithDataFS module %d is nil", i+1)
continue
}
c.sources = append(c.sources, datafiles.FS(fsys)) c.sources = append(c.sources, datafiles.FS(fsys))
} }
c.given = true c.given = true
} }
} }
var errNoData = errors.New("fejkdata: New names no data to load; pass WithDataFS(data.Modules()...), importing github.com/larvit/fejkdata/data, for every module fejkdata ships, WithDataFS or WithDataPath with your own, or WithDataFS() for none") var errNoData = errors.New("fejkdata: New was given no data to load; pass WithDataFS(data.Modules()...), importing github.com/larvit/fejkdata/data, for every module fejkdata ships, WithDataFS or WithDataPath with your own, or WithDataFS() for none")
// ErrLoad marks data that fails to load: in New, or on the first call reaching a category // ErrLoad marks data that fails to load: in New, or on the first call reaching a category
// of an indexed source. // of an indexed source.
@@ -99,6 +104,9 @@ func New(opts ...Option) (*Generator, error) {
if !c.given { if !c.given {
return nil, errNoData return nil, errNoData
} }
if c.err != nil {
return nil, c.err
}
root, err := loadSources(c.sources) root, err := loadSources(c.sources)
if err != nil { if err != nil {
return nil, fmt.Errorf("fejkdata: %w", loadError{err}) return nil, fmt.Errorf("fejkdata: %w", loadError{err})