Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,15 @@ default_language_version:
node: system

repos:
- repo: https://github.com/crate-ci/typos
rev: v1.50.1
hooks:
- id: typos
# Drop the upstream default `--write-changes` so the hook reports and
# fails instead of rewriting files. Keep `--force-exclude` so the
# excludes in typos.toml still apply to the paths prek passes in.
args: ["--force-exclude"]

- repo: https://github.com/pre-commit/pre-commit-hooks
rev: 3e8a8703264a2f4a69428a0aa4dcb512790b2c8c # 6.0.0
hooks:
Expand Down
73 changes: 73 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,79 @@ These are the only variables currently being used on the playbooks, but can be e

Additional settings can be found in `playbook/group_vars/all`, but these are not intended to be freely changed and should be treated with care.

## Spell checking

Every managed repository runs [typos](https://github.com/crate-ci/typos) as a prek hook.
The hook is templated in `template/.pre-commit-config.yaml.j2`.
The word lists are **not** templated: each repository carries its own `typos.toml`, hand-maintained.

That split is forced by the tool. typos has no layered configuration yet ([crate-ci/typos#193](https://github.com/crate-ci/typos/issues/193)).
Keeping the word lists local also means adding a word is a single PR in a single repository, rather than a PR here plus a sync to every managed repository.

### The core config

As convention, new repositories should start from this block and add only what they actually need.

```toml
[files]
# Bare `typos` skips hidden directories, but prek passes explicit paths and so does
# check them. Turn it off so a local run and the hook agree; without it, .github/
# and .readme/ are invisible locally but not to CI.
ignore-hidden = false

extend-exclude = [
# Required once ignore-hidden is off, or typos walks .git/objects.
".git/",
# Generated by `make regenerate-nix` (crate2nix).
"Cargo.nix",
"crate-hashes.json",
# Generated by `make crds`. See "check each string once" below.
"extra/crds.yaml",
"deploy/helm/*/crds/crds.yaml",
# Diagram sources; the payload is base64 and produces only noise.
"*.drawio",
"*.drawio.svg",
]

[default]
# typos has no native suppression directive (crate-ci/typos#316), so these regexes
# provide one. They cover `#`, `//`, `<!-- -->`, `;`, `/* */` and Jinja `{# #}`
# comments. Both failure modes are safe: an unterminated `:off` suppresses nothing
# rather than swallowing the rest of the file, and `disable-line` only matches when
# the marker ends the line, so trailing text defeats it instead of widening it.
extend-ignore-re = [
"(?Rm)^.*(#|//|<!--|;|/\\*)\\s*spellchecker:disable-line\\s*(-->|#\\}|\\*/)?\\s*$",
"(#|//|<!--|;|/\\*)\\s*spellchecker:ignore-next-line\\s*(-->|#\\}|\\*/)?\\s*\\n.*",
"(?s)(#|//|<!--|;|/\\*|\")\\s*spellchecker:off\\s*(-->|#\\}|\\*/|\")?.*?(#|//|<!--|;|/\\*|\")\\s*spellchecker:on\\s*(-->|#\\}|\\*/|\")?",
]

[default.extend-words]
# Azure Kubernetes Service. Appears in the README footer and as the runner platform
# in tests/interu.yaml. A single lowercase entry covers every casing.
aks = "aks"
```

`aks` is the only word that is genuinely universal.
Everything else measured across the operator repositories turned out to be repo-local: `aas` in opa-operator, `shs` in spark-k8s-operator, base64 fixtures in secret-operator. <!-- spellchecker:disable-line -->
Short tokens that appear in several repositories (`ot`, `fo`) do so for unrelated reasons and belong in the repository that has them, not here. <!-- spellchecker:disable-line -->

### Check each string once

`extra/crds.yaml` is excluded on purpose.
Its content is generated: partly Kubernetes' own schema documentation, which is not ours to correct, and partly doc comments owned by `operator-rs` or by the operator's own `crd` module — both of which are already checked at their source.
The same applies to files rendered from `template/`: a typo in `template/.readme/partials/borrowed/footer.md.j2.j2` is caught here, once, instead of in all sixteen repositories.

> [!NOTE]
> Excluding rendered content more thoroughly — everything a repository receives from `operator-templating` or `operator-rs` — is a known refinement that has not been done yet.
> The generated CRDs are the case that mattered in practice.

### Conventions

- The hook runs report-only. `args: ["--force-exclude"]`.
- Every entry in a `typos.toml` gets a one-line comment saying what the word is.
- Prefer an in-place marker over a config entry when the word is correct at one site and would still be a typo elsewhere: `spellchecker:disable-line` at the end of the line, `spellchecker:ignore-next-line` on the line above, or `spellchecker:off` / `:on` around a block.
- Licence and other verbatim third-party files are excluded, never corrected.

## Making changes to the template

If you want to make a change that should be rolled out to all operators, make the change in the `template` directory.
Expand Down
14 changes: 14 additions & 0 deletions template/.pre-commit-config.yaml.j2
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,20 @@ default_language_version:
node: system

repos:
# The word lists live in a per-repo `typos.toml`, which is deliberately NOT
# templated: typos has no layered configuration
# (https://github.com/crate-ci/typos/issues/193), so the nearest config file
# wins outright and a templated one could not be extended locally. Only the
# hook itself is shared, because it is identical everywhere.
- repo: https://github.com/crate-ci/typos
rev: v1.50.1
hooks:
- id: typos
# Drop the upstream default `--write-changes` so the hook reports and
# fails instead of rewriting files. Keep `--force-exclude` so the
# excludes in typos.toml still apply to the paths prek passes in.
args: ["--force-exclude"]

- repo: https://github.com/pre-commit/pre-commit-hooks
rev: 3e8a8703264a2f4a69428a0aa4dcb512790b2c8c # 6.0.0
hooks:
Expand Down
52 changes: 52 additions & 0 deletions typos.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
# Configuration for typos (https://github.com/crate-ci/typos), run via the prek
# hook in .pre-commit-config.yaml.
#
# This config covers operator-templating itself. The operator repositories each
# carry their own typos.toml, which is deliberately NOT rolled out from
# template/: typos has no layered configuration
# (https://github.com/crate-ci/typos/issues/193), so the nearest config file
# wins outright and is never merged with one further up the tree. A templated
# config could not be extended with repo-specific words, and adding one word to
# one operator would otherwise mean a PR here plus a sync to all repositories.
#
# Only the hook is shared, via template/.pre-commit-config.yaml.j2.
#
# Before adding an entry here, consider an in-place marker instead. Use one when
# the word is correct at this one site and would still be a typo elsewhere:
#
# # spellchecker:disable-line at the end of the line it applies to
# # spellchecker:ignore-next-line on its own line, above the offending line
# # spellchecker:off / :on around a block
#
# Every entry below gets a one-line comment saying what the word is.

[files]
# Bare `typos` skips hidden directories, but prek passes explicit paths and so
# does check them. Turn it off so both agree -- without this, template/.readme/
# and template/.github/ are invisible to a local run but not to the hook.
ignore-hidden = false

extend-exclude = [
# `.git` itself, which ignore-hidden = false would otherwise pull in.
".git/",
]

[default]
# typos has no native suppression directive
# (https://github.com/crate-ci/typos/issues/316), so these regexes provide one.
# They cover `#`, `//`, `<!-- -->`, `;`, `/* */` and Jinja `{# #}` comments.
#
# Both failure modes are safe: an unterminated `:off` suppresses nothing rather
# than swallowing the rest of the file, and `disable-line` only matches when the
# marker ends the line, so trailing text defeats it instead of widening it.
extend-ignore-re = [
"(?Rm)^.*(#|//|<!--|;|/\\*)\\s*spellchecker:disable-line\\s*(-->|#\\}|\\*/)?\\s*$",
"(#|//|<!--|;|/\\*)\\s*spellchecker:ignore-next-line\\s*(-->|#\\}|\\*/)?\\s*\\n.*",
"(?s)(#|//|<!--|;|/\\*|\")\\s*spellchecker:off\\s*(-->|#\\}|\\*/|\")?.*?(#|//|<!--|;|/\\*|\")\\s*spellchecker:on\\s*(-->|#\\}|\\*/|\")?",
]

[default.extend-words]
# Azure Kubernetes Service. Appears in the README footer partial that is
# rendered into every operator repository. A single lowercase entry covers
# every casing, so no separate `AKS` entry is needed.
aks = "aks"