-
Notifications
You must be signed in to change notification settings - Fork 710
Forward compat scheme #4899
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
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 |
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 <[email protected]>
I use GHCup to manage my Haskell environment. Based on that, I know my currently only installed and in use version of Cabal is 3.10.2.1 (also Why does cabal-version: 3.10
name: foo
version: 1.0
executable foo
main-is: main.hs
build-depends: base The error is
which brought me here. Changing the first line of cabal-version: 3.0 solves the problem, but... what's wrong with 3.10, if that is the version I have installed? The content of main :: IO ()
main = print 0 |
... or |
I think rather than link to this ticket we should link to https://cabal.readthedocs.io/en/stable/file-format-changelog.html and maybe the message could be |
@gbaz you're so right. Not being able use the |
See: #4899 Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
See: haskell#4899 Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
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: