Repository navigation
q2 add: keep unknown record keys, refuse newer records, pin line endings - #1183
Merged
Merged
Conversation
Makes `.quarto-source.yml` safe to share with other tools (bd-yjg91sls): - Keys q2 doesn't own survive a rewrite (#1175). `SourceRecord` gains a flattened `extra` mapping (file order kept); `record::inspect` returns the parsed prior record, and `write_record` carries its extra keys into the new record. Nothing is carried from an unreadable record or one with a newer schema version. - A newer schema version is not read with v1 rules (#1176). The version is probed before the rest of the record is parsed, so a v2 record that doesn't fit v1 shapes still reads as "newer", not "unreadable". It is reported as a local change (needs --force), with an "Upgrade q2" hint. - Line endings. Any install that writes an extension creates `_extensions/.gitattributes` with `* -text` when it is missing (never edits an existing one; No Change and --dry-run write nothing), so git's core.autocrlf can't turn every file into a "local edit". A file that differs from its hash only by CRLF<->LF is reported as "line endings changed" with a hint naming the fix; it still needs --force. `--json` gains `gitattributes_written`. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Contributor
✅ Snyk checks have passed. No issues have been found so far.
💻 Catch issues earlier using the plugins for VS Code, JetBrains IDEs, Visual Studio, and Eclipse. |
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
cscheid
deleted the
feature/bd-yjg91sls-quarto-source-record-contract
branch
November 11, 2026 23:14
cscheid
pushed a commit
that referenced
this pull request
Nov 11, 2026
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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.
Makes
.quarto-source.ymlsafe to share with other tools. Quarto Wizard's development version now writes this record too. Strand: bd-yjg91sls. Plan:claude-notes/plans/2026-11-11-quarto-source-record-contract.md.Fixes #1175. Fixes #1176. Part of #1177 (the line-ending rule). The spec and JSON Schema (#1177) and
track/commit(#1178) are still under discussion in the plan doc, and aren't in this PR.Changes
Unknown keys are kept (#1175).
SourceRecordgains a flattenedextra: serde_yaml::Mapping, which keeps the keys in file order.record::inspectreplacesinstalled_stateand also returns the parsed record.write_recordis now per extension: q2 sets the keys it owns (version,source,kind,ref,files) and copies every other key from the record being replaced. Nothing is carried over from an unreadable record or from one with a newer schema version.Newer schema versions (#1176).
parse_recordreadsversionbefore parsing the rest. AboveRECORD_VERSION, it returnsEditKind::NewerRecord(v). That goes through the existing local-changes refusal, so replacing the record needs--force, and the error adds an "Upgrade q2" hint. Checking the version first matters: a v2 record that doesn't fit v1's shapes is still reported as newer, not as unreadable. A version that is 0, missing or not an integer reports as unreadable.Line endings. On Windows, Git's
core.autocrlf(on by default in Git for Windows) rewrites LF to CRLF on checkout. Every text file then stops matching its hash and looks locally edited._extensions/.gitattributeswith* -textwhen the file is missing. The file sits next to the extensions, not inside one, so it is never hashed and doesn't clash with a.gitattributesan extension ships. An existing file is never edited.[No Change]and--dry-rundon't write it; the dry run prints "would also create".--jsongainsgitattributes_written.-text, noteol=lf:eol=lfconverts on commit, which would break extensions that ship CRLF files. The plan doc has the reasoning and the precedents (cargo vendor, go.sum).line endings changed, with a hint that names autocrlf and the.gitattributesfix. It still needs--force, so other tools reading the record keep the same exact hash rule.The user guide (
docs/guides/authoring/extensions.qmd) has the new behavior.Testing
record.rs: extra keys round-trip in order and don't count as edits; a newer version is reported even when the rest doesn't parse; version 0, missing or not an integer is unreadable; CRLF and LF conversions in both directions; a real edit made with CRLF still counts as modified.tests/integration/add.rsfollow the repros inq2 adddrops keys it doesn't know when it rewrites.quarto-source.yml#1175 andq2 addignores the schema version of.quarto-source.ymland reads a newer record as version 1 #1176, plus.gitattributescreation (dry run, No Change, existing file, JSON) and the line-endings message.* text=auto,git check-attrreportstext: unsetunder_extensions/, and withcore.autocrlf=truean LF file checks out as LF.cargo xtask verify(Rust steps), then a full workspace run: 19,288 tests passed. One local failure isn't related to this PR:quarto-coreknitr::capture_tests::capture_classifies_piecesgetsrlang_errorinstead ofsimpleErrorfrom my local R 4.6 install. This PR doesn't touchquarto-core.ring's build script needs a Windows C toolchain. The change uses no platform-specific APIs, and paths in the new code go throughPath::join.🤖 Generated with Claude Code