feat: add JSON as a second canonicalized language#27
Merged
Conversation
Adds JSON to git-ast's clean/smudge round-trip, alongside the existing Rust support. JSON is additive and slots into the per-extension dispatch in filters::transform — no change to the pkt-line protocol, printer, or pktline. - src/json.rs: canonicalize() parses with serde_json and re-emits a deterministic canonical form (object keys sorted, pretty-printed, trailing newline). Same contract as printer::canonicalize; fail-closed on invalid JSON. - src/filters.rs: transform() now dispatches by extension — .rs -> printer, .json -> json — with smudge identity and pass-through for everything else. - src/setup.rs: routes both *.rs and *.json in .gitattributes (idempotent). - src/main.rs / lib.rs: help text + crate docs updated for two languages. Canonical form is sorted-key *pretty* JSON (diff-friendly) rather than compact RFC-8785 JCS — same value-level normalization, one value per line. serde_json only (its Map is a BTreeMap, so keys sort and scalars format deterministically). Tests: - 6 unit tests in json.rs (sort/normalize, idempotence, key-order independence, value fidelity, trailing newline, reject-invalid) - 2 protocol tests in filters.rs (clean canonicalizes JSON; invalid JSON yields status=error over the filter-process protocol) - 4 JSON scenarios in the cucumber claims suite (reformatting -> no diff, byte-identical blobs, checkout round-trip, fail-closed) driving real git; the install step now routes *.json too. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
20a745d to
c2ce65f
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds JSON as a second canonicalized language in git-ast's clean/smudge round-trip, alongside the Rust support from #26. JSON is additive: it slots into the per-extension dispatch in
filters::transform— no change to the pkt-linefilter-processprotocol, theprinter, orpktline.src/json.rs—canonicalize()parses withserde_jsonand re-emits a deterministic canonical form (object keys sorted, pretty-printed, trailing newline). Same contract asprinter::canonicalize; fail-closed on invalid JSON (rejects the commit).src/filters.rs—transform()now dispatches by extension:.rs → printer,.json → json, smudge identity, pass-through otherwise.src/setup.rs— routes both*.rsand*.jsonin.gitattributes(idempotent).src/main.rs/src/lib.rs— help text + crate docs updated for two languages.Design note
Canonical form is sorted-key pretty JSON, not compact RFC-8785 JCS — same value-level normalization (sorted keys, deterministic scalars), but one value per line so the filter's cleaner diffs purpose holds.
serde_jsononly (itsMapis aBTreeMap, so keys sort and scalars format deterministically).Tests — all green (31 unit + 10 scenarios / 40 steps)
src/json.rs(6): sort/normalize, idempotence, key-order independence, value fidelity, trailing newline, reject-invalid.src/filters.rs(2):cleancanonicalizes JSON over the protocol; invalid JSON yieldsstatus=error.tests/features/claims.feature, 4 new): reformatting → no diff, byte-identical blobs, checkout round-trip, fail-closed — driving real git. The install step now routes*.jsontoo.cargo fmt --all -- --check+cargo clippy --all-targets -- -D warningsclean.PR run sheet
transform/pktline/setup; one dispatch arm + one language moduleTrust ledger
Moves row 8.1 toward 🟡: a second language now rides the same working pipeline. Rust remains a documented subset; structural diff/merge (node identity) stays out of scope.
🤖 Generated with Claude Code