Thank you for helping improve the bundled presets and tooling for pc-init.
git clone https://github.com/cleder/gpc-init.git
cd gpc-init
uv sync
uv tool install prek
prek installlang/<id>/preset.yaml # language presets (--lang)
framework/<id>/preset.yaml # framework presets (--framework)
gpc_init/ # Python package source
tests/ # pytest test suite
Each preset is a standalone preset.yaml file that follows the pre-commit config format.
Every hook (by id) MUST have a description explaining what it does — a name is encouraged too, but description is what makes generated .pre-commit-config.yaml files self-documenting and is not optional.
A language preset looks like this:
---
repos:
- repo: https://github.com/example/hook
rev: v1.2.3
hooks:
- id: hook-id
name: Example hook
description: What this hook doesA hook may optionally declare a category to mark it as legacy or experimental instead of the default preset category:
- id: mypy
category: legacy
description: "Mirror of mypy for pre-commit"Omit category for hooks that belong in the curated default (preset) — most hooks.
Use category: legacy when the hook is superseded by a newer hook already in the same preset but is still usable (e.g. mypy, superseded by ty).
Use category: experimental for a brand-new, not-yet-proven hook.
Users opt into legacy/experimental hooks with --profile (e.g. pc-init --lang py --profile legacy); preset hooks are always included.
Framework presets may additionally declare which languages and frameworks they recommend:
---
recommended:
lang:
- py
framework:
- git
repos:
- ...A new lang/<id>/ or framework/<id>/ directory needs two files, not just a preset:
lang/<id>/preset.yaml # the hooks (see "Adding or updating a hook" above)
lang/<id>/metadata.yaml # fullname, icon, and detection data (required)
metadata.yaml is what makes the language/framework discoverable — it drives pc-init list, --detect, CLI alias normalization (e.g. --lang=python), and the generated AWESOME.md display label.
Without it, CI's scripts/validate_metadata.py check fails.
For a language:
---
fullname: Python
icon: "🐍"
extensions:
- .py
- .pyi
filenames: [] # case-insensitive file stems with no fixed extension, e.g. dockerfile
aliases:
- python # extra --lang values that normalize to this idFor a framework, metadata.yaml declares how --detect recognizes it instead of extensions/filenames/aliases:
---
fullname: Django
icon: "🎸"
detect:
- file_exists: manage.pySupported declarative rules (each list entry is OR'd — any match detects the framework):
file_exists: <path>— a file exists at that path relative to the repo rootdir_exists: <path>— a directory exists at that pathglob: "<pattern>"— any file in the repo tree matches the filename pattern (e.g."*.nika.yaml")package_json_dep: <name>—package.jsonlists<name>as a dependency or devDependency
If detection genuinely needs to read file content or apply logic that doesn't reduce to one of the rules above (see sphinx/k8s/git for examples), add a Python function to gpc_init/detector.py and register it in _DETECTOR_REGISTRY, then reference it as detect: "python:<function_name>".
This escape hatch is intentionally a fixed allowlist, not an arbitrary import path — a custom --presets catalog must not be able to smuggle in code.
Extensions, filenames, and aliases must be globally unique across every language — the catalog loader hard-fails at load time if two languages claim the same one. Run this before opening a PR:
uv run scripts/validate_metadata.pyOne PR must touch exactly one language or framework preset.
If you want to update both lang/py/preset.yaml and framework/django/preset.yaml, open two separate PRs.
Run all four commands against the preset file before opening a PR. CI enforces the same checks and will fail if they are skipped.
pre-commit validate-config lang/<id>/preset.yaml
pre-commit autoupdate -c lang/<id>/preset.yaml
prek validate-config lang/<id>/preset.yaml
prek autoupdate -c lang/<id>/preset.yamlAfter running autoupdate, commit the file if any revisions changed.
To validate and update every preset at once:
find . -name "preset*.yaml" | xargs -I{} pre-commit validate-config {}
find . -name "preset*.yaml" | xargs -I{} pre-commit autoupdate -c {}
find . -name "preset*.yaml" | xargs -I{} prek validate-config {}
find . -name "preset*.yaml" | xargs -I{} prek autoupdate -c {}The repository includes a .justfile for using the just runner framework.
You can install just with uv.
uv tool install rust-justOnce you have this installed you can use just to see the available recipes.
❱ just
just --list
Available recipes:
awesome
default
test
update target="all" type="lang"
validate target="all" type="lang"validate and update both take an optional target (a language or framework alias, defaulting to all) and type (lang or framework, defaulting to lang).
This lets you validate and/or update a given preset in a concise manner: just provide the alias, and, for framework presets, the type.
❱ just validate py
Validating py ...
success: All configs are valid
success: All configs are valid❱ just update py
Autoupdating py...
[https://github.com/MarcoGorelli/absolufy-imports] already up to date!
[https://github.com/astral-sh/ruff-pre-commit] updating v0.15.19 -> v0.15.20
[https://github.com/abravalheri/validate-pyproject] already up to date!
...For a framework preset, pass framework as the second argument, e.g. just validate django framework.
To validate or update every preset at once, omit the target (or pass all):
just validate
just updateOnly include hooks that are publicly available, actively maintained, and add clear value over hooks already in the preset.
Every hook MUST have a description, harvested from its own .pre-commit-hooks.yaml where possible.
After uv sync, run the CLI directly without installing:
uv run pc-init --help
uv run pc-init --lang=py --framework=djangoOr install it into the project venv once:
uv pip install -e .
pc-init --helpRun the test suite and static checks before opening a PR:
just testwhich will run:
uv run pytest tests --cov=gpc_init tests
uv run complexipy --failed gpc_init
uv run ruff check gpc_init tests
uv run ruff format gpc_init tests
uv run pyrefly check gpc_init tests
uv run ty check gpc_init testsFill in the PR description and complete every item in the pre-submission checklist before requesting review. Incomplete checklists will not be merged.