docs: checklist for adding or changing a .cabal file format field#12056
Open
andreabedini wants to merge 1 commit into
Open
docs: checklist for adding or changing a .cabal file format field#12056andreabedini wants to merge 1 commit into
andreabedini wants to merge 1 commit into
Conversation
There was a problem hiding this comment.
Pull request overview
This PR adds a new CONTRIBUTING guide section describing the required workflow for introducing or changing .cabal file format fields, with a focus on correctly gating syntax behind cabal-version (and ensuring cabal check enforces the introduction version) to prevent issues like #9331.
Changes:
- Documented a step-by-step checklist for adding/changing
.cabalfields, centered onCabalSpecVersionandcabalSpecLatest. - Documented the correct way to gate fields in
FieldGrammar.hs(and why not to usecabalSpecLatestby name). - Documented adding the corresponding
checkSpecVerenforcement inCabal/.../Check/Target.hs, plus changelog updates.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comment on lines
+376
to
+379
| 3. **Gate the field in the grammar.** In | ||
| `Cabal-syntax/src/Distribution/PackageDescription/FieldGrammar.hs` mark the | ||
| field with `availableSince <Constructor> []`. | ||
|
|
Comment on lines
+380
to
+386
| > ⚠️ Use the **literal constructor whose value equals `cabalSpecLatest` | ||
| > today** (e.g. `availableSince CabalSpecV3_18 []`) — **not** the name | ||
| > `cabalSpecLatest`. `cabalSpecLatest` is bumped on every new spec version, | ||
| > so writing the name would retroactively (and wrongly) move the field's | ||
| > introduction version forward each time the spec advances. Hard-code the | ||
| > value; it must stay pinned to the version in which the field actually | ||
| > appeared. |
Comment on lines
+367
to
+374
| 2. **Bump `cabalSpecLatest`** (in the same module) to that constructor, in the | ||
| *same change* that adds it. The constructor and `cabalSpecLatest` should | ||
| never drift apart: a constructor for an unreleased spec version that is not | ||
| yet `cabalSpecLatest` is a latent bug. (As of this writing the tree is in | ||
| exactly that state — `CabalSpecV3_18` was added this cycle for the | ||
| `build-type: Make` removal, but `cabalSpecLatest` was left at | ||
| `CabalSpecV3_16` — which is why new fields were mis-gated. If you add a | ||
| field now, also fix the bump.) |
Add a 'Adding or changing a `.cabal` file format field' section explaining how to gate new fields behind `cabal-version` to avoid the haskell#9331 class of bug where ungated fields are silently accepted by older Cabal. The checklist covers the full mechanism around `CabalSpecVersion`: ensuring a constructor exists for the next unreleased spec version (a major API break), keeping `cabalSpecLatest` in sync, gating the field in `FieldGrammar.hs` with a literal `availableSince` constructor (not the name `cabalSpecLatest`), adding a matching `checkSpecVer` in `Check/Target.hs`, and documenting the change.
18d998a to
9e897eb
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 a new section to
CONTRIBUTING.md, "Adding or changing a.cabalfile format field", documenting how to correctly gate new or changed.cabalfields behindcabal-version.This is the class of bug described in #9331: when a new field is not gated, an older
Cabal/cabal-installsilently accepts it and does the wrong thing, or a newer field leaks into a package that claims an oldcabal-version. Features that influence generated files (Paths_*.hs,cabal_macros.h, autogen sources, …) are especially dangerous when ungated.I tried to be as clear as possible, please review and suggest changes.
What it documents
A step-by-step checklist around the
CabalSpecVersionenum:CabalSpecVersionconstructor exists for the next unreleased (even) spec version — and that adding one is an API-breaking change requiring a major version bump, with the total functions that must be extended.cabalSpecLatestin the same change, so the constructor andcabalSpecLatestnever drift apart.FieldGrammar.hswithavailableSince <literal constructor> []— not the namecabalSpecLatest, which would retroactively move the field's introduction version forward on every spec bump.checkSpecVerinCabal/.../Check/Target.hssocabal checkreports the field used below its introduction version.doc/file-format-changelog.rstand add achangelog.d/entry.Type of change
Documentation only — no code changes, no changelog entry required.