Add pretty_format_json as builtin hook#915
Conversation
897d3f3 to
ae79e95
Compare
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## master #915 +/- ##
==========================================
+ Coverage 91.93% 92.14% +0.20%
==========================================
Files 107 108 +1
Lines 21164 21750 +586
==========================================
+ Hits 19458 20042 +584
- Misses 1706 1708 +2 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
ae79e95 to
386ebd2
Compare
|
Not sure why our binary sizes don't match, a good idea would be to have this computed on CI (I know CodeCov can do that automatically for JavaScript bundles or something? But not sure about Rust) Will open an issue about that, but relative size like you did is fine 👍 Edit: oh, did you build in release mode? I doubt it would matter though I thought similar was the same crate difftastic uses but that is strsim It says there is a testing crate for it https://github.com/mitsuhiko/similar-asserts maybe that could simplify the tests, but no need to |
|
@lmmx Yes I did, assumed you did aswell fom this snippet: |
|
@lmmx I'll take a look at simplifying the tests. Could also assign a new issue to me, so I can pick it up later on, when time allows |
All good! Just FYI, you don't need to be assigned anything to work on it here. Open source repos work on a pull-based model where contributors pick up issues they want to work on. I'm just another contributor here, not a maintainer, so I can't assign tickets anyway 😁 My comment was just a suggestion if you were after any more ideas, feel free to leave it as is. Enjoy your weekend 😄 |
I think you might be on different operating systems or architectures? |
|
Arm, macbook here! Didnt think it would be such a difference. Like the ci suggestion! |
Linux, no I didn't expect it to be such a gap either |
pretty_format_json as builtin hook
333ae62 to
107da9e
Compare
📦 Cargo Bloat ComparisonBinary size change: +1.60% (25.0 MiB → 25.4 MiB) Expand for cargo-bloat outputHead Branch ResultsBase Branch Results |
|
@j178 Anything I can add to this PR? I checked the similar-asserts crate, but didn't find it cleaned up tests more than simple test files, like it has at the moment. If you still prefer the other way, I'm happy to change it. |
|
Your work is fantastic - the rest is on my end now. I just need more time to figure out all the details and make sure everything lines up with the Python implementation. If I think anything needs tweaking, I’ll make adjustments based on what you’ve built. Thanks for all your hard work! |
107da9e to
03d9478
Compare
03d9478 to
f4722c7
Compare
There was a problem hiding this comment.
Pull request overview
Adds a new builtin implementation of the pretty-format-json hook to close a remaining gap in pre-commit-hooks parity, including formatting behavior, diff output, docs, schema updates, and test coverage.
Changes:
- Implement
pretty-format-jsonas arepo: builtinhook (intentionally not enabled for automatic fast-path replacement of the upstream Python hook yet). - Add documentation + schema + builtin listing updates to expose the new hook.
- Add integration/unit tests and introduce the
similardependency for diff rendering.
Reviewed changes
Copilot reviewed 9 out of 10 changed files in this pull request and generated 7 comments.
Show a summary per file
| File | Description |
|---|---|
prek.schema.json |
Allows pretty-format-json as a valid builtin hook id in the schema. |
docs/builtin.md |
Documents the new hook, its supported args, and current availability caveats. |
crates/prek/tests/list_builtins.rs |
Ensures builtin listing output includes pretty-format-json. |
crates/prek/tests/builtin_hooks.rs |
Adds end-to-end integration tests for formatting/autofix/options. |
crates/prek/src/hooks/pre_commit_hooks/pretty_format_json.rs |
New hook implementation: parse/reorder/format JSON, optional autofix, and diff output. |
crates/prek/src/hooks/pre_commit_hooks/mod.rs |
Wires the new module and export for hook dispatch. |
crates/prek/src/hooks/builtin_hooks/mod.rs |
Registers the new builtin hook and its metadata/types/stages. |
crates/prek/Cargo.toml |
Adds similar as a dependency for the prek crate. |
Cargo.toml |
Adds similar to workspace dependencies. |
Cargo.lock |
Locks the new dependency. |
⚡️ Hyperfine BenchmarksSummary: 0 regressions, 0 improvements above the 10% threshold. Environment
CLI CommandsBenchmarking basic commands in the main repo:
|
| Command | Mean [ms] | Min [ms] | Max [ms] | Relative |
|---|---|---|---|---|
prek-base --version |
2.4 ± 0.1 | 2.2 | 3.1 | 1.04 ± 0.07 |
prek-head --version |
2.3 ± 0.1 | 2.2 | 2.8 | 1.00 |
prek list
| Command | Mean [ms] | Min [ms] | Max [ms] | Relative |
|---|---|---|---|---|
prek-base list |
9.2 ± 2.6 | 8.7 | 34.3 | 1.03 ± 0.29 |
prek-head list |
8.9 ± 0.1 | 8.7 | 9.5 | 1.00 |
prek validate-config .pre-commit-config.yaml
| Command | Mean [ms] | Min [ms] | Max [ms] | Relative |
|---|---|---|---|---|
prek-base validate-config .pre-commit-config.yaml |
3.2 ± 0.0 | 3.1 | 3.3 | 1.01 ± 0.02 |
prek-head validate-config .pre-commit-config.yaml |
3.2 ± 0.0 | 3.1 | 3.2 | 1.00 |
prek sample-config
| Command | Mean [ms] | Min [ms] | Max [ms] | Relative |
|---|---|---|---|---|
prek-base sample-config |
2.7 ± 0.2 | 2.6 | 3.7 | 1.02 ± 0.06 |
prek-head sample-config |
2.6 ± 0.0 | 2.5 | 2.8 | 1.00 |
Cold vs Warm Runs
Comparing first run (cold) vs subsequent runs (warm cache):
prek run --all-files (cold - no cache)
| Command | Mean [ms] | Min [ms] | Max [ms] | Relative |
|---|---|---|---|---|
prek-base run --all-files |
156.6 ± 4.5 | 151.9 | 164.4 | 1.01 ± 0.04 |
prek-head run --all-files |
154.7 ± 3.3 | 152.0 | 162.4 | 1.00 |
prek run --all-files (warm - with cache)
| Command | Mean [ms] | Min [ms] | Max [ms] | Relative |
|---|---|---|---|---|
prek-base run --all-files |
155.0 ± 4.1 | 149.9 | 167.6 | 1.00 |
prek-head run --all-files |
155.2 ± 2.4 | 150.8 | 159.3 | 1.00 ± 0.03 |
Full Hook Suite
Running the builtin hook suite on the benchmark workspace:
prek run --all-files (full builtin hook suite)
| Command | Mean [ms] | Min [ms] | Max [ms] | Relative |
|---|---|---|---|---|
prek-base run --all-files |
155.7 ± 3.8 | 151.2 | 175.4 | 1.00 |
prek-head run --all-files |
159.7 ± 19.8 | 151.9 | 288.2 | 1.03 ± 0.13 |
Individual Hook Performance
Benchmarking each hook individually on the test repo:
prek run trailing-whitespace --all-files
| Command | Mean [ms] | Min [ms] | Max [ms] | Relative |
|---|---|---|---|---|
prek-base run trailing-whitespace --all-files |
21.9 ± 0.4 | 21.0 | 22.7 | 1.02 ± 0.03 |
prek-head run trailing-whitespace --all-files |
21.6 ± 0.4 | 20.7 | 22.6 | 1.00 |
prek run end-of-file-fixer --all-files
| Command | Mean [ms] | Min [ms] | Max [ms] | Relative |
|---|---|---|---|---|
prek-base run end-of-file-fixer --all-files |
27.8 ± 1.5 | 25.2 | 30.7 | 1.00 |
prek-head run end-of-file-fixer --all-files |
27.9 ± 1.6 | 25.5 | 31.9 | 1.00 ± 0.08 |
prek run check-json --all-files
| Command | Mean [ms] | Min [ms] | Max [ms] | Relative |
|---|---|---|---|---|
prek-base run check-json --all-files |
12.7 ± 0.5 | 11.5 | 13.8 | 1.05 ± 0.05 |
prek-head run check-json --all-files |
12.1 ± 0.2 | 11.8 | 12.6 | 1.00 |
prek run check-yaml --all-files
| Command | Mean [ms] | Min [ms] | Max [ms] | Relative |
|---|---|---|---|---|
prek-base run check-yaml --all-files |
12.0 ± 0.3 | 11.6 | 12.7 | 1.02 ± 0.03 |
prek-head run check-yaml --all-files |
11.8 ± 0.2 | 11.5 | 12.3 | 1.00 |
prek run check-toml --all-files
| Command | Mean [ms] | Min [ms] | Max [ms] | Relative |
|---|---|---|---|---|
prek-base run check-toml --all-files |
12.1 ± 0.3 | 11.6 | 13.2 | 1.01 ± 0.03 |
prek-head run check-toml --all-files |
12.0 ± 0.2 | 11.5 | 12.4 | 1.00 |
prek run check-xml --all-files
| Command | Mean [ms] | Min [ms] | Max [ms] | Relative |
|---|---|---|---|---|
prek-base run check-xml --all-files |
12.2 ± 0.3 | 11.5 | 13.0 | 1.00 ± 0.04 |
prek-head run check-xml --all-files |
12.2 ± 0.3 | 11.5 | 12.7 | 1.00 |
prek run detect-private-key --all-files
| Command | Mean [ms] | Min [ms] | Max [ms] | Relative |
|---|---|---|---|---|
prek-base run detect-private-key --all-files |
18.5 ± 1.1 | 17.0 | 21.2 | 1.02 ± 0.10 |
prek-head run detect-private-key --all-files |
18.2 ± 1.4 | 16.6 | 22.5 | 1.00 |
prek run fix-byte-order-marker --all-files
| Command | Mean [ms] | Min [ms] | Max [ms] | Relative |
|---|---|---|---|---|
prek-base run fix-byte-order-marker --all-files |
23.6 ± 1.6 | 21.1 | 26.9 | 1.00 ± 0.09 |
prek-head run fix-byte-order-marker --all-files |
23.6 ± 1.4 | 20.5 | 26.8 | 1.00 |
Installation Performance
Benchmarking hook installation (fast path hooks skip Python setup):
prek install-hooks (cold - no cache)
| Command | Mean [ms] | Min [ms] | Max [ms] | Relative |
|---|---|---|---|---|
prek-base install-hooks |
4.8 ± 0.1 | 4.7 | 4.9 | 1.00 ± 0.02 |
prek-head install-hooks |
4.8 ± 0.0 | 4.7 | 4.8 | 1.00 |
prek install-hooks (warm - with cache)
| Command | Mean [ms] | Min [ms] | Max [ms] | Relative |
|---|---|---|---|---|
prek-base install-hooks |
4.8 ± 0.1 | 4.7 | 4.8 | 1.00 |
prek-head install-hooks |
4.8 ± 0.1 | 4.7 | 4.9 | 1.01 ± 0.02 |
File Filtering/Scoping Performance
Testing different file selection modes:
prek run (staged files only)
| Command | Mean [ms] | Min [ms] | Max [ms] | Relative |
|---|---|---|---|---|
prek-base run |
52.8 ± 1.1 | 51.6 | 56.8 | 1.00 |
prek-head run |
53.7 ± 1.4 | 51.7 | 57.0 | 1.02 ± 0.03 |
prek run --files '*.json' (specific file type)
| Command | Mean [ms] | Min [ms] | Max [ms] | Relative |
|---|---|---|---|---|
prek-base run --files '*.json' |
9.1 ± 0.1 | 8.9 | 9.3 | 1.01 ± 0.02 |
prek-head run --files '*.json' |
9.0 ± 0.1 | 8.9 | 9.3 | 1.00 |
Workspace Discovery & Initialization
Benchmarking hook discovery and initialization overhead:
prek run --dry-run --all-files (measures init overhead)
| Command | Mean [ms] | Min [ms] | Max [ms] | Relative |
|---|---|---|---|---|
prek-base run --dry-run --all-files |
14.2 ± 0.9 | 13.8 | 17.8 | 1.02 ± 0.06 |
prek-head run --dry-run --all-files |
13.9 ± 0.1 | 13.7 | 14.2 | 1.00 |
Meta Hooks Performance
Benchmarking meta hooks separately:
prek run check-hooks-apply --all-files
| Command | Mean [ms] | Min [ms] | Max [ms] | Relative |
|---|---|---|---|---|
prek-base run check-hooks-apply --all-files |
13.6 ± 0.7 | 12.5 | 14.3 | 1.08 ± 0.06 |
prek-head run check-hooks-apply --all-files |
12.6 ± 0.1 | 12.5 | 13.0 | 1.00 |
prek run check-useless-excludes --all-files
| Command | Mean [ms] | Min [ms] | Max [ms] | Relative |
|---|---|---|---|---|
prek-base run check-useless-excludes --all-files |
12.5 ± 0.1 | 12.3 | 12.8 | 1.00 |
prek-head run check-useless-excludes --all-files |
12.6 ± 0.1 | 12.4 | 12.7 | 1.00 ± 0.01 |
prek run identity --all-files
| Command | Mean [ms] | Min [ms] | Max [ms] | Relative |
|---|---|---|---|---|
prek-base run identity --all-files |
11.0 ± 0.1 | 10.7 | 11.2 | 1.00 |
prek-head run identity --all-files |
11.1 ± 0.1 | 10.9 | 11.2 | 1.01 ± 0.01 |
9a7ea0d to
ac0c55d
Compare
ac0c55d to
0309e6d
Compare
pretty_format_json as builtin hookpretty_format_json as builtin hook
|
Finally, let’s merge, thanks so much for your work! |
|
Completely forgot about this haha! Great to see! |
Description
Following the information provided in 880. This is an implementation of the
pretty-format-jsonhook.The pretty-format-json has 1k grep.app hits. It's the final unimplemented hook used by
airflowas mentioned in this comment.Notes
Preserve JSON Order
preserve_orderfeature toserde_json. This preventsserdefrom automatically ordering JSON data, which is important for comparisons with older implementations.serdeuses aBTreeMapforObject. Enablingpreserve_orderswitches it toIndexMap.sort-keysargument.Git-Style Diff with
similarsimilarlibrary to perform git-style diff checks.pre-commit.Q: why is my size so much smaller than both sizes mentioned here?
Performance
Ran these commands on the
airflowrepository:Output
Old pre-commit:

New:

Where both would autofix to the same:
