build: enforce ruff format and dotnet format via pre-commit hooks - #3581
Conversation
Add a pre-commit config (astral-sh/ruff-pre-commit for Python under pyrevitlib/, excluding the vendored rpw/ wrapper; a local hook for C#) so any commit touching Python or C# gets auto-formatted and stopped for review if anything changed. The C# side needed its own wrapper (dev/scripts/format_staged_csharp.py) since dotnet format needs a project/solution context per file and --include only accepts solution-relative paths; it groups staged files by which of the four first-party solutions under dev/ they belong to and excludes the dev/modules/ git submodules. Also adds the .editorconfig dotnet format needed to avoid rewriting brace style repo-wide: this codebase has two co-existing, internally-consistent conventions (same-line/K&R almost everywhere; Allman in the newer pyRevitAssemblyBuilder/pyRevitExtensionParser/pyRevitExtensionParserTester trio), verified directly against the source rather than assumed, with both directions round-tripped through the hook before landing this. Migrates pyproject.toml's [tool.ruff] settings to [tool.ruff.lint] (the top-level keys are deprecated in the ruff version already pinned in Pipfile) - surfaced as a warning while testing the new ruff-format hook.
Match all first-party Python (extensions/, dev/scripts/, release/bin-assets/, docs/, extras/, etc.) instead of just pyrevitlib/, which missed the bundled extensions' own startup/command scripts entirely. Switch to an exclude-list (vendored site-packages/, pyrevitlib/rpw/, dev/modules/) since enumerating every first-party location as an allow-list turned out to be the more fragile direction - there are more of them than expected.
|
Unable to trigger custom agent "Code Reviewer". You have run out of credits 😔 |
|
And this one too is cool! @romangolev |
There was a problem hiding this comment.
Pull request overview
This PR wires up commit-time auto-formatting for the pyRevit repo without reformatting the existing codebase. It adds a pre-commit configuration that runs ruff format on first-party Python and a local hook that runs dotnet format on staged C# files, plus an .editorconfig that encodes the repo's two co-existing brace conventions so dotnet format follows whichever style each area already uses. It also migrates deprecated [tool.ruff] keys and documents the new setup step in AGENTS.md.
Changes:
- Add
.pre-commit-config.yaml(ruff-format + localdotnet formathook) and aformat_staged_csharp.pyhelper that groups staged.csfiles by their owning solution. - Add
.editorconfigencoding per-directory C# brace conventions (K&R default, Allman for thepyRevitAssemblyBuilder/pyRevitExtensionParser/pyRevitExtensionParserTestertrio). - Add
pre-commitas a dev dependency, migratepyproject.tomlruff config to[tool.ruff.lint], and updateAGENTS.mddocs.
Reviewed changes
Copilot reviewed 6 out of 7 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
.pre-commit-config.yaml |
Defines the ruff-format hook and the local dotnet format C# hook; ruff rev does not match the pinned Pipfile version. |
dev/scripts/format_staged_csharp.py |
New helper that groups staged C# files by first-party solution and runs dotnet format per group. |
.editorconfig |
Encodes indentation and per-directory brace conventions for dotnet format. |
pyproject.toml |
Migrates deprecated [tool.ruff] keys to [tool.ruff.lint] / [tool.ruff.lint.pydocstyle]. |
Pipfile |
Adds pre-commit dev dependency and an install-hooks script. |
Pipfile.lock |
Regenerated lock adding pre-commit and its transitive dependencies. |
AGENTS.md |
Documents the new hook-install step and updated Python/C# code-style enforcement. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
|
@romangolev please review comments above and set for ready for review |
…behavior in documentation
|
📦 New work-in-progress (wip) builds are available for 7.0.0.26237+2139 |
|
📦 New work-in-progress (wip) builds are available for 7.0.0.26237+2139 |
Summary
Adds commit-time auto-formatting so new Python and C# changes stay consistent, without silently rewriting the whole repo in this PR.
.pre-commit-config.yaml:ruff format(officialastral-sh/ruff-pre-commitmirror, pinned to match theruffversion already inPipfile) for any commit touching first-party Python (pyrevitlib/,extensions/,dev/scripts/,release/bin-assets/,docs/,extras/, etc. - vendoredsite-packages/,pyrevitlib/rpw/, and thedev/modules/git submodules excluded), plus a local hook that runsdotnet formaton any staged.csfile.dev/scripts/format_staged_csharp.py:dotnet formatneeds a project/solution context per file and--includeonly accepts solution-relative paths, so this groups staged files by which of the four first-party solutions underdev/they belong to and invokes onedotnet formatper group..editorconfig: without this,dotnet formatfalls back to Roslyn's default brace style (Allman) and rewrites every brace in any file it touches, regardless of the codebase's actual style. This repo has two co-existing, internally-consistent conventions - same-line/K&R almost everywhere, Allman in the newerpyRevitAssemblyBuilder/pyRevitExtensionParser/pyRevitExtensionParserTestertrio - verified directly against the source (not assumed) and encoded per-directory so the hook follows whichever convention a given area already uses.pyproject.toml: migrated[tool.ruff]to[tool.ruff.lint]- the top-level keys are deprecated in theruffversion already pinned, surfaced as a warning while testing the new hook.AGENTS.md: documents the newpipenv run pre-commit installsetup step and what's now enforced vs. what still needs a manualruff check --fix.This PR only wires up enforcement for future commits - it does not reformat the existing codebase. Both tools have never touched this repo before, so running them across everything (
pipenv run pre-commit run --all-files) surfaces real, pre-existing drift (extra spaces, missing spaces after keywords, trailing whitespace, inconsistent blank lines) in roughly 550 files repo-wide.That repo-wide pass should be run as a separate follow-up only after this PR is approved and merged - once the hook config and
.editorconfigconventions here are confirmed correct, not before. Doing it first would produce an enormous diff on top of a still-under-review formatting policy, and any correction to the policy after the fact would mean redoing it.To run it once this lands:
Test plan
pre-commitlocally, ran the real git hook against staged Python and C# violations - each hook only fires when its language is actually staged, clean files produce zero changes, and genuine drift gets caught and fixed correctly..editorconfigin place - no cross-contamination between the two areas.ruff check pyrevitlib/pyrevit/loader/sessionmgr.pystill applies the docstring lint rules correctly after thepyproject.tomlmigration.