feat(bib): bib diff — entry-level structural diff (#135 sub-feature C of 3)#181
Merged
feat(bib): bib diff — entry-level structural diff (#135 sub-feature C of 3)#181
Conversation
… of 3) `bib verify` already prints a unified line-based diff on drift, but that's mechanically useful and editorially noisy: a citekey rename ripples through dozens of lines and the reader has to reconstruct meaning by eye. `bib diff` gives the meaning directly: which entries were added, removed, changed (and which fields changed). - New `scitadel-export::diff` module: pure logic over a format-neutral `Entry` shape. Identity rule per spec: citekey → DOI → arxiv_id → (title, year), strict per-rung first-match-wins. All output lists sorted by citekey for byte-stable output. - New `scitadel-export::diff_input`: format sniff (content-first; JSON parse trial, fallback to BibTeX) so `.bib` and `.json` are interchangeable on the command line. - New `scitadel-export::diff_format`: hand-rolled ANSI text renderer + serde JSON renderer. No new color/diff crates. - CLI `scitadel bib diff <file_a> [<file_b>] [--question-id <id>] [--format text|json] [--no-color] [--reader <r>]`. Exit 0 if no diff, 1 if any diff (mirrors `git diff`). Color auto-off on non-TTY via `std::io::IsTerminal`. - MCP tool `bib_diff` mirroring CLI; returns the structured BibDiff JSON unconditionally so callers can branch. Tests: 34 unit tests in scitadel-export (4 identity-rung tests, 6 field-change tests, sort determinism, JSON round-trip, mixed-format zero-diff, format detection, format renderer color toggle). 7 CLI integration tests (identical files exit 0, drifted files exit 1 with text report, --no-color strips ANSI, --format json round-trips, mixed-format zero-diff, --question-id form against seeded DB, missing-second-side error). 6 inline CLI tests. 335 total tests pass. Closes #135 (after sub-features A and B already landed in #180 and #137 iter 2). [tape-exempt: text-only --help addition under bib diff; output is colored text on stdout, not TUI rendering]
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
scitadel bib diff <file_a> [<file_b>] [--question-id <id>]— entry-level (added / removed / changed) structural diff between two bibliographies, the human-readable explainer whenbib verifysays drift detected. Auto-detects BibTeX vs CSL-JSON by content sniff; the two flavors are interchangeable in either argument slot.citekey → DOI → arxiv_id → (title, year), strict per-rung first-match-wins. Lists sorted by citekey for deterministic output.scitadel-export::diff_format(no new color/diff crates), TTY-detect viastd::io::IsTerminal,--no-colorfor CI.--format jsonfor structured CI consumption; serde-derived round-trip.0(no diff) /1(any diff) mirrorgit diff.bib_diffmirroring the CLI for agent workflows.Test plan
scitadel-export(4 identity-rung tests, 6 field-change tests, sort determinism, JSON round-trip, mixed-format zero-diff, format detection, ANSI color toggle)--no-colorstrips ANSI,--format jsonround-trips, BibTeX-vs-CSL-JSON of the same shortlist exit 0,--question-idform against a seeded DB, missing-second-side error)scitadel-tuiper quality gate)just lintcleanCloses
Closes #135 (after #180 sub-feature A and #151 sub-feature B landed)
[tape-exempt: text-only --help addition under bib diff; output is colored text on stdout, not TUI rendering]