Commit 9b3686fb authored by Oleg Grenrus's avatar Oleg Grenrus

Add NonEmptySet and use it in Dependency

parent 8d9e8afe
......@@ -15,6 +15,9 @@ library
, Cabal ^>=3.3.0.0
, QuickCheck ^>=2.13.2
if !impl(ghc >= 8.0)
build-depends: semigroups
exposed-modules:
Test.QuickCheck.GenericArbitrary
Test.QuickCheck.Instances.Cabal
......@@ -6,10 +6,12 @@ module Test.QuickCheck.Instances.Cabal () where
import Control.Applicative (liftA2)
import Data.Char (isAlphaNum, isDigit)
import Data.List (intercalate)
import Data.List.NonEmpty (NonEmpty (..))
import Distribution.Utils.Generic (lowercase)
import Test.QuickCheck
import Distribution.CabalSpecVersion
import Distribution.Compat.NonEmptySet (NonEmptySet)
import Distribution.Compiler
import Distribution.FieldGrammar.Newtypes
import Distribution.ModuleName
......@@ -30,6 +32,8 @@ import Distribution.Version
import Test.QuickCheck.GenericArbitrary
import qualified Distribution.Compat.NonEmptySet as NES
#if !MIN_VERSION_base(4,8,0)
import Control.Applicative (pure, (<$>), (<*>))
#endif
......@@ -332,6 +336,19 @@ instance Arbitrary CompilerId where
arbitrary = genericArbitrary
shrink = genericShrink
-------------------------------------------------------------------------------
-- NonEmptySet
-------------------------------------------------------------------------------
instance (Arbitrary a, Ord a) => Arbitrary (NonEmptySet a) where
arbitrary = mk <$> arbitrary <*> arbitrary where
mk x xs = NES.fromNonEmpty (x :| xs)
shrink nes = case NES.toNonEmpty nes of
x :| xs -> map mk (shrink (x, xs))
where
mk (x,xs) = NES.fromNonEmpty (x :| xs)
-------------------------------------------------------------------------------
-- Helpers
-------------------------------------------------------------------------------
......
......@@ -372,7 +372,7 @@ instance Described Dependency where
[ reChar '{'
, RESpaces
-- no leading or trailing comma
, REMunch reSpacedComma reUnqualComponent
, REMunch1 reSpacedComma reUnqualComponent
, RESpaces
, reChar '}'
]
......
......@@ -20,7 +20,7 @@ import Distribution.CabalSpecVersion (CabalSpecVersion)
import Distribution.Compiler (CompilerFlavor, CompilerId, PerCompilerFlavor)
import Distribution.InstalledPackageInfo (AbiDependency, ExposedModule, InstalledPackageInfo)
import Distribution.ModuleName (ModuleName)
import Distribution.Package (Dependency, PackageIdentifier, PackageName)
import Distribution.Package (PackageIdentifier, PackageName)
import Distribution.PackageDescription
import Distribution.Simple.Compiler (DebugInfoLevel, OptimisationLevel, ProfDetailLevel)
import Distribution.Simple.Flag (Flag)
......@@ -31,6 +31,7 @@ import Distribution.System
import Distribution.Types.AbiHash (AbiHash)
import Distribution.Types.ComponentId (ComponentId)
import Distribution.Types.CondTree
import Distribution.Types.Dependency (Dependency (..), mainLibSet)
import Distribution.Types.ExecutableScope
import Distribution.Types.ExeDependency
import Distribution.Types.ForeignLib
......@@ -52,6 +53,8 @@ import Distribution.Utils.ShortText (ShortText, fromShortText)
import Distribution.Verbosity
import Distribution.Verbosity.Internal
import qualified Distribution.Compat.NonEmptySet as NES
-------------------------------------------------------------------------------
-- instances
-------------------------------------------------------------------------------
......@@ -61,9 +64,16 @@ instance (Show a, ToExpr b, ToExpr c, Show b, Show c, Eq a, Eq c, Eq b) => ToExp
instance (Show a, ToExpr b, ToExpr c, Show b, Show c, Eq a, Eq c, Eq b) => ToExpr (CondBranch a b c)
instance (ToExpr a) => ToExpr (NubList a)
instance (ToExpr a) => ToExpr (Flag a)
instance ToExpr a => ToExpr (NES.NonEmptySet a) where
toExpr xs = App "NonEmptySet.fromNonEmpty" [toExpr $ NES.toNonEmpty xs]
instance ToExpr a => ToExpr (PerCompilerFlavor a)
instance ToExpr Dependency where
toExpr d@(Dependency pn vr cs)
| cs == mainLibSet = App "Dependency" [toExpr pn, toExpr vr, App "mainLibSet" []]
| otherwise = genericToExpr d
instance ToExpr AbiDependency
instance ToExpr AbiHash
instance ToExpr Arch
......@@ -78,7 +88,6 @@ instance ToExpr CompilerId
instance ToExpr ComponentId
instance ToExpr DebugInfoLevel
instance ToExpr DefUnitId
instance ToExpr Dependency
instance ToExpr ExeDependency
instance ToExpr Executable
instance ToExpr ExecutableScope
......
......@@ -352,6 +352,7 @@ library
Distribution.Compat.Graph
Distribution.Compat.Internal.TempFile
Distribution.Compat.Newtype
Distribution.Compat.NonEmptySet
Distribution.Compat.ResponseFile
Distribution.Compat.Prelude.Internal
Distribution.Compat.Process
......@@ -693,6 +694,9 @@ test-suite unit-tests
if !impl(ghc >= 7.10)
build-depends: void
if !impl(ghc >= 8.0)
build-depends: semigroups
test-suite parser-tests
type: exitcode-stdio-1.0
hs-source-dirs: tests
......
......@@ -45,6 +45,7 @@ import Distribution.Utils.Generic
import Control.Monad
import qualified Data.Set as Set
import qualified Distribution.Compat.NonEmptySet as NonEmptySet
import qualified Data.Map as Map
import Distribution.Pretty
import Text.PrettyPrint
......@@ -179,7 +180,7 @@ toConfiguredComponent pkg_descr this_cid lib_dep_map exe_dep_map component = do
text "package" <+> pretty pn
Just p -> return p
-- Return all library components
forM (Set.toList sublibs) $ \lib ->
forM (NonEmptySet.toList sublibs) $ \lib ->
let comp = CLibName lib in
case Map.lookup (CLibName $ LSubLibName $
packageNameToUnqualComponentName name) pkg
......
{-# LANGUAGE CPP #-}
{-# LANGUAGE DeriveDataTypeable #-}
module Distribution.Compat.NonEmptySet (
NonEmptySet,
-- * Construction
singleton,
-- * Conversions
toNonEmpty,
fromNonEmpty,
toList,
-- * Query
member,
-- * Map
map,
) where
import Prelude (Bool (..), Eq, Ord (..), Read, Show (..), String, error, return, showParen, showString, ($), (++), (.))
import Control.DeepSeq (NFData (..))
import Data.Data (Data)
import Data.List.NonEmpty (NonEmpty (..))
import Data.Semigroup (Semigroup (..))
import Data.Typeable (Typeable)
import qualified Data.Foldable as F
import qualified Data.Set as Set
import Distribution.Compat.Binary (Binary (..))
import Distribution.Utils.Structured
#if MIN_VERSION_binary(0,6,0)
import Control.Applicative (empty)
#else
import Control.Monad (fail)
#endif
newtype NonEmptySet a = NES (Set.Set a)
deriving (Eq, Ord, Typeable, Data, Read)
-------------------------------------------------------------------------------
-- Instances
-------------------------------------------------------------------------------
instance Show a => Show (NonEmptySet a) where
showsPrec d s = showParen (d > 10)
$ showString "fromNonEmpty "
. showsPrec 11 (toNonEmpty s)
instance Binary a => Binary (NonEmptySet a) where
put (NES s) = put s
get = do
xs <- get
if Set.null xs
#if MIN_VERSION_binary(0,6,0)
then empty
#else
then fail "NonEmptySet: empty"
#endif
else return (NES xs)
instance Structured a => Structured (NonEmptySet a) where
structure = containerStructure
instance NFData a => NFData (NonEmptySet a) where
rnf (NES x) = rnf x
-- | Note: there aren't @Monoid@ instance.
instance Ord a => Semigroup (NonEmptySet a) where
NES x <> NES y = NES (Set.union x y)
instance F.Foldable NonEmptySet where
foldMap f (NES s) = F.foldMap f s
foldr f z (NES s) = F.foldr f z s
#if MIN_VERSION_base(4,8,0)
toList = toList
null _ = False
length (NES s) = F.length s
#endif
-------------------------------------------------------------------------------
-- Constructors
-------------------------------------------------------------------------------
singleton :: a -> NonEmptySet a
singleton = NES . Set.singleton
-------------------------------------------------------------------------------
-- Conversions
-------------------------------------------------------------------------------
fromNonEmpty :: Ord a => NonEmpty a -> NonEmptySet a
fromNonEmpty (x :| xs) = NES (Set.fromList (x : xs))
toNonEmpty :: NonEmptySet a -> NonEmpty a
toNonEmpty (NES s) = case Set.toList s of
[] -> panic "toNonEmpty"
x:xs -> x :| xs
toList :: NonEmptySet a -> [a]
toList (NES s) = Set.toList s
-------------------------------------------------------------------------------
-- Query
-------------------------------------------------------------------------------
member :: Ord a => a -> NonEmptySet a -> Bool
member x (NES xs) = Set.member x xs
-------------------------------------------------------------------------------
-- Map
-------------------------------------------------------------------------------
map
:: ( Ord b
#if !MIN_VERSION_containers(0,5,2)
, Ord a
#endif
)
=> (a -> b) -> NonEmptySet a -> NonEmptySet b
map f (NES x) = NES (Set.map f x)
-------------------------------------------------------------------------------
-- Internal
-------------------------------------------------------------------------------
panic :: String -> a
panic msg = error $ "NonEmptySet invariant violated: " ++ msg
......@@ -47,6 +47,7 @@ module Distribution.Compat.Prelude (
-- * Some types
Map,
Set,
NonEmptySet,
Identity (..),
Proxy (..),
Void,
......@@ -171,6 +172,7 @@ import Text.Read (readMaybe)
import qualified Text.PrettyPrint as Disp
import Distribution.Utils.Structured (Structured)
import Distribution.Compat.NonEmptySet (NonEmptySet)
-- | New name for 'Text.PrettyPrint.<>'
(<<>>) :: Disp.Doc -> Disp.Doc -> Disp.Doc
......
......@@ -594,7 +594,7 @@ checkFields pkg =
, name `elem` map prettyShow knownLanguages ]
testedWithImpossibleRanges =
[ Dependency (mkPackageName (prettyShow compiler)) vr Set.empty
[ Dependency (mkPackageName (prettyShow compiler)) vr mainLibSet
| (compiler, vr) <- testedWith pkg
, isNoVersion vr ]
......
......@@ -64,9 +64,7 @@ import Distribution.Types.CondTree
import Distribution.Types.Condition
import Distribution.Types.DependencyMap
import qualified Data.Map.Strict as Map.Strict
import qualified Data.Map.Lazy as Map
import qualified Data.Set as Set
import Data.Tree ( Tree(Node) )
------------------------------------------------------------------------------
......@@ -188,7 +186,7 @@ resolveWithFlags dom enabled os arch impl constrs trees checkDeps =
either (Left . fromDepMapUnion) Right $ explore (build mempty dom)
where
extraConstrs = toDepMap
[ Dependency pn ver mempty
[ Dependency pn ver mainLibSet
| PackageVersionConstraint pn ver <- constrs
]
......@@ -232,11 +230,7 @@ resolveWithFlags dom enabled os arch impl constrs trees checkDeps =
mp :: Either DepMapUnion a -> Either DepMapUnion a -> Either DepMapUnion a
mp m@(Right _) _ = m
mp _ m@(Right _) = m
mp (Left xs) (Left ys) =
let union = Map.foldrWithKey (Map.Strict.insertWith combine)
(unDepMapUnion xs) (unDepMapUnion ys)
combine x y = (\(vr, cs) -> (simplifyVersionRange vr,cs)) $ unionVersionRanges' x y
in union `seq` Left (DepMapUnion union)
mp (Left xs) (Left ys) = Left (xs <> ys)
-- `mzero'
mz :: Either DepMapUnion a
......@@ -312,21 +306,24 @@ extractConditions f gpkg =
]
-- | A map of dependencies that combines version ranges using 'unionVersionRanges'.
newtype DepMapUnion = DepMapUnion { unDepMapUnion :: Map PackageName (VersionRange, Set LibraryName) }
-- | A map of package constraints that combines version ranges using 'unionVersionRanges'.
newtype DepMapUnion = DepMapUnion { unDepMapUnion :: Map PackageName (VersionRange, NonEmptySet LibraryName) }
-- An union of versions should correspond to an intersection of the components.
-- The intersection may not be necessary.
unionVersionRanges' :: (VersionRange, Set LibraryName)
-> (VersionRange, Set LibraryName)
-> (VersionRange, Set LibraryName)
unionVersionRanges' (vra, csa) (vrb, csb) =
(unionVersionRanges vra vrb, Set.intersection csa csb)
instance Semigroup DepMapUnion where
DepMapUnion x <> DepMapUnion y = DepMapUnion $
Map.unionWith unionVersionRanges' x y
unionVersionRanges'
:: (VersionRange, NonEmptySet LibraryName)
-> (VersionRange, NonEmptySet LibraryName)
-> (VersionRange, NonEmptySet LibraryName)
unionVersionRanges' (vr, cs) (vr', cs') = (unionVersionRanges vr vr', cs <> cs')
toDepMapUnion :: [Dependency] -> DepMapUnion
toDepMapUnion ds =
DepMapUnion $ Map.fromListWith unionVersionRanges' [ (p,(vr,cs)) | Dependency p vr cs <- ds ]
fromDepMapUnion :: DepMapUnion -> [Dependency]
fromDepMapUnion m = [ Dependency p vr cs | (p,(vr,cs)) <- Map.toList (unDepMapUnion m) ]
......
......@@ -39,6 +39,7 @@ module Distribution.Parsec (
parsecQuoted,
parsecMaybeQuoted,
parsecCommaList,
parsecCommaNonEmpty,
parsecLeadingCommaList,
parsecLeadingCommaNonEmpty,
parsecOptCommaList,
......@@ -293,6 +294,9 @@ parsecStandard f = do
parsecCommaList :: CabalParsing m => m a -> m [a]
parsecCommaList p = P.sepBy (p <* P.spaces) (P.char ',' *> P.spaces P.<?> "comma")
parsecCommaNonEmpty :: CabalParsing m => m a -> m (NonEmpty a)
parsecCommaNonEmpty p = P.sepByNonEmpty (p <* P.spaces) (P.char ',' *> P.spaces P.<?> "comma")
-- | Like 'parsecCommaList' but accept leading or trailing comma.
--
-- @
......
......@@ -549,7 +549,7 @@ testSuiteLibV09AsLibAndExe pkg_descr
testLibDep = Dependency
pkgName'
(thisVersion $ pkgVersion $ package pkg_descr)
(Set.singleton LMainLibName)
mainLibSet
exe = Executable {
exeName = mkUnqualComponentName $ stubName test,
modulePath = stubFilePath test,
......
......@@ -146,7 +146,7 @@ import Text.PrettyPrint
import Distribution.Compat.Environment ( lookupEnv )
import Distribution.Compat.Exception ( catchExit, catchIO )
import qualified Data.Set as Set
import qualified Distribution.Compat.NonEmptySet as NonEmptySet
type UseExternalInternalDeps = Bool
......@@ -936,7 +936,7 @@ dependencySatisfiable
then True
else
-- Backward compatibility for the old sublibrary syntax
(sublibs == Set.singleton LMainLibName
(sublibs == mainLibSet
&& Map.member
(pn, CLibName $ LSubLibName $
packageNameToUnqualComponentName depName)
......@@ -1291,10 +1291,10 @@ selectDependency pkgid internalIndex installedIndex requiredDepsMap
case Map.lookup dep_pkgname internalIndex of
Just cname ->
if use_external_internal_deps
then do_external (Just $ maybeToLibraryName cname) <$> Set.toList libs
then do_external (Just $ maybeToLibraryName cname) <$> NonEmptySet.toList libs
else do_internal
_ ->
do_external Nothing <$> Set.toList libs
do_external Nothing <$> NonEmptySet.toList libs
where
-- It's an internal library, and we're not per-component build
......
......@@ -7,14 +7,14 @@ module Distribution.Types.Dependency
, depVerRange
, depLibraries
, simplifyDependency
, mainLibSet
) where
import Distribution.Compat.Prelude
import Prelude ()
import Distribution.Version
(VersionRange, anyVersion, simplifyVersionRange )
import Distribution.Types.VersionRange (isAnyVersionLight)
import Distribution.Version (VersionRange, anyVersion, simplifyVersionRange)
import Distribution.CabalSpecVersion
import Distribution.Compat.CharParsing (char, spaces)
......@@ -26,8 +26,8 @@ import Distribution.Types.PackageName
import Distribution.Types.UnqualComponentName
import Text.PrettyPrint ((<+>))
import qualified Data.Set as Set
import qualified Text.PrettyPrint as PP
import qualified Distribution.Compat.NonEmptySet as NonEmptySet
import qualified Text.PrettyPrint as PP
-- | Describes a dependency on a source package (API)
--
......@@ -37,7 +37,7 @@ import qualified Text.PrettyPrint as PP
data Dependency = Dependency
PackageName
VersionRange
(Set LibraryName)
(NonEmptySet LibraryName)
-- ^ The set of libraries required from the package.
-- Only the selected libraries will be built.
-- It does not affect the cabal-install solver yet.
......@@ -49,7 +49,7 @@ depPkgName (Dependency pn _ _) = pn
depVerRange :: Dependency -> VersionRange
depVerRange (Dependency _ vr _) = vr
depLibraries :: Dependency -> Set LibraryName
depLibraries :: Dependency -> NonEmptySet LibraryName
depLibraries (Dependency _ _ cs) = cs
-- | Smart constructor of 'Dependency'.
......@@ -59,8 +59,8 @@ depLibraries (Dependency _ _ cs) = cs
--
-- @since 3.4.0.0
--
mkDependency :: PackageName -> VersionRange -> Set LibraryName -> Dependency
mkDependency pn vr lb = Dependency pn vr (Set.map conv lb)
mkDependency :: PackageName -> VersionRange -> NonEmptySet LibraryName -> Dependency
mkDependency pn vr lb = Dependency pn vr (NonEmptySet.map conv lb)
where
pn' = packageNameToUnqualComponentName pn
......@@ -80,10 +80,10 @@ instance Pretty Dependency where
| otherwise = pretty ver
withSubLibs doc
| sublibs == mainLib = doc
| sublibs == mainLibSet = doc
| otherwise = doc <<>> PP.colon <<>> PP.braces prettySublibs
prettySublibs = PP.hsep $ PP.punctuate PP.comma $ prettySublib <$> Set.toList sublibs
prettySublibs = PP.hsep $ PP.punctuate PP.comma $ prettySublib <$> NonEmptySet.toList sublibs
prettySublib LMainLibName = PP.text $ unPackageName name
prettySublib (LSubLibName un) = PP.text $ unUnqualComponentName un
......@@ -91,24 +91,24 @@ instance Pretty Dependency where
-- |
--
-- >>> simpleParsec "mylib:sub" :: Maybe Dependency
-- Just (Dependency (PackageName "mylib") (OrLaterVersion (mkVersion [0])) (fromList [LSubLibName (UnqualComponentName "sub")]))
-- Just (Dependency (PackageName "mylib") (OrLaterVersion (mkVersion [0])) (fromNonEmpty (LSubLibName (UnqualComponentName "sub") :| [])))
--
-- >>> simpleParsec "mylib:{sub1,sub2}" :: Maybe Dependency
-- Just (Dependency (PackageName "mylib") (OrLaterVersion (mkVersion [0])) (fromList [LSubLibName (UnqualComponentName "sub1"),LSubLibName (UnqualComponentName "sub2")]))
-- Just (Dependency (PackageName "mylib") (OrLaterVersion (mkVersion [0])) (fromNonEmpty (LSubLibName (UnqualComponentName "sub1") :| [LSubLibName (UnqualComponentName "sub2")])))
--
-- >>> simpleParsec "mylib:{ sub1 , sub2 }" :: Maybe Dependency
-- Just (Dependency (PackageName "mylib") (OrLaterVersion (mkVersion [0])) (fromList [LSubLibName (UnqualComponentName "sub1"),LSubLibName (UnqualComponentName "sub2")]))
-- Just (Dependency (PackageName "mylib") (OrLaterVersion (mkVersion [0])) (fromNonEmpty (LSubLibName (UnqualComponentName "sub1") :| [LSubLibName (UnqualComponentName "sub2")])))
--
-- >>> simpleParsec "mylib:{ sub1 , sub2 } ^>= 42" :: Maybe Dependency
-- Just (Dependency (PackageName "mylib") (MajorBoundVersion (mkVersion [42])) (fromList [LSubLibName (UnqualComponentName "sub1"),LSubLibName (UnqualComponentName "sub2")]))
-- Just (Dependency (PackageName "mylib") (MajorBoundVersion (mkVersion [42])) (fromNonEmpty (LSubLibName (UnqualComponentName "sub1") :| [LSubLibName (UnqualComponentName "sub2")])))
--
-- >>> simpleParsec "mylib:{ } ^>= 42" :: Maybe Dependency
-- Just (Dependency (PackageName "mylib") (MajorBoundVersion (mkVersion [42])) (fromList []))
-- Nothing
--
-- >>> traverse_ print (map simpleParsec ["mylib:mylib", "mylib:{mylib}", "mylib:{mylib,sublib}" ] :: [Maybe Dependency])
-- Just (Dependency (PackageName "mylib") (OrLaterVersion (mkVersion [0])) (fromList [LMainLibName]))
-- Just (Dependency (PackageName "mylib") (OrLaterVersion (mkVersion [0])) (fromList [LMainLibName]))
-- Just (Dependency (PackageName "mylib") (OrLaterVersion (mkVersion [0])) (fromList [LMainLibName,LSubLibName (UnqualComponentName "sublib")]))
-- Just (Dependency (PackageName "mylib") (OrLaterVersion (mkVersion [0])) (fromNonEmpty (LMainLibName :| [])))
-- Just (Dependency (PackageName "mylib") (OrLaterVersion (mkVersion [0])) (fromNonEmpty (LMainLibName :| [])))
-- Just (Dependency (PackageName "mylib") (OrLaterVersion (mkVersion [0])) (fromNonEmpty (LMainLibName :| [LSubLibName (UnqualComponentName "sublib")])))
--
-- Spaces around colon are not allowed:
--
......@@ -118,17 +118,17 @@ instance Pretty Dependency where
-- Sublibrary syntax is accepted since @cabal-version: 3.0@
--
-- >>> map (`simpleParsec'` "mylib:sub") [CabalSpecV2_4, CabalSpecV3_0] :: [Maybe Dependency]
-- [Nothing,Just (Dependency (PackageName "mylib") (OrLaterVersion (mkVersion [0])) (fromList [LSubLibName (UnqualComponentName "sub")]))]
-- [Nothing,Just (Dependency (PackageName "mylib") (OrLaterVersion (mkVersion [0])) (fromNonEmpty (LSubLibName (UnqualComponentName "sub") :| [])))]
--
instance Parsec Dependency where
parsec = do
name <- parsec
libs <- option mainLib $ do
libs <- option mainLibSet $ do
_ <- char ':'
versionGuardMultilibs
parsecWarning PWTExperimental "colon specifier is experimental feature (issue #5660)"
Set.singleton <$> parseLib <|> parseMultipleLibs
NonEmptySet.singleton <$> parseLib <|> parseMultipleLibs
spaces -- https://github.com/haskell/cabal/issues/5846
......@@ -139,7 +139,7 @@ instance Parsec Dependency where
parseMultipleLibs = between
(char '{' *> spaces)
(spaces *> char '}')
(Set.fromList <$> parsecCommaList parseLib)
(NonEmptySet.fromNonEmpty <$> parsecCommaNonEmpty parseLib)
versionGuardMultilibs :: CabalParsing m => m ()
versionGuardMultilibs = do
......@@ -152,8 +152,8 @@ versionGuardMultilibs = do
]
-- | Library set with main library.
mainLib :: Set LibraryName
mainLib = Set.singleton LMainLibName
mainLibSet :: NonEmptySet LibraryName
mainLibSet = NonEmptySet.singleton LMainLibName
-- | Simplify the 'VersionRange' expression in a 'Dependency'.
-- See 'simplifyVersionRange'.
......
......@@ -17,7 +17,7 @@ import qualified Data.Map.Lazy as Map
-- | A map of dependencies. Newtyped since the default monoid instance is not
-- appropriate. The monoid instance uses 'intersectVersionRanges'.
newtype DependencyMap = DependencyMap { unDependencyMap :: Map PackageName (VersionRange, Set LibraryName) }
newtype DependencyMap = DependencyMap { unDependencyMap :: Map PackageName (VersionRange, NonEmptySet LibraryName) }
deriving (Show, Read)
instance Monoid DependencyMap where
......@@ -28,9 +28,9 @@ instance Semigroup DependencyMap where
(DependencyMap a) <> (DependencyMap b) =
DependencyMap (Map.unionWith intersectVersionRangesAndJoinComponents a b)
intersectVersionRangesAndJoinComponents :: (VersionRange, Set LibraryName)
-> (VersionRange, Set LibraryName)
-> (VersionRange, Set LibraryName)
intersectVersionRangesAndJoinComponents :: (VersionRange, NonEmptySet LibraryName)
-> (VersionRange, NonEmptySet LibraryName)
-> (VersionRange, NonEmptySet LibraryName)
intersectVersionRangesAndJoinComponents (va, ca) (vb, cb) =
(intersectVersionRanges va vb, ca <> cb)
......
......@@ -3,6 +3,7 @@
module Distribution.Types.PackageVersionConstraint (
PackageVersionConstraint(..),
thisPackageVersionConstraint,
simplifyPackageVersionConstraint,
) where
import Distribution.Compat.Prelude
......@@ -10,10 +11,11 @@ import Prelude ()
import Distribution.Parsec
import Distribution.Pretty
import Distribution.Types.PackageName
import Distribution.Types.PackageId
import Distribution.Types.PackageName
import Distribution.Types.Version
import Distribution.Types.VersionRange.Internal
import Distribution.Version (simplifyVersionRange)
import qualified Distribution.Compat.CharParsing as P
import Text.PrettyPrint ((<+>))
......@@ -66,3 +68,7 @@ instance Parsec PackageVersionConstraint where
thisPackageVersionConstraint :: PackageIdentifier -> PackageVersionConstraint