Re: Why upper bound version numbers?

Versions of package dependencies can be categorised into 5 sets: D1) Versions which the maintainer has tested and found to work D2) Versions which the maintainer has not tested but expects to work D3) Versions which the maintainer has tested and found to not work D4) Versions which the maintainer has not tested but expects to not work D5) Everything else Cabal, however, only knows of 3 sets: C1) Versions which satisfy build-depends C2) Versions which satisfy build-depends with --allow-newer C3) Everything else The problem arises from the fact that the D sets to not map well onto the C sets, even after combining D1&D2 and D3&D4. Perhaps this could be solved with a new .cabal property, breaks-with. The solver will then prefer packages in this order: 1) Versions that satisfy build-depends 2) Versions that are not in breaks-with, unless a flag such as --strict-build-depends is applied This may also lead to clearer build-depends, as instead of multiple ranges with gaps to skip know broken versions, build-depends can list a single range, and breaks-with can list the bad versions.

My five cents: There is discussion/work in Cabal dev about splitting the solver out. [1] I hope that at the end, there will be functionality that you can construct build/install plan by whatever means and use cabal functionality to execute it. Another functionality brought by work on haskell-security is that 01-index.tar.gz is append only file, so it’s “easy” to travel back in time in Hackage history. Combining those one can run an experiment, on how much - existing upper bounds prevent cabal from finding working install-plan; and how this change over time, because of maintainers activity. - non-existing upper bounds prevent found install-plan to compile properly; and how this change over time, because of a) maintainers own activity, b) Hackage trustee activity - other stats Until quantitative report justifying that upper bounds are clearly bad-idea, I would not propose any dramatical changes to how default solver works or Cabal-definition-format spec. With own solvers it would be easy to experiment and provide own metadata. As Hackage Trustee I do see much more full-of-red (failed builds) matrices on matrix.h.h.o than dark green ones (no install plan). Unfortunately only my gut feeling, no hard numbers but, but GHC <7.4/7.6 tends to be often red (because of base ==4.*, or base <5), or there are full lines of red because newer version of dependency causes breakage (which is no upper-bounds) For example. fast-logger introduced new type alias and new functionality in System.Log.FastLogger in minor version 2.4.4 [3]: --- Diff for | 2.4.3 → 2.4.4 | --- + System.Log.FastLogger.Date + type FormattedTime = ByteString + type TimeFormat = ByteString + newTimeCache :: TimeFormat -> IO (IO FormattedTime) + simpleTimeFormat :: TimeFormat + simpleTimeFormat' :: TimeFormat × System.Log.FastLogger + type FastLogger = LogStr -> IO () + LogCallback :: (LogStr -> IO ()) -> (IO ()) -> LogType + LogFile :: FilePath -> BufSize -> LogType + LogFileAutoRotate :: FileLogSpec -> BufSize -> LogType + LogNone :: LogType + LogStderr :: BufSize -> LogType + LogStdout :: BufSize -> LogType + data LogType + type TimedFastLogger = (FormattedTime -> LogStr) -> IO () + newFastLogger :: LogType -> IO (FastLogger, IO ()) + newTimedFastLogger :: (IO FormattedTime) -> LogType -> IO (TimedFastLogger, IO ()) + withFastLogger :: LogType -> (FastLogger -> IO a) -> IO () + withTimedFastLogger :: (IO FormattedTime) -> LogType -> (TimedFastLogger -> IO a) -> IO () × System.Log.FastLogger.File × New: check :: FilePath -> IO () Old: check :: FileLogSpec -> IO () [+ Added] [- Removed] [× Modified] [· Unmodified] And according to PVP you can do it, bumping only minor version. (The change in System.Log.FastLogger.File is breaking change, so it should been major bump, but our example holds even it was 2.4.4 -> 2.5) wai-logger package depends on fast-logger, and broke after new fast-logger release [4] because of: - doesn’t have upper-bounds - import(ed) modules improperly [5] The new version was fixed immediately, so I suspect that whetever the issue were about breakage or restrictive-upper bounds (pinged from Stackage) it would been fixed as fast. Yet now there is still lot’s of red in the matrix [6]. It’s highly unlikely that old versions would be picked by solver, but not impossible, happened to me, ekg-json picked very old aeson version (well again, no bounds there!) and broke. [7] To summarise this example, I’d rather make PRs to relax version bounds, then try to guess what bounds I have to adjust so I get working install plan. And to conclude, - Please setup CI, e.g. using Herbert’s script [8]. It’s very easy! - Have the base bounds restricting GHC’s to ones you test. - Contributing (i.e. to bump version bounds) would be extremely easy for others and you. Herbert is also very fast to make packages for newer (even unreleased version of GHC), so we had ability to test and fix! many packages before GHC-8.0 was officially released making adaptations as early as this year’s January. - Oleg - [1]: https://github.com/haskell/cabal/pull/3222 - [2]: http://matrix.hackage.haskell.org/packages see red-alert tag - [3]: http://hackage.haskell.org/package/fast-logger-2.4.4/docs/System-Log-FastLog... - [4]: https://github.com/kazu-yamamoto/logger/issues/88 - [5]: https://wiki.haskell.org/Import_modules_properly - [6]: http://imgur.com/bTYI8KC - [7] https://github.com/tibbe/ekg-json/pull/3 - [8] https://github.com/hvr/multi-ghc-travis
On 09 Jun 2016, at 12:22, Jeremy .
wrote: Versions of package dependencies can be categorised into 5 sets:
D1) Versions which the maintainer has tested and found to work D2) Versions which the maintainer has not tested but expects to work D3) Versions which the maintainer has tested and found to not work D4) Versions which the maintainer has not tested but expects to not work D5) Everything else
Cabal, however, only knows of 3 sets:
C1) Versions which satisfy build-depends C2) Versions which satisfy build-depends with --allow-newer C3) Everything else
The problem arises from the fact that the D sets to not map well onto the C sets, even after combining D1&D2 and D3&D4. Perhaps this could be solved with a new .cabal property, breaks-with. The solver will then prefer packages in this order:
1) Versions that satisfy build-depends 2) Versions that are not in breaks-with, unless a flag such as --strict-build-depends is applied
This may also lead to clearer build-depends, as instead of multiple ranges with gaps to skip know broken versions, build-depends can list a single range, and breaks-with can list the bad versions. _______________________________________________ ghc-devs mailing list ghc-devs@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs
participants (2)
-
Jeremy .
-
Oleg Grenrus