Skip to content

Capability 001: Configuration

Status: Accepted

Context

repo generates a repository from one file, .repo.yaml, which the developer owns and edits (mission statement; target picture, sections Configuration and Commands). This capability defines that file, the commands that write its template, and how repo update reads and checks it. What repo update generates from it is not part of this capability.

References

Details

Fields of .repo.yaml:

Field Level Required Content
name repository yes Human-readable name
description repository yes One sentence
repository repository yes Path of the repository at its host, e.g. gitlab.com/<group>/<project>
repoType repository yes single or mono
ci repository yes gitlab or github
assistants repository no Any of claude, copilot; empty or absent: none
documentation repository no lean or extended (capability 010); absent: lean
requirements repository no repo or external (capability 010); absent: repo
tracker repository no Issue list URL for requirements: external (capability 010); absent: derived
artifacts repository yes List of artifacts
name artifact yes Slug: executable, archive, image, tag prefix, and, in mono, directory
title artifact yes Human-readable name
description artifact yes One sentence
language artifact yes cpp, go, java, typescript, kicad
type artifact yes library, service, tool, frontend-react, firmware-stm32, electronics
modules artifact no Modules to generate; absent: the profile's defaults
registry artifact no Container registry; absent: derived from repository and ci
port artifact no Host port of a service or frontend in the generated Compose files; absent: 8080 plus the artifact's position, counted from 0
meta repository — Written by repo update only: generatorVersion, and the modules per artifact

Values derived from repository:

Value single mono
Go module path <repository> <repository>/<name>
Java package Reversed host, then the path segments of the Go module path Same
Container registry Registry of the ci host for the Go module path without its last segment Same

Supported combinations of language and type:

Language Types
cpp library, service, tool, firmware-stm32
go library, service, tool
java library, service
typescript frontend-react
kicad electronics

Functional Requirements

  1. repo init writes a .repo.yaml template with repoType: single and one artifact into the current directory.
  2. repo init-mono writes a .repo.yaml template with repoType: mono and two artifacts into the current directory.
  3. repo add appends one artifact to the artifacts list of a mono .repo.yaml.
  4. Every template contains each field of its level with an empty or example value and a comment naming the permitted values. repo add keeps the existing content and comments of the file.
  5. The first line of a template points editors to the schema of .repo.yaml in the generator's docs site, as a comment the YAML language server reads.
  6. repo update reads .repo.yaml from the current directory and validates it before it writes anything. Validation reports every violation found, not only the first.
  7. Validation rules:
    1. Every required field is present and not empty.
    2. Every enumerated field has a permitted value; language and type form a supported combination.
    3. single: exactly one artifact; mono: at least one.
    4. An artifact name is a slug: lowercase letters, digits, and single hyphens, starting with a letter and not ending with a hyphen. Artifact names are unique.
    5. repository consists of a host and at least two path segments, without scheme or .git.
  8. After successful generation, repo update rewrites the meta block, with meta.generatorVersion set to its own version, and changes nothing else in .repo.yaml.
  9. repo version prints the generator version.
  10. No command accepts options or arguments.

Non-Functional Requirements

  1. A developer who knows the target picture fills in a template without other documentation; the comments suffice.

Technical Requirements

None.

Error Handling

  1. A violation is reported as .repo.yaml:<line>: <field>: <problem>, one per line, on standard error; the command exits non-zero and writes nothing.
  2. repo init and repo init-mono refuse an existing .repo.yaml and leave it untouched.
  3. repo add refuses a missing .repo.yaml and a single one.
  4. repo update without .repo.yaml in the current directory names the file and suggests repo init or repo init-mono; inside an artifact directory of a mono-repository it also suggests running from the repository root.
  5. A .repo.yaml or .mono-repo.yaml of the previous format (top-level key content:) is refused with a message that the format changed with repo 2.0.0 and that the old version remains available as v1.5.0.
  6. A command given an option or argument fails with its usage text.

Out of Scope

  • What repo update generates, the modules, and repo check
  • Deriving values from the Git remote or the directory name when writing a template
  • Migrating a configuration of the previous format

Acceptance Criteria

  1. Empty directory, repo init: .repo.yaml exists with repoType: single and one artifact.
  2. Empty directory, repo init-mono: .repo.yaml exists with repoType: mono and two artifacts.
  3. Existing .repo.yaml, repo init and repo init-mono: refused; the file is unchanged.
  4. mono .repo.yaml with comments, repo add: three artifacts; the comments and the first two artifacts are unchanged.
  5. single .repo.yaml, repo add: refused; the file is unchanged.
  6. Unfilled template from repo init, repo update: every empty required field is reported with its line; nothing is written.
  7. single with two artifacts, mono without artifacts: each reported.
  8. language: java, type: tool: reported as an unsupported combination.
  9. Two artifacts with the same name, names Bridge, my_bridge, ../x, bridge-: each reported.
  10. repository: https://gitlab.com/<group>/<project>.git, repository: <project>: each reported.
  11. Valid .repo.yaml, repo update: meta.generatorVersion equals the version that repo version prints; the file outside meta is byte-identical.
  12. Previous format with content:: refused with the hint to v1.5.0.
  13. repo update --dry-run, repo init --name x: each fails with the usage text.
  14. mono with repository: gitlab.com/<group>/<project> and a Go artifact bridge: Go module path gitlab.com/<group>/<project>/bridge.
  15. Empty directory, repo init and repo init-mono: the first line of .repo.yaml is # yaml-language-server: $schema= followed by the URL of repo-config.schema.json in the docs site.

Decisions

  1. Templates carry no derived values. The previous repo init derived the CI system, artifact name, and module path from the Git remote. A template with comments is simpler and shows every field; the developer fills in a handful of values once.
  2. repo update writes only the meta block into .repo.yaml. It never reformats the developer's file, so comments survive; repo add is the only other command that edits it.
  3. Validation reports all violations at once. A filled-in template typically has several gaps; one run per gap would be tedious.
  4. repo update runs from the repository root only. One .repo.yaml describes the whole repository, so there is no per-artifact entry point.
  5. An artifact's directory in a mono-repository is its name. The name is a slug anyway, like the project slug of a single repository; a separate path would only allow the two to differ. Consequence: artifacts cannot be grouped in subdirectories, and renaming an artifact moves its directory.
  6. One repository field instead of a module path per artifact. Go module path, Java package, and registry default all follow from where the repository lives, so the developer states it once. Consequence: a Go module path that differs from the repository path, such as a vanity import path, is not possible.