Make great documentation goal 1.2, and plan the README's reorganisation and the nested-template gaps #33
@@ -1,9 +1,3 @@
|
||||
# The merge gate: `docker build .` fails if vet, complexity, formatting or tests
|
||||
# fail, and CI runs exactly this. Day-to-day, prefer `docker compose run`
|
||||
# (bind-mounts source, no rebuilds). GO_VERSION defaults to the latest stable Go;
|
||||
# the lowest supported version builds the `portable` stage, which every supported
|
||||
# Go must pass:
|
||||
# docker build --build-arg GO_VERSION=1.22.12 --target portable .
|
||||
ARG GO_VERSION=1.27.1
|
||||
FROM golang:${GO_VERSION} AS portable
|
||||
|
||||
|
||||
@@ -322,7 +322,6 @@ func (p *calcParser) binary(next func() (calcNode, error), ops ...byte) (calcNod
|
||||
}
|
||||
}
|
||||
|
||||
// factor is a table-shaped scanner, one case per token kind, kept whole on purpose.
|
||||
func (p *calcParser) factor() (calcNode, error) {
|
||||
p.space()
|
||||
if p.pos >= len(p.rs) {
|
||||
|
||||
@@ -1,19 +1,3 @@
|
||||
# Docker-based dev workflow — no local tooling beyond Docker is required.
|
||||
#
|
||||
# docker compose run --rm test
|
||||
# docker compose run --rm vet
|
||||
# docker compose run --rm build
|
||||
#
|
||||
# The full gate — vet, formatting, cyclomatic complexity and tests — is
|
||||
# `docker build .`, which is what CI runs.
|
||||
#
|
||||
# Build caches persist in the `gocache` volume, so re-runs are fast and the
|
||||
# host tree stays clean. Commands that rewrite source (fmt, tidy) keep your
|
||||
# ownership when run with `--user "$(id -u):$(id -g)"`.
|
||||
#
|
||||
# GO_VERSION picks the toolchain image (default: latest stable). Test the lowest
|
||||
# supported Go with: GO_VERSION=1.22.12 docker compose run --rm test
|
||||
|
||||
x-go: &go
|
||||
image: golang:${GO_VERSION:-1.27.1}
|
||||
working_dir: /app
|
||||
|
||||
@@ -187,5 +187,4 @@ func readsTable(n node, a arm) bool {
|
||||
return isTable
|
||||
}
|
||||
|
||||
// checkColumnDraws fences a record's columns as one render.
|
||||
func checkColumnDraws(t *template, columns []string) error { return surveyColumns(t, columns).check() }
|
||||
|
||||
@@ -15,8 +15,7 @@ type ftoken struct {
|
||||
|
||||
// eachToken scans a format string once and calls fn for each unit, the single
|
||||
// source of truth for how braces are read: "{{" and "}}" are literal braces, a "{"
|
||||
// opens a token that must reach its "}", and a lone "}" is an error. A table-shaped
|
||||
// scanner, one case per rune kind, kept whole on purpose.
|
||||
// opens a token that must reach its "}", and a lone "}" is an error.
|
||||
func eachToken(format string, fn func(ftoken) error) error {
|
||||
rs := []rune(format)
|
||||
for i := 0; i < len(rs); i++ {
|
||||
|
||||
@@ -515,8 +515,6 @@ func checkPathNames(path string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// isOption reports whether a template key configures the node instead of naming a
|
||||
// field. These names can never be fields.
|
||||
func isOption(name string) bool {
|
||||
switch name {
|
||||
case "datatype", "drawGroup", "format", "repeat", "separator", "weight":
|
||||
|
||||
@@ -99,7 +99,6 @@ func splitOutside(s string, c byte) []string {
|
||||
}
|
||||
}
|
||||
|
||||
// isSelector reports whether a segment is a [key or name] rather than a name.
|
||||
func isSelector(seg string) bool { return strings.HasPrefix(seg, "[") }
|
||||
|
||||
func hasSelector(segs []string) bool {
|
||||
@@ -111,7 +110,6 @@ func hasSelector(segs []string) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// selectorOf is the key or name a selector segment holds.
|
||||
func selectorOf(seg string) string { return seg[1 : len(seg)-1] }
|
||||
|
||||
// nameSegments is the segments of a path that are names, its selectors left out.
|
||||
@@ -470,8 +468,6 @@ func unreachableInChoice(c *choice, want string) error {
|
||||
return fmt.Errorf("not every variant of this %d-way choice carries %q; all carry %v", len(c.items), want, offered)
|
||||
}
|
||||
|
||||
// checkPath runs pathCheck over a path read at load; level names the head in its
|
||||
// errors.
|
||||
func checkPath(n node, tail []string, level string) error {
|
||||
_, err := (&pathCheck{level: level, tail: tail}).run(n)
|
||||
return err
|
||||
|
||||
@@ -6,7 +6,8 @@ import (
|
||||
)
|
||||
|
||||
// rng is the randomness a builtin sample draws from; *rand.Rand satisfies it. The
|
||||
// render path takes the concrete *session instead.
|
||||
// render path takes the concrete *session instead, which keeps the hold set of the walk
|
||||
// drawing through it off the heap.
|
||||
type rng interface {
|
||||
IntN(n int) int
|
||||
Float64() float64
|
||||
@@ -106,8 +107,6 @@ func expandAnew(s *session, t *template) string {
|
||||
// pick selects one item. Uniform choices are O(1); weighted choices are an
|
||||
// O(log n) search over precomputed cumulative weights. compile guarantees a
|
||||
// non-empty choice and a finite positive total, so the index is always in range.
|
||||
// The session is concrete rather than the rng interface, which would make the
|
||||
// walk that draws through it leak its hold set to the heap.
|
||||
func pick(s *session, c *choice) node {
|
||||
if c.cum == nil {
|
||||
return c.items[s.IntN(len(c.items))]
|
||||
|
||||
@@ -82,7 +82,6 @@ func isTableOption(name string) bool {
|
||||
// token arm.
|
||||
const inSelector = `[]{}"|`
|
||||
|
||||
// compileTable compiles a category object naming a rows file into a table.
|
||||
func compileTable(m map[string]any, segment string, files *categoryFiles) (*table, error) {
|
||||
o, err := readTableOptions(m)
|
||||
if err != nil {
|
||||
@@ -472,8 +471,7 @@ func (t *table) builtLookup() *rowLookup {
|
||||
return &t.lookup
|
||||
}
|
||||
|
||||
// drawRow picks a row over the whole table. The session is concrete rather than the rng
|
||||
// interface so that the walk that draws through it keeps its hold set off the heap.
|
||||
// drawRow picks a row over the whole table.
|
||||
func (t *table) drawRow(s *session) int {
|
||||
if t.cum == nil {
|
||||
return s.IntN(t.rowCount())
|
||||
|
||||
@@ -28,11 +28,6 @@ ranking `readSurvey.walk` hardest and all seven the unit they would least modify
|
||||
|
||||
This round, in order:
|
||||
|
||||
- Delete the prose the seats found empty: "kept whole on purpose"
|
||||
(`format.go`, `calc.go`), the second copy of the concrete-session rationale
|
||||
(`table.drawRow`, `pick`), the doc comments restating `isSelector`, `selectorOf`,
|
||||
`checkPath`, `checkColumnDraws`, `compileTable` and `isOption`, and the `compose.yaml`
|
||||
and `Dockerfile` preambles restating the README's Development.
|
||||
- Run the nine-seat panel again and file what it names here.
|
||||
|
||||
### Data
|
||||
@@ -313,7 +308,7 @@ because pairing a street with its exact postnummer rewrites shipped rows.
|
||||
second copy that drifts. Split the comprehension rule while there, which packs the
|
||||
gate, its exceptions, the round and the at-or-above-7.0 regime into one line.
|
||||
- Scope `AGENTS.md`'s `Hard tabs.` to the Go source, or drop it: `gofmt` already gates
|
||||
Go at `Dockerfile:21`, and the shipped JSON under `data/` is two-space, so the rule as
|
||||
Go at `Dockerfile:16`, and the shipped JSON under `data/` is two-space, so the rule as
|
||||
written is one no Go file can break and every data file does.
|
||||
- Make `gitea.larvit.se/larvit/fejkdata` a pull mirror of GitHub:
|
||||
Gitea converts a repository to a mirror only by re-creating it, so until that runs
|
||||
|
||||
Reference in New Issue
Block a user