New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Forward compat scheme #4899
Comments
This provides a provisional (i.e. hacky) retrofitted implementation of the forward-compat scheme described in haskell#4899 for the cabal-2.0 branch. This hack works by constructing a dummy package description in case the package description fails to be parsed via the standard parser, and we detect a new-style cabal-spec declaration.
This compares the request spec-version to the lib:Cabal's version in order to determine whether cabal is able to properly understand the package. If it's newer than the currently linked lib:Cabal version it's turned into a global `FailResult` which the solver treats as desired in terms of backtracking and error reporting. This is related to the new spec-version forward-compat scheme (see haskell#4899). This is complements haskell#4900 for the 2.0 branch.
This compares the request spec-version to the lib:Cabal's version in order to determine whether cabal is able to properly understand the package. If it's newer than the currently linked lib:Cabal version it's turned into a global `FailResult` which the solver treats as desired in terms of backtracking and error reporting. This is related to the new spec-version forward-compat scheme (see haskell#4899). This is complements haskell#4900 for the 2.0 branch.
This compares the request spec-version to the lib:Cabal's version in order to determine whether cabal is able to properly understand the package. If it's newer than the currently linked lib:Cabal version it's turned into a global `FailResult` which the solver treats as desired in terms of backtracking and error reporting. This is related to the new spec-version forward-compat scheme (see haskell#4899). This is a forward-port of haskell#4907 to the `master` branch
Related: #4448. |
This seems like a good way forward. |
This provides a provisional (i.e. hacky) retrofitted implementation of the forward-compat scheme described in haskell#4899 for the cabal-2.2 branch This hack works by constructing a dummy package description in case the package description fails to be parsed via the standard parser, and we detect a new-style cabal-spec declaration.
@hvr, should the ABNF contain end-of-line character? |
This provides a provisional (i.e. hacky) retrofitted implementation of the forward-compat scheme described in haskell#4899 for the cabal-2.2 branch This hack works by constructing a dummy package description in case the package description fails to be parsed via the standard parser, and we detect a new-style cabal-spec declaration.
This provides a provisional (i.e. hacky) retrofitted implementation of the forward-compat scheme described in haskell#4899 for the cabal-2.2 branch This hack works by constructing a dummy package description in case the package description fails to be parsed via the standard parser, and we detect a new-style cabal-spec declaration.
This provides a provisional (i.e. hacky) retrofitted implementation of the forward-compat scheme described in haskell#4899 for the cabal-2.2 branch This hack works by constructing a dummy package description in case the package description fails to be parsed via the standard parser, and we detect a new-style cabal-spec declaration.
This provides a provisional (i.e. hacky) retrofitted implementation of the forward-compat scheme described in haskell#4899 for the cabal-2.2 branch This hack works by constructing a dummy package description in case the package description fails to be parsed via the standard parser, and we detect a new-style cabal-spec declaration.
merged in #5046 |
…d as a range CI reports a failure: unexpected cabal-version higher than 2.2 cannot be specified as a range. See haskell/cabal#4899 expecting ".", "-", white space, "&&" or "||" >=2.2 setup-Simple-Cabal-2.2.0.1-x86_64-linux-ghc-8.0.2: Failed parsing "./hwormhole.cabal". This change also relaxes the lower bound to 2.0 instead of the very new 2.2 and see how that goes.
…d as a range CI reports a failure: unexpected cabal-version higher than 2.2 cannot be specified as a range. See haskell/cabal#4899 expecting ".", "-", white space, "&&" or "||" >=2.2 setup-Simple-Cabal-2.2.0.1-x86_64-linux-ghc-8.0.2: Failed parsing "./hwormhole.cabal". This change also relaxes the lower bound to 2.0 instead of the very new 2.2 and see how that goes.
…d as a range This change also relaxes the lower bound to 1.24 instead of the very new 2.2 and see how that goes. CI reports a failure: unexpected cabal-version higher than 2.2 cannot be specified as a range. See haskell/cabal#4899 expecting ".", "-", white space, "&&" or "||" >=2.2 setup-Simple-Cabal-2.2.0.1-x86_64-linux-ghc-8.0.2: Failed parsing "./hwormhole.cabal".
also move `cabal-version` field (for this following warning: `"cabal-version should be at the beginning of the file starting with spec version 2.2. See haskell/cabal#4899).
If you were brought here by a Cabal error message and just want to fix your Cabal file, replace
with
and move the |
I've been able to fix this issue on Debian by running |
I ran the following (anonymized) command:
With the following
|
hackage sucks again: haskell/cabal#4899 (comment)
I encountered the following error message while using `stack build`: Unsupported cabal-version 2.0.1.1. See haskell/cabal#4899.
When fourmolu fails to parse the Cabal file the user doesn't know what is the actual error as only the cabal filepath is reported. This makes the necessary changes to actually show what were the errors that the cabal file parser encountered. Before: Parsing this .cabal file failed: /path/to/file.cabal After: Parsing this .cabal file failed: /path/to/file.cabal:0:0: Unsupported cabal-version 3.8. See haskell/cabal#4899. Note: Removing the `Eq` instance on `OrmoluException` was the easy way to not having to implement an orphan `Eq` instance on `PError`. This does not have any impact elsewhere as we're actually not making use of the `Eq` instance on this exception type.
When fourmolu fails to parse the Cabal file the user doesn't know what is the actual error as only the cabal filepath is reported. This makes the necessary changes to actually show what were the errors that the cabal file parser encountered. Before: Parsing this .cabal file failed: /path/to/file.cabal After: Parsing this .cabal file failed: /path/to/file.cabal:0:0: Unsupported cabal-version 3.8. See haskell/cabal#4899. Note: Removing the `Eq` instance on `OrmoluException` was the easy way to not having to implement an orphan `Eq` instance on `PError`. This does not have any impact elsewhere as we're actually not making use of the `Eq` instance on this exception type.
When ormolu fails to parse the Cabal file the user doesn't know what is the actual error as only the cabal filepath is reported. This makes the necessary changes to actually show what errors the cabal file parser encountered. Before: Parsing this .cabal file failed: /path/to/file.cabal After: Parsing this .cabal file failed: /path/to/file.cabal:0:0: Unsupported cabal-version 3.8. See haskell/cabal#4899. Note: Removing the `Eq` instance on `OrmoluException` was the easy way to not having to implement an orphan `Eq` instance on `PError`. This does not have any impact elsewhere as we're actually not making use of the `Eq` instance on this exception type.
When ormolu fails to parse the Cabal file the user doesn't know what is the actual error as only the cabal filepath is reported. This makes the necessary changes to actually show what errors the cabal file parser encountered. Before: Parsing this .cabal file failed: /path/to/file.cabal After: Parsing this .cabal file failed: /path/to/file.cabal:0:0: Unsupported cabal-version 3.8. See haskell/cabal#4899. Note: Removing the `Eq` instance on `OrmoluException` was the easy way to not having to implement an orphan `Eq` instance on `PError`. This does not have any impact elsewhere as we're actually not making use of the `Eq` instance on this exception type.
When ormolu fails to parse the Cabal file the user doesn't know what is the actual error as only the cabal filepath is reported. This makes the necessary changes to actually show what errors the cabal file parser encountered. Before: Parsing this .cabal file failed: /path/to/file.cabal After: Parsing this .cabal file failed: /path/to/file.cabal:0:0: Unsupported cabal-version 3.8. See haskell/cabal#4899. Note: Removing the `Eq` instance on `OrmoluException` was the easy way to not having to implement an orphan `Eq` instance on `PError`. This does not have any impact elsewhere as we're actually not making use of the `Eq` instance on this exception type.
When ormolu fails to parse the Cabal file the user doesn't know what is the actual error as only the cabal filepath is reported. This makes the necessary changes to actually show what errors the cabal file parser encountered. Before: Parsing this .cabal file failed: /path/to/file.cabal After: Parsing this .cabal file failed: /path/to/file.cabal:0:0: Unsupported cabal-version 3.8. See haskell/cabal#4899. Note: Removing the `Eq` instance on `OrmoluException` was the easy way to not having to implement an orphan `Eq` instance on `PError`. This does not have any impact elsewhere as we're actually not making use of the `Eq` instance on this exception type.
xcffib.cabal:11:1: error: cabal-version should be at the beginning of the file starting with spec version 2.2. See haskell/cabal#4899 10 | build-type: Simple 11 | cabal-version: 2.4 | ^ Error: cabal: parse error Warning: These warnings may cause trouble when distributing the package: Warning: In 'extra-source-files': the pattern 'test/generator/*.py' does not match the file 'test/generator/render_1.7.py' because the extensions do not exactly match (e.g., foo.en.html does not exactly match *.html). To enable looser suffix-only matching, set 'cabal-version: 2.4' or higher. Signed-off-by: Tycho Andersen <tycho@tycho.pizza>
Generally, a given
cabal-install
release is only expected to understand (cabal-)spec(ification)-versions that were known at the time of release.The Cabal-1.12 release, and more recently the Cabal-2.0 release have made it apparent that we don't have a good forward-compatibility story in place, thereby limiting our ability to evolve the
.cabal
format. Concretely,cabal-install-1.10
is not expected to understand package meta-data declared using thecabal-version:1.12
spec(ification)-version; also, upon encountering such a future.cabal
file in the package index,cabal-install-1.10
ought to gracefully recover (instead of failing fatally to parse the package index). A similar situation occurred with the Cabal-2.0 release, which also introduced new syntax which previous parsers would fail to recognise, again resulting in fatal parsing failures.To prevent this from happening again, the following forward compatibility has been devised, which is intended to make it possible to evolve the lexical and syntactical structure of the
.cabal
format in future, while not breaking legacy clients.New-style Cabal-Specification Version Declaration
A new-style spec-version declaration at the beginning of a the
.cabal
file (without any preceding whitespace) and follow the following case-insensitive grammar (expressed in RFC5234 ABNF):The use of a new-style spec-version is
It's also assumed that the following invariant holds:
.cabal
parser.Scanning the Cabal-Specification Version
.cabal
file contains a valid new-style spec-version declaration, it is authoritative;.cabal
parser or a heuristiccabal-version
-scanner (tbd) must be used to determine the exact spec-version).The new-style spec-version declaration is designed to be simple to parse by means of common string operations. A simple implementation is shown below
Appendix: Compatiblity with clients prior to cabal 2.0
Since this new scheme is only understood properly starting with cabal 2.0, older clients need to avoid being exposed to spec-versions 2.0 and newer.
To this end we exploit that cabal 2.0 started using the incremental secure
01-index.tar
package index by default, while cabal versions prior to cabal 2.0 use the (non-incremental/non-secure)00-index.tar
package index by default (NB: cabal 1.24 was the first release that added experimental non-default/opt-in support for the secure01-index.tar
), by establishing the following hackage-side invariant:00-index.tar.gz
contains only.cabal
files with a spec version below 2This way, the huge install-base of legacy cabal clients prior to cabal 2.0 keep working without requiring modifications, as they won't be exposed to incompatible
.cabal
files; with the unfortunate exception that the (hopefully uncommon) cabal clients prior to cabal 1.12 may still be exposed to incompatible cabal versions using the>=
-less spec-version declarations.The text was updated successfully, but these errors were encountered: