Answer architecture round 8: a shipped package's folder spells its namespace (data/sv_SE, data/geo/SE) under its lowered Go name, as a second bench chose, a mounted root folder reads as its namespace, and item 196 cites goal 9.2

This commit is contained in:
2026-10-11 14:11:46 +02:00
committed by Lillem4n
parent 26f3c95031
commit 203486a9d3
97 changed files with 81 additions and 42 deletions
+1 -1
View File
@@ -47,7 +47,7 @@ In [docs/decisions.md](docs/decisions.md):
- `FakeTemplate` and `NewTemplate` both stay - `FakeTemplate` and `NewTemplate` both stay
- The shipped data is embedded, not discovered - The shipped data is embedded, not discovered
- The shipped data is Go packages a library imports by choice, and the CLI carries every one, from 0.1.0 - The shipped data is Go packages a library imports by choice, and the CLI carries every one, from 0.1.0
- A shipped package is named by its namespace in lower case without separators, and its manifest mounts it there with `namespace` - A shipped package's folder spells its namespace, its Go name is that namespace in lower case without separators, and its manifest mounts it with `namespace`
- A source whose manifest carries an index loads each category on first reach; any other loads in `New`, with what it reads - A source whose manifest carries an index loads each category on first reach; any other loads in `New`, with what it reads
- Every `{…}` draws afresh, and only a name keeps a pick - Every `{…}` draws afresh, and only a name keeps a pick
- Reference sigils follow the filesystem - Reference sigils follow the filesystem
+2 -2
View File
@@ -126,8 +126,8 @@ replacement, and each removed path, column or flag.
`sv_SE.sex[f].first-name[Kim]`, and a category with no columns names the record `sv_SE.sex[f].first-name[Kim]`, and a category with no columns names the record
that gives it one. that gives it one.
- The shipped data comes in Go packages, one per module, each exporting `FS`: - The shipped data comes in Go packages, one per module, each exporting `FS`:
`github.com/larvit/fejkdata/data/enus`, `…/svse`, `…/misc`, `…/geose` and `github.com/larvit/fejkdata/data/en_US` (package `enus`), `…/sv_SE` (`svse`), `…/misc`,
`…/geous`. `data.Modules()`, from `github.com/larvit/fejkdata/data`, lists every one, `…/geo/SE` (`geose`) and `…/geo/US` (`geous`). `data.Modules()`, from `github.com/larvit/fejkdata/data`, lists every one,
and the CLI carries them all. `New` loads the modules `WithDataFS(modules...)` names and and the CLI carries them all. `New` loads the modules `WithDataFS(modules...)` names and
the folders `WithDataPath` names, and fails, naming `WithDataFS`, where no such option the folders `WithDataPath` names, and fails, naming `WithDataFS`, where no such option
is given. A manifest's `namespace` mounts its source under a dot path. is given. A manifest's `namespace` mounts its source under a dot path.
+9 -9
View File
@@ -6,15 +6,15 @@ Every shipped dataset, its source, its licence and the attribution it asks for.
| Table | Source | Licence | Attribution | Rebuild | | Table | Source | Licence | Attribution | Rebuild |
|-------|--------|---------|-------------|---------| |-------|--------|---------|-------------|---------|
| `geose/locality.tsv`, `postal-code.tsv` | [GeoNames](https://www.geonames.org/) postal codes for SE; populations from SCB tätorter 2023 | [CC BY 4.0](https://creativecommons.org/licenses/by/4.0/); CC0 1.0 | "Postal codes from GeoNames, www.geonames.org" | `data-import/geo-se.py` | | `geo/SE/locality.tsv`, `postal-code.tsv` | [GeoNames](https://www.geonames.org/) postal codes for SE; populations from SCB tätorter 2023 | [CC BY 4.0](https://creativecommons.org/licenses/by/4.0/); CC0 1.0 | "Postal codes from GeoNames, www.geonames.org" | `data-import/geo-se.py` |
| `geose/region.tsv`, `municipality.tsv` | [SCB](https://www.scb.se/) län and kommun codes 2026 and population 2024 | [CC0 1.0](https://creativecommons.org/publicdomain/zero/1.0/) | none required | `data-import/geo-se.py` | | `geo/SE/region.tsv`, `municipality.tsv` | [SCB](https://www.scb.se/) län and kommun codes 2026 and population 2024 | [CC0 1.0](https://creativecommons.org/publicdomain/zero/1.0/) | none required | `data-import/geo-se.py` |
| `geose/street.tsv` | [Trafikverket NVDB](https://www.trafikverket.se/) Gatunamn, through the open API | CC0 1.0 | none required | `data-import/geo-se.py` | | `geo/SE/street.tsv` | [Trafikverket NVDB](https://www.trafikverket.se/) Gatunamn, through the open API | CC0 1.0 | none required | `data-import/geo-se.py` |
| `geous/region.tsv`, `municipality.tsv`, `locality.tsv` | [Census Bureau](https://www.census.gov/) Gazetteer 2026 and population estimates 2025 | [public domain](https://www.usa.gov/government-works) | none required | `data-import/geo-us.py` | | `geo/US/region.tsv`, `municipality.tsv`, `locality.tsv` | [Census Bureau](https://www.census.gov/) Gazetteer 2026 and population estimates 2025 | [public domain](https://www.usa.gov/government-works) | none required | `data-import/geo-us.py` |
| `geous/postal-code.tsv`, `street.tsv` | Census Bureau ZCTA to place relationships 2020 and TIGER/Line 2025 address ranges and feature names | public domain | none required | `data-import/geo-us.py` | | `geo/US/postal-code.tsv`, `street.tsv` | Census Bureau ZCTA to place relationships 2020 and TIGER/Line 2025 address ranges and feature names | public domain | none required | `data-import/geo-us.py` |
| `svse/first-name.tsv`, `last-name.tsv` | [SCB](https://www.scb.se/) names with at least two bearers, 31 December 2022 | CC0 1.0 | "Källa: SCB" | `data-import/names-se.py` | | `sv_SE/first-name.tsv`, `last-name.tsv` | [SCB](https://www.scb.se/) names with at least two bearers, 31 December 2022 | CC0 1.0 | "Källa: SCB" | `data-import/names-se.py` |
| `enus/first-name.tsv` | [SSA](https://www.ssa.gov/oact/babynames/) baby names, births 1930 to 2020, through [hackerb9/ssa-baby-names](https://github.com/hackerb9/ssa-baby-names) | public domain | none required | `data-import/names-us.py` | | `en_US/first-name.tsv` | [SSA](https://www.ssa.gov/oact/babynames/) baby names, births 1930 to 2020, through [hackerb9/ssa-baby-names](https://github.com/hackerb9/ssa-baby-names) | public domain | none required | `data-import/names-us.py` |
| `enus/last-name.tsv` | Census Bureau surnames occurring 100 or more times, 2010 | public domain | none required | `data-import/names-us.py` | | `en_US/last-name.tsv` | Census Bureau surnames occurring 100 or more times, 2010 | public domain | none required | `data-import/names-us.py` |
| `svse/sex.tsv`, `svse/birth-number.tsv`, `svse/title.tsv`, `enus/sex.tsv`, `enus/title.tsv`, `misc/car.tsv` | curated; Skatteverket's test birth numbers are facts, and `car.tsv` waits for an international source (goal 14) | — | — | — | | `sv_SE/sex.tsv`, `sv_SE/birth-number.tsv`, `sv_SE/title.tsv`, `en_US/sex.tsv`, `en_US/title.tsv`, `misc/car.tsv` | curated; Skatteverket's test birth numbers are facts, and `car.tsv` waits for an international source (goal 14) | — | — | — |
| `misc/currency.tsv` | [datasets/currency-codes](https://github.com/datasets/currency-codes); symbols from [Unicode CLDR](https://github.com/unicode-org/cldr) `en.xml` and `root.xml` | PDDL 1.0; [Unicode License v3](https://www.unicode.org/license.txt) | CLDR: "Copyright © 1991-2025 Unicode, Inc. Unicode and the Unicode Logo are registered trademarks of Unicode, Inc. in the United States and other countries." | `data-import/currency.py` | | `misc/currency.tsv` | [datasets/currency-codes](https://github.com/datasets/currency-codes); symbols from [Unicode CLDR](https://github.com/unicode-org/cldr) `en.xml` and `root.xml` | PDDL 1.0; [Unicode License v3](https://www.unicode.org/license.txt) | CLDR: "Copyright © 1991-2025 Unicode, Inc. Unicode and the Unicode Logo are registered trademarks of Unicode, Inc. in the United States and other countries." | `data-import/currency.py` |
| `misc/httpmethod.tsv` | [IANA HTTP Method Registry](https://www.iana.org/assignments/http-methods/) | [public domain](https://www.iana.org/help/licensing-terms) | none required | `data-import/httpmethod.py` | | `misc/httpmethod.tsv` | [IANA HTTP Method Registry](https://www.iana.org/assignments/http-methods/) | [public domain](https://www.iana.org/help/licensing-terms) | none required | `data-import/httpmethod.py` |
| `misc/httpstatus.tsv` | [IANA HTTP Status Code Registry](https://www.iana.org/assignments/http-status-codes/) | [public domain](https://www.iana.org/help/licensing-terms) | none required | `data-import/httpstatus.py` | | `misc/httpstatus.tsv` | [IANA HTTP Status Code Registry](https://www.iana.org/assignments/http-status-codes/) | [public domain](https://www.iana.org/help/licensing-terms) | none required | `data-import/httpstatus.py` |
+9 -8
View File
@@ -160,10 +160,11 @@ it to a name and read the name
## Data ## Data
The shipped data comes in modules, each a Go package under [`data/`](data) named by its The shipped data comes in modules, each a Go package in the folder under [`data/`](data)
namespace in lower case without separators: one per locale (`enus` for `en_US`, `svse` its namespace spells, a dot a slash: one per locale (`data/en_US`, `data/sv_SE`), one per
for `sv_SE`), one per country's tree of places (`geose` for `geo.SE`, `geous` for country's tree of places (`data/geo/SE`, `data/geo/US`), and the locale-neutral
`geo.US`), and the locale-neutral `misc`. Each embeds its files, so nothing is read from `data/misc`. A package's Go name is its namespace in lower case without separators:
`svse`, `enus`, `geose`, `geous`, `misc`. Each embeds its files, so nothing is read from
disk. The CLI carries every module, and a library loads those it passes to `WithDataFS` disk. The CLI carries every module, and a library loads those it passes to `WithDataFS`
([Library](#library)). A directory is a namespace: each JSON file is a category named ([Library](#library)). A directory is a namespace: each JSON file is a category named
after the file, each subdirectory a dot-path segment, so `mydata/sv_SE/person.json` is after the file, each subdirectory a dot-path segment, so `mydata/sv_SE/person.json` is
@@ -184,7 +185,7 @@ every category of its source, so a category file it leaves out never loads.
The index maps each category's dot path to an entry: `parent`, the table it links to, The index maps each category's dot path to an entry: `parent`, the table it links to,
which needs its own entry in the same folder; and `paths`, every path `List` advertises which needs its own entry in the same folder; and `paths`, every path `List` advertises
below the category, `""` for the category itself. Each shipped module's manifest, such as below the category, `""` for the category itself. Each shipped module's manifest, such as
[`data/svse/.fejkdata.json`](data/svse/.fejkdata.json), carries one, so in a copy you [`data/sv_SE/.fejkdata.json`](data/sv_SE/.fejkdata.json), carries one, so in a copy you
edit, delete its `index` and keep its `namespace`, or keep the index current. edit, delete its `index` and keep its `namespace`, or keep the index current.
A table whose parent column differs from its entry's `parent` fails at first reach, and a A table whose parent column differs from its entry's `parent` fails at first reach, and a
table linking under another source's table needs a source without an index. `//go:embed` table linking under another source's table needs a source without an index. `//go:embed`
@@ -194,7 +195,7 @@ the root, with no `namespace`; name the manifest in the pattern too.
A manifest's `namespace` is the dot path its source's root sits under: a folder holding A manifest's `namespace` is the dot path its source's root sits under: a folder holding
`person.json` with `"namespace": "sv_SE"` provides `sv_SE.person`, its subfolders adding `person.json` with `"namespace": "sv_SE"` provides `sv_SE.person`, its subfolders adding
segments below that. It needs no index. Each shipped module carries one, so segments below that. It needs no index. Each shipped module carries one, so
`data/svse/person.json` is `sv_SE.person`. `data/sv_SE/person.json` is `sv_SE.person`.
Each locale carries `address`, `color`, `company`, `date`, `email`, `first-name`, Each locale carries `address`, `color`, `company`, `date`, `email`, `first-name`,
`ip`, `last-name`, `person`, `phone`, `price`, `sentence`, `sex`, `time`, `url`, `ip`, `last-name`, `person`, `phone`, `price`, `sentence`, `sex`, `time`, `url`,
@@ -363,8 +364,8 @@ only the ones you read, pass each locale's `FS` with its country's places:
```go ```go
import ( import (
"github.com/larvit/fejkdata" "github.com/larvit/fejkdata"
"github.com/larvit/fejkdata/data/geose" geose "github.com/larvit/fejkdata/data/geo/SE"
"github.com/larvit/fejkdata/data/svse" svse "github.com/larvit/fejkdata/data/sv_SE"
) )
f, err := fejkdata.New(fejkdata.WithDataFS(svse.FS, geose.FS)) f, err := fejkdata.New(fejkdata.WithDataFS(svse.FS, geose.FS))
+1 -1
View File
@@ -1,5 +1,5 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
"""Rebuild data/geose/*.tsv from SCB (CC0), GeoNames (CC BY 4.0) and Trafikverket NVDB (CC0). """Rebuild data/geo/SE/*.tsv from SCB (CC0), GeoNames (CC BY 4.0) and Trafikverket NVDB (CC0).
TRAFIKVERKET_API_KEY=… data-import/geo-se.py [--key-file FILE] [--cache DIR] [--streets-per-locality N] [--out DIR] TRAFIKVERKET_API_KEY=… data-import/geo-se.py [--key-file FILE] [--cache DIR] [--streets-per-locality N] [--out DIR]
""" """
+1 -1
View File
@@ -1,5 +1,5 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
"""Rebuild data/geous/*.tsv from the Census Bureau's Gazetteer, population estimates, ZCTA relationships and TIGER/Line files (public domain). """Rebuild data/geo/US/*.tsv from the Census Bureau's Gazetteer, population estimates, ZCTA relationships and TIGER/Line files (public domain).
data-import/geo-us.py [--cache DIR] [--min-population N] [--streets-per-locality N] [--out DIR] data-import/geo-us.py [--cache DIR] [--min-population N] [--streets-per-locality N] [--out DIR]
""" """
+2 -2
View File
@@ -5,14 +5,14 @@ import math
import sys import sys
from pathlib import Path from pathlib import Path
DATA = Path(__file__).resolve().parent.parent / "data" DATA = Path(__file__).resolve().parent.parent / "data" / "geo"
CACHE = Path(__file__).resolve().parent / "cache" CACHE = Path(__file__).resolve().parent / "cache"
def parser(doc, country, **own): def parser(doc, country, **own):
"""A parser for the options every country's import takes, plus the script's own: each keyword names one option, with """A parser for the options every country's import takes, plus the script's own: each keyword names one option, with
"_" standing for "-".""" "_" standing for "-"."""
options = {"cache": {"default": str(CACHE)}, "out": {"default": str(DATA / ("geo" + country.lower()))}, "streets_per_locality": {"type": int, "default": 10}, **own} options = {"cache": {"default": str(CACHE)}, "out": {"default": str(DATA / country)}, "streets_per_locality": {"type": int, "default": 10}, **own}
p = argparse.ArgumentParser(description=doc.splitlines()[0]) p = argparse.ArgumentParser(description=doc.splitlines()[0])
for name in sorted(options): for name in sorted(options):
p.add_argument("--" + name.replace("_", "-"), **options[name]) p.add_argument("--" + name.replace("_", "-"), **options[name])
+2 -2
View File
@@ -1,5 +1,5 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
"""Rebuild data/svse/first-name.tsv and last-name.tsv from SCB's whole-population name counts (CC0, "Källa: SCB"). """Rebuild data/sv_SE/first-name.tsv and last-name.tsv from SCB's whole-population name counts (CC0, "Källa: SCB").
data-import/names-se.py [--source URL_OR_FILE] [--first N] [--last N] [--cache DIR] [--out DIR] data-import/names-se.py [--source URL_OR_FILE] [--first N] [--last N] [--cache DIR] [--out DIR]
@@ -14,7 +14,7 @@ import tsv
import xlsx import xlsx
SOURCE = "https://www.scb.se/contentassets/9fe7dbb460994c72b835163dbc491ef9/namn-med-minst-tva-barare-31-december-2022.xlsx" SOURCE = "https://www.scb.se/contentassets/9fe7dbb460994c72b835163dbc491ef9/namn-med-minst-tva-barare-31-december-2022.xlsx"
OUT = Path(__file__).resolve().parent.parent / "data" / "svse" OUT = Path(__file__).resolve().parent.parent / "data" / "sv_SE"
CACHE = Path(__file__).resolve().parent / "cache" CACHE = Path(__file__).resolve().parent / "cache"
SHEETS = {"f": "Tilltalsnamn kvinnor", "m": "Tilltalsnamn män"} SHEETS = {"f": "Tilltalsnamn kvinnor", "m": "Tilltalsnamn män"}
SURNAMES = "Efternamn" SURNAMES = "Efternamn"
+2 -2
View File
@@ -1,5 +1,5 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
"""Rebuild data/enus/first-name.tsv and last-name.tsv from SSA baby names and the Census 2010 surnames (public domain). """Rebuild data/en_US/first-name.tsv and last-name.tsv from SSA baby names and the Census 2010 surnames (public domain).
data-import/names-us.py [--names URL_OR_FILE] [--surnames URL_OR_FILE] [--from-year YEAR] [--first N] [--last N] [--cache DIR] [--out DIR] data-import/names-us.py [--names URL_OR_FILE] [--surnames URL_OR_FILE] [--from-year YEAR] [--first N] [--last N] [--cache DIR] [--out DIR]
@@ -20,7 +20,7 @@ import tsv
NAMES = "https://raw.githubusercontent.com/hackerb9/ssa-baby-names/master/alldata.txt" NAMES = "https://raw.githubusercontent.com/hackerb9/ssa-baby-names/master/alldata.txt"
SURNAMES = "https://www2.census.gov/topics/genealogy/2010surnames/names.zip" SURNAMES = "https://www2.census.gov/topics/genealogy/2010surnames/names.zip"
OUT = Path(__file__).resolve().parent.parent / "data" / "enus" OUT = Path(__file__).resolve().parent.parent / "data" / "en_US"
CACHE = Path(__file__).resolve().parent / "cache" CACHE = Path(__file__).resolve().parent / "cache"
MC = re.compile(r"^Mc([a-z])") MC = re.compile(r"^Mc([a-z])")
PLACEHOLDERS = {"Baby", "Female", "Infant", "Male", "Notnamed", "Unknown", "Unnamed"} PLACEHOLDERS = {"Baby", "Female", "Infant", "Male", "Notnamed", "Unknown", "Unnamed"}
+4 -4
View File
@@ -4,11 +4,11 @@ package data
import ( import (
"io/fs" "io/fs"
"github.com/larvit/fejkdata/data/enus" enus "github.com/larvit/fejkdata/data/en_US"
"github.com/larvit/fejkdata/data/geose" geose "github.com/larvit/fejkdata/data/geo/SE"
"github.com/larvit/fejkdata/data/geous" geous "github.com/larvit/fejkdata/data/geo/US"
"github.com/larvit/fejkdata/data/misc" "github.com/larvit/fejkdata/data/misc"
"github.com/larvit/fejkdata/data/svse" svse "github.com/larvit/fejkdata/data/sv_SE"
) )
//go:generate env REGENERATE=1 go test -run ^TestShippedManifestsAreCurrent$ .. //go:generate env REGENERATE=1 go test -run ^TestShippedManifestsAreCurrent$ ..
+32
View File
@@ -417,3 +417,35 @@ Inherited architect, decided by:
- Navigation, Self-sufficiency: `data/svse/.fejkdata.json:26` `namespace`: a namespace no longer mirrors its folder, so the path alone no longer finds the file - Navigation, Self-sufficiency: `data/svse/.fejkdata.json:26` `namespace`: a namespace no longer mirrors its folder, so the path alone no longer finds the file
- Self-sufficiency: `internal/datafiles/manifest.go:23` `Manifest.Reads`: its comment and withMissingModules' only make sense after the README - Self-sufficiency: `internal/datafiles/manifest.go:23` `Manifest.Reads`: its comment and withMissingModules' only make sense after the README
- Locality: `internal/datafiles/datafiles.go:77` `Source.Walk`: the mount is translated in opposite directions by Walk and Load - Locality: `internal/datafiles/datafiles.go:77` `Source.Walk`: the mount is translated in opposite directions by Walk and Load
## 2026-10-11T11:30:01Z, PR #203 at 2a4694b, against bf1becb
Ruling: worse
Fell: Navigation. Under the floor of 7.0: Navigation 6.88, so the same ruling counts as worse.
| Seat | Navigation | Locality | Shape | Self-sufficiency | Overall |
|---|---|---|---|---|---|
| Mid A | worse | better | same | same | same |
| Inherited architect | worse | same | same | same | same |
| Seat | Navigation | Locality | Shape | Self-sufficiency | Overall |
|---|---|---|---|---|---|
| Junior A | 7 | 5.5 | 6 | 6 | 6 |
| Mid A | 7 | 5.5 | 6.5 | 6 | 6 |
| Maintainability senior | 7 | 6 | 6.5 | 6.5 | 6.5 |
| Inherited architect | 6.5 | 5.5 | 5.5 | 6.5 | 6 |
| Mean | 6.88 | 5.63 | 6.13 | 6.25 | 6.13 |
Mid A, decided by:
- Locality: `fejkdata.go:66` `WithDataFS`: every module is named at the call site, where the base silently started each generator from a package-level embed
- Navigation: `data/geose/fs.go:1` `geose`: a dotfile manifest decides the namespace and the folder follows a lowered, no-separator rule, one translation step from a failing path to its file
- Navigation: `internal/datafiles/datafiles.go:57` `Source.labelled`: a shipped file's error prints sv_SE (address.json), where the base printed the openable data/sv_SE/address.json
- Locality: `data.go:27` `addSource`: where a category lands depends on a field in a hidden file, a partial offset
Inherited architect, decided by:
- Navigation: `data/svse/fs.go:1` `svse`: the step from a dot path to a folder goes through the lowered-namespace rule, stated only in the README and each package doc
- Navigation: `internal/datafiles/datafiles.go:57` `labelled`: errors name sv_SE (address.json), not a path that opens as written
- Locality: `fejkdata.go:99` `New`: New loads exactly its options, cancelled by `data/svse/fs.go:1`'s dependency on geose that nothing in Go expresses
+13 -9
View File
@@ -138,7 +138,7 @@ A directory a machine happens to have would make `--seed 42` machine-dependent;
## The shipped data is Go packages a library imports by choice, and the CLI carries every one, from 0.1.0 ## The shipped data is Go packages a library imports by choice, and the CLI carries every one, from 0.1.0
2026-10-04, Lilleman auf Larv; revised 2026-10-09 to put the packages in the core's Go module. Serves goals 2.3, 6.2, 7.3, 9 and 10.1. Carried out by `todo.md` items 181, 184, 185 and 186. The CLI binary may grow to hundreds of MB. 2026-10-04, Lilleman auf Larv; revised 2026-10-09 to put the packages in the core's Go module. Serves goals 2.3, 6.2, 7.3, 9 and 10.1. Carried out by `todo.md` items 181, 184, 185, 186 and 196. The CLI binary may grow to hundreds of MB.
- One Go package per locale, one per country's `geo` tree, and one for `misc`, all in the core's Go module. A package registers nothing when imported. - One Go package per locale, one per country's `geo` tree, and one for `misc`, all in the core's Go module. A package registers nothing when imported.
- A bare `New()` loads no data and fails, naming the option to add. `WithoutShippedData` goes. - A bare `New()` loads no data and fails, naming the option to add. `WithoutShippedData` goes.
@@ -152,15 +152,19 @@ A directory a machine happens to have would make `--seed 42` machine-dependent;
Valid while the shipped data stays under 100 MiB, which a gate test holds (`todo.md` item 192): `go get` fetches the whole Go module, and the `go` command refuses a Go module zip over 500 MiB (`MaxZipFile` in `golang.org/x/mod/zip`). Past it, `todo.md` item 193 moves the largest packages into nested Go modules that keep their import paths, each requiring the core release that drops the package, so no build sees it twice. Valid while the shipped data stays under 100 MiB, which a gate test holds (`todo.md` item 192): `go get` fetches the whole Go module, and the `go` command refuses a Go module zip over 500 MiB (`MaxZipFile` in `golang.org/x/mod/zip`). Past it, `todo.md` item 193 moves the largest packages into nested Go modules that keep their import paths, each requiring the core release that drops the package, so no build sees it twice.
## A shipped package is named by its namespace in lower case without separators, and its manifest mounts it there with `namespace` ## A shipped package's folder spells its namespace, its Go name is that namespace in lower case without separators, and its manifest mounts it with `namespace`
2026-10-11, Lilleman auf Larv, from a bench of a Go test author, a data author and a 2026-10-11, Lilleman auf Larv, from two benches of a Go test author, a data author and a
custom-CLI builder. Serves goals 1 and 3.3. `sv_SE` ships as `data/svse`, `en_US` as custom-CLI builder. Serves goals 1 and 3.3. `sv_SE` ships in `data/sv_SE` as package
`data/enus`, `geo.SE` as `data/geose`, `geo.US` as `data/geous`, and `misc` as `data/misc`: `svse`, `en_US` in `data/en_US` as `enus`, `geo.SE` in `data/geo/SE` as `geose`, `geo.US` in
Go linters flag a capital or an underscore in a package name, and `SE.FS` read as a type. `data/geo/US` as `geous`, and `misc` in `data/misc`: Go linters flag a capital or an
Each package holds its files at its root, and its manifest's `namespace` puts them under underscore in a package name, and `SE.FS` read as a type, while a folder spelling its
the namespace, so no path repeats it. Valid until a locale's lowered name clashes with namespace takes a reader from a dot path in an error or a template to its file. The second
another's. bench chose that over flat folders such as `data/svse`, 2 to 1, at the cost of a package
name that differs from its folder. A locale is one folder, never a language folder holding
regions: `en_US` and `en_GB` are different languages that share a name. Each package
holds its files at its root, and its manifest's `namespace` puts them under the namespace,
so no path repeats it. Valid until a locale's lowered name clashes with another's.
## A source whose manifest carries an index loads each category on first reach; any other loads in `New`, with what it reads ## A source whose manifest carries an index loads each category on first reach; any other loads in `New`, with what it reads
+2
View File
@@ -58,6 +58,8 @@ func (s Source) labelled(p string) string {
switch { switch {
case s.label != "": case s.label != "":
return path.Join(s.label, p) return path.Join(s.label, p)
case s.mount != nil && p == ".":
return strings.Join(s.mount, ".")
case s.mount != nil: case s.mount != nil:
return fmt.Sprintf("%s (%s)", strings.Join(s.mount, "."), p) return fmt.Sprintf("%s (%s)", strings.Join(s.mount, "."), p)
} }
+1 -1
View File
@@ -76,7 +76,7 @@
| 129 | 0.1.0 | decision | **Take a template wherever the library renders, so `fake:"{/sv_SE.person.first}"` and `Fake("{/sv_SE.person}")` render, and text with no `{…}` prints as written, as the CLI already does.** | 5 | 8 | 8 | 10 | 5.9, 7 | 25.0 | | 129 | 0.1.0 | decision | **Take a template wherever the library renders, so `fake:"{/sv_SE.person.first}"` and `Fake("{/sv_SE.person}")` render, and text with no `{…}` prints as written, as the CLI already does.** | 5 | 8 | 8 | 10 | 5.9, 7 | 25.0 |
| 163 | 0.1.0 | | **Lift the CLI's `--repeat` cap, since the CLI streams each render, and give the builtins' count and decimal caps a technical reason in the README.** | 2 | 2 | 7 | 7 | 2, 5.7 | 24.8 | | 163 | 0.1.0 | | **Lift the CLI's `--repeat` cap, since the CLI streams each render, and give the builtins' count and decimal caps a technical reason in the README.** | 2 | 2 | 7 | 7 | 2, 5.7 | 24.8 |
| 57 | 0.1.0 | | **Rewrite `CHANGELOG.md`'s `[Unreleased]` as what v0.1.0 holds.** | 1 | 2 | 6 | 6 | 1.1 | 22.5 | | 57 | 0.1.0 | | **Rewrite `CHANGELOG.md`'s `[Unreleased]` as what v0.1.0 holds.** | 1 | 2 | 6 | 6 | 1.1 | 22.5 |
| 196 | 0.1.0 | decision | **Name, in the error for a reference nothing loaded provides, the module the reader's manifest reads by default that would provide it, or say none does.** | 3 | 4 | 6 | 8 | 6.2 | 20.0 | | 196 | 0.1.0 | decision | **Name, in the error for a reference nothing loaded provides, the module the reader's manifest reads by default that would provide it, or say none does.** | 3 | 4 | 6 | 8 | 6.2, 9.2 | 20.0 |
| 164 | 0.1.0 | | **Let a table's format or a cell bind a name, which lives in that format or cell and keeps one pick through the draw.** | 2 | 2 | 5 | 7 | 4.1, 5.3 | 19.4 | | 164 | 0.1.0 | | **Let a table's format or a cell bind a name, which lives in that format or cell and keeps one pick through the draw.** | 2 | 2 | 5 | 7 | 4.1, 5.3 | 19.4 |
| 157 | 0.1.0 | | **Show in the README's CLI section how PowerShell and cmd.exe pipe a template, one line per shell family.** | 1 | 1 | 5 | 6 | 7.2 | 17.1 | | 157 | 0.1.0 | | **Show in the README's CLI section how PowerShell and cmd.exe pipe a template, one line per shell family.** | 1 | 1 | 5 | 6 | 7.2 | 17.1 |
| 181 | 0.1.0 | decision | **Fail a load where two sources define one category, unless the library's option or the CLI's flag says the later replaces the earlier, and then make every read reach the replacement.** | 5 | 4 | 6 | 9 | 9.3 | 16.8 | | 181 | 0.1.0 | decision | **Fail a load where two sources define one category, unless the library's option or the CLI's flag says the later replaces the earlier, and then make every read reach the replacement.** | 5 | 4 | 6 | 9 | 9.3 | 16.8 |