config loading fixtures ======================= Each case pairs a `config.yaml` input with the `result` of loading it: either the normalized repo listing, or the startup error. Paths are shown with the config file's directory as `$BASE`. Regenerate the result hunks with `go test -run TestLoadConfig . -testmark.regen`. Good configs ------------ The minimal config: one repo, and the `%` placeholder saying its path matches its name. [testmark]:# (good-minimal/config.yaml) ```yaml repos: parnass: path: "%" ``` [testmark]:# (good-minimal/result) ```text repo parnass: path=$BASE/parnass ``` Names may be slash-nested to arbitrary depth; paths may be relative (resolved against the config file's directory, even pointing outside it) or absolute; descriptions are optional. [testmark]:# (good-varied/config.yaml) ```yaml repos: parnass: path: "%" description: "the showcase repo" work/infra/deploy: path: ../deploy elsewhere: path: /srv/git/elsewhere ``` [testmark]:# (good-varied/result) ```text repo elsewhere: path=/srv/git/elsewhere repo parnass: path=$BASE/parnass description="the showcase repo" repo work/infra/deploy: path=$PARENT/deploy ``` Trailing slashes on paths are normalized away. [testmark]:# (good-trailing-slash-path/config.yaml) ```yaml repos: tidy: path: "sub/dir/" ``` [testmark]:# (good-trailing-slash-path/result) ```text repo tidy: path=$BASE/sub/dir ``` Bad configs ----------- Every problem below is a startup error: socle refuses to run on a config it can't fully honor. Unknown keys are errors, not silence; typos should not quietly change meaning. [testmark]:# (err-unknown-key/config.yaml) ```yaml repos: parnass: path: "%" exposed: true ``` [testmark]:# (err-unknown-key/result) ```text error: config $BASE/config.yaml: yaml: unmarshal errors: line 4: field exposed not found in type main.repoConfig ``` A config with nothing to serve is a misconfiguration. [testmark]:# (err-no-repos/config.yaml) ```yaml repos: {} ``` [testmark]:# (err-no-repos/result) ```text error: config $BASE/config.yaml: no repos configured; a socle with nothing on display is a misconfiguration ``` Repo names are validated: segments of `[A-Za-z0-9._-]`, no leading dot or dash. [testmark]:# (err-bad-name/config.yaml) ```yaml repos: .hidden: path: "%" ``` [testmark]:# (err-bad-name/result) ```text error: config $BASE/config.yaml: invalid: repo name ".hidden": segment ".hidden" starts with "." ``` Names ending in `.git` are rejected: URLs treat a trailing `.git` as an alias for the plain name, and configuring one would make that alias ambiguous. [testmark]:# (err-git-suffix-name/config.yaml) ```yaml repos: parnass.git: path: "%" ``` [testmark]:# (err-git-suffix-name/result) ```text error: config $BASE/config.yaml: invalid: repo name "parnass.git": segment "parnass.git" ends in .git (reserved as a URL alias for the plain name) ``` No repo name may be a path-prefix of another; nested names would make URL dispatch ambiguous. [testmark]:# (err-prefix-collision/config.yaml) ```yaml repos: work: path: "%" work/deploy: path: "%" ``` [testmark]:# (err-prefix-collision/result) ```text error: config $BASE/config.yaml: repo "work" is a path-prefix of repo "work/deploy"; nested names would make URL dispatch ambiguous ``` The path field is required; an empty entry is probably an accident, so there is no default. [testmark]:# (err-missing-path/config.yaml) ```yaml repos: parnass: description: "all description, no substance" ``` [testmark]:# (err-missing-path/result) ```text error: config $BASE/config.yaml: repo "parnass": missing required field "path" (use "path: %" to serve the path matching the repo name) ``` Serving the filesystem root is refused outright. [testmark]:# (err-root-path/config.yaml) ```yaml repos: everything: path: "/" ``` [testmark]:# (err-root-path/result) ```text error: config $BASE/config.yaml: repo "everything": path "/" is the filesystem root; refusing ```