cabal-install-solver 3.14.2.0 → 3.16.0.0
raw patch · 15 files changed
+187/−122 lines, 15 filesdep ~Cabaldep ~Cabal-syntaxdep ~containersPVP ok
version bump matches the API change (PVP)
Dependency ranges changed: Cabal, Cabal-syntax, containers
API changes (from Hackage documentation)
- Distribution.Solver.Types.PackageConstraint: dispPackageConstraint :: PackageConstraint -> Doc
- Distribution.Solver.Types.PackageConstraint: dispPackageProperty :: PackageProperty -> Doc
- Distribution.Solver.Types.ProjectConfigPath: docProjectConfigPaths :: [ProjectConfigPath] -> Doc
+ Distribution.Solver.Compat.Prelude: ($dmget) :: (Binary t, Generic t, GBinaryGet (Rep t)) => Get t
+ Distribution.Solver.Compat.Prelude: ($dmput) :: (Binary t, Generic t, GBinaryPut (Rep t)) => t -> Put
+ Distribution.Solver.Compat.Prelude: ($dmrnf) :: (NFData a, Generic a, GNFData Zero (Rep a)) => a -> ()
+ Distribution.Solver.Types.ConstraintSource: ConstraintSourceWithRepl :: ConstraintSource
+ Distribution.Solver.Types.ConstraintSource: instance Distribution.Pretty.Pretty Distribution.Solver.Types.ConstraintSource.ConstraintSource
+ Distribution.Solver.Types.PackageConstraint: instance Distribution.Pretty.Pretty Distribution.Solver.Types.PackageConstraint.ConstraintScope
+ Distribution.Solver.Types.PackageConstraint: instance Distribution.Pretty.Pretty Distribution.Solver.Types.PackageConstraint.PackageConstraint
+ Distribution.Solver.Types.PackageConstraint: instance Distribution.Pretty.Pretty Distribution.Solver.Types.PackageConstraint.PackageProperty
+ Distribution.Solver.Types.ProjectConfigPath: docProjectConfigFiles :: [ProjectConfigPath] -> Doc
+ Distribution.Solver.Types.ProjectConfigPath: instance Distribution.Pretty.Pretty Distribution.Solver.Types.ProjectConfigPath.ProjectConfigPath
+ Distribution.Solver.Types.ProjectConfigPath: isUntrimmedUriConfigPath :: ProjectConfigPath -> Bool
+ Distribution.Solver.Types.ProjectConfigPath: quoteUntrimmed :: FilePath -> Doc
+ Distribution.Solver.Types.ProjectConfigPath: untrimmedUriImportMsg :: Doc -> ProjectConfigPath -> Doc
- Distribution.Solver.Compat.Prelude: ($!) :: forall (r :: RuntimeRep) a (b :: TYPE r). (a -> b) -> a -> b
+ Distribution.Solver.Compat.Prelude: ($!) :: (a -> b) -> a -> b
- Distribution.Solver.Compat.Prelude: ($) :: forall (r :: RuntimeRep) a (b :: TYPE r). (a -> b) -> a -> b
+ Distribution.Solver.Compat.Prelude: ($) :: (a -> b) -> a -> b
- Distribution.Solver.Compat.Prelude: class () => Binary t
+ Distribution.Solver.Compat.Prelude: class Binary t
- Distribution.Solver.Compat.Prelude: class () => Bounded a
+ Distribution.Solver.Compat.Prelude: class Bounded a
- Distribution.Solver.Compat.Prelude: class () => Enum a
+ Distribution.Solver.Compat.Prelude: class Enum a
- Distribution.Solver.Compat.Prelude: class () => Eq a
+ Distribution.Solver.Compat.Prelude: class Eq a
- Distribution.Solver.Compat.Prelude: class () => Foldable (t :: Type -> Type)
+ Distribution.Solver.Compat.Prelude: class Foldable (t :: Type -> Type)
- Distribution.Solver.Compat.Prelude: class () => Functor (f :: Type -> Type)
+ Distribution.Solver.Compat.Prelude: class Functor (f :: Type -> Type)
- Distribution.Solver.Compat.Prelude: class () => Generic a
+ Distribution.Solver.Compat.Prelude: class Generic a
- Distribution.Solver.Compat.Prelude: class () => IsString a
+ Distribution.Solver.Compat.Prelude: class IsString a
- Distribution.Solver.Compat.Prelude: class () => NFData a
+ Distribution.Solver.Compat.Prelude: class NFData a
- Distribution.Solver.Compat.Prelude: class () => Num a
+ Distribution.Solver.Compat.Prelude: class Num a
- Distribution.Solver.Compat.Prelude: class () => Read a
+ Distribution.Solver.Compat.Prelude: class Read a
- Distribution.Solver.Compat.Prelude: class () => Semigroup a
+ Distribution.Solver.Compat.Prelude: class Semigroup a
- Distribution.Solver.Compat.Prelude: class () => Show a
+ Distribution.Solver.Compat.Prelude: class Show a
- Distribution.Solver.Compat.Prelude: class () => Typeable (a :: k)
+ Distribution.Solver.Compat.Prelude: class Typeable (a :: k)
- Distribution.Solver.Compat.Prelude: data () => Bool
+ Distribution.Solver.Compat.Prelude: data Bool
- Distribution.Solver.Compat.Prelude: data () => Char
+ Distribution.Solver.Compat.Prelude: data Char
- Distribution.Solver.Compat.Prelude: data () => Double
+ Distribution.Solver.Compat.Prelude: data Double
- Distribution.Solver.Compat.Prelude: data () => Either a b
+ Distribution.Solver.Compat.Prelude: data Either a b
- Distribution.Solver.Compat.Prelude: data () => ExitCode
+ Distribution.Solver.Compat.Prelude: data ExitCode
- Distribution.Solver.Compat.Prelude: data () => Float
+ Distribution.Solver.Compat.Prelude: data Float
- Distribution.Solver.Compat.Prelude: data () => IO a
+ Distribution.Solver.Compat.Prelude: data IO a
- Distribution.Solver.Compat.Prelude: data () => IOException
+ Distribution.Solver.Compat.Prelude: data IOException
- Distribution.Solver.Compat.Prelude: data () => Int
+ Distribution.Solver.Compat.Prelude: data Int
- Distribution.Solver.Compat.Prelude: data () => Int16
+ Distribution.Solver.Compat.Prelude: data Int16
- Distribution.Solver.Compat.Prelude: data () => Int32
+ Distribution.Solver.Compat.Prelude: data Int32
- Distribution.Solver.Compat.Prelude: data () => Int64
+ Distribution.Solver.Compat.Prelude: data Int64
- Distribution.Solver.Compat.Prelude: data () => Int8
+ Distribution.Solver.Compat.Prelude: data Int8
- Distribution.Solver.Compat.Prelude: data () => Integer
+ Distribution.Solver.Compat.Prelude: data Integer
- Distribution.Solver.Compat.Prelude: data () => Map k a
+ Distribution.Solver.Compat.Prelude: data Map k a
- Distribution.Solver.Compat.Prelude: data () => Maybe a
+ Distribution.Solver.Compat.Prelude: data Maybe a
- Distribution.Solver.Compat.Prelude: data () => NonEmpty a
+ Distribution.Solver.Compat.Prelude: data NonEmpty a
- Distribution.Solver.Compat.Prelude: data () => NonEmptySet a
+ Distribution.Solver.Compat.Prelude: data NonEmptySet a
- Distribution.Solver.Compat.Prelude: data () => Ordering
+ Distribution.Solver.Compat.Prelude: data Ordering
- Distribution.Solver.Compat.Prelude: data () => Proxy (t :: k)
+ Distribution.Solver.Compat.Prelude: data Proxy (t :: k)
- Distribution.Solver.Compat.Prelude: data () => Set a
+ Distribution.Solver.Compat.Prelude: data Set a
- Distribution.Solver.Compat.Prelude: data () => SomeException
+ Distribution.Solver.Compat.Prelude: data SomeException
- Distribution.Solver.Compat.Prelude: data () => Void
+ Distribution.Solver.Compat.Prelude: data Void
- Distribution.Solver.Compat.Prelude: data () => Word
+ Distribution.Solver.Compat.Prelude: data Word
- Distribution.Solver.Compat.Prelude: data () => Word16
+ Distribution.Solver.Compat.Prelude: data Word16
- Distribution.Solver.Compat.Prelude: data () => Word32
+ Distribution.Solver.Compat.Prelude: data Word32
- Distribution.Solver.Compat.Prelude: data () => Word64
+ Distribution.Solver.Compat.Prelude: data Word64
- Distribution.Solver.Compat.Prelude: data () => Word8
+ Distribution.Solver.Compat.Prelude: data Word8
- Distribution.Solver.Compat.Prelude: error :: forall (r :: RuntimeRep) (a :: TYPE r). HasCallStack => [Char] -> a
+ Distribution.Solver.Compat.Prelude: error :: HasCallStack => [Char] -> a
- Distribution.Solver.Compat.Prelude: errorWithoutStackTrace :: forall (r :: RuntimeRep) (a :: TYPE r). [Char] -> a
+ Distribution.Solver.Compat.Prelude: errorWithoutStackTrace :: [Char] -> a
- Distribution.Solver.Compat.Prelude: infix 4 `notElem`
+ Distribution.Solver.Compat.Prelude: infix 4 ~
- Distribution.Solver.Compat.Prelude: infixl 4 <$>
+ Distribution.Solver.Compat.Prelude: infixl 4 <$
- Distribution.Solver.Compat.Prelude: infixl 6 <+>
+ Distribution.Solver.Compat.Prelude: infixl 6 +
- Distribution.Solver.Compat.Prelude: infixl 7 *
+ Distribution.Solver.Compat.Prelude: infixl 7 `rem`
- Distribution.Solver.Compat.Prelude: infixr 0 $!
+ Distribution.Solver.Compat.Prelude: infixr 0 `seq`
- Distribution.Solver.Compat.Prelude: infixr 5 ++
+ Distribution.Solver.Compat.Prelude: infixr 5 :|
- Distribution.Solver.Compat.Prelude: infixr 8 ^^
+ Distribution.Solver.Compat.Prelude: infixr 8 **
- Distribution.Solver.Compat.Prelude: newtype () => Const a (b :: k)
+ Distribution.Solver.Compat.Prelude: newtype Const a (b :: k)
- Distribution.Solver.Compat.Prelude: newtype () => Identity a
+ Distribution.Solver.Compat.Prelude: newtype Identity a
- Distribution.Solver.Compat.Prelude: seq :: forall {r :: RuntimeRep} a (b :: TYPE r). a -> b -> b
+ Distribution.Solver.Compat.Prelude: seq :: a -> b -> b
- Distribution.Solver.Compat.Prelude: undefined :: forall (r :: RuntimeRep) (a :: TYPE r). HasCallStack => a
+ Distribution.Solver.Compat.Prelude: undefined :: HasCallStack => a
- Distribution.Solver.Modular.ConflictSet: type ConflictMap = Map (Var QPN) Int
+ Distribution.Solver.Modular.ConflictSet: type ConflictMap = Map Var QPN Int
- Distribution.Solver.Modular.Dependency: type ConflictMap = Map (Var QPN) Int
+ Distribution.Solver.Modular.Dependency: type ConflictMap = Map Var QPN Int
- Distribution.Solver.Modular.Index: type Index = Map PN (Map I PInfo)
+ Distribution.Solver.Modular.Index: type Index = Map PN Map I PInfo
- Distribution.Solver.Modular.LabeledGraph: graphFromEdges :: forall key node edge. Ord key => [(node, key, [(edge, key)])] -> (Graph edge, Vertex -> (node, key, [(edge, key)]), key -> Maybe Vertex)
+ Distribution.Solver.Modular.LabeledGraph: graphFromEdges :: Ord key => [(node, key, [(edge, key)])] -> (Graph edge, Vertex -> (node, key, [(edge, key)]), key -> Maybe Vertex)
- Distribution.Solver.Modular.Package: data () => PackageIdentifier
+ Distribution.Solver.Modular.Package: data PackageIdentifier
- Distribution.Solver.Modular.Package: data () => PackageName
+ Distribution.Solver.Modular.Package: data PackageName
- Distribution.Solver.Modular.Package: data () => PkgconfigName
+ Distribution.Solver.Modular.Package: data PkgconfigName
- Distribution.Solver.Modular.Tree: type TreeTrav d c a = TreeF d c (Tree d a) -> TreeF d a (Tree d a)
+ Distribution.Solver.Modular.Tree: type TreeTrav d c a = TreeF d c Tree d a -> TreeF d a Tree d a
- Distribution.Solver.Types.DependencyResolver: type DependencyResolver loc = Platform -> CompilerInfo -> InstalledPackageIndex -> PackageIndex (SourcePackage loc) -> Maybe PkgConfigDb -> (PackageName -> PackagePreferences) -> [LabeledPackageConstraint] -> Set PackageName -> Progress String String [ResolverPackage loc]
+ Distribution.Solver.Types.DependencyResolver: type DependencyResolver loc = Platform -> CompilerInfo -> InstalledPackageIndex -> PackageIndex SourcePackage loc -> Maybe PkgConfigDb -> PackageName -> PackagePreferences -> [LabeledPackageConstraint] -> Set PackageName -> Progress String String [ResolverPackage loc]
Files
- ChangeLog.md +1/−1
- LICENSE +1/−1
- cabal-install-solver.cabal +9/−8
- src/Distribution/Solver/Compat/Prelude.hs +1/−1
- src/Distribution/Solver/Modular/Linking.hs +1/−1
- src/Distribution/Solver/Modular/Message.hs +0/−1
- src/Distribution/Solver/Modular/PSQ.hs +1/−1
- src/Distribution/Solver/Modular/Solver.hs +3/−1
- src/Distribution/Solver/Modular/Tree.hs +1/−1
- src/Distribution/Solver/Modular/WeightedPSQ.hs +1/−1
- src/Distribution/Solver/Types/ConstraintSource.hs +34/−23
- src/Distribution/Solver/Types/PackageConstraint.hs +17/−22
- src/Distribution/Solver/Types/PkgConfigDb.hs +0/−1
- src/Distribution/Solver/Types/ProjectConfigPath.hs +115/−57
- tests/UnitTests/Distribution/Solver/Modular/MessageUtils.hs +2/−2
ChangeLog.md view
@@ -1,1 +1,1 @@-Please see https://github.com/haskell/cabal/blob/master/release-notes/cabal-install-3.14.2.0.md+Please see https://github.com/haskell/cabal/blob/master/release-notes/cabal-install-3.16.0.0.md
LICENSE view
@@ -1,4 +1,4 @@-Copyright (c) 2003-2024, Cabal Development Team.+Copyright (c) 2003-2025, Cabal Development Team. See the AUTHORS file for the full list of copyright holders. See */LICENSE for the copyright holders of the subcomponents.
cabal-install-solver.cabal view
@@ -1,6 +1,6 @@-cabal-version: 2.2+cabal-version: 3.6 name: cabal-install-solver-version: 3.14.2.0+version: 3.16.0.0 synopsis: The solver component of cabal-install description: The solver component used in the cabal-install command-line program.@@ -11,7 +11,7 @@ license-file: LICENSE author: Cabal Development Team (see AUTHORS file) maintainer: Cabal Development Team <cabal-devel@haskell.org>-copyright: 2003-2024, Cabal Development Team+copyright: 2003-2025, Cabal Development Team category: Distribution build-type: Simple extra-doc-files:@@ -38,7 +38,7 @@ hs-source-dirs: src-assertion ghc-options: -Wall -Wcompat -Wnoncanonical-monad-instances- -fwarn-tabs -fwarn-incomplete-uni-patterns+ -Wtabs -Wincomplete-uni-patterns if impl(ghc < 8.8) ghc-options: -Wnoncanonical-monadfail-instances@@ -101,9 +101,9 @@ , array >=0.4 && <0.6 , base >=4.13 && <4.22 , bytestring >=0.10.6.0 && <0.13- , Cabal ^>=3.14- , Cabal-syntax ^>=3.14- , containers >=0.5.6.2 && <0.8+ , Cabal ^>=3.16+ , Cabal-syntax ^>=3.16+ , containers >=0.5.6.2 && <0.9 , edit-distance ^>= 0.2.2 , directory >= 1.3.7.0 && < 1.4 , filepath ^>=1.4.0.0 || ^>=1.5.0.0@@ -118,7 +118,8 @@ if flag(debug-tracetree) cpp-options: -DDEBUG_TRACETREE- build-depends: tracetree ^>=0.1+ build-depends:+ , tracetree ^>=0.1 Test-Suite unit-tests default-language: Haskell2010
src/Distribution/Solver/Compat/Prelude.hs view
@@ -1,5 +1,5 @@ -- to suppress WARNING in "Distribution.Compat.Prelude.Internal"-{-# OPTIONS_GHC -fno-warn-deprecations #-}+{-# OPTIONS_GHC -Wno-deprecations #-} -- | This module does two things: --
src/Distribution/Solver/Modular/Linking.hs view
@@ -2,7 +2,7 @@ {-# LANGUAGE MultiParamTypeClasses #-} -- TODO: remove this-{-# OPTIONS -fno-warn-incomplete-uni-patterns #-}+{-# OPTIONS -Wno-incomplete-uni-patterns #-} module Distribution.Solver.Modular.Linking ( validateLinking ) where
src/Distribution/Solver/Modular/Message.hs view
@@ -1,6 +1,5 @@ {-# LANGUAGE BangPatterns #-} {-# LANGUAGE LambdaCase #-}-{-# LANGUAGE ViewPatterns #-} module Distribution.Solver.Modular.Message ( Message(..),
src/Distribution/Solver/Modular/PSQ.hs view
@@ -1,4 +1,4 @@-{-# LANGUAGE DeriveFunctor, DeriveFoldable, DeriveTraversable #-}+{-# LANGUAGE DeriveTraversable #-} module Distribution.Solver.Modular.PSQ ( PSQ(..) -- Unit test needs constructor access , casePSQ
src/Distribution/Solver/Modular/Solver.hs view
@@ -1,7 +1,7 @@ {-# LANGUAGE CPP #-} #ifdef DEBUG_TRACETREE {-# LANGUAGE FlexibleInstances #-}-{-# OPTIONS_GHC -fno-warn-orphans #-}+{-# OPTIONS_GHC -Wno-orphans #-} #endif module Distribution.Solver.Modular.Solver ( SolverConfig(..)@@ -171,6 +171,7 @@ -- -- This only does something if the @debug-tracetree@ configure argument was -- given; otherwise this is just the identity function.+{- FOURMOLU_DISABLE -} traceTree :: #ifdef DEBUG_TRACETREE GSimpleTree a =>@@ -183,6 +184,7 @@ #else traceTree _ _ = id #endif+{- FOURMOLU_ENABLE -} #ifdef DEBUG_TRACETREE instance GSimpleTree (Tree d c) where
src/Distribution/Solver/Modular/Tree.hs view
@@ -1,4 +1,4 @@-{-# LANGUAGE DeriveFunctor, DeriveFoldable, DeriveTraversable #-}+{-# LANGUAGE DeriveTraversable #-} module Distribution.Solver.Modular.Tree ( POption(..) , Tree(..)
src/Distribution/Solver/Modular/WeightedPSQ.hs view
@@ -1,4 +1,4 @@-{-# LANGUAGE DeriveFunctor, DeriveFoldable, DeriveTraversable #-}+{-# LANGUAGE DeriveTraversable #-} {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE TupleSections #-} module Distribution.Solver.Modular.WeightedPSQ (
src/Distribution/Solver/Types/ConstraintSource.hs view
@@ -6,7 +6,8 @@ import Distribution.Solver.Compat.Prelude import Distribution.Solver.Types.ProjectConfigPath (ProjectConfigPath, docProjectConfigPath)-import Text.PrettyPrint (render)+import Distribution.Pretty (Pretty(pretty), prettyShow)+import Text.PrettyPrint (text) -- | Source of a 'PackageConstraint'. data ConstraintSource =@@ -41,6 +42,10 @@ -- from Cabal >= 3.11 | ConstraintSourceMultiRepl + -- | Constraint introduced by --with-repl, which requires features+ -- from Cabal >= 3.15+ | ConstraintSourceWithRepl+ -- | Constraint introduced by --enable-profiling-shared, which requires features -- from Cabal >= 3.13 | ConstraintSourceProfiledDynamic@@ -55,31 +60,37 @@ -- | An internal constraint due to compatibility issues with the Setup.hs -- command line interface requires a maximum upper bound on Cabal | ConstraintSetupCabalMaxVersion- deriving (Eq, Show, Generic)+ deriving (Show, Eq, Generic) instance Binary ConstraintSource instance Structured ConstraintSource -- | Description of a 'ConstraintSource'. showConstraintSource :: ConstraintSource -> String-showConstraintSource (ConstraintSourceMainConfig path) =- "main config " ++ path-showConstraintSource (ConstraintSourceProjectConfig path) =- "project config " ++ render (docProjectConfigPath path)-showConstraintSource (ConstraintSourceUserConfig path)= "user config " ++ path-showConstraintSource ConstraintSourceCommandlineFlag = "command line flag"-showConstraintSource ConstraintSourceUserTarget = "user target"-showConstraintSource ConstraintSourceNonReinstallablePackage =- "non-reinstallable package"-showConstraintSource ConstraintSourceFreeze = "cabal freeze"-showConstraintSource ConstraintSourceConfigFlagOrTarget =- "config file, command line flag, or user target"-showConstraintSource ConstraintSourceMultiRepl =- "--enable-multi-repl"-showConstraintSource ConstraintSourceProfiledDynamic =- "--enable-profiling-shared"-showConstraintSource ConstraintSourceUnknown = "unknown source"-showConstraintSource ConstraintSetupCabalMinVersion =- "minimum version of Cabal used by Setup.hs"-showConstraintSource ConstraintSetupCabalMaxVersion =- "maximum version of Cabal used by Setup.hs"+showConstraintSource = prettyShow++instance Pretty ConstraintSource where+ pretty constraintSource = case constraintSource of+ (ConstraintSourceMainConfig path) ->+ text "main config" <+> text path+ (ConstraintSourceProjectConfig path) ->+ text "project config" <+> docProjectConfigPath path+ (ConstraintSourceUserConfig path)-> text "user config " <+> text path+ ConstraintSourceCommandlineFlag -> text "command line flag"+ ConstraintSourceUserTarget -> text "user target"+ ConstraintSourceNonReinstallablePackage ->+ text "non-reinstallable package"+ ConstraintSourceFreeze -> text "cabal freeze"+ ConstraintSourceConfigFlagOrTarget ->+ text "config file, command line flag, or user target"+ ConstraintSourceMultiRepl ->+ text "--enable-multi-repl"+ ConstraintSourceWithRepl ->+ text "--with-repl"+ ConstraintSourceProfiledDynamic ->+ text "--enable-profiling-shared"+ ConstraintSourceUnknown -> text "unknown source"+ ConstraintSetupCabalMinVersion ->+ text "minimum version of Cabal used by Setup.hs"+ ConstraintSetupCabalMaxVersion ->+ text "maximum version of Cabal used by Setup.hs"
src/Distribution/Solver/Types/PackageConstraint.hs view
@@ -11,9 +11,7 @@ scopeToPackageName, constraintScopeMatches, PackageProperty(..),- dispPackageProperty, PackageConstraint(..),- dispPackageConstraint, showPackageConstraint, packageConstraintToDependency ) where@@ -23,7 +21,7 @@ import Distribution.Package (PackageName) import Distribution.PackageDescription (FlagAssignment, dispFlagAssignment)-import Distribution.Pretty (flatStyle, pretty)+import Distribution.Pretty (flatStyle, Pretty(pretty)) import Distribution.Types.PackageVersionConstraint (PackageVersionConstraint (..)) import Distribution.Version (VersionRange, simplifyVersionRange) @@ -82,12 +80,11 @@ in setup pp && pn == pn' constraintScopeMatches (ScopeAnyQualifier pn) (Q _ pn') = pn == pn' --- | Pretty-prints a constraint scope.-dispConstraintScope :: ConstraintScope -> Disp.Doc-dispConstraintScope (ScopeTarget pn) = pretty pn <<>> Disp.text "." <<>> pretty pn-dispConstraintScope (ScopeQualified q pn) = dispQualifier q <<>> pretty pn-dispConstraintScope (ScopeAnySetupQualifier pn) = Disp.text "setup." <<>> pretty pn-dispConstraintScope (ScopeAnyQualifier pn) = Disp.text "any." <<>> pretty pn+instance Pretty ConstraintScope where+ pretty (ScopeTarget pn) = pretty pn <<>> Disp.text "." <<>> pretty pn+ pretty (ScopeQualified q pn) = dispQualifier q <<>> pretty pn+ pretty (ScopeAnySetupQualifier pn) = Disp.text "setup." <<>> pretty pn+ pretty (ScopeAnyQualifier pn) = Disp.text "any." <<>> pretty pn -- | A package property is a logical predicate on packages. data PackageProperty@@ -101,24 +98,22 @@ instance Binary PackageProperty instance Structured PackageProperty --- | Pretty-prints a package property.-dispPackageProperty :: PackageProperty -> Disp.Doc-dispPackageProperty (PackagePropertyVersion verrange) = pretty verrange-dispPackageProperty PackagePropertyInstalled = Disp.text "installed"-dispPackageProperty PackagePropertySource = Disp.text "source"-dispPackageProperty (PackagePropertyFlags flags) = dispFlagAssignment flags-dispPackageProperty (PackagePropertyStanzas stanzas) =- Disp.hsep $ map (Disp.text . showStanza) stanzas+instance Pretty PackageProperty where+ pretty (PackagePropertyVersion verrange) = pretty verrange+ pretty PackagePropertyInstalled = Disp.text "installed"+ pretty PackagePropertySource = Disp.text "source"+ pretty (PackagePropertyFlags flags) = dispFlagAssignment flags+ pretty (PackagePropertyStanzas stanzas) =+ Disp.hsep $ map (Disp.text . showStanza) stanzas -- | A package constraint consists of a scope plus a property -- that must hold for all packages within that scope. data PackageConstraint = PackageConstraint ConstraintScope PackageProperty deriving (Eq, Show) --- | Pretty-prints a package constraint.-dispPackageConstraint :: PackageConstraint -> Disp.Doc-dispPackageConstraint (PackageConstraint scope prop) =- dispConstraintScope scope <+> dispPackageProperty prop+instance Pretty PackageConstraint where+ pretty (PackageConstraint scope prop) =+ pretty scope <+> pretty prop -- | Alternative textual representation of a package constraint -- for debugging purposes (slightly more verbose than that@@ -126,7 +121,7 @@ -- showPackageConstraint :: PackageConstraint -> String showPackageConstraint pc@(PackageConstraint scope prop) =- Disp.renderStyle flatStyle . postprocess $ dispPackageConstraint pc2+ Disp.renderStyle flatStyle . postprocess $ pretty pc2 where pc2 = case prop of PackagePropertyVersion vr ->
src/Distribution/Solver/Types/PkgConfigDb.hs view
@@ -1,5 +1,4 @@ {-# LANGUAGE DeriveGeneric #-}-{-# LANGUAGE LambdaCase #-} ----------------------------------------------------------------------------- -- | -- Module : Distribution.Solver.Types.PkgConfigDb
src/Distribution/Solver/Types/ProjectConfigPath.hs view
@@ -12,13 +12,16 @@ -- * Messages , docProjectConfigPath- , docProjectConfigPaths+ , docProjectConfigFiles , cyclicalImportMsg+ , untrimmedUriImportMsg , docProjectConfigPathFailReason+ , quoteUntrimmed -- * Checks and Normalization , isCyclicConfigPath , isTopLevelConfigPath+ , isUntrimmedUriConfigPath , canonicalizeConfigPath ) where @@ -30,12 +33,17 @@ import Data.List.NonEmpty ((<|)) import Network.URI (parseURI, parseAbsoluteURI) import System.Directory-import System.FilePath+import System.FilePath hiding (splitPath)+import qualified System.FilePath as FP (splitPath)+import qualified System.FilePath.Posix as Posix+import qualified System.FilePath.Windows as Windows import qualified Data.List.NonEmpty as NE import Distribution.Solver.Modular.Version (VR)-import Distribution.Pretty (prettyShow)+import Distribution.Pretty (prettyShow, Pretty(..))+import Distribution.Utils.String (trim) import Text.PrettyPrint import Distribution.Simple.Utils (ordNub)+import Distribution.System (OS(Windows), buildOS) -- | Path to a configuration file, either a singleton project root, or a longer -- list representing a path to an import. The path is a non-empty list that we@@ -51,6 +59,9 @@ newtype ProjectConfigPath = ProjectConfigPath (NonEmpty FilePath) deriving (Eq, Show, Generic) +instance Pretty ProjectConfigPath where+ pretty = docProjectConfigPath+ -- | Sorts URIs after local file paths and longer file paths after shorter ones -- as measured by the number of path segments. If still equal, then sorting is -- lexical.@@ -58,6 +69,14 @@ -- The project itself, a single element root path, compared to any of the -- configuration paths it imports, should always sort first. Comparing one -- project root path against another is done lexically.+--+-- For comparison purposes, path separators are normalized to the @buildOS@+-- platform's path separator.+--+-- >>> let abFwd = ProjectConfigPath $ "a/b.config" :| []+-- >>> let abBwd = ProjectConfigPath $ "a\\b.config" :| []+-- >>> compare abFwd abBwd+-- EQ instance Ord ProjectConfigPath where compare pa@(ProjectConfigPath (NE.toList -> as)) pb@(ProjectConfigPath (NE.toList -> bs)) = case (as, bs) of@@ -66,7 +85,7 @@ -- this though, do a comparison anyway when both sides have length -- 1. The root path, the project itself, should always be the first -- path in a sorted listing.- ([a], [b]) -> compare a b+ ([a], [b]) -> compare (splitPath a) (splitPath b) ([_], _) -> LT (_, [_]) -> GT @@ -80,6 +99,16 @@ P.<> compare (length aPaths) (length bPaths) P.<> compare aPaths bPaths where+ splitPath = FP.splitPath . normSep where+ normSep p =+ if buildOS == Windows+ then+ Windows.joinPath $ Windows.splitDirectories+ [if Posix.isPathSeparator c then Windows.pathSeparator else c| c <- p]+ else+ Posix.joinPath $ Posix.splitDirectories+ [if Windows.isPathSeparator c then Posix.pathSeparator else c| c <- p]+ aPaths = splitPath <$> as bPaths = splitPath <$> bs aImporters = snd $ unconsProjectConfigPath pa@@ -89,35 +118,39 @@ instance Structured ProjectConfigPath -- | Renders the path like this;--- @--- D.config--- imported by: C.config--- imported by: B.config--- imported by: A.project--- @+--+-- >D.config+-- > imported by: C.config+-- > imported by: B.config+-- > imported by: A.project+-- -- >>> render . docProjectConfigPath $ ProjectConfigPath $ "D.config" :| ["C.config", "B.config", "A.project"] -- "D.config\n imported by: C.config\n imported by: B.config\n imported by: A.project" docProjectConfigPath :: ProjectConfigPath -> Doc-docProjectConfigPath (ProjectConfigPath (p :| [])) = text p-docProjectConfigPath (ProjectConfigPath (p :| ps)) = vcat $- text p : [ text " " <+> text "imported by:" <+> text l | l <- ps ]+docProjectConfigPath (ProjectConfigPath (p :| [])) = quoteUntrimmed p+docProjectConfigPath (ProjectConfigPath (p :| ps)) = vcat $ quoteUntrimmed p :+ [ text " " <+> text "imported by:" <+> quoteUntrimmed l | l <- ps ] +-- | If the path has leading or trailing spaces then show it quoted.+quoteUntrimmed :: FilePath -> Doc+quoteUntrimmed s = if trim s /= s then quotes (text s) else text s+ -- | Renders the paths as a list without showing which path imports another, -- like this;--- @--- - cabal.project--- - project-cabal/constraints.config--- - project-cabal/ghc-latest.config--- - project-cabal/ghc-options.config--- - project-cabal/pkgs.config--- - project-cabal/pkgs/benchmarks.config--- - project-cabal/pkgs/buildinfo.config--- - project-cabal/pkgs/cabal.config--- - project-cabal/pkgs/install.config--- - project-cabal/pkgs/integration-tests.config--- - project-cabal/pkgs/tests.config--- @ --+-- >- cabal.project+-- >- project-cabal/constraints.config+-- >- project-cabal/ghc-latest.config+-- >- project-cabal/ghc-options.config+-- >- project-cabal/pkgs.config+-- >- project-cabal/pkgs/benchmarks.config+-- >- project-cabal/pkgs/buildinfo.config+-- >- project-cabal/pkgs/cabal.config+-- >- project-cabal/pkgs/install.config+-- >- project-cabal/pkgs/integration-tests.config+-- >- project-cabal/pkgs/tests.config+--+-- -- >>> :{ -- do -- let ps =@@ -133,11 +166,11 @@ -- , ProjectConfigPath ("project-cabal/pkgs/integration-tests.config" :| ["project-cabal/pkgs.config","cabal.project"]) -- , ProjectConfigPath ("project-cabal/pkgs/tests.config" :| ["project-cabal/pkgs.config","cabal.project"]) -- ]--- return . render $ docProjectConfigPaths ps+-- return . render $ docProjectConfigFiles ps -- :} -- "- cabal.project\n- project-cabal/constraints.config\n- project-cabal/ghc-latest.config\n- project-cabal/ghc-options.config\n- project-cabal/pkgs.config\n- project-cabal/pkgs/benchmarks.config\n- project-cabal/pkgs/buildinfo.config\n- project-cabal/pkgs/cabal.config\n- project-cabal/pkgs/install.config\n- project-cabal/pkgs/integration-tests.config\n- project-cabal/pkgs/tests.config"-docProjectConfigPaths :: [ProjectConfigPath] -> Doc-docProjectConfigPaths ps = vcat+docProjectConfigFiles :: [ProjectConfigPath] -> Doc+docProjectConfigFiles ps = vcat [ text "-" <+> text p | p <- ordNub [ p | ProjectConfigPath (p :| _) <- ps ] ]@@ -150,6 +183,14 @@ , nest 2 (docProjectConfigPath path) ] +-- | A message for an import that has leading or trailing spaces.+untrimmedUriImportMsg :: Doc -> ProjectConfigPath -> Doc+untrimmedUriImportMsg intro path =+ vcat+ [ intro <+> text "import has leading or trailing whitespace" <> semi+ , nest 2 (docProjectConfigPath path)+ ]+ docProjectConfigPathFailReason :: VR -> ProjectConfigPath -> Doc docProjectConfigPathFailReason vr pcp | ProjectConfigPath (p :| []) <- pcp =@@ -178,6 +219,11 @@ isCyclicConfigPath :: ProjectConfigPath -> Bool isCyclicConfigPath (ProjectConfigPath p) = length p /= length (NE.nub p) +-- | Check if the last segment of the path (root or importee) is a URI that has+-- leading or trailing spaces.+isUntrimmedUriConfigPath :: ProjectConfigPath -> Bool+isUntrimmedUriConfigPath (ProjectConfigPath (p :| _)) = let p' = trim p in p' /= p && isURI p'+ -- | Check if the project config path is top-level, meaning it was not included by -- some other project config. isTopLevelConfigPath :: ProjectConfigPath -> Bool@@ -196,7 +242,7 @@ makeRelativeConfigPath :: FilePath -> ProjectConfigPath -> ProjectConfigPath makeRelativeConfigPath dir (ProjectConfigPath p) = ProjectConfigPath- $ (\segment -> (if isURI segment then segment else makeRelative dir segment))+ $ (\segment@(trim -> trimSegment) -> (if isURI trimSegment then trimSegment else makeRelative dir segment)) <$> p -- | Normalizes and canonicalizes a path removing '.' and '..' indirections.@@ -204,33 +250,31 @@ -- instead of relative to the file it was imported from. -- -- It converts paths like this:--- @--- └─ hops-0.project--- └─ hops/hops-1.config--- └─ ../hops-2.config--- └─ hops/hops-3.config--- └─ ../hops-4.config--- └─ hops/hops-5.config--- └─ ../hops-6.config--- └─ hops/hops-7.config--- └─ ../hops-8.config--- └─ hops/hops-9.config--- @ --+-- > hops-0.project+-- > └─ hops/hops-1.config+-- > └─ ../hops-2.config+-- > └─ hops/hops-3.config+-- > └─ ../hops-4.config+-- > └─ hops/hops-5.config+-- > └─ ../hops-6.config+-- > └─ hops/hops-7.config+-- > └─ ../hops-8.config+-- > └─ hops/hops-9.config+-- -- Into paths like this:--- @--- └─ hops-0.project--- └─ hops/hops-1.config--- └─ hops-2.config--- └─ hops/hops-3.config--- └─ hops-4.config--- └─ hops/hops-5.config--- └─ hops-6.config--- └─ hops/hops-7.config--- └─ hops-8.config--- └─ hops/hops-9.config--- @ --+-- > hops-0.project+-- > └─ hops/hops-1.config+-- > └─ hops-2.config+-- > └─ hops/hops-3.config+-- > └─ hops-4.config+-- > └─ hops/hops-5.config+-- > └─ hops-6.config+-- > └─ hops/hops-7.config+-- > └─ hops-8.config+-- > └─ hops/hops-9.config+-- -- That way we have @hops-8.config@ instead of -- @./hops/../hops/../hops/../hops/../hops-8.config@. --@@ -275,11 +319,25 @@ -- return $ expected == render (docProjectConfigPath p) ++ "\n" -- :} -- True+--+-- "A string is a valid URL potentially surrounded by spaces if, after stripping leading and trailing whitespace from it, it is a valid URL."+-- [W3C/HTML5/URLs](https://www.w3.org/TR/2010/WD-html5-20100624/urls.html)+--+-- Trailing spaces for @ProjectConfigPath@ URLs are trimmed.+--+-- >>> p <- canonicalizeConfigPath "" (ProjectConfigPath $ ("https://www.stackage.org/nightly-2024-12-05/cabal.config ") :| [])+-- >>> render $ docProjectConfigPath p+-- "https://www.stackage.org/nightly-2024-12-05/cabal.config"+--+-- >>> let d = testDir+-- >>> p <- canonicalizeConfigPath d (ProjectConfigPath $ ("https://www.stackage.org/nightly-2024-12-05/cabal.config ") :| [d </> "cabal.project"])+-- >>> render $ docProjectConfigPath p+-- "https://www.stackage.org/nightly-2024-12-05/cabal.config\n imported by: cabal.project" canonicalizeConfigPath :: FilePath -> ProjectConfigPath -> IO ProjectConfigPath canonicalizeConfigPath d (ProjectConfigPath p) = do- xs <- sequence $ NE.scanr (\importee -> (>>= \importer ->- if isURI importee- then pure importee+ xs <- sequence $ NE.scanr (\importee@(trim -> trimImportee) -> (>>= \importer@(trim -> trimImporter) ->+ if isURI trimImportee || isURI trimImporter+ then pure trimImportee else canonicalizePath $ d </> takeDirectory importer </> importee)) (pure ".") p return . makeRelativeConfigPath d . ProjectConfigPath . NE.fromList $ NE.init xs
tests/UnitTests/Distribution/Solver/Modular/MessageUtils.hs view
@@ -58,9 +58,9 @@ isOutOfBounds range a b = not $ withinRange range a b testRange :: Int -> [String] -> String -> Assertion-testRange range elems erronousElement = assertBool "String should be out of bounds to make a spelling suggestion" (isOutOfBounds range erronousElement suggestion)+testRange range elems erroneousElement = assertBool "String should be out of bounds to make a spelling suggestion" (isOutOfBounds range erroneousElement suggestion) where- suggestion = mostSimilarElement erronousElement elems+ suggestion = mostSimilarElement erroneousElement elems outOfBounds :: [String] outOfBounds =