Shared dev tooling for AndreiCostinescu's repos, so formatting/lint rules and CI checks are defined once instead of copy-pasted per repo.
hooks/+.pre-commit-hooks.yaml— a pre-commit hook repo: license-header check (C/C++ and Python variants), clang-format, clang-tidy, DCO sign-off. Ruff itself isn't wrapped here — a Python consumer addsastral-sh/ruff-pre-commitas its own separaterepo:entry.config/— canonical.clang-format/.clang-tidy/ruff.toml.scripts/devtools.py— the actualsetup/format/lint/sync-devtools/license-headers/help/detect-languagesimplementation, taking the language(s) to act on as trailing positional args (cpp,python, or both —setup/format/lint/sync-devtools/license-headersrequire at least one). Stdlib-only Python (3.5+, no pip installs needed to run it). (The pre-commit hooks inhooks/staysh— those only ever run through Git's own hook mechanism, which always has a POSIX shell available even on Windows, so there's no reason to change them.)dev.py(see "Using it in a repo" below) — the one tiny script each consumer copies into its own repo root, identical everywhere except for its pinnedDEVTOOLS_REV. Its only job is bootstrapping: download a pinned snapshot of this repo into.devtools/(no git submodule — a plain, gitignored download cache, refetched only whenDEVTOOLS_REVchanges or.devtools/is missing) soscripts/devtools.pyactually exists on a fresh clone, then exec straight into it with the same argv. Python, not Make: Make isn't preinstalled on Windows, and Python is already a hard requirement forscripts/devtools.pyitself, so there's no reason to impose a second tool just to get from a fresh clone to that script running..github/actions/—check-clang-format,run-clang-tidy, andcheck-ruffcomposite actions for CI, wrapping the one command each that's identical everywhere.
The steps are the same whether you're wiring this into an existing repo or
bootstrapping a brand-new one — a new repo just needs git init and its
initial project metadata (pyproject.toml for Python, CMakeLists.txt for
C++) in place before step 5, since setup relies on both for python and
detect-languages looks for both.
No git submodule is involved — dev.py downloads a pinned snapshot of this
repo into .devtools/ itself, so cloning the consumer repo needs nothing
beyond a normal git clone.
-
Point
.pre-commit-config.yamlat this repo (repo: https://github.com/AndreiCostinescu/DevTools, pinnedrev:), listing the hook ids you need (license-header-check-cpp/-python,clang-format,clang-tidy,dco-check). -
Copy this repo's
dev.pyinto the consumer repo root, unmodified except for itsDEVTOOLS_REV— fill that in with a pinned commit SHA (or tag, once this repo has any) before running it;"latest"is also accepted, always tracking the current tip ofmain, but is unpinned by design so prefer a real SHA/tag anywhere reproducibility matters (e.g. CI).dev.pyvalidates whatever you set against GitHub before attempting the download, so a bad/unfilledDEVTOOLS_REVfails with a clear message rather than a confusing 404. All real logic lives inscripts/devtools.py;dev.pyis only the bootstrap that fetches it. -
Python repos only: give
pyproject.tomladevoptional-dependency group that includes at leastruffandpre-commit, e.g.:[project.optional-dependencies] dev = ["ruff", "pre-commit"]
This is the one manual, one-time step —
devtools.pywon't editpyproject.tomlfor you, since (unlike the config files it syncs below) its contents are project-specific. Once thedevextra exists,setupinstalls from it automatically every time — see step 4. -
Run
python dev.py setup cpp(orpython dev.py setup python, orpython dev.py setup cpp python) — at least one language is required forsetup/format/lint/sync-devtools/license-headers. Not sure what to pass?python dev.py detect-languagesprints a suggestion based on what's in the repo —python dev.py helpshows the same suggestion alongside the usage summary.Before
setupeven starts,dev.pyhas already downloaded.devtools/(see step 2).setupitself does the rest: clears any conflictingcore.hooksPath, runspip install -e ".[dev]"(or justpip install pre-commitif you only passedcpp), runspre-commit installfor thepre-commitandcommit-msgstages, and syncs the canonical config files (.clang-format/.clang-tidy/ruff.tomlfor the languages you passed) from.devtools/config/into the repo root. That sync is tracked via a.devtools-sync.sha256state file, so a latersync-devtoolsrun detects local edits to a synced file and warns instead of overwriting them. -
In CI, reference the composite actions as
AndreiCostinescu/DevTools/.github/actions/<action_name>@<repo_rev>. -
Commit the result:
dev.py,.pre-commit-config.yaml, the newly-synced config files, and the.gitignoreentriessetup/sync-devtoolsadd (.devtools/itself, plus the state file's temp write)..devtools/is never committed — it's rebuilt fromdev.py'sDEVTOOLS_REVon demand.
When this repo changes, bump DEVTOOLS_REV in each consuming repo's
dev.py (and the pinned rev: in its .pre-commit-config.yaml, if that
hook set also changed) to pick it up — nothing here is pulled automatically.
- AndreiUtils (cpp)
- ConceptLibrary (python)
- RecordingLib (cpp)
- PerceptionData (cpp)