diff --git a/CHANGELOG.md b/CHANGELOG.md index cd2f818..77350f8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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 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 - category names is ignored. `New` with no data loads, and renders templates that read - none. The CLI's `-n` takes `0`; `--list` ignores `--repeat`, `--separator`, `--format` + category names is ignored. `New(WithDataFS())` loads no data, and renders templates that + read none. The CLI's `-n` takes `0`; `--list` ignores `--repeat`, `--separator`, `--format` and `--table`, and `--table` is ignored without `--format sql`. - 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, @@ -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 `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 - `en_US.address.street` no longer carries `name` and `suffix`, and a locale folder - loads only beside `geo`. + `en_US.address.street` no longer carries `name` and `suffix`, and a locale's `address` + reads its country's `geo` module. - `{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`. `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 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. - 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 breaks fails there. diff --git a/README.md b/README.md index 2c5fd45..5c44394 100644 --- a/README.md +++ b/README.md @@ -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 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 -`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. `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 | | 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 | +| 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 behaviour that adds or removes no value and changes no path, format or spelling. diff --git a/fejkdata.go b/fejkdata.go index 0504b51..a6603a1 100644 --- a/fejkdata.go +++ b/fejkdata.go @@ -37,6 +37,7 @@ type config struct { seed uint64 seeded bool sources []datafiles.Source + err error // given is whether an option named the data to load, though it may name none. given bool } @@ -64,14 +65,18 @@ func WithDataPath(dir string) Option { // with none loads no data. func WithDataFS(modules ...fs.FS) Option { 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.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 // of an indexed source. @@ -99,6 +104,9 @@ func New(opts ...Option) (*Generator, error) { if !c.given { return nil, errNoData } + if c.err != nil { + return nil, c.err + } root, err := loadSources(c.sources) if err != nil { return nil, fmt.Errorf("fejkdata: %w", loadError{err})