diff --git a/Cabal-QuickCheck/src/Test/QuickCheck/Instances/Cabal.hs b/Cabal-QuickCheck/src/Test/QuickCheck/Instances/Cabal.hs index e5b5077d414..91fd47863cf 100644 --- a/Cabal-QuickCheck/src/Test/QuickCheck/Instances/Cabal.hs +++ b/Cabal-QuickCheck/src/Test/QuickCheck/Instances/Cabal.hs @@ -208,6 +208,23 @@ instance Arbitrary Dependency where | (pn', vr', lb') <- shrink (pn, vr, lb) ] +------------------------------------------------------------------------------- +-- Private Dependency +------------------------------------------------------------------------------- + +instance Arbitrary PrivateAlias where + arbitrary = PrivateAlias <$> arbitrary + shrink (PrivateAlias al) = PrivateAlias <$> shrink al +instance Arbitrary PrivateDependency where + arbitrary = PrivateDependency + <$> arbitrary + <*> arbitrary + + shrink (PrivateDependency al dps) = + [ PrivateDependency al' dps' + | (al', dps') <- shrink (al, dps) + ] + ------------------------------------------------------------------------------- -- PackageVersionConstraint ------------------------------------------------------------------------------- diff --git a/Cabal-described/src/Distribution/Described.hs b/Cabal-described/src/Distribution/Described.hs index 717fd6a5c7a..a47126b8247 100644 --- a/Cabal-described/src/Distribution/Described.hs +++ b/Cabal-described/src/Distribution/Described.hs @@ -76,7 +76,7 @@ import Distribution.Types.AbiDependency (AbiDependency) import Distribution.Types.AbiHash (AbiHash) import Distribution.Types.BenchmarkType (BenchmarkType) import Distribution.Types.BuildType (BuildType) -import Distribution.Types.Dependency (Dependency) +import Distribution.Types.Dependency (Dependency, PrivateAlias(..), PrivateDependency) import Distribution.Types.ExecutableScope (ExecutableScope) import Distribution.Types.ExeDependency (ExeDependency) import Distribution.Types.ExposedModule (ExposedModule) @@ -391,6 +391,19 @@ instance Described Dependency where where vr = RENamed "version-range" (describe (Proxy :: Proxy VersionRange)) +instance Described PrivateDependency where + describe _ = REAppend + [ RENamed "alias" (describe (Proxy :: Proxy PrivateAlias)) + , RESpaces1 + , "with" + , RESpaces1 + , reChar '(' + , RESpaces + , REMunch reSpacedComma (describe (Proxy :: Proxy Dependency)) + , RESpaces + , reChar ')' + ] + instance Described ExecutableScope where describe _ = REUnion ["public","private"] @@ -446,6 +459,9 @@ instance Described ModuleName where describe _ = REMunch1 (reChar '.') component where component = RECharSet csUpper <> REMunch reEps (REUnion [RECharSet csAlphaNum, RECharSet (fromString "_'")]) +instance Described PrivateAlias where + describe _ = describe (Proxy :: Proxy ModuleName) + instance Described ModuleReexport where describe _ = RETodo diff --git a/Cabal-syntax/Cabal-syntax.cabal b/Cabal-syntax/Cabal-syntax.cabal index 7cb73b50bae..a1ddd3018df 100644 --- a/Cabal-syntax/Cabal-syntax.cabal +++ b/Cabal-syntax/Cabal-syntax.cabal @@ -135,6 +135,7 @@ library Distribution.Types.Condition Distribution.Types.ConfVar Distribution.Types.Dependency + Distribution.Types.Dependency.Lens Distribution.Types.DependencyMap Distribution.Types.ExeDependency Distribution.Types.Executable diff --git a/Cabal-syntax/src/Distribution/ModuleName.hs b/Cabal-syntax/src/Distribution/ModuleName.hs index 90082d29f06..09f1fddb763 100644 --- a/Cabal-syntax/src/Distribution/ModuleName.hs +++ b/Cabal-syntax/src/Distribution/ModuleName.hs @@ -18,6 +18,7 @@ module Distribution.ModuleName ( ModuleName , fromString , fromComponents + , combineModuleName , components , toFilePath , main @@ -99,12 +100,6 @@ validModuleComponent (c : cs) = isUpper c && all validModuleChar cs instance IsString ModuleName where fromString = ModuleName . toShortText --- | Construct a 'ModuleName' from valid module components, i.e. parts --- separated by dots. -fromComponents :: [String] -> ModuleName -fromComponents comps = fromString (intercalate "." comps) -{-# DEPRECATED fromComponents "Exists for cabal-install only" #-} - -- | The module name @Main@. main :: ModuleName main = ModuleName (fromString "Main") @@ -119,6 +114,19 @@ components mn = split (unModuleName mn) (chunk, []) -> chunk : [] (chunk, _ : rest) -> chunk : split rest +-- | Construct a 'ModuleName' from valid module components, i.e. parts +-- separated by dots. +-- +-- Inverse of 'components', i.e. @fromComponents (components x) = x@ +fromComponents :: [String] -> ModuleName +fromComponents comps = fromString (intercalate "." comps) +{-# DEPRECATED fromComponents "Exists for cabal-install only" #-} + +-- | Append one valid module name onto another valid module name +-- This is used when adding the module suffix to private dependencies +combineModuleName :: ModuleName -> ModuleName -> ModuleName +combineModuleName mn1 mn2 = fromComponents (components mn1 ++ components mn2) + -- | Convert a module name to a file path, but without any file extension. -- For example: -- diff --git a/Cabal-syntax/src/Distribution/PackageDescription/Configuration.hs b/Cabal-syntax/src/Distribution/PackageDescription/Configuration.hs index e811c361221..83cc5633b01 100644 --- a/Cabal-syntax/src/Distribution/PackageDescription/Configuration.hs +++ b/Cabal-syntax/src/Distribution/PackageDescription/Configuration.hs @@ -31,7 +31,6 @@ module Distribution.PackageDescription.Configuration , mapTreeConstrs , transformAllBuildInfos , transformAllBuildDepends - , transformAllBuildDependsN , simplifyWithSysParams ) where @@ -63,6 +62,7 @@ import Distribution.Version import qualified Data.Map.Lazy as Map import Data.Tree (Tree (Node)) +import qualified Distribution.Types.Dependency.Lens as L ------------------------------------------------------------------------------ @@ -187,12 +187,12 @@ resolveWithFlags -- ^ Arch where the installed artifacts will run (host Arch) -> CompilerInfo -- ^ Compiler information - -> [PackageVersionConstraint] + -> [(IsPrivate, PackageVersionConstraint)] -- ^ Additional constraints - -> [CondTree ConfVar [Dependency] PDTagged] - -> ([Dependency] -> DepTestRslt [Dependency]) + -> [CondTree ConfVar Dependencies PDTagged] + -> (Dependencies -> DepTestRslt Dependencies) -- ^ Dependency test function. - -> Either [Dependency] (TargetSet PDTagged, FlagAssignment) + -> Either Dependencies (TargetSet PDTagged, FlagAssignment) -- ^ Either the missing dependencies (error case), or a pair of -- (set of build targets with dependencies, chosen flag assignments) resolveWithFlags dom enabled os arch impl constrs trees checkDeps = @@ -324,7 +324,7 @@ extractConditions f gpkg = ] -- | A map of package constraints that combines version ranges using 'unionVersionRanges'. -newtype DepMapUnion = DepMapUnion {unDepMapUnion :: Map PackageName (VersionRange, NonEmptySet LibraryName)} +newtype DepMapUnion = DepMapUnion {unDepMapUnion :: Map (PackageName, IsPrivate) (VersionRange, NonEmptySet LibraryName)} instance Semigroup DepMapUnion where DepMapUnion x <> DepMapUnion y = @@ -337,12 +337,22 @@ unionVersionRanges' -> (VersionRange, NonEmptySet LibraryName) unionVersionRanges' (vr, cs) (vr', cs') = (unionVersionRanges vr vr', cs <> cs') -toDepMapUnion :: [Dependency] -> DepMapUnion +toDepMapUnion :: Dependencies -> DepMapUnion toDepMapUnion ds = - DepMapUnion $ Map.fromListWith unionVersionRanges' [(p, (vr, cs)) | Dependency p vr cs <- ds] + DepMapUnion $ + Map.fromListWith + unionVersionRanges' + ( [((p, Public), (vr, cs)) | Dependency p vr cs <- publicDependencies ds] + ++ [((p, Private (private_alias d)), (vr, cs)) | d <- privateDependencies ds, Dependency p vr cs <- private_depends d] + ) -fromDepMapUnion :: DepMapUnion -> [Dependency] -fromDepMapUnion m = [Dependency p vr cs | (p, (vr, cs)) <- Map.toList (unDepMapUnion m)] +fromDepMapUnion :: DepMapUnion -> Dependencies +fromDepMapUnion m = + Dependencies + [Dependency p vr cs | ((p, Public), (vr, cs)) <- Map.toList (unDepMapUnion m)] + [PrivateDependency alias deps | (alias, deps) <- Map.toList priv_deps] + where + priv_deps = Map.fromListWith (++) [(sn, [Dependency p vr cs]) | ((p, Private sn), (vr, cs)) <- Map.toList (unDepMapUnion m)] freeVars :: CondTree ConfVar c a -> [FlagName] freeVars t = [f | PackageFlag f <- freeVars' t] @@ -400,8 +410,9 @@ flattenTaggedTargets (TargetSet targets) = foldr untag (Nothing, []) targets | otherwise -> (mb_lib, (n, redoBD c) : comps) (PDNull, x) -> x -- actually this should not happen, but let's be liberal where + deps = fromDepMap depMap redoBD :: L.HasBuildInfo a => a -> a - redoBD = set L.targetBuildDepends $ fromDepMap depMap + redoBD = set L.targetPrivateBuildDepends (privateDependencies deps) . set L.targetBuildDepends (publicDependencies deps) ------------------------------------------------------------------------------ -- Convert GenericPackageDescription to PackageDescription @@ -453,7 +464,7 @@ finalizePD :: FlagAssignment -- ^ Explicitly specified flag assignments -> ComponentRequestedSpec - -> (Dependency -> Bool) + -> (IsPrivate -> Dependency -> Bool) -- ^ Is a given dependency satisfiable from the set of -- available packages? If this is unknown then use -- True. @@ -461,11 +472,11 @@ finalizePD -- ^ The 'Arch' and 'OS' -> CompilerInfo -- ^ Compiler information - -> [PackageVersionConstraint] + -> [(IsPrivate, PackageVersionConstraint)] -- ^ Additional constraints -> GenericPackageDescription -> Either - [Dependency] + Dependencies (PackageDescription, FlagAssignment) -- ^ Either missing dependencies or the resolved package -- description along with the flag assignments chosen. @@ -526,8 +537,11 @@ finalizePD | otherwise -> [b, not b] -- flagDefaults = map (\(n,x:_) -> (n,x)) flagChoices check ds = - let missingDeps = filter (not . satisfyDep) ds - in if null missingDeps + let missingDeps = + Dependencies + (filter (not . satisfyDep Public) (publicDependencies ds)) + (mapMaybe (\(PrivateDependency priv pds) -> case filter (not . satisfyDep (Private priv)) pds of [] -> Nothing; pds' -> Just (PrivateDependency priv pds')) (privateDependencies ds)) + in if null (publicDependencies missingDeps) && null (privateDependencies missingDeps) then DepOk else MissingDeps missingDeps @@ -652,19 +666,8 @@ transformAllBuildDepends -> GenericPackageDescription -> GenericPackageDescription transformAllBuildDepends f = - over (L.traverseBuildInfos . L.targetBuildDepends . traverse) f + over (L.traverseBuildInfos . L.targetPrivateBuildDepends . traverse . L.private_depends . traverse) f + . over (L.traverseBuildInfos . L.targetBuildDepends . traverse) f . over (L.packageDescription . L.setupBuildInfo . traverse . L.setupDepends . traverse) f -- cannot be point-free as normal because of higher rank - . over (\f' -> L.allCondTrees $ traverseCondTreeC f') (map f) - --- | Walk a 'GenericPackageDescription' and apply @f@ to all nested --- @build-depends@ fields. -transformAllBuildDependsN - :: ([Dependency] -> [Dependency]) - -> GenericPackageDescription - -> GenericPackageDescription -transformAllBuildDependsN f = - over (L.traverseBuildInfos . L.targetBuildDepends) f - . over (L.packageDescription . L.setupBuildInfo . traverse . L.setupDepends) f - -- cannot be point-free as normal because of higher rank - . over (\f' -> L.allCondTrees $ traverseCondTreeC f') f + . over (\f' -> L.allCondTrees $ traverseCondTreeC f') (mapDependencies f) diff --git a/Cabal-syntax/src/Distribution/PackageDescription/FieldGrammar.hs b/Cabal-syntax/src/Distribution/PackageDescription/FieldGrammar.hs index db6b7f7607b..1f3e2a90bc2 100644 --- a/Cabal-syntax/src/Distribution/PackageDescription/FieldGrammar.hs +++ b/Cabal-syntax/src/Distribution/PackageDescription/FieldGrammar.hs @@ -171,6 +171,7 @@ libraryFieldGrammar , c (List CommaFSep (Identity LegacyExeDependency) LegacyExeDependency) , c (List CommaFSep (Identity PkgconfigDependency) PkgconfigDependency) , c (List CommaVCat (Identity Dependency) Dependency) + , c (List CommaVCat (Identity PrivateDependency) PrivateDependency) , c (List CommaVCat (Identity Mixin) Mixin) , c (List CommaVCat (Identity ModuleReexport) ModuleReexport) , c (List FSep (MQuoted Extension) Extension) @@ -220,6 +221,7 @@ foreignLibFieldGrammar , c (List CommaFSep (Identity ExeDependency) ExeDependency) , c (List CommaFSep (Identity LegacyExeDependency) LegacyExeDependency) , c (List CommaFSep (Identity PkgconfigDependency) PkgconfigDependency) + , c (List CommaVCat (Identity PrivateDependency) PrivateDependency) , c (List CommaVCat (Identity Dependency) Dependency) , c (List CommaVCat (Identity Mixin) Mixin) , c (List FSep (Identity ForeignLibOption) ForeignLibOption) @@ -260,6 +262,7 @@ executableFieldGrammar , c (List CommaFSep (Identity LegacyExeDependency) LegacyExeDependency) , c (List CommaFSep (Identity PkgconfigDependency) PkgconfigDependency) , c (List CommaVCat (Identity Dependency) Dependency) + , c (List CommaVCat (Identity PrivateDependency) PrivateDependency) , c (List CommaVCat (Identity Mixin) Mixin) , c (List FSep (MQuoted Extension) Extension) , c (List FSep (MQuoted Language) Language) @@ -336,6 +339,7 @@ testSuiteFieldGrammar , c (List CommaFSep (Identity PkgconfigDependency) PkgconfigDependency) , c (List CommaFSep Token String) , c (List CommaVCat (Identity Dependency) Dependency) + , c (List CommaVCat (Identity PrivateDependency) PrivateDependency) , c (List CommaVCat (Identity Mixin) Mixin) , c (List FSep (MQuoted Extension) Extension) , c (List FSep (MQuoted Language) Language) @@ -480,6 +484,7 @@ benchmarkFieldGrammar , c (List CommaFSep (Identity LegacyExeDependency) LegacyExeDependency) , c (List CommaFSep (Identity PkgconfigDependency) PkgconfigDependency) , c (List CommaVCat (Identity Dependency) Dependency) + , c (List CommaVCat (Identity PrivateDependency) PrivateDependency) , c (List CommaVCat (Identity Mixin) Mixin) , c (List FSep (MQuoted Extension) Extension) , c (List FSep (MQuoted Language) Language) @@ -582,6 +587,7 @@ buildInfoFieldGrammar , c (List CommaFSep (Identity LegacyExeDependency) LegacyExeDependency) , c (List CommaFSep (Identity PkgconfigDependency) PkgconfigDependency) , c (List CommaVCat (Identity Dependency) Dependency) + , c (List CommaVCat (Identity PrivateDependency) PrivateDependency) , c (List CommaVCat (Identity Mixin) Mixin) , c (List FSep (MQuoted Extension) Extension) , c (List FSep (MQuoted Language) Language) @@ -676,6 +682,7 @@ buildInfoFieldGrammar = <*> pure mempty -- static-options ??? <*> prefixedFields "x-" L.customFieldsBI <*> monoidalFieldAla "build-depends" formatDependencyList L.targetBuildDepends + <*> monoidalFieldAla "private-build-depends" formatPrivateDependencyList L.targetPrivateBuildDepends <*> monoidalFieldAla "mixins" formatMixinList L.mixins ^^^ availableSince CabalSpecV2_0 [] {-# SPECIALIZE buildInfoFieldGrammar :: ParsecFieldGrammar' BuildInfo #-} @@ -800,6 +807,9 @@ setupBInfoFieldGrammar def = formatDependencyList :: [Dependency] -> List CommaVCat (Identity Dependency) Dependency formatDependencyList = alaList CommaVCat +formatPrivateDependencyList :: [PrivateDependency] -> List CommaVCat (Identity PrivateDependency) PrivateDependency +formatPrivateDependencyList = alaList CommaVCat + formatMixinList :: [Mixin] -> List CommaVCat (Identity Mixin) Mixin formatMixinList = alaList CommaVCat diff --git a/Cabal-syntax/src/Distribution/PackageDescription/Parsec.hs b/Cabal-syntax/src/Distribution/PackageDescription/Parsec.hs index ae4c0cfec6b..3294fb4fec1 100644 --- a/Cabal-syntax/src/Distribution/PackageDescription/Parsec.hs +++ b/Cabal-syntax/src/Distribution/PackageDescription/Parsec.hs @@ -64,6 +64,7 @@ import qualified Data.Set as Set import qualified Distribution.Compat.Newtype as Newtype import qualified Distribution.Compat.NonEmptySet as NES import qualified Distribution.Types.BuildInfo.Lens as L +import qualified Distribution.Types.Dependency.Lens as L import qualified Distribution.Types.Executable.Lens as L import qualified Distribution.Types.ForeignLib.Lens as L import qualified Distribution.Types.GenericPackageDescription.Lens as L @@ -264,7 +265,7 @@ goSections specVer = traverse_ process -> Map String CondTreeBuildInfo -- \^ common stanzas -> [Field Position] - -> ParseResult (CondTree ConfVar [Dependency] a) + -> ParseResult (CondTree ConfVar Dependencies a) parseCondTree' = parseCondTreeWithCommonStanzas specVer parseSection :: Name Position -> [SectionArg Position] -> [Field Position] -> SectionParser () @@ -480,10 +481,10 @@ parseCondTree -- ^ common stanzas -> (BuildInfo -> a) -- ^ constructor from buildInfo - -> (a -> [Dependency]) + -> (a -> Dependencies) -- ^ condition extractor -> [Field Position] - -> ParseResult (CondTree ConfVar [Dependency] a) + -> ParseResult (CondTree ConfVar Dependencies a) parseCondTree v hasElif grammar commonStanzas fromBuildInfo cond = go where go fields0 = do @@ -497,7 +498,7 @@ parseCondTree v hasElif grammar commonStanzas fromBuildInfo cond = go branches <- concat <$> traverse parseIfs ss return $ endo $ CondNode x (cond x) branches - parseIfs :: [Section Position] -> ParseResult [CondBranch ConfVar [Dependency] a] + parseIfs :: [Section Position] -> ParseResult [CondBranch ConfVar Dependencies a] parseIfs [] = return [] parseIfs (MkSection (Name _ name) test fields : sections) | name == "if" = do test' <- parseConditionConfVar test @@ -510,7 +511,7 @@ parseCondTree v hasElif grammar commonStanzas fromBuildInfo cond = go parseElseIfs :: [Section Position] - -> ParseResult (Maybe (CondTree ConfVar [Dependency] a), [CondBranch ConfVar [Dependency] a]) + -> ParseResult (Maybe (CondTree ConfVar Dependencies a), [CondBranch ConfVar Dependencies a]) parseElseIfs [] = return (Nothing, []) parseElseIfs (MkSection (Name pos name) args fields : sections) | name == "else" = do unless (null args) $ @@ -589,7 +590,7 @@ with new AST, this all need to be rewritten. -- The approach is simple, and have good properties: -- -- * Common stanzas are parsed exactly once, even if not-used. Thus we report errors in them. -type CondTreeBuildInfo = CondTree ConfVar [Dependency] BuildInfo +type CondTreeBuildInfo = CondTree ConfVar Dependencies BuildInfo -- | Create @a@ from 'BuildInfo'. -- This class is used to implement common stanza parsing. @@ -631,10 +632,10 @@ parseCondTreeWithCommonStanzas -> Map String CondTreeBuildInfo -- ^ common stanzas -> [Field Position] - -> ParseResult (CondTree ConfVar [Dependency] a) + -> ParseResult (CondTree ConfVar Dependencies a) parseCondTreeWithCommonStanzas v grammar fromBuildInfo commonStanzas fields = do (fields', endo) <- processImports v fromBuildInfo commonStanzas fields - x <- parseCondTree v hasElif grammar commonStanzas fromBuildInfo (view L.targetBuildDepends) fields' + x <- parseCondTree v hasElif grammar commonStanzas fromBuildInfo (\bi -> Dependencies (view L.targetBuildDepends bi) (view L.targetPrivateBuildDepends bi)) fields' return (endo x) where hasElif = specHasElif v @@ -648,7 +649,7 @@ processImports -> Map String CondTreeBuildInfo -- ^ common stanzas -> [Field Position] - -> ParseResult ([Field Position], CondTree ConfVar [Dependency] a -> CondTree ConfVar [Dependency] a) + -> ParseResult ([Field Position], CondTree ConfVar Dependencies a -> CondTree ConfVar Dependencies a) processImports v fromBuildInfo commonStanzas = go [] where hasCommonStanzas = specHasCommonStanzas v @@ -691,11 +692,11 @@ warnImport _ f = pure (Just f) mergeCommonStanza :: L.HasBuildInfo a => (BuildInfo -> a) - -> CondTree ConfVar [Dependency] BuildInfo - -> CondTree ConfVar [Dependency] a - -> CondTree ConfVar [Dependency] a + -> CondTree ConfVar Dependencies BuildInfo + -> CondTree ConfVar Dependencies a + -> CondTree ConfVar Dependencies a mergeCommonStanza fromBuildInfo (CondNode bi _ bis) (CondNode x _ cs) = - CondNode x' (x' ^. L.targetBuildDepends) cs' + CondNode x' (Dependencies (view L.targetBuildDepends x') (view L.targetPrivateBuildDepends x')) cs' where -- new value is old value with buildInfo field _prepended_. x' = x & L.buildInfo %~ (bi <>) @@ -814,7 +815,8 @@ postProcessInternalDeps specVer gpd where transformBI :: BuildInfo -> BuildInfo transformBI = - over L.targetBuildDepends (concatMap transformD) + over (L.targetPrivateBuildDepends . traverse . L.private_depends) (concatMap transformD) + . over L.targetBuildDepends (concatMap transformD) . over L.mixins (map transformM) transformSBI :: SetupBuildInfo -> SetupBuildInfo diff --git a/Cabal-syntax/src/Distribution/PackageDescription/PrettyPrint.hs b/Cabal-syntax/src/Distribution/PackageDescription/PrettyPrint.hs index b03b1b99ada..425b273aeb2 100644 --- a/Cabal-syntax/src/Distribution/PackageDescription/PrettyPrint.hs +++ b/Cabal-syntax/src/Distribution/PackageDescription/PrettyPrint.hs @@ -61,6 +61,7 @@ import Text.PrettyPrint (Doc, char, hsep, parens, text) import qualified Data.ByteString.Lazy.Char8 as BS.Char8 import qualified Distribution.Compat.NonEmptySet as NES +import qualified Distribution.Types.Dependency.Lens as L -- | Writes a .cabal file from a generic package description writeGenericPackageDescription :: FilePath -> GenericPackageDescription -> IO () @@ -121,7 +122,7 @@ ppFlag v flag@(MkPackageFlag name _ _ _) = PrettySection () "flag" [ppFlagName name] $ prettyFieldGrammar v (flagFieldGrammar name) flag -ppCondTree2 :: CabalSpecVersion -> PrettyFieldGrammar' s -> CondTree ConfVar [Dependency] s -> [PrettyField ()] +ppCondTree2 :: CabalSpecVersion -> PrettyFieldGrammar' s -> CondTree ConfVar Dependencies s -> [PrettyField ()] ppCondTree2 v grammar = go where -- TODO: recognise elif opportunities @@ -140,42 +141,42 @@ ppCondTree2 v grammar = go , PrettySection () "else" [] (go elseTree) ] -ppCondLibrary :: CabalSpecVersion -> Maybe (CondTree ConfVar [Dependency] Library) -> [PrettyField ()] +ppCondLibrary :: CabalSpecVersion -> Maybe (CondTree ConfVar Dependencies Library) -> [PrettyField ()] ppCondLibrary _ Nothing = mempty ppCondLibrary v (Just condTree) = pure $ PrettySection () "library" [] $ ppCondTree2 v (libraryFieldGrammar LMainLibName) condTree -ppCondSubLibraries :: CabalSpecVersion -> [(UnqualComponentName, CondTree ConfVar [Dependency] Library)] -> [PrettyField ()] +ppCondSubLibraries :: CabalSpecVersion -> [(UnqualComponentName, CondTree ConfVar Dependencies Library)] -> [PrettyField ()] ppCondSubLibraries v libs = [ PrettySection () "library" [pretty n] $ ppCondTree2 v (libraryFieldGrammar $ LSubLibName n) condTree | (n, condTree) <- libs ] -ppCondForeignLibs :: CabalSpecVersion -> [(UnqualComponentName, CondTree ConfVar [Dependency] ForeignLib)] -> [PrettyField ()] +ppCondForeignLibs :: CabalSpecVersion -> [(UnqualComponentName, CondTree ConfVar Dependencies ForeignLib)] -> [PrettyField ()] ppCondForeignLibs v flibs = [ PrettySection () "foreign-library" [pretty n] $ ppCondTree2 v (foreignLibFieldGrammar n) condTree | (n, condTree) <- flibs ] -ppCondExecutables :: CabalSpecVersion -> [(UnqualComponentName, CondTree ConfVar [Dependency] Executable)] -> [PrettyField ()] +ppCondExecutables :: CabalSpecVersion -> [(UnqualComponentName, CondTree ConfVar Dependencies Executable)] -> [PrettyField ()] ppCondExecutables v exes = [ PrettySection () "executable" [pretty n] $ ppCondTree2 v (executableFieldGrammar n) condTree | (n, condTree) <- exes ] -ppCondTestSuites :: CabalSpecVersion -> [(UnqualComponentName, CondTree ConfVar [Dependency] TestSuite)] -> [PrettyField ()] +ppCondTestSuites :: CabalSpecVersion -> [(UnqualComponentName, CondTree ConfVar Dependencies TestSuite)] -> [PrettyField ()] ppCondTestSuites v suites = [ PrettySection () "test-suite" [pretty n] $ ppCondTree2 v testSuiteFieldGrammar (fmap FG.unvalidateTestSuite condTree) | (n, condTree) <- suites ] -ppCondBenchmarks :: CabalSpecVersion -> [(UnqualComponentName, CondTree ConfVar [Dependency] Benchmark)] -> [PrettyField ()] +ppCondBenchmarks :: CabalSpecVersion -> [(UnqualComponentName, CondTree ConfVar Dependencies Benchmark)] -> [PrettyField ()] ppCondBenchmarks v suites = [ PrettySection () "benchmark" [pretty n] $ ppCondTree2 v benchmarkFieldGrammar (fmap FG.unvalidateBenchmark condTree) @@ -239,16 +240,16 @@ pdToGpd pd = , condBenchmarks = mkCondTree' benchmarkName <$> benchmarks pd } where - -- We set CondTree's [Dependency] to an empty list, as it + -- We set CondTree's Dependencies to an empty list, as it -- is not pretty printed anyway. - mkCondTree x = CondNode x [] [] - mkCondTreeL l = (fromMaybe (mkUnqualComponentName "") (libraryNameString (libName l)), CondNode l [] []) + mkCondTree x = CondNode x mempty mempty + mkCondTreeL l = (fromMaybe (mkUnqualComponentName "") (libraryNameString (libName l)), CondNode l mempty mempty) mkCondTree' :: (a -> UnqualComponentName) -> a - -> (UnqualComponentName, CondTree ConfVar [Dependency] a) - mkCondTree' f x = (f x, CondNode x [] []) + -> (UnqualComponentName, CondTree ConfVar Dependencies a) + mkCondTree' f x = (f x, CondNode x mempty []) ------------------------------------------------------------------------------- -- Internal libs @@ -263,7 +264,8 @@ preProcessInternalDeps specVer gpd where transformBI :: BuildInfo -> BuildInfo transformBI = - over L.targetBuildDepends (concatMap transformD) + over (L.targetPrivateBuildDepends . traverse . L.private_depends) (concatMap transformD) + . over L.targetBuildDepends (concatMap transformD) . over L.mixins (map transformM) transformSBI :: SetupBuildInfo -> SetupBuildInfo diff --git a/Cabal-syntax/src/Distribution/Types/BuildInfo.hs b/Cabal-syntax/src/Distribution/Types/BuildInfo.hs index da1f8aea88f..5fd8e737b9f 100644 --- a/Cabal-syntax/src/Distribution/Types/BuildInfo.hs +++ b/Cabal-syntax/src/Distribution/Types/BuildInfo.hs @@ -140,6 +140,7 @@ data BuildInfo = BuildInfo -- simple assoc-list. , targetBuildDepends :: [Dependency] -- ^ Dependencies specific to a library or executable target + , targetPrivateBuildDepends :: [PrivateDependency] , mixins :: [Mixin] } deriving (Generic, Show, Read, Eq, Ord, Typeable, Data) @@ -196,6 +197,7 @@ instance Monoid BuildInfo where , staticOptions = mempty , customFieldsBI = [] , targetBuildDepends = [] + , targetPrivateBuildDepends = [] , mixins = [] } mappend = (<>) @@ -248,6 +250,7 @@ instance Semigroup BuildInfo where , staticOptions = combine staticOptions , customFieldsBI = combine customFieldsBI , targetBuildDepends = combineNub targetBuildDepends + , targetPrivateBuildDepends = combineNub targetPrivateBuildDepends , mixins = combine mixins } where diff --git a/Cabal-syntax/src/Distribution/Types/BuildInfo/Lens.hs b/Cabal-syntax/src/Distribution/Types/BuildInfo/Lens.hs index 19453a671b9..84b49ad7bb1 100644 --- a/Cabal-syntax/src/Distribution/Types/BuildInfo/Lens.hs +++ b/Cabal-syntax/src/Distribution/Types/BuildInfo/Lens.hs @@ -13,7 +13,7 @@ import Prelude () import Distribution.Compiler (PerCompilerFlavor) import Distribution.ModuleName (ModuleName) import Distribution.Types.BuildInfo (BuildInfo) -import Distribution.Types.Dependency (Dependency) +import Distribution.Types.Dependency (Dependency, PrivateDependency) import Distribution.Types.ExeDependency (ExeDependency) import Distribution.Types.LegacyExeDependency (LegacyExeDependency) import Distribution.Types.Mixin (Mixin) @@ -207,6 +207,10 @@ class HasBuildInfo a where targetBuildDepends = buildInfo . targetBuildDepends {-# INLINE targetBuildDepends #-} + targetPrivateBuildDepends :: Lens' a [PrivateDependency] + targetPrivateBuildDepends = buildInfo . targetPrivateBuildDepends + {-# INLINE targetPrivateBuildDepends #-} + mixins :: Lens' a [Mixin] mixins = buildInfo . mixins {-# INLINE mixins #-} @@ -350,6 +354,9 @@ instance HasBuildInfo BuildInfo where targetBuildDepends f s = fmap (\x -> s{T.targetBuildDepends = x}) (f (T.targetBuildDepends s)) {-# INLINE targetBuildDepends #-} + targetPrivateBuildDepends f s = fmap (\x -> s{T.targetPrivateBuildDepends = x}) (f (T.targetPrivateBuildDepends s)) + {-# INLINE targetPrivateBuildDepends #-} + mixins f s = fmap (\x -> s{T.mixins = x}) (f (T.mixins s)) {-# INLINE mixins #-} diff --git a/Cabal-syntax/src/Distribution/Types/ComponentName.hs b/Cabal-syntax/src/Distribution/Types/ComponentName.hs index 01ed6f7655f..2b791bb50cc 100644 --- a/Cabal-syntax/src/Distribution/Types/ComponentName.hs +++ b/Cabal-syntax/src/Distribution/Types/ComponentName.hs @@ -8,6 +8,7 @@ module Distribution.Types.ComponentName , componentNameRaw , componentNameStanza , componentNameString + , NotLibComponentName (..) ) where import Distribution.Compat.Prelude diff --git a/Cabal-syntax/src/Distribution/Types/Dependency.hs b/Cabal-syntax/src/Distribution/Types/Dependency.hs index 10d0506b57e..63c5e196d7f 100644 --- a/Cabal-syntax/src/Distribution/Types/Dependency.hs +++ b/Cabal-syntax/src/Distribution/Types/Dependency.hs @@ -1,5 +1,8 @@ {-# LANGUAGE DeriveDataTypeable #-} {-# LANGUAGE DeriveGeneric #-} +{-# LANGUAGE InstanceSigs #-} +{-# LANGUAGE LambdaCase #-} +{-# LANGUAGE ScopedTypeVariables #-} module Distribution.Types.Dependency ( Dependency (..) @@ -9,6 +12,12 @@ module Distribution.Types.Dependency , depLibraries , simplifyDependency , mainLibSet + , PrivateDependency (..) + , PrivateAlias (..) + , Dependencies (..) + , IsPrivate (..) + , mapDependencies + , foldIsPrivate ) where import Distribution.Compat.Prelude @@ -26,9 +35,55 @@ import Distribution.Types.LibraryName import Distribution.Types.PackageName import Distribution.Types.UnqualComponentName +import qualified Distribution.Compat.CharParsing as P import qualified Distribution.Compat.NonEmptySet as NES +import Distribution.ModuleName import qualified Text.PrettyPrint as PP +data IsPrivate = Private PrivateAlias | Public deriving (Show, Ord, Read, Eq, Generic, Data) + +data Dependencies = Dependencies {publicDependencies :: [Dependency], privateDependencies :: [PrivateDependency]} deriving (Eq, Show, Generic, Data) + +newtype PrivateAlias = PrivateAlias ModuleName deriving (Show, Eq, Generic, Data, Read, Ord) + +instance Pretty PrivateAlias where + pretty (PrivateAlias p) = pretty p + +instance Parsec PrivateAlias where + parsec = PrivateAlias <$> parsec + +-- | Construct a 'PrivateAlias' from a valid module name 'String'. +-- +-- This is just a convenience function intended for valid module strings. It is +-- an error if it is used with a string that is not a valid module name. If you +-- are parsing user input then use 'Distribution.Text.simpleParse' instead. +instance IsString PrivateAlias where + fromString = PrivateAlias . fromString + +data PrivateDependency = PrivateDependency {private_alias :: PrivateAlias, private_depends :: [Dependency]} deriving (Eq, Show, Generic, Data, Read, Ord) + +instance Parsec PrivateDependency where + parsec = do + alias <- parsec + P.spaces + _ <- P.string "with" + P.spaces + let parensLax p = P.between (P.char '(' >> P.spaces) (P.char ')' >> P.spaces) p + deps <- parensLax (parsecCommaList parsec) + return (PrivateDependency alias deps) + +instance Pretty PrivateDependency where + pretty (PrivateDependency alias deps) = PP.hsep [pretty alias, PP.text "with", PP.parens (PP.hsep (PP.punctuate PP.comma (map pretty deps)))] + +instance Semigroup Dependencies where + (Dependencies p1 pr1) <> (Dependencies p2 pr2) = Dependencies (p1 <> p2) (pr1 <> pr2) + +instance Monoid Dependencies where + mempty = Dependencies mempty mempty + +mapDependencies :: (Dependency -> Dependency) -> Dependencies -> Dependencies +mapDependencies f (Dependencies pub priv) = Dependencies (map f pub) (map (\d -> d{private_depends = map f (private_depends d)}) priv) + -- | Describes a dependency on a source package (API) -- -- /Invariant:/ package name does not appear as 'LSubLibName' in @@ -72,10 +127,26 @@ mkDependency pn vr lb = Dependency pn vr (NES.map conv lb) | ln == pn' = LMainLibName | otherwise = l +instance Binary IsPrivate +instance Structured IsPrivate +instance NFData IsPrivate where rnf = genericRnf + instance Binary Dependency instance Structured Dependency instance NFData Dependency where rnf = genericRnf +instance Binary PrivateDependency +instance Structured PrivateDependency +instance NFData PrivateDependency where rnf = genericRnf + +instance Binary PrivateAlias +instance Structured PrivateAlias +instance NFData PrivateAlias where rnf = genericRnf + +instance Binary Dependencies +instance Structured Dependencies +instance NFData Dependencies where rnf = genericRnf + -- | -- -- >>> prettyShow $ Dependency (mkPackageName "pkg") anyVersion mainLibSet @@ -139,6 +210,7 @@ instance Pretty Dependency where -- >>> map (`simpleParsec'` "mylib:sub") [CabalSpecV2_4, CabalSpecV3_0] :: [Maybe Dependency] -- [Nothing,Just (Dependency (PackageName "mylib") (OrLaterVersion (mkVersion [0])) (fromNonEmpty (LSubLibName (UnqualComponentName "sub") :| [])))] instance Parsec Dependency where + parsec :: forall m. CabalParsing m => m Dependency parsec = do name <- parsec @@ -181,3 +253,9 @@ mainLibSet = NES.singleton LMainLibName simplifyDependency :: Dependency -> Dependency simplifyDependency (Dependency name range comps) = Dependency name (simplifyVersionRange range) comps + +-- | Deconstruct 'IsPrivate' using a function on a 'PrivateAlias' or a default value; akin to 'maybe'. +foldIsPrivate :: a -> (PrivateAlias -> a) -> IsPrivate -> a +foldIsPrivate d f = \case + Public -> d + Private a -> f a diff --git a/Cabal-syntax/src/Distribution/Types/Dependency/Lens.hs b/Cabal-syntax/src/Distribution/Types/Dependency/Lens.hs new file mode 100644 index 00000000000..8dfb9d5bd27 --- /dev/null +++ b/Cabal-syntax/src/Distribution/Types/Dependency/Lens.hs @@ -0,0 +1,14 @@ +module Distribution.Types.Dependency.Lens + ( private_depends + ) where + +import Distribution.Compat.Lens +import Distribution.Compat.Prelude +import Prelude () + +import Distribution.Types.Dependency (Dependency, PrivateDependency) + +import qualified Distribution.Types.Dependency as T + +private_depends :: Lens' PrivateDependency [Dependency] +private_depends f d = fmap (\x -> d{T.private_depends = x}) (f (T.private_depends d)) diff --git a/Cabal-syntax/src/Distribution/Types/DependencyMap.hs b/Cabal-syntax/src/Distribution/Types/DependencyMap.hs index aebca2c4cbf..c7175d21404 100644 --- a/Cabal-syntax/src/Distribution/Types/DependencyMap.hs +++ b/Cabal-syntax/src/Distribution/Types/DependencyMap.hs @@ -18,7 +18,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, NonEmptySet LibraryName)} +newtype DependencyMap = DependencyMap {unDependencyMap :: Map (PackageName, IsPrivate) (VersionRange, NonEmptySet LibraryName)} deriving (Show, Read, Eq) instance Monoid DependencyMap where @@ -36,12 +36,22 @@ intersectVersionRangesAndJoinComponents intersectVersionRangesAndJoinComponents (va, ca) (vb, cb) = (intersectVersionRanges va vb, ca <> cb) -toDepMap :: [Dependency] -> DependencyMap +toDepMap :: Dependencies -> DependencyMap toDepMap ds = - DependencyMap $ Map.fromListWith intersectVersionRangesAndJoinComponents [(p, (vr, cs)) | Dependency p vr cs <- ds] + DependencyMap $ + Map.fromListWith + intersectVersionRangesAndJoinComponents + ( [((p, Public), (vr, cs)) | Dependency p vr cs <- publicDependencies ds] + ++ [((p, Private pn), (vr, cs)) | PrivateDependency pn pds <- privateDependencies ds, Dependency p vr cs <- pds] + ) -fromDepMap :: DependencyMap -> [Dependency] -fromDepMap m = [Dependency p vr cs | (p, (vr, cs)) <- Map.toList (unDependencyMap m)] +fromDepMap :: DependencyMap -> Dependencies +fromDepMap m = + Dependencies + [Dependency p vr cs | ((p, Public), (vr, cs)) <- Map.toList (unDependencyMap m)] + [PrivateDependency alias deps | (alias, deps) <- Map.toList priv_deps] + where + priv_deps = Map.fromListWith (++) [(sn, [Dependency p vr cs]) | ((p, (Private sn)), (vr, cs)) <- Map.toList (unDependencyMap m)] -- Apply extra constraints to a dependency map. -- Combines dependencies where the result will only contain keys from the left @@ -49,11 +59,11 @@ fromDepMap m = [Dependency p vr cs | (p, (vr, cs)) <- Map.toList (unDependencyMa -- be intersected. constrainBy :: DependencyMap - -> [PackageVersionConstraint] + -> [(IsPrivate, PackageVersionConstraint)] -> DependencyMap constrainBy = foldl' tightenConstraint where - tightenConstraint (DependencyMap l) (PackageVersionConstraint pn vr) = DependencyMap $ - case Map.lookup pn l of + tightenConstraint (DependencyMap l) (ip, PackageVersionConstraint pn vr) = DependencyMap $ + case Map.lookup (pn, ip) l of Nothing -> l - Just (vr', cs) -> Map.insert pn (intersectVersionRanges vr' vr, cs) l + Just (vr', cs) -> Map.insert (pn, ip) (intersectVersionRanges vr' vr, cs) l diff --git a/Cabal-syntax/src/Distribution/Types/GenericPackageDescription.hs b/Cabal-syntax/src/Distribution/Types/GenericPackageDescription.hs index 55ec8652304..312db47053b 100644 --- a/Cabal-syntax/src/Distribution/Types/GenericPackageDescription.hs +++ b/Cabal-syntax/src/Distribution/Types/GenericPackageDescription.hs @@ -44,30 +44,30 @@ data GenericPackageDescription = GenericPackageDescription -- Perfectly, PackageIndex should have sum type, so we don't need to -- have dummy GPDs. , genPackageFlags :: [PackageFlag] - , condLibrary :: Maybe (CondTree ConfVar [Dependency] Library) + , condLibrary :: Maybe (CondTree ConfVar Dependencies Library) , condSubLibraries :: [ ( UnqualComponentName - , CondTree ConfVar [Dependency] Library + , CondTree ConfVar Dependencies Library ) ] , condForeignLibs :: [ ( UnqualComponentName - , CondTree ConfVar [Dependency] ForeignLib + , CondTree ConfVar Dependencies ForeignLib ) ] , condExecutables :: [ ( UnqualComponentName - , CondTree ConfVar [Dependency] Executable + , CondTree ConfVar Dependencies Executable ) ] , condTestSuites :: [ ( UnqualComponentName - , CondTree ConfVar [Dependency] TestSuite + , CondTree ConfVar Dependencies TestSuite ) ] , condBenchmarks :: [ ( UnqualComponentName - , CondTree ConfVar [Dependency] Benchmark + , CondTree ConfVar Dependencies Benchmark ) ] } @@ -99,15 +99,15 @@ instance L.HasBuildInfos GenericPackageDescription where <*> (traverse . L._2 . traverseCondTreeBuildInfo) f x5 <*> (traverse . L._2 . traverseCondTreeBuildInfo) f x6 --- We use this traversal to keep [Dependency] field in CondTree up to date. +-- We use this traversal to keep Dependencies field in CondTree up to date. traverseCondTreeBuildInfo :: forall f comp v . (Applicative f, L.HasBuildInfo comp) - => LensLike' f (CondTree v [Dependency] comp) L.BuildInfo + => LensLike' f (CondTree v Dependencies comp) L.BuildInfo traverseCondTreeBuildInfo g = node where - mkCondNode :: comp -> [CondBranch v [Dependency] comp] -> CondTree v [Dependency] comp - mkCondNode comp = CondNode comp (view L.targetBuildDepends comp) + mkCondNode :: comp -> [CondBranch v Dependencies comp] -> CondTree v Dependencies comp + mkCondNode comp = CondNode comp (Dependencies (view L.targetBuildDepends comp) (view L.targetPrivateBuildDepends comp)) node (CondNode comp _ branches) = mkCondNode diff --git a/Cabal-syntax/src/Distribution/Types/GenericPackageDescription/Lens.hs b/Cabal-syntax/src/Distribution/Types/GenericPackageDescription/Lens.hs index 213c97128f9..9d6ad5d2a2b 100644 --- a/Cabal-syntax/src/Distribution/Types/GenericPackageDescription/Lens.hs +++ b/Cabal-syntax/src/Distribution/Types/GenericPackageDescription/Lens.hs @@ -22,7 +22,7 @@ import Distribution.System (Arch, OS) import Distribution.Types.Benchmark (Benchmark) import Distribution.Types.CondTree (CondTree) import Distribution.Types.ConfVar (ConfVar (..)) -import Distribution.Types.Dependency (Dependency) +import Distribution.Types.Dependency (Dependencies) import Distribution.Types.Executable (Executable) import Distribution.Types.Flag (FlagName, PackageFlag (MkPackageFlag)) import Distribution.Types.ForeignLib (ForeignLib) @@ -49,35 +49,35 @@ genPackageFlags :: Lens' GenericPackageDescription [PackageFlag] genPackageFlags f s = fmap (\x -> s{T.genPackageFlags = x}) (f (T.genPackageFlags s)) {-# INLINE genPackageFlags #-} -condLibrary :: Lens' GenericPackageDescription (Maybe (CondTree ConfVar [Dependency] Library)) +condLibrary :: Lens' GenericPackageDescription (Maybe (CondTree ConfVar Dependencies Library)) condLibrary f s = fmap (\x -> s{T.condLibrary = x}) (f (T.condLibrary s)) {-# INLINE condLibrary #-} -condSubLibraries :: Lens' GenericPackageDescription [(UnqualComponentName, (CondTree ConfVar [Dependency] Library))] +condSubLibraries :: Lens' GenericPackageDescription [(UnqualComponentName, (CondTree ConfVar Dependencies Library))] condSubLibraries f s = fmap (\x -> s{T.condSubLibraries = x}) (f (T.condSubLibraries s)) {-# INLINE condSubLibraries #-} -condForeignLibs :: Lens' GenericPackageDescription [(UnqualComponentName, (CondTree ConfVar [Dependency] ForeignLib))] +condForeignLibs :: Lens' GenericPackageDescription [(UnqualComponentName, (CondTree ConfVar Dependencies ForeignLib))] condForeignLibs f s = fmap (\x -> s{T.condForeignLibs = x}) (f (T.condForeignLibs s)) {-# INLINE condForeignLibs #-} -condExecutables :: Lens' GenericPackageDescription [(UnqualComponentName, (CondTree ConfVar [Dependency] Executable))] +condExecutables :: Lens' GenericPackageDescription [(UnqualComponentName, (CondTree ConfVar Dependencies Executable))] condExecutables f s = fmap (\x -> s{T.condExecutables = x}) (f (T.condExecutables s)) {-# INLINE condExecutables #-} -condTestSuites :: Lens' GenericPackageDescription [(UnqualComponentName, (CondTree ConfVar [Dependency] TestSuite))] +condTestSuites :: Lens' GenericPackageDescription [(UnqualComponentName, (CondTree ConfVar Dependencies TestSuite))] condTestSuites f s = fmap (\x -> s{T.condTestSuites = x}) (f (T.condTestSuites s)) {-# INLINE condTestSuites #-} -condBenchmarks :: Lens' GenericPackageDescription [(UnqualComponentName, (CondTree ConfVar [Dependency] Benchmark))] +condBenchmarks :: Lens' GenericPackageDescription [(UnqualComponentName, (CondTree ConfVar Dependencies Benchmark))] condBenchmarks f s = fmap (\x -> s{T.condBenchmarks = x}) (f (T.condBenchmarks s)) {-# INLINE condBenchmarks #-} allCondTrees :: Applicative f => ( forall a - . CondTree ConfVar [Dependency] a - -> f (CondTree ConfVar [Dependency] a) + . CondTree ConfVar Dependencies a + -> f (CondTree ConfVar Dependencies a) ) -> GenericPackageDescription -> f GenericPackageDescription diff --git a/Cabal-syntax/src/Distribution/Types/PackageDescription.hs b/Cabal-syntax/src/Distribution/Types/PackageDescription.hs index a3f1d0c33da..b994f9c8813 100644 --- a/Cabal-syntax/src/Distribution/Types/PackageDescription.hs +++ b/Cabal-syntax/src/Distribution/Types/PackageDescription.hs @@ -60,8 +60,6 @@ module Distribution.Types.PackageDescription import Distribution.Compat.Prelude import Prelude () -import Control.Monad ((<=<)) - -- lens import Distribution.Types.Benchmark @@ -362,13 +360,20 @@ enabledBuildInfos pkg enabled = -- ------------------------------------------------------------ -- | Get the combined build-depends entries of all components. -allBuildDepends :: PackageDescription -> [Dependency] -allBuildDepends = targetBuildDepends <=< allBuildInfo +allBuildDepends :: PackageDescription -> [(IsPrivate, Dependency)] +allBuildDepends pd = do + bi <- allBuildInfo pd + [(Public, d) | d <- targetBuildDepends bi] + ++ [(Private p, d) | PrivateDependency p ds <- targetPrivateBuildDepends bi, d <- ds] -- | Get the combined build-depends entries of all enabled components, per the -- given request spec. -enabledBuildDepends :: PackageDescription -> ComponentRequestedSpec -> [Dependency] -enabledBuildDepends spec pd = targetBuildDepends =<< enabledBuildInfos spec pd +enabledBuildDepends :: PackageDescription -> ComponentRequestedSpec -> [(IsPrivate, Dependency)] +enabledBuildDepends spec pd = + do + bi <- enabledBuildInfos spec pd + [(Public, d) | d <- targetBuildDepends bi] + ++ [(Private p, d) | PrivateDependency p ds <- targetPrivateBuildDepends bi, d <- ds] updatePackageDescription :: HookedBuildInfo -> PackageDescription -> PackageDescription updatePackageDescription (mb_lib_bi, exe_bi) p = diff --git a/Cabal-tests/tests/NoThunks.hs b/Cabal-tests/tests/NoThunks.hs index 6a81475dc03..9bc45114694 100644 --- a/Cabal-tests/tests/NoThunks.hs +++ b/Cabal-tests/tests/NoThunks.hs @@ -79,6 +79,9 @@ instance NoThunks ModuleReexport instance NoThunks LibraryVisibility instance NoThunks ForeignLibType instance NoThunks GenericPackageDescription +instance NoThunks Dependencies +instance NoThunks PrivateDependency +instance NoThunks PrivateAlias instance NoThunks KnownRepoType instance NoThunks Library instance NoThunks LibraryName diff --git a/Cabal-tests/tests/ParserTests/regressions/Octree-0.5.expr b/Cabal-tests/tests/ParserTests/regressions/Octree-0.5.expr index 3d03421210b..14f8b716352 100644 --- a/Cabal-tests/tests/ParserTests/regressions/Octree-0.5.expr +++ b/Cabal-tests/tests/ParserTests/regressions/Octree-0.5.expr @@ -154,26 +154,30 @@ GenericPackageDescription { (OrLaterVersion (mkVersion [2, 4, 0])) mainLibSet], + targetPrivateBuildDepends = [], mixins = []}}, - condTreeConstraints = [ - Dependency - (PackageName "base") - (IntersectVersionRanges + condTreeConstraints = + Dependencies { + publicDependencies = [ + Dependency + (PackageName "base") + (IntersectVersionRanges + (OrLaterVersion + (mkVersion [4, 0])) + (EarlierVersion + (mkVersion [4, 7]))) + mainLibSet, + Dependency + (PackageName "AC-Vector") (OrLaterVersion - (mkVersion [4, 0])) - (EarlierVersion - (mkVersion [4, 7]))) - mainLibSet, - Dependency - (PackageName "AC-Vector") - (OrLaterVersion - (mkVersion [2, 3, 0])) - mainLibSet, - Dependency - (PackageName "QuickCheck") - (OrLaterVersion - (mkVersion [2, 4, 0])) - mainLibSet], + (mkVersion [2, 3, 0])) + mainLibSet, + Dependency + (PackageName "QuickCheck") + (OrLaterVersion + (mkVersion [2, 4, 0])) + mainLibSet], + privateDependencies = []}, condTreeComponents = []}, condSubLibraries = [], condForeignLibs = [], @@ -260,27 +264,31 @@ GenericPackageDescription { (OrLaterVersion (mkVersion [2, 4, 0])) mainLibSet], + targetPrivateBuildDepends = [], mixins = []}, testCodeGenerators = []}, - condTreeConstraints = [ - Dependency - (PackageName "base") - (IntersectVersionRanges + condTreeConstraints = + Dependencies { + publicDependencies = [ + Dependency + (PackageName "base") + (IntersectVersionRanges + (OrLaterVersion + (mkVersion [4, 0])) + (EarlierVersion + (mkVersion [4, 7]))) + mainLibSet, + Dependency + (PackageName "AC-Vector") (OrLaterVersion - (mkVersion [4, 0])) - (EarlierVersion - (mkVersion [4, 7]))) - mainLibSet, - Dependency - (PackageName "AC-Vector") - (OrLaterVersion - (mkVersion [2, 3, 0])) - mainLibSet, - Dependency - (PackageName "QuickCheck") - (OrLaterVersion - (mkVersion [2, 4, 0])) - mainLibSet], + (mkVersion [2, 3, 0])) + mainLibSet, + Dependency + (PackageName "QuickCheck") + (OrLaterVersion + (mkVersion [2, 4, 0])) + mainLibSet], + privateDependencies = []}, condTreeComponents = []}, _×_ (UnqualComponentName "readme") @@ -365,30 +373,34 @@ GenericPackageDescription { (PackageName "markdown-unlit") (OrLaterVersion (mkVersion [0])) mainLibSet], + targetPrivateBuildDepends = [], mixins = []}, testCodeGenerators = []}, - condTreeConstraints = [ - Dependency - (PackageName "base") - (IntersectVersionRanges + condTreeConstraints = + Dependencies { + publicDependencies = [ + Dependency + (PackageName "base") + (IntersectVersionRanges + (OrLaterVersion + (mkVersion [4, 0])) + (EarlierVersion + (mkVersion [4, 7]))) + mainLibSet, + Dependency + (PackageName "AC-Vector") (OrLaterVersion - (mkVersion [4, 0])) - (EarlierVersion - (mkVersion [4, 7]))) - mainLibSet, - Dependency - (PackageName "AC-Vector") - (OrLaterVersion - (mkVersion [2, 3, 0])) - mainLibSet, - Dependency - (PackageName "QuickCheck") - (OrLaterVersion - (mkVersion [2, 4, 0])) - mainLibSet, - Dependency - (PackageName "markdown-unlit") - (OrLaterVersion (mkVersion [0])) - mainLibSet], + (mkVersion [2, 3, 0])) + mainLibSet, + Dependency + (PackageName "QuickCheck") + (OrLaterVersion + (mkVersion [2, 4, 0])) + mainLibSet, + Dependency + (PackageName "markdown-unlit") + (OrLaterVersion (mkVersion [0])) + mainLibSet], + privateDependencies = []}, condTreeComponents = []}], condBenchmarks = []} diff --git a/Cabal-tests/tests/ParserTests/regressions/anynone.expr b/Cabal-tests/tests/ParserTests/regressions/anynone.expr index 3191425d609..c28388a521e 100644 --- a/Cabal-tests/tests/ParserTests/regressions/anynone.expr +++ b/Cabal-tests/tests/ParserTests/regressions/anynone.expr @@ -103,12 +103,16 @@ GenericPackageDescription { (PackageName "base") (OrLaterVersion (mkVersion [0])) mainLibSet], + targetPrivateBuildDepends = [], mixins = []}}, - condTreeConstraints = [ - Dependency - (PackageName "base") - (OrLaterVersion (mkVersion [0])) - mainLibSet], + condTreeConstraints = + Dependencies { + publicDependencies = [ + Dependency + (PackageName "base") + (OrLaterVersion (mkVersion [0])) + mainLibSet], + privateDependencies = []}, condTreeComponents = []}, condSubLibraries = [], condForeignLibs = [], diff --git a/Cabal-tests/tests/ParserTests/regressions/big-version.expr b/Cabal-tests/tests/ParserTests/regressions/big-version.expr index e677de20626..baca580b38a 100644 --- a/Cabal-tests/tests/ParserTests/regressions/big-version.expr +++ b/Cabal-tests/tests/ParserTests/regressions/big-version.expr @@ -100,8 +100,12 @@ GenericPackageDescription { PerCompilerFlavor [] [], customFieldsBI = [], targetBuildDepends = [], + targetPrivateBuildDepends = [], mixins = []}}, - condTreeConstraints = [], + condTreeConstraints = + Dependencies { + publicDependencies = [], + privateDependencies = []}, condTreeComponents = []}, condSubLibraries = [], condForeignLibs = [], diff --git a/Cabal-tests/tests/ParserTests/regressions/common-conditional.expr b/Cabal-tests/tests/ParserTests/regressions/common-conditional.expr index f6ffe291e59..c9ba4e6eed2 100644 --- a/Cabal-tests/tests/ParserTests/regressions/common-conditional.expr +++ b/Cabal-tests/tests/ParserTests/regressions/common-conditional.expr @@ -120,12 +120,16 @@ GenericPackageDescription { (PackageName "ghc-prim") (OrLaterVersion (mkVersion [0])) mainLibSet], + targetPrivateBuildDepends = [], mixins = []}}, - condTreeConstraints = [ - Dependency - (PackageName "ghc-prim") - (OrLaterVersion (mkVersion [0])) - mainLibSet], + condTreeConstraints = + Dependencies { + publicDependencies = [ + Dependency + (PackageName "ghc-prim") + (OrLaterVersion (mkVersion [0])) + mainLibSet], + privateDependencies = []}, condTreeComponents = [ CondBranch { condBranchCondition = @@ -203,20 +207,24 @@ GenericPackageDescription { (PackageName "containers") (OrLaterVersion (mkVersion [0])) mainLibSet], + targetPrivateBuildDepends = [], mixins = []}}, - condTreeConstraints = [ - Dependency - (PackageName "base") - (IntersectVersionRanges - (OrLaterVersion - (mkVersion [4, 10])) - (EarlierVersion - (mkVersion [4, 11]))) - mainLibSet, - Dependency - (PackageName "containers") - (OrLaterVersion (mkVersion [0])) - mainLibSet], + condTreeConstraints = + Dependencies { + publicDependencies = [ + Dependency + (PackageName "base") + (IntersectVersionRanges + (OrLaterVersion + (mkVersion [4, 10])) + (EarlierVersion + (mkVersion [4, 11]))) + mainLibSet, + Dependency + (PackageName "containers") + (OrLaterVersion (mkVersion [0])) + mainLibSet], + privateDependencies = []}, condTreeComponents = [ CondBranch { condBranchCondition = @@ -286,12 +294,16 @@ GenericPackageDescription { (PackageName "Win32") (OrLaterVersion (mkVersion [0])) mainLibSet], + targetPrivateBuildDepends = [], mixins = []}}, - condTreeConstraints = [ - Dependency - (PackageName "Win32") - (OrLaterVersion (mkVersion [0])) - mainLibSet], + condTreeConstraints = + Dependencies { + publicDependencies = [ + Dependency + (PackageName "Win32") + (OrLaterVersion (mkVersion [0])) + mainLibSet], + privateDependencies = []}, condTreeComponents = []}, condBranchIfFalse = Nothing}]}, condBranchIfFalse = Nothing}]}, @@ -364,13 +376,17 @@ GenericPackageDescription { (PackageName "HUnit") (OrLaterVersion (mkVersion [0])) mainLibSet], + targetPrivateBuildDepends = [], mixins = []}, testCodeGenerators = []}, - condTreeConstraints = [ - Dependency - (PackageName "HUnit") - (OrLaterVersion (mkVersion [0])) - mainLibSet], + condTreeConstraints = + Dependencies { + publicDependencies = [ + Dependency + (PackageName "HUnit") + (OrLaterVersion (mkVersion [0])) + mainLibSet], + privateDependencies = []}, condTreeComponents = [ CondBranch { condBranchCondition = @@ -436,9 +452,13 @@ GenericPackageDescription { PerCompilerFlavor [] [], customFieldsBI = [], targetBuildDepends = [], + targetPrivateBuildDepends = [], mixins = []}, testCodeGenerators = []}, - condTreeConstraints = [], + condTreeConstraints = + Dependencies { + publicDependencies = [], + privateDependencies = []}, condTreeComponents = []}, condBranchIfFalse = Nothing}, CondBranch { @@ -517,21 +537,25 @@ GenericPackageDescription { (PackageName "containers") (OrLaterVersion (mkVersion [0])) mainLibSet], + targetPrivateBuildDepends = [], mixins = []}, testCodeGenerators = []}, - condTreeConstraints = [ - Dependency - (PackageName "base") - (IntersectVersionRanges - (OrLaterVersion - (mkVersion [4, 10])) - (EarlierVersion - (mkVersion [4, 11]))) - mainLibSet, - Dependency - (PackageName "containers") - (OrLaterVersion (mkVersion [0])) - mainLibSet], + condTreeConstraints = + Dependencies { + publicDependencies = [ + Dependency + (PackageName "base") + (IntersectVersionRanges + (OrLaterVersion + (mkVersion [4, 10])) + (EarlierVersion + (mkVersion [4, 11]))) + mainLibSet, + Dependency + (PackageName "containers") + (OrLaterVersion (mkVersion [0])) + mainLibSet], + privateDependencies = []}, condTreeComponents = [ CondBranch { condBranchCondition = @@ -601,13 +625,17 @@ GenericPackageDescription { (PackageName "Win32") (OrLaterVersion (mkVersion [0])) mainLibSet], + targetPrivateBuildDepends = [], mixins = []}, testCodeGenerators = []}, - condTreeConstraints = [ - Dependency - (PackageName "Win32") - (OrLaterVersion (mkVersion [0])) - mainLibSet], + condTreeConstraints = + Dependencies { + publicDependencies = [ + Dependency + (PackageName "Win32") + (OrLaterVersion (mkVersion [0])) + mainLibSet], + privateDependencies = []}, condTreeComponents = []}, condBranchIfFalse = Nothing}, CondBranch { @@ -678,13 +706,17 @@ GenericPackageDescription { (PackageName "Win32") (OrLaterVersion (mkVersion [0])) mainLibSet], + targetPrivateBuildDepends = [], mixins = []}, testCodeGenerators = []}, - condTreeConstraints = [ - Dependency - (PackageName "Win32") - (OrLaterVersion (mkVersion [0])) - mainLibSet], + condTreeConstraints = + Dependencies { + publicDependencies = [ + Dependency + (PackageName "Win32") + (OrLaterVersion (mkVersion [0])) + mainLibSet], + privateDependencies = []}, condTreeComponents = []}, condBranchIfFalse = Nothing}]}, condBranchIfFalse = Nothing}]}], diff --git a/Cabal-tests/tests/ParserTests/regressions/common.expr b/Cabal-tests/tests/ParserTests/regressions/common.expr index e0eb4a1dde7..955af0e2ca8 100644 --- a/Cabal-tests/tests/ParserTests/regressions/common.expr +++ b/Cabal-tests/tests/ParserTests/regressions/common.expr @@ -118,12 +118,16 @@ GenericPackageDescription { (PackageName "ghc-prim") (OrLaterVersion (mkVersion [0])) mainLibSet], + targetPrivateBuildDepends = [], mixins = []}}, - condTreeConstraints = [ - Dependency - (PackageName "ghc-prim") - (OrLaterVersion (mkVersion [0])) - mainLibSet], + condTreeConstraints = + Dependencies { + publicDependencies = [ + Dependency + (PackageName "ghc-prim") + (OrLaterVersion (mkVersion [0])) + mainLibSet], + privateDependencies = []}, condTreeComponents = []}, condSubLibraries = [], condForeignLibs = [], @@ -194,12 +198,16 @@ GenericPackageDescription { (PackageName "HUnit") (OrLaterVersion (mkVersion [0])) mainLibSet], + targetPrivateBuildDepends = [], mixins = []}, testCodeGenerators = []}, - condTreeConstraints = [ - Dependency - (PackageName "HUnit") - (OrLaterVersion (mkVersion [0])) - mainLibSet], + condTreeConstraints = + Dependencies { + publicDependencies = [ + Dependency + (PackageName "HUnit") + (OrLaterVersion (mkVersion [0])) + mainLibSet], + privateDependencies = []}, condTreeComponents = []}], condBenchmarks = []} diff --git a/Cabal-tests/tests/ParserTests/regressions/common2.expr b/Cabal-tests/tests/ParserTests/regressions/common2.expr index b3cb004eecb..83596f63a7b 100644 --- a/Cabal-tests/tests/ParserTests/regressions/common2.expr +++ b/Cabal-tests/tests/ParserTests/regressions/common2.expr @@ -126,24 +126,28 @@ GenericPackageDescription { (PackageName "ghc-prim") (OrLaterVersion (mkVersion [0])) mainLibSet], + targetPrivateBuildDepends = [], mixins = []}}, - condTreeConstraints = [ - Dependency - (PackageName "base") - (IntersectVersionRanges - (OrLaterVersion - (mkVersion [4, 10])) - (EarlierVersion - (mkVersion [4, 11]))) - mainLibSet, - Dependency - (PackageName "containers") - (OrLaterVersion (mkVersion [0])) - mainLibSet, - Dependency - (PackageName "ghc-prim") - (OrLaterVersion (mkVersion [0])) - mainLibSet], + condTreeConstraints = + Dependencies { + publicDependencies = [ + Dependency + (PackageName "base") + (IntersectVersionRanges + (OrLaterVersion + (mkVersion [4, 10])) + (EarlierVersion + (mkVersion [4, 11]))) + mainLibSet, + Dependency + (PackageName "containers") + (OrLaterVersion (mkVersion [0])) + mainLibSet, + Dependency + (PackageName "ghc-prim") + (OrLaterVersion (mkVersion [0])) + mainLibSet], + privateDependencies = []}, condTreeComponents = [ CondBranch { condBranchCondition = @@ -213,12 +217,16 @@ GenericPackageDescription { (PackageName "Win32") (OrLaterVersion (mkVersion [0])) mainLibSet], + targetPrivateBuildDepends = [], mixins = []}}, - condTreeConstraints = [ - Dependency - (PackageName "Win32") - (OrLaterVersion (mkVersion [0])) - mainLibSet], + condTreeConstraints = + Dependencies { + publicDependencies = [ + Dependency + (PackageName "Win32") + (OrLaterVersion (mkVersion [0])) + mainLibSet], + privateDependencies = []}, condTreeComponents = []}, condBranchIfFalse = Nothing}]}, condSubLibraries = [ @@ -305,24 +313,28 @@ GenericPackageDescription { (PackageName "ghc-prim") (OrLaterVersion (mkVersion [0])) mainLibSet], + targetPrivateBuildDepends = [], mixins = []}}, - condTreeConstraints = [ - Dependency - (PackageName "base") - (IntersectVersionRanges - (OrLaterVersion - (mkVersion [4, 10])) - (EarlierVersion - (mkVersion [4, 11]))) - mainLibSet, - Dependency - (PackageName "containers") - (OrLaterVersion (mkVersion [0])) - mainLibSet, - Dependency - (PackageName "ghc-prim") - (OrLaterVersion (mkVersion [0])) - mainLibSet], + condTreeConstraints = + Dependencies { + publicDependencies = [ + Dependency + (PackageName "base") + (IntersectVersionRanges + (OrLaterVersion + (mkVersion [4, 10])) + (EarlierVersion + (mkVersion [4, 11]))) + mainLibSet, + Dependency + (PackageName "containers") + (OrLaterVersion (mkVersion [0])) + mainLibSet, + Dependency + (PackageName "ghc-prim") + (OrLaterVersion (mkVersion [0])) + mainLibSet], + privateDependencies = []}, condTreeComponents = [ CondBranch { condBranchCondition = @@ -394,12 +406,16 @@ GenericPackageDescription { (PackageName "Win32") (OrLaterVersion (mkVersion [0])) mainLibSet], + targetPrivateBuildDepends = [], mixins = []}}, - condTreeConstraints = [ - Dependency - (PackageName "Win32") - (OrLaterVersion (mkVersion [0])) - mainLibSet], + condTreeConstraints = + Dependencies { + publicDependencies = [ + Dependency + (PackageName "Win32") + (OrLaterVersion (mkVersion [0])) + mainLibSet], + privateDependencies = []}, condTreeComponents = []}, condBranchIfFalse = Nothing}]}], condForeignLibs = [], @@ -482,25 +498,29 @@ GenericPackageDescription { (PackageName "HUnit") (OrLaterVersion (mkVersion [0])) mainLibSet], + targetPrivateBuildDepends = [], mixins = []}, testCodeGenerators = []}, - condTreeConstraints = [ - Dependency - (PackageName "base") - (IntersectVersionRanges - (OrLaterVersion - (mkVersion [4, 10])) - (EarlierVersion - (mkVersion [4, 11]))) - mainLibSet, - Dependency - (PackageName "containers") - (OrLaterVersion (mkVersion [0])) - mainLibSet, - Dependency - (PackageName "HUnit") - (OrLaterVersion (mkVersion [0])) - mainLibSet], + condTreeConstraints = + Dependencies { + publicDependencies = [ + Dependency + (PackageName "base") + (IntersectVersionRanges + (OrLaterVersion + (mkVersion [4, 10])) + (EarlierVersion + (mkVersion [4, 11]))) + mainLibSet, + Dependency + (PackageName "containers") + (OrLaterVersion (mkVersion [0])) + mainLibSet, + Dependency + (PackageName "HUnit") + (OrLaterVersion (mkVersion [0])) + mainLibSet], + privateDependencies = []}, condTreeComponents = [ CondBranch { condBranchCondition = @@ -570,13 +590,17 @@ GenericPackageDescription { (PackageName "Win32") (OrLaterVersion (mkVersion [0])) mainLibSet], + targetPrivateBuildDepends = [], mixins = []}, testCodeGenerators = []}, - condTreeConstraints = [ - Dependency - (PackageName "Win32") - (OrLaterVersion (mkVersion [0])) - mainLibSet], + condTreeConstraints = + Dependencies { + publicDependencies = [ + Dependency + (PackageName "Win32") + (OrLaterVersion (mkVersion [0])) + mainLibSet], + privateDependencies = []}, condTreeComponents = []}, condBranchIfFalse = Nothing}, CondBranch { @@ -647,13 +671,17 @@ GenericPackageDescription { (PackageName "Win32") (OrLaterVersion (mkVersion [0])) mainLibSet], + targetPrivateBuildDepends = [], mixins = []}, testCodeGenerators = []}, - condTreeConstraints = [ - Dependency - (PackageName "Win32") - (OrLaterVersion (mkVersion [0])) - mainLibSet], + condTreeConstraints = + Dependencies { + publicDependencies = [ + Dependency + (PackageName "Win32") + (OrLaterVersion (mkVersion [0])) + mainLibSet], + privateDependencies = []}, condTreeComponents = []}, condBranchIfFalse = Nothing}, CondBranch { @@ -720,9 +748,13 @@ GenericPackageDescription { PerCompilerFlavor [] [], customFieldsBI = [], targetBuildDepends = [], + targetPrivateBuildDepends = [], mixins = []}, testCodeGenerators = []}, - condTreeConstraints = [], + condTreeConstraints = + Dependencies { + publicDependencies = [], + privateDependencies = []}, condTreeComponents = []}, condBranchIfFalse = Nothing}]}], condBenchmarks = []} diff --git a/Cabal-tests/tests/ParserTests/regressions/common3.expr b/Cabal-tests/tests/ParserTests/regressions/common3.expr index 21b200baa7b..acad707bda7 100644 --- a/Cabal-tests/tests/ParserTests/regressions/common3.expr +++ b/Cabal-tests/tests/ParserTests/regressions/common3.expr @@ -118,12 +118,16 @@ GenericPackageDescription { (PackageName "ghc-prim") (OrLaterVersion (mkVersion [0])) mainLibSet], + targetPrivateBuildDepends = [], mixins = []}}, - condTreeConstraints = [ - Dependency - (PackageName "ghc-prim") - (OrLaterVersion (mkVersion [0])) - mainLibSet], + condTreeConstraints = + Dependencies { + publicDependencies = [ + Dependency + (PackageName "ghc-prim") + (OrLaterVersion (mkVersion [0])) + mainLibSet], + privateDependencies = []}, condTreeComponents = []}, condSubLibraries = [], condForeignLibs = [], @@ -206,24 +210,28 @@ GenericPackageDescription { (PackageName "HUnit") (OrLaterVersion (mkVersion [0])) mainLibSet], + targetPrivateBuildDepends = [], mixins = []}, testCodeGenerators = []}, - condTreeConstraints = [ - Dependency - (PackageName "base") - (IntersectVersionRanges - (OrLaterVersion - (mkVersion [4, 10])) - (EarlierVersion - (mkVersion [4, 11]))) - mainLibSet, - Dependency - (PackageName "containers") - (OrLaterVersion (mkVersion [0])) - mainLibSet, - Dependency - (PackageName "HUnit") - (OrLaterVersion (mkVersion [0])) - mainLibSet], + condTreeConstraints = + Dependencies { + publicDependencies = [ + Dependency + (PackageName "base") + (IntersectVersionRanges + (OrLaterVersion + (mkVersion [4, 10])) + (EarlierVersion + (mkVersion [4, 11]))) + mainLibSet, + Dependency + (PackageName "containers") + (OrLaterVersion (mkVersion [0])) + mainLibSet, + Dependency + (PackageName "HUnit") + (OrLaterVersion (mkVersion [0])) + mainLibSet], + privateDependencies = []}, condTreeComponents = []}], condBenchmarks = []} diff --git a/Cabal-tests/tests/ParserTests/regressions/elif.expr b/Cabal-tests/tests/ParserTests/regressions/elif.expr index 1315d689467..d22deddf324 100644 --- a/Cabal-tests/tests/ParserTests/regressions/elif.expr +++ b/Cabal-tests/tests/ParserTests/regressions/elif.expr @@ -109,8 +109,12 @@ GenericPackageDescription { PerCompilerFlavor [] [], customFieldsBI = [], targetBuildDepends = [], + targetPrivateBuildDepends = [], mixins = []}}, - condTreeConstraints = [], + condTreeConstraints = + Dependencies { + publicDependencies = [], + privateDependencies = []}, condTreeComponents = [ CondBranch { condBranchCondition = @@ -180,12 +184,16 @@ GenericPackageDescription { (PackageName "unix") (OrLaterVersion (mkVersion [0])) mainLibSet], + targetPrivateBuildDepends = [], mixins = []}}, - condTreeConstraints = [ - Dependency - (PackageName "unix") - (OrLaterVersion (mkVersion [0])) - mainLibSet], + condTreeConstraints = + Dependencies { + publicDependencies = [ + Dependency + (PackageName "unix") + (OrLaterVersion (mkVersion [0])) + mainLibSet], + privateDependencies = []}, condTreeComponents = []}, condBranchIfFalse = Nothing}]}, condSubLibraries = [], diff --git a/Cabal-tests/tests/ParserTests/regressions/elif2.expr b/Cabal-tests/tests/ParserTests/regressions/elif2.expr index 61f2177cbaa..ece3c44ab04 100644 --- a/Cabal-tests/tests/ParserTests/regressions/elif2.expr +++ b/Cabal-tests/tests/ParserTests/regressions/elif2.expr @@ -109,8 +109,12 @@ GenericPackageDescription { PerCompilerFlavor [] [], customFieldsBI = [], targetBuildDepends = [], + targetPrivateBuildDepends = [], mixins = []}}, - condTreeConstraints = [], + condTreeConstraints = + Dependencies { + publicDependencies = [], + privateDependencies = []}, condTreeComponents = [ CondBranch { condBranchCondition = @@ -180,12 +184,16 @@ GenericPackageDescription { (PackageName "unix") (OrLaterVersion (mkVersion [0])) mainLibSet], + targetPrivateBuildDepends = [], mixins = []}}, - condTreeConstraints = [ - Dependency - (PackageName "unix") - (OrLaterVersion (mkVersion [0])) - mainLibSet], + condTreeConstraints = + Dependencies { + publicDependencies = [ + Dependency + (PackageName "unix") + (OrLaterVersion (mkVersion [0])) + mainLibSet], + privateDependencies = []}, condTreeComponents = []}, condBranchIfFalse = Just CondNode { @@ -249,8 +257,12 @@ GenericPackageDescription { PerCompilerFlavor [] [], customFieldsBI = [], targetBuildDepends = [], + targetPrivateBuildDepends = [], mixins = []}}, - condTreeConstraints = [], + condTreeConstraints = + Dependencies { + publicDependencies = [], + privateDependencies = []}, condTreeComponents = [ CondBranch { condBranchCondition = @@ -320,12 +332,16 @@ GenericPackageDescription { (PackageName "Win32") (OrLaterVersion (mkVersion [0])) mainLibSet], + targetPrivateBuildDepends = [], mixins = []}}, - condTreeConstraints = [ - Dependency - (PackageName "Win32") - (OrLaterVersion (mkVersion [0])) - mainLibSet], + condTreeConstraints = + Dependencies { + publicDependencies = [ + Dependency + (PackageName "Win32") + (OrLaterVersion (mkVersion [0])) + mainLibSet], + privateDependencies = []}, condTreeComponents = []}, condBranchIfFalse = Just CondNode { @@ -389,8 +405,12 @@ GenericPackageDescription { PerCompilerFlavor [] [], customFieldsBI = [], targetBuildDepends = [], + targetPrivateBuildDepends = [], mixins = []}}, - condTreeConstraints = [], + condTreeConstraints = + Dependencies { + publicDependencies = [], + privateDependencies = []}, condTreeComponents = []}}]}}]}, condSubLibraries = [], condForeignLibs = [], diff --git a/Cabal-tests/tests/ParserTests/regressions/encoding-0.8.expr b/Cabal-tests/tests/ParserTests/regressions/encoding-0.8.expr index e1b125e7a32..681892c14e0 100644 --- a/Cabal-tests/tests/ParserTests/regressions/encoding-0.8.expr +++ b/Cabal-tests/tests/ParserTests/regressions/encoding-0.8.expr @@ -126,16 +126,20 @@ GenericPackageDescription { (ThisVersion (mkVersion [4, 4]))) mainLibSet], + targetPrivateBuildDepends = [], mixins = []}}, - condTreeConstraints = [ - Dependency - (PackageName "base") - (UnionVersionRanges - (LaterVersion - (mkVersion [4, 4])) - (ThisVersion - (mkVersion [4, 4]))) - mainLibSet], + condTreeConstraints = + Dependencies { + publicDependencies = [ + Dependency + (PackageName "base") + (UnionVersionRanges + (LaterVersion + (mkVersion [4, 4])) + (ThisVersion + (mkVersion [4, 4]))) + mainLibSet], + privateDependencies = []}, condTreeComponents = []}, condSubLibraries = [], condForeignLibs = [], diff --git a/Cabal-tests/tests/ParserTests/regressions/generics-sop.expr b/Cabal-tests/tests/ParserTests/regressions/generics-sop.expr index 9084371a614..9d721e24db8 100644 --- a/Cabal-tests/tests/ParserTests/regressions/generics-sop.expr +++ b/Cabal-tests/tests/ParserTests/regressions/generics-sop.expr @@ -278,40 +278,44 @@ GenericPackageDescription { (EarlierVersion (mkVersion [1, 5]))) mainLibSet], + targetPrivateBuildDepends = [], mixins = []}}, - condTreeConstraints = [ - Dependency - (PackageName "base") - (IntersectVersionRanges - (OrLaterVersion - (mkVersion [4, 7])) - (EarlierVersion - (mkVersion [5]))) - mainLibSet, - Dependency - (PackageName "template-haskell") - (IntersectVersionRanges - (OrLaterVersion - (mkVersion [2, 8])) - (EarlierVersion - (mkVersion [2, 13]))) - mainLibSet, - Dependency - (PackageName "ghc-prim") - (IntersectVersionRanges - (OrLaterVersion - (mkVersion [0, 3])) - (EarlierVersion - (mkVersion [0, 6]))) - mainLibSet, - Dependency - (PackageName "deepseq") - (IntersectVersionRanges - (OrLaterVersion - (mkVersion [1, 3])) - (EarlierVersion - (mkVersion [1, 5]))) - mainLibSet], + condTreeConstraints = + Dependencies { + publicDependencies = [ + Dependency + (PackageName "base") + (IntersectVersionRanges + (OrLaterVersion + (mkVersion [4, 7])) + (EarlierVersion + (mkVersion [5]))) + mainLibSet, + Dependency + (PackageName "template-haskell") + (IntersectVersionRanges + (OrLaterVersion + (mkVersion [2, 8])) + (EarlierVersion + (mkVersion [2, 13]))) + mainLibSet, + Dependency + (PackageName "ghc-prim") + (IntersectVersionRanges + (OrLaterVersion + (mkVersion [0, 3])) + (EarlierVersion + (mkVersion [0, 6]))) + mainLibSet, + Dependency + (PackageName "deepseq") + (IntersectVersionRanges + (OrLaterVersion + (mkVersion [1, 3])) + (EarlierVersion + (mkVersion [1, 5]))) + mainLibSet], + privateDependencies = []}, condTreeComponents = [ CondBranch { condBranchCondition = @@ -385,16 +389,20 @@ GenericPackageDescription { (EarlierVersion (mkVersion [0, 9]))) mainLibSet], + targetPrivateBuildDepends = [], mixins = []}}, - condTreeConstraints = [ - Dependency - (PackageName "tagged") - (IntersectVersionRanges - (OrLaterVersion - (mkVersion [0, 7])) - (EarlierVersion - (mkVersion [0, 9]))) - mainLibSet], + condTreeConstraints = + Dependencies { + publicDependencies = [ + Dependency + (PackageName "tagged") + (IntersectVersionRanges + (OrLaterVersion + (mkVersion [0, 7])) + (EarlierVersion + (mkVersion [0, 9]))) + mainLibSet], + privateDependencies = []}, condTreeComponents = []}, condBranchIfFalse = Nothing}, CondBranch { @@ -478,25 +486,29 @@ GenericPackageDescription { (EarlierVersion (mkVersion [0, 6]))) mainLibSet], + targetPrivateBuildDepends = [], mixins = []}}, - condTreeConstraints = [ - Dependency - (PackageName - "transformers-compat") - (IntersectVersionRanges - (OrLaterVersion - (mkVersion [0, 3])) - (EarlierVersion - (mkVersion [0, 6]))) - mainLibSet, - Dependency - (PackageName "transformers") - (IntersectVersionRanges - (OrLaterVersion - (mkVersion [0, 3])) - (EarlierVersion - (mkVersion [0, 6]))) - mainLibSet], + condTreeConstraints = + Dependencies { + publicDependencies = [ + Dependency + (PackageName + "transformers-compat") + (IntersectVersionRanges + (OrLaterVersion + (mkVersion [0, 3])) + (EarlierVersion + (mkVersion [0, 6]))) + mainLibSet, + Dependency + (PackageName "transformers") + (IntersectVersionRanges + (OrLaterVersion + (mkVersion [0, 3])) + (EarlierVersion + (mkVersion [0, 6]))) + mainLibSet], + privateDependencies = []}, condTreeComponents = []}, condBranchIfFalse = Nothing}, CondBranch { @@ -565,8 +577,12 @@ GenericPackageDescription { PerCompilerFlavor [] [], customFieldsBI = [], targetBuildDepends = [], + targetPrivateBuildDepends = [], mixins = []}}, - condTreeConstraints = [], + condTreeConstraints = + Dependencies { + publicDependencies = [], + privateDependencies = []}, condTreeComponents = []}, condBranchIfFalse = Nothing}, CondBranch { @@ -635,8 +651,12 @@ GenericPackageDescription { PerCompilerFlavor [] [], customFieldsBI = [], targetBuildDepends = [], + targetPrivateBuildDepends = [], mixins = []}}, - condTreeConstraints = [], + condTreeConstraints = + Dependencies { + publicDependencies = [], + privateDependencies = []}, condTreeComponents = []}, condBranchIfFalse = Nothing}]}, condSubLibraries = [], @@ -721,21 +741,25 @@ GenericPackageDescription { (EarlierVersion (mkVersion [0, 14]))) mainLibSet], + targetPrivateBuildDepends = [], mixins = []}, testCodeGenerators = []}, - condTreeConstraints = [ - Dependency - (PackageName "base") - (OrLaterVersion (mkVersion [0])) - mainLibSet, - Dependency - (PackageName "doctest") - (IntersectVersionRanges - (OrLaterVersion - (mkVersion [0, 13])) - (EarlierVersion - (mkVersion [0, 14]))) - mainLibSet], + condTreeConstraints = + Dependencies { + publicDependencies = [ + Dependency + (PackageName "base") + (OrLaterVersion (mkVersion [0])) + mainLibSet, + Dependency + (PackageName "doctest") + (IntersectVersionRanges + (OrLaterVersion + (mkVersion [0, 13])) + (EarlierVersion + (mkVersion [0, 14]))) + mainLibSet], + privateDependencies = []}, condTreeComponents = []}, _×_ (UnqualComponentName @@ -814,20 +838,24 @@ GenericPackageDescription { (PackageName "generics-sop") (OrLaterVersion (mkVersion [0])) mainLibSet], + targetPrivateBuildDepends = [], mixins = []}, testCodeGenerators = []}, - condTreeConstraints = [ - Dependency - (PackageName "base") - (IntersectVersionRanges - (OrLaterVersion - (mkVersion [4, 6])) - (EarlierVersion - (mkVersion [5]))) - mainLibSet, - Dependency - (PackageName "generics-sop") - (OrLaterVersion (mkVersion [0])) - mainLibSet], + condTreeConstraints = + Dependencies { + publicDependencies = [ + Dependency + (PackageName "base") + (IntersectVersionRanges + (OrLaterVersion + (mkVersion [4, 6])) + (EarlierVersion + (mkVersion [5]))) + mainLibSet, + Dependency + (PackageName "generics-sop") + (OrLaterVersion (mkVersion [0])) + mainLibSet], + privateDependencies = []}, condTreeComponents = []}], condBenchmarks = []} diff --git a/Cabal-tests/tests/ParserTests/regressions/hasktorch.expr b/Cabal-tests/tests/ParserTests/regressions/hasktorch.expr index 346af927d1b..a2cdde88871 100644 --- a/Cabal-tests/tests/ParserTests/regressions/hasktorch.expr +++ b/Cabal-tests/tests/ParserTests/regressions/hasktorch.expr @@ -398,80 +398,84 @@ GenericPackageDescription { (EarlierVersion (mkVersion [0, 0, 2]))) mainLibSet], + targetPrivateBuildDepends = [], mixins = []}}, - condTreeConstraints = [ - Dependency - (PackageName "base") - (IntersectVersionRanges + condTreeConstraints = + Dependencies { + publicDependencies = [ + Dependency + (PackageName "base") + (IntersectVersionRanges + (UnionVersionRanges + (ThisVersion (mkVersion [4, 7])) + (LaterVersion + (mkVersion [4, 7]))) + (EarlierVersion + (mkVersion [5]))) + mainLibSet, + Dependency + (PackageName "dimensions") (UnionVersionRanges - (ThisVersion (mkVersion [4, 7])) + (ThisVersion (mkVersion [1, 0])) (LaterVersion - (mkVersion [4, 7]))) - (EarlierVersion - (mkVersion [5]))) - mainLibSet, - Dependency - (PackageName "dimensions") - (UnionVersionRanges - (ThisVersion (mkVersion [1, 0])) - (LaterVersion - (mkVersion [1, 0]))) - mainLibSet, - Dependency - (PackageName "safe-exceptions") - (UnionVersionRanges - (ThisVersion - (mkVersion [0, 1, 0])) - (LaterVersion - (mkVersion [0, 1, 0]))) - mainLibSet, - Dependency - (PackageName "singletons") - (UnionVersionRanges - (ThisVersion (mkVersion [2, 2])) - (LaterVersion - (mkVersion [2, 2]))) - mainLibSet, - Dependency - (PackageName "text") - (UnionVersionRanges - (ThisVersion - (mkVersion [1, 2, 2])) - (LaterVersion - (mkVersion [1, 2, 2]))) - mainLibSet, - Dependency - (PackageName "hasktorch") - (OrLaterVersion (mkVersion [0])) - (NonEmptySet.fromNonEmpty - (NE.fromList - [ - LSubLibName - (UnqualComponentName - "hasktorch-cpu")])), - Dependency - (PackageName "hasktorch-ffi-th") - (IntersectVersionRanges + (mkVersion [1, 0]))) + mainLibSet, + Dependency + (PackageName "safe-exceptions") (UnionVersionRanges (ThisVersion - (mkVersion [0, 0, 1])) + (mkVersion [0, 1, 0])) + (LaterVersion + (mkVersion [0, 1, 0]))) + mainLibSet, + Dependency + (PackageName "singletons") + (UnionVersionRanges + (ThisVersion (mkVersion [2, 2])) (LaterVersion - (mkVersion [0, 0, 1]))) - (EarlierVersion - (mkVersion [0, 0, 2]))) - mainLibSet, - Dependency - (PackageName - "hasktorch-types-th") - (IntersectVersionRanges + (mkVersion [2, 2]))) + mainLibSet, + Dependency + (PackageName "text") (UnionVersionRanges (ThisVersion - (mkVersion [0, 0, 1])) + (mkVersion [1, 2, 2])) (LaterVersion - (mkVersion [0, 0, 1]))) - (EarlierVersion - (mkVersion [0, 0, 2]))) - mainLibSet], + (mkVersion [1, 2, 2]))) + mainLibSet, + Dependency + (PackageName "hasktorch") + (OrLaterVersion (mkVersion [0])) + (NonEmptySet.fromNonEmpty + (NE.fromList + [ + LSubLibName + (UnqualComponentName + "hasktorch-cpu")])), + Dependency + (PackageName "hasktorch-ffi-th") + (IntersectVersionRanges + (UnionVersionRanges + (ThisVersion + (mkVersion [0, 0, 1])) + (LaterVersion + (mkVersion [0, 0, 1]))) + (EarlierVersion + (mkVersion [0, 0, 2]))) + mainLibSet, + Dependency + (PackageName + "hasktorch-types-th") + (IntersectVersionRanges + (UnionVersionRanges + (ThisVersion + (mkVersion [0, 0, 1])) + (LaterVersion + (mkVersion [0, 0, 1]))) + (EarlierVersion + (mkVersion [0, 0, 2]))) + mainLibSet], + privateDependencies = []}, condTreeComponents = [ CondBranch { condBranchCondition = @@ -646,8 +650,12 @@ GenericPackageDescription { PerCompilerFlavor [] [], customFieldsBI = [], targetBuildDepends = [], + targetPrivateBuildDepends = [], mixins = []}}, - condTreeConstraints = [], + condTreeConstraints = + Dependencies { + publicDependencies = [], + privateDependencies = []}, condTreeComponents = []}, condBranchIfFalse = Nothing}, CondBranch { @@ -897,17 +905,21 @@ GenericPackageDescription { LSubLibName (UnqualComponentName "hasktorch-gpu")]))], + targetPrivateBuildDepends = [], mixins = []}}, - condTreeConstraints = [ - Dependency - (PackageName "hasktorch") - (OrLaterVersion (mkVersion [0])) - (NonEmptySet.fromNonEmpty - (NE.fromList - [ - LSubLibName - (UnqualComponentName - "hasktorch-gpu")]))], + condTreeConstraints = + Dependencies { + publicDependencies = [ + Dependency + (PackageName "hasktorch") + (OrLaterVersion (mkVersion [0])) + (NonEmptySet.fromNonEmpty + (NE.fromList + [ + LSubLibName + (UnqualComponentName + "hasktorch-gpu")]))], + privateDependencies = []}, condTreeComponents = [ CondBranch { condBranchCondition = @@ -1088,8 +1100,12 @@ GenericPackageDescription { PerCompilerFlavor [] [], customFieldsBI = [], targetBuildDepends = [], + targetPrivateBuildDepends = [], mixins = []}}, - condTreeConstraints = [], + condTreeConstraints = + Dependencies { + publicDependencies = [], + privateDependencies = []}, condTreeComponents = []}, condBranchIfFalse = Nothing}]}, condBranchIfFalse = Nothing}]}, @@ -1535,6 +1551,7 @@ GenericPackageDescription { LSubLibName (UnqualComponentName "hasktorch-indef-signed")]))], + targetPrivateBuildDepends = [], mixins = [ Mixin { @@ -2582,100 +2599,103 @@ GenericPackageDescription { "Torch.Sig.Tensor.Random.THC") (ModuleName "Torch.Undefined.Double.Tensor.Random.THC")]}}]}}, - condTreeConstraints = [ - Dependency - (PackageName "base") - (IntersectVersionRanges + condTreeConstraints = + Dependencies { + publicDependencies = [ + Dependency + (PackageName "base") + (IntersectVersionRanges + (UnionVersionRanges + (ThisVersion (mkVersion [4, 7])) + (LaterVersion + (mkVersion [4, 7]))) + (EarlierVersion + (mkVersion [5]))) + mainLibSet, + Dependency + (PackageName + "hasktorch-types-th") + (IntersectVersionRanges + (UnionVersionRanges + (ThisVersion + (mkVersion [0, 0, 1])) + (LaterVersion + (mkVersion [0, 0, 1]))) + (EarlierVersion + (mkVersion [0, 0, 2]))) + mainLibSet, + Dependency + (PackageName "dimensions") (UnionVersionRanges - (ThisVersion (mkVersion [4, 7])) + (ThisVersion (mkVersion [1, 0])) (LaterVersion - (mkVersion [4, 7]))) - (EarlierVersion - (mkVersion [5]))) - mainLibSet, - Dependency - (PackageName - "hasktorch-types-th") - (IntersectVersionRanges + (mkVersion [1, 0]))) + mainLibSet, + Dependency + (PackageName "hasktorch-ffi-th") + (IntersectVersionRanges + (UnionVersionRanges + (ThisVersion + (mkVersion [0, 0, 1])) + (LaterVersion + (mkVersion [0, 0, 1]))) + (EarlierVersion + (mkVersion [0, 0, 2]))) + mainLibSet, + Dependency + (PackageName + "hasktorch-types-th") + (IntersectVersionRanges + (UnionVersionRanges + (ThisVersion + (mkVersion [0, 0, 1])) + (LaterVersion + (mkVersion [0, 0, 1]))) + (EarlierVersion + (mkVersion [0, 0, 2]))) + mainLibSet, + Dependency + (PackageName "safe-exceptions") (UnionVersionRanges (ThisVersion - (mkVersion [0, 0, 1])) + (mkVersion [0, 1, 0])) (LaterVersion - (mkVersion [0, 0, 1]))) - (EarlierVersion - (mkVersion [0, 0, 2]))) - mainLibSet, - Dependency - (PackageName "dimensions") - (UnionVersionRanges - (ThisVersion (mkVersion [1, 0])) - (LaterVersion - (mkVersion [1, 0]))) - mainLibSet, - Dependency - (PackageName "hasktorch-ffi-th") - (IntersectVersionRanges + (mkVersion [0, 1, 0]))) + mainLibSet, + Dependency + (PackageName "singletons") (UnionVersionRanges - (ThisVersion - (mkVersion [0, 0, 1])) + (ThisVersion (mkVersion [2, 2])) (LaterVersion - (mkVersion [0, 0, 1]))) - (EarlierVersion - (mkVersion [0, 0, 2]))) - mainLibSet, - Dependency - (PackageName - "hasktorch-types-th") - (IntersectVersionRanges + (mkVersion [2, 2]))) + mainLibSet, + Dependency + (PackageName "text") (UnionVersionRanges (ThisVersion - (mkVersion [0, 0, 1])) + (mkVersion [1, 2, 2])) (LaterVersion - (mkVersion [0, 0, 1]))) - (EarlierVersion - (mkVersion [0, 0, 2]))) - mainLibSet, - Dependency - (PackageName "safe-exceptions") - (UnionVersionRanges - (ThisVersion - (mkVersion [0, 1, 0])) - (LaterVersion - (mkVersion [0, 1, 0]))) - mainLibSet, - Dependency - (PackageName "singletons") - (UnionVersionRanges - (ThisVersion (mkVersion [2, 2])) - (LaterVersion - (mkVersion [2, 2]))) - mainLibSet, - Dependency - (PackageName "text") - (UnionVersionRanges - (ThisVersion - (mkVersion [1, 2, 2])) - (LaterVersion - (mkVersion [1, 2, 2]))) - mainLibSet, - Dependency - (PackageName "hasktorch") - (OrLaterVersion (mkVersion [0])) - (NonEmptySet.fromNonEmpty - (NE.fromList - [ - LSubLibName - (UnqualComponentName - "hasktorch-indef-floating")])), - Dependency - (PackageName "hasktorch") - (OrLaterVersion (mkVersion [0])) - (NonEmptySet.fromNonEmpty - (NE.fromList - [ - LSubLibName - (UnqualComponentName - "hasktorch-indef-signed")]))], + (mkVersion [1, 2, 2]))) + mainLibSet, + Dependency + (PackageName "hasktorch") + (OrLaterVersion (mkVersion [0])) + (NonEmptySet.fromNonEmpty + (NE.fromList + [ + LSubLibName + (UnqualComponentName + "hasktorch-indef-floating")])), + Dependency + (PackageName "hasktorch") + (OrLaterVersion (mkVersion [0])) + (NonEmptySet.fromNonEmpty + (NE.fromList + [ + LSubLibName + (UnqualComponentName + "hasktorch-indef-signed")]))], + privateDependencies = []}, condTreeComponents = [ CondBranch { @@ -2744,8 +2764,12 @@ GenericPackageDescription { PerCompilerFlavor [] [], customFieldsBI = [], targetBuildDepends = [], + targetPrivateBuildDepends = [], mixins = []}}, - condTreeConstraints = [], + condTreeConstraints = + Dependencies { + publicDependencies = [], + privateDependencies = []}, condTreeComponents = []}, condBranchIfFalse = Just @@ -2842,6 +2866,7 @@ GenericPackageDescription { LSubLibName (UnqualComponentName "hasktorch-indef-unsigned")]))], + targetPrivateBuildDepends = [], mixins = [ Mixin { @@ -4840,16 +4865,19 @@ GenericPackageDescription { "Torch.Sig.Tensor.Random.THC") (ModuleName "Torch.Undefined.Float.Tensor.Random.THC")]}}]}}, - condTreeConstraints = [ - Dependency - (PackageName "hasktorch") - (OrLaterVersion (mkVersion [0])) - (NonEmptySet.fromNonEmpty - (NE.fromList - [ - LSubLibName - (UnqualComponentName - "hasktorch-indef-unsigned")]))], + condTreeConstraints = + Dependencies { + publicDependencies = [ + Dependency + (PackageName "hasktorch") + (OrLaterVersion (mkVersion [0])) + (NonEmptySet.fromNonEmpty + (NE.fromList + [ + LSubLibName + (UnqualComponentName + "hasktorch-indef-unsigned")]))], + privateDependencies = []}, condTreeComponents = []}}]}, _×_ (UnqualComponentName @@ -5193,6 +5221,7 @@ GenericPackageDescription { (EarlierVersion (mkVersion [0, 0, 2]))) mainLibSet], + targetPrivateBuildDepends = [], mixins = [ Mixin { @@ -6242,124 +6271,127 @@ GenericPackageDescription { "Torch.Sig.Tensor.Random.THC") (ModuleName "Torch.FFI.THC.Double.TensorRandom")]}}]}}, - condTreeConstraints = [ - Dependency - (PackageName "base") - (IntersectVersionRanges - (UnionVersionRanges - (ThisVersion (mkVersion [4, 7])) - (LaterVersion - (mkVersion [4, 7]))) - (EarlierVersion - (mkVersion [5]))) - mainLibSet, - Dependency - (PackageName - "hasktorch-types-th") - (IntersectVersionRanges - (UnionVersionRanges - (ThisVersion - (mkVersion [0, 0, 1])) - (LaterVersion - (mkVersion [0, 0, 1]))) - (EarlierVersion - (mkVersion [0, 0, 2]))) - mainLibSet, - Dependency - (PackageName "dimensions") - (UnionVersionRanges - (ThisVersion (mkVersion [1, 0])) - (LaterVersion - (mkVersion [1, 0]))) - mainLibSet, - Dependency - (PackageName "hasktorch-ffi-th") - (IntersectVersionRanges + condTreeConstraints = + Dependencies { + publicDependencies = [ + Dependency + (PackageName "base") + (IntersectVersionRanges + (UnionVersionRanges + (ThisVersion (mkVersion [4, 7])) + (LaterVersion + (mkVersion [4, 7]))) + (EarlierVersion + (mkVersion [5]))) + mainLibSet, + Dependency + (PackageName + "hasktorch-types-th") + (IntersectVersionRanges + (UnionVersionRanges + (ThisVersion + (mkVersion [0, 0, 1])) + (LaterVersion + (mkVersion [0, 0, 1]))) + (EarlierVersion + (mkVersion [0, 0, 2]))) + mainLibSet, + Dependency + (PackageName "dimensions") (UnionVersionRanges - (ThisVersion - (mkVersion [0, 0, 1])) + (ThisVersion (mkVersion [1, 0])) (LaterVersion - (mkVersion [0, 0, 1]))) - (EarlierVersion - (mkVersion [0, 0, 2]))) - mainLibSet, - Dependency - (PackageName - "hasktorch-types-th") - (IntersectVersionRanges + (mkVersion [1, 0]))) + mainLibSet, + Dependency + (PackageName "hasktorch-ffi-th") + (IntersectVersionRanges + (UnionVersionRanges + (ThisVersion + (mkVersion [0, 0, 1])) + (LaterVersion + (mkVersion [0, 0, 1]))) + (EarlierVersion + (mkVersion [0, 0, 2]))) + mainLibSet, + Dependency + (PackageName + "hasktorch-types-th") + (IntersectVersionRanges + (UnionVersionRanges + (ThisVersion + (mkVersion [0, 0, 1])) + (LaterVersion + (mkVersion [0, 0, 1]))) + (EarlierVersion + (mkVersion [0, 0, 2]))) + mainLibSet, + Dependency + (PackageName "safe-exceptions") (UnionVersionRanges (ThisVersion - (mkVersion [0, 0, 1])) + (mkVersion [0, 1, 0])) (LaterVersion - (mkVersion [0, 0, 1]))) - (EarlierVersion - (mkVersion [0, 0, 2]))) - mainLibSet, - Dependency - (PackageName "safe-exceptions") - (UnionVersionRanges - (ThisVersion - (mkVersion [0, 1, 0])) - (LaterVersion - (mkVersion [0, 1, 0]))) - mainLibSet, - Dependency - (PackageName "singletons") - (UnionVersionRanges - (ThisVersion (mkVersion [2, 2])) - (LaterVersion - (mkVersion [2, 2]))) - mainLibSet, - Dependency - (PackageName "text") - (UnionVersionRanges - (ThisVersion - (mkVersion [1, 2, 2])) - (LaterVersion - (mkVersion [1, 2, 2]))) - mainLibSet, - Dependency - (PackageName "hasktorch") - (OrLaterVersion (mkVersion [0])) - (NonEmptySet.fromNonEmpty - (NE.fromList - [ - LSubLibName - (UnqualComponentName - "hasktorch-indef-floating")])), - Dependency - (PackageName "hasktorch") - (OrLaterVersion (mkVersion [0])) - (NonEmptySet.fromNonEmpty - (NE.fromList - [ - LSubLibName - (UnqualComponentName - "hasktorch-indef-signed")])), - Dependency - (PackageName - "hasktorch-ffi-thc") - (IntersectVersionRanges + (mkVersion [0, 1, 0]))) + mainLibSet, + Dependency + (PackageName "singletons") (UnionVersionRanges - (ThisVersion - (mkVersion [0, 0, 1])) + (ThisVersion (mkVersion [2, 2])) (LaterVersion - (mkVersion [0, 0, 1]))) - (EarlierVersion - (mkVersion [0, 0, 2]))) - mainLibSet, - Dependency - (PackageName - "hasktorch-types-thc") - (IntersectVersionRanges + (mkVersion [2, 2]))) + mainLibSet, + Dependency + (PackageName "text") (UnionVersionRanges (ThisVersion - (mkVersion [0, 0, 1])) + (mkVersion [1, 2, 2])) (LaterVersion - (mkVersion [0, 0, 1]))) - (EarlierVersion - (mkVersion [0, 0, 2]))) - mainLibSet], + (mkVersion [1, 2, 2]))) + mainLibSet, + Dependency + (PackageName "hasktorch") + (OrLaterVersion (mkVersion [0])) + (NonEmptySet.fromNonEmpty + (NE.fromList + [ + LSubLibName + (UnqualComponentName + "hasktorch-indef-floating")])), + Dependency + (PackageName "hasktorch") + (OrLaterVersion (mkVersion [0])) + (NonEmptySet.fromNonEmpty + (NE.fromList + [ + LSubLibName + (UnqualComponentName + "hasktorch-indef-signed")])), + Dependency + (PackageName + "hasktorch-ffi-thc") + (IntersectVersionRanges + (UnionVersionRanges + (ThisVersion + (mkVersion [0, 0, 1])) + (LaterVersion + (mkVersion [0, 0, 1]))) + (EarlierVersion + (mkVersion [0, 0, 2]))) + mainLibSet, + Dependency + (PackageName + "hasktorch-types-thc") + (IntersectVersionRanges + (UnionVersionRanges + (ThisVersion + (mkVersion [0, 0, 1])) + (LaterVersion + (mkVersion [0, 0, 1]))) + (EarlierVersion + (mkVersion [0, 0, 2]))) + mainLibSet], + privateDependencies = []}, condTreeComponents = [ CondBranch { @@ -6428,8 +6460,12 @@ GenericPackageDescription { PerCompilerFlavor [] [], customFieldsBI = [], targetBuildDepends = [], + targetPrivateBuildDepends = [], mixins = []}}, - condTreeConstraints = [], + condTreeConstraints = + Dependencies { + publicDependencies = [], + privateDependencies = []}, condTreeComponents = []}, condBranchIfFalse = Just @@ -6527,6 +6563,7 @@ GenericPackageDescription { LSubLibName (UnqualComponentName "hasktorch-indef-unsigned")]))], + targetPrivateBuildDepends = [], mixins = [ Mixin { @@ -7823,16 +7860,19 @@ GenericPackageDescription { "Torch.Sig.Tensor.Math.Pointwise.Signed") (ModuleName "Torch.FFI.THC.Int.TensorMathPointwise")]}}]}}, - condTreeConstraints = [ - Dependency - (PackageName "hasktorch") - (OrLaterVersion (mkVersion [0])) - (NonEmptySet.fromNonEmpty - (NE.fromList - [ - LSubLibName - (UnqualComponentName - "hasktorch-indef-unsigned")]))], + condTreeConstraints = + Dependencies { + publicDependencies = [ + Dependency + (PackageName "hasktorch") + (OrLaterVersion (mkVersion [0])) + (NonEmptySet.fromNonEmpty + (NE.fromList + [ + LSubLibName + (UnqualComponentName + "hasktorch-indef-unsigned")]))], + privateDependencies = []}, condTreeComponents = []}}]}, _×_ (UnqualComponentName @@ -8212,6 +8252,7 @@ GenericPackageDescription { (PackageName "hasktorch-indef") (OrLaterVersion (mkVersion [0])) mainLibSet], + targetPrivateBuildDepends = [], mixins = [ Mixin { mixinPackageName = PackageName @@ -8278,33 +8319,36 @@ GenericPackageDescription { "Torch.Sig.Tensor.Random.THC") (ModuleName "Torch.Undefined.Tensor.Random.THC")]}}]}}, - condTreeConstraints = [ - Dependency - (PackageName "base") - (IntersectVersionRanges - (UnionVersionRanges - (ThisVersion (mkVersion [4, 7])) - (LaterVersion - (mkVersion [4, 7]))) - (EarlierVersion - (mkVersion [5]))) - mainLibSet, - Dependency - (PackageName - "hasktorch-signatures-partial") - (IntersectVersionRanges - (UnionVersionRanges - (ThisVersion - (mkVersion [0, 0, 1])) - (LaterVersion - (mkVersion [0, 0, 1]))) - (EarlierVersion - (mkVersion [0, 0, 2]))) - mainLibSet, - Dependency - (PackageName "hasktorch-indef") - (OrLaterVersion (mkVersion [0])) - mainLibSet], + condTreeConstraints = + Dependencies { + publicDependencies = [ + Dependency + (PackageName "base") + (IntersectVersionRanges + (UnionVersionRanges + (ThisVersion (mkVersion [4, 7])) + (LaterVersion + (mkVersion [4, 7]))) + (EarlierVersion + (mkVersion [5]))) + mainLibSet, + Dependency + (PackageName + "hasktorch-signatures-partial") + (IntersectVersionRanges + (UnionVersionRanges + (ThisVersion + (mkVersion [0, 0, 1])) + (LaterVersion + (mkVersion [0, 0, 1]))) + (EarlierVersion + (mkVersion [0, 0, 2]))) + mainLibSet, + Dependency + (PackageName "hasktorch-indef") + (OrLaterVersion (mkVersion [0])) + mainLibSet], + privateDependencies = []}, condTreeComponents = []}, _×_ (UnqualComponentName @@ -8700,6 +8744,7 @@ GenericPackageDescription { (PackageName "hasktorch-indef") (OrLaterVersion (mkVersion [0])) mainLibSet], + targetPrivateBuildDepends = [], mixins = [ Mixin { mixinPackageName = PackageName @@ -8761,33 +8806,36 @@ GenericPackageDescription { "Torch.Sig.Tensor.Random.THC") (ModuleName "Torch.Undefined.Tensor.Random.THC")]}}]}}, - condTreeConstraints = [ - Dependency - (PackageName "base") - (IntersectVersionRanges - (UnionVersionRanges - (ThisVersion (mkVersion [4, 7])) - (LaterVersion - (mkVersion [4, 7]))) - (EarlierVersion - (mkVersion [5]))) - mainLibSet, - Dependency - (PackageName - "hasktorch-signatures-partial") - (IntersectVersionRanges - (UnionVersionRanges - (ThisVersion - (mkVersion [0, 0, 1])) - (LaterVersion - (mkVersion [0, 0, 1]))) - (EarlierVersion - (mkVersion [0, 0, 2]))) - mainLibSet, - Dependency - (PackageName "hasktorch-indef") - (OrLaterVersion (mkVersion [0])) - mainLibSet], + condTreeConstraints = + Dependencies { + publicDependencies = [ + Dependency + (PackageName "base") + (IntersectVersionRanges + (UnionVersionRanges + (ThisVersion (mkVersion [4, 7])) + (LaterVersion + (mkVersion [4, 7]))) + (EarlierVersion + (mkVersion [5]))) + mainLibSet, + Dependency + (PackageName + "hasktorch-signatures-partial") + (IntersectVersionRanges + (UnionVersionRanges + (ThisVersion + (mkVersion [0, 0, 1])) + (LaterVersion + (mkVersion [0, 0, 1]))) + (EarlierVersion + (mkVersion [0, 0, 2]))) + mainLibSet, + Dependency + (PackageName "hasktorch-indef") + (OrLaterVersion (mkVersion [0])) + mainLibSet], + privateDependencies = []}, condTreeComponents = []}, _×_ (UnqualComponentName @@ -9463,34 +9511,38 @@ GenericPackageDescription { (EarlierVersion (mkVersion [0, 0, 2]))) mainLibSet], + targetPrivateBuildDepends = [], mixins = []}}, - condTreeConstraints = [ - Dependency - (PackageName "base") - (IntersectVersionRanges - (UnionVersionRanges - (ThisVersion (mkVersion [4, 7])) - (LaterVersion - (mkVersion [4, 7]))) - (EarlierVersion - (mkVersion [5]))) - mainLibSet, - Dependency - (PackageName "hasktorch-indef") - (OrLaterVersion (mkVersion [0])) - mainLibSet, - Dependency - (PackageName - "hasktorch-signatures-partial") - (IntersectVersionRanges - (UnionVersionRanges - (ThisVersion - (mkVersion [0, 0, 1])) - (LaterVersion - (mkVersion [0, 0, 1]))) - (EarlierVersion - (mkVersion [0, 0, 2]))) - mainLibSet], + condTreeConstraints = + Dependencies { + publicDependencies = [ + Dependency + (PackageName "base") + (IntersectVersionRanges + (UnionVersionRanges + (ThisVersion (mkVersion [4, 7])) + (LaterVersion + (mkVersion [4, 7]))) + (EarlierVersion + (mkVersion [5]))) + mainLibSet, + Dependency + (PackageName "hasktorch-indef") + (OrLaterVersion (mkVersion [0])) + mainLibSet, + Dependency + (PackageName + "hasktorch-signatures-partial") + (IntersectVersionRanges + (UnionVersionRanges + (ThisVersion + (mkVersion [0, 0, 1])) + (LaterVersion + (mkVersion [0, 0, 1]))) + (EarlierVersion + (mkVersion [0, 0, 2]))) + mainLibSet], + privateDependencies = []}, condTreeComponents = []}], condForeignLibs = [], condExecutables = [ @@ -9577,27 +9629,31 @@ GenericPackageDescription { LSubLibName (UnqualComponentName "hasktorch-cpu")]))], + targetPrivateBuildDepends = [], mixins = []}}, - condTreeConstraints = [ - Dependency - (PackageName "base") - (IntersectVersionRanges - (UnionVersionRanges - (ThisVersion (mkVersion [4, 7])) - (LaterVersion - (mkVersion [4, 7]))) - (EarlierVersion - (mkVersion [5]))) - mainLibSet, - Dependency - (PackageName "hasktorch") - (OrLaterVersion (mkVersion [0])) - (NonEmptySet.fromNonEmpty - (NE.fromList - [ - LSubLibName - (UnqualComponentName - "hasktorch-cpu")]))], + condTreeConstraints = + Dependencies { + publicDependencies = [ + Dependency + (PackageName "base") + (IntersectVersionRanges + (UnionVersionRanges + (ThisVersion (mkVersion [4, 7])) + (LaterVersion + (mkVersion [4, 7]))) + (EarlierVersion + (mkVersion [5]))) + mainLibSet, + Dependency + (PackageName "hasktorch") + (OrLaterVersion (mkVersion [0])) + (NonEmptySet.fromNonEmpty + (NE.fromList + [ + LSubLibName + (UnqualComponentName + "hasktorch-cpu")]))], + privateDependencies = []}, condTreeComponents = []}, _×_ (UnqualComponentName @@ -9682,27 +9738,31 @@ GenericPackageDescription { LSubLibName (UnqualComponentName "hasktorch-gpu")]))], + targetPrivateBuildDepends = [], mixins = []}}, - condTreeConstraints = [ - Dependency - (PackageName "base") - (IntersectVersionRanges - (UnionVersionRanges - (ThisVersion (mkVersion [4, 7])) - (LaterVersion - (mkVersion [4, 7]))) - (EarlierVersion - (mkVersion [5]))) - mainLibSet, - Dependency - (PackageName "hasktorch") - (OrLaterVersion (mkVersion [0])) - (NonEmptySet.fromNonEmpty - (NE.fromList - [ - LSubLibName - (UnqualComponentName - "hasktorch-gpu")]))], + condTreeConstraints = + Dependencies { + publicDependencies = [ + Dependency + (PackageName "base") + (IntersectVersionRanges + (UnionVersionRanges + (ThisVersion (mkVersion [4, 7])) + (LaterVersion + (mkVersion [4, 7]))) + (EarlierVersion + (mkVersion [5]))) + mainLibSet, + Dependency + (PackageName "hasktorch") + (OrLaterVersion (mkVersion [0])) + (NonEmptySet.fromNonEmpty + (NE.fromList + [ + LSubLibName + (UnqualComponentName + "hasktorch-gpu")]))], + privateDependencies = []}, condTreeComponents = []}, _×_ (UnqualComponentName @@ -9782,22 +9842,26 @@ GenericPackageDescription { (PackageName "hasktorch") (OrLaterVersion (mkVersion [0])) mainLibSet], + targetPrivateBuildDepends = [], mixins = []}}, - condTreeConstraints = [ - Dependency - (PackageName "base") - (IntersectVersionRanges - (UnionVersionRanges - (ThisVersion (mkVersion [4, 7])) - (LaterVersion - (mkVersion [4, 7]))) - (EarlierVersion - (mkVersion [5]))) - mainLibSet, - Dependency - (PackageName "hasktorch") - (OrLaterVersion (mkVersion [0])) - mainLibSet], + condTreeConstraints = + Dependencies { + publicDependencies = [ + Dependency + (PackageName "base") + (IntersectVersionRanges + (UnionVersionRanges + (ThisVersion (mkVersion [4, 7])) + (LaterVersion + (mkVersion [4, 7]))) + (EarlierVersion + (mkVersion [5]))) + mainLibSet, + Dependency + (PackageName "hasktorch") + (OrLaterVersion (mkVersion [0])) + mainLibSet], + privateDependencies = []}, condTreeComponents = []}, _×_ (UnqualComponentName "memcheck") @@ -9876,22 +9940,26 @@ GenericPackageDescription { (PackageName "hasktorch") (OrLaterVersion (mkVersion [0])) mainLibSet], + targetPrivateBuildDepends = [], mixins = []}}, - condTreeConstraints = [ - Dependency - (PackageName "base") - (IntersectVersionRanges - (UnionVersionRanges - (ThisVersion (mkVersion [4, 7])) - (LaterVersion - (mkVersion [4, 7]))) - (EarlierVersion - (mkVersion [5]))) - mainLibSet, - Dependency - (PackageName "hasktorch") - (OrLaterVersion (mkVersion [0])) - mainLibSet], + condTreeConstraints = + Dependencies { + publicDependencies = [ + Dependency + (PackageName "base") + (IntersectVersionRanges + (UnionVersionRanges + (ThisVersion (mkVersion [4, 7])) + (LaterVersion + (mkVersion [4, 7]))) + (EarlierVersion + (mkVersion [5]))) + mainLibSet, + Dependency + (PackageName "hasktorch") + (OrLaterVersion (mkVersion [0])) + mainLibSet], + privateDependencies = []}, condTreeComponents = []}], condTestSuites = [ _×_ @@ -10084,110 +10152,114 @@ GenericPackageDescription { (PackageName "generic-lens") (OrLaterVersion (mkVersion [0])) mainLibSet], + targetPrivateBuildDepends = [], mixins = []}, testCodeGenerators = []}, - condTreeConstraints = [ - Dependency - (PackageName "QuickCheck") - (UnionVersionRanges - (ThisVersion - (mkVersion [2, 11])) - (LaterVersion - (mkVersion [2, 11]))) - mainLibSet, - Dependency - (PackageName "backprop") - (UnionVersionRanges - (ThisVersion - (mkVersion [0, 2, 5])) - (LaterVersion - (mkVersion [0, 2, 5]))) - mainLibSet, - Dependency - (PackageName "base") - (IntersectVersionRanges + condTreeConstraints = + Dependencies { + publicDependencies = [ + Dependency + (PackageName "QuickCheck") (UnionVersionRanges - (ThisVersion (mkVersion [4, 7])) + (ThisVersion + (mkVersion [2, 11])) (LaterVersion - (mkVersion [4, 7]))) - (EarlierVersion - (mkVersion [5]))) - mainLibSet, - Dependency - (PackageName "dimensions") - (UnionVersionRanges - (ThisVersion (mkVersion [1, 0])) - (LaterVersion - (mkVersion [1, 0]))) - mainLibSet, - Dependency - (PackageName - "ghc-typelits-natnormalise") - (OrLaterVersion (mkVersion [0])) - mainLibSet, - Dependency - (PackageName "hasktorch") - (OrLaterVersion (mkVersion [0])) - mainLibSet, - Dependency - (PackageName "hspec") - (UnionVersionRanges - (ThisVersion - (mkVersion [2, 4, 4])) - (LaterVersion - (mkVersion [2, 4, 4]))) - mainLibSet, - Dependency - (PackageName "singletons") - (UnionVersionRanges - (ThisVersion (mkVersion [2, 2])) - (LaterVersion - (mkVersion [2, 2]))) - mainLibSet, - Dependency - (PackageName "mtl") - (UnionVersionRanges - (ThisVersion - (mkVersion [2, 2, 2])) - (LaterVersion - (mkVersion [2, 2, 2]))) - mainLibSet, - Dependency - (PackageName - "microlens-platform") - (UnionVersionRanges - (ThisVersion - (mkVersion [0, 3, 10])) - (LaterVersion - (mkVersion [0, 3, 10]))) - mainLibSet, - Dependency - (PackageName "monad-loops") - (UnionVersionRanges - (ThisVersion - (mkVersion [0, 4, 3])) - (LaterVersion - (mkVersion [0, 4, 3]))) - mainLibSet, - Dependency - (PackageName "time") - (UnionVersionRanges - (ThisVersion - (mkVersion [1, 8, 0])) - (LaterVersion - (mkVersion [1, 8, 0]))) - mainLibSet, - Dependency - (PackageName "transformers") - (UnionVersionRanges - (ThisVersion - (mkVersion [0, 5, 5])) - (LaterVersion - (mkVersion [0, 5, 5]))) - mainLibSet, - Dependency - (PackageName "generic-lens") - (OrLaterVersion (mkVersion [0])) - mainLibSet], + (mkVersion [2, 11]))) + mainLibSet, + Dependency + (PackageName "backprop") + (UnionVersionRanges + (ThisVersion + (mkVersion [0, 2, 5])) + (LaterVersion + (mkVersion [0, 2, 5]))) + mainLibSet, + Dependency + (PackageName "base") + (IntersectVersionRanges + (UnionVersionRanges + (ThisVersion (mkVersion [4, 7])) + (LaterVersion + (mkVersion [4, 7]))) + (EarlierVersion + (mkVersion [5]))) + mainLibSet, + Dependency + (PackageName "dimensions") + (UnionVersionRanges + (ThisVersion (mkVersion [1, 0])) + (LaterVersion + (mkVersion [1, 0]))) + mainLibSet, + Dependency + (PackageName + "ghc-typelits-natnormalise") + (OrLaterVersion (mkVersion [0])) + mainLibSet, + Dependency + (PackageName "hasktorch") + (OrLaterVersion (mkVersion [0])) + mainLibSet, + Dependency + (PackageName "hspec") + (UnionVersionRanges + (ThisVersion + (mkVersion [2, 4, 4])) + (LaterVersion + (mkVersion [2, 4, 4]))) + mainLibSet, + Dependency + (PackageName "singletons") + (UnionVersionRanges + (ThisVersion (mkVersion [2, 2])) + (LaterVersion + (mkVersion [2, 2]))) + mainLibSet, + Dependency + (PackageName "mtl") + (UnionVersionRanges + (ThisVersion + (mkVersion [2, 2, 2])) + (LaterVersion + (mkVersion [2, 2, 2]))) + mainLibSet, + Dependency + (PackageName + "microlens-platform") + (UnionVersionRanges + (ThisVersion + (mkVersion [0, 3, 10])) + (LaterVersion + (mkVersion [0, 3, 10]))) + mainLibSet, + Dependency + (PackageName "monad-loops") + (UnionVersionRanges + (ThisVersion + (mkVersion [0, 4, 3])) + (LaterVersion + (mkVersion [0, 4, 3]))) + mainLibSet, + Dependency + (PackageName "time") + (UnionVersionRanges + (ThisVersion + (mkVersion [1, 8, 0])) + (LaterVersion + (mkVersion [1, 8, 0]))) + mainLibSet, + Dependency + (PackageName "transformers") + (UnionVersionRanges + (ThisVersion + (mkVersion [0, 5, 5])) + (LaterVersion + (mkVersion [0, 5, 5]))) + mainLibSet, + Dependency + (PackageName "generic-lens") + (OrLaterVersion (mkVersion [0])) + mainLibSet], + privateDependencies = []}, condTreeComponents = []}], condBenchmarks = []} diff --git a/Cabal-tests/tests/ParserTests/regressions/hidden-main-lib.expr b/Cabal-tests/tests/ParserTests/regressions/hidden-main-lib.expr index fba99528b53..c341d178084 100644 --- a/Cabal-tests/tests/ParserTests/regressions/hidden-main-lib.expr +++ b/Cabal-tests/tests/ParserTests/regressions/hidden-main-lib.expr @@ -105,12 +105,16 @@ GenericPackageDescription { (PackageName "base") (OrLaterVersion (mkVersion [0])) mainLibSet], + targetPrivateBuildDepends = [], mixins = []}}, - condTreeConstraints = [ - Dependency - (PackageName "base") - (OrLaterVersion (mkVersion [0])) - mainLibSet], + condTreeConstraints = + Dependencies { + publicDependencies = [ + Dependency + (PackageName "base") + (OrLaterVersion (mkVersion [0])) + mainLibSet], + privateDependencies = []}, condTreeComponents = []}, condSubLibraries = [], condForeignLibs = [], diff --git a/Cabal-tests/tests/ParserTests/regressions/indentation.expr b/Cabal-tests/tests/ParserTests/regressions/indentation.expr index e5b106dc5cd..88a6c09c396 100644 --- a/Cabal-tests/tests/ParserTests/regressions/indentation.expr +++ b/Cabal-tests/tests/ParserTests/regressions/indentation.expr @@ -110,8 +110,12 @@ GenericPackageDescription { PerCompilerFlavor [] [], customFieldsBI = [], targetBuildDepends = [], + targetPrivateBuildDepends = [], mixins = []}}, - condTreeConstraints = [], + condTreeConstraints = + Dependencies { + publicDependencies = [], + privateDependencies = []}, condTreeComponents = []}, condSubLibraries = [], condForeignLibs = [], diff --git a/Cabal-tests/tests/ParserTests/regressions/indentation2.expr b/Cabal-tests/tests/ParserTests/regressions/indentation2.expr index 46f24105f0f..755195fc848 100644 --- a/Cabal-tests/tests/ParserTests/regressions/indentation2.expr +++ b/Cabal-tests/tests/ParserTests/regressions/indentation2.expr @@ -103,8 +103,12 @@ GenericPackageDescription { PerCompilerFlavor [] [], customFieldsBI = [], targetBuildDepends = [], + targetPrivateBuildDepends = [], mixins = []}}, - condTreeConstraints = [], + condTreeConstraints = + Dependencies { + publicDependencies = [], + privateDependencies = []}, condTreeComponents = []}, condSubLibraries = [], condForeignLibs = [], diff --git a/Cabal-tests/tests/ParserTests/regressions/indentation3.expr b/Cabal-tests/tests/ParserTests/regressions/indentation3.expr index 0191d063f6e..db211c2be9c 100644 --- a/Cabal-tests/tests/ParserTests/regressions/indentation3.expr +++ b/Cabal-tests/tests/ParserTests/regressions/indentation3.expr @@ -105,8 +105,12 @@ GenericPackageDescription { PerCompilerFlavor [] [], customFieldsBI = [], targetBuildDepends = [], + targetPrivateBuildDepends = [], mixins = []}}, - condTreeConstraints = [], + condTreeConstraints = + Dependencies { + publicDependencies = [], + privateDependencies = []}, condTreeComponents = []}, condSubLibraries = [], condForeignLibs = [], diff --git a/Cabal-tests/tests/ParserTests/regressions/issue-5055.expr b/Cabal-tests/tests/ParserTests/regressions/issue-5055.expr index 07c04ec6cb9..ee3554212a0 100644 --- a/Cabal-tests/tests/ParserTests/regressions/issue-5055.expr +++ b/Cabal-tests/tests/ParserTests/regressions/issue-5055.expr @@ -112,16 +112,20 @@ GenericPackageDescription { (EarlierVersion (mkVersion [5]))) mainLibSet], + targetPrivateBuildDepends = [], mixins = []}}, - condTreeConstraints = [ - Dependency - (PackageName "base") - (IntersectVersionRanges - (OrLaterVersion - (mkVersion [4, 8])) - (EarlierVersion - (mkVersion [5]))) - mainLibSet], + condTreeConstraints = + Dependencies { + publicDependencies = [ + Dependency + (PackageName "base") + (IntersectVersionRanges + (OrLaterVersion + (mkVersion [4, 8])) + (EarlierVersion + (mkVersion [5]))) + mainLibSet], + privateDependencies = []}, condTreeComponents = []}], condTestSuites = [ _×_ @@ -195,17 +199,21 @@ GenericPackageDescription { (EarlierVersion (mkVersion [5]))) mainLibSet], + targetPrivateBuildDepends = [], mixins = []}, testCodeGenerators = []}, - condTreeConstraints = [ - Dependency - (PackageName "base") - (IntersectVersionRanges - (OrLaterVersion - (mkVersion [4, 8])) - (EarlierVersion - (mkVersion [5]))) - mainLibSet], + condTreeConstraints = + Dependencies { + publicDependencies = [ + Dependency + (PackageName "base") + (IntersectVersionRanges + (OrLaterVersion + (mkVersion [4, 8])) + (EarlierVersion + (mkVersion [5]))) + mainLibSet], + privateDependencies = []}, condTreeComponents = [ CondBranch { condBranchCondition = @@ -271,9 +279,13 @@ GenericPackageDescription { PerCompilerFlavor [] [], customFieldsBI = [], targetBuildDepends = [], + targetPrivateBuildDepends = [], mixins = []}, testCodeGenerators = []}, - condTreeConstraints = [], + condTreeConstraints = + Dependencies { + publicDependencies = [], + privateDependencies = []}, condTreeComponents = []}, condBranchIfFalse = Nothing}]}], condBenchmarks = []} diff --git a/Cabal-tests/tests/ParserTests/regressions/issue-5846.expr b/Cabal-tests/tests/ParserTests/regressions/issue-5846.expr index 2ff7de7917e..86bdde11186 100644 --- a/Cabal-tests/tests/ParserTests/regressions/issue-5846.expr +++ b/Cabal-tests/tests/ParserTests/regressions/issue-5846.expr @@ -134,44 +134,48 @@ GenericPackageDescription { (UnqualComponentName "a"), LSubLibName (UnqualComponentName "b")]))], + targetPrivateBuildDepends = [], mixins = []}}, - condTreeConstraints = [ - Dependency - (PackageName "lib1") - (OrLaterVersion (mkVersion [0])) - (NonEmptySet.fromNonEmpty - (NE.fromList - [ - LSubLibName - (UnqualComponentName "a"), - LSubLibName - (UnqualComponentName "b")])), - Dependency - (PackageName "lib2") - (OrLaterVersion (mkVersion [0])) - (NonEmptySet.fromNonEmpty - (NE.fromList - [ - LSubLibName - (UnqualComponentName "c")])), - Dependency - (PackageName "lib3") - (OrLaterVersion (mkVersion [1])) - (NonEmptySet.fromNonEmpty - (NE.fromList - [ - LSubLibName - (UnqualComponentName "d")])), - Dependency - (PackageName "lib4") - (OrLaterVersion (mkVersion [1])) - (NonEmptySet.fromNonEmpty - (NE.fromList - [ - LSubLibName - (UnqualComponentName "a"), - LSubLibName - (UnqualComponentName "b")]))], + condTreeConstraints = + Dependencies { + publicDependencies = [ + Dependency + (PackageName "lib1") + (OrLaterVersion (mkVersion [0])) + (NonEmptySet.fromNonEmpty + (NE.fromList + [ + LSubLibName + (UnqualComponentName "a"), + LSubLibName + (UnqualComponentName "b")])), + Dependency + (PackageName "lib2") + (OrLaterVersion (mkVersion [0])) + (NonEmptySet.fromNonEmpty + (NE.fromList + [ + LSubLibName + (UnqualComponentName "c")])), + Dependency + (PackageName "lib3") + (OrLaterVersion (mkVersion [1])) + (NonEmptySet.fromNonEmpty + (NE.fromList + [ + LSubLibName + (UnqualComponentName "d")])), + Dependency + (PackageName "lib4") + (OrLaterVersion (mkVersion [1])) + (NonEmptySet.fromNonEmpty + (NE.fromList + [ + LSubLibName + (UnqualComponentName "a"), + LSubLibName + (UnqualComponentName "b")]))], + privateDependencies = []}, condTreeComponents = []}, condSubLibraries = [], condForeignLibs = [], diff --git a/Cabal-tests/tests/ParserTests/regressions/issue-6083-a.expr b/Cabal-tests/tests/ParserTests/regressions/issue-6083-a.expr index 43c345dd170..3d5861da196 100644 --- a/Cabal-tests/tests/ParserTests/regressions/issue-6083-a.expr +++ b/Cabal-tests/tests/ParserTests/regressions/issue-6083-a.expr @@ -111,21 +111,25 @@ GenericPackageDescription { LSubLibName (UnqualComponentName "sublib")]))], + targetPrivateBuildDepends = [], mixins = []}}, - condTreeConstraints = [ - Dependency - (PackageName "base") - (OrLaterVersion (mkVersion [0])) - mainLibSet, - Dependency - (PackageName "issue") - (OrLaterVersion (mkVersion [0])) - (NonEmptySet.fromNonEmpty - (NE.fromList - [ - LSubLibName - (UnqualComponentName - "sublib")]))], + condTreeConstraints = + Dependencies { + publicDependencies = [ + Dependency + (PackageName "base") + (OrLaterVersion (mkVersion [0])) + mainLibSet, + Dependency + (PackageName "issue") + (OrLaterVersion (mkVersion [0])) + (NonEmptySet.fromNonEmpty + (NE.fromList + [ + LSubLibName + (UnqualComponentName + "sublib")]))], + privateDependencies = []}, condTreeComponents = []}, condSubLibraries = [ _×_ @@ -193,8 +197,12 @@ GenericPackageDescription { PerCompilerFlavor [] [], customFieldsBI = [], targetBuildDepends = [], + targetPrivateBuildDepends = [], mixins = []}}, - condTreeConstraints = [], + condTreeConstraints = + Dependencies { + publicDependencies = [], + privateDependencies = []}, condTreeComponents = []}], condForeignLibs = [], condExecutables = [ @@ -267,16 +275,20 @@ GenericPackageDescription { (PackageName "sublib") (OrLaterVersion (mkVersion [0])) mainLibSet], + targetPrivateBuildDepends = [], mixins = []}}, - condTreeConstraints = [ - Dependency - (PackageName "issue") - (OrLaterVersion (mkVersion [0])) - mainLibSet, - Dependency - (PackageName "sublib") - (OrLaterVersion (mkVersion [0])) - mainLibSet], + condTreeConstraints = + Dependencies { + publicDependencies = [ + Dependency + (PackageName "issue") + (OrLaterVersion (mkVersion [0])) + mainLibSet, + Dependency + (PackageName "sublib") + (OrLaterVersion (mkVersion [0])) + mainLibSet], + privateDependencies = []}, condTreeComponents = []}, _×_ (UnqualComponentName "demo-b") @@ -352,21 +364,25 @@ GenericPackageDescription { LSubLibName (UnqualComponentName "sublib")]))], + targetPrivateBuildDepends = [], mixins = []}}, - condTreeConstraints = [ - Dependency - (PackageName "issue") - (OrLaterVersion (mkVersion [0])) - mainLibSet, - Dependency - (PackageName "issue") - (OrLaterVersion (mkVersion [0])) - (NonEmptySet.fromNonEmpty - (NE.fromList - [ - LSubLibName - (UnqualComponentName - "sublib")]))], + condTreeConstraints = + Dependencies { + publicDependencies = [ + Dependency + (PackageName "issue") + (OrLaterVersion (mkVersion [0])) + mainLibSet, + Dependency + (PackageName "issue") + (OrLaterVersion (mkVersion [0])) + (NonEmptySet.fromNonEmpty + (NE.fromList + [ + LSubLibName + (UnqualComponentName + "sublib")]))], + privateDependencies = []}, condTreeComponents = []}], condTestSuites = [], condBenchmarks = []} diff --git a/Cabal-tests/tests/ParserTests/regressions/issue-6083-b.expr b/Cabal-tests/tests/ParserTests/regressions/issue-6083-b.expr index e6606851627..7de6fff480d 100644 --- a/Cabal-tests/tests/ParserTests/regressions/issue-6083-b.expr +++ b/Cabal-tests/tests/ParserTests/regressions/issue-6083-b.expr @@ -111,21 +111,25 @@ GenericPackageDescription { LSubLibName (UnqualComponentName "sublib")]))], + targetPrivateBuildDepends = [], mixins = []}}, - condTreeConstraints = [ - Dependency - (PackageName "base") - (OrLaterVersion (mkVersion [0])) - mainLibSet, - Dependency - (PackageName "issue") - (OrLaterVersion (mkVersion [0])) - (NonEmptySet.fromNonEmpty - (NE.fromList - [ - LSubLibName - (UnqualComponentName - "sublib")]))], + condTreeConstraints = + Dependencies { + publicDependencies = [ + Dependency + (PackageName "base") + (OrLaterVersion (mkVersion [0])) + mainLibSet, + Dependency + (PackageName "issue") + (OrLaterVersion (mkVersion [0])) + (NonEmptySet.fromNonEmpty + (NE.fromList + [ + LSubLibName + (UnqualComponentName + "sublib")]))], + privateDependencies = []}, condTreeComponents = []}, condSubLibraries = [ _×_ @@ -193,8 +197,12 @@ GenericPackageDescription { PerCompilerFlavor [] [], customFieldsBI = [], targetBuildDepends = [], + targetPrivateBuildDepends = [], mixins = []}}, - condTreeConstraints = [], + condTreeConstraints = + Dependencies { + publicDependencies = [], + privateDependencies = []}, condTreeComponents = []}], condForeignLibs = [], condExecutables = [ @@ -272,21 +280,25 @@ GenericPackageDescription { LSubLibName (UnqualComponentName "sublib")]))], + targetPrivateBuildDepends = [], mixins = []}}, - condTreeConstraints = [ - Dependency - (PackageName "issue") - (OrLaterVersion (mkVersion [0])) - mainLibSet, - Dependency - (PackageName "issue") - (OrLaterVersion (mkVersion [0])) - (NonEmptySet.fromNonEmpty - (NE.fromList - [ - LSubLibName - (UnqualComponentName - "sublib")]))], + condTreeConstraints = + Dependencies { + publicDependencies = [ + Dependency + (PackageName "issue") + (OrLaterVersion (mkVersion [0])) + mainLibSet, + Dependency + (PackageName "issue") + (OrLaterVersion (mkVersion [0])) + (NonEmptySet.fromNonEmpty + (NE.fromList + [ + LSubLibName + (UnqualComponentName + "sublib")]))], + privateDependencies = []}, condTreeComponents = []}, _×_ (UnqualComponentName "demo-b") @@ -362,21 +374,25 @@ GenericPackageDescription { LSubLibName (UnqualComponentName "sublib")]))], + targetPrivateBuildDepends = [], mixins = []}}, - condTreeConstraints = [ - Dependency - (PackageName "issue") - (OrLaterVersion (mkVersion [0])) - mainLibSet, - Dependency - (PackageName "issue") - (OrLaterVersion (mkVersion [0])) - (NonEmptySet.fromNonEmpty - (NE.fromList - [ - LSubLibName - (UnqualComponentName - "sublib")]))], + condTreeConstraints = + Dependencies { + publicDependencies = [ + Dependency + (PackageName "issue") + (OrLaterVersion (mkVersion [0])) + mainLibSet, + Dependency + (PackageName "issue") + (OrLaterVersion (mkVersion [0])) + (NonEmptySet.fromNonEmpty + (NE.fromList + [ + LSubLibName + (UnqualComponentName + "sublib")]))], + privateDependencies = []}, condTreeComponents = []}], condTestSuites = [], condBenchmarks = []} diff --git a/Cabal-tests/tests/ParserTests/regressions/issue-6083-c.expr b/Cabal-tests/tests/ParserTests/regressions/issue-6083-c.expr index 7435b0d59b4..aaafb65ceed 100644 --- a/Cabal-tests/tests/ParserTests/regressions/issue-6083-c.expr +++ b/Cabal-tests/tests/ParserTests/regressions/issue-6083-c.expr @@ -111,21 +111,25 @@ GenericPackageDescription { LSubLibName (UnqualComponentName "sublib")]))], + targetPrivateBuildDepends = [], mixins = []}}, - condTreeConstraints = [ - Dependency - (PackageName "base") - (OrLaterVersion (mkVersion [0])) - mainLibSet, - Dependency - (PackageName "issue") - (OrLaterVersion (mkVersion [0])) - (NonEmptySet.fromNonEmpty - (NE.fromList - [ - LSubLibName - (UnqualComponentName - "sublib")]))], + condTreeConstraints = + Dependencies { + publicDependencies = [ + Dependency + (PackageName "base") + (OrLaterVersion (mkVersion [0])) + mainLibSet, + Dependency + (PackageName "issue") + (OrLaterVersion (mkVersion [0])) + (NonEmptySet.fromNonEmpty + (NE.fromList + [ + LSubLibName + (UnqualComponentName + "sublib")]))], + privateDependencies = []}, condTreeComponents = []}, condSubLibraries = [ _×_ @@ -193,8 +197,12 @@ GenericPackageDescription { PerCompilerFlavor [] [], customFieldsBI = [], targetBuildDepends = [], + targetPrivateBuildDepends = [], mixins = []}}, - condTreeConstraints = [], + condTreeConstraints = + Dependencies { + publicDependencies = [], + privateDependencies = []}, condTreeComponents = []}], condForeignLibs = [], condExecutables = [], diff --git a/Cabal-tests/tests/ParserTests/regressions/issue-6083-pkg-pkg.expr b/Cabal-tests/tests/ParserTests/regressions/issue-6083-pkg-pkg.expr index a221632efa4..bd946d92f0d 100644 --- a/Cabal-tests/tests/ParserTests/regressions/issue-6083-pkg-pkg.expr +++ b/Cabal-tests/tests/ParserTests/regressions/issue-6083-pkg-pkg.expr @@ -106,16 +106,20 @@ GenericPackageDescription { (PackageName "freetype") (OrLaterVersion (mkVersion [0])) mainLibSet], + targetPrivateBuildDepends = [], mixins = []}}, - condTreeConstraints = [ - Dependency - (PackageName "freetype") - (OrLaterVersion (mkVersion [0])) - mainLibSet, - Dependency - (PackageName "freetype") - (OrLaterVersion (mkVersion [0])) - mainLibSet], + condTreeConstraints = + Dependencies { + publicDependencies = [ + Dependency + (PackageName "freetype") + (OrLaterVersion (mkVersion [0])) + mainLibSet, + Dependency + (PackageName "freetype") + (OrLaterVersion (mkVersion [0])) + mainLibSet], + privateDependencies = []}, condTreeComponents = []}, condSubLibraries = [], condForeignLibs = [], diff --git a/Cabal-tests/tests/ParserTests/regressions/issue-774.expr b/Cabal-tests/tests/ParserTests/regressions/issue-774.expr index e1ffb85dceb..eb23ebfb0b0 100644 --- a/Cabal-tests/tests/ParserTests/regressions/issue-774.expr +++ b/Cabal-tests/tests/ParserTests/regressions/issue-774.expr @@ -112,8 +112,12 @@ GenericPackageDescription { PerCompilerFlavor [] [], customFieldsBI = [], targetBuildDepends = [], + targetPrivateBuildDepends = [], mixins = []}}, - condTreeConstraints = [], + condTreeConstraints = + Dependencies { + publicDependencies = [], + privateDependencies = []}, condTreeComponents = []}, condSubLibraries = [], condForeignLibs = [], diff --git a/Cabal-tests/tests/ParserTests/regressions/jaeger-flamegraph.expr b/Cabal-tests/tests/ParserTests/regressions/jaeger-flamegraph.expr index c9e675ceb76..d4dacada3a3 100644 --- a/Cabal-tests/tests/ParserTests/regressions/jaeger-flamegraph.expr +++ b/Cabal-tests/tests/ParserTests/regressions/jaeger-flamegraph.expr @@ -156,21 +156,25 @@ GenericPackageDescription { (MajorBoundVersion (mkVersion [2, 12, 6, 1])) mainLibSet], + targetPrivateBuildDepends = [], mixins = []}}, - condTreeConstraints = [ - Dependency - (PackageName "base") - (UnionVersionRanges - (MajorBoundVersion - (mkVersion [4, 11, 1, 0])) + condTreeConstraints = + Dependencies { + publicDependencies = [ + Dependency + (PackageName "base") + (UnionVersionRanges + (MajorBoundVersion + (mkVersion [4, 11, 1, 0])) + (MajorBoundVersion + (mkVersion [4, 12, 0, 0]))) + mainLibSet, + Dependency + (PackageName "QuickCheck") (MajorBoundVersion - (mkVersion [4, 12, 0, 0]))) - mainLibSet, - Dependency - (PackageName "QuickCheck") - (MajorBoundVersion - (mkVersion [2, 12, 6, 1])) - mainLibSet], + (mkVersion [2, 12, 6, 1])) + mainLibSet], + privateDependencies = []}, condTreeComponents = []}, condSubLibraries = [], condForeignLibs = [], @@ -286,52 +290,56 @@ GenericPackageDescription { (MajorBoundVersion (mkVersion [1, 2, 3, 1])) mainLibSet], + targetPrivateBuildDepends = [], mixins = []}}, - condTreeConstraints = [ - Dependency - (PackageName "base") - (UnionVersionRanges + condTreeConstraints = + Dependencies { + publicDependencies = [ + Dependency + (PackageName "base") + (UnionVersionRanges + (MajorBoundVersion + (mkVersion [4, 11, 1, 0])) + (MajorBoundVersion + (mkVersion [4, 12, 0, 0]))) + mainLibSet, + Dependency + (PackageName + "jaeger-flamegraph") + (OrLaterVersion (mkVersion [0])) + mainLibSet, + Dependency + (PackageName "bytestring") (MajorBoundVersion - (mkVersion [4, 11, 1, 0])) + (mkVersion [0, 10, 8, 2])) + mainLibSet, + Dependency + (PackageName "containers") (MajorBoundVersion - (mkVersion [4, 12, 0, 0]))) - mainLibSet, - Dependency - (PackageName - "jaeger-flamegraph") - (OrLaterVersion (mkVersion [0])) - mainLibSet, - Dependency - (PackageName "bytestring") - (MajorBoundVersion - (mkVersion [0, 10, 8, 2])) - mainLibSet, - Dependency - (PackageName "containers") - (MajorBoundVersion - (mkVersion [0, 6, 0, 1])) - mainLibSet, - Dependency - (PackageName "extra") - (MajorBoundVersion - (mkVersion [1, 6, 13])) - mainLibSet, - Dependency - (PackageName "aeson") - (MajorBoundVersion - (mkVersion [1, 4, 1, 0])) - mainLibSet, - Dependency - (PackageName - "optparse-applicative") - (MajorBoundVersion - (mkVersion [0, 14, 3, 0])) - mainLibSet, - Dependency - (PackageName "text") - (MajorBoundVersion - (mkVersion [1, 2, 3, 1])) - mainLibSet], + (mkVersion [0, 6, 0, 1])) + mainLibSet, + Dependency + (PackageName "extra") + (MajorBoundVersion + (mkVersion [1, 6, 13])) + mainLibSet, + Dependency + (PackageName "aeson") + (MajorBoundVersion + (mkVersion [1, 4, 1, 0])) + mainLibSet, + Dependency + (PackageName + "optparse-applicative") + (MajorBoundVersion + (mkVersion [0, 14, 3, 0])) + mainLibSet, + Dependency + (PackageName "text") + (MajorBoundVersion + (mkVersion [1, 2, 3, 1])) + mainLibSet], + privateDependencies = []}, condTreeComponents = []}], condTestSuites = [ _×_ @@ -435,36 +443,40 @@ GenericPackageDescription { (MajorBoundVersion (mkVersion [0, 10])) mainLibSet], + targetPrivateBuildDepends = [], mixins = []}, testCodeGenerators = []}, - condTreeConstraints = [ - Dependency - (PackageName "base") - (UnionVersionRanges + condTreeConstraints = + Dependencies { + publicDependencies = [ + Dependency + (PackageName "base") + (UnionVersionRanges + (MajorBoundVersion + (mkVersion [4, 11, 1, 0])) + (MajorBoundVersion + (mkVersion [4, 12, 0, 0]))) + mainLibSet, + Dependency + (PackageName + "jaeger-flamegraph") + (OrLaterVersion (mkVersion [0])) + mainLibSet, + Dependency + (PackageName "tasty") (MajorBoundVersion - (mkVersion [4, 11, 1, 0])) + (mkVersion [1, 1, 0, 4])) + mainLibSet, + Dependency + (PackageName "tasty-hspec") (MajorBoundVersion - (mkVersion [4, 12, 0, 0]))) - mainLibSet, - Dependency - (PackageName - "jaeger-flamegraph") - (OrLaterVersion (mkVersion [0])) - mainLibSet, - Dependency - (PackageName "tasty") - (MajorBoundVersion - (mkVersion [1, 1, 0, 4])) - mainLibSet, - Dependency - (PackageName "tasty-hspec") - (MajorBoundVersion - (mkVersion [1, 1, 5])) - mainLibSet, - Dependency - (PackageName "tasty-quickcheck") - (MajorBoundVersion - (mkVersion [0, 10])) - mainLibSet], + (mkVersion [1, 1, 5])) + mainLibSet, + Dependency + (PackageName "tasty-quickcheck") + (MajorBoundVersion + (mkVersion [0, 10])) + mainLibSet], + privateDependencies = []}, condTreeComponents = []}], condBenchmarks = []} diff --git a/Cabal-tests/tests/ParserTests/regressions/leading-comma-2.expr b/Cabal-tests/tests/ParserTests/regressions/leading-comma-2.expr index 0bb5556b2f4..d71b1d8604e 100644 --- a/Cabal-tests/tests/ParserTests/regressions/leading-comma-2.expr +++ b/Cabal-tests/tests/ParserTests/regressions/leading-comma-2.expr @@ -132,32 +132,36 @@ GenericPackageDescription { (PackageName "directory") (OrLaterVersion (mkVersion [0])) mainLibSet], + targetPrivateBuildDepends = [], mixins = []}}, - condTreeConstraints = [ - Dependency - (PackageName "base") - (OrLaterVersion (mkVersion [0])) - mainLibSet, - Dependency - (PackageName "containers") - (OrLaterVersion (mkVersion [0])) - mainLibSet, - Dependency - (PackageName "deepseq") - (OrLaterVersion (mkVersion [0])) - mainLibSet, - Dependency - (PackageName "transformers") - (OrLaterVersion (mkVersion [0])) - mainLibSet, - Dependency - (PackageName "filepath") - (OrLaterVersion (mkVersion [0])) - mainLibSet, - Dependency - (PackageName "directory") - (OrLaterVersion (mkVersion [0])) - mainLibSet], + condTreeConstraints = + Dependencies { + publicDependencies = [ + Dependency + (PackageName "base") + (OrLaterVersion (mkVersion [0])) + mainLibSet, + Dependency + (PackageName "containers") + (OrLaterVersion (mkVersion [0])) + mainLibSet, + Dependency + (PackageName "deepseq") + (OrLaterVersion (mkVersion [0])) + mainLibSet, + Dependency + (PackageName "transformers") + (OrLaterVersion (mkVersion [0])) + mainLibSet, + Dependency + (PackageName "filepath") + (OrLaterVersion (mkVersion [0])) + mainLibSet, + Dependency + (PackageName "directory") + (OrLaterVersion (mkVersion [0])) + mainLibSet], + privateDependencies = []}, condTreeComponents = []}, condSubLibraries = [], condForeignLibs = [], diff --git a/Cabal-tests/tests/ParserTests/regressions/leading-comma.expr b/Cabal-tests/tests/ParserTests/regressions/leading-comma.expr index b1ba1b282f4..7a166677823 100644 --- a/Cabal-tests/tests/ParserTests/regressions/leading-comma.expr +++ b/Cabal-tests/tests/ParserTests/regressions/leading-comma.expr @@ -125,32 +125,36 @@ GenericPackageDescription { (PackageName "directory") (OrLaterVersion (mkVersion [0])) mainLibSet], + targetPrivateBuildDepends = [], mixins = []}}, - condTreeConstraints = [ - Dependency - (PackageName "base") - (OrLaterVersion (mkVersion [0])) - mainLibSet, - Dependency - (PackageName "containers") - (OrLaterVersion (mkVersion [0])) - mainLibSet, - Dependency - (PackageName "deepseq") - (OrLaterVersion (mkVersion [0])) - mainLibSet, - Dependency - (PackageName "transformers") - (OrLaterVersion (mkVersion [0])) - mainLibSet, - Dependency - (PackageName "filepath") - (OrLaterVersion (mkVersion [0])) - mainLibSet, - Dependency - (PackageName "directory") - (OrLaterVersion (mkVersion [0])) - mainLibSet], + condTreeConstraints = + Dependencies { + publicDependencies = [ + Dependency + (PackageName "base") + (OrLaterVersion (mkVersion [0])) + mainLibSet, + Dependency + (PackageName "containers") + (OrLaterVersion (mkVersion [0])) + mainLibSet, + Dependency + (PackageName "deepseq") + (OrLaterVersion (mkVersion [0])) + mainLibSet, + Dependency + (PackageName "transformers") + (OrLaterVersion (mkVersion [0])) + mainLibSet, + Dependency + (PackageName "filepath") + (OrLaterVersion (mkVersion [0])) + mainLibSet, + Dependency + (PackageName "directory") + (OrLaterVersion (mkVersion [0])) + mainLibSet], + privateDependencies = []}, condTreeComponents = []}, condSubLibraries = [], condForeignLibs = [], diff --git a/Cabal-tests/tests/ParserTests/regressions/libpq1.expr b/Cabal-tests/tests/ParserTests/regressions/libpq1.expr index 8906a91f63b..8e097892041 100644 --- a/Cabal-tests/tests/ParserTests/regressions/libpq1.expr +++ b/Cabal-tests/tests/ParserTests/regressions/libpq1.expr @@ -210,24 +210,28 @@ GenericPackageDescription { (EarlierVersion (mkVersion [0, 11]))) mainLibSet], + targetPrivateBuildDepends = [], mixins = []}}, - condTreeConstraints = [ - Dependency - (PackageName "base") - (IntersectVersionRanges - (OrLaterVersion - (mkVersion [4, 3])) - (EarlierVersion - (mkVersion [4, 13]))) - mainLibSet, - Dependency - (PackageName "bytestring") - (IntersectVersionRanges - (OrLaterVersion - (mkVersion [0, 9, 1, 0])) - (EarlierVersion - (mkVersion [0, 11]))) - mainLibSet], + condTreeConstraints = + Dependencies { + publicDependencies = [ + Dependency + (PackageName "base") + (IntersectVersionRanges + (OrLaterVersion + (mkVersion [4, 3])) + (EarlierVersion + (mkVersion [4, 13]))) + mainLibSet, + Dependency + (PackageName "bytestring") + (IntersectVersionRanges + (OrLaterVersion + (mkVersion [0, 9, 1, 0])) + (EarlierVersion + (mkVersion [0, 11]))) + mainLibSet], + privateDependencies = []}, condTreeComponents = [ CondBranch { condBranchCondition = @@ -301,16 +305,20 @@ GenericPackageDescription { (EarlierVersion (mkVersion [2, 8]))) mainLibSet], + targetPrivateBuildDepends = [], mixins = []}}, - condTreeConstraints = [ - Dependency - (PackageName "unix") - (IntersectVersionRanges - (OrLaterVersion - (mkVersion [2, 4, 2, 0])) - (EarlierVersion - (mkVersion [2, 8]))) - mainLibSet], + condTreeConstraints = + Dependencies { + publicDependencies = [ + Dependency + (PackageName "unix") + (IntersectVersionRanges + (OrLaterVersion + (mkVersion [2, 4, 2, 0])) + (EarlierVersion + (mkVersion [2, 8]))) + mainLibSet], + privateDependencies = []}, condTreeComponents = []}, condBranchIfFalse = Nothing}, CondBranch { @@ -385,16 +393,20 @@ GenericPackageDescription { (EarlierVersion (mkVersion [2, 7]))) mainLibSet], + targetPrivateBuildDepends = [], mixins = []}}, - condTreeConstraints = [ - Dependency - (PackageName "Win32") - (IntersectVersionRanges - (OrLaterVersion - (mkVersion [2, 2, 0, 2])) - (EarlierVersion - (mkVersion [2, 7]))) - mainLibSet], + condTreeConstraints = + Dependencies { + publicDependencies = [ + Dependency + (PackageName "Win32") + (IntersectVersionRanges + (OrLaterVersion + (mkVersion [2, 2, 0, 2])) + (EarlierVersion + (mkVersion [2, 7]))) + mainLibSet], + privateDependencies = []}, condTreeComponents = []}, condBranchIfFalse = Nothing}, CondBranch { @@ -468,8 +480,12 @@ GenericPackageDescription { PerCompilerFlavor [] [], customFieldsBI = [], targetBuildDepends = [], + targetPrivateBuildDepends = [], mixins = []}}, - condTreeConstraints = [], + condTreeConstraints = + Dependencies { + publicDependencies = [], + privateDependencies = []}, condTreeComponents = []}, condBranchIfFalse = Just CondNode { @@ -533,8 +549,12 @@ GenericPackageDescription { PerCompilerFlavor [] [], customFieldsBI = [], targetBuildDepends = [], + targetPrivateBuildDepends = [], mixins = []}}, - condTreeConstraints = [], + condTreeConstraints = + Dependencies { + publicDependencies = [], + privateDependencies = []}, condTreeComponents = [ CondBranch { condBranchCondition = @@ -600,8 +620,12 @@ GenericPackageDescription { PerCompilerFlavor [] [], customFieldsBI = [], targetBuildDepends = [], + targetPrivateBuildDepends = [], mixins = []}}, - condTreeConstraints = [], + condTreeConstraints = + Dependencies { + publicDependencies = [], + privateDependencies = []}, condTreeComponents = []}, condBranchIfFalse = Just CondNode { @@ -665,8 +689,12 @@ GenericPackageDescription { PerCompilerFlavor [] [], customFieldsBI = [], targetBuildDepends = [], + targetPrivateBuildDepends = [], mixins = []}}, - condTreeConstraints = [], + condTreeConstraints = + Dependencies { + publicDependencies = [], + privateDependencies = []}, condTreeComponents = [ CondBranch { condBranchCondition = @@ -732,8 +760,12 @@ GenericPackageDescription { PerCompilerFlavor [] [], customFieldsBI = [], targetBuildDepends = [], + targetPrivateBuildDepends = [], mixins = []}}, - condTreeConstraints = [], + condTreeConstraints = + Dependencies { + publicDependencies = [], + privateDependencies = []}, condTreeComponents = []}, condBranchIfFalse = Nothing}]}}]}}]}, diff --git a/Cabal-tests/tests/ParserTests/regressions/libpq2.expr b/Cabal-tests/tests/ParserTests/regressions/libpq2.expr index 3c26ece45ad..12539463cc4 100644 --- a/Cabal-tests/tests/ParserTests/regressions/libpq2.expr +++ b/Cabal-tests/tests/ParserTests/regressions/libpq2.expr @@ -215,24 +215,28 @@ GenericPackageDescription { (EarlierVersion (mkVersion [0, 11]))) mainLibSet], + targetPrivateBuildDepends = [], mixins = []}}, - condTreeConstraints = [ - Dependency - (PackageName "base") - (IntersectVersionRanges - (OrLaterVersion - (mkVersion [4, 3])) - (EarlierVersion - (mkVersion [4, 13]))) - mainLibSet, - Dependency - (PackageName "bytestring") - (IntersectVersionRanges - (OrLaterVersion - (mkVersion [0, 9, 1, 0])) - (EarlierVersion - (mkVersion [0, 11]))) - mainLibSet], + condTreeConstraints = + Dependencies { + publicDependencies = [ + Dependency + (PackageName "base") + (IntersectVersionRanges + (OrLaterVersion + (mkVersion [4, 3])) + (EarlierVersion + (mkVersion [4, 13]))) + mainLibSet, + Dependency + (PackageName "bytestring") + (IntersectVersionRanges + (OrLaterVersion + (mkVersion [0, 9, 1, 0])) + (EarlierVersion + (mkVersion [0, 11]))) + mainLibSet], + privateDependencies = []}, condTreeComponents = [ CondBranch { condBranchCondition = @@ -306,16 +310,20 @@ GenericPackageDescription { (EarlierVersion (mkVersion [2, 8]))) mainLibSet], + targetPrivateBuildDepends = [], mixins = []}}, - condTreeConstraints = [ - Dependency - (PackageName "unix") - (IntersectVersionRanges - (OrLaterVersion - (mkVersion [2, 4, 2, 0])) - (EarlierVersion - (mkVersion [2, 8]))) - mainLibSet], + condTreeConstraints = + Dependencies { + publicDependencies = [ + Dependency + (PackageName "unix") + (IntersectVersionRanges + (OrLaterVersion + (mkVersion [2, 4, 2, 0])) + (EarlierVersion + (mkVersion [2, 8]))) + mainLibSet], + privateDependencies = []}, condTreeComponents = []}, condBranchIfFalse = Nothing}, CondBranch { @@ -390,16 +398,20 @@ GenericPackageDescription { (EarlierVersion (mkVersion [2, 7]))) mainLibSet], + targetPrivateBuildDepends = [], mixins = []}}, - condTreeConstraints = [ - Dependency - (PackageName "Win32") - (IntersectVersionRanges - (OrLaterVersion - (mkVersion [2, 2, 0, 2])) - (EarlierVersion - (mkVersion [2, 7]))) - mainLibSet], + condTreeConstraints = + Dependencies { + publicDependencies = [ + Dependency + (PackageName "Win32") + (IntersectVersionRanges + (OrLaterVersion + (mkVersion [2, 2, 0, 2])) + (EarlierVersion + (mkVersion [2, 7]))) + mainLibSet], + privateDependencies = []}, condTreeComponents = []}, condBranchIfFalse = Nothing}, CondBranch { @@ -470,8 +482,12 @@ GenericPackageDescription { PerCompilerFlavor [] [], customFieldsBI = [], targetBuildDepends = [], + targetPrivateBuildDepends = [], mixins = []}}, - condTreeConstraints = [], + condTreeConstraints = + Dependencies { + publicDependencies = [], + privateDependencies = []}, condTreeComponents = []}, condBranchIfFalse = Just CondNode { @@ -535,8 +551,12 @@ GenericPackageDescription { PerCompilerFlavor [] [], customFieldsBI = [], targetBuildDepends = [], + targetPrivateBuildDepends = [], mixins = []}}, - condTreeConstraints = [], + condTreeConstraints = + Dependencies { + publicDependencies = [], + privateDependencies = []}, condTreeComponents = [ CondBranch { condBranchCondition = @@ -602,8 +622,12 @@ GenericPackageDescription { PerCompilerFlavor [] [], customFieldsBI = [], targetBuildDepends = [], + targetPrivateBuildDepends = [], mixins = []}}, - condTreeConstraints = [], + condTreeConstraints = + Dependencies { + publicDependencies = [], + privateDependencies = []}, condTreeComponents = []}, condBranchIfFalse = Just CondNode { @@ -667,8 +691,12 @@ GenericPackageDescription { PerCompilerFlavor [] [], customFieldsBI = [], targetBuildDepends = [], + targetPrivateBuildDepends = [], mixins = []}}, - condTreeConstraints = [], + condTreeConstraints = + Dependencies { + publicDependencies = [], + privateDependencies = []}, condTreeComponents = [ CondBranch { condBranchCondition = @@ -734,8 +762,12 @@ GenericPackageDescription { PerCompilerFlavor [] [], customFieldsBI = [], targetBuildDepends = [], + targetPrivateBuildDepends = [], mixins = []}}, - condTreeConstraints = [], + condTreeConstraints = + Dependencies { + publicDependencies = [], + privateDependencies = []}, condTreeComponents = []}, condBranchIfFalse = Nothing}]}}]}}]}, diff --git a/Cabal-tests/tests/ParserTests/regressions/mixin-1.expr b/Cabal-tests/tests/ParserTests/regressions/mixin-1.expr index de8a15f04c0..27e23d6650f 100644 --- a/Cabal-tests/tests/ParserTests/regressions/mixin-1.expr +++ b/Cabal-tests/tests/ParserTests/regressions/mixin-1.expr @@ -114,6 +114,7 @@ GenericPackageDescription { (PackageName "str-bytestring") (OrLaterVersion (mkVersion [0])) mainLibSet], + targetPrivateBuildDepends = [], mixins = [ Mixin { mixinPackageName = PackageName @@ -143,19 +144,22 @@ GenericPackageDescription { (ModuleName "Str.ByteString")], includeRequiresRn = DefaultRenaming}}]}}, - condTreeConstraints = [ - Dependency - (PackageName "base") - (OrLaterVersion (mkVersion [0])) - mainLibSet, - Dependency - (PackageName "str-string") - (OrLaterVersion (mkVersion [0])) - mainLibSet, - Dependency - (PackageName "str-bytestring") - (OrLaterVersion (mkVersion [0])) - mainLibSet], + condTreeConstraints = + Dependencies { + publicDependencies = [ + Dependency + (PackageName "base") + (OrLaterVersion (mkVersion [0])) + mainLibSet, + Dependency + (PackageName "str-string") + (OrLaterVersion (mkVersion [0])) + mainLibSet, + Dependency + (PackageName "str-bytestring") + (OrLaterVersion (mkVersion [0])) + mainLibSet], + privateDependencies = []}, condTreeComponents = []}], condTestSuites = [], condBenchmarks = []} diff --git a/Cabal-tests/tests/ParserTests/regressions/mixin-2.expr b/Cabal-tests/tests/ParserTests/regressions/mixin-2.expr index 3bf06bc9c3b..e0ff2fcb192 100644 --- a/Cabal-tests/tests/ParserTests/regressions/mixin-2.expr +++ b/Cabal-tests/tests/ParserTests/regressions/mixin-2.expr @@ -114,6 +114,7 @@ GenericPackageDescription { (PackageName "str-bytestring") (OrLaterVersion (mkVersion [0])) mainLibSet], + targetPrivateBuildDepends = [], mixins = [ Mixin { mixinPackageName = PackageName @@ -143,19 +144,22 @@ GenericPackageDescription { (ModuleName "Str.ByteString")], includeRequiresRn = DefaultRenaming}}]}}, - condTreeConstraints = [ - Dependency - (PackageName "base") - (OrLaterVersion (mkVersion [0])) - mainLibSet, - Dependency - (PackageName "str-string") - (OrLaterVersion (mkVersion [0])) - mainLibSet, - Dependency - (PackageName "str-bytestring") - (OrLaterVersion (mkVersion [0])) - mainLibSet], + condTreeConstraints = + Dependencies { + publicDependencies = [ + Dependency + (PackageName "base") + (OrLaterVersion (mkVersion [0])) + mainLibSet, + Dependency + (PackageName "str-string") + (OrLaterVersion (mkVersion [0])) + mainLibSet, + Dependency + (PackageName "str-bytestring") + (OrLaterVersion (mkVersion [0])) + mainLibSet], + privateDependencies = []}, condTreeComponents = []}], condTestSuites = [], condBenchmarks = []} diff --git a/Cabal-tests/tests/ParserTests/regressions/mixin-3.expr b/Cabal-tests/tests/ParserTests/regressions/mixin-3.expr index 0c0fc57a8b8..d89df8b451d 100644 --- a/Cabal-tests/tests/ParserTests/regressions/mixin-3.expr +++ b/Cabal-tests/tests/ParserTests/regressions/mixin-3.expr @@ -114,6 +114,7 @@ GenericPackageDescription { (PackageName "str-bytestring") (OrLaterVersion (mkVersion [0])) mainLibSet], + targetPrivateBuildDepends = [], mixins = [ Mixin { mixinPackageName = PackageName @@ -126,19 +127,22 @@ GenericPackageDescription { [ModuleName "Foo"], includeRequiresRn = DefaultRenaming}}]}}, - condTreeConstraints = [ - Dependency - (PackageName "base") - (OrLaterVersion (mkVersion [0])) - mainLibSet, - Dependency - (PackageName "str-string") - (OrLaterVersion (mkVersion [0])) - mainLibSet, - Dependency - (PackageName "str-bytestring") - (OrLaterVersion (mkVersion [0])) - mainLibSet], + condTreeConstraints = + Dependencies { + publicDependencies = [ + Dependency + (PackageName "base") + (OrLaterVersion (mkVersion [0])) + mainLibSet, + Dependency + (PackageName "str-string") + (OrLaterVersion (mkVersion [0])) + mainLibSet, + Dependency + (PackageName "str-bytestring") + (OrLaterVersion (mkVersion [0])) + mainLibSet], + privateDependencies = []}, condTreeComponents = []}], condTestSuites = [], condBenchmarks = []} diff --git a/Cabal-tests/tests/ParserTests/regressions/monad-param.expr b/Cabal-tests/tests/ParserTests/regressions/monad-param.expr index 28d57c1e3b0..296104ef38b 100644 --- a/Cabal-tests/tests/ParserTests/regressions/monad-param.expr +++ b/Cabal-tests/tests/ParserTests/regressions/monad-param.expr @@ -136,20 +136,24 @@ GenericPackageDescription { (PackageName "stm") (OrLaterVersion (mkVersion [0])) mainLibSet], + targetPrivateBuildDepends = [], mixins = []}}, - condTreeConstraints = [ - Dependency - (PackageName "base") - (OrLaterVersion (mkVersion [0])) - mainLibSet, - Dependency - (PackageName "mtl") - (OrLaterVersion (mkVersion [0])) - mainLibSet, - Dependency - (PackageName "stm") - (OrLaterVersion (mkVersion [0])) - mainLibSet], + condTreeConstraints = + Dependencies { + publicDependencies = [ + Dependency + (PackageName "base") + (OrLaterVersion (mkVersion [0])) + mainLibSet, + Dependency + (PackageName "mtl") + (OrLaterVersion (mkVersion [0])) + mainLibSet, + Dependency + (PackageName "stm") + (OrLaterVersion (mkVersion [0])) + mainLibSet], + privateDependencies = []}, condTreeComponents = []}, condSubLibraries = [], condForeignLibs = [], diff --git a/Cabal-tests/tests/ParserTests/regressions/multiple-libs-2.expr b/Cabal-tests/tests/ParserTests/regressions/multiple-libs-2.expr index a8c6b0c0c4a..48b5264673c 100644 --- a/Cabal-tests/tests/ParserTests/regressions/multiple-libs-2.expr +++ b/Cabal-tests/tests/ParserTests/regressions/multiple-libs-2.expr @@ -105,12 +105,16 @@ GenericPackageDescription { (PackageName "base") (OrLaterVersion (mkVersion [0])) mainLibSet], + targetPrivateBuildDepends = [], mixins = []}}, - condTreeConstraints = [ - Dependency - (PackageName "base") - (OrLaterVersion (mkVersion [0])) - mainLibSet], + condTreeConstraints = + Dependencies { + publicDependencies = [ + Dependency + (PackageName "base") + (OrLaterVersion (mkVersion [0])) + mainLibSet], + privateDependencies = []}, condTreeComponents = []}, condSubLibraries = [ _×_ @@ -183,12 +187,16 @@ GenericPackageDescription { (PackageName "base") (OrLaterVersion (mkVersion [0])) mainLibSet], + targetPrivateBuildDepends = [], mixins = []}}, - condTreeConstraints = [ - Dependency - (PackageName "base") - (OrLaterVersion (mkVersion [0])) - mainLibSet], + condTreeConstraints = + Dependencies { + publicDependencies = [ + Dependency + (PackageName "base") + (OrLaterVersion (mkVersion [0])) + mainLibSet], + privateDependencies = []}, condTreeComponents = []}], condForeignLibs = [], condExecutables = [], diff --git a/Cabal-tests/tests/ParserTests/regressions/noVersion.expr b/Cabal-tests/tests/ParserTests/regressions/noVersion.expr index 8187272c2c0..f4f99c23bb3 100644 --- a/Cabal-tests/tests/ParserTests/regressions/noVersion.expr +++ b/Cabal-tests/tests/ParserTests/regressions/noVersion.expr @@ -105,12 +105,16 @@ GenericPackageDescription { (PackageName "bad-package") (EarlierVersion (mkVersion [0])) mainLibSet], + targetPrivateBuildDepends = [], mixins = []}}, - condTreeConstraints = [ - Dependency - (PackageName "bad-package") - (EarlierVersion (mkVersion [0])) - mainLibSet], + condTreeConstraints = + Dependencies { + publicDependencies = [ + Dependency + (PackageName "bad-package") + (EarlierVersion (mkVersion [0])) + mainLibSet], + privateDependencies = []}, condTreeComponents = []}, condSubLibraries = [], condForeignLibs = [], diff --git a/Cabal-tests/tests/ParserTests/regressions/nothing-unicode.expr b/Cabal-tests/tests/ParserTests/regressions/nothing-unicode.expr index 2f2663733c6..74501fb3845 100644 --- a/Cabal-tests/tests/ParserTests/regressions/nothing-unicode.expr +++ b/Cabal-tests/tests/ParserTests/regressions/nothing-unicode.expr @@ -116,8 +116,12 @@ GenericPackageDescription { PerCompilerFlavor [] [], customFieldsBI = [], targetBuildDepends = [], + targetPrivateBuildDepends = [], mixins = []}}, - condTreeConstraints = [], + condTreeConstraints = + Dependencies { + publicDependencies = [], + privateDependencies = []}, condTreeComponents = [ CondBranch { condBranchCondition = @@ -183,8 +187,12 @@ GenericPackageDescription { PerCompilerFlavor [] [], customFieldsBI = [], targetBuildDepends = [], + targetPrivateBuildDepends = [], mixins = []}}, - condTreeConstraints = [], + condTreeConstraints = + Dependencies { + publicDependencies = [], + privateDependencies = []}, condTreeComponents = []}, condBranchIfFalse = Nothing}]}, condSubLibraries = [], diff --git a/Cabal-tests/tests/ParserTests/regressions/shake.expr b/Cabal-tests/tests/ParserTests/regressions/shake.expr index 8dd849d75bd..5099b41c052 100644 --- a/Cabal-tests/tests/ParserTests/regressions/shake.expr +++ b/Cabal-tests/tests/ParserTests/regressions/shake.expr @@ -383,81 +383,85 @@ GenericPackageDescription { (OrLaterVersion (mkVersion [1, 1])) mainLibSet], + targetPrivateBuildDepends = [], mixins = []}}, - condTreeConstraints = [ - Dependency - (PackageName "base") - (OrLaterVersion - (mkVersion [4, 5])) - mainLibSet, - Dependency - (PackageName "directory") - (OrLaterVersion (mkVersion [0])) - mainLibSet, - Dependency - (PackageName "hashable") - (OrLaterVersion - (mkVersion [1, 1, 2, 3])) - mainLibSet, - Dependency - (PackageName "binary") - (OrLaterVersion (mkVersion [0])) - mainLibSet, - Dependency - (PackageName "filepath") - (OrLaterVersion (mkVersion [0])) - mainLibSet, - Dependency - (PackageName "process") - (OrLaterVersion - (mkVersion [1, 1])) - mainLibSet, - Dependency - (PackageName - "unordered-containers") - (OrLaterVersion - (mkVersion [0, 2, 1])) - mainLibSet, - Dependency - (PackageName "bytestring") - (OrLaterVersion (mkVersion [0])) - mainLibSet, - Dependency - (PackageName "utf8-string") - (OrLaterVersion - (mkVersion [0, 3])) - mainLibSet, - Dependency - (PackageName "time") - (OrLaterVersion (mkVersion [0])) - mainLibSet, - Dependency - (PackageName "random") - (OrLaterVersion (mkVersion [0])) - mainLibSet, - Dependency - (PackageName "js-jquery") - (OrLaterVersion (mkVersion [0])) - mainLibSet, - Dependency - (PackageName "js-flot") - (OrLaterVersion (mkVersion [0])) - mainLibSet, - Dependency - (PackageName "transformers") - (OrLaterVersion - (mkVersion [0, 2])) - mainLibSet, - Dependency - (PackageName "extra") - (OrLaterVersion - (mkVersion [1, 4, 8])) - mainLibSet, - Dependency - (PackageName "deepseq") - (OrLaterVersion - (mkVersion [1, 1])) - mainLibSet], + condTreeConstraints = + Dependencies { + publicDependencies = [ + Dependency + (PackageName "base") + (OrLaterVersion + (mkVersion [4, 5])) + mainLibSet, + Dependency + (PackageName "directory") + (OrLaterVersion (mkVersion [0])) + mainLibSet, + Dependency + (PackageName "hashable") + (OrLaterVersion + (mkVersion [1, 1, 2, 3])) + mainLibSet, + Dependency + (PackageName "binary") + (OrLaterVersion (mkVersion [0])) + mainLibSet, + Dependency + (PackageName "filepath") + (OrLaterVersion (mkVersion [0])) + mainLibSet, + Dependency + (PackageName "process") + (OrLaterVersion + (mkVersion [1, 1])) + mainLibSet, + Dependency + (PackageName + "unordered-containers") + (OrLaterVersion + (mkVersion [0, 2, 1])) + mainLibSet, + Dependency + (PackageName "bytestring") + (OrLaterVersion (mkVersion [0])) + mainLibSet, + Dependency + (PackageName "utf8-string") + (OrLaterVersion + (mkVersion [0, 3])) + mainLibSet, + Dependency + (PackageName "time") + (OrLaterVersion (mkVersion [0])) + mainLibSet, + Dependency + (PackageName "random") + (OrLaterVersion (mkVersion [0])) + mainLibSet, + Dependency + (PackageName "js-jquery") + (OrLaterVersion (mkVersion [0])) + mainLibSet, + Dependency + (PackageName "js-flot") + (OrLaterVersion (mkVersion [0])) + mainLibSet, + Dependency + (PackageName "transformers") + (OrLaterVersion + (mkVersion [0, 2])) + mainLibSet, + Dependency + (PackageName "extra") + (OrLaterVersion + (mkVersion [1, 4, 8])) + mainLibSet, + Dependency + (PackageName "deepseq") + (OrLaterVersion + (mkVersion [1, 1])) + mainLibSet], + privateDependencies = []}, condTreeComponents = [ CondBranch { condBranchCondition = @@ -523,8 +527,12 @@ GenericPackageDescription { PerCompilerFlavor [] [], customFieldsBI = [], targetBuildDepends = [], + targetPrivateBuildDepends = [], mixins = []}}, - condTreeConstraints = [], + condTreeConstraints = + Dependencies { + publicDependencies = [], + privateDependencies = []}, condTreeComponents = [ CondBranch { condBranchCondition = @@ -594,12 +602,16 @@ GenericPackageDescription { (PackageName "old-time") (OrLaterVersion (mkVersion [0])) mainLibSet], + targetPrivateBuildDepends = [], mixins = []}}, - condTreeConstraints = [ - Dependency - (PackageName "old-time") - (OrLaterVersion (mkVersion [0])) - mainLibSet], + condTreeConstraints = + Dependencies { + publicDependencies = [ + Dependency + (PackageName "old-time") + (OrLaterVersion (mkVersion [0])) + mainLibSet], + privateDependencies = []}, condTreeComponents = []}, condBranchIfFalse = Nothing}]}, condBranchIfFalse = Just @@ -664,8 +676,12 @@ GenericPackageDescription { PerCompilerFlavor [] [], customFieldsBI = [], targetBuildDepends = [], + targetPrivateBuildDepends = [], mixins = []}}, - condTreeConstraints = [], + condTreeConstraints = + Dependencies { + publicDependencies = [], + privateDependencies = []}, condTreeComponents = [ CondBranch { condBranchCondition = @@ -736,13 +752,17 @@ GenericPackageDescription { (OrLaterVersion (mkVersion [2, 5, 1])) mainLibSet], + targetPrivateBuildDepends = [], mixins = []}}, - condTreeConstraints = [ - Dependency - (PackageName "unix") - (OrLaterVersion - (mkVersion [2, 5, 1])) - mainLibSet], + condTreeConstraints = + Dependencies { + publicDependencies = [ + Dependency + (PackageName "unix") + (OrLaterVersion + (mkVersion [2, 5, 1])) + mainLibSet], + privateDependencies = []}, condTreeComponents = []}, condBranchIfFalse = Nothing}]}}, CondBranch { @@ -813,12 +833,16 @@ GenericPackageDescription { (PackageName "unix") (OrLaterVersion (mkVersion [0])) mainLibSet], + targetPrivateBuildDepends = [], mixins = []}}, - condTreeConstraints = [ - Dependency - (PackageName "unix") - (OrLaterVersion (mkVersion [0])) - mainLibSet], + condTreeConstraints = + Dependencies { + publicDependencies = [ + Dependency + (PackageName "unix") + (OrLaterVersion (mkVersion [0])) + mainLibSet], + privateDependencies = []}, condTreeComponents = []}, condBranchIfFalse = Nothing}]}, condSubLibraries = [], @@ -1065,87 +1089,91 @@ GenericPackageDescription { (PackageName "primitive") (OrLaterVersion (mkVersion [0])) mainLibSet], + targetPrivateBuildDepends = [], mixins = []}}, - condTreeConstraints = [ - Dependency - (PackageName "base") - (IntersectVersionRanges - (OrLaterVersion (mkVersion [4])) - (EarlierVersion - (mkVersion [5]))) - mainLibSet, - Dependency - (PackageName "directory") - (OrLaterVersion (mkVersion [0])) - mainLibSet, - Dependency - (PackageName "hashable") - (OrLaterVersion - (mkVersion [1, 1, 2, 3])) - mainLibSet, - Dependency - (PackageName "binary") - (OrLaterVersion (mkVersion [0])) - mainLibSet, - Dependency - (PackageName "filepath") - (OrLaterVersion (mkVersion [0])) - mainLibSet, - Dependency - (PackageName "process") - (OrLaterVersion - (mkVersion [1, 1])) - mainLibSet, - Dependency - (PackageName - "unordered-containers") - (OrLaterVersion - (mkVersion [0, 2, 1])) - mainLibSet, - Dependency - (PackageName "bytestring") - (OrLaterVersion (mkVersion [0])) - mainLibSet, - Dependency - (PackageName "utf8-string") - (OrLaterVersion - (mkVersion [0, 3])) - mainLibSet, - Dependency - (PackageName "time") - (OrLaterVersion (mkVersion [0])) - mainLibSet, - Dependency - (PackageName "random") - (OrLaterVersion (mkVersion [0])) - mainLibSet, - Dependency - (PackageName "js-jquery") - (OrLaterVersion (mkVersion [0])) - mainLibSet, - Dependency - (PackageName "js-flot") - (OrLaterVersion (mkVersion [0])) - mainLibSet, - Dependency - (PackageName "transformers") - (OrLaterVersion - (mkVersion [0, 2])) - mainLibSet, - Dependency - (PackageName "extra") - (OrLaterVersion - (mkVersion [1, 4, 8])) - mainLibSet, - Dependency - (PackageName "deepseq") - (OrLaterVersion - (mkVersion [1, 1])) - mainLibSet, - Dependency - (PackageName "primitive") - (OrLaterVersion (mkVersion [0])) - mainLibSet], + condTreeConstraints = + Dependencies { + publicDependencies = [ + Dependency + (PackageName "base") + (IntersectVersionRanges + (OrLaterVersion (mkVersion [4])) + (EarlierVersion + (mkVersion [5]))) + mainLibSet, + Dependency + (PackageName "directory") + (OrLaterVersion (mkVersion [0])) + mainLibSet, + Dependency + (PackageName "hashable") + (OrLaterVersion + (mkVersion [1, 1, 2, 3])) + mainLibSet, + Dependency + (PackageName "binary") + (OrLaterVersion (mkVersion [0])) + mainLibSet, + Dependency + (PackageName "filepath") + (OrLaterVersion (mkVersion [0])) + mainLibSet, + Dependency + (PackageName "process") + (OrLaterVersion + (mkVersion [1, 1])) + mainLibSet, + Dependency + (PackageName + "unordered-containers") + (OrLaterVersion + (mkVersion [0, 2, 1])) + mainLibSet, + Dependency + (PackageName "bytestring") + (OrLaterVersion (mkVersion [0])) + mainLibSet, + Dependency + (PackageName "utf8-string") + (OrLaterVersion + (mkVersion [0, 3])) + mainLibSet, + Dependency + (PackageName "time") + (OrLaterVersion (mkVersion [0])) + mainLibSet, + Dependency + (PackageName "random") + (OrLaterVersion (mkVersion [0])) + mainLibSet, + Dependency + (PackageName "js-jquery") + (OrLaterVersion (mkVersion [0])) + mainLibSet, + Dependency + (PackageName "js-flot") + (OrLaterVersion (mkVersion [0])) + mainLibSet, + Dependency + (PackageName "transformers") + (OrLaterVersion + (mkVersion [0, 2])) + mainLibSet, + Dependency + (PackageName "extra") + (OrLaterVersion + (mkVersion [1, 4, 8])) + mainLibSet, + Dependency + (PackageName "deepseq") + (OrLaterVersion + (mkVersion [1, 1])) + mainLibSet, + Dependency + (PackageName "primitive") + (OrLaterVersion (mkVersion [0])) + mainLibSet], + privateDependencies = []}, condTreeComponents = [ CondBranch { condBranchCondition = @@ -1210,8 +1238,12 @@ GenericPackageDescription { PerCompilerFlavor [] [], customFieldsBI = [], targetBuildDepends = [], + targetPrivateBuildDepends = [], mixins = []}}, - condTreeConstraints = [], + condTreeConstraints = + Dependencies { + publicDependencies = [], + privateDependencies = []}, condTreeComponents = []}, condBranchIfFalse = Nothing}, CondBranch { @@ -1275,8 +1307,12 @@ GenericPackageDescription { PerCompilerFlavor [] [], customFieldsBI = [], targetBuildDepends = [], + targetPrivateBuildDepends = [], mixins = []}}, - condTreeConstraints = [], + condTreeConstraints = + Dependencies { + publicDependencies = [], + privateDependencies = []}, condTreeComponents = [ CondBranch { condBranchCondition = @@ -1343,12 +1379,16 @@ GenericPackageDescription { (PackageName "old-time") (OrLaterVersion (mkVersion [0])) mainLibSet], + targetPrivateBuildDepends = [], mixins = []}}, - condTreeConstraints = [ - Dependency - (PackageName "old-time") - (OrLaterVersion (mkVersion [0])) - mainLibSet], + condTreeConstraints = + Dependencies { + publicDependencies = [ + Dependency + (PackageName "old-time") + (OrLaterVersion (mkVersion [0])) + mainLibSet], + privateDependencies = []}, condTreeComponents = []}, condBranchIfFalse = Nothing}]}, condBranchIfFalse = Just @@ -1410,8 +1450,12 @@ GenericPackageDescription { PerCompilerFlavor [] [], customFieldsBI = [], targetBuildDepends = [], + targetPrivateBuildDepends = [], mixins = []}}, - condTreeConstraints = [], + condTreeConstraints = + Dependencies { + publicDependencies = [], + privateDependencies = []}, condTreeComponents = [ CondBranch { condBranchCondition = @@ -1479,13 +1523,17 @@ GenericPackageDescription { (OrLaterVersion (mkVersion [2, 5, 1])) mainLibSet], + targetPrivateBuildDepends = [], mixins = []}}, - condTreeConstraints = [ - Dependency - (PackageName "unix") - (OrLaterVersion - (mkVersion [2, 5, 1])) - mainLibSet], + condTreeConstraints = + Dependencies { + publicDependencies = [ + Dependency + (PackageName "unix") + (OrLaterVersion + (mkVersion [2, 5, 1])) + mainLibSet], + privateDependencies = []}, condTreeComponents = []}, condBranchIfFalse = Nothing}]}}, CondBranch { @@ -1553,12 +1601,16 @@ GenericPackageDescription { (PackageName "unix") (OrLaterVersion (mkVersion [0])) mainLibSet], + targetPrivateBuildDepends = [], mixins = []}}, - condTreeConstraints = [ - Dependency - (PackageName "unix") - (OrLaterVersion (mkVersion [0])) - mainLibSet], + condTreeConstraints = + Dependencies { + publicDependencies = [ + Dependency + (PackageName "unix") + (OrLaterVersion (mkVersion [0])) + mainLibSet], + privateDependencies = []}, condTreeComponents = []}, condBranchIfFalse = Nothing}]}], condTestSuites = [ @@ -1848,89 +1900,93 @@ GenericPackageDescription { (OrLaterVersion (mkVersion [2, 0])) mainLibSet], + targetPrivateBuildDepends = [], mixins = []}, testCodeGenerators = []}, - condTreeConstraints = [ - Dependency - (PackageName "base") - (IntersectVersionRanges - (OrLaterVersion (mkVersion [4])) - (EarlierVersion - (mkVersion [5]))) - mainLibSet, - Dependency - (PackageName "directory") - (OrLaterVersion (mkVersion [0])) - mainLibSet, - Dependency - (PackageName "hashable") - (OrLaterVersion - (mkVersion [1, 1, 2, 3])) - mainLibSet, - Dependency - (PackageName "binary") - (OrLaterVersion (mkVersion [0])) - mainLibSet, - Dependency - (PackageName "filepath") - (OrLaterVersion (mkVersion [0])) - mainLibSet, - Dependency - (PackageName "process") - (OrLaterVersion - (mkVersion [1, 1])) - mainLibSet, - Dependency - (PackageName - "unordered-containers") - (OrLaterVersion - (mkVersion [0, 2, 1])) - mainLibSet, - Dependency - (PackageName "bytestring") - (OrLaterVersion (mkVersion [0])) - mainLibSet, - Dependency - (PackageName "utf8-string") - (OrLaterVersion - (mkVersion [0, 3])) - mainLibSet, - Dependency - (PackageName "time") - (OrLaterVersion (mkVersion [0])) - mainLibSet, - Dependency - (PackageName "random") - (OrLaterVersion (mkVersion [0])) - mainLibSet, - Dependency - (PackageName "js-jquery") - (OrLaterVersion (mkVersion [0])) - mainLibSet, - Dependency - (PackageName "js-flot") - (OrLaterVersion (mkVersion [0])) - mainLibSet, - Dependency - (PackageName "transformers") - (OrLaterVersion - (mkVersion [0, 2])) - mainLibSet, - Dependency - (PackageName "deepseq") - (OrLaterVersion - (mkVersion [1, 1])) - mainLibSet, - Dependency - (PackageName "extra") - (OrLaterVersion - (mkVersion [1, 4, 8])) - mainLibSet, - Dependency - (PackageName "QuickCheck") - (OrLaterVersion - (mkVersion [2, 0])) - mainLibSet], + condTreeConstraints = + Dependencies { + publicDependencies = [ + Dependency + (PackageName "base") + (IntersectVersionRanges + (OrLaterVersion (mkVersion [4])) + (EarlierVersion + (mkVersion [5]))) + mainLibSet, + Dependency + (PackageName "directory") + (OrLaterVersion (mkVersion [0])) + mainLibSet, + Dependency + (PackageName "hashable") + (OrLaterVersion + (mkVersion [1, 1, 2, 3])) + mainLibSet, + Dependency + (PackageName "binary") + (OrLaterVersion (mkVersion [0])) + mainLibSet, + Dependency + (PackageName "filepath") + (OrLaterVersion (mkVersion [0])) + mainLibSet, + Dependency + (PackageName "process") + (OrLaterVersion + (mkVersion [1, 1])) + mainLibSet, + Dependency + (PackageName + "unordered-containers") + (OrLaterVersion + (mkVersion [0, 2, 1])) + mainLibSet, + Dependency + (PackageName "bytestring") + (OrLaterVersion (mkVersion [0])) + mainLibSet, + Dependency + (PackageName "utf8-string") + (OrLaterVersion + (mkVersion [0, 3])) + mainLibSet, + Dependency + (PackageName "time") + (OrLaterVersion (mkVersion [0])) + mainLibSet, + Dependency + (PackageName "random") + (OrLaterVersion (mkVersion [0])) + mainLibSet, + Dependency + (PackageName "js-jquery") + (OrLaterVersion (mkVersion [0])) + mainLibSet, + Dependency + (PackageName "js-flot") + (OrLaterVersion (mkVersion [0])) + mainLibSet, + Dependency + (PackageName "transformers") + (OrLaterVersion + (mkVersion [0, 2])) + mainLibSet, + Dependency + (PackageName "deepseq") + (OrLaterVersion + (mkVersion [1, 1])) + mainLibSet, + Dependency + (PackageName "extra") + (OrLaterVersion + (mkVersion [1, 4, 8])) + mainLibSet, + Dependency + (PackageName "QuickCheck") + (OrLaterVersion + (mkVersion [2, 0])) + mainLibSet], + privateDependencies = []}, condTreeComponents = [ CondBranch { condBranchCondition = @@ -1996,9 +2052,13 @@ GenericPackageDescription { PerCompilerFlavor [] [], customFieldsBI = [], targetBuildDepends = [], + targetPrivateBuildDepends = [], mixins = []}, testCodeGenerators = []}, - condTreeConstraints = [], + condTreeConstraints = + Dependencies { + publicDependencies = [], + privateDependencies = []}, condTreeComponents = []}, condBranchIfFalse = Nothing}, CondBranch { @@ -2065,9 +2125,13 @@ GenericPackageDescription { PerCompilerFlavor [] [], customFieldsBI = [], targetBuildDepends = [], + targetPrivateBuildDepends = [], mixins = []}, testCodeGenerators = []}, - condTreeConstraints = [], + condTreeConstraints = + Dependencies { + publicDependencies = [], + privateDependencies = []}, condTreeComponents = []}, condBranchIfFalse = Nothing}, CondBranch { @@ -2134,9 +2198,13 @@ GenericPackageDescription { PerCompilerFlavor [] [], customFieldsBI = [], targetBuildDepends = [], + targetPrivateBuildDepends = [], mixins = []}, testCodeGenerators = []}, - condTreeConstraints = [], + condTreeConstraints = + Dependencies { + publicDependencies = [], + privateDependencies = []}, condTreeComponents = [ CondBranch { condBranchCondition = @@ -2206,13 +2274,17 @@ GenericPackageDescription { (PackageName "old-time") (OrLaterVersion (mkVersion [0])) mainLibSet], + targetPrivateBuildDepends = [], mixins = []}, testCodeGenerators = []}, - condTreeConstraints = [ - Dependency - (PackageName "old-time") - (OrLaterVersion (mkVersion [0])) - mainLibSet], + condTreeConstraints = + Dependencies { + publicDependencies = [ + Dependency + (PackageName "old-time") + (OrLaterVersion (mkVersion [0])) + mainLibSet], + privateDependencies = []}, condTreeComponents = []}, condBranchIfFalse = Nothing}]}, condBranchIfFalse = Just @@ -2277,9 +2349,13 @@ GenericPackageDescription { PerCompilerFlavor [] [], customFieldsBI = [], targetBuildDepends = [], + targetPrivateBuildDepends = [], mixins = []}, testCodeGenerators = []}, - condTreeConstraints = [], + condTreeConstraints = + Dependencies { + publicDependencies = [], + privateDependencies = []}, condTreeComponents = [ CondBranch { condBranchCondition = @@ -2350,14 +2426,18 @@ GenericPackageDescription { (OrLaterVersion (mkVersion [2, 5, 1])) mainLibSet], + targetPrivateBuildDepends = [], mixins = []}, testCodeGenerators = []}, - condTreeConstraints = [ - Dependency - (PackageName "unix") - (OrLaterVersion - (mkVersion [2, 5, 1])) - mainLibSet], + condTreeConstraints = + Dependencies { + publicDependencies = [ + Dependency + (PackageName "unix") + (OrLaterVersion + (mkVersion [2, 5, 1])) + mainLibSet], + privateDependencies = []}, condTreeComponents = []}, condBranchIfFalse = Nothing}]}}, CondBranch { @@ -2428,13 +2508,17 @@ GenericPackageDescription { (PackageName "unix") (OrLaterVersion (mkVersion [0])) mainLibSet], + targetPrivateBuildDepends = [], mixins = []}, testCodeGenerators = []}, - condTreeConstraints = [ - Dependency - (PackageName "unix") - (OrLaterVersion (mkVersion [0])) - mainLibSet], + condTreeConstraints = + Dependencies { + publicDependencies = [ + Dependency + (PackageName "unix") + (OrLaterVersion (mkVersion [0])) + mainLibSet], + privateDependencies = []}, condTreeComponents = []}, condBranchIfFalse = Nothing}]}], condBenchmarks = []} diff --git a/Cabal-tests/tests/ParserTests/regressions/spdx-1.expr b/Cabal-tests/tests/ParserTests/regressions/spdx-1.expr index 2ca07bf2322..a4b5453730b 100644 --- a/Cabal-tests/tests/ParserTests/regressions/spdx-1.expr +++ b/Cabal-tests/tests/ParserTests/regressions/spdx-1.expr @@ -99,8 +99,12 @@ GenericPackageDescription { PerCompilerFlavor [] [], customFieldsBI = [], targetBuildDepends = [], + targetPrivateBuildDepends = [], mixins = []}}, - condTreeConstraints = [], + condTreeConstraints = + Dependencies { + publicDependencies = [], + privateDependencies = []}, condTreeComponents = []}, condSubLibraries = [], condForeignLibs = [], diff --git a/Cabal-tests/tests/ParserTests/regressions/spdx-2.expr b/Cabal-tests/tests/ParserTests/regressions/spdx-2.expr index 9c50edd4864..c4bdcfb0c1c 100644 --- a/Cabal-tests/tests/ParserTests/regressions/spdx-2.expr +++ b/Cabal-tests/tests/ParserTests/regressions/spdx-2.expr @@ -103,8 +103,12 @@ GenericPackageDescription { PerCompilerFlavor [] [], customFieldsBI = [], targetBuildDepends = [], + targetPrivateBuildDepends = [], mixins = []}}, - condTreeConstraints = [], + condTreeConstraints = + Dependencies { + publicDependencies = [], + privateDependencies = []}, condTreeComponents = []}, condSubLibraries = [], condForeignLibs = [], diff --git a/Cabal-tests/tests/ParserTests/regressions/spdx-3.expr b/Cabal-tests/tests/ParserTests/regressions/spdx-3.expr index 944faa4c0c0..53abd4ed448 100644 --- a/Cabal-tests/tests/ParserTests/regressions/spdx-3.expr +++ b/Cabal-tests/tests/ParserTests/regressions/spdx-3.expr @@ -103,8 +103,12 @@ GenericPackageDescription { PerCompilerFlavor [] [], customFieldsBI = [], targetBuildDepends = [], + targetPrivateBuildDepends = [], mixins = []}}, - condTreeConstraints = [], + condTreeConstraints = + Dependencies { + publicDependencies = [], + privateDependencies = []}, condTreeComponents = []}, condSubLibraries = [], condForeignLibs = [], diff --git a/Cabal-tests/tests/ParserTests/regressions/th-lift-instances.expr b/Cabal-tests/tests/ParserTests/regressions/th-lift-instances.expr index 8f2edf09a36..dd59047de84 100644 --- a/Cabal-tests/tests/ParserTests/regressions/th-lift-instances.expr +++ b/Cabal-tests/tests/ParserTests/regressions/th-lift-instances.expr @@ -180,57 +180,61 @@ GenericPackageDescription { (EarlierVersion (mkVersion [0, 11]))) mainLibSet], + targetPrivateBuildDepends = [], mixins = []}}, - condTreeConstraints = [ - Dependency - (PackageName "base") - (IntersectVersionRanges - (OrLaterVersion - (mkVersion [4, 4])) - (EarlierVersion - (mkVersion [5]))) - mainLibSet, - Dependency - (PackageName "template-haskell") - (EarlierVersion - (mkVersion [2, 10])) - mainLibSet, - Dependency - (PackageName "th-lift") - (OrLaterVersion (mkVersion [0])) - mainLibSet, - Dependency - (PackageName "containers") - (IntersectVersionRanges - (OrLaterVersion - (mkVersion [0, 4])) - (EarlierVersion - (mkVersion [0, 6]))) - mainLibSet, - Dependency - (PackageName "vector") - (IntersectVersionRanges - (OrLaterVersion - (mkVersion [0, 9])) - (EarlierVersion - (mkVersion [0, 11]))) - mainLibSet, - Dependency - (PackageName "text") - (IntersectVersionRanges - (OrLaterVersion - (mkVersion [0, 11])) - (EarlierVersion - (mkVersion [1, 3]))) - mainLibSet, - Dependency - (PackageName "bytestring") - (IntersectVersionRanges - (OrLaterVersion - (mkVersion [0, 9])) + condTreeConstraints = + Dependencies { + publicDependencies = [ + Dependency + (PackageName "base") + (IntersectVersionRanges + (OrLaterVersion + (mkVersion [4, 4])) + (EarlierVersion + (mkVersion [5]))) + mainLibSet, + Dependency + (PackageName "template-haskell") (EarlierVersion - (mkVersion [0, 11]))) - mainLibSet], + (mkVersion [2, 10])) + mainLibSet, + Dependency + (PackageName "th-lift") + (OrLaterVersion (mkVersion [0])) + mainLibSet, + Dependency + (PackageName "containers") + (IntersectVersionRanges + (OrLaterVersion + (mkVersion [0, 4])) + (EarlierVersion + (mkVersion [0, 6]))) + mainLibSet, + Dependency + (PackageName "vector") + (IntersectVersionRanges + (OrLaterVersion + (mkVersion [0, 9])) + (EarlierVersion + (mkVersion [0, 11]))) + mainLibSet, + Dependency + (PackageName "text") + (IntersectVersionRanges + (OrLaterVersion + (mkVersion [0, 11])) + (EarlierVersion + (mkVersion [1, 3]))) + mainLibSet, + Dependency + (PackageName "bytestring") + (IntersectVersionRanges + (OrLaterVersion + (mkVersion [0, 9])) + (EarlierVersion + (mkVersion [0, 11]))) + mainLibSet], + privateDependencies = []}, condTreeComponents = []}, condSubLibraries = [], condForeignLibs = [], @@ -356,63 +360,67 @@ GenericPackageDescription { (EarlierVersion (mkVersion [2, 8]))) mainLibSet], + targetPrivateBuildDepends = [], mixins = []}, testCodeGenerators = []}, - condTreeConstraints = [ - Dependency - (PackageName "base") - (OrLaterVersion (mkVersion [0])) - mainLibSet, - Dependency - (PackageName "template-haskell") - (EarlierVersion - (mkVersion [2, 10])) - mainLibSet, - Dependency - (PackageName "containers") - (IntersectVersionRanges - (OrLaterVersion - (mkVersion [0, 4])) - (EarlierVersion - (mkVersion [0, 6]))) - mainLibSet, - Dependency - (PackageName "vector") - (IntersectVersionRanges - (OrLaterVersion - (mkVersion [0, 9])) - (EarlierVersion - (mkVersion [0, 11]))) - mainLibSet, - Dependency - (PackageName "text") - (IntersectVersionRanges - (OrLaterVersion - (mkVersion [0, 11])) - (EarlierVersion - (mkVersion [1, 2]))) - mainLibSet, - Dependency - (PackageName "bytestring") - (IntersectVersionRanges - (OrLaterVersion - (mkVersion [0, 9])) - (EarlierVersion - (mkVersion [0, 11]))) - mainLibSet, - Dependency - (PackageName - "th-lift-instances") - (OrLaterVersion (mkVersion [0])) - mainLibSet, - Dependency - (PackageName "QuickCheck") - (IntersectVersionRanges - (OrLaterVersion - (mkVersion [2, 6])) + condTreeConstraints = + Dependencies { + publicDependencies = [ + Dependency + (PackageName "base") + (OrLaterVersion (mkVersion [0])) + mainLibSet, + Dependency + (PackageName "template-haskell") (EarlierVersion - (mkVersion [2, 8]))) - mainLibSet], + (mkVersion [2, 10])) + mainLibSet, + Dependency + (PackageName "containers") + (IntersectVersionRanges + (OrLaterVersion + (mkVersion [0, 4])) + (EarlierVersion + (mkVersion [0, 6]))) + mainLibSet, + Dependency + (PackageName "vector") + (IntersectVersionRanges + (OrLaterVersion + (mkVersion [0, 9])) + (EarlierVersion + (mkVersion [0, 11]))) + mainLibSet, + Dependency + (PackageName "text") + (IntersectVersionRanges + (OrLaterVersion + (mkVersion [0, 11])) + (EarlierVersion + (mkVersion [1, 2]))) + mainLibSet, + Dependency + (PackageName "bytestring") + (IntersectVersionRanges + (OrLaterVersion + (mkVersion [0, 9])) + (EarlierVersion + (mkVersion [0, 11]))) + mainLibSet, + Dependency + (PackageName + "th-lift-instances") + (OrLaterVersion (mkVersion [0])) + mainLibSet, + Dependency + (PackageName "QuickCheck") + (IntersectVersionRanges + (OrLaterVersion + (mkVersion [2, 6])) + (EarlierVersion + (mkVersion [2, 8]))) + mainLibSet], + privateDependencies = []}, condTreeComponents = []}, _×_ (UnqualComponentName "doctests") @@ -495,27 +503,31 @@ GenericPackageDescription { (PackageName "filepath") (OrLaterVersion (mkVersion [0])) mainLibSet], + targetPrivateBuildDepends = [], mixins = []}, testCodeGenerators = []}, - condTreeConstraints = [ - Dependency - (PackageName "base") - (OrLaterVersion (mkVersion [0])) - mainLibSet, - Dependency - (PackageName "directory") - (OrLaterVersion - (mkVersion [1, 0])) - mainLibSet, - Dependency - (PackageName "doctest") - (OrLaterVersion - (mkVersion [0, 9, 1])) - mainLibSet, - Dependency - (PackageName "filepath") - (OrLaterVersion (mkVersion [0])) - mainLibSet], + condTreeConstraints = + Dependencies { + publicDependencies = [ + Dependency + (PackageName "base") + (OrLaterVersion (mkVersion [0])) + mainLibSet, + Dependency + (PackageName "directory") + (OrLaterVersion + (mkVersion [1, 0])) + mainLibSet, + Dependency + (PackageName "doctest") + (OrLaterVersion + (mkVersion [0, 9, 1])) + mainLibSet, + Dependency + (PackageName "filepath") + (OrLaterVersion (mkVersion [0])) + mainLibSet], + privateDependencies = []}, condTreeComponents = [ CondBranch { condBranchCondition = @@ -581,9 +593,13 @@ GenericPackageDescription { PerCompilerFlavor [] [], customFieldsBI = [], targetBuildDepends = [], + targetPrivateBuildDepends = [], mixins = []}, testCodeGenerators = []}, - condTreeConstraints = [], + condTreeConstraints = + Dependencies { + publicDependencies = [], + privateDependencies = []}, condTreeComponents = []}, condBranchIfFalse = Nothing}]}], condBenchmarks = []} diff --git a/Cabal-tests/tests/ParserTests/regressions/version-sets.expr b/Cabal-tests/tests/ParserTests/regressions/version-sets.expr index b134e4584ad..1d3277c8b33 100644 --- a/Cabal-tests/tests/ParserTests/regressions/version-sets.expr +++ b/Cabal-tests/tests/ParserTests/regressions/version-sets.expr @@ -189,72 +189,76 @@ GenericPackageDescription { (MajorBoundVersion (mkVersion [2, 2, 0, 0]))) mainLibSet], + targetPrivateBuildDepends = [], mixins = []}}, - condTreeConstraints = [ - Dependency - (PackageName "network") - (MajorBoundVersion - (mkVersion [0])) - mainLibSet, - Dependency - (PackageName "base") - (ThisVersion (mkVersion [1])) - mainLibSet, - Dependency - (PackageName "base") - (ThisVersion (mkVersion [1])) - mainLibSet, - Dependency - (PackageName "base") - (UnionVersionRanges + condTreeConstraints = + Dependencies { + publicDependencies = [ + Dependency + (PackageName "network") + (MajorBoundVersion + (mkVersion [0])) + mainLibSet, + Dependency + (PackageName "base") (ThisVersion (mkVersion [1])) - (ThisVersion (mkVersion [2]))) - mainLibSet, - Dependency - (PackageName "base") - (ThisVersion (mkVersion [1, 2])) - mainLibSet, - Dependency - (PackageName "base") - (UnionVersionRanges + mainLibSet, + Dependency + (PackageName "base") + (ThisVersion (mkVersion [1])) + mainLibSet, + Dependency + (PackageName "base") + (UnionVersionRanges + (ThisVersion (mkVersion [1])) + (ThisVersion (mkVersion [2]))) + mainLibSet, + Dependency + (PackageName "base") (ThisVersion (mkVersion [1, 2])) - (ThisVersion - (mkVersion [3, 4]))) - mainLibSet, - Dependency - (PackageName "ghc") - (UnionVersionRanges - (ThisVersion - (mkVersion [8, 6, 3])) + mainLibSet, + Dependency + (PackageName "base") + (UnionVersionRanges + (ThisVersion (mkVersion [1, 2])) + (ThisVersion + (mkVersion [3, 4]))) + mainLibSet, + Dependency + (PackageName "ghc") (UnionVersionRanges (ThisVersion - (mkVersion [8, 4, 4])) + (mkVersion [8, 6, 3])) (UnionVersionRanges (ThisVersion - (mkVersion [8, 2, 2])) + (mkVersion [8, 4, 4])) (UnionVersionRanges (ThisVersion - (mkVersion [8, 0, 2])) + (mkVersion [8, 2, 2])) (UnionVersionRanges (ThisVersion - (mkVersion [7, 10, 3])) + (mkVersion [8, 0, 2])) (UnionVersionRanges (ThisVersion - (mkVersion [7, 8, 4])) + (mkVersion [7, 10, 3])) (UnionVersionRanges (ThisVersion - (mkVersion [7, 6, 3])) - (ThisVersion - (mkVersion [7, 4, 2]))))))))) - mainLibSet, - Dependency - (PackageName "Cabal") - (UnionVersionRanges - (MajorBoundVersion - (mkVersion [2, 4, 1, 1])) - (MajorBoundVersion - (mkVersion [2, 2, 0, 0]))) - mainLibSet], + (mkVersion [7, 8, 4])) + (UnionVersionRanges + (ThisVersion + (mkVersion [7, 6, 3])) + (ThisVersion + (mkVersion [7, 4, 2]))))))))) + mainLibSet, + Dependency + (PackageName "Cabal") + (UnionVersionRanges + (MajorBoundVersion + (mkVersion [2, 4, 1, 1])) + (MajorBoundVersion + (mkVersion [2, 2, 0, 0]))) + mainLibSet], + privateDependencies = []}, condTreeComponents = []}, condSubLibraries = [], condForeignLibs = [], diff --git a/Cabal-tests/tests/ParserTests/regressions/wl-pprint-indef.expr b/Cabal-tests/tests/ParserTests/regressions/wl-pprint-indef.expr index 03959b195c0..ebd5e41d199 100644 --- a/Cabal-tests/tests/ParserTests/regressions/wl-pprint-indef.expr +++ b/Cabal-tests/tests/ParserTests/regressions/wl-pprint-indef.expr @@ -127,17 +127,21 @@ GenericPackageDescription { (OrLaterVersion (mkVersion [0, 1, 0, 0])) mainLibSet], + targetPrivateBuildDepends = [], mixins = []}}, - condTreeConstraints = [ - Dependency - (PackageName "base") - (EarlierVersion (mkVersion [5])) - mainLibSet, - Dependency - (PackageName "str-sig") - (OrLaterVersion - (mkVersion [0, 1, 0, 0])) - mainLibSet], + condTreeConstraints = + Dependencies { + publicDependencies = [ + Dependency + (PackageName "base") + (EarlierVersion (mkVersion [5])) + mainLibSet, + Dependency + (PackageName "str-sig") + (OrLaterVersion + (mkVersion [0, 1, 0, 0])) + mainLibSet], + privateDependencies = []}, condTreeComponents = []}, condSubLibraries = [], condForeignLibs = [], @@ -219,21 +223,25 @@ GenericPackageDescription { (PackageName "wl-pprint-indef") (OrLaterVersion (mkVersion [0])) mainLibSet], + targetPrivateBuildDepends = [], mixins = []}}, - condTreeConstraints = [ - Dependency - (PackageName "base") - (EarlierVersion (mkVersion [5])) - mainLibSet, - Dependency - (PackageName "str-string") - (OrLaterVersion - (mkVersion [0, 1, 0, 0])) - mainLibSet, - Dependency - (PackageName "wl-pprint-indef") - (OrLaterVersion (mkVersion [0])) - mainLibSet], + condTreeConstraints = + Dependencies { + publicDependencies = [ + Dependency + (PackageName "base") + (EarlierVersion (mkVersion [5])) + mainLibSet, + Dependency + (PackageName "str-string") + (OrLaterVersion + (mkVersion [0, 1, 0, 0])) + mainLibSet, + Dependency + (PackageName "wl-pprint-indef") + (OrLaterVersion (mkVersion [0])) + mainLibSet], + privateDependencies = []}, condTreeComponents = []}], condTestSuites = [], condBenchmarks = []} diff --git a/Cabal-tests/tests/UnitTests/Distribution/Described.hs b/Cabal-tests/tests/UnitTests/Distribution/Described.hs index 2c73c805c71..4e041c6d380 100644 --- a/Cabal-tests/tests/UnitTests/Distribution/Described.hs +++ b/Cabal-tests/tests/UnitTests/Distribution/Described.hs @@ -12,7 +12,7 @@ import Test.Tasty (TestTree, testGroup) import Distribution.Compiler (CompilerFlavor, CompilerId) import Distribution.ModuleName (ModuleName) import Distribution.System (Arch, OS) -import Distribution.Types.Dependency (Dependency) +import Distribution.Types.Dependency (Dependency, PrivateDependency) import Distribution.Types.Flag (FlagAssignment, FlagName) import Distribution.Types.IncludeRenaming (IncludeRenaming) import Distribution.Types.Mixin (Mixin) @@ -30,6 +30,7 @@ import Test.QuickCheck.Instances.Cabal () tests :: TestTree tests = testGroup "Described" [ testDescribed (Proxy :: Proxy Dependency) + , testDescribed (Proxy :: Proxy PrivateDependency) , testDescribed (Proxy :: Proxy PackageName) , testDescribed (Proxy :: Proxy PackageIdentifier) , testDescribed (Proxy :: Proxy PackageVersionConstraint) diff --git a/Cabal-tests/tests/UnitTests/Distribution/Utils/Structured.hs b/Cabal-tests/tests/UnitTests/Distribution/Utils/Structured.hs index 9b36dd9d7ce..c59f83e69f3 100644 --- a/Cabal-tests/tests/UnitTests/Distribution/Utils/Structured.hs +++ b/Cabal-tests/tests/UnitTests/Distribution/Utils/Structured.hs @@ -33,15 +33,15 @@ md5Check proxy md5Int = structureHash proxy @?= md5FromInteger md5Int md5CheckGenericPackageDescription :: Proxy GenericPackageDescription -> Assertion md5CheckGenericPackageDescription proxy = md5Check proxy #if MIN_VERSION_base(4,19,0) - 0x4acd7857947385180d814f36dc1a759e + 0x4e7925b423973107ea2f615c3eb6e207 #else - 0x3ff3fa6c3c570bcafa10b457b1208cc8 + 0x5e28eb7641ac5fd9574068ed7743f58f #endif md5CheckLocalBuildInfo :: Proxy LocalBuildInfo -> Assertion md5CheckLocalBuildInfo proxy = md5Check proxy #if MIN_VERSION_base(4,19,0) - 0x5f774efdb0aedcbf5263d3d99e38d50b + 0x3f7451c297d58669475d5f2782f6c9b9 #else - 0x0f53d756836a410f72b31feb7d9f7b09 + 0x8e8d315d525d3ec36cfd4e0ba0095f1c #endif diff --git a/Cabal-tree-diff/src/Data/TreeDiff/Instances/Cabal.hs b/Cabal-tree-diff/src/Data/TreeDiff/Instances/Cabal.hs index 15fae62649e..863eaac1fb4 100644 --- a/Cabal-tree-diff/src/Data/TreeDiff/Instances/Cabal.hs +++ b/Cabal-tree-diff/src/Data/TreeDiff/Instances/Cabal.hs @@ -71,6 +71,8 @@ instance ToExpr CabalSpecVersion instance ToExpr CompilerFlavor instance ToExpr CompilerId instance ToExpr ComponentId +instance ToExpr ComponentName +instance ToExpr NotLibComponentName instance ToExpr DebugInfoLevel instance ToExpr DefUnitId instance ToExpr DumpBuildInfo @@ -127,5 +129,8 @@ instance ToExpr UnqualComponentName instance ToExpr Verbosity instance ToExpr VerbosityFlag instance ToExpr VerbosityLevel +instance ToExpr Dependencies +instance ToExpr PrivateDependency +instance ToExpr PrivateAlias instance ToExpr ShortText where toExpr = toExpr . fromShortText diff --git a/Cabal/src/Distribution/Backpack/ComponentsGraph.hs b/Cabal/src/Distribution/Backpack/ComponentsGraph.hs index aef3db817c6..0c7cb6a18ca 100644 --- a/Cabal/src/Distribution/Backpack/ComponentsGraph.hs +++ b/Cabal/src/Distribution/Backpack/ComponentsGraph.hs @@ -73,7 +73,7 @@ mkComponentsGraph enabled pkg_descr = toolDependencies = CExeName <$> getAllInternalToolDependencies pkg_descr bi libDependencies = do - Dependency pkgname _ lns <- targetBuildDepends bi + Dependency pkgname _ lns <- (targetBuildDepends bi ++ concatMap private_depends (targetPrivateBuildDepends bi)) guard (pkgname == packageName pkg_descr) ln <- NES.toList lns diff --git a/Cabal/src/Distribution/Backpack/Configure.hs b/Cabal/src/Distribution/Backpack/Configure.hs index 8e9eb18ae6a..43b75db0408 100644 --- a/Cabal/src/Distribution/Backpack/Configure.hs +++ b/Cabal/src/Distribution/Backpack/Configure.hs @@ -103,7 +103,7 @@ configureComponentLocalBuildInfos let conf_pkg_map = Map.fromListWith Map.union - [ ( pc_pkgname pkg + [ ( (pc_pkgname pkg, pc_alias pkg) , Map.singleton (pc_compname pkg) ( AnnotatedId @@ -117,8 +117,10 @@ configureComponentLocalBuildInfos ] `Map.union` Map.fromListWith Map.union - [ (pkg, Map.singleton (ann_cname aid) aid) - | PromisedComponent pkg aid <- promisedPkgDeps + [ ( (pkg, alias) + , Map.singleton (ann_cname aid) aid + ) + | PromisedComponent pkg aid alias <- promisedPkgDeps ] graph1 <- toConfiguredComponents @@ -151,7 +153,7 @@ configureComponentLocalBuildInfos , emptyModuleShape ) ) - | PromisedComponent _ aid <- promisedPkgDeps + | PromisedComponent _ aid _ <- promisedPkgDeps ] uid_lookup def_uid | Just pkg <- PackageIndex.lookupUnitId installedPackageSet uid = diff --git a/Cabal/src/Distribution/Backpack/ConfiguredComponent.hs b/Cabal/src/Distribution/Backpack/ConfiguredComponent.hs index 9bfaefb7e0b..22045ca3b6c 100644 --- a/Cabal/src/Distribution/Backpack/ConfiguredComponent.hs +++ b/Cabal/src/Distribution/Backpack/ConfiguredComponent.hs @@ -100,7 +100,7 @@ dispConfiguredComponent cc = mkConfiguredComponent :: PackageDescription -> ComponentId - -> [AnnotatedId ComponentId] -- lib deps + -> [(AnnotatedId ComponentId, IsPrivate)] -- lib deps -> [AnnotatedId ComponentId] -- exe deps -> Component -> LogProgress ConfiguredComponent @@ -120,6 +120,8 @@ mkConfiguredComponent pkg_descr this_cid lib_deps exe_deps component = do { ci_ann_id = aid , ci_renaming = rns , ci_implicit = False + , -- Mixins can't be private + ci_alias = Public } -- Any @build-depends@ which is not explicitly mentioned in @@ -127,14 +129,15 @@ mkConfiguredComponent pkg_descr this_cid lib_deps exe_deps component = do let used_explicitly = Set.fromList (map ci_id explicit_includes) implicit_includes = map - ( \aid -> + ( \(aid, alias) -> ComponentInclude { ci_ann_id = aid , ci_renaming = defaultIncludeRenaming , ci_implicit = True + , ci_alias = alias } ) - $ filter (flip Set.notMember used_explicitly . ann_id) lib_deps + $ filter (flip Set.notMember used_explicitly . ann_id . fst) lib_deps return ConfiguredComponent @@ -161,13 +164,14 @@ mkConfiguredComponent pkg_descr this_cid lib_deps exe_deps component = do deps_map = Map.fromList [ ((packageName dep, ann_cname dep), dep) - | dep <- lib_deps + | (dep, _) <- lib_deps ] is_public = componentName component == CLibName LMainLibName +-- A function from PackageName -> Maybe PrivateQualifier -> ComponentName -> ResolvedComponentId type ConfiguredComponentMap = - Map PackageName (Map ComponentName (AnnotatedId ComponentId)) + Map (PackageName, IsPrivate) (Map ComponentName ((AnnotatedId ComponentId))) toConfiguredComponent :: PackageDescription @@ -180,14 +184,16 @@ toConfiguredComponent pkg_descr this_cid lib_dep_map exe_dep_map component = do lib_deps <- if newPackageDepsBehaviour pkg_descr then fmap concat $ - forM (targetBuildDepends bi) $ - \(Dependency name _ sublibs) -> do - case Map.lookup name lib_dep_map of + forM ([(d, Public) | d <- targetBuildDepends bi] ++ [(d, Private alias) | (PrivateDependency alias ds) <- targetPrivateBuildDepends bi, d <- ds]) $ + \((Dependency name _ sublibs), alias) -> do + case Map.lookup (name, alias) lib_dep_map of Nothing -> dieProgress $ text "Dependency on unbuildable" <+> text "package" <+> pretty name + <+> foldIsPrivate mempty pretty alias + <+> text (show lib_dep_map) Just pkg -> do -- Return all library components forM (NonEmptySet.toList sublibs) $ \lib -> @@ -199,7 +205,8 @@ toConfiguredComponent pkg_descr this_cid lib_dep_map exe_dep_map component = do <+> text (showLibraryName lib) <+> text "from" <+> pretty name - Just v -> return v + <+> foldIsPrivate mempty pretty alias + Just v -> return (v, alias) else return old_style_lib_deps mkConfiguredComponent pkg_descr @@ -217,8 +224,8 @@ toConfiguredComponent pkg_descr this_cid lib_dep_map exe_dep_map component = do -- because it would imply a cyclic dependency for the -- library itself. old_style_lib_deps = - [ e - | (pn, comp_map) <- Map.toList lib_dep_map + [ (e, alias) + | ((pn, alias), comp_map) <- Map.toList lib_dep_map , pn /= packageName pkg_descr , (cn, e) <- Map.toList comp_map , cn == CLibName LMainLibName @@ -236,7 +243,7 @@ toConfiguredComponent pkg_descr this_cid lib_dep_map exe_dep_map component = do -- which the package is attempting to use (those deps are only -- fed in when cabal-install uses this codepath.) -- TODO: Let cabal-install request errors here - Just exe <- [Map.lookup (CExeName cn) =<< Map.lookup pn exe_dep_map] + Just exe <- [Map.lookup (CExeName cn) =<< Map.lookup (pn, Public) exe_dep_map] ] -- | Also computes the 'ComponentId', and sets cc_public if necessary. @@ -292,7 +299,7 @@ extendConfiguredComponentMap extendConfiguredComponentMap cc = Map.insertWith Map.union - (pkgName (cc_pkgid cc)) + ((pkgName (cc_pkgid cc)), Public) (Map.singleton (cc_name cc) (cc_ann_id cc)) -- Compute the 'ComponentId's for a graph of 'Component's. The diff --git a/Cabal/src/Distribution/Backpack/LinkedComponent.hs b/Cabal/src/Distribution/Backpack/LinkedComponent.hs index b2d2bc25066..98b2a1f8493 100644 --- a/Cabal/src/Distribution/Backpack/LinkedComponent.hs +++ b/Cabal/src/Distribution/Backpack/LinkedComponent.hs @@ -155,8 +155,8 @@ toLinkedComponent -- on the ModuleShape) to resolve these into linked identities. unlinked_includes :: [ComponentInclude (OpenUnitId, ModuleShape) IncludeRenaming] unlinked_includes = - [ ComponentInclude (fmap lookupUid dep_aid) rns i - | ComponentInclude dep_aid rns i <- cid_includes + [ ComponentInclude (fmap lookupUid dep_aid) rns i alias + | ComponentInclude dep_aid rns i alias <- cid_includes ] lookupUid :: ComponentId -> (OpenUnitId, ModuleShape) @@ -184,7 +184,7 @@ toLinkedComponent , preModShapeRequires = Set.fromList src_reqs } : [ renamePreModuleShape (toPreModuleShape sh) rns - | ComponentInclude (AnnotatedId{ann_id = (_, sh)}) rns _ <- unlinked_includes + | ComponentInclude (AnnotatedId{ann_id = (_, sh)}) rns _ _ <- unlinked_includes ] reqs = preModShapeRequires pre_shape insts = @@ -236,7 +236,7 @@ toLinkedComponent -- src_reqs_u <- traverse convertReq src_reqs -- Read out all the final results by converting back -- into a pure representation. - let convertIncludeU (ComponentInclude dep_aid rns i) = do + let convertIncludeU (ComponentInclude dep_aid rns i alias) = do let component_name = pretty $ ann_cname dep_aid uid <- convertUnitIdU (ann_id dep_aid) component_name return @@ -244,6 +244,7 @@ toLinkedComponent { ci_ann_id = dep_aid{ann_id = uid} , ci_renaming = rns , ci_implicit = i + , ci_alias = alias } ) diff --git a/Cabal/src/Distribution/Backpack/ModuleScope.hs b/Cabal/src/Distribution/Backpack/ModuleScope.hs index 5e18766a15d..40b68513149 100644 --- a/Cabal/src/Distribution/Backpack/ModuleScope.hs +++ b/Cabal/src/Distribution/Backpack/ModuleScope.hs @@ -70,6 +70,7 @@ data ModuleScope = ModuleScope { modScopeProvides :: ModuleProvides , modScopeRequires :: ModuleRequires } + deriving (Show) -- | An empty 'ModuleScope'. emptyModuleScope :: ModuleScope @@ -92,6 +93,7 @@ data ModuleSource | FromExposedModules ModuleName | FromOtherModules ModuleName | FromSignatures ModuleName + deriving (Show) -- We don't have line numbers, but if we did, we'd want to record that -- too @@ -123,7 +125,7 @@ dispComponent pn cn = -- | An 'OpenModule', annotated with where it came from in a Cabal file. data WithSource a = WithSource ModuleSource a - deriving (Functor, Foldable, Traversable) + deriving (Show, Functor, Foldable, Traversable) unWithSource :: WithSource a -> a unWithSource (WithSource _ x) = x diff --git a/Cabal/src/Distribution/Backpack/PreExistingComponent.hs b/Cabal/src/Distribution/Backpack/PreExistingComponent.hs index 5f937de9062..3c5bc90e1f5 100644 --- a/Cabal/src/Distribution/Backpack/PreExistingComponent.hs +++ b/Cabal/src/Distribution/Backpack/PreExistingComponent.hs @@ -27,6 +27,7 @@ import Distribution.Types.AnnotatedId data PromisedComponent = PromisedComponent { pr_pkgname :: PackageName , pr_cid :: AnnotatedId ComponentId + , pr_alias :: IsPrivate } instance Package PromisedComponent where @@ -47,13 +48,14 @@ data PreExistingComponent = PreExistingComponent , pc_cid :: ComponentId , pc_open_uid :: OpenUnitId , pc_shape :: ModuleShape + , pc_alias :: IsPrivate } -- | Convert an 'InstalledPackageInfo' into a 'PreExistingComponent', -- which was brought into scope under the 'PackageName' (important for -- a package qualified reference.) -ipiToPreExistingComponent :: InstalledPackageInfo -> PreExistingComponent -ipiToPreExistingComponent ipi = +ipiToPreExistingComponent :: IsPrivate -> InstalledPackageInfo -> PreExistingComponent +ipiToPreExistingComponent alias ipi = PreExistingComponent { pc_pkgname = packageName ipi , pc_compname = CLibName $ Installed.sourceLibName ipi @@ -65,6 +67,7 @@ ipiToPreExistingComponent ipi = (Installed.installedComponentId ipi) (Map.fromList (Installed.instantiatedWith ipi)) , pc_shape = shapeInstalledPackage ipi + , pc_alias = alias } instance HasMungedPackageId PreExistingComponent where diff --git a/Cabal/src/Distribution/Backpack/UnifyM.hs b/Cabal/src/Distribution/Backpack/UnifyM.hs index 6e0f00d9f63..46d1be8d5a1 100644 --- a/Cabal/src/Distribution/Backpack/UnifyM.hs +++ b/Cabal/src/Distribution/Backpack/UnifyM.hs @@ -481,6 +481,7 @@ convertInclude } , ci_renaming = incl@(IncludeRenaming prov_rns req_rns) , ci_implicit = implicit + , ci_alias = alias } ) = addErrContext (text "In" <+> ci_msg ci) $ do let pn = packageName pid @@ -619,12 +620,31 @@ convertInclude | (from, to) <- rns ] return (r, prov_rns) + + -- TODO: Test hiding and private depends to check that works + + -- Expand the alias + let prepend_alias mn = case alias of + Private (PrivateAlias alias_mn) -> combineModuleName alias_mn mn + Public -> mn + + let pre_prov_scope' = map (first prepend_alias) pre_prov_scope + + let prov_rns'' = + case prov_rns' of + DefaultRenaming -> case alias of + Public -> DefaultRenaming + Private{} -> ModuleRenaming (map ((\x -> (x, prepend_alias x)) . fst) (pre_prov_scope)) + ModuleRenaming rn -> ModuleRenaming (map (\(x, y) -> (x, prepend_alias y)) rn) + -- Can't happen, expanded above + HidingRenaming{} -> error "unreachable" + let prov_scope = modSubst req_subst $ Map.fromListWith (++) [ (k, [source v]) - | (k, v) <- pre_prov_scope + | (k, v) <- pre_prov_scope' ] provs_u <- convertModuleProvides prov_scope @@ -646,8 +666,9 @@ convertInclude , ann_pid = pid , ann_cname = compname } - , ci_renaming = prov_rns' + , ci_renaming = prov_rns'' , ci_implicit = ci_implicit ci + , ci_alias = alias } ) ) diff --git a/Cabal/src/Distribution/PackageDescription/Check.hs b/Cabal/src/Distribution/PackageDescription/Check.hs index ef97b0d23be..79123f7f9df 100644 --- a/Cabal/src/Distribution/PackageDescription/Check.hs +++ b/Cabal/src/Distribution/PackageDescription/Check.hs @@ -909,14 +909,15 @@ wrapParseWarning fp pw = PackageDistSuspicious (ParseWarning fp pw) -- each of those branch will be checked one by one. extractAssocDeps :: UnqualComponentName -- Name of the target library - -> CondTree ConfVar [Dependency] Library + -> CondTree ConfVar Dependencies Library -> AssocDep extractAssocDeps n ct = let a = ignoreConditions ct in -- Merging is fine here, remember the specific -- library dependencies will be checked branch -- by branch. - (n, snd a) + -- MP: TOOD: WRONG + (n, publicDependencies (snd a)) -- | August 2022: this function is an oddity due to the historical -- GenericPackageDescription/PackageDescription split (check @@ -952,8 +953,8 @@ pd2gpd pd = gpd } -- From target to simple, unconditional CondTree. - t2c :: a -> CondTree ConfVar [Dependency] a - t2c a = CondNode a [] [] + t2c :: a -> CondTree ConfVar Dependencies a + t2c a = CondNode a mempty [] -- From named target to unconditional CondTree. Notice we have -- a function to extract the name *and* a function to modify @@ -963,7 +964,7 @@ pd2gpd pd = gpd :: (a -> UnqualComponentName) -> (a -> a) -> a - -> (UnqualComponentName, CondTree ConfVar [Dependency] a) + -> (UnqualComponentName, CondTree ConfVar Dependencies a) t2cName nf mf a = (nf a, t2c . mf $ a) ln :: Library -> UnqualComponentName diff --git a/Cabal/src/Distribution/PackageDescription/Check/Conditional.hs b/Cabal/src/Distribution/PackageDescription/Check/Conditional.hs index da05b2c80b9..60ffd13477a 100644 --- a/Cabal/src/Distribution/PackageDescription/Check/Conditional.hs +++ b/Cabal/src/Distribution/PackageDescription/Check/Conditional.hs @@ -61,8 +61,8 @@ annotateCondTree . (Eq a, Monoid a) => [PackageFlag] -- User flags. -> TargetAnnotation a - -> CondTree ConfVar [Dependency] a - -> CondTree ConfVar [Dependency] (TargetAnnotation a) + -> CondTree ConfVar Dependencies a + -> CondTree ConfVar Dependencies (TargetAnnotation a) annotateCondTree fs ta (CondNode a c bs) = let ta' = updateTargetAnnotation a ta bs' = map (annotateBranch ta') bs @@ -71,10 +71,10 @@ annotateCondTree fs ta (CondNode a c bs) = where annotateBranch :: TargetAnnotation a - -> CondBranch ConfVar [Dependency] a + -> CondBranch ConfVar Dependencies a -> CondBranch ConfVar - [Dependency] + Dependencies (TargetAnnotation a) annotateBranch wta (CondBranch k t mf) = let uf = isPkgFlagCond k @@ -117,13 +117,13 @@ crossAnnotateBranches :: forall a . (Eq a, Monoid a) => [PackageFlag] -- `default: true` flags. - -> [CondBranch ConfVar [Dependency] (TargetAnnotation a)] - -> [CondBranch ConfVar [Dependency] (TargetAnnotation a)] + -> [CondBranch ConfVar Dependencies (TargetAnnotation a)] + -> [CondBranch ConfVar Dependencies (TargetAnnotation a)] crossAnnotateBranches fs bs = map crossAnnBranch bs where crossAnnBranch - :: CondBranch ConfVar [Dependency] (TargetAnnotation a) - -> CondBranch ConfVar [Dependency] (TargetAnnotation a) + :: CondBranch ConfVar Dependencies (TargetAnnotation a) + -> CondBranch ConfVar Dependencies (TargetAnnotation a) crossAnnBranch wr = let rs = filter (/= wr) bs @@ -131,7 +131,7 @@ crossAnnotateBranches fs bs = map crossAnnBranch bs in updateTargetAnnBranch (mconcat ts) wr - realiseBranch :: CondBranch ConfVar [Dependency] (TargetAnnotation a) -> Maybe a + realiseBranch :: CondBranch ConfVar Dependencies (TargetAnnotation a) -> Maybe a realiseBranch b = let -- We are only interested in True by default package flags. @@ -144,8 +144,8 @@ crossAnnotateBranches fs bs = map crossAnnBranch bs updateTargetAnnBranch :: a - -> CondBranch ConfVar [Dependency] (TargetAnnotation a) - -> CondBranch ConfVar [Dependency] (TargetAnnotation a) + -> CondBranch ConfVar Dependencies (TargetAnnotation a) + -> CondBranch ConfVar Dependencies (TargetAnnotation a) updateTargetAnnBranch a (CondBranch k t mt) = let updateTargetAnnTree (CondNode ka c wbs) = (CondNode (updateTargetAnnotation a ka) c wbs) @@ -163,7 +163,7 @@ checkCondTarget -- Naming function (some targets -- need to have their name -- spoonfed to them. - -> (UnqualComponentName, CondTree ConfVar [Dependency] a) + -> (UnqualComponentName, CondTree ConfVar Dependencies a) -- Target name/condtree. -> CheckM m () checkCondTarget fs cf nf (unqualName, ct) = @@ -172,7 +172,7 @@ checkCondTarget fs cf nf (unqualName, ct) = -- Walking the tree. Remember that CondTree is not a binary -- tree but a /rose/tree. wTree - :: CondTree ConfVar [Dependency] (TargetAnnotation a) + :: CondTree ConfVar Dependencies (TargetAnnotation a) -> CheckM m () wTree (CondNode ta _ bs) -- There are no branches ([] == True) *or* every branch @@ -190,13 +190,13 @@ checkCondTarget fs cf nf (unqualName, ct) = mapM_ wBranch bs isSimple - :: CondBranch ConfVar [Dependency] (TargetAnnotation a) + :: CondBranch ConfVar Dependencies (TargetAnnotation a) -> Bool isSimple (CondBranch _ _ Nothing) = True isSimple (CondBranch _ _ (Just _)) = False wBranch - :: CondBranch ConfVar [Dependency] (TargetAnnotation a) + :: CondBranch ConfVar Dependencies (TargetAnnotation a) -> CheckM m () wBranch (CondBranch k t mf) = do checkCondVars k diff --git a/Cabal/src/Distribution/Simple/Configure.hs b/Cabal/src/Distribution/Simple/Configure.hs index 3dfe0b7e0be..abc36cdf78b 100644 --- a/Cabal/src/Distribution/Simple/Configure.hs +++ b/Cabal/src/Distribution/Simple/Configure.hs @@ -6,6 +6,7 @@ {-# LANGUAGE RankNTypes #-} {-# LANGUAGE RecordWildCards #-} {-# LANGUAGE ScopedTypeVariables #-} +{-# LANGUAGE TupleSections #-} ----------------------------------------------------------------------------- @@ -818,9 +819,9 @@ computeLocalBuildConfig cfg comp programDb = do data PackageInfo = PackageInfo { internalPackageSet :: Set LibraryName - , promisedDepsSet :: Map (PackageName, ComponentName) ComponentId + , promisedDepsSet :: Map (PackageName, ComponentName, IsPrivate) ComponentId , installedPackageSet :: InstalledPackageIndex - , requiredDepsMap :: Map (PackageName, ComponentName) InstalledPackageInfo + , requiredDepsMap :: Map (PackageName, ComponentName, IsPrivate) InstalledPackageInfo } configurePackage @@ -973,12 +974,12 @@ finalizeAndConfigurePackage cfg lbc0 g_pkg_descr comp platform enabled = do -- NB: The fact that we bundle all the constraints together means -- that is not possible to configure a test-suite to use one -- version of a dependency, and the executable to use another. - ( allConstraints :: [PackageVersionConstraint] - , requiredDepsMap :: Map (PackageName, ComponentName) InstalledPackageInfo + ( allConstraints :: [(IsPrivate, PackageVersionConstraint)] + , requiredDepsMap :: Map (PackageName, ComponentName, IsPrivate) InstalledPackageInfo ) <- either (dieWithException verbosity) return $ combinedConstraints - (configConstraints cfg) + (map (Public,) $ configConstraints cfg) -- configConstraints are per package and can't specify private aliases (configDependencies cfg) installedPackageSet @@ -1354,8 +1355,8 @@ configureComponents return lbi -mkPromisedDepsSet :: [GivenComponent] -> Map (PackageName, ComponentName) ComponentId -mkPromisedDepsSet comps = Map.fromList [((pn, CLibName ln), cid) | GivenComponent pn ln cid <- comps] +mkPromisedDepsSet :: [GivenComponent] -> Map (PackageName, ComponentName, IsPrivate) ComponentId +mkPromisedDepsSet comps = Map.fromList [((pn, CLibName ln, alias), cid) | GivenComponent pn ln cid alias <- comps] -- | Adds the extra program paths from the flags provided to @configure@ as -- well as specified locations for certain known programs and their default @@ -1458,10 +1459,10 @@ dependencySatisfiable -- ^ installed set -> Set LibraryName -- ^ library components - -> Map (PackageName, ComponentName) ComponentId - -> Map (PackageName, ComponentName) InstalledPackageInfo + -> Map (PackageName, ComponentName, IsPrivate) ComponentId + -> Map (PackageName, ComponentName, IsPrivate) InstalledPackageInfo -- ^ required dependencies - -> (Dependency -> Bool) + -> (IsPrivate -> Dependency -> Bool) dependencySatisfiable use_external_internal_deps exact_config @@ -1471,6 +1472,7 @@ dependencySatisfiable packageLibraries promisedDeps requiredDepsMap + alias (Dependency depName vr sublibs) | exact_config = -- When we're given '--exact-configuration', we assume that all @@ -1493,6 +1495,7 @@ dependencySatisfiable , CLibName $ LSubLibName $ packageNameToUnqualComponentName depName + , alias ) requiredDepsMap ) @@ -1542,8 +1545,8 @@ dependencySatisfiable -- Don't check if it's visible, we promise to build it before we need it. || promised where - maybeIPI = Map.lookup (depName, CLibName lib) requiredDepsMap - promised = isJust $ Map.lookup (depName, CLibName lib) promisedDeps + maybeIPI = Map.lookup (depName, CLibName lib, alias) requiredDepsMap + promised = isJust $ Map.lookup (depName, CLibName lib, alias) promisedDeps -- | Finalize a generic package description. -- @@ -1552,8 +1555,8 @@ configureFinalizedPackage :: Verbosity -> ConfigFlags -> ComponentRequestedSpec - -> [PackageVersionConstraint] - -> (Dependency -> Bool) + -> [(IsPrivate, PackageVersionConstraint)] + -> (IsPrivate -> Dependency -> Bool) -- ^ tests if a dependency is satisfiable. -- Might say it's satisfiable even when not. -> Compiler @@ -1620,10 +1623,10 @@ configureDependencies :: Verbosity -> UseExternalInternalDeps -> Set LibraryName - -> Map (PackageName, ComponentName) ComponentId + -> Map (PackageName, ComponentName, IsPrivate) ComponentId -> InstalledPackageIndex -- ^ installed packages - -> Map (PackageName, ComponentName) InstalledPackageInfo + -> Map (PackageName, ComponentName, IsPrivate) InstalledPackageInfo -- ^ required deps -> PackageDescription -> ComponentRequestedSpec @@ -1643,7 +1646,7 @@ configureDependencies partitionEithers $ concat [ fmap (\s -> (dep, s)) <$> status - | dep <- enabledBuildDepends pkg_descr enableSpec + | (alias, dep) <- enabledBuildDepends pkg_descr enableSpec , let status = selectDependency (package pkg_descr) @@ -1652,6 +1655,7 @@ configureDependencies installedPackageSet requiredDepsMap use_external_internal_deps + alias dep ] @@ -1874,16 +1878,17 @@ selectDependency -- ^ Package id of current package -> Set LibraryName -- ^ package libraries - -> Map (PackageName, ComponentName) ComponentId + -> Map (PackageName, ComponentName, IsPrivate) ComponentId -- ^ Set of components that are promised, i.e. are not installed already. See 'PromisedDependency' for more details. -> InstalledPackageIndex -- ^ Installed packages - -> Map (PackageName, ComponentName) InstalledPackageInfo + -> Map (PackageName, ComponentName, IsPrivate) InstalledPackageInfo -- ^ Packages for which we have been given specific deps to -- use -> UseExternalInternalDeps -- ^ Are we configuring a -- single component? + -> IsPrivate -> Dependency -> [Either FailedDependency DependencyResolution] selectDependency @@ -1893,6 +1898,7 @@ selectDependency installedIndex requiredDepsMap use_external_internal_deps + alias (Dependency dep_pkgname vr libs) = -- If the dependency specification matches anything in the internal package -- index, then we prefer that match to anything in the second. @@ -1926,31 +1932,31 @@ selectDependency -- We have to look it up externally do_external_external :: LibraryName -> Either FailedDependency DependencyResolution do_external_external lib - | Just cid <- Map.lookup (dep_pkgname, CLibName lib) promisedIndex = - return $ PromisedDependency (PromisedComponent dep_pkgname (AnnotatedId currentCabalId (CLibName lib) cid)) + | Just cid <- Map.lookup (dep_pkgname, CLibName lib, alias) promisedIndex = + return $ PromisedDependency (PromisedComponent dep_pkgname (AnnotatedId currentCabalId (CLibName lib) cid) alias) do_external_external lib = do - ipi <- case Map.lookup (dep_pkgname, CLibName lib) requiredDepsMap of + ipi <- case Map.lookup (dep_pkgname, CLibName lib, alias) requiredDepsMap of -- If we know the exact pkg to use, then use it. Just pkginstance -> Right pkginstance -- Otherwise we just pick an arbitrary instance of the latest version. Nothing -> case pickLastIPI $ PackageIndex.lookupInternalDependency installedIndex dep_pkgname vr lib of Nothing -> Left (DependencyNotExists dep_pkgname) Just pkg -> Right pkg - return $ ExternalDependency $ ipiToPreExistingComponent ipi + return $ ExternalDependency $ ipiToPreExistingComponent alias ipi do_external_internal :: LibraryName -> Either FailedDependency DependencyResolution do_external_internal lib - | Just cid <- Map.lookup (dep_pkgname, CLibName lib) promisedIndex = - return $ PromisedDependency (PromisedComponent dep_pkgname (AnnotatedId currentCabalId (CLibName lib) cid)) + | Just cid <- Map.lookup (dep_pkgname, CLibName lib, alias) promisedIndex = + return $ PromisedDependency (PromisedComponent dep_pkgname (AnnotatedId currentCabalId (CLibName lib) cid) alias) do_external_internal lib = do - ipi <- case Map.lookup (dep_pkgname, CLibName lib) requiredDepsMap of + ipi <- case Map.lookup (dep_pkgname, CLibName lib, alias) requiredDepsMap of -- If we know the exact pkg to use, then use it. Just pkginstance -> Right pkginstance Nothing -> case pickLastIPI $ PackageIndex.lookupInternalDependency installedIndex pn vr lib of -- It's an internal library, being looked up externally Nothing -> Left (DependencyMissingInternal dep_pkgname lib) Just pkg -> Right pkg - return $ ExternalDependency $ ipiToPreExistingComponent ipi + return $ ExternalDependency $ ipiToPreExistingComponent alias ipi pickLastIPI :: [(Version, [InstalledPackageInfo])] -> Maybe InstalledPackageInfo pickLastIPI pkgs = safeHead . snd . last =<< nonEmpty pkgs @@ -2116,14 +2122,14 @@ interpretPackageDbFlags userInstall specificDBs = -- deps in the end. So we still need to remember which installed packages to -- pick. combinedConstraints - :: [PackageVersionConstraint] + :: [(IsPrivate, PackageVersionConstraint)] -> [GivenComponent] -- ^ installed dependencies -> InstalledPackageIndex -> Either CabalException - ( [PackageVersionConstraint] - , Map (PackageName, ComponentName) InstalledPackageInfo + ( [(IsPrivate, PackageVersionConstraint)] + , Map (PackageName, ComponentName, IsPrivate) InstalledPackageInfo ) combinedConstraints constraints dependencies installedPackages = do when (not (null badComponentIds)) $ @@ -2134,27 +2140,27 @@ combinedConstraints constraints dependencies installedPackages = do return (allConstraints, idConstraintMap) where - allConstraints :: [PackageVersionConstraint] + allConstraints :: [(IsPrivate, PackageVersionConstraint)] allConstraints = constraints - ++ [ thisPackageVersionConstraint (packageId pkg) - | (_, _, _, Just pkg) <- dependenciesPkgInfo + ++ [ (mAlias, thisPackageVersionConstraint (packageId pkg)) + | (_, _, mAlias, _, Just pkg) <- dependenciesPkgInfo ] - idConstraintMap :: Map (PackageName, ComponentName) InstalledPackageInfo + idConstraintMap :: Map (PackageName, ComponentName, IsPrivate) InstalledPackageInfo idConstraintMap = Map.fromList -- NB: do NOT use the packageName from -- dependenciesPkgInfo! - [ ((pn, cname), pkg) - | (pn, cname, _, Just pkg) <- dependenciesPkgInfo + [ ((pn, cname, alias), pkg) + | (pn, cname, alias, _, Just pkg) <- dependenciesPkgInfo ] -- The dependencies along with the installed package info, if it exists - dependenciesPkgInfo :: [(PackageName, ComponentName, ComponentId, Maybe InstalledPackageInfo)] + dependenciesPkgInfo :: [(PackageName, ComponentName, IsPrivate, ComponentId, Maybe InstalledPackageInfo)] dependenciesPkgInfo = - [ (pkgname, CLibName lname, cid, mpkg) - | GivenComponent pkgname lname cid <- dependencies + [ (pkgname, CLibName lname, alias, cid, mpkg) + | GivenComponent pkgname lname cid alias <- dependencies , let mpkg = PackageIndex.lookupComponentId installedPackages @@ -2165,8 +2171,8 @@ combinedConstraints constraints dependencies installedPackages = do -- (i.e. someone has written a hash) and didn't find it then it's -- an error. badComponentIds = - [ (pkgname, cname, cid) - | (pkgname, cname, cid, Nothing) <- dependenciesPkgInfo + [ (pkgname, cname, alias, cid) + | (pkgname, cname, alias, cid, Nothing) <- dependenciesPkgInfo ] dispDependencies deps = @@ -2180,8 +2186,9 @@ combinedConstraints constraints dependencies installedPackages = do _ -> ":" <<>> pretty cname <<>> char '=' <<>> pretty cid + <<>> foldIsPrivate "" (\a -> "=" <<>> pretty a) alias ) - | (pkgname, cname, cid) <- deps + | (pkgname, cname, alias, cid) <- deps ] -- ----------------------------------------------------------------------------- diff --git a/Cabal/src/Distribution/Simple/Errors.hs b/Cabal/src/Distribution/Simple/Errors.hs index 45029565e99..23602c92f64 100644 --- a/Cabal/src/Distribution/Simple/Errors.hs +++ b/Cabal/src/Distribution/Simple/Errors.hs @@ -125,7 +125,7 @@ data CabalException | CantFindForeignLibraries [String] | ExpectedAbsoluteDirectory FilePath | FlagsNotSpecified [FlagName] - | EncounteredMissingDependency [Dependency] + | EncounteredMissingDependency Dependencies | CompilerDoesn'tSupportThinning | CompilerDoesn'tSupportReexports | CompilerDoesn'tSupportBackpack @@ -553,8 +553,11 @@ exceptionMessage e = case e of . sep . punctuate comma . map (pretty . simplifyDependency) + . allDependencies $ missing ) + where + allDependencies (Dependencies pub priv) = pub ++ concatMap private_depends priv CompilerDoesn'tSupportThinning -> "Your compiler does not support thinning and renaming on " ++ "package flags. To use this feature you must use " diff --git a/Cabal/src/Distribution/Simple/GHC/Internal.hs b/Cabal/src/Distribution/Simple/GHC/Internal.hs index a4b75cdb6d3..87fc54fc05c 100644 --- a/Cabal/src/Distribution/Simple/GHC/Internal.hs +++ b/Cabal/src/Distribution/Simple/GHC/Internal.hs @@ -672,7 +672,7 @@ getHaskellObjects _implInfo lib lbi clbi pref wanted_obj_ext allow_split_objs -- and is a hack to avoid passing bogus `-package` arguments to GHC. The assumption being that -- in 99% of cases we will include the right `-package` so that the C file finds the right headers. mkGhcOptPackages - :: Map (PackageName, ComponentName) ComponentId + :: Map (PackageName, ComponentName, IsPrivate) ComponentId -> ComponentLocalBuildInfo -> [(OpenUnitId, ModuleRenaming)] mkGhcOptPackages promisedPkgsMap clbi = diff --git a/Cabal/src/Distribution/Simple/Setup/Config.hs b/Cabal/src/Distribution/Simple/Setup/Config.hs index 14e76c7d769..60633eb4498 100644 --- a/Cabal/src/Distribution/Simple/Setup/Config.hs +++ b/Cabal/src/Distribution/Simple/Setup/Config.hs @@ -756,7 +756,7 @@ configureOptions showOrParseArgs = configDependencies (\v flags -> flags{configDependencies = v}) ( reqArg - "NAME[:COMPONENT_NAME]=CID" + "NAME[:COMPONENT_NAME]=CID[=ALIAS]" (parsecToReadE (const "dependency expected") ((\x -> [x]) `fmap` parsecGivenComponent)) (map prettyGivenComponent) ) @@ -767,7 +767,7 @@ configureOptions showOrParseArgs = configPromisedDependencies (\v flags -> flags{configPromisedDependencies = v}) ( reqArg - "NAME[:COMPONENT_NAME]=CID" + "NAME[:COMPONENT_NAME]=CID[=ALIAS]" (parsecToReadE (const "dependency expected") ((\x -> [x]) `fmap` parsecGivenComponent)) (map prettyGivenComponent) ) @@ -910,16 +910,20 @@ parsecGivenComponent = do else LSubLibName ucn _ <- P.char '=' cid <- parsec - return $ GivenComponent pn ln cid + alias <- P.option Public $ do + _ <- P.char '=' + Private <$> parsec + return $ GivenComponent pn ln cid alias prettyGivenComponent :: GivenComponent -> String -prettyGivenComponent (GivenComponent pn cn cid) = +prettyGivenComponent (GivenComponent pn cn cid alias) = prettyShow pn ++ case cn of LMainLibName -> "" LSubLibName n -> ":" ++ prettyShow n ++ "=" ++ prettyShow cid + ++ (case alias of Public -> ""; Private a -> "=" ++ prettyShow a) installDirsOptions :: [OptionField (InstallDirs (Flag PathTemplate))] installDirsOptions = diff --git a/Cabal/src/Distribution/Types/ComponentInclude.hs b/Cabal/src/Distribution/Types/ComponentInclude.hs index 6999b6544d7..604e0975cc6 100644 --- a/Cabal/src/Distribution/Types/ComponentInclude.hs +++ b/Cabal/src/Distribution/Types/ComponentInclude.hs @@ -7,6 +7,7 @@ module Distribution.Types.ComponentInclude import Distribution.Types.AnnotatedId import Distribution.Types.ComponentName +import Distribution.Types.Dependency (IsPrivate) import Distribution.Types.PackageId -- Once ci_id is refined to an 'OpenUnitId' or 'DefUnitId', @@ -19,7 +20,9 @@ data ComponentInclude id rn = ComponentInclude , ci_implicit :: Bool -- ^ Did this come from an entry in @mixins@, or -- was implicitly generated by @build-depends@? + , ci_alias :: IsPrivate } + deriving (Show) ci_id :: ComponentInclude id rn -> id ci_id = ann_id . ci_ann_id diff --git a/Cabal/src/Distribution/Types/GivenComponent.hs b/Cabal/src/Distribution/Types/GivenComponent.hs index c8314311d89..1ebcea15f79 100644 --- a/Cabal/src/Distribution/Types/GivenComponent.hs +++ b/Cabal/src/Distribution/Types/GivenComponent.hs @@ -8,6 +8,7 @@ module Distribution.Types.GivenComponent import Distribution.Compat.Prelude import Distribution.Types.ComponentId +import Distribution.Types.Dependency import Distribution.Types.LibraryName import Distribution.Types.PackageName @@ -22,6 +23,7 @@ data GivenComponent = GivenComponent , givenComponentName :: LibraryName -- --dependency is for libraries -- only, not for any component , givenComponentId :: ComponentId + , givenComponentAlias :: IsPrivate } deriving (Generic, Read, Show, Eq, Typeable) diff --git a/Cabal/src/Distribution/Types/LocalBuildConfig.hs b/Cabal/src/Distribution/Types/LocalBuildConfig.hs index 9126d92f1eb..070908f3b11 100644 --- a/Cabal/src/Distribution/Types/LocalBuildConfig.hs +++ b/Cabal/src/Distribution/Types/LocalBuildConfig.hs @@ -101,7 +101,7 @@ data ComponentBuildDescr = ComponentBuildDescr -- ^ A map from component name to all matching -- components. These coincide with 'componentGraph' -- There may be more than one matching component because of backpack instantiations - , promisedPkgs :: Map (PackageName, ComponentName) ComponentId + , promisedPkgs :: Map (PackageName, ComponentName, IsPrivate) ComponentId -- ^ The packages we were promised, but aren't already installed. -- MP: Perhaps this just needs to be a Set UnitId at this stage. , installedPkgs :: InstalledPackageIndex diff --git a/Cabal/src/Distribution/Types/LocalBuildInfo.hs b/Cabal/src/Distribution/Types/LocalBuildInfo.hs index a5706fff09a..799c48e0d7b 100644 --- a/Cabal/src/Distribution/Types/LocalBuildInfo.hs +++ b/Cabal/src/Distribution/Types/LocalBuildInfo.hs @@ -156,7 +156,7 @@ pattern LocalBuildInfo -> Maybe (SymbolicPath Pkg File) -> Graph ComponentLocalBuildInfo -> Map ComponentName [ComponentLocalBuildInfo] - -> Map (PackageName, ComponentName) ComponentId + -> Map (PackageName, ComponentName, IsPrivate) ComponentId -> InstalledPackageIndex -> PackageDescription -> ProgramDb diff --git a/cabal-install-solver/cabal-install-solver.cabal b/cabal-install-solver/cabal-install-solver.cabal index a531ef12635..ab41ac7786b 100644 --- a/cabal-install-solver/cabal-install-solver.cabal +++ b/cabal-install-solver/cabal-install-solver.cabal @@ -66,11 +66,13 @@ library Distribution.Solver.Modular.MessageUtils Distribution.Solver.Modular.Package Distribution.Solver.Modular.Preference + Distribution.Solver.Modular.PrivateScopeClosure Distribution.Solver.Modular.PSQ Distribution.Solver.Modular.RetryLog Distribution.Solver.Modular.Solver Distribution.Solver.Modular.Tree Distribution.Solver.Modular.Validate + Distribution.Solver.Modular.ValidateDependencies Distribution.Solver.Modular.Var Distribution.Solver.Modular.Version Distribution.Solver.Modular.WeightedPSQ diff --git a/cabal-install-solver/src/Distribution/Solver/Modular/Assignment.hs b/cabal-install-solver/src/Distribution/Solver/Modular/Assignment.hs index d1ae64e5b38..00d5666ba8f 100644 --- a/cabal-install-solver/src/Distribution/Solver/Modular/Assignment.hs +++ b/cabal-install-solver/src/Distribution/Solver/Modular/Assignment.hs @@ -54,7 +54,7 @@ toCPs (A pa fa sa) rdm = cvm :: QPN -> Maybe Vertex -- Note that the RevDepMap contains duplicate dependencies. Therefore the nub. (g, vm, cvm) = graphFromEdges (L.map (\ (x, xs) -> ((), x, nub xs)) - (M.toList rdm)) + (M.toList $ revDeps rdm)) tg :: Graph Component tg = transposeG g -- Topsort the dependency graph, yielding a list of pkgs in the right order. diff --git a/cabal-install-solver/src/Distribution/Solver/Modular/Builder.hs b/cabal-install-solver/src/Distribution/Solver/Modular/Builder.hs index 5d196f4fd9f..d9a2a7b5e2a 100644 --- a/cabal-install-solver/src/Distribution/Solver/Modular/Builder.hs +++ b/cabal-install-solver/src/Distribution/Solver/Modular/Builder.hs @@ -73,7 +73,7 @@ extendOpen qpn' gs s@(BS { rdeps = gs', open = o' }) = go gs' o' gs -- the later addition will have better dependency information. go g o ((Stanza sn@(SN qpn _) t) : ngs) = go g (StanzaGoal sn t (flagGR qpn) : o) ngs - go g o ((Simple (LDep dr (Dep (PkgComponent qpn _) _)) c) : ngs) + go g o ((Simple (LDep dr (Dep (PkgComponent qpn _) _is_private _)) c) : ngs) | qpn == qpn' = -- We currently only add a self-dependency to the graph if it is -- between a package and its setup script. The edge creates a cycle @@ -81,10 +81,19 @@ extendOpen qpn' gs s@(BS { rdeps = gs', open = o' }) = go gs' o' gs -- instance for the setup script. We may need to track other -- self-dependencies once we implement component-based solving. case c of - ComponentSetup -> go (M.adjust (addIfAbsent (ComponentSetup, qpn')) qpn g) o ngs + ComponentSetup -> go g{revDeps = M.adjust (addIfAbsent (ComponentSetup, qpn')) qpn (revDeps g)} o ngs _ -> go g o ngs - | qpn `M.member` g = go (M.adjust (addIfAbsent (c, qpn')) qpn g) o ngs - | otherwise = go (M.insert qpn [(c, qpn')] g) (PkgGoal qpn (DependencyGoal dr) : o) ngs + | qpn `M.member` (revDeps g) + = go g{ revDeps = M.adjust (addIfAbsent (c, qpn')) qpn (revDeps g) + -- If qpn is already a member of revDeps, it is already in the privScopes mapping. + } o ngs + | otherwise + = go g{ revDeps = M.insert qpn [(c, qpn')] (revDeps g) + , privScopes = case qpn of + Q (PackagePath _ ql@QualAlias{}) _ -> + M.insertWith(<>) ql (S.singleton qpn) (privScopes g) + _ -> privScopes g + } (PkgGoal qpn (DependencyGoal dr) : o) ngs -- code above is correct; insert/adjust have different arg order go g o ((Simple (LDep _dr (Ext _ext )) _) : ngs) = go g o ngs go g o ((Simple (LDep _dr (Lang _lang))_) : ngs) = go g o ngs @@ -100,12 +109,12 @@ extendOpen qpn' gs s@(BS { rdeps = gs', open = o' }) = go gs' o' gs -- | Given the current scope, qualify all the package names in the given set of -- dependencies and then extend the set of open goals accordingly. -scopedExtendOpen :: QPN -> FlaggedDeps PN -> FlagInfo -> +scopedExtendOpen :: RevDepMap -> QPN -> FlaggedDeps PN -> FlagInfo -> BuildState -> BuildState -scopedExtendOpen qpn fdeps fdefs s = extendOpen qpn gs s +scopedExtendOpen rdm qpn fdeps fdefs s = extendOpen qpn gs s where -- Qualify all package names - qfdeps = qualifyDeps (qualifyOptions s) qpn fdeps + qfdeps = qualifyDeps (qualifyOptions s) rdm qpn fdeps -- Introduce all package flags qfdefs = L.map (\ (fn, b) -> Flagged (FN qpn fn) b [] []) $ M.toList fdefs -- Combine new package and flag goals @@ -179,8 +188,8 @@ addChildren bs@(BS { rdeps = rdm, next = OneGoal (StanzaGoal qsn@(SN qpn _) t gr -- and furthermore we update the set of goals. -- -- TODO: We could inline this above. -addChildren bs@(BS { next = Instance qpn (PInfo fdeps _ fdefs _) }) = - addChildren ((scopedExtendOpen qpn fdeps fdefs bs) +addChildren bs@(BS { rdeps = rdm, next = Instance qpn (PInfo fdeps _ fdefs _) }) = + addChildren ((scopedExtendOpen rdm qpn fdeps fdefs bs) { next = Goals }) {------------------------------------------------------------------------------- @@ -252,7 +261,7 @@ buildTree idx (IndependentGoals ind) igs = build Linker { buildState = BS { index = idx - , rdeps = M.fromList (L.map (\ qpn -> (qpn, [])) qpns) + , rdeps = RevDepMap { revDeps = M.fromList (L.map (\ qpn -> (qpn, [])) qpns), privScopes = mempty } , open = L.map topLevelGoal qpns , next = Goals , qualifyOptions = defaultQualifyOptions idx @@ -263,7 +272,7 @@ buildTree idx (IndependentGoals ind) igs = topLevelGoal qpn = PkgGoal qpn UserGoal qpns | ind = L.map makeIndependent igs - | otherwise = L.map (Q (PackagePath DefaultNamespace QualToplevel)) igs + | otherwise = L.map (Q (PackagePath DefaultNamespace QualToplevel) ) igs {------------------------------------------------------------------------------- Goals diff --git a/cabal-install-solver/src/Distribution/Solver/Modular/ConfiguredConversion.hs b/cabal-install-solver/src/Distribution/Solver/Modular/ConfiguredConversion.hs index 0e2e8ad5baa..1b9d357fdd1 100644 --- a/cabal-install-solver/src/Distribution/Solver/Modular/ConfiguredConversion.hs +++ b/cabal-install-solver/src/Distribution/Solver/Modular/ConfiguredConversion.hs @@ -4,9 +4,8 @@ module Distribution.Solver.Modular.ConfiguredConversion import Data.Maybe import Prelude hiding (pi) -import Data.Either (partitionEithers) -import Distribution.Package (UnitId, packageId) +import Distribution.Package (UnitId) import qualified Distribution.Simple.PackageIndex as SI @@ -21,6 +20,7 @@ import Distribution.Solver.Types.SolverId import Distribution.Solver.Types.SolverPackage import Distribution.Solver.Types.InstSolverPackage import Distribution.Solver.Types.SourcePackage +import Distribution.Types.Dependency (IsPrivate(..), PrivateAlias) -- | Converts from the solver specific result @CP QPN@ into -- a 'ResolverPackage', which can then be converted into @@ -33,40 +33,69 @@ convCP iidx sidx (CP qpi fa es ds) = Left pi -> PreExisting $ InstSolverPackage { instSolverPkgIPI = fromJust $ SI.lookupUnitId iidx pi, - instSolverPkgLibDeps = fmap fst ds', - instSolverPkgExeDeps = fmap snd ds' + instSolverPkgLibDeps = fmap fst (ds' Nothing), + instSolverPkgExeDeps = fmap snd (ds' Nothing) } Right pi -> Configured $ - SolverPackage { + let libAndExeDeps = ds' (Just (pkgName pi)) + in SolverPackage { solverPkgSource = srcpkg, solverPkgFlags = fa, solverPkgStanzas = es, - solverPkgLibDeps = fmap fst ds', - solverPkgExeDeps = fmap snd ds' + solverPkgLibDeps = fmap fst libAndExeDeps, + solverPkgExeDeps = fmap snd libAndExeDeps } where srcpkg = fromMaybe (error "convCP: lookupPackageId failed") $ CI.lookupPackageId sidx pi where - ds' :: ComponentDeps ([SolverId] {- lib -}, [SolverId] {- exe -}) - ds' = fmap (partitionEithers . map convConfId) ds + + ds' :: Maybe PackageName -> ComponentDeps (([(SolverId, IsPrivate)] {- lib -}, [SolverId] {- exe -})) + ds' pn = fmap (partitionDeps . map (convConfId pn)) ds + +partitionDeps :: [Converted] -> (([(SolverId, IsPrivate)], [SolverId])) +partitionDeps [] = ([], []) +partitionDeps (dep:deps) = + let (p, e) = partitionDeps deps + in case dep of + AliasPkg sid pn -> ((sid, Private pn) : p, e) + NormalPkg sid -> ((sid, Public) :p, e) + NormalExe sid -> (p, sid:e) convPI :: PI QPN -> Either UnitId PackageId convPI (PI _ (I _ (Inst pi))) = Left pi -convPI pi = Right (packageId (either id id (convConfId pi))) +convPI (PI (Q _ pn) (I v _)) = Right (PackageIdentifier pn v) + +data Converted = NormalPkg SolverId | NormalExe SolverId | AliasPkg SolverId PrivateAlias + deriving Show -convConfId :: PI QPN -> Either SolverId {- is lib -} SolverId {- is exe -} -convConfId (PI (Q (PackagePath _ q) pn) (I v loc)) = +convConfId :: Maybe PackageName -> PI QPN -> Converted +convConfId parent (PI (Q (PackagePath ns qn) pn) (I v loc)) = case loc of - Inst pi -> Left (PreExistingId sourceId pi) + Inst pi + -- As below, we need to identify where `AliasPkg` applies. This is + -- needed to qualify `solverPkgLibDeps` since we may have multiple + -- instances of the same package qualified. + | QualAlias pn' alias <- qn + , parent == Just pn' -> AliasPkg (PreExistingId sourceId pi) alias + + | otherwise + -> NormalPkg (PreExistingId sourceId pi) _otherwise - | QualExe _ pn' <- q + -- Same reasoning as for exes, the "top" qualified goal is the one + -- which is private and needs to be aliased, but there might be other goals underneath which + -- are solved in the same scope (but are not private) + | QualAlias pn' alias <- qn + , parent == Just pn' -> AliasPkg (PlannedId sourceId) alias + + | IndependentBuildTool _ pn' <- ns -- NB: the dependencies of the executable are also -- qualified. So the way to tell if this is an executable -- dependency is to make sure the qualifier is pointing -- at the actual thing. Fortunately for us, I was -- silly and didn't allow arbitrarily nested build-tools -- dependencies, so a shallow check works. - , pn == pn' -> Right (PlannedId sourceId) - | otherwise -> Left (PlannedId sourceId) + , pn == pn' -> NormalExe (PlannedId sourceId) + + | otherwise -> NormalPkg (PlannedId sourceId) where sourceId = PackageIdentifier pn v diff --git a/cabal-install-solver/src/Distribution/Solver/Modular/Cycles.hs b/cabal-install-solver/src/Distribution/Solver/Modular/Cycles.hs index b82e39a0d26..eaf0b1bb789 100644 --- a/cabal-install-solver/src/Distribution/Solver/Modular/Cycles.hs +++ b/cabal-install-solver/src/Distribution/Solver/Modular/Cycles.hs @@ -1,6 +1,7 @@ +{-# LANGUAGE TupleSections #-} {-# LANGUAGE TypeFamilies #-} module Distribution.Solver.Modular.Cycles ( - detectCyclesPhase + findCycles ) where import Prelude hiding (cycle) @@ -8,51 +9,20 @@ import qualified Data.Map as M import qualified Data.Set as S import qualified Distribution.Compat.Graph as G -import Distribution.Simple.Utils (ordNub) import Distribution.Solver.Modular.Dependency -import Distribution.Solver.Modular.Flag import Distribution.Solver.Modular.Tree import qualified Distribution.Solver.Modular.ConflictSet as CS -import Distribution.Solver.Types.ComponentDeps (Component) import Distribution.Solver.Types.PackagePath +import Distribution.Solver.Modular.ValidateDependencies --- | Find and reject any nodes with cyclic dependencies -detectCyclesPhase :: Tree d c -> Tree d c -detectCyclesPhase = go - where - -- Only check children of choice nodes. - go :: Tree d c -> Tree d c - go (PChoice qpn rdm gr cs) = - PChoice qpn rdm gr $ fmap (checkChild qpn) (fmap go cs) - go (FChoice qfn@(FN qpn _) rdm gr w m d cs) = - FChoice qfn rdm gr w m d $ fmap (checkChild qpn) (fmap go cs) - go (SChoice qsn@(SN qpn _) rdm gr w cs) = - SChoice qsn rdm gr w $ fmap (checkChild qpn) (fmap go cs) - go (GoalChoice rdm cs) = GoalChoice rdm (fmap go cs) - go x@(Fail _ _) = x - go x@(Done _ _) = x - - checkChild :: QPN -> Tree d c -> Tree d c - checkChild qpn x@(PChoice _ rdm _ _) = failIfCycle qpn rdm x - checkChild qpn x@(FChoice _ rdm _ _ _ _ _) = failIfCycle qpn rdm x - checkChild qpn x@(SChoice _ rdm _ _ _) = failIfCycle qpn rdm x - checkChild qpn x@(GoalChoice rdm _) = failIfCycle qpn rdm x - checkChild _ x@(Fail _ _) = x - checkChild qpn x@(Done rdm _) = failIfCycle qpn rdm x - - failIfCycle :: QPN -> RevDepMap -> Tree d c -> Tree d c - failIfCycle qpn rdm x = - case findCycles qpn rdm of - Nothing -> x - Just relSet -> Fail relSet CyclicDependencies -- | Given the reverse dependency map from a node in the tree, check -- if the solution is cyclic. If it is, return the conflict set containing -- all decisions that could potentially break the cycle. -- -- TODO: The conflict set should also contain flag and stanza variables. -findCycles :: QPN -> RevDepMap -> Maybe ConflictSet -findCycles pkg rdm = +findCycles :: QPN -> RevDepMap -> Maybe (ConflictSet, FailReason) +findCycles pkg rdm = (,CyclicDependencies) <$> -- This function has two parts: a faster cycle check that is called at every -- step and a slower calculation of the conflict set. -- @@ -102,19 +72,9 @@ findCycles pkg rdm = else foldl go (S.insert x s) $ neighbors x neighbors :: QPN -> [QPN] - neighbors x = case x `M.lookup` rdm of + neighbors x = case x `M.lookup` revDeps rdm of Nothing -> findCyclesError "cannot find node" Just xs -> map snd xs findCyclesError = error . ("Distribution.Solver.Modular.Cycles.findCycles: " ++) -data RevDepMapNode = RevDepMapNode QPN [(Component, QPN)] - -instance G.IsNode RevDepMapNode where - type Key RevDepMapNode = QPN - nodeKey (RevDepMapNode qpn _) = qpn - nodeNeighbors (RevDepMapNode _ ns) = ordNub $ map snd ns - -revDepMapToGraph :: RevDepMap -> G.Graph RevDepMapNode -revDepMapToGraph rdm = G.fromDistinctList - [RevDepMapNode qpn ns | (qpn, ns) <- M.toList rdm] diff --git a/cabal-install-solver/src/Distribution/Solver/Modular/Dependency.hs b/cabal-install-solver/src/Distribution/Solver/Modular/Dependency.hs index 27debc9c6f0..cca47f92bb1 100644 --- a/cabal-install-solver/src/Distribution/Solver/Modular/Dependency.hs +++ b/cabal-install-solver/src/Distribution/Solver/Modular/Dependency.hs @@ -25,7 +25,7 @@ module Distribution.Solver.Modular.Dependency ( , qualifyDeps , unqualifyDeps -- * Reverse dependency map - , RevDepMap + , RevDepMap(..) -- * Goals , Goal(..) , GoalReason(..) @@ -58,6 +58,7 @@ import Distribution.Solver.Types.PackagePath import Distribution.Types.LibraryName import Distribution.Types.PkgconfigVersionRange import Distribution.Types.UnqualComponentName +import Distribution.Types.Dependency {------------------------------------------------------------------------------- Constrained instances @@ -119,11 +120,11 @@ data LDep qpn = LDep (DependencyReason qpn) (Dep qpn) -- | A dependency (constraint) associates a package name with a constrained -- instance. It can also represent other types of dependencies, such as -- dependencies on language extensions. -data Dep qpn = Dep (PkgComponent qpn) CI -- ^ dependency on a package component +data Dep qpn = Dep (PkgComponent qpn) IsPrivate CI -- ^ dependency on a package component | Ext Extension -- ^ dependency on a language extension | Lang Language -- ^ dependency on a language version | Pkg PkgconfigName PkgconfigVersionRange -- ^ dependency on a pkg-config package - deriving Functor + deriving (Functor) -- | An exposed component within a package. This type is used to represent -- build-depends and build-tool-depends dependencies. @@ -174,15 +175,15 @@ data QualifyOptions = QO { -- -- NOTE: It's the _dependencies_ of a package that may or may not be independent -- from the package itself. Package flag choices must of course be consistent. -qualifyDeps :: QualifyOptions -> QPN -> FlaggedDeps PN -> FlaggedDeps QPN -qualifyDeps QO{..} (Q pp@(PackagePath ns q) pn) = go +qualifyDeps :: QualifyOptions -> RevDepMap -> QPN -> FlaggedDeps PN -> FlaggedDeps QPN +qualifyDeps QO{..} rdm (Q pp@(PackagePath ns q) pn) = go where go :: FlaggedDeps PN -> FlaggedDeps QPN go = map go1 go1 :: FlaggedDep PN -> FlaggedDep QPN - go1 (Flagged fn nfo t f) = Flagged (fmap (Q pp) fn) nfo (go t) (go f) - go1 (Stanza sn t) = Stanza (fmap (Q pp) sn) (go t) + go1 (Flagged fn nfo t f) = Flagged (fmap (Q pp ) fn) nfo (go t) (go f) + go1 (Stanza sn t) = Stanza (fmap (Q pp ) sn) (go t) go1 (Simple dep comp) = Simple (goLDep dep comp) comp -- Suppose package B has a setup dependency on package A. @@ -194,18 +195,19 @@ qualifyDeps QO{..} (Q pp@(PackagePath ns q) pn) = go -- @"A"@ into @"B-setup.A"@, but we should not apply that same qualifier -- to the DependencyReason. goLDep :: LDep PN -> Component -> LDep QPN - goLDep (LDep dr dep) comp = LDep (fmap (Q pp) dr) (goD dep comp) + goLDep (LDep dr dep) comp = LDep (fmap (Q pp ) dr) (goD dep comp) goD :: Dep PN -> Component -> Dep QPN goD (Ext ext) _ = Ext ext goD (Lang lang) _ = Lang lang goD (Pkg pkn vr) _ = Pkg pkn vr - goD (Dep dep@(PkgComponent qpn (ExposedExe _)) ci) _ = - Dep (Q (PackagePath ns (QualExe pn qpn)) <$> dep) ci - goD (Dep dep@(PkgComponent qpn (ExposedLib _)) ci) comp - | qBase qpn = Dep (Q (PackagePath ns (QualBase pn)) <$> dep) ci - | qSetup comp = Dep (Q (PackagePath ns (QualSetup pn)) <$> dep) ci - | otherwise = Dep (Q (PackagePath ns inheritedQ ) <$> dep) ci + goD (Dep dep@(PkgComponent qpn (ExposedExe _)) is_private ci) _ = + Dep (Q (PackagePath (IndependentBuildTool pn qpn) QualToplevel) <$> dep) is_private ci + goD (Dep dep@(PkgComponent qpn (ExposedLib _)) is_private ci) comp + | Private pq <- is_private = Dep (Q (PackagePath ns (QualAlias pn pq)) <$> dep) is_private ci + | qBase qpn = Dep (Q (PackagePath ns (QualBase pn)) <$> dep) is_private ci + | qSetup comp = Dep (Q (PackagePath (IndependentComponent pn ComponentSetup) QualToplevel) <$> dep) is_private ci + | otherwise = Dep (Q (PackagePath ns (inheritedQ qpn) ) <$> dep) is_private ci -- If P has a setup dependency on Q, and Q has a regular dependency on R, then -- we say that the 'Setup' qualifier is inherited: P has an (indirect) setup @@ -214,12 +216,19 @@ qualifyDeps QO{..} (Q pp@(PackagePath ns q) pn) = go -- The inherited qualifier is only used for regular dependencies; for setup -- and base dependencies we override the existing qualifier. See #3160 for -- a detailed discussion. - inheritedQ :: Qualifier - inheritedQ = case q of - QualSetup _ -> q - QualExe _ _ -> q - QualToplevel -> q - QualBase _ -> QualToplevel + inheritedQ :: PackageName -> Qualifier + inheritedQ pnx = case q of + QualToplevel -> QualToplevel + QualBase {} -> QualToplevel + -- check if package name is in same private scope (if so, persist) + QualAlias {} -> + -- Lookup this dependency in the reverse dependency map + -- with the package-path of the package that introduced + -- this dependency, which will match if this dependency is + -- included in the same private scope. + case M.lookup (Q pp pnx) (revDeps rdm) of + Just _x -> q -- found, use same private qualifier + Nothing -> QualToplevel -- not found, use top level qual -- Should we qualify this goal with the 'Base' package path? qBase :: PN -> Bool @@ -259,7 +268,12 @@ unqualifyDeps = go -- | A map containing reverse dependencies between qualified -- package names. -type RevDepMap = Map QPN [(Component, QPN)] +data RevDepMap = RevDepMap + { revDeps :: Map QPN [(Component, QPN)] + -- ^ The reverse dependencies + , privScopes :: Map Qualifier {- a private qualifier -} (S.Set QPN) {- caches the packages in this private scope -} + -- ^ Information related to reverse dependency mapped additionally cached here. + } {------------------------------------------------------------------------------- Goals diff --git a/cabal-install-solver/src/Distribution/Solver/Modular/Explore.hs b/cabal-install-solver/src/Distribution/Solver/Modular/Explore.hs index 90038a28f5c..cf1544bc0fd 100644 --- a/cabal-install-solver/src/Distribution/Solver/Modular/Explore.hs +++ b/cabal-install-solver/src/Distribution/Solver/Modular/Explore.hs @@ -220,9 +220,9 @@ exploreLog mbj enableBj fineGrainedConflicts (CountConflicts countConflicts) idx let es' = es { esConflictMap = updateCM c (esConflictMap es) } in failWith (Failure c fr) (NoSolution c es') go (DoneF rdm a) = \ _ -> succeedWith Success (a, rdm) - go (PChoiceF qpn _ gr ts) = + go (PChoiceF qpn rdm gr ts) = backjump mbj enableBj fineGrainedConflicts - (couldResolveConflicts qpn) + (couldResolveConflicts rdm qpn) (logSkippedPackage qpn) (P qpn) (avoidSet (P qpn) gr) $ -- try children in order, W.mapWithKey -- when descending ... @@ -267,23 +267,23 @@ exploreLog mbj enableBj fineGrainedConflicts (CountConflicts countConflicts) idx -- is true, because it is always safe to explore a package instance. -- Skipping it is an optimization. If false, it returns a new conflict set -- to be merged with the previous one. - couldResolveConflicts :: QPN -> POption -> S.Set CS.Conflict -> Maybe ConflictSet - couldResolveConflicts currentQPN@(Q _ pn) (POption i@(I v _) _) conflicts = + couldResolveConflicts :: RevDepMap -> QPN -> POption -> S.Set CS.Conflict -> Maybe ConflictSet + couldResolveConflicts rdm currentQPN@(Q _ pn) (POption i@(I v _) _) conflicts = let (PInfo deps _ _ _) = idx M.! pn M.! i - qdeps = qualifyDeps (defaultQualifyOptions idx) currentQPN deps + qdeps = qualifyDeps (defaultQualifyOptions idx) rdm currentQPN deps couldBeResolved :: CS.Conflict -> Maybe ConflictSet couldBeResolved CS.OtherConflict = Nothing couldBeResolved (CS.GoalConflict conflictingDep) = -- Check whether this package instance also has 'conflictingDep' -- as a dependency (ignoring flag and stanza choices). - if null [() | Simple (LDep _ (Dep (PkgComponent qpn _) _)) _ <- qdeps, qpn == conflictingDep] + if null [() | Simple (LDep _ (Dep (PkgComponent qpn _) _is_private _)) _ <- qdeps, qpn == conflictingDep] then Nothing else Just CS.empty couldBeResolved (CS.VersionConstraintConflict dep excludedVersion) = -- Check whether this package instance also excludes version -- 'excludedVersion' of 'dep' (ignoring flag and stanza choices). - let vrs = [vr | Simple (LDep _ (Dep (PkgComponent qpn _) (Constrained vr))) _ <- qdeps, qpn == dep ] + let vrs = [vr | Simple (LDep _ (Dep (PkgComponent qpn _) _is_private (Constrained vr))) _ <- qdeps, qpn == dep ] vrIntersection = L.foldl' (.&&.) anyVersion vrs in if checkVR vrIntersection excludedVersion then Nothing diff --git a/cabal-install-solver/src/Distribution/Solver/Modular/Index.hs b/cabal-install-solver/src/Distribution/Solver/Modular/Index.hs index 2f28d12de85..0c17ff731e3 100644 --- a/cabal-install-solver/src/Distribution/Solver/Modular/Index.hs +++ b/cabal-install-solver/src/Distribution/Solver/Modular/Index.hs @@ -60,13 +60,13 @@ groupMap xs = M.fromListWith (flip (++)) (L.map (\ (x, y) -> (x, [y])) xs) defaultQualifyOptions :: Index -> QualifyOptions defaultQualifyOptions idx = QO { - qoBaseShim = or [ dep == base + qoBaseShim = or [ dep == base | -- Find all versions of base .. Just is <- [M.lookup base idx] -- .. which are installed .. , (I _ver (Inst _), PInfo deps _comps _flagNfo _fr) <- M.toList is -- .. and flatten all their dependencies .. - , (LDep _ (Dep (PkgComponent dep _) _ci), _comp) <- flattenFlaggedDeps deps + , (LDep _ (Dep (PkgComponent dep _) _ _ci), _comp) <- flattenFlaggedDeps deps ] , qoSetupIndependent = True } diff --git a/cabal-install-solver/src/Distribution/Solver/Modular/IndexConversion.hs b/cabal-install-solver/src/Distribution/Solver/Modular/IndexConversion.hs index 72d0b8193e3..fc5b15f33d1 100644 --- a/cabal-install-solver/src/Distribution/Solver/Modular/IndexConversion.hs +++ b/cabal-install-solver/src/Distribution/Solver/Modular/IndexConversion.hs @@ -147,7 +147,7 @@ convIPId dr comp idx ipid = Nothing -> Left ipid Just ipi -> let (pn, i) = convId ipi name = ExposedLib LMainLibName -- TODO: Handle sub-libraries. - in Right (D.Simple (LDep dr (Dep (PkgComponent pn name) (Fixed i))) comp) + in Right (D.Simple (LDep dr (Dep (PkgComponent pn name) Public (Fixed i))) comp) -- NB: something we pick up from the -- InstalledPackageIndex is NEVER an executable @@ -172,6 +172,7 @@ convSP os arch cinfo constraints strfl solveExes (SourcePackage (PackageIdentifi -- want to keep the condition tree, but simplify much of the test. -- | Convert a generic package description to a solver-specific 'PInfo'. +-- Key function for private dependencies convGPD :: OS -> Arch -> CompilerInfo -> [LabeledPackageConstraint] -> StrongFlags -> SolveExecutables -> PN -> GenericPackageDescription -> PInfo @@ -182,7 +183,7 @@ convGPD os arch cinfo constraints strfl solveExes pn conv :: Monoid a => Component -> (a -> BuildInfo) -> DependencyReason PN -> - CondTree ConfVar [Dependency] a -> FlaggedDeps PN + CondTree ConfVar Dependencies a -> FlaggedDeps PN conv comp getInfo dr = convCondTree M.empty dr pkg os arch cinfo pn fds comp getInfo solveExes . addBuildableCondition getInfo @@ -251,7 +252,7 @@ testConditionForComponent :: OS -> CompilerInfo -> [LabeledPackageConstraint] -> (a -> Bool) - -> CondTree ConfVar [Dependency] a + -> CondTree ConfVar Dependencies a -> Maybe Bool testConditionForComponent os arch cinfo constraints p tree = case go $ extractCondition p tree of @@ -329,17 +330,20 @@ convCondTree :: Map FlagName Bool -> DependencyReason PN -> PackageDescription - Component -> (a -> BuildInfo) -> SolveExecutables -> - CondTree ConfVar [Dependency] a -> FlaggedDeps PN + CondTree ConfVar Dependencies a -> FlaggedDeps PN convCondTree flags dr pkg os arch cinfo pn fds comp getInfo solveExes@(SolveExecutables solveExes') (CondNode info ds branches) = -- Merge all library and build-tool dependencies at every level in -- the tree of flagged dependencies. Otherwise 'extractCommon' -- could create duplicate dependencies, and the number of -- duplicates could grow exponentially from the leaves to the root -- of the tree. - mergeSimpleDeps $ - [ D.Simple singleDep comp - | dep <- ds - , singleDep <- convLibDeps dr dep ] -- unconditional package dependencies + mergeSimpleDeps $ ([ D.Simple singleDep comp + | dep <- publicDependencies ds + , singleDep <- convLibDeps dr dep ]) -- unconditional package dependencies + + ++ [ D.Simple singleDep comp + | dep <- privateDependencies ds + , singleDep <- convLibDepsAs dr dep ] -- unconditional package dependencies ++ L.map (\e -> D.Simple (LDep dr (Ext e)) comp) (allExtensions bi) -- unconditional extension dependencies ++ L.map (\l -> D.Simple (LDep dr (Lang l)) comp) (allLanguages bi) -- unconditional language dependencies @@ -390,7 +394,7 @@ mergeSimpleDeps deps = L.map (uncurry toFlaggedDep) (M.toList merged) ++ unmerge => (Map (SimpleFlaggedDepKey qpn) (SimpleFlaggedDepValue qpn), FlaggedDeps qpn) -> FlaggedDep qpn -> (Map (SimpleFlaggedDepKey qpn) (SimpleFlaggedDepValue qpn), FlaggedDeps qpn) - f (merged', unmerged') (D.Simple (LDep dr (Dep dep (Constrained vr))) comp) = + f (merged', unmerged') (D.Simple (LDep dr (Dep dep Public (Constrained vr))) comp) = ( M.insertWith mergeValues (SimpleFlaggedDepKey dep comp) (SimpleFlaggedDepValue dr vr) @@ -408,7 +412,7 @@ mergeSimpleDeps deps = L.map (uncurry toFlaggedDep) (M.toList merged) ++ unmerge -> SimpleFlaggedDepValue qpn -> FlaggedDep qpn toFlaggedDep (SimpleFlaggedDepKey dep comp) (SimpleFlaggedDepValue dr vr) = - D.Simple (LDep dr (Dep dep (Constrained vr))) comp + D.Simple (LDep dr (Dep dep Public (Constrained vr))) comp -- | Branch interpreter. Mutually recursive with 'convCondTree'. -- @@ -461,7 +465,7 @@ convBranch :: Map FlagName Bool -> Component -> (a -> BuildInfo) -> SolveExecutables - -> CondBranch ConfVar [Dependency] a + -> CondBranch ConfVar Dependencies a -> FlaggedDeps PN convBranch flags dr pkg os arch cinfo pn fds comp getInfo solveExes (CondBranch c' t' mf') = go c' @@ -532,10 +536,10 @@ convBranch flags dr pkg os arch cinfo pn fds comp getInfo solveExes (CondBranch -- Union the DependencyReasons, because the extracted dependency can be -- avoided by removing the dependency from either side of the -- conditional. - [ D.Simple (LDep (unionDRs vs1 vs2) (Dep dep1 (Constrained $ vr1 .||. vr2))) comp - | D.Simple (LDep vs1 (Dep dep1 (Constrained vr1))) _ <- ps - , D.Simple (LDep vs2 (Dep dep2 (Constrained vr2))) _ <- ps' - , dep1 == dep2 + [ D.Simple (LDep (unionDRs vs1 vs2) (Dep dep1 is_private1 (Constrained $ vr1 .||. vr2))) comp + | D.Simple (LDep vs1 (Dep dep1 is_private1 (Constrained vr1))) _ <- ps + , D.Simple (LDep vs2 (Dep dep2 is_private2 (Constrained vr2))) _ <- ps' + , dep1 == dep2 && is_private1 == is_private2 ] -- | Merge DependencyReasons by unioning their variables. @@ -547,12 +551,17 @@ unionDRs (DependencyReason pn' fs1 ss1) (DependencyReason _ fs2 ss2) = -- package) to solver-specific dependencies. convLibDeps :: DependencyReason PN -> Dependency -> [LDep PN] convLibDeps dr (Dependency pn vr libs) = - [ LDep dr $ Dep (PkgComponent pn (ExposedLib lib)) (Constrained vr) + [ LDep dr $ Dep (PkgComponent pn (ExposedLib lib)) Public (Constrained vr) | lib <- NonEmptySet.toList libs ] +convLibDepsAs :: DependencyReason PN -> PrivateDependency -> [LDep PN] +convLibDepsAs dr (PrivateDependency alias deps) = + [ LDep dr $ Dep (PkgComponent pn (ExposedLib lib)) (Private alias) (Constrained vr) + | Dependency pn vr libs <- deps, lib <- NonEmptySet.toList libs ] + -- | Convert a Cabal dependency on an executable (build-tools) to a solver-specific dependency. convExeDep :: DependencyReason PN -> ExeDependency -> LDep PN -convExeDep dr (ExeDependency pn exe vr) = LDep dr $ Dep (PkgComponent pn (ExposedExe exe)) (Constrained vr) +convExeDep dr (ExeDependency pn exe vr) = LDep dr $ Dep (PkgComponent pn (ExposedExe exe)) Public (Constrained vr) -- | Convert setup dependencies convSetupBuildInfo :: PN -> SetupBuildInfo -> FlaggedDeps PN diff --git a/cabal-install-solver/src/Distribution/Solver/Modular/Linking.hs b/cabal-install-solver/src/Distribution/Solver/Modular/Linking.hs index 3e4e2de3ee6..6e9b2f3ae86 100644 --- a/cabal-install-solver/src/Distribution/Solver/Modular/Linking.hs +++ b/cabal-install-solver/src/Distribution/Solver/Modular/Linking.hs @@ -85,11 +85,11 @@ validateLinking index = (`runReader` initVS) . go go :: Tree d c -> Validate (Tree d c) go (PChoice qpn rdm gr cs) = - PChoice qpn rdm gr <$> W.traverseWithKey (goP qpn) (fmap go cs) + PChoice qpn rdm gr <$> W.traverseWithKey (goP rdm qpn) (fmap go cs) go (FChoice qfn rdm gr t m d cs) = - FChoice qfn rdm gr t m d <$> W.traverseWithKey (goF qfn) (fmap go cs) + FChoice qfn rdm gr t m d <$> W.traverseWithKey (goF rdm qfn) (fmap go cs) go (SChoice qsn rdm gr t cs) = - SChoice qsn rdm gr t <$> W.traverseWithKey (goS qsn) (fmap go cs) + SChoice qsn rdm gr t <$> W.traverseWithKey (goS rdm qsn) (fmap go cs) -- For the other nodes we just recurse go (GoalChoice rdm cs) = GoalChoice rdm <$> T.traverse go cs @@ -97,29 +97,29 @@ validateLinking index = (`runReader` initVS) . go go (Fail conflictSet failReason) = return $ Fail conflictSet failReason -- Package choices - goP :: QPN -> POption -> Validate (Tree d c) -> Validate (Tree d c) - goP qpn@(Q _pp pn) opt@(POption i _) r = do + goP :: RevDepMap -> QPN -> POption -> Validate (Tree d c) -> Validate (Tree d c) + goP rdm qpn@(Q _pp pn) opt@(POption i _) r = do vs <- ask let PInfo deps _ _ _ = vsIndex vs ! pn ! i - qdeps = qualifyDeps (vsQualifyOptions vs) qpn deps + qdeps = qualifyDeps (vsQualifyOptions vs) rdm qpn deps newSaved = M.insert qpn qdeps (vsSaved vs) - case execUpdateState (pickPOption qpn opt qdeps) vs of + case execUpdateState (pickPOption rdm qpn opt qdeps) vs of Left (cs, err) -> return $ Fail cs (DependenciesNotLinked err) Right vs' -> local (const vs' { vsSaved = newSaved }) r -- Flag choices - goF :: QFN -> Bool -> Validate (Tree d c) -> Validate (Tree d c) - goF qfn b r = do + goF :: RevDepMap -> QFN -> Bool -> Validate (Tree d c) -> Validate (Tree d c) + goF rdm qfn b r = do vs <- ask - case execUpdateState (pickFlag qfn b) vs of + case execUpdateState (pickFlag rdm qfn b) vs of Left (cs, err) -> return $ Fail cs (DependenciesNotLinked err) Right vs' -> local (const vs') r -- Stanza choices (much the same as flag choices) - goS :: QSN -> Bool -> Validate (Tree d c) -> Validate (Tree d c) - goS qsn b r = do + goS :: RevDepMap -> QSN -> Bool -> Validate (Tree d c) -> Validate (Tree d c) + goS rdm qsn b r = do vs <- ask - case execUpdateState (pickStanza qsn b) vs of + case execUpdateState (pickStanza rdm qsn b) vs of Left (cs, err) -> return $ Fail cs (DependenciesNotLinked err) Right vs' -> local (const vs') r @@ -159,9 +159,9 @@ conflict = lift' . Left execUpdateState :: UpdateState () -> ValidateState -> Either Conflict ValidateState execUpdateState = execStateT . unUpdateState -pickPOption :: QPN -> POption -> FlaggedDeps QPN -> UpdateState () -pickPOption qpn (POption i Nothing) _deps = pickConcrete qpn i -pickPOption qpn (POption i (Just pp')) deps = pickLink qpn i pp' deps +pickPOption :: RevDepMap -> QPN -> POption -> FlaggedDeps QPN -> UpdateState () +pickPOption _rdm qpn (POption i Nothing) _deps = pickConcrete qpn i +pickPOption rdm qpn (POption i (Just pp')) deps = pickLink rdm qpn i pp' deps pickConcrete :: QPN -> I -> UpdateState () pickConcrete qpn@(Q pp _) i = do @@ -177,8 +177,8 @@ pickConcrete qpn@(Q pp _) i = do Just lg -> makeCanonical lg qpn i -pickLink :: QPN -> I -> PackagePath -> FlaggedDeps QPN -> UpdateState () -pickLink qpn@(Q _pp pn) i pp' deps = do +pickLink :: RevDepMap -> QPN -> I -> PackagePath -> FlaggedDeps QPN -> UpdateState () +pickLink rdm qpn@(Q _pp pn) i pp' deps = do vs <- get -- The package might already be in a link group @@ -209,7 +209,7 @@ pickLink qpn@(Q _pp pn) i pp' deps = do updateLinkGroup lgTarget' -- Make sure all dependencies are linked as well - linkDeps target deps + linkDeps rdm target deps makeCanonical :: LinkGroup -> QPN -> I -> UpdateState () makeCanonical lg qpn@(Q pp _) i = @@ -233,8 +233,8 @@ makeCanonical lg qpn@(Q pp _) i = -- because having the direct dependencies in a link group means that we must -- have already made or will make sooner or later a link choice for one of these -- as well, and cover their dependencies at that point. -linkDeps :: QPN -> FlaggedDeps QPN -> UpdateState () -linkDeps target = \deps -> do +linkDeps :: RevDepMap -> QPN -> FlaggedDeps QPN -> UpdateState () +linkDeps rdm target = \deps -> do -- linkDeps is called in two places: when we first link one package to -- another, and when we discover more dependencies of an already linked -- package after doing some flag assignment. It is therefore important that @@ -248,7 +248,7 @@ linkDeps target = \deps -> do go1 :: FlaggedDep QPN -> FlaggedDep QPN -> UpdateState () go1 dep rdep = case (dep, rdep) of - (Simple (LDep dr1 (Dep (PkgComponent qpn _) _)) _, ~(Simple (LDep dr2 (Dep (PkgComponent qpn' _) _)) _)) -> do + (Simple (LDep dr1 (Dep (PkgComponent qpn _) _is_private1 _)) _, ~(Simple (LDep dr2 (Dep (PkgComponent qpn' _) _is_private2 _)) _)) -> do vs <- get let lg = M.findWithDefault (lgSingleton qpn Nothing) qpn $ vsLinks vs lg' = M.findWithDefault (lgSingleton qpn' Nothing) qpn' $ vsLinks vs @@ -276,19 +276,19 @@ linkDeps target = \deps -> do requalify :: FlaggedDeps QPN -> UpdateState (FlaggedDeps QPN) requalify deps = do vs <- get - return $ qualifyDeps (vsQualifyOptions vs) target (unqualifyDeps deps) + return $ qualifyDeps (vsQualifyOptions vs) rdm target (unqualifyDeps deps) -pickFlag :: QFN -> Bool -> UpdateState () -pickFlag qfn b = do +pickFlag :: RevDepMap -> QFN -> Bool -> UpdateState () +pickFlag rdm qfn b = do modify $ \vs -> vs { vsFlags = M.insert qfn b (vsFlags vs) } verifyFlag qfn - linkNewDeps (F qfn) b + linkNewDeps rdm (F qfn) b -pickStanza :: QSN -> Bool -> UpdateState () -pickStanza qsn b = do +pickStanza :: RevDepMap -> QSN -> Bool -> UpdateState () +pickStanza rdm qsn b = do modify $ \vs -> vs { vsStanzas = M.insert qsn b (vsStanzas vs) } verifyStanza qsn - linkNewDeps (S qsn) b + linkNewDeps rdm (S qsn) b -- | Link dependencies that we discover after making a flag or stanza choice. -- @@ -297,15 +297,15 @@ pickStanza qsn b = do -- non-trivial link group, then these new dependencies have to be linked as -- well. In linkNewDeps, we compute such new dependencies and make sure they are -- linked. -linkNewDeps :: Var QPN -> Bool -> UpdateState () -linkNewDeps var b = do +linkNewDeps :: RevDepMap -> Var QPN -> Bool -> UpdateState () +linkNewDeps rdm var b = do vs <- get let qpn@(Q pp pn) = varPN var qdeps = vsSaved vs ! qpn lg = vsLinks vs ! qpn newDeps = findNewDeps vs qdeps linkedTo = S.delete pp (lgMembers lg) - forM_ (S.toList linkedTo) $ \pp' -> linkDeps (Q pp' pn) newDeps + forM_ (S.toList linkedTo) $ \pp' -> linkDeps rdm (Q pp' pn) newDeps where findNewDeps :: ValidateState -> FlaggedDeps QPN -> FlaggedDeps QPN findNewDeps vs = concatMap (findNewDeps' vs) diff --git a/cabal-install-solver/src/Distribution/Solver/Modular/Message.hs b/cabal-install-solver/src/Distribution/Solver/Modular/Message.hs index e097d3e081c..3eb01081efb 100644 --- a/cabal-install-solver/src/Distribution/Solver/Modular/Message.hs +++ b/cabal-install-solver/src/Distribution/Solver/Modular/Message.hs @@ -302,6 +302,12 @@ showFR c Backjump = " (backjumping, conflict set: " ++ s showFR _ MultipleInstances = " (multiple instances)" showFR c (DependenciesNotLinked msg) = " (dependencies not linked: " ++ msg ++ "; conflict set: " ++ showConflictSet c ++ ")" showFR c CyclicDependencies = " (cyclic dependencies; conflict set: " ++ showConflictSet c ++ ")" +showFR c (InvalidPrivateScope qual) + = " (a private scope must contain its closure, but package" ++ plural ++ " " ++ showConflictSet c ++ " " ++ isOrAre ++ " not included in the private scope " ++ prettyShow qual ++ ")" + where + (plural, isOrAre) + | [_] <- CS.toList c = ("", "is") + | otherwise = ("s", "are") showFR _ (UnsupportedSpecVer ver) = " (unsupported spec-version " ++ prettyShow ver ++ ")" -- The following are internal failures. They should not occur. In the -- interest of not crashing unnecessarily, we still just print an error diff --git a/cabal-install-solver/src/Distribution/Solver/Modular/Package.hs b/cabal-install-solver/src/Distribution/Solver/Modular/Package.hs index ccd0e4d4a70..6b35808902a 100644 --- a/cabal-install-solver/src/Distribution/Solver/Modular/Package.hs +++ b/cabal-install-solver/src/Distribution/Solver/Modular/Package.hs @@ -11,8 +11,6 @@ module Distribution.Solver.Modular.Package , QPV , instI , makeIndependent - , primaryPP - , setupPP , showI , showPI , unPN @@ -77,29 +75,6 @@ instI :: I -> Bool instI (I _ (Inst _)) = True instI _ = False --- | Is the package in the primary group of packages. This is used to --- determine (1) if we should try to establish stanza preferences --- for this goal, and (2) whether or not a user specified @--constraint@ --- should apply to this dependency (grep 'primaryPP' to see the --- use sites). In particular this does not include packages pulled in --- as setup deps. --- -primaryPP :: PackagePath -> Bool -primaryPP (PackagePath _ns q) = go q - where - go QualToplevel = True - go (QualBase _) = True - go (QualSetup _) = False - go (QualExe _ _) = False - --- | Is the package a dependency of a setup script. This is used to --- establish whether or not certain constraints should apply to this --- dependency (grep 'setupPP' to see the use sites). --- -setupPP :: PackagePath -> Bool -setupPP (PackagePath _ns (QualSetup _)) = True -setupPP (PackagePath _ns _) = False - -- | Qualify a target package with its own name so that its dependencies are not -- required to be consistent with other targets. makeIndependent :: PN -> QPN diff --git a/cabal-install-solver/src/Distribution/Solver/Modular/Preference.hs b/cabal-install-solver/src/Distribution/Solver/Modular/Preference.hs index 9e0d5fb4d22..61713c305c0 100644 --- a/cabal-install-solver/src/Distribution/Solver/Modular/Preference.hs +++ b/cabal-install-solver/src/Distribution/Solver/Modular/Preference.hs @@ -43,6 +43,7 @@ import Distribution.Solver.Modular.Tree import Distribution.Solver.Modular.Version import qualified Distribution.Solver.Modular.ConflictSet as CS import qualified Distribution.Solver.Modular.WeightedPSQ as W +import Distribution.Solver.Types.ComponentDeps (Component(..)) -- | Update the weights of children under 'PChoice' nodes. 'addWeights' takes a -- list of weight-calculating functions in order to avoid sorting the package @@ -358,6 +359,7 @@ onlyConstrained p = go go x = x + -- | Sort all goals using the provided function. sortGoals :: (Variable QPN -> Variable QPN -> Ordering) -> EndoTreeTrav d c sortGoals variableOrder = go @@ -420,8 +422,9 @@ deferSetupExeChoices = go go x = x noSetupOrExe :: Goal QPN -> Bool - noSetupOrExe (Goal (P (Q (PackagePath _ns (QualSetup _)) _)) _) = False - noSetupOrExe (Goal (P (Q (PackagePath _ns (QualExe _ _)) _)) _) = False + -- TODO: MP defer all component goals? + noSetupOrExe (Goal (P (Q (PackagePath (IndependentComponent _ ComponentSetup) _) _)) _) = False + noSetupOrExe (Goal (P (Q (PackagePath (IndependentBuildTool {}) _) _)) _) = False noSetupOrExe _ = True -- | Transformation that tries to avoid making weak flag choices early. diff --git a/cabal-install-solver/src/Distribution/Solver/Modular/PrivateScopeClosure.hs b/cabal-install-solver/src/Distribution/Solver/Modular/PrivateScopeClosure.hs new file mode 100644 index 00000000000..513e9aa1d77 --- /dev/null +++ b/cabal-install-solver/src/Distribution/Solver/Modular/PrivateScopeClosure.hs @@ -0,0 +1,204 @@ +{-# LANGUAGE BangPatterns #-} +{-# LANGUAGE LambdaCase #-} +{-# LANGUAGE TupleSections #-} +{-# LANGUAGE ViewPatterns #-} +module Distribution.Solver.Modular.PrivateScopeClosure where + +import Data.Maybe +import qualified Data.Set as S +import Prelude hiding (cycle) +import qualified Data.Map as M + +import Distribution.Solver.Modular.Dependency +import Distribution.Solver.Modular.Tree +import qualified Distribution.Solver.Modular.ConflictSet as CS +import Distribution.Solver.Types.PackagePath + +-- | Given the reverse dependency map from a node in the tree, check if the +-- solution has any bad closures. If it does, return the conflict set containing +-- the variables violating private deps closures. +-- +-- INVARIANT: The RevDepMap forms an acyclic graph (guaranteed by this check running after 'findCycles') +findBadPrivClosures :: QPN + -- ^ Newly added package that I need to check if violates property + -> RevDepMap + -> Maybe (ConflictSet, FailReason) +{- +Note [The Private Scope Closure Property Check] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +In practice, for every package that is added to the solution (the 'QPN'), we ask: +Does choosing this package violate the closure property? +By case analysis: + + (a) If the package X introduced is in a private scope S, then S may now + violate the closure property. To determine so, + * We take the list of packages in that same private scope S[1] (the + so-called "roots" of the check) + + * And compute, for each root, the up-to-private reverse-dependency + closure[2] of that package X qualified with QualTopLevel instead of the + private scope[3]. + + * If we were able to reach the private scope S from the "special closure" of the + top-level-qualified roots, the closure property is violated! + + (b) If the package X introduced is NOT in a private scope, we need to + determine all packages Ys in private scopes PSs that depend on this package X. + * We do so by traversing upwards from X, ie computing the up-to-private + reverse-dependency closure[2] of X. + + * For every private scope PS reached from traversing upwards from X + (possibleBadPrivateScopes), we get the list of packages in that private + scope PS (see [1] again), the "roots" of this branch of the check. + + * For every package (aka root) in that private scope, we traverse upwards + from the top-level-qualified root[3] until we find another private scope + or until we find the "original" package X from which we originally + computed the reachable roots. + + This is similar to up-to-private reverse-dependency closure[2] of the + root but we also stop traversing upwards if we find the package X. + + * If the package X is reachable from any of the private scopes' roots + then the property is violated. That is, if we can reach PS from the + (non-private) X, and one of the roots of PS can reach X too, then X sits + unqualified between two packages in the private scope (violating the + closure property) + +Additionally, when the private closure property is violated for some private +qualifier Q, we compute the packages missing from the private scope for it +to be valid (see 'computeBadPkgs'). + +[1] We associate private scopes to the set of packages contained in it in a +cache in the 'RevDepMap' (the 'privScopes' field). We insert into this +mapping around the same time a package is introduced in the reverse +dependency map, if the package has a private scope. + +This cache is needed for the 'findBadPrivClosures' check to be fast, because +we always need to find the set of packages in a given private scope to perform the check. + +[2] The up-to-private reverse-dependency closure of X is the +reverse-dependency closure of X, constructed by traversing upwards the +reverse dependency map, with the twist of stopping at any +privately-qualified reverse dependency. + +The function which computes this 'upwardsClosure' local to 'findBadPrivClosures'. +When the first argument is 'True', we additionally stop when the package X is reached. + +We use this "special closure" because dependencies introduced by packages in +a private scope can only violate the property of that scope (it is +impossible for them to violate the property of scopes further upward) + +[3] When we traverse upwards from a privately-qualified root, we want to +first unqualify the root and search the unqualified space. The local function +'findRevDepsTopLevel' explains in more detail with an example. + +-} +findBadPrivClosures pkg rdm = do + -- Maybe a bad scope and the reachable-from-roots map + let badScopeAndPaths = + case pkg of + Q (PackagePath _ ql@QualAlias{}) _ -> do + -- (a) case + let + roots = pkgsInPrivScope ql + reachableTopLevel = upwardsClosure False (concatMap findRevDepsTopLevel roots) + isViolated = + -- From the top level roots there can be no package in the same private scope reachable + any ((== ql) . getQual) (M.keys reachableTopLevel) + in + if isViolated then Just (ql, reachableTopLevel) else Nothing + + Q (PackagePath _ _) _ -> do + -- (b) case + let + upClosureFromPkg = upwardsClosure False [pkg] + roots = + -- Filter out from the scope packages which were reached from `pkg`: + S.filter (not . (`M.member` upClosureFromPkg)) $ + M.foldrWithKey (\p _ acc -> + if hasPrivateQual p -- privately-qualified package reached from `pkg` + then (pkgsInPrivScope (getQual p)) <> acc + else acc) S.empty upClosureFromPkg + reachableTopLevel = + S.map (\x -> (getQual x, upwardsClosure True $ findRevDepsTopLevel x)) roots + invalidScopes = + -- For any of the qualifiers, if the package is reachable from + -- the roots the prv scope of that root is bad + S.filter (any (== pkg) . M.keys . snd) reachableTopLevel + in + case S.toList invalidScopes of + -- We only report one bad scope. Eventually we could report more. + (ql,rbl):_ -> Just (ql, M.unionWith (<>) rbl upClosureFromPkg {- report with the remaining half of the closure too -}) + [] -> Nothing + + + (badScope, paths) <- badScopeAndPaths + -- All packages in paths from roots to terminal nodes in the same private scope + let badPkgs = concat . M.elems . M.filterWithKey (\k _ -> badScope == getQual k) $ paths + return (CS.fromList $ map P badPkgs, InvalidPrivateScope badScope) + + + where + + pkgsInPrivScope :: Qualifier -> S.Set QPN + pkgsInPrivScope ql' = fromMaybe (error "all private scopes should be cached") $ M.lookup ql' (privScopes rdm) + + -- Find the reverse dependencies of this QPN, but in the top-level scope. + -- + -- Recall that the private closure property may only be violated by pkgA + -- depending privately on pkgB and pkgD, but not on pkgC, when + -- pkgB --top-level-depends-> pkgC + -- pkgC --top-level-depends-> pkgD + -- + -- In the reverse dependency map we'd have + -- pkgD(private) --rd-> pkgA(top) + -- pkgB(private) --rd-> pkgA(top) + -- pkgC(top) --rd-> pkgB(private) + -- pkgD(top) --rd-> pkgC(top) + -- + -- So, for each pkg with a private scope (like pkgD or pkgB), we look for + -- the top-level equivalent of that package (this function), and will + -- traverse up until we find (or not) that there is a reverse dep on a + -- package in the same private scope as the root from which we started. + findRevDepsTopLevel (Q (PackagePath namespace _) pn) = + case (Q (PackagePath namespace QualToplevel) pn) `M.lookup` revDeps rdm of + Nothing -> + -- If this package wasn't at the top-level means there is no + -- top-level package publicly depending on it. Nothing to worry about then. + [] + Just rdeps -> map snd rdeps + + getQual (Q (PackagePath _ ql) _) = ql + + hasPrivateQual :: QPN -> Bool + hasPrivateQual = \case + Q (PackagePath _ QualAlias{}) _ -> True + _ -> False + + upwardsClosure :: Bool {- Whether to stop traversing when `pkg` is found -} + -> [QPN] {- ps roots in qualtoplevel -} + -> M.Map QPN [QPN] {- all the things you can reach (stopping at pkg and on any private thing); only lookup privately qualified packages!-} + upwardsClosure stopAtPkg = fst . foldl go mempty + where + go :: (M.Map QPN [QPN] {- de-duplicate things we've seen -}, [QPN]) + -> QPN -> (M.Map QPN [QPN], [QPN]) + go (s,path) x + | x `M.member` s + = (s, path) + | hasPrivateQual x + = (M.insert x path s, path) + | stopAtPkg && x == pkg + = (M.insert x (dontLook x) s, path) + | otherwise + = let nbs = neighbors x + in foldl go (M.insert x (dontLook x) s, if null nbs then path else x:path) nbs + -- \^ We don't add x to the path if this is a terminal node. + + dontLook x = error $ "We should only lookup privately-qualified pkgs, but instead " ++ show x ++ " was looked up -- it is only inserted in the map for de-duplication purposes." + + neighbors :: QPN -> [QPN] + neighbors x = case x `M.lookup` revDeps rdm of + Nothing -> error $ "cannot find node: " ++ show x + Just xs -> map snd xs + diff --git a/cabal-install-solver/src/Distribution/Solver/Modular/Solver.hs b/cabal-install-solver/src/Distribution/Solver/Modular/Solver.hs index 39bd7bf4690..a1e57408670 100644 --- a/cabal-install-solver/src/Distribution/Solver/Modular/Solver.hs +++ b/cabal-install-solver/src/Distribution/Solver/Modular/Solver.hs @@ -36,6 +36,8 @@ import Distribution.Solver.Modular.Log import Distribution.Solver.Modular.Message import Distribution.Solver.Modular.Package import qualified Distribution.Solver.Modular.Preference as P +import Distribution.Solver.Modular.ValidateDependencies +import Distribution.Solver.Modular.PrivateScopeClosure import Distribution.Solver.Modular.Validate import Distribution.Solver.Modular.Linking import Distribution.Solver.Modular.PSQ (PSQ) @@ -98,8 +100,11 @@ solve :: SolverConfig -- ^ solver parameters -> RetryLog Message SolverFailure (Assignment, RevDepMap) solve sc cinfo idx pkgConfigDB userPrefs userConstraints userGoals = explorePhase . - traceTree "cycles.json" id . - detectCycles . + traceTree "invalid-dep-graph.json" id . + detectInvalidDepGraphPhase + [ findCycles -- this first + , findBadPrivClosures -- then this + ] . traceTree "heuristics.json" id . trav ( heuristicsPhase . @@ -118,7 +123,6 @@ solve sc cinfo idx pkgConfigDB userPrefs userConstraints userGoals = (fineGrainedConflicts sc) (countConflicts sc) idx - detectCycles = detectCyclesPhase heuristicsPhase = let sortGoals = case goalOrder sc of diff --git a/cabal-install-solver/src/Distribution/Solver/Modular/Tree.hs b/cabal-install-solver/src/Distribution/Solver/Modular/Tree.hs index 10d372525b1..0de377f5876 100644 --- a/cabal-install-solver/src/Distribution/Solver/Modular/Tree.hs +++ b/cabal-install-solver/src/Distribution/Solver/Modular/Tree.hs @@ -127,6 +127,7 @@ data FailReason = UnsupportedExtension Extension | MultipleInstances | DependenciesNotLinked String | CyclicDependencies + | InvalidPrivateScope Qualifier | UnsupportedSpecVer Ver deriving (Eq, Show) diff --git a/cabal-install-solver/src/Distribution/Solver/Modular/Validate.hs b/cabal-install-solver/src/Distribution/Solver/Modular/Validate.hs index cbe6282b6d0..7b9d8a8bf3f 100644 --- a/cabal-install-solver/src/Distribution/Solver/Modular/Validate.hs +++ b/cabal-install-solver/src/Distribution/Solver/Modular/Validate.hs @@ -158,7 +158,7 @@ validate = go where go :: Tree d c -> Validate (Tree d c) - go (PChoice qpn rdm gr ts) = PChoice qpn rdm gr <$> W.traverseWithKey (\k -> goP qpn k . go) ts + go (PChoice qpn rdm gr ts) = PChoice qpn rdm gr <$> W.traverseWithKey (\k -> goP rdm qpn k . go) ts go (FChoice qfn rdm gr b m d ts) = do -- Flag choices may occur repeatedly (because they can introduce new constraints @@ -190,8 +190,8 @@ validate = go go (Fail c fr ) = pure (Fail c fr) -- What to do for package nodes ... - goP :: QPN -> POption -> Validate (Tree d c) -> Validate (Tree d c) - goP qpn@(Q _pp pn) (POption i _) r = do + goP :: RevDepMap -> QPN -> POption -> Validate (Tree d c) -> Validate (Tree d c) + goP rdm qpn@(Q _pp pn) (POption i _) r = do PA ppa pfa psa <- asks pa -- obtain current preassignment extSupported <- asks supportedExt -- obtain the supported extensions langSupported <- asks supportedLang -- obtain the supported languages @@ -204,7 +204,7 @@ validate = go -- obtain dependencies and index-dictated exclusions introduced by the choice let (PInfo deps comps _ mfr) = idx ! pn ! i -- qualify the deps in the current scope - let qdeps = qualifyDeps qo qpn deps + let qdeps = qualifyDeps qo rdm qpn deps -- the new active constraints are given by the instance we have chosen, -- plus the dependency information we have for that instance let newactives = extractAllDeps pfa psa qdeps @@ -400,7 +400,7 @@ extend extSupported langSupported pkgPresent newactives ppa = foldM extendSingle extendSingle a (LDep dr (Pkg pn vr)) = if pkgPresent pn vr then Right a else Left (dependencyReasonToConflictSet dr, MissingPkgconfigPackage pn vr) - extendSingle a (LDep dr (Dep dep@(PkgComponent qpn _) ci)) = + extendSingle a (LDep dr (Dep dep@(PkgComponent qpn _) _is_private ci)) = let mergedDep = M.findWithDefault (MergedDepConstrained []) qpn a in case (\ x -> M.insert qpn x a) <$> merge mergedDep (PkgDep dr dep ci) of Left (c, (d, d')) -> Left (c, ConflictingConstraints d d') @@ -530,7 +530,7 @@ extendRequiredComponents eqpn available = foldM extendSingle extendSingle :: Map QPN ComponentDependencyReasons -> LDep QPN -> Either Conflict (Map QPN ComponentDependencyReasons) - extendSingle required (LDep dr (Dep (PkgComponent qpn comp) _)) = + extendSingle required (LDep dr (Dep (PkgComponent qpn comp) _is_private _)) = let compDeps = M.findWithDefault M.empty qpn required success = Right $ M.insertWith M.union qpn (M.insert comp dr compDeps) required in -- Only check for the existence of the component if its package has diff --git a/cabal-install-solver/src/Distribution/Solver/Modular/ValidateDependencies.hs b/cabal-install-solver/src/Distribution/Solver/Modular/ValidateDependencies.hs new file mode 100644 index 00000000000..37edcfefc81 --- /dev/null +++ b/cabal-install-solver/src/Distribution/Solver/Modular/ValidateDependencies.hs @@ -0,0 +1,66 @@ +{-# LANGUAGE TypeFamilies #-} +module Distribution.Solver.Modular.ValidateDependencies ( + detectInvalidDepGraphPhase + , RevDepMapNode(..) + , revDepMapToGraph + ) where + +import Prelude hiding (cycle) +import qualified Data.Map as M + +import qualified Distribution.Compat.Graph as G +import Distribution.Simple.Utils (ordNub) +import Distribution.Solver.Modular.Dependency +import Distribution.Solver.Modular.Flag +import Distribution.Solver.Modular.Tree +import Distribution.Solver.Types.ComponentDeps (Component) +import Distribution.Solver.Types.PackagePath + +-- | Run checks on the dependencies at every node, such as the cycle check +-- 'findCycles' and the private scope closure check 'findBadPrivClosures' +detectInvalidDepGraphPhase :: [QPN -> RevDepMap -> Maybe (ConflictSet, FailReason)] + -- ^ The list of checks to run at every node, run left to right. + -> Tree d c -> Tree d c +detectInvalidDepGraphPhase checks = go + where + -- Only check children of choice nodes. + go :: Tree d c -> Tree d c + go (PChoice qpn rdm gr cs) = + PChoice qpn rdm gr $ fmap (checkChild qpn) (fmap go cs) + go (FChoice qfn@(FN qpn _) rdm gr w m d cs) = + FChoice qfn rdm gr w m d $ fmap (checkChild qpn) (fmap go cs) + go (SChoice qsn@(SN qpn _) rdm gr w cs) = + SChoice qsn rdm gr w $ fmap (checkChild qpn) (fmap go cs) + go (GoalChoice rdm cs) = GoalChoice rdm (fmap go cs) + go x@(Fail _ _) = x + go x@(Done _ _) = x + + checkChild :: QPN -> Tree d c -> Tree d c + checkChild qpn x@(PChoice _ rdm _ _) = failIfBad qpn rdm x + checkChild qpn x@(FChoice _ rdm _ _ _ _ _) = failIfBad qpn rdm x + checkChild qpn x@(SChoice _ rdm _ _ _) = failIfBad qpn rdm x + checkChild qpn x@(GoalChoice rdm _) = failIfBad qpn rdm x + checkChild _ x@(Fail _ _) = x + checkChild qpn x@(Done rdm _) = failIfBad qpn rdm x + + failIfBad :: QPN -> RevDepMap -> Tree d c -> Tree d c + failIfBad qpn rdm x = maybe x (uncurry Fail) (goCheck checks) where + goCheck :: [QPN -> RevDepMap -> Maybe (ConflictSet, FailReason)] -> Maybe (ConflictSet, FailReason) + goCheck [] = Nothing -- no more check, succeed + goCheck (c:cs) = + case c qpn rdm of + Nothing -> + -- success for this check, but we need to run all checks + goCheck cs + Just f -> Just f + +data RevDepMapNode = RevDepMapNode QPN [(Component, QPN)] + +instance G.IsNode RevDepMapNode where + type Key RevDepMapNode = QPN + nodeKey (RevDepMapNode qpn _) = qpn + nodeNeighbors (RevDepMapNode _ ns) = ordNub $ map snd ns + +revDepMapToGraph :: RevDepMap -> G.Graph RevDepMapNode +revDepMapToGraph rdm = G.fromDistinctList + [RevDepMapNode qpn ns | (qpn, ns) <- M.toList $ revDeps rdm] diff --git a/cabal-install-solver/src/Distribution/Solver/Types/ComponentDeps.hs b/cabal-install-solver/src/Distribution/Solver/Types/ComponentDeps.hs index 8926521673b..aad27391de7 100644 --- a/cabal-install-solver/src/Distribution/Solver/Types/ComponentDeps.hs +++ b/cabal-install-solver/src/Distribution/Solver/Types/ComponentDeps.hs @@ -83,7 +83,7 @@ type ComponentDep a = (Component, a) -- | Fine-grained dependencies for a package. -- --- Typically used as @ComponentDeps [Dependency]@, to represent the list of +-- Typically used as @ComponentDeps Dependencies@, to represent the list of -- dependencies for each named component within a package. -- newtype ComponentDeps a = ComponentDeps { unComponentDeps :: Map Component a } diff --git a/cabal-install-solver/src/Distribution/Solver/Types/InstSolverPackage.hs b/cabal-install-solver/src/Distribution/Solver/Types/InstSolverPackage.hs index 871a0dd15a9..8476e757f90 100644 --- a/cabal-install-solver/src/Distribution/Solver/Types/InstSolverPackage.hs +++ b/cabal-install-solver/src/Distribution/Solver/Types/InstSolverPackage.hs @@ -6,7 +6,7 @@ module Distribution.Solver.Types.InstSolverPackage import Distribution.Solver.Compat.Prelude import Prelude () -import Distribution.Package ( Package(..), HasMungedPackageId(..), HasUnitId(..) ) +import Distribution.Package ( Package(..), HasMungedPackageId(..), HasUnitId(..), IsPrivate ) import Distribution.Solver.Types.ComponentDeps ( ComponentDeps ) import Distribution.Solver.Types.SolverId import Distribution.Types.MungedPackageId @@ -18,7 +18,7 @@ import Distribution.InstalledPackageInfo (InstalledPackageInfo) -- specified by the dependency solver. data InstSolverPackage = InstSolverPackage { instSolverPkgIPI :: InstalledPackageInfo, - instSolverPkgLibDeps :: ComponentDeps [SolverId], + instSolverPkgLibDeps :: ComponentDeps [(SolverId, IsPrivate)], instSolverPkgExeDeps :: ComponentDeps [SolverId] } deriving (Eq, Show, Generic) diff --git a/cabal-install-solver/src/Distribution/Solver/Types/PackageConstraint.hs b/cabal-install-solver/src/Distribution/Solver/Types/PackageConstraint.hs index fbe56380e81..b67eb771984 100644 --- a/cabal-install-solver/src/Distribution/Solver/Types/PackageConstraint.hs +++ b/cabal-install-solver/src/Distribution/Solver/Types/PackageConstraint.hs @@ -1,4 +1,5 @@ {-# LANGUAGE DeriveGeneric #-} +{-# LANGUAGE TypeApplications #-} -- | Per-package constraints. Package constraints must be respected by the -- solver. Multiple constraints for each package can be given, though obviously @@ -31,6 +32,8 @@ import Distribution.Solver.Types.OptionalStanza import Distribution.Solver.Types.PackagePath import qualified Text.PrettyPrint as Disp +import Distribution.Solver.Types.ComponentDeps (Component(..)) +import Distribution.Types.Dependency -- | Determines to what packages and in what contexts a @@ -43,11 +46,10 @@ data ConstraintScope -- namespace (for --no-independent-goals) or it is an independent namespace -- with the given package name (for --independent-goals). - -- TODO: Try to generalize the ConstraintScopes once component-based - -- solving is implemented, and remove this special case for targets. = ScopeTarget PackageName -- | The package with the specified name and qualifier. - | ScopeQualified Qualifier PackageName + | ScopeQualified Namespace Qualifier PackageName + -- | The package with the specified name when it has a -- setup qualifier. | ScopeAnySetupQualifier PackageName @@ -60,24 +62,30 @@ data ConstraintScope -- the package with the specified name when that package is a -- top-level dependency in the default namespace. scopeToplevel :: PackageName -> ConstraintScope -scopeToplevel = ScopeQualified QualToplevel +scopeToplevel = ScopeQualified DefaultNamespace QualToplevel -- | Returns the package name associated with a constraint scope. scopeToPackageName :: ConstraintScope -> PackageName scopeToPackageName (ScopeTarget pn) = pn -scopeToPackageName (ScopeQualified _ pn) = pn +scopeToPackageName (ScopeQualified _ _ pn) = pn scopeToPackageName (ScopeAnySetupQualifier pn) = pn scopeToPackageName (ScopeAnyQualifier pn) = pn +-- | Whether a ConstraintScope matches a qualified package name, the crucial +-- function which determines the rules about when constraints apply. constraintScopeMatches :: ConstraintScope -> QPN -> Bool constraintScopeMatches (ScopeTarget pn) (Q (PackagePath ns q) pn') = let namespaceMatches DefaultNamespace = True namespaceMatches (Independent namespacePn) = pn == namespacePn + namespaceMatches (IndependentComponent {}) = False + namespaceMatches (IndependentBuildTool {}) = False in namespaceMatches ns && q == QualToplevel && pn == pn' -constraintScopeMatches (ScopeQualified q pn) (Q (PackagePath _ q') pn') = - q == q' && pn == pn' +constraintScopeMatches (ScopeQualified ns cq cpn) (Q (PackagePath qual_ns q) cpn') = + -- Should we check whether ns subsumes qual_ns rather than equality? + ns == qual_ns && cq == q && cpn == cpn' + constraintScopeMatches (ScopeAnySetupQualifier pn) (Q pp pn') = - let setup (PackagePath _ (QualSetup _)) = True + let setup (PackagePath (IndependentComponent _ ComponentSetup) _) = True setup _ = False in setup pp && pn == pn' constraintScopeMatches (ScopeAnyQualifier pn) (Q _ pn') = pn == pn' @@ -85,7 +93,8 @@ 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 (ScopeQualified _ (QualAlias apn alias) p) = Disp.text "private." <<>> pretty apn <<>> Disp.text "." <<>> pretty @PrivateAlias alias <<>> Disp.text ":" <<>> pretty p +dispConstraintScope (ScopeQualified ns _q pn) = dispNamespace ns <<>> pretty pn dispConstraintScope (ScopeAnySetupQualifier pn) = Disp.text "setup." <<>> pretty pn dispConstraintScope (ScopeAnyQualifier pn) = Disp.text "any." <<>> pretty pn diff --git a/cabal-install-solver/src/Distribution/Solver/Types/PackagePath.hs b/cabal-install-solver/src/Distribution/Solver/Types/PackagePath.hs index 4fc4df25f97..895ea6afba1 100644 --- a/cabal-install-solver/src/Distribution/Solver/Types/PackagePath.hs +++ b/cabal-install-solver/src/Distribution/Solver/Types/PackagePath.hs @@ -2,18 +2,19 @@ module Distribution.Solver.Types.PackagePath ( PackagePath(..) , Namespace(..) , Qualifier(..) - , dispQualifier , Qualified(..) , QPN + , dispNamespace , dispQPN , showQPN ) where import Distribution.Solver.Compat.Prelude import Prelude () -import Distribution.Package (PackageName) -import Distribution.Pretty (pretty, flatStyle) +import Distribution.Package (PackageName, PrivateAlias) +import Distribution.Pretty (Pretty, pretty, flatStyle) import qualified Text.PrettyPrint as Disp +import Distribution.Solver.Types.ComponentDeps -- | A package path consists of a namespace and a package path inside that -- namespace. @@ -25,11 +26,18 @@ data PackagePath = PackagePath Namespace Qualifier -- Package choices in different namespaces are considered completely independent -- by the solver. data Namespace = - -- | The default namespace + -- | A goal which is solved DefaultNamespace - -- | A namespace for a specific build target + -- | A goal which is solved per-package + -- `--independent-goals` | Independent PackageName + + + | IndependentComponent PackageName Component + -- Build-tools are solved per-package so there are consistent build-tools across + -- components. + | IndependentBuildTool PackageName PackageName deriving (Eq, Ord, Show) -- | Pretty-prints a namespace. The result is either empty or @@ -37,6 +45,9 @@ data Namespace = dispNamespace :: Namespace -> Disp.Doc dispNamespace DefaultNamespace = Disp.empty dispNamespace (Independent i) = pretty i <<>> Disp.text "." +dispNamespace (IndependentBuildTool pn btp) = pretty pn <<>> Disp.text ":" <<>> + pretty btp <<>> Disp.text ":exe." +dispNamespace (IndependentComponent pn c) = pretty pn <<>> Disp.text ":" <<>> pretty c <<>> Disp.text "." -- | Qualifier of a package within a namespace (see 'PackagePath') data Qualifier = @@ -48,26 +59,9 @@ data Qualifier = -- This makes it possible to have base shims. | QualBase PackageName - -- | Setup dependency - -- - -- By rights setup dependencies ought to be nestable; after all, the setup - -- dependencies of a package might themselves have setup dependencies, which - -- are independent from everything else. However, this very quickly leads to - -- infinite search trees in the solver. Therefore we limit ourselves to - -- a single qualifier (within a given namespace). - | QualSetup PackageName - - -- | If we depend on an executable from a package (via - -- @build-tools@), we should solve for the dependencies of that - -- package separately (since we're not going to actually try to - -- link it.) We qualify for EACH package separately; e.g., - -- @'Exe' pn1 pn2@ qualifies the @build-tools@ dependency on - -- @pn2@ from package @pn1@. (If we tracked only @pn1@, that - -- would require a consistent dependency resolution for all - -- of the depended upon executables from a package; if we - -- tracked only @pn2@, that would require us to pick only one - -- version of an executable over the entire install plan.) - | QualExe PackageName PackageName + -- A goal which is solved per-component + | QualAlias PackageName PrivateAlias + deriving (Eq, Ord, Show) -- | Pretty-prints a qualifier. The result is either empty or @@ -80,10 +74,11 @@ data Qualifier = -- 'Base' qualifier, will always be @base@). dispQualifier :: Qualifier -> Disp.Doc dispQualifier QualToplevel = Disp.empty -dispQualifier (QualSetup pn) = pretty pn <<>> Disp.text ":setup." -dispQualifier (QualExe pn pn2) = pretty pn <<>> Disp.text ":" <<>> - pretty pn2 <<>> Disp.text ":exe." -dispQualifier (QualBase pn) = pretty pn <<>> Disp.text "." +dispQualifier (QualBase pn) = pretty pn <<>> Disp.text ".bb." +dispQualifier (QualAlias pn alias) = pretty pn <<>> Disp.text ":" <<>> pretty alias <<>> Disp.text "." + +instance Pretty Qualifier where + pretty = dispQualifier -- | A qualified entity. Pairs a package path with the entity. data Qualified a = Q PackagePath a diff --git a/cabal-install-solver/src/Distribution/Solver/Types/ResolverPackage.hs b/cabal-install-solver/src/Distribution/Solver/Types/ResolverPackage.hs index 840e58aff94..e079ef15980 100644 --- a/cabal-install-solver/src/Distribution/Solver/Types/ResolverPackage.hs +++ b/cabal-install-solver/src/Distribution/Solver/Types/ResolverPackage.hs @@ -17,6 +17,7 @@ import qualified Distribution.Solver.Types.ComponentDeps as CD import Distribution.Compat.Graph (IsNode(..)) import Distribution.Package (Package(..), HasUnitId(..)) import Distribution.Simple.Utils (ordNub) +import Distribution.Types.Dependency (IsPrivate) -- | The dependency resolver picks either pre-existing installed packages -- or it picks source packages along with package configuration. @@ -34,7 +35,7 @@ instance Package (ResolverPackage loc) where packageId (PreExisting ipkg) = packageId ipkg packageId (Configured spkg) = packageId spkg -resolverPackageLibDeps :: ResolverPackage loc -> CD.ComponentDeps [SolverId] +resolverPackageLibDeps :: ResolverPackage loc -> CD.ComponentDeps [(SolverId, IsPrivate)] resolverPackageLibDeps (PreExisting ipkg) = instSolverPkgLibDeps ipkg resolverPackageLibDeps (Configured spkg) = solverPkgLibDeps spkg @@ -48,5 +49,5 @@ instance IsNode (ResolverPackage loc) where nodeKey (Configured spkg) = PlannedId (packageId spkg) -- Use dependencies for ALL components nodeNeighbors pkg = - ordNub $ CD.flatDeps (resolverPackageLibDeps pkg) ++ + ordNub $ (map fst (CD.flatDeps (resolverPackageLibDeps pkg))) ++ CD.flatDeps (resolverPackageExeDeps pkg) diff --git a/cabal-install-solver/src/Distribution/Solver/Types/SolverId.hs b/cabal-install-solver/src/Distribution/Solver/Types/SolverId.hs index d32ccc17e74..115207272ca 100644 --- a/cabal-install-solver/src/Distribution/Solver/Types/SolverId.hs +++ b/cabal-install-solver/src/Distribution/Solver/Types/SolverId.hs @@ -23,7 +23,7 @@ instance Binary SolverId instance Structured SolverId instance Show SolverId where - show = show . solverSrcId + show = show . solverSrcId instance Package SolverId where packageId = solverSrcId diff --git a/cabal-install-solver/src/Distribution/Solver/Types/SolverPackage.hs b/cabal-install-solver/src/Distribution/Solver/Types/SolverPackage.hs index 186f140aefe..18bf3bcc9fa 100644 --- a/cabal-install-solver/src/Distribution/Solver/Types/SolverPackage.hs +++ b/cabal-install-solver/src/Distribution/Solver/Types/SolverPackage.hs @@ -12,6 +12,7 @@ import Distribution.Solver.Types.ComponentDeps ( ComponentDeps ) import Distribution.Solver.Types.OptionalStanza import Distribution.Solver.Types.SolverId import Distribution.Solver.Types.SourcePackage +import Distribution.Types.Dependency (IsPrivate) -- | A 'SolverPackage' is a package specified by the dependency solver. -- It will get elaborated into a 'ConfiguredPackage' or even an @@ -24,7 +25,7 @@ data SolverPackage loc = SolverPackage { solverPkgSource :: SourcePackage loc, solverPkgFlags :: FlagAssignment, solverPkgStanzas :: OptionalStanzaSet, - solverPkgLibDeps :: ComponentDeps [SolverId], + solverPkgLibDeps :: ComponentDeps [(SolverId, IsPrivate)], solverPkgExeDeps :: ComponentDeps [SolverId] } deriving (Eq, Show, Generic) diff --git a/cabal-install/src/Distribution/Client/CmdOutdated.hs b/cabal-install/src/Distribution/Client/CmdOutdated.hs index ed40a1a85e6..2493f8fe14e 100644 --- a/cabal-install/src/Distribution/Client/CmdOutdated.hs +++ b/cabal-install/src/Distribution/Client/CmdOutdated.hs @@ -443,7 +443,7 @@ depsFromPkgDesc verbosity comp platform = do finalizePD mempty (ComponentRequestedSpec True True) - (const True) + (\_ _ -> True) platform cinfo [] @@ -457,7 +457,11 @@ depsFromPkgDesc verbosity comp platform = do "Reading the list of dependencies from the package description" return $ map toPVC bd where - toPVC (Dependency pn vr _) = PackageVersionConstraint pn vr + -- It doesn't seem critical that we report the scope in which the package + -- is outdated, because, in order for that report to be consistent with the + -- rest of Cabal, we must first consider how cabal outdated and cabal + -- freeze work wrt private dependencies (TODO). + toPVC (_alias, (Dependency pn vr _)) = PackageVersionConstraint pn vr -- | Various knobs for customising the behaviour of 'listOutdated'. data ListOutdatedSettings = ListOutdatedSettings diff --git a/cabal-install/src/Distribution/Client/CmdRepl.hs b/cabal-install/src/Distribution/Client/CmdRepl.hs index 39468a8e545..f5c012da2cf 100644 --- a/cabal-install/src/Distribution/Client/CmdRepl.hs +++ b/cabal-install/src/Distribution/Client/CmdRepl.hs @@ -132,7 +132,8 @@ import Distribution.Types.CondTree ( CondTree (..) ) import Distribution.Types.Dependency - ( Dependency (..) + ( Dependencies (..) + , Dependency (..) , mainLibSet ) import Distribution.Types.Library @@ -300,7 +301,7 @@ replAction flags@NixStyleFlags{extraFlags = r@ReplFlags{..}, ..} targetStrings g sourcePackage = fakeProjectSourcePackage projectRoot & lSrcpkgDescription . L.condLibrary - .~ Just (CondNode library [baseDep] []) + .~ Just (CondNode library (Dependencies [baseDep] []) []) library = emptyLibrary{libBuildInfo = lBuildInfo} lBuildInfo = emptyBuildInfo diff --git a/cabal-install/src/Distribution/Client/Configure.hs b/cabal-install/src/Distribution/Client/Configure.hs index fc7ea49fe31..08ba1fbba82 100644 --- a/cabal-install/src/Distribution/Client/Configure.hs +++ b/cabal-install/src/Distribution/Client/Configure.hs @@ -534,7 +534,7 @@ configurePackage CD.nonSetupDeps deps ] , configDependencies = - [ GivenComponent (packageName srcid) cname uid + [ GivenComponent (packageName srcid) cname uid PkgDesc.Public | ConfiguredId srcid (Just (PkgDesc.CLibName cname)) uid <- CD.nonSetupDeps deps ] @@ -555,7 +555,7 @@ configurePackage pkg = case finalizePD flags (enableStanzas stanzas) - (const True) + (\_ _ -> True) platform comp [] diff --git a/cabal-install/src/Distribution/Client/Dependency.hs b/cabal-install/src/Distribution/Client/Dependency.hs index 66a0a103c23..c9317f83a8e 100644 --- a/cabal-install/src/Distribution/Client/Dependency.hs +++ b/cabal-install/src/Distribution/Client/Dependency.hs @@ -1,3 +1,5 @@ +{-# LANGUAGE TupleSections #-} + ----------------------------------------------------------------------------- ----------------------------------------------------------------------------- @@ -960,10 +962,10 @@ data PackageProblem = DuplicateFlag PD.FlagName | MissingFlag PD.FlagName | ExtraFlag PD.FlagName - | DuplicateDeps [PackageId] - | MissingDep Dependency - | ExtraDep PackageId - | InvalidDep Dependency PackageId + | DuplicateDeps [(PackageId, IsPrivate)] + | MissingDep Dependency (IsPrivate) + | ExtraDep PackageId (IsPrivate) + | InvalidDep Dependency PackageId (IsPrivate) showPackageProblem :: PackageProblem -> String showPackageProblem (DuplicateFlag flag) = @@ -974,20 +976,23 @@ showPackageProblem (ExtraFlag flag) = "extra flag given that is not used by the package: " ++ PD.unFlagName flag showPackageProblem (DuplicateDeps pkgids) = "duplicate packages specified as selected dependencies: " - ++ intercalate ", " (map prettyShow pkgids) -showPackageProblem (MissingDep dep) = + ++ intercalate ", " (map (\(x, y) -> foldIsPrivate "" ((<> ".") . prettyShow) y <> prettyShow x) pkgids) +showPackageProblem (MissingDep dep palias) = "the package has a dependency " + ++ foldIsPrivate "" ((<> ".") . prettyShow) palias ++ prettyShow dep ++ " but no package has been selected to satisfy it." -showPackageProblem (ExtraDep pkgid) = +showPackageProblem (ExtraDep pkgid palias) = "the package configuration specifies " + ++ foldIsPrivate "" ((<> ".") . prettyShow) palias ++ prettyShow pkgid ++ " but (with the given flag assignment) the package does not actually" ++ " depend on any version of that package." -showPackageProblem (InvalidDep dep pkgid) = +showPackageProblem (InvalidDep dep pkgid palias) = "the package depends on " ++ prettyShow dep ++ " but the configuration specifies " + ++ foldIsPrivate "" ((<> ".") . prettyShow) palias ++ prettyShow pkgid ++ " which does not satisfy the dependency." @@ -1012,13 +1017,18 @@ configuredPackageProblems | pkgs <- CD.nonSetupDeps ( fmap - (duplicatesBy (comparing packageName)) + (duplicatesBy (comparing (\(x, y) -> (packageName x, y)))) specifiedDeps1 ) ] - ++ [MissingDep dep | OnlyInLeft dep <- mergedDeps] - ++ [ExtraDep pkgid | OnlyInRight pkgid <- mergedDeps] - ++ [ InvalidDep dep pkgid | InBoth dep pkgid <- mergedDeps, not (packageSatisfiesDependency pkgid dep) + ++ [MissingDep dep alias | OnlyInLeft (dep, alias) <- mergedDeps] + ++ [ExtraDep pkgid palias | OnlyInRight (pkgid, palias) <- mergedDeps] + ++ [ InvalidDep dep pkgid palias + | InBoth (dep, palias) (pkgid, _palias) <- mergedDeps + , assert + (palias == _palias) + not + (packageSatisfiesDependency pkgid dep) ] where -- TODO: sanity tests on executable deps @@ -1026,10 +1036,10 @@ configuredPackageProblems thisPkgName :: PackageName thisPkgName = packageName (srcpkgDescription pkg) - specifiedDeps1 :: ComponentDeps [PackageId] - specifiedDeps1 = fmap (map solverSrcId) specifiedDeps0 + specifiedDeps1 :: ComponentDeps [(PackageId, IsPrivate)] + specifiedDeps1 = fmap (map (first solverSrcId)) specifiedDeps0 - specifiedDeps :: [PackageId] + specifiedDeps :: [(PackageId, IsPrivate)] specifiedDeps = CD.flatDeps specifiedDeps1 mergedFlags :: [MergeResult PD.FlagName PD.FlagName] @@ -1047,19 +1057,19 @@ configuredPackageProblems dependencyName (Dependency name _ _) = name - mergedDeps :: [MergeResult Dependency PackageId] + mergedDeps :: [MergeResult (Dependency, IsPrivate) (PackageId, IsPrivate)] mergedDeps = mergeDeps requiredDeps specifiedDeps mergeDeps - :: [Dependency] - -> [PackageId] - -> [MergeResult Dependency PackageId] + :: [(Dependency, IsPrivate)] + -> [(PackageId, IsPrivate)] + -> [MergeResult (Dependency, IsPrivate) (PackageId, IsPrivate)] mergeDeps required specified = let sortNubOn f = nubBy ((==) `on` f) . sortBy (compare `on` f) in mergeBy - (\dep pkgid -> dependencyName dep `compare` packageName pkgid) - (sortNubOn dependencyName required) - (sortNubOn packageName specified) + (\(dep, alias1) (pkgid, alias2) -> (dependencyName dep, alias1) `compare` (packageName pkgid, alias2)) + (sortNubOn (first dependencyName) required) + (sortNubOn (first packageName) specified) compSpec = enableStanzas stanzas -- TODO: It would be nicer to use ComponentDeps here so we can be more @@ -1068,13 +1078,13 @@ configuredPackageProblems -- have to allow for duplicates when we fold specifiedDeps; once we have -- proper ComponentDeps here we should get rid of the `nubOn` in -- `mergeDeps`. - requiredDeps :: [Dependency] + requiredDeps :: [(Dependency, IsPrivate)] requiredDeps = -- TODO: use something lower level than finalizePD case finalizePD specifiedFlags compSpec - (const True) + (\_ _ -> True) platform cinfo [] @@ -1088,9 +1098,11 @@ configuredPackageProblems -- See #3775 -- filter - ((/= thisPkgName) . dependencyName) - (PD.enabledBuildDepends resolvedPkg compSpec) - ++ maybe [] PD.setupDepends (PD.setupBuildInfo resolvedPkg) + ((/= thisPkgName) . dependencyName . fst) + ( map (\(x, y) -> (y, x)) $ + PD.enabledBuildDepends resolvedPkg compSpec + ) + ++ maybe [] (map (,Public) . PD.setupDepends) (PD.setupBuildInfo resolvedPkg) Left _ -> error "configuredPackageInvalidDeps internal error" diff --git a/cabal-install/src/Distribution/Client/GenBounds.hs b/cabal-install/src/Distribution/Client/GenBounds.hs index ae78b50c004..a5dfdd91f3c 100644 --- a/cabal-install/src/Distribution/Client/GenBounds.hs +++ b/cabal-install/src/Distribution/Client/GenBounds.hs @@ -39,9 +39,6 @@ import Distribution.Package , packageVersion , unPackageName ) -import Distribution.PackageDescription - ( enabledBuildDepends - ) import Distribution.PackageDescription.Configuration ( finalizePD ) @@ -67,6 +64,7 @@ import Distribution.Types.ComponentRequestedSpec ( defaultComponentRequestedSpec ) import Distribution.Types.Dependency +import Distribution.Types.PackageDescription import Distribution.Utils.Path (relativeSymbolicPath) import Distribution.Version ( LowerBound (..) @@ -138,7 +136,7 @@ genBounds verbosity packageDBs repoCtxt comp platform progdb globalFlags freezeF finalizePD mempty defaultComponentRequestedSpec - (const True) + (\_ _ -> True) platform cinfo [] @@ -147,8 +145,12 @@ genBounds verbosity packageDBs repoCtxt comp platform progdb globalFlags freezeF Left _ -> putStrLn "finalizePD failed" Right (pd, _) -> do let needBounds = - map depName $ - filter (not . hasUpperBound . depVersion) $ + -- TODO: This is not quite right for gen-bounds when private + -- dependencies are included: comparing package names is no longer + -- sufficient because some packages "duplicated" by also being + -- present within some private scope + map (depName . snd) $ + filter (not . hasUpperBound . depVersion . snd) $ enabledBuildDepends pd defaultComponentRequestedSpec pkgs <- @@ -177,10 +179,10 @@ genBounds verbosity packageDBs repoCtxt comp platform progdb globalFlags freezeF traverse_ (notice verbosity . (++ ",") . showBounds padTo) thePkgs depName :: Dependency -> String -depName (Dependency pn _ _) = unPackageName pn +depName = unPackageName . depPkgName depVersion :: Dependency -> VersionRange -depVersion (Dependency _ vr _) = vr +depVersion = depVerRange -- | The message printed when some dependencies are found to be lacking proper -- PVP-mandated bounds. diff --git a/cabal-install/src/Distribution/Client/Init/Utils.hs b/cabal-install/src/Distribution/Client/Init/Utils.hs index 12605a669a0..fd0868a3a5f 100644 --- a/cabal-install/src/Distribution/Client/Init/Utils.hs +++ b/cabal-install/src/Distribution/Client/Init/Utils.hs @@ -321,7 +321,7 @@ fixupDocFiles v pkgDesc mkStringyDep :: String -> Dependency mkStringyDep = mkPackageNameDep . mkPackageName -getBaseDep :: Interactive m => InstalledPackageIndex -> InitFlags -> m [Dependency] +getBaseDep :: Interactive m => InstalledPackageIndex -> InitFlags -> m [P.Dependency] getBaseDep pkgIx flags = retrieveDependencies silent diff --git a/cabal-install/src/Distribution/Client/Install.hs b/cabal-install/src/Distribution/Client/Install.hs index a31e4d2ce62..c5e9c28136e 100644 --- a/cabal-install/src/Distribution/Client/Install.hs +++ b/cabal-install/src/Distribution/Client/Install.hs @@ -154,6 +154,7 @@ import Distribution.Client.Utils import Distribution.Package ( HasMungedPackageId (..) , HasUnitId (..) + , IsPrivate (..) , Package (..) , PackageId , PackageIdentifier (..) @@ -1661,7 +1662,7 @@ installReadyPackage CD.nonSetupDeps deps ] , configDependencies = - [ GivenComponent (packageName srcid) cname dep_ipid + [ GivenComponent (packageName srcid) cname dep_ipid Public | ConfiguredId srcid (Just (PackageDescription.CLibName cname)) dep_ipid <- CD.nonSetupDeps deps ] @@ -1677,7 +1678,7 @@ installReadyPackage pkg = case finalizePD flags (enableStanzas stanzas) - (const True) + (\_ _ -> True) platform cinfo [] diff --git a/cabal-install/src/Distribution/Client/InstallPlan.hs b/cabal-install/src/Distribution/Client/InstallPlan.hs index 46212baaccc..ffafbaf071b 100644 --- a/cabal-install/src/Distribution/Client/InstallPlan.hs +++ b/cabal-install/src/Distribution/Client/InstallPlan.hs @@ -630,7 +630,11 @@ configureInstallPlan configFlags solverPlan = -- NB: no support for executable dependencies } where - deps = fmap (concatMap (map configuredId . mapDep)) (solverPkgLibDeps spkg) + -- If the private alias of a given dependency matters to the configured + -- package deps we should instead add it to the datatype rather than + -- discarding it here. However, we probably only care about the + -- dependencies as a whole here (right?), so we simply discard the scope. + deps = fmap (concatMap (map configuredId . mapDep . fst)) (solverPkgLibDeps spkg) -- ------------------------------------------------------------ @@ -757,22 +761,23 @@ failed -> ([srcpkg], Processing) failed plan (Processing processingSet completedSet failedSet) pkgid = assert (pkgid `Set.member` processingSet) $ - assert (all (`Set.notMember` processingSet) (drop 1 newlyFailedIds)) $ - assert (all (`Set.notMember` completedSet) (drop 1 newlyFailedIds)) $ + assert (all (`Set.notMember` processingSet) newlyFailedIds) $ + assert (all (`Set.notMember` completedSet) newlyFailedIds) $ -- but note that some newlyFailed may already be in the failed set -- since one package can depend on two packages that both fail and -- so would be in the rev-dep closure for both. assert (processingInvariant plan processing') $ - ( map asConfiguredPackage (drop 1 newlyFailed) + ( map asConfiguredPackage newlyFailed , processing' ) where processingSet' = Set.delete pkgid processingSet - failedSet' = failedSet `Set.union` Set.fromList newlyFailedIds + failedSet' = failedSet `Set.union` Set.fromList newlyFailedIds `Set.union` Set.singleton pkgid newlyFailedIds = map nodeKey newlyFailed - newlyFailed = - fromMaybe (internalError "failed" "package not in graph") $ - Graph.revClosure (planGraph plan) [pkgid] + newlyFailed = case fromMaybe (internalError "failed" "package not in graph") $ + Graph.revClosure (planGraph plan) [pkgid] of + [] -> error "impossible" + _ : tail' -> tail' processing' = Processing processingSet' completedSet failedSet' asConfiguredPackage (Configured pkg) = pkg diff --git a/cabal-install/src/Distribution/Client/InstallSymlink.hs b/cabal-install/src/Distribution/Client/InstallSymlink.hs index 1701aa1f652..78f5fd0b613 100644 --- a/cabal-install/src/Distribution/Client/InstallSymlink.hs +++ b/cabal-install/src/Distribution/Client/InstallSymlink.hs @@ -205,7 +205,7 @@ symlinkBinaries case finalizePD flags (enableStanzas stanzas) - (const True) + (\_ _ -> True) platform cinfo [] diff --git a/cabal-install/src/Distribution/Client/List.hs b/cabal-install/src/Distribution/Client/List.hs index b03211038de..d8bfa969ba7 100644 --- a/cabal-install/src/Distribution/Client/List.hs +++ b/cabal-install/src/Distribution/Client/List.hs @@ -651,7 +651,8 @@ mergePackageInfo versionPref installedPkgs sourcePkgs selectedPkg showVer = source , dependencies = combine - ( map (SourceDependency . simplifyDependency) + -- We discard info (with `snd`) about private scopes because we don't yet report them in cabal list or cabal info (TODO). + ( map (SourceDependency . simplifyDependency . snd) . Source.allBuildDepends ) source diff --git a/cabal-install/src/Distribution/Client/ProjectConfig.hs b/cabal-install/src/Distribution/Client/ProjectConfig.hs index 5d04f101c7d..78a2669e5e2 100644 --- a/cabal-install/src/Distribution/Client/ProjectConfig.hs +++ b/cabal-install/src/Distribution/Client/ProjectConfig.hs @@ -1535,7 +1535,7 @@ readSourcePackageCabalFile verbosity pkgfilename content = unless (null warnings) $ info verbosity (formatWarnings warnings) return pkg - (warnings, Left (mspecVersion, errors)) -> + (warnings, Left (mspecVersion, errors)) -> do throwIO $ CabalFileParseError pkgfilename content errors mspecVersion warnings where formatWarnings warnings = diff --git a/cabal-install/src/Distribution/Client/ProjectOrchestration.hs b/cabal-install/src/Distribution/Client/ProjectOrchestration.hs index 2d963b0e07f..d17bbf4b3fe 100644 --- a/cabal-install/src/Distribution/Client/ProjectOrchestration.hs +++ b/cabal-install/src/Distribution/Client/ProjectOrchestration.hs @@ -1158,7 +1158,7 @@ writeBuildReports settings buildContext plan buildOutcomes = do Right br -> case buildResultTests br of TestsNotTried -> BuildReports.NotTried TestsOk -> BuildReports.Ok - in Just $ (BuildReports.BuildReport (packageId pkg) os arch (compilerId comp) cabalInstallID (elabFlagAssignment pkg) (map (packageId . fst) $ elabLibDependencies pkg) installOutcome docsOutcome testsOutcome, getRepo . elabPkgSourceLocation $ pkg) -- TODO handle failure log files? + in Just $ (BuildReports.BuildReport (packageId pkg) os arch (compilerId comp) cabalInstallID (elabFlagAssignment pkg) (map (packageId . (\(a, _, _) -> a)) $ elabLibDependencies pkg) installOutcome docsOutcome testsOutcome, getRepo . elabPkgSourceLocation $ pkg) -- TODO handle failure log files? fromPlanPackage _ _ = Nothing buildReports = mapMaybe (\x -> fromPlanPackage x (InstallPlan.lookupBuildOutcome x buildOutcomes)) $ InstallPlan.toList plan diff --git a/cabal-install/src/Distribution/Client/ProjectPlanOutput.hs b/cabal-install/src/Distribution/Client/ProjectPlanOutput.hs index d38f07037a6..9484e4cd52b 100644 --- a/cabal-install/src/Distribution/Client/ProjectPlanOutput.hs +++ b/cabal-install/src/Distribution/Client/ProjectPlanOutput.hs @@ -21,11 +21,12 @@ module Distribution.Client.ProjectPlanOutput , argsEquivalentOfGhcEnvironmentFile ) where +import Data.Either import Distribution.Client.DistDirLayout import Distribution.Client.HashValue (hashValue, showHashValue) import Distribution.Client.ProjectBuilding.Types import Distribution.Client.ProjectPlanning.Types -import Distribution.Client.Types.ConfiguredId (confInstId) +import Distribution.Client.Types.ConfiguredId (ConfiguredId, confInstId) import Distribution.Client.Types.PackageLocation (PackageLocation (..)) import Distribution.Client.Types.Repo (RemoteRepo (..), Repo (..)) import Distribution.Client.Types.SourceRepo (SourceRepoMaybe, SourceRepositoryPackage (..)) @@ -199,9 +200,9 @@ encodePlanAsJson distDirLayout elaboratedInstallPlan elaboratedSharedConfig = J.object $ [ comp2str c J..= J.object - ( [ "depends" J..= map (jdisplay . confInstId) (map fst ldeps) - , "exe-depends" J..= map (jdisplay . confInstId) edeps - ] + ( handleLibDepends ldeps + ++ [ "exe-depends" J..= map (jdisplay . confInstId) edeps + ] ++ bin_file c ) | (c, (ldeps, edeps)) <- @@ -212,10 +213,10 @@ encodePlanAsJson distDirLayout elaboratedInstallPlan elaboratedSharedConfig = ] in ["components" J..= components] ElabComponent comp -> - [ "depends" J..= map (jdisplay . confInstId) (map fst $ elabLibDependencies elab) - , "exe-depends" J..= map jdisplay (elabExeDependencies elab) - , "component-name" J..= J.String (comp2str (compSolverName comp)) - ] + handleLibDepends (elabLibDependencies elab) + ++ [ "exe-depends" J..= map jdisplay (elabExeDependencies elab) + , "component-name" J..= J.String (comp2str (compSolverName comp)) + ] ++ bin_file (compSolverName comp) where -- \| Only add build-info file location if the Setup.hs CLI @@ -321,6 +322,20 @@ encodePlanAsJson distDirLayout elaboratedInstallPlan elaboratedSharedConfig = then dist_dir "build" prettyShow s ("lib" ++ prettyShow s) <.> dllExtension plat else InstallDirs.bindir (elabInstallDirs elab) ("lib" ++ prettyShow s) <.> dllExtension plat + handleLibDepends :: [(ConfiguredId, Bool, IsPrivate)] -> [J.Pair] + handleLibDepends deps = + let (publicDeps, privateDeps) = + partitionEithers $ + map + ( \(p, _, mb) -> case mb of + Public -> Left p + Private alias -> Right (alias, p) + ) + deps + in [ "depends" J..= map (jdisplay . confInstId) publicDeps + , "private-depends" J..= J.object (map (\(al, p) -> prettyShow al J..= (jdisplay . confInstId) p) privateDeps) + ] + comp2str :: ComponentDeps.Component -> String comp2str = prettyShow @@ -639,7 +654,7 @@ postBuildProjectStatus ] elabLibDeps :: ElaboratedConfiguredPackage -> [UnitId] - elabLibDeps = map (newSimpleUnitId . confInstId) . map fst . elabLibDependencies + elabLibDeps = map (newSimpleUnitId . confInstId) . map (\(p, _, _) -> p) . elabLibDependencies -- Was a build was attempted for this package? -- If it doesn't have both a build status and outcome then the answer is no. diff --git a/cabal-install/src/Distribution/Client/ProjectPlanning.hs b/cabal-install/src/Distribution/Client/ProjectPlanning.hs index 38a59b9818c..ad802f24118 100644 --- a/cabal-install/src/Distribution/Client/ProjectPlanning.hs +++ b/cabal-install/src/Distribution/Client/ProjectPlanning.hs @@ -6,7 +6,10 @@ {-# LANGUAGE NamedFieldPuns #-} {-# LANGUAGE RankNTypes #-} {-# LANGUAGE RecordWildCards #-} +{-# LANGUAGE TupleSections #-} {-# LANGUAGE TypeFamilies #-} +{-# LANGUAGE ViewPatterns #-} +{-# LANGUAGE NoMonoLocalBinds #-} -- | -- /Elaborated: worked out with great care and nicety of detail; executed with great minuteness: elaborate preparations; elaborate care./ @@ -1711,12 +1714,10 @@ elaborateInstallPlan where compSolverName = CD.ComponentSetup compComponentName = Nothing - - dep_pkgs = elaborateLibSolverId mapDep =<< CD.setupDeps deps0 - + dep_pkgs = [(d', rn) | (d, rn) <- CD.setupDeps deps0, d' <- elaborateLibSolverId mapDep d] compLibDependencies = -- MP: No idea what this function does - map (\cid -> (configuredId cid, False)) dep_pkgs + map (\(cid, rn) -> (configuredId cid, False, rn)) dep_pkgs compLinkedLibDependencies = notImpl "compLinkedLibDependencies" compOrderLibDependencies = notImpl "compOrderLibDependencies" @@ -1766,7 +1767,7 @@ elaborateInstallPlan let do_ cid = let cid' = annotatedIdToConfiguredId . ci_ann_id $ cid - in (cid', False) -- filled in later in pruneInstallPlanPhase2) + in (cid', False, ci_alias cid) -- filled in later in pruneInstallPlanPhase2) -- 2. Read out the dependencies from the ConfiguredComponent cc0 let compLibDependencies = -- Nub because includes can show up multiple times @@ -1881,35 +1882,35 @@ elaborateInstallPlan external_lib_dep_sids = CD.select (== compSolverName) deps0 external_exe_dep_sids = CD.select (== compSolverName) exe_deps0 - external_lib_dep_pkgs = concatMap mapDep external_lib_dep_sids + external_exe_dep_sids_raw = [(sid, Public) | sid <- external_exe_dep_sids] -- Combine library and build-tool dependencies, for backwards -- compatibility (See issue #5412 and the documentation for -- InstallPlan.fromSolverInstallPlan), but prefer the versions -- specified as build-tools. external_exe_dep_pkgs = - concatMap mapDep $ - ordNubBy (pkgName . packageId) $ - external_exe_dep_sids ++ external_lib_dep_sids + [(d, alias) | (sid, alias) <- ordNubBy (pkgName . packageId . fst) $ external_exe_dep_sids_raw ++ external_lib_dep_sids, d <- mapDep sid] + + external_lib_dep_pkgs = [(d, alias) | (sid, alias) <- external_lib_dep_sids, d <- mapDep sid] external_exe_map = Map.fromList $ [ (getComponentId pkg, paths) - | pkg <- external_exe_dep_pkgs + | (pkg, _) <- external_exe_dep_pkgs , let paths = planPackageExePaths pkg ] exe_map1 = Map.union external_exe_map $ fmap (\x -> [x]) exe_map external_lib_cc_map = - Map.fromListWith Map.union $ - map mkCCMapping external_lib_dep_pkgs + Map.fromListWith Map.union (map mkCCMapping external_lib_dep_pkgs) external_exe_cc_map = Map.fromListWith Map.union $ map mkCCMapping external_exe_dep_pkgs external_lc_map = Map.fromList $ map mkShapeMapping $ - external_lib_dep_pkgs ++ concatMap mapDep external_exe_dep_sids + -- MP: TODO... should these aliases work here as well + (map fst external_lib_dep_pkgs ++ concatMap (mapDep . fst) external_exe_dep_sids_raw) compPkgConfigDependencies = [ ( pn @@ -2043,9 +2044,10 @@ elaborateInstallPlan filterExt' :: [(ConfiguredId, a)] -> [(ConfiguredId, a)] filterExt' = filter (isExt . fst) + filterExt'' = filter (isExt . (\(d, _, _) -> d)) pkgLibDependencies = - buildComponentDeps (filterExt' . compLibDependencies) + buildComponentDeps (filterExt'' . compLibDependencies) pkgExeDependencies = buildComponentDeps (filterExt . compExeDependencies) pkgExeDependencyPaths = @@ -2112,7 +2114,7 @@ elaborateInstallPlan elabPkgDescription = case PD.finalizePD flags elabEnabledSpec - (const True) + (\_ _ -> True) platform (compilerInfo compiler) [] @@ -2179,7 +2181,7 @@ elaborateInstallPlan elabSetupScriptStyle elabPkgDescription libDepGraph - deps0 + (fmap (map fst) deps0) elabSetupPackageDBStack = buildAndRegisterDbs elabInplaceBuildPackageDBStack = inplacePackageDbs @@ -2458,42 +2460,45 @@ matchElabPkg p elab = -- and 'ComponentName' to the 'ComponentId' that should be used -- in this case. mkCCMapping - :: ElaboratedPlanPackage - -> (PackageName, Map ComponentName (AnnotatedId ComponentId)) -mkCCMapping = - InstallPlan.foldPlanPackage - ( \ipkg -> - ( packageName ipkg - , Map.singleton - (ipiComponentName ipkg) - -- TODO: libify - ( AnnotatedId - { ann_id = IPI.installedComponentId ipkg - , ann_pid = packageId ipkg - , ann_cname = IPI.sourceComponentName ipkg - } + :: (ElaboratedPlanPackage, IsPrivate) + -> ((PackageName, IsPrivate), Map ComponentName ((AnnotatedId ComponentId))) +mkCCMapping (ep, alias) = foldpp ep + where + foldpp = + InstallPlan.foldPlanPackage + ( \ipkg -> + ( (packageName ipkg, alias) + , Map.singleton + (ipiComponentName ipkg) + -- TODO: libify + ( AnnotatedId + { ann_id = IPI.installedComponentId ipkg + , ann_pid = packageId ipkg + , ann_cname = IPI.sourceComponentName ipkg + } + ) ) ) - ) - $ \elab -> - let mk_aid cn = - AnnotatedId - { ann_id = elabComponentId elab - , ann_pid = packageId elab - , ann_cname = cn - } - in ( packageName elab - , case elabPkgOrComp elab of - ElabComponent comp -> - case compComponentName comp of - Nothing -> Map.empty - Just n -> Map.singleton n (mk_aid n) - ElabPackage _ -> - Map.fromList $ - map - (\comp -> let cn = Cabal.componentName comp in (cn, mk_aid cn)) - (Cabal.pkgBuildableComponents (elabPkgDescription elab)) - ) + $ \elab -> + let mk_aid cn = + ( AnnotatedId + { ann_id = elabComponentId elab + , ann_pid = packageId elab + , ann_cname = cn + } + ) + in ( (packageName elab, alias) + , case elabPkgOrComp elab of + ElabComponent comp -> + case compComponentName comp of + Nothing -> Map.empty + Just n -> Map.singleton n (mk_aid n) + ElabPackage _ -> + Map.fromList $ + map + (\comp -> let cn = Cabal.componentName comp in (cn, mk_aid cn)) + (Cabal.pkgBuildableComponents (elabPkgDescription elab)) + ) -- | Given an 'ElaboratedPlanPackage', generate the mapping from 'ComponentId' -- to the shape of this package, as per mix-in linking. @@ -3525,7 +3530,7 @@ pruneInstallPlanPass2 pkgs = where -- We initially assume that all the dependencies are external (hence the boolean is always -- False) and here we correct the dependencies so the right packages are marked promised. - addInternal (cid, _) = (cid, (cid `Set.member` inMemoryTargets)) + addInternal (cid, _, pn) = (cid, (cid `Set.member` inMemoryTargets), pn) libTargetsRequiredForRevDeps = [ c @@ -3694,7 +3699,7 @@ setupHsScriptOptions , usePackageIndex = Nothing , useDependencies = [ (uid, srcid) - | (ConfiguredId srcid (Just (CLibName LMainLibName)) uid, _) <- + | (ConfiguredId srcid (Just (CLibName LMainLibName)) uid, _, _) <- elabSetupDependencies elab ] , useDependenciesExclusive = True @@ -3906,14 +3911,14 @@ setupHsConfigureFlags -- enough info anyway) -- configDependencies = - [ cidToGivenComponent cid - | (cid, is_internal) <- elabLibDependencies elab + [ cidToGivenComponent alias cid + | (cid, is_internal, alias) <- elabLibDependencies elab , not is_internal ] configPromisedDependencies = - [ cidToGivenComponent cid - | (cid, is_internal) <- elabLibDependencies elab + [ cidToGivenComponent alias cid + | (cid, is_internal, alias) <- elabLibDependencies elab , is_internal ] @@ -3921,7 +3926,7 @@ setupHsConfigureFlags case elabPkgOrComp of ElabPackage _ -> [ thisPackageVersionConstraint srcid - | (ConfiguredId srcid _ _uid, _) <- elabLibDependencies elab + | (ConfiguredId srcid _ _uid, _, _) <- elabLibDependencies elab ] ElabComponent _ -> [] @@ -3944,8 +3949,8 @@ setupHsConfigureFlags configUseResponseFiles = mempty configAllowDependingOnPrivateLibs = Flag $ not $ libraryVisibilitySupported pkgConfigCompiler - cidToGivenComponent :: ConfiguredId -> GivenComponent - cidToGivenComponent (ConfiguredId srcid mb_cn cid) = GivenComponent (packageName srcid) ln cid + cidToGivenComponent :: IsPrivate -> ConfiguredId -> GivenComponent + cidToGivenComponent alias (ConfiguredId srcid mb_cn cid) = GivenComponent (packageName srcid) ln cid alias where ln = case mb_cn of Just (CLibName lname) -> lname @@ -4208,7 +4213,7 @@ packageHashInputs ElabPackage (ElaboratedPackage{..}) -> Set.fromList $ [ confInstId dep - | (dep, _) <- CD.select relevantDeps pkgLibDependencies + | (dep, _, _) <- CD.select relevantDeps pkgLibDependencies ] ++ [ confInstId dep | dep <- CD.select relevantDeps pkgExeDependencies @@ -4217,7 +4222,7 @@ packageHashInputs Set.fromList ( map confInstId - ( map fst (compLibDependencies comp) + ( map (\(d, _, _) -> d) (compLibDependencies comp) ++ compExeDependencies comp ) ) diff --git a/cabal-install/src/Distribution/Client/ProjectPlanning/SetupPolicy.hs b/cabal-install/src/Distribution/Client/ProjectPlanning/SetupPolicy.hs index 212a5d93f81..bcde2e796f5 100644 --- a/cabal-install/src/Distribution/Client/ProjectPlanning/SetupPolicy.hs +++ b/cabal-install/src/Distribution/Client/ProjectPlanning/SetupPolicy.hs @@ -178,7 +178,7 @@ instance IsNode NonSetupLibDepSolverPlanPackage where nodeKey spkg nodeNeighbors (NonSetupLibDepSolverPlanPackage spkg) = - ordNub $ CD.nonSetupDeps (resolverPackageLibDeps spkg) + ordNub $ map fst (CD.nonSetupDeps (resolverPackageLibDeps spkg)) -- | Work out which version of the Cabal we will be using to talk to the -- Setup.hs interface for this package. diff --git a/cabal-install/src/Distribution/Client/ProjectPlanning/Types.hs b/cabal-install/src/Distribution/Client/ProjectPlanning/Types.hs index 5b4896b0568..5f88f755d17 100644 --- a/cabal-install/src/Distribution/Client/ProjectPlanning/Types.hs +++ b/cabal-install/src/Distribution/Client/ProjectPlanning/Types.hs @@ -179,7 +179,13 @@ showElaboratedInstallPlan = InstallPlan.showInstallPlan_gen showNode installed_deps = map pretty . nodeNeighbors - local_deps cfg = [(if internal then text "+" else mempty) <> pretty (confInstId uid) | (uid, internal) <- elabLibDependencies cfg] + local_deps cfg = + [ (if internal then text "+" else mempty) <> mpalias <> pretty (confInstId uid) + | (uid, internal, alias) <- elabLibDependencies cfg + , let mpalias = case alias of + Public -> mempty + Private al -> pretty al <> text "." + ] -- TODO: [code cleanup] decide if we really need this, there's not much in it, and in principle -- even platform and compiler could be different if we're building things @@ -569,13 +575,13 @@ elabOrderLibDependencies elab = ElabPackage pkg -> map (newSimpleUnitId . confInstId) $ ordNub $ - CD.flatDeps (map fst <$> pkgLibDependencies pkg) + CD.flatDeps (map (\(cid, _, _) -> cid) <$> pkgLibDependencies pkg) ElabComponent comp -> compOrderLibDependencies comp -- | The library dependencies (i.e., the libraries we depend on, NOT -- the dependencies of the library), NOT including setup dependencies. -- These are passed to the @Setup@ script via @--dependency@ or @--promised-dependency@. -elabLibDependencies :: ElaboratedConfiguredPackage -> [(ConfiguredId, Bool)] +elabLibDependencies :: ElaboratedConfiguredPackage -> [(ConfiguredId, Bool, IsPrivate)] elabLibDependencies elab = case elabPkgOrComp elab of ElabPackage pkg -> ordNub (CD.nonSetupDeps (pkgLibDependencies pkg)) @@ -609,7 +615,7 @@ elabExeDependencyPaths elab = -- | The setup dependencies (the library dependencies of the setup executable; -- note that it is not legal for setup scripts to have executable -- dependencies at the moment.) -elabSetupDependencies :: ElaboratedConfiguredPackage -> [(ConfiguredId, Bool)] +elabSetupDependencies :: ElaboratedConfiguredPackage -> [(ConfiguredId, Bool, IsPrivate)] elabSetupDependencies elab = case elabPkgOrComp elab of ElabPackage pkg -> CD.setupDeps (pkgLibDependencies pkg) @@ -669,7 +675,7 @@ data ElaboratedComponent = ElaboratedComponent , compComponentName :: Maybe ComponentName -- ^ The name of the component to be built. Nothing if -- it's a setup dep. - , compLibDependencies :: [(ConfiguredId, Bool)] + , compLibDependencies :: [(ConfiguredId, Bool, IsPrivate)] -- ^ The *external* library dependencies of this component. We -- pass this to the configure script. The Bool indicates whether the -- dependency is a promised dependency (True) or not (False). @@ -716,7 +722,7 @@ compOrderExeDependencies = map (newSimpleUnitId . confInstId) . compExeDependenc data ElaboratedPackage = ElaboratedPackage { pkgInstalledId :: InstalledPackageId - , pkgLibDependencies :: ComponentDeps [(ConfiguredId, Bool)] + , pkgLibDependencies :: ComponentDeps [(ConfiguredId, Bool, IsPrivate)] -- ^ The exact dependencies (on other plan packages) -- The boolean value indicates whether the dependency is a promised dependency -- or not. @@ -790,7 +796,7 @@ whyNotPerComponent = \case -- which can be useful in some circumstances. pkgOrderDependencies :: ElaboratedPackage -> ComponentDeps [UnitId] pkgOrderDependencies pkg = - fmap (map (newSimpleUnitId . confInstId)) (map fst <$> pkgLibDependencies pkg) + fmap (map (newSimpleUnitId . confInstId)) (map (\(cid, _, _) -> cid) <$> pkgLibDependencies pkg) `Mon.mappend` fmap (map (newSimpleUnitId . confInstId)) (pkgExeDependencies pkg) -- | This is used in the install plan to indicate how the package will be diff --git a/cabal-install/src/Distribution/Client/ScriptUtils.hs b/cabal-install/src/Distribution/Client/ScriptUtils.hs index aeae4eaf459..894356074df 100644 --- a/cabal-install/src/Distribution/Client/ScriptUtils.hs +++ b/cabal-install/src/Distribution/Client/ScriptUtils.hs @@ -102,7 +102,8 @@ import Distribution.Fields , readFields ) import Distribution.PackageDescription - ( ignoreConditions + ( Dependencies (..) + , ignoreConditions ) import Distribution.PackageDescription.FieldGrammar ( executableFieldGrammar @@ -472,10 +473,11 @@ updateContextAndWriteProjectFile ctx scriptPath scriptExecutable = do absScript <- unsafeMakeSymbolicPath . makeRelative (normalise projectRoot) <$> canonicalizePath scriptPath let + deps = Dependencies (targetBuildDepends $ buildInfo executable) (targetPrivateBuildDepends $ buildInfo executable) sourcePackage = fakeProjectSourcePackage projectRoot & lSrcpkgDescription . L.condExecutables - .~ [(scriptComponenetName scriptPath, CondNode executable (targetBuildDepends $ buildInfo executable) [])] + .~ [(scriptComponenetName scriptPath, CondNode executable deps [])] executable = scriptExecutable & L.modulePath .~ absScript diff --git a/cabal-install/src/Distribution/Client/Setup.hs b/cabal-install/src/Distribution/Client/Setup.hs index c89f2a3524a..499dfa82641 100644 --- a/cabal-install/src/Distribution/Client/Setup.hs +++ b/cabal-install/src/Distribution/Client/Setup.hs @@ -740,14 +740,15 @@ filterConfigureFlags' flags cabalLibVersion -- (public sublibraries), so we convert it to the legacy -- --dependency=pkg_or_internal_component=cid configDependencies = - let convertToLegacyInternalDep (GivenComponent _ (LSubLibName cn) cid) = + let convertToLegacyInternalDep (GivenComponent _ (LSubLibName cn) cid alias) = Just $ GivenComponent (unqualComponentNameToPackageName cn) LMainLibName cid - convertToLegacyInternalDep (GivenComponent pn LMainLibName cid) = - Just $ GivenComponent pn LMainLibName cid + alias + convertToLegacyInternalDep (GivenComponent pn LMainLibName cid alias) = + Just $ GivenComponent pn LMainLibName cid alias in catMaybes $ convertToLegacyInternalDep <$> configDependencies flags , -- Cabal < 2.5 doesn't know about '--allow-depending-on-private-libs'. configAllowDependingOnPrivateLibs = NoFlag diff --git a/cabal-install/src/Distribution/Client/SolverInstallPlan.hs b/cabal-install/src/Distribution/Client/SolverInstallPlan.hs index f4422080a4b..76d45f455f0 100644 --- a/cabal-install/src/Distribution/Client/SolverInstallPlan.hs +++ b/cabal-install/src/Distribution/Client/SolverInstallPlan.hs @@ -56,6 +56,7 @@ import Prelude () import Distribution.Package ( HasUnitId (..) + , IsPrivate (..) , Package (..) , PackageId , PackageIdentifier (..) @@ -81,6 +82,7 @@ import Distribution.Solver.Types.SolverPackage import Data.Array ((!)) import qualified Data.Foldable as Foldable import qualified Data.Graph as OldGraph +import qualified Data.List as List import qualified Data.Map as Map import Distribution.Compat.Graph (Graph, IsNode (..)) import qualified Distribution.Compat.Graph as Graph @@ -313,7 +315,7 @@ nonSetupClosure index pkgids0 = closure Graph.empty pkgids0 Nothing -> closure completed' pkgids' where completed' = Graph.insert pkg completed - pkgids' = CD.nonSetupDeps (resolverPackageLibDeps pkg) ++ pkgids + pkgids' = map fst (CD.nonSetupDeps (resolverPackageLibDeps pkg)) ++ pkgids -- | Compute the root sets of a plan -- @@ -349,7 +351,7 @@ libraryRoots index = setupRoots :: SolverPlanIndex -> [[SolverId]] setupRoots = filter (not . null) - . map (CD.setupDeps . resolverPackageLibDeps) + . map (map fst . CD.setupDeps . resolverPackageLibDeps) . Foldable.toList -- | Given a package index where we assume we want to use all the packages @@ -365,42 +367,56 @@ dependencyInconsistencies' :: SolverPlanIndex -> [(PackageName, [(PackageIdentifier, Version)])] dependencyInconsistencies' index = - [ (name, [(pid, packageVersion dep) | (dep, pids) <- uses, pid <- pids]) + [ (name, [(pid, packageVersion dep) | (dep, pids) <- map snd uses, pid <- pids]) | (name, ipid_map) <- Map.toList inverseIndex - , let uses = Map.elems ipid_map - , reallyIsInconsistent (map fst uses) + , let uses = Map.toAscList ipid_map -- We need a sorted list with (aliases, packages) (aliases before packages) to call groupBy on. + , any (reallyIsInconsistent . map (fst . snd)) $ + -- We group together all packages without a private alias, and those with + -- private aliases by its scope name AND the SolverId of the package + -- (because, across packages, there may exist scopes with the same name). + List.groupBy + ( \x y -> case (x, y) of + (((Public, _), _), (_, _)) -> False + ((_, _), ((Public, _), _)) -> False + (((aliasA, sidA), _), ((aliasB, sidB), _)) + | aliasA == aliasB -> + sidA == sidB + | otherwise -> + False + ) + uses ] where -- For each package name (of a dependency, somewhere) -- and each installed ID of that package -- the associated package instance - -- and a list of reverse dependencies (as source IDs) - inverseIndex :: Map PackageName (Map SolverId (SolverPlanPackage, [PackageId])) + -- and a list of reverse dependencies (as source IDs) and the possible private scope of each revdep + inverseIndex :: Map PackageName (Map (IsPrivate, SolverId) (SolverPlanPackage, [PackageId])) inverseIndex = Map.fromListWith (Map.unionWith (\(a, b) (_, b') -> (a, b ++ b'))) - [ (packageName dep, Map.fromList [(sid, (dep, [packageId pkg]))]) + [ (packageName dep, Map.fromList [((palias, sid), (dep, [(packageId pkg)]))]) | -- For each package @pkg@ pkg <- Foldable.toList index , -- Find out which @sid@ @pkg@ depends on - sid <- CD.nonSetupDeps (resolverPackageLibDeps pkg) + (sid, palias) <- CD.nonSetupDeps (resolverPackageLibDeps pkg) , -- And look up those @sid@ (i.e., @sid@ is the ID of @dep@) Just dep <- [Graph.lookup sid index] ] -- If, in a single install plan, we depend on more than one version of a - -- package, then this is ONLY okay in the (rather special) case that we - -- depend on precisely two versions of that package, and one of them - -- depends on the other. This is necessary for example for the base where - -- we have base-3 depending on base-4. - reallyIsInconsistent :: [SolverPlanPackage] -> Bool + -- package in the same top-level or private scope, then this is ONLY okay + -- in the (rather special) case that we depend on precisely two versions of + -- that package, and one of them depends on the other. This is necessary + -- for example for the base where we have base-3 depending on base-4. + reallyIsInconsistent :: ([SolverPlanPackage]) -> Bool reallyIsInconsistent [] = False reallyIsInconsistent [_p] = False reallyIsInconsistent [p1, p2] = let pid1 = nodeKey p1 pid2 = nodeKey p2 - in pid1 `notElem` CD.nonSetupDeps (resolverPackageLibDeps p2) - && pid2 `notElem` CD.nonSetupDeps (resolverPackageLibDeps p1) + in pid1 `notElem` map fst (CD.nonSetupDeps (resolverPackageLibDeps p2)) + && pid2 `notElem` map fst (CD.nonSetupDeps (resolverPackageLibDeps p1)) reallyIsInconsistent _ = True -- | The graph of packages (nodes) and dependencies (edges) must be acyclic. diff --git a/cabal-install/src/Distribution/Client/Targets.hs b/cabal-install/src/Distribution/Client/Targets.hs index 1a37c9c73b9..bab0b0ded04 100644 --- a/cabal-install/src/Distribution/Client/Targets.hs +++ b/cabal-install/src/Distribution/Client/Targets.hs @@ -84,7 +84,8 @@ import Distribution.Types.PackageVersionConstraint ) import Distribution.PackageDescription - ( GenericPackageDescription + ( ComponentName + , GenericPackageDescription ) import Distribution.Simple.Utils ( dieWithException @@ -106,6 +107,8 @@ import qualified Data.Map as Map import Distribution.Client.Errors import qualified Distribution.Client.GZipUtils as GZipUtils import qualified Distribution.Compat.CharParsing as P +import Distribution.Solver.Types.ComponentDeps +import Distribution.Types.Dependency import Distribution.Utils.Path (makeSymbolicPath) import Network.URI ( URI (..) @@ -613,6 +616,7 @@ data UserQualifier UserQualSetup PackageName | -- | Executable dependency. UserQualExe PackageName PackageName + | UserQualComp PackageName ComponentName deriving (Eq, Show, Generic) instance Binary UserQualifier @@ -623,6 +627,7 @@ instance Structured UserQualifier data UserConstraintScope = -- | Scope that applies to the package when it has the specified qualifier. UserQualified UserQualifier PackageName + | UserPrivateQualifier PackageName PrivateAlias PackageName | -- | Scope that applies to the package when it has a setup qualifier. UserAnySetupQualifier PackageName | -- | Scope that applies to the package when it has any qualifier. @@ -632,14 +637,17 @@ data UserConstraintScope instance Binary UserConstraintScope instance Structured UserConstraintScope -fromUserQualifier :: UserQualifier -> Qualifier -fromUserQualifier UserQualToplevel = QualToplevel -fromUserQualifier (UserQualSetup name) = QualSetup name -fromUserQualifier (UserQualExe name1 name2) = QualExe name1 name2 +fromUserQualifier :: UserQualifier -> Namespace +fromUserQualifier UserQualToplevel = DefaultNamespace +fromUserQualifier (UserQualSetup pn) = IndependentComponent pn ComponentSetup +fromUserQualifier (UserQualExe pn bpn) = IndependentBuildTool pn bpn +fromUserQualifier (UserQualComp pn cn) = IndependentComponent pn (componentNameToComponent cn) fromUserConstraintScope :: UserConstraintScope -> ConstraintScope fromUserConstraintScope (UserQualified q pn) = - ScopeQualified (fromUserQualifier q) pn + ScopeQualified (fromUserQualifier q) QualToplevel pn +fromUserConstraintScope (UserPrivateQualifier pn alias cpn) = + ScopeQualified DefaultNamespace (QualAlias pn alias) cpn fromUserConstraintScope (UserAnySetupQualifier pn) = ScopeAnySetupQualifier pn fromUserConstraintScope (UserAnyQualifier pn) = ScopeAnyQualifier pn @@ -658,6 +666,7 @@ userConstraintPackageName (UserConstraint scope _) = scopePN scope scopePN (UserQualified _ pn) = pn scopePN (UserAnyQualifier pn) = pn scopePN (UserAnySetupQualifier pn) = pn + scopePN (UserPrivateQualifier _ _ pn) = pn userToPackageConstraint :: UserConstraint -> PackageConstraint userToPackageConstraint (UserConstraint scope prop) = @@ -706,10 +715,24 @@ instance Parsec UserConstraint where withDot pn | pn == mkPackageName "any" = UserAnyQualifier <$> parsec | pn == mkPackageName "setup" = UserAnySetupQualifier <$> parsec + | pn == mkPackageName "private" = do + qpn <- parsec + _ <- P.char '.' + alias <- parsec + _ <- P.char ':' + cpn <- parsec + return $ UserPrivateQualifier qpn alias cpn | otherwise = P.unexpected $ "constraint scope: " ++ unPackageName pn - withColon :: PackageName -> m UserConstraintScope - withColon pn = + withColon, setupQual, compQual :: PackageName -> m UserConstraintScope + withColon pn = setupQual pn <|> compQual pn + + compQual pn = do + comp_qual <- UserQualComp pn <$> parsec + void $ P.char '.' + UserQualified comp_qual <$> parsec + + setupQual pn = UserQualified (UserQualSetup pn) <$ P.string "setup." <*> parsec diff --git a/cabal-install/src/Distribution/Client/Types/ConfiguredPackage.hs b/cabal-install/src/Distribution/Client/Types/ConfiguredPackage.hs index 0b7d62e7e77..aefb7bee26f 100644 --- a/cabal-install/src/Distribution/Client/Types/ConfiguredPackage.hs +++ b/cabal-install/src/Distribution/Client/Types/ConfiguredPackage.hs @@ -41,7 +41,7 @@ data ConfiguredPackage loc = ConfiguredPackage , confPkgDeps :: CD.ComponentDeps [ConfiguredId] -- ^ set of exact dependencies (installed or source). -- - -- These must be consistent with the 'buildDepends' + -- These must be consistent with the 'buildDepends' and 'privateBuildDepends' -- in the 'PackageDescription' that you'd get by -- applying the flag assignment and optional stanzas. } diff --git a/cabal-install/tests/IntegrationTests2.hs b/cabal-install/tests/IntegrationTests2.hs index 6579b2ddcc2..cc955240fc7 100644 --- a/cabal-install/tests/IntegrationTests2.hs +++ b/cabal-install/tests/IntegrationTests2.hs @@ -468,7 +468,7 @@ testTargetSelectorAmbiguous reportSubCase = do condLibrary = Nothing, condSubLibraries = [], condForeignLibs = [], - condExecutables = [ ( exeName exe, CondNode exe [] [] ) + condExecutables = [ ( exeName exe, CondNode exe mempty [] ) | exe <- exes ], condTestSuites = [], condBenchmarks = [] diff --git a/cabal-install/tests/UnitTests.hs b/cabal-install/tests/UnitTests.hs index 8434f623e82..a7d94e93890 100644 --- a/cabal-install/tests/UnitTests.hs +++ b/cabal-install/tests/UnitTests.hs @@ -24,11 +24,12 @@ import qualified UnitTests.Distribution.Solver.Modular.RetryLog import qualified UnitTests.Distribution.Solver.Modular.Solver import qualified UnitTests.Distribution.Solver.Modular.WeightedPSQ import qualified UnitTests.Distribution.Solver.Types.OptionalStanza +import UnitTests.Options (extraOptions) main :: IO () main = do initTests <- UnitTests.Distribution.Client.Init.tests - defaultMain $ + defaultMainWithIngredients (includingOptions extraOptions : defaultIngredients) $ testGroup "Unit Tests" [ testGroup diff --git a/cabal-install/tests/UnitTests/Distribution/Client/DescribedInstances.hs b/cabal-install/tests/UnitTests/Distribution/Client/DescribedInstances.hs index 7e52d25173f..a1b34671a04 100644 --- a/cabal-install/tests/UnitTests/Distribution/Client/DescribedInstances.hs +++ b/cabal-install/tests/UnitTests/Distribution/Client/DescribedInstances.hs @@ -8,6 +8,7 @@ import Distribution.Client.Compat.Prelude import Data.List ((\\)) import Distribution.Described +import Distribution.Types.Dependency (PrivateAlias) import Distribution.Types.PackageId (PackageIdentifier) import Distribution.Types.PackageName (PackageName) import Distribution.Types.VersionRange (VersionRange) @@ -164,6 +165,7 @@ instance Described UserConstraint where REUnion [ "any." <> describePN , "setup." <> describePN + , "private." <> describePN <> "." <> describe (Proxy :: Proxy PrivateAlias) <> ":" <> describePN , describePN , describePN <> ":setup." <> describePN ] diff --git a/cabal-install/tests/UnitTests/Distribution/Client/Init/Utils.hs b/cabal-install/tests/UnitTests/Distribution/Client/Init/Utils.hs index e5ed0748a45..6991613a515 100644 --- a/cabal-install/tests/UnitTests/Distribution/Client/Init/Utils.hs +++ b/cabal-install/tests/UnitTests/Distribution/Client/Init/Utils.hs @@ -78,12 +78,12 @@ mkLicense :: SPDX.LicenseId -> SPDX.License mkLicense lid = SPDX.License (SPDX.ELicense (SPDX.ELicenseId lid) Nothing) mangleBaseDep :: a -> (a -> [Dependency]) -> [Dependency] -mangleBaseDep target f = - [ if unPackageName x == "base" - then Dependency x anyVersion z - else dep - | dep@(Dependency x _ z) <- f target - ] +mangleBaseDep target f = map go (f target) + where + go dep@(Dependency x _ z) = + if unPackageName x == "base" + then Dependency x anyVersion z + else dep infix 1 @?!, @!? diff --git a/cabal-install/tests/UnitTests/Distribution/Solver/Modular/DSL.hs b/cabal-install/tests/UnitTests/Distribution/Solver/Modular/DSL.hs index 991c5cafa0e..bc9bbc14d04 100644 --- a/cabal-install/tests/UnitTests/Distribution/Solver/Modular/DSL.hs +++ b/cabal-install/tests/UnitTests/Distribution/Solver/Modular/DSL.hs @@ -1,11 +1,12 @@ {-# LANGUAGE GeneralizedNewtypeDeriving #-} {-# LANGUAGE OverloadedStrings #-} +{-# LANGUAGE PatternSynonyms #-} {-# LANGUAGE RecordWildCards #-} {-# LANGUAGE ScopedTypeVariables #-} -- | DSL for testing the modular solver module UnitTests.Distribution.Solver.Modular.DSL - ( ExampleDependency (..) + ( ExampleDependency (.., ExAny, ExFix, ExRange, ExSubLibAny, ExSubLibFix, ExFixPriv, ExAnyPriv) , Dependencies (..) , ExSubLib (..) , ExTest (..) @@ -140,6 +141,7 @@ import Distribution.Solver.Types.Variable -------------------------------------------------------------------------------} type ExamplePkgName = String +type ExamplePrivateAlias = String type ExamplePkgVersion = Int type ExamplePkgHash = String -- for example "installed" packages type ExampleFlagName = String @@ -181,18 +183,36 @@ publicDependencies = mempty{depsVisibility = C.LibraryVisibilityPublic} unbuildableDependencies :: Dependencies unbuildableDependencies = mempty{depsIsBuildable = False} +pattern ExAny :: ExamplePkgName -> ExampleDependency +pattern ExAny p = ExAnyD Nothing p +pattern ExFix :: ExamplePkgName -> ExamplePkgVersion -> ExampleDependency +pattern ExFix p v = ExFixD Nothing p v +pattern ExRange :: ExamplePkgName -> ExamplePkgVersion -> ExamplePkgVersion -> ExampleDependency +pattern ExRange p v1 v2 = ExRangeD Nothing p v1 v2 + +pattern ExSubLibAny :: ExamplePkgName -> ExampleSubLibName -> ExampleDependency +pattern ExSubLibAny e l = ExSubLibAnyD Nothing e l + +pattern ExSubLibFix :: ExamplePkgName -> ExampleSubLibName -> ExamplePkgVersion -> ExampleDependency +pattern ExSubLibFix e l v = ExSubLibFixD Nothing e l v + +pattern ExAnyPriv :: ExamplePrivateAlias -> ExamplePkgName -> ExampleDependency +pattern ExAnyPriv alias p = ExAnyD (Just alias) p +pattern ExFixPriv :: ExamplePrivateAlias -> ExamplePkgName -> ExamplePkgVersion -> ExampleDependency +pattern ExFixPriv alias p v = ExFixD (Just alias) p v + data ExampleDependency = -- | Simple dependency on any version - ExAny ExamplePkgName + ExAnyD (Maybe ExamplePrivateAlias) ExamplePkgName | -- | Simple dependency on a fixed version - ExFix ExamplePkgName ExamplePkgVersion + ExFixD (Maybe ExamplePrivateAlias) ExamplePkgName ExamplePkgVersion | -- | Simple dependency on a range of versions, with an inclusive lower bound -- and an exclusive upper bound. - ExRange ExamplePkgName ExamplePkgVersion ExamplePkgVersion + ExRangeD (Maybe ExamplePrivateAlias) ExamplePkgName ExamplePkgVersion ExamplePkgVersion | -- | Sub-library dependency - ExSubLibAny ExamplePkgName ExampleSubLibName + ExSubLibAnyD (Maybe ExamplePrivateAlias) ExamplePkgName ExampleSubLibName | -- | Sub-library dependency on a fixed version - ExSubLibFix ExamplePkgName ExampleSubLibName ExamplePkgVersion + ExSubLibFixD (Maybe ExamplePrivateAlias) ExamplePkgName ExampleSubLibName ExamplePkgVersion | -- | Build-tool-depends dependency ExBuildToolAny ExamplePkgName ExampleExeName | -- | Build-tool-depends dependency on a fixed version @@ -272,13 +292,12 @@ data ExampleQualifier = QualNone | QualIndep ExamplePkgName | QualSetup ExamplePkgName - | -- The two package names are the build target and the package containing the - -- setup script. - QualIndepSetup ExamplePkgName ExamplePkgName | -- The two package names are the package depending on the exe and the -- package containing the exe. QualExe ExamplePkgName ExamplePkgName +-- TODO: Add QualPrivateAlias? + -- | Whether to enable tests in all packages in a test case. newtype EnableAllTests = EnableAllTests Bool deriving (BooleanFlag) @@ -390,9 +409,9 @@ exInst pn v hash deps = ExInst pn v hash (map exInstHash deps) -- these packages. type ExampleDb = [Either ExampleInstalled ExampleAvailable] -type DependencyTree a = C.CondTree C.ConfVar [C.Dependency] a +type DependencyTree a = C.CondTree C.ConfVar C.Dependencies a -type DependencyComponent a = C.CondBranch C.ConfVar [C.Dependency] a +type DependencyComponent a = C.CondBranch C.ConfVar C.Dependencies a exDbPkgs :: ExampleDb -> [ExamplePkgName] exDbPkgs = map (either exInstName exAvName) @@ -589,11 +608,11 @@ exAvSrcPkg ex = extractFlags deps = concatMap go (depsExampleDependencies deps) where go :: ExampleDependency -> [ExampleFlagName] - go (ExAny _) = [] - go (ExFix _ _) = [] - go (ExRange _ _ _) = [] - go (ExSubLibAny _ _) = [] - go (ExSubLibFix _ _ _) = [] + go (ExAnyD{}) = [] + go (ExFixD{}) = [] + go (ExRangeD{}) = [] + go (ExSubLibAnyD{}) = [] + go (ExSubLibFixD{}) = [] go (ExBuildToolAny _ _) = [] go (ExBuildToolFix _ _ _) = [] go (ExLegacyBuildToolAny _) = [] @@ -622,7 +641,8 @@ exAvSrcPkg ex = mkCondTree :: (C.LibraryVisibility -> C.BuildInfo -> a) -> Dependencies -> DependencyTree a mkCondTree mkComponent deps = let (libraryDeps, exts, mlang, pcpkgs, buildTools, legacyBuildTools) = splitTopLevel (depsExampleDependencies deps) - (directDeps, flaggedDeps) = splitDeps libraryDeps + (allDirectDeps, flaggedDeps) = splitDeps libraryDeps + (privateDeps, directDeps) = partition (\(_, _, _, is_private) -> isJust is_private) allDirectDeps component = mkComponent (depsVisibility deps) bi bi = mempty @@ -649,12 +669,20 @@ exAvSrcPkg ex = , -- TODO: Arguably, build-tools dependencies should also -- effect constraints on conditional tree. But no way to -- distinguish between them - C.condTreeConstraints = map mkDirect directDeps + C.condTreeConstraints = + mempty + { C.publicDependencies = map mkDirect directDeps + , C.privateDependencies = map mkDirectD privateDeps + } , C.condTreeComponents = map (mkFlagged mkComponent) flaggedDeps } - mkDirect :: (ExamplePkgName, C.LibraryName, C.VersionRange) -> C.Dependency - mkDirect (dep, name, vr) = C.Dependency (C.mkPackageName dep) vr (NonEmptySet.singleton name) + mkDirect :: (ExamplePkgName, C.LibraryName, C.VersionRange, Maybe ExamplePrivateAlias) -> C.Dependency + mkDirect (dep, name, vr, _) = C.Dependency (C.mkPackageName dep) vr (NonEmptySet.singleton name) + + mkDirectD :: (ExamplePkgName, C.LibraryName, C.VersionRange, Maybe ExamplePrivateAlias) -> C.PrivateDependency + mkDirectD (dep, name, vr, Just alias) = C.PrivateDependency (C.PrivateAlias (fromString alias)) [C.Dependency (C.mkPackageName dep) vr (NonEmptySet.singleton name)] + mkDirectD (_, _, _, Nothing) = error "mkDirectD: private deps are never Nothing since we partition them by 'isJust' above" mkFlagged :: (C.LibraryVisibility -> C.BuildInfo -> a) @@ -673,26 +701,26 @@ exAvSrcPkg ex = -- guarded by a flag. splitDeps :: [ExampleDependency] - -> ( [(ExamplePkgName, C.LibraryName, C.VersionRange)] + -> ( [(ExamplePkgName, C.LibraryName, C.VersionRange, Maybe ExamplePrivateAlias)] , [(ExampleFlagName, Dependencies, Dependencies)] ) splitDeps [] = ([], []) - splitDeps (ExAny p : deps) = + splitDeps (ExAnyD is_priv p : deps) = let (directDeps, flaggedDeps) = splitDeps deps - in ((p, C.LMainLibName, C.anyVersion) : directDeps, flaggedDeps) - splitDeps (ExFix p v : deps) = + in ((p, C.LMainLibName, C.anyVersion, is_priv) : directDeps, flaggedDeps) + splitDeps (ExFixD is_priv p v : deps) = let (directDeps, flaggedDeps) = splitDeps deps - in ((p, C.LMainLibName, C.thisVersion $ mkSimpleVersion v) : directDeps, flaggedDeps) - splitDeps (ExRange p v1 v2 : deps) = + in ((p, C.LMainLibName, C.thisVersion $ mkSimpleVersion v, is_priv) : directDeps, flaggedDeps) + splitDeps (ExRangeD is_priv p v1 v2 : deps) = let (directDeps, flaggedDeps) = splitDeps deps - in ((p, C.LMainLibName, mkVersionRange v1 v2) : directDeps, flaggedDeps) - splitDeps (ExSubLibAny p lib : deps) = + in ((p, C.LMainLibName, mkVersionRange v1 v2, is_priv) : directDeps, flaggedDeps) + splitDeps (ExSubLibAnyD is_priv p lib : deps) = let (directDeps, flaggedDeps) = splitDeps deps - in ((p, C.LSubLibName (C.mkUnqualComponentName lib), C.anyVersion) : directDeps, flaggedDeps) - splitDeps (ExSubLibFix p lib v : deps) = + in ((p, C.LSubLibName (C.mkUnqualComponentName lib), C.anyVersion, is_priv) : directDeps, flaggedDeps) + splitDeps (ExSubLibFixD is_priv p lib v : deps) = let (directDeps, flaggedDeps) = splitDeps deps - in ((p, C.LSubLibName (C.mkUnqualComponentName lib), C.thisVersion $ mkSimpleVersion v) : directDeps, flaggedDeps) + in ((p, C.LSubLibName (C.mkUnqualComponentName lib), C.thisVersion $ mkSimpleVersion v, is_priv) : directDeps, flaggedDeps) splitDeps (ExFlagged f a b : deps) = let (directDeps, flaggedDeps) = splitDeps deps in (directDeps, (f, a, b) : flaggedDeps) @@ -702,7 +730,10 @@ exAvSrcPkg ex = mkSetupDeps :: [ExampleDependency] -> [C.Dependency] mkSetupDeps deps = case splitDeps deps of - (directDeps, []) -> map mkDirect directDeps + (directDeps, []) -> + if any (\(_, _, _, p) -> isJust p) directDeps + then error "mkSetupDeps: custom setup has private deps" + else map mkDirect directDeps _ -> error "mkSetupDeps: custom setup has non-simple deps" -- Check for `UnknownLanguages` and `UnknownExtensions`. See @@ -844,7 +875,7 @@ exResolve fmap ( \p -> PackageConstraint - (scopeToplevel (C.mkPackageName p)) + (ScopeAnyQualifier (C.mkPackageName p)) (PackagePropertyStanzas [TestStanzas]) ) (exDbPkgs db) diff --git a/cabal-install/tests/UnitTests/Distribution/Solver/Modular/DSL/TestCaseUtils.hs b/cabal-install/tests/UnitTests/Distribution/Solver/Modular/DSL/TestCaseUtils.hs index 91ec541f976..6bec16ea5e1 100644 --- a/cabal-install/tests/UnitTests/Distribution/Solver/Modular/DSL/TestCaseUtils.hs +++ b/cabal-install/tests/UnitTests/Distribution/Solver/Modular/DSL/TestCaseUtils.hs @@ -18,6 +18,7 @@ module UnitTests.Distribution.Solver.Modular.DSL.TestCaseUtils , preferences , setVerbose , enableAllTests + , solverResult , solverSuccess , solverFailure , anySolverFailure @@ -46,6 +47,7 @@ import Language.Haskell.Extension (Extension (..), Language (..)) -- cabal-install import Distribution.Client.Dependency (foldProgress) +import qualified Distribution.Solver.Types.ComponentDeps as C import qualified Distribution.Solver.Types.PackagePath as P import Distribution.Solver.Types.PkgConfigDb (PkgConfigDb (..), pkgConfigDbFromList) import Distribution.Solver.Types.Settings @@ -144,6 +146,9 @@ data SolverResult = SolverResult -- the given plan. } +solverResult :: ([String] -> Bool) -> [(String, Int)] -> SolverResult +solverResult slog r = SolverResult slog (Right r) + solverSuccess :: [(String, Int)] -> SolverResult solverSuccess = SolverResult (const True) . Right @@ -314,13 +319,9 @@ runTest SolverTest{..} = askOption $ \(OptionShowSolverLog showSolverLog) -> P.QualToplevel QualSetup s -> P.PackagePath - P.DefaultNamespace - (P.QualSetup (C.mkPackageName s)) - QualIndepSetup p s -> - P.PackagePath - (P.Independent $ C.mkPackageName p) - (P.QualSetup (C.mkPackageName s)) + (P.IndependentComponent (C.mkPackageName s) C.ComponentSetup) + (P.QualToplevel) QualExe p1 p2 -> P.PackagePath - P.DefaultNamespace - (P.QualExe (C.mkPackageName p1) (C.mkPackageName p2)) + (P.IndependentBuildTool (C.mkPackageName p1) (C.mkPackageName p2)) + P.QualToplevel diff --git a/cabal-install/tests/UnitTests/Distribution/Solver/Modular/QuickCheck.hs b/cabal-install/tests/UnitTests/Distribution/Solver/Modular/QuickCheck.hs index 114db775f21..7fcd6107ddf 100644 --- a/cabal-install/tests/UnitTests/Distribution/Solver/Modular/QuickCheck.hs +++ b/cabal-install/tests/UnitTests/Distribution/Solver/Modular/QuickCheck.hs @@ -24,6 +24,8 @@ import Distribution.Utils.ShortText (ShortText) import Distribution.Client.Setup (defaultMaxBackjumps) +import Distribution.ModuleName +import Distribution.Types.Dependency (PrivateAlias (..)) import Distribution.Types.LibraryVisibility import Distribution.Types.PackageName import Distribution.Types.UnqualComponentName @@ -34,6 +36,7 @@ import Distribution.Solver.Types.ComponentDeps , ComponentDeps ) import qualified Distribution.Solver.Types.ComponentDeps as CD +import qualified Distribution.Solver.Types.ComponentDeps as P import Distribution.Solver.Types.OptionalStanza import Distribution.Solver.Types.PackageConstraint import qualified Distribution.Solver.Types.PackagePath as P @@ -75,7 +78,8 @@ tests = ReverseOrder -> reverse targets in counterexample (showResults r1 r2) $ noneReachedBackjumpLimit [r1, r2] ==> - isRight (resultPlan r1) === isRight (resultPlan r2) + isRight (resultPlan r1) + === isRight (resultPlan r2) , testPropertyWithSeed "solvable without --independent-goals => solvable with --independent-goals" $ \test reorderGoals -> @@ -92,7 +96,8 @@ tests = Nothing in counterexample (showResults r1 r2) $ noneReachedBackjumpLimit [r1, r2] ==> - isRight (resultPlan r1) `implies` isRight (resultPlan r2) + isRight (resultPlan r1) + `implies` isRight (resultPlan r2) , testPropertyWithSeed "backjumping does not affect solvability" $ \test reorderGoals indepGoals -> let r1 = solve' (EnableBackjumping True) test @@ -108,7 +113,8 @@ tests = Nothing in counterexample (showResults r1 r2) $ noneReachedBackjumpLimit [r1, r2] ==> - isRight (resultPlan r1) === isRight (resultPlan r2) + isRight (resultPlan r1) + === isRight (resultPlan r2) , testPropertyWithSeed "fine-grained conflicts does not affect solvability" $ \test reorderGoals indepGoals -> let r1 = solve' (FineGrainedConflicts True) test @@ -124,7 +130,8 @@ tests = Nothing in counterexample (showResults r1 r2) $ noneReachedBackjumpLimit [r1, r2] ==> - isRight (resultPlan r1) === isRight (resultPlan r2) + isRight (resultPlan r1) + === isRight (resultPlan r2) , testPropertyWithSeed "prefer oldest does not affect solvability" $ \test reorderGoals indepGoals -> let r1 = solve' (PreferOldest True) test @@ -140,7 +147,8 @@ tests = Nothing in counterexample (showResults r1 r2) $ noneReachedBackjumpLimit [r1, r2] ==> - isRight (resultPlan r1) === isRight (resultPlan r2) + isRight (resultPlan r1) + === isRight (resultPlan r2) , -- The next two tests use --no-count-conflicts, because the goal order used -- with --count-conflicts depends on the total set of conflicts seen by the -- solver. The solver explores more of the tree and encounters more @@ -165,7 +173,8 @@ tests = Nothing in counterexample (showResults r1 r2) $ noneReachedBackjumpLimit [r1, r2] ==> - resultPlan r1 === resultPlan r2 + resultPlan r1 + === resultPlan r2 , testPropertyWithSeed "fine-grained conflicts does not affect the result (with static goal order)" $ \test reorderGoals indepGoals -> @@ -182,7 +191,8 @@ tests = Nothing in counterexample (showResults r1 r2) $ noneReachedBackjumpLimit [r1, r2] ==> - resultPlan r1 === resultPlan r2 + resultPlan r1 + === resultPlan r2 ] where noneReachedBackjumpLimit :: [Result] -> Bool @@ -612,10 +622,14 @@ instance Hashable a => Hashable (P.Qualified a) instance Hashable P.PackagePath instance Hashable P.Qualifier instance Hashable P.Namespace +instance Hashable P.Component +instance Hashable UnqualComponentName instance Hashable OptionalStanza instance Hashable FlagName instance Hashable PackageName instance Hashable ShortText +instance Hashable ModuleName +instance Hashable PrivateAlias deriving instance Generic (Variable pn) deriving instance Generic (P.Qualified a) diff --git a/cabal-install/tests/UnitTests/Distribution/Solver/Modular/Solver.hs b/cabal-install/tests/UnitTests/Distribution/Solver/Modular/Solver.hs index a1f5eed3c62..b555df8b3c3 100644 --- a/cabal-install/tests/UnitTests/Distribution/Solver/Modular/Solver.hs +++ b/cabal-install/tests/UnitTests/Distribution/Solver/Modular/Solver.hs @@ -1,3 +1,4 @@ +{-# LANGUAGE BlockArguments #-} {-# LANGUAGE OverloadedStrings #-} -- | This is a set of unit tests for the dependency solver, @@ -7,10 +8,15 @@ module UnitTests.Distribution.Solver.Modular.Solver (tests) where -- base + +import Control.Monad import Data.List (isInfixOf) import qualified Distribution.Version as V +-- mtl +import Control.Monad.State + -- test-framework import Test.Tasty as TF import Test.Tasty.ExpectedFailure @@ -23,6 +29,9 @@ import Language.Haskell.Extension ) -- cabal-install + +import Data.Bifunctor +import qualified Distribution.Solver.Types.ComponentDeps as P import Distribution.Solver.Types.Flag import Distribution.Solver.Types.OptionalStanza import Distribution.Solver.Types.PackageConstraint @@ -92,7 +101,7 @@ tests = , testGroup "Qualified manual flag constraints" [ let name = "Top-level flag constraint does not constrain setup dep's flag" - cs = [ExFlagConstraint (ScopeQualified P.QualToplevel "B") "flag" False] + cs = [ExFlagConstraint (ScopeQualified P.DefaultNamespace P.QualToplevel "B") "flag" False] in runTest $ constraints cs $ mkTest dbSetupDepWithManualFlag name ["A"] $ @@ -105,7 +114,7 @@ tests = ] , let name = "Solver can toggle setup dep's flag to match top-level constraint" cs = - [ ExFlagConstraint (ScopeQualified P.QualToplevel "B") "flag" False + [ ExFlagConstraint (ScopeQualified P.DefaultNamespace P.QualToplevel "B") "flag" False , ExVersionConstraint (ScopeAnyQualifier "b-2-true-dep") V.noVersion ] in runTest $ @@ -120,8 +129,8 @@ tests = ] , let name = "User can constrain flags separately with qualified constraints" cs = - [ ExFlagConstraint (ScopeQualified P.QualToplevel "B") "flag" True - , ExFlagConstraint (ScopeQualified (P.QualSetup "A") "B") "flag" False + [ ExFlagConstraint (ScopeQualified P.DefaultNamespace P.QualToplevel "B") "flag" True + , ExFlagConstraint (ScopeQualified (P.IndependentComponent "A" P.ComponentSetup) P.QualToplevel "B") "flag" False ] in runTest $ constraints cs $ @@ -135,15 +144,15 @@ tests = ] , -- Regression test for #4299 let name = "Solver can link deps when only one has constrained manual flag" - cs = [ExFlagConstraint (ScopeQualified P.QualToplevel "B") "flag" False] + cs = [ExFlagConstraint (ScopeQualified P.DefaultNamespace P.QualToplevel "B") "flag" False] in runTest $ constraints cs $ mkTest dbLinkedSetupDepWithManualFlag name ["A"] $ solverSuccess [("A", 1), ("B", 1), ("b-1-false-dep", 1)] , let name = "Solver cannot link deps that have conflicting manual flag constraints" cs = - [ ExFlagConstraint (ScopeQualified P.QualToplevel "B") "flag" True - , ExFlagConstraint (ScopeQualified (P.QualSetup "A") "B") "flag" False + [ ExFlagConstraint (ScopeQualified P.DefaultNamespace P.QualToplevel "B") "flag" True + , ExFlagConstraint (ScopeQualified (P.IndependentComponent "A" P.ComponentSetup) P.QualToplevel "B") "flag" False ] failureReason = "(constraint from unknown source requires opposite flag selection)" checkFullLog lns = @@ -279,8 +288,8 @@ tests = mkTest dbConstraints "force older versions with unqualified constraint" ["A", "B", "C"] $ solverSuccess [("A", 1), ("B", 2), ("C", 3), ("D", 1), ("D", 2), ("D", 3)] , let cs = - [ ExVersionConstraint (ScopeQualified P.QualToplevel "D") $ mkVersionRange 1 4 - , ExVersionConstraint (ScopeQualified (P.QualSetup "B") "D") $ mkVersionRange 4 7 + [ ExVersionConstraint (ScopeQualified P.DefaultNamespace P.QualToplevel "D") $ mkVersionRange 1 4 + , ExVersionConstraint (ScopeQualified (P.IndependentComponent "B" P.ComponentSetup) P.QualToplevel "D") $ mkVersionRange 4 7 ] in runTest $ constraints cs $ @@ -363,7 +372,7 @@ tests = , runTest $ testIndepGoals5 "indepGoals5 - default goal order" DefaultGoalOrder , runTest $ testIndepGoals6 "indepGoals6 - fixed goal order" FixedGoalOrder , runTest $ testIndepGoals6 "indepGoals6 - default goal order" DefaultGoalOrder - , expectFailBecause "#9466" $ runTest $ testIndepGoals7 "indepGoals7" + , runTest $ testIndepGoals7 "indepGoals7" , runTest $ testIndepGoals8 "indepGoals8" ] , -- Tests designed for the backjumping blog post @@ -517,6 +526,7 @@ tests = ++ "[__1] rejecting: H:bt-pkg:exe.bt-pkg-2.0.0 (conflict: H => H:bt-pkg:exe.bt-pkg (exe exe1)==3.0.0)" , runTest $ chooseExeAfterBuildToolsPackage True "choose exe after choosing its package - success" , runTest $ chooseExeAfterBuildToolsPackage False "choose exe after choosing its package - failure" + , runTest $ needTwoBuildToolPkgVersions "needs two build-tool-pkg versions" , runTest $ rejectInstalledBuildToolPackage "reject installed package for build-tool dependency" , runTest $ requireConsistentBuildToolVersions "build tool versions must be consistent within one package" ] @@ -859,6 +869,29 @@ tests = SolverResult (isInfixOf msg) $ Right [("A", 1), ("B", 1)] ] + , testGroup + "Private dependencies" + [ runTest privDep1 + , runTest privDep2 + , runTest privDep3 + , runTest privDep4 + , runTest privDep5 + , runTest privDep6 + , runTest privDep7 + , runTest privDep7a + , runTest privDep8 + , runTest privDep8a + , runTest privDep9 + , runTest privDep10 + , runTest privDep11 + , runTest privDep12 + , runTest privDep13 + , runTest privDep14 + , runTest privDep15 + -- These tests should only be run manually! (Not enabled by default) + -- , runTest $ _manualPrivDepsStressTest True + -- , runTest $ _manualPrivDepsStressTestWithBacktracking True + ] , -- Tests for the contents of the solver's log testGroup "Solver log" @@ -2366,6 +2399,20 @@ dbBuildTools = , Right $ exAv "bt-pkg" 1 [] ] +needTwoBuildToolPkgVersions :: String -> SolverTest +needTwoBuildToolPkgVersions name = setVerbose $ mkTest db name ["A"] (solverSuccess [("A", 1), ("build-tool-pkg", 1), ("build-tool-pkg", 2)]) + where + db :: ExampleDb + db = + [ Right $ exAv "build-tool-pkg" 1 [] `withExe` exExe "build-tool-exe" [] + , Right $ exAv "build-tool-pkg" 2 [] `withExe` exExe "build-tool-exe" [] + , Right $ + exAvNoLibrary "A" 1 + `withExe` exExe + "my-exe" + [ExFix "build-tool-pkg" 1, ExBuildToolFix "build-tool-pkg" "build-tool-exe" 2] + ] + -- The solver should never choose an installed package for a build tool -- dependency. rejectInstalledBuildToolPackage :: String -> SolverTest @@ -2583,6 +2630,313 @@ setupStanzaTest2 = ["A"] (solverFailure ("unknown package: A:setup.C (dependency of A:setup.B *test)" `isInfixOf`)) +-- +-- Private Dependency tests + +-- Test 1: A and B can choose different versions of C because C is a private dependency of A +priv_db1 :: ExampleDb +priv_db1 = + [ Left $ exInst "C" 1 "C-1" [] + , Left $ exInst "C" 2 "C-2" [] + , Right $ exAv "A" 1 [ExFixPriv "G0" "C" 1] + , Right $ exAv "B" 1 [ExFix "C" 2] + , Right $ exAv "D" 1 [ExAny "A", ExAny "B"] + ] + +privDep1 :: SolverTest +privDep1 = setVerbose $ mkTest priv_db1 "private-dependencies-1" ["D"] (solverSuccess [("A", 1), ("B", 1), ("D", 1)]) + +-- Test 2: A depends on both C publically and privately, directly +priv_db2 :: ExampleDb +priv_db2 = + [ Left $ exInst "C" 1 "C-1" [] + , Right $ exAv "A" 1 [ExFix "C" 1, ExFixPriv "G0" "C" 1] + ] + +privDep2 :: SolverTest +privDep2 = setVerbose $ mkTest priv_db2 "private-dependencies-2" ["A"] (solverSuccess [("A", 1)]) + +-- Test 3: A depends on both C publically and privately, transitively +priv_db3 :: ExampleDb +priv_db3 = + [ Left $ exInst "C" 1 "C-1" [] + , Right $ exAv "D" 1 [ExFix "C" 1] + , Right $ exAv "A" 1 [ExFix "D" 1, ExFixPriv "G0" "C" 1] + ] + +privDep3 :: SolverTest +privDep3 = setVerbose $ mkTest priv_db3 "private-dependencies-3" ["A"] (solverSuccess [("A", 1), ("D", 1)]) + +-- Test 4: Private dependency do not apply transitively, so we fail because the +-- version of E must match +priv_db4 :: ExampleDb +priv_db4 = + [ Left $ exInst "E" 1 "E-1" [] + , Left $ exInst "E" 2 "E-2" [] + , Right $ exAv "C" 1 [ExFix "E" 1] + , Right $ exAv "C" 2 [ExFix "E" 2] + , Right $ exAv "A" 1 [ExFixPriv "G0" "C" 1] + , Right $ exAv "B" 1 [ExFix "C" 2] + , Right $ exAv "D" 1 [ExAny "A", ExAny "B"] + ] + +privDep4 :: SolverTest +privDep4 = setVerbose $ mkTest priv_db4 "private-dependencies-4" ["D"] (solverFailure ("(conflict: E==2.0.0/installed-2, A:G0.C => E==1.0.0)" `isInfixOf`)) + +-- Test 5: Private dependencies and setup dependencies can choose different versions + +priv_db5 :: ExampleDb +priv_db5 = + [ Left $ exInst "E" 1 "E-1" [] + , Left $ exInst "E" 2 "E-2" [] + , Right $ exAv "A" 1 [ExFixPriv "G0" "E" 1] `withSetupDeps` [ExFix "E" 2] + ] + +privDep5 :: SolverTest +privDep5 = setVerbose $ mkTest priv_db5 "private-dependencies-5" ["A"] (solverSuccess [("A", 1)]) + +-- Private scope, with two dependencies +priv_db6 :: ExampleDb +priv_db6 = + let f1 = exInst "F" 1 "F-1" [] + f2 = exInst "F" 2 "F-2" [] + in [ Left $ exInst "E" 1 "E-1" [f1] + , Left $ exInst "E" 2 "E-2" [f2] + , Left f1 + , Left f2 + , Right $ exAv "A" 1 [ExFix "E" 2, ExFixPriv "G0" "E" 1, ExAnyPriv "G0" "F"] + ] + +privDep6 :: SolverTest +privDep6 = setVerbose $ mkTest priv_db6 "private-dependencies-6" ["A"] (solverSuccess [("A", 1)]) + +-- A dependency structure which violates the closure property for private dependency scopes +priv_db7 :: ExampleDb +priv_db7 = + [ Right $ exAv "A" 1 [ExAny "B"] + , Right $ exAv "B" 1 [ExAny "C"] + , Right $ exAv "C" 1 [] + , Right $ exAv "P" 1 [ExFixPriv "G0" "A" 1, ExAnyPriv "G0" "C"] + ] + +privDep7 :: SolverTest +privDep7 = setVerbose $ mkTest priv_db7 "private-dependencies-7" ["P"] (solverFailure ("a private scope must contain its closure, but package B is not included in the private scope P:G0" `isInfixOf`)) + +-- Closure property with external deps +priv_db7a :: ExampleDb +priv_db7a = + let a = exInst "A" 1 "A-1" [b] + b = exInst "B" 1 "B-1" [c] + c = exInst "C" 1 "C-1" [] + in [ Left a + , Left b + , Left c + , Right $ exAv "P" 1 [ExFixPriv "G0" "A" 1, ExAnyPriv "G0" "C"] + ] + +privDep7a :: SolverTest +privDep7a = setVerbose $ mkTest priv_db7a "private-dependencies-7a" ["P"] (solverFailure ("a private scope must contain its closure, but package B is not included in the private scope P:G0" `isInfixOf`)) + +priv_db8 :: ExampleDb +priv_db8 = + [ Right $ exAv "A" 1 [ExAny "B"] + , Right $ exAv "B" 1 [ExAny "C"] + , Right $ exAv "C" 1 [] + , Right $ exAv "P" 1 [ExFixPriv "G0" "A" 1, ExAnyPriv "G0" "B", ExAnyPriv "G0" "C"] + ] + +privDep8 :: SolverTest +privDep8 = setVerbose $ mkTest priv_db8 "private-dependencies-8" ["P"] (solverSuccess [("A", 1), ("B", 1), ("C", 1), ("P", 1)]) + +priv_db8a :: ExampleDb +priv_db8a = + let a = exInst "A" 1 "A-1" [b] + b = exInst "B" 1 "B-1" [c] + c = exInst "C" 1 "C-1" [] + in [ Left a + , Left b + , Left c + , Right $ exAv "P" 1 [ExFixPriv "G0" "A" 1, ExAnyPriv "G0" "B", ExAnyPriv "G0" "C"] + ] + +privDep8a :: SolverTest +privDep8a = setVerbose $ mkTest priv_db8a "private-dependencies-8a" ["P"] (solverSuccess [("P", 1)]) + +-- Two different private scopes can have two different versions +priv_db9 :: ExampleDb +priv_db9 = + let a = exInst "A" 1 "A-1" [] + b = exInst "A" 2 "A-2" [] + in [ Left a + , Left b + , Right $ exAv "P" 1 [ExFixPriv "G0" "A" 1, ExFixPriv "G1" "A" 2] + ] + +privDep9 :: SolverTest +privDep9 = setVerbose $ mkTest priv_db9 "private-dependencies-9" ["P"] (solverSuccess [("P", 1)]) + +-- Backtrack when closure property is violated +priv_db10 :: ExampleDb +priv_db10 = + let a2 = exInst "A" 2 "A-2" [b] + a1 = exInst "A" 1 "A-1" [] + b = exInst "B" 1 "B-1" [c] + c = exInst "C" 1 "C-1" [] + in [ Left a1 + , Left a2 + , Left b + , Left c + , Right $ exAv "P" 1 [ExAnyPriv "G0" "A", ExAnyPriv "G0" "C"] + ] + +privDep10 :: SolverTest +privDep10 = + setVerbose $ + mkTest + priv_db10 + "private-dependencies-10" + ["P"] + (solverResult (any ("a private scope must contain its closure, but package B is not included in the private scope P:G0" `isInfixOf`)) [("P", 1)]) + +-- Testing constraints DON'T apply to private dependencies +priv_db11 :: ExampleDb +priv_db11 = + [ Left (exInst "A" 1 "A-1" []) + , Right $ exAv "P" 1 [ExAnyPriv "G0" "A"] + ] + +privDep11 :: SolverTest +privDep11 = + setVerbose $ + constraints [ExVersionConstraint (ScopeQualified P.DefaultNamespace P.QualToplevel "A") (V.thisVersion (V.mkVersion [2]))] $ + mkTest priv_db11 "private-dependencies-11" ["P"] (solverSuccess [("P", 1)]) + +-- Testing suitably scoped constraints do apply to private dependencies +privDep12 :: SolverTest +privDep12 = + setVerbose $ + constraints [ExVersionConstraint (ScopeQualified P.DefaultNamespace (P.QualAlias "P" "G0") "A") (V.thisVersion (V.mkVersion [2]))] $ + mkTest priv_db11 "private-dependencies-12" ["P"] (solverFailure ("constraint from unknown source requires ==2" `isInfixOf`)) + +-- Testing that `any` qualifier applies to private deps +privDep13 :: SolverTest +privDep13 = + setVerbose $ + constraints [ExVersionConstraint (ScopeAnyQualifier "A") (V.thisVersion (V.mkVersion [2]))] $ + mkTest priv_db11 "private-dependencies-13" ["P"] (solverFailure ("constraint from unknown source requires ==2" `isInfixOf`)) + +-- Testing nested private scopes +priv_db14 :: ExampleDb +priv_db14 = + priv_db6 -- uses A depends on E, F pkg names. + ++ [ Left $ exInst "B" 1 "B-1" [] + , Right $ exAv "P" 1 [ExAnyPriv "G0" "A", ExAnyPriv "G0" "B"] + ] + +privDep14 :: SolverTest +privDep14 = + setVerbose $ + mkTest priv_db14 "private-dependencies-14" ["P"] (solverSuccess [("A", 1), ("P", 1)]) + +-- Testing nested private scopes, where outer private scope includes deps of nested private scope. +priv_db15 :: ExampleDb +priv_db15 = + let f1 = exInst "F" 1 "F-1" [] + f2 = exInst "F" 2 "F-2" [] + in [ Left $ exInst "E" 1 "E-1" [f1] + , Left $ exInst "E" 2 "E-2" [f2] + , Left f1 + , Left f2 + , Right $ exAv "A" 1 [ExFix "E" 2, ExFixPriv "G0" "E" 1, ExAnyPriv "G0" "F"] + , Right $ exAv "P" 1 [ExAnyPriv "G0" "A", ExAnyPriv "G0" "E"] + ] + +privDep15 :: SolverTest +privDep15 = + setVerbose $ + mkTest priv_db15 "private-dependencies-15" ["P"] (solverSuccess [("A", 1), ("P", 1)]) + +uniqPkgName :: State Int String +uniqPkgName = do + i <- get + modify' (+ 1) + return ("pkgN" ++ show i) +uniqScope :: State Int String +uniqScope = do + i <- get + modify' (+ 1) + return ("S" ++ show i) + +-- The stress test for private dependencies without backtracking +manual_priv_stress + :: Bool + -- ^ Use private scopes? + -> ExampleDb +manual_priv_stress usePrivScopes = (`evalState` 1) do + (deps, depsOfDeps) <- bimap concat concat . unzip <$> forM [1 .. param] (const $ mkPkg param) + return ([Right $ exAv "P" 1 $ map (ExAny . exAvName) deps] ++ map Right (deps ++ depsOfDeps)) + where + param :: Int + param = 6 + + mkPkg :: Int -> State Int ([ExampleAvailable], [ExampleAvailable]) + mkPkg 0 = return ([], []) + mkPkg i = do + (depPkgs, depsOfDeps) <- bimap concat concat . unzip <$> forM [1 .. param] (const $ mkPkg (i - 1)) + deps <- + concat <$> forM (zip depPkgs [(1 :: Int) ..]) \(p, ix) -> + if even ix && usePrivScopes + then do + sc <- uniqScope + return [ExAnyPriv sc (exAvName p)] + else return [ExAny (exAvName p)] -- note, no backtracking so no constraints. + pkgid <- uniqPkgName + return ([exAv pkgid 1 deps], (depPkgs ++ depsOfDeps)) + +-- The stress test for private dependencies with backtracking +manual_priv_stress_with_bt + :: Bool + -- ^ Use private scopes? + -> ExampleDb +manual_priv_stress_with_bt usePrivScopes = (`evalState` 1) do + (deps, depsOfDeps) <- bimap concat concat . unzip <$> forM [1 .. param] (const $ mkPkg param) + return ([Right $ exAv "P" 1 $ map (ExAny . exAvName) deps] ++ map Right (deps ++ depsOfDeps)) + where + param :: Int + param = 5 + + mkPkg :: Int -> State Int ([ExampleAvailable], [ExampleAvailable]) + mkPkg 0 = return ([], []) + mkPkg i = do + (depPkgs, depsOfDeps) <- bimap concat concat . unzip <$> forM [1 .. param] (const $ mkPkg (i - 1)) + let nn n = + concat <$> forM (zip depPkgs [(1 :: Int) ..]) \(p, ix) -> + let ver = if ix `mod` n == 0 then 1 else 2 + in if even ix && usePrivScopes + then do + sc <- uniqScope + return [ExFixPriv sc (exAvName p) ver] + else return [ExFix (exAvName p) ver] + deps <- nn 13 + deps' <- nn 14 + pkgid <- uniqPkgName + return ([exAv pkgid 1 deps, exAv pkgid 2 deps'], (depPkgs ++ depsOfDeps)) + +-- | This is a stress test of private dependencies which should be manually +-- enabled for local testing, but not enabled in CI. +_manualPrivDepsStressTest :: Bool -> SolverTest +_manualPrivDepsStressTest b = + setVerbose $ + mkTest (manual_priv_stress b) "manual-private-dependencies-stress-test" ["P"] (solverSuccess [("P", 1)]) + +-- | This is a stress test of private dependencies which should be manually +-- enabled for local testing, but not enabled in CI. +-- It is quite hard to provoke backtracking in a procedural test, but here's an attempt. +_manualPrivDepsStressTestWithBacktracking :: Bool -> SolverTest +_manualPrivDepsStressTestWithBacktracking b = + setVerbose $ + mkTest (manual_priv_stress_with_bt b) "manual-private-dependencies-stress-test-backtrack" ["P"] (solverSuccess [("P", 1)]) + -- | Returns true if the second list contains all elements of the first list, in -- order. containsInOrder :: Eq a => [a] -> [a] -> Bool diff --git a/cabal-testsuite/PackageTests/PrivateDeps/cabal-hooks-demo/README.md b/cabal-testsuite/PackageTests/PrivateDeps/cabal-hooks-demo/README.md new file mode 100644 index 00000000000..bc40cd6f9a5 --- /dev/null +++ b/cabal-testsuite/PackageTests/PrivateDeps/cabal-hooks-demo/README.md @@ -0,0 +1,10 @@ +Proof of concept for Cabal hooks compatability scheme, which tests private +dependencies + +* `lib01` - The library which defines the hooks interface, which can have different versions. + +* `main-prog` - A program written against the `lib01` interface, but needs to work with multiple versions. + +* `hooks-exe` - The executable which can be compiled against multiple versions of `lib01`. + +* `hooks-lib` - A compability library which depends on all versions of lib01 which are supported and provides conversions between the new and old datatypes. diff --git a/cabal-testsuite/PackageTests/PrivateDeps/cabal-hooks-demo/cabal.project b/cabal-testsuite/PackageTests/PrivateDeps/cabal-hooks-demo/cabal.project new file mode 100644 index 00000000000..e25e053a3c0 --- /dev/null +++ b/cabal-testsuite/PackageTests/PrivateDeps/cabal-hooks-demo/cabal.project @@ -0,0 +1 @@ +packages: hooks-exe hooks-lib main-prog diff --git a/cabal-testsuite/PackageTests/PrivateDeps/cabal-hooks-demo/cabal.test.hs b/cabal-testsuite/PackageTests/PrivateDeps/cabal-hooks-demo/cabal.test.hs new file mode 100644 index 00000000000..de74350e18a --- /dev/null +++ b/cabal-testsuite/PackageTests/PrivateDeps/cabal-hooks-demo/cabal.test.hs @@ -0,0 +1,20 @@ +import Test.Cabal.Prelude + +main = + cabalTest $ recordMode DoNotRecord $ + withProjectFile "cabal.project" $ + withRepo "repo" $ do + cabal "build" ["exe:hooks-exe", "--constraint=private.hooks-exe.L01:lib01 == 0.1.0.0"] + exePath <- withPlan $ planExePath "hooks-exe" "hooks-exe" + out1 <- cabal' "run" ["exe:main-prog", "--", exePath] + + assertOutputContains "0.1.0.0" out1 + assertOutputContains "hooks_show: A" out1 + assertOutputContains "hooks_inc: B" out1 + + cabal "build" ["exe:hooks-exe", "--constraint=private.hooks-exe.L01:lib01 == 0.2.0.0"] + out2 <- cabal' "run" ["exe:main-prog", "--", exePath] + + assertOutputContains "0.2.0.0" out2 + assertOutputContains "hooks_show: A {value = 5}" out2 + assertOutputContains "hooks_inc: B" out2 diff --git a/cabal-testsuite/PackageTests/PrivateDeps/cabal-hooks-demo/hooks-exe/CHANGELOG.md b/cabal-testsuite/PackageTests/PrivateDeps/cabal-hooks-demo/hooks-exe/CHANGELOG.md new file mode 100644 index 00000000000..ae45e4d0b14 --- /dev/null +++ b/cabal-testsuite/PackageTests/PrivateDeps/cabal-hooks-demo/hooks-exe/CHANGELOG.md @@ -0,0 +1,5 @@ +# Revision history for hooks-exe + +## 0.1.0.0 -- YYYY-mm-dd + +* First version. Released on an unsuspecting world. diff --git a/cabal-testsuite/PackageTests/PrivateDeps/cabal-hooks-demo/hooks-exe/app/Main.hs b/cabal-testsuite/PackageTests/PrivateDeps/cabal-hooks-demo/hooks-exe/app/Main.hs new file mode 100644 index 00000000000..38dc9f85525 --- /dev/null +++ b/cabal-testsuite/PackageTests/PrivateDeps/cabal-hooks-demo/hooks-exe/app/Main.hs @@ -0,0 +1,35 @@ +{-# LANGUAGE ScopedTypeVariables #-} +{-# LANGUAGE OverloadedStrings #-} +{-# LANGUAGE CPP #-} +module Main where + +import System.Environment + +import Prelude hiding (getContents, putStr, hPutStr) +import Data.ByteString.Lazy (getContents, putStr, hPutStr) +import System.Environment (getArgs) +import System.IO (stderr, hPrint) +import Data.String +import Data.Binary +import L01.Lib + +-- | Create an executable which accepts the name of a hook as the argument, +-- then reads arguments to the hook over stdin and writes the results of the hook +-- to stdout. +main :: IO () +main = do + [hookName] <- getArgs + case hookName of + "version" -> do + putStr $ encode (VERSION_lib01 :: String) + "show" -> do + s <- getContents + let a1 :: A = decode s + res = show a1 + putStr (encode res) + "inc" -> do + s <- getContents + let a1 :: A = decode s + res = inc a1 + putStr (encode res) + _ -> error "Hook not yet implemented" diff --git a/cabal-testsuite/PackageTests/PrivateDeps/cabal-hooks-demo/hooks-exe/hooks-exe.cabal b/cabal-testsuite/PackageTests/PrivateDeps/cabal-hooks-demo/hooks-exe/hooks-exe.cabal new file mode 100644 index 00000000000..b03865b863a --- /dev/null +++ b/cabal-testsuite/PackageTests/PrivateDeps/cabal-hooks-demo/hooks-exe/hooks-exe.cabal @@ -0,0 +1,19 @@ +cabal-version: 3.0 +name: hooks-exe +version: 0.1.0.0 +license: NONE +author: matthewtpickering@gmail.com +maintainer: Matthew Pickering +build-type: Simple +extra-doc-files: CHANGELOG.md + +common warnings + ghc-options: -Wall + +executable hooks-exe + import: warnings + main-is: Main.hs + build-depends: base, bytestring, binary, directory + private-build-depends: L01 with (lib01) + hs-source-dirs: app + default-language: Haskell2010 diff --git a/cabal-testsuite/PackageTests/PrivateDeps/cabal-hooks-demo/hooks-lib/CHANGELOG.md b/cabal-testsuite/PackageTests/PrivateDeps/cabal-hooks-demo/hooks-lib/CHANGELOG.md new file mode 100644 index 00000000000..85a864adeca --- /dev/null +++ b/cabal-testsuite/PackageTests/PrivateDeps/cabal-hooks-demo/hooks-lib/CHANGELOG.md @@ -0,0 +1,5 @@ +# Revision history for hooks-lib + +## 0.1.0.0 -- YYYY-mm-dd + +* First version. Released on an unsuspecting world. diff --git a/cabal-testsuite/PackageTests/PrivateDeps/cabal-hooks-demo/hooks-lib/hooks-lib.cabal b/cabal-testsuite/PackageTests/PrivateDeps/cabal-hooks-demo/hooks-lib/hooks-lib.cabal new file mode 100644 index 00000000000..bb5efe62961 --- /dev/null +++ b/cabal-testsuite/PackageTests/PrivateDeps/cabal-hooks-demo/hooks-lib/hooks-lib.cabal @@ -0,0 +1,20 @@ +cabal-version: 3.0 +name: hooks-lib +version: 0.1.0.0 +license: NONE +author: matthewtpickering@gmail.com +maintainer: Matthew Pickering +build-type: Simple +extra-doc-files: CHANGELOG.md + +common warnings + ghc-options: -Wall + +library + import: warnings + exposed-modules: HooksLib + build-depends: base, lib01 == 0.2.0.0, mtl, process, binary, bytestring, deepseq + private-build-depends: V01 with (lib01 == 0.1.0.0), V02 with (lib01 == 0.2.0.0) + hs-source-dirs: src + default-language: Haskell2010 + diff --git a/cabal-testsuite/PackageTests/PrivateDeps/cabal-hooks-demo/hooks-lib/src/HooksLib.hs b/cabal-testsuite/PackageTests/PrivateDeps/cabal-hooks-demo/hooks-lib/src/HooksLib.hs new file mode 100644 index 00000000000..aae813b46f5 --- /dev/null +++ b/cabal-testsuite/PackageTests/PrivateDeps/cabal-hooks-demo/hooks-lib/src/HooksLib.hs @@ -0,0 +1,133 @@ +{-# LANGUAGE PackageImports #-} +{-# LANGUAGE ScopedTypeVariables #-} +{-# LANGUAGE LambdaCase #-} +{-# LANGUAGE OverloadedStrings #-} +module HooksLib where + +import Control.Monad.Reader + +import V01.Lib as L1 +import V02.Lib as L2 +import "lib01" Lib as L + +import System.IO (stderr) +import System.Process +import Control.Exception as C +import Data.Binary +import Control.Concurrent +import GHC.IO.Handle (BufferMode(..), hClose, hSetBuffering) +import Control.Concurrent.MVar +import Control.Concurrent +import qualified Control.Exception as C +import Data.ByteString.Lazy (hPutStr, hGetContents) +import qualified Data.ByteString.Char8 as C8 +import Control.DeepSeq +import GHC.IO.Exception as GHC +import Foreign.C.Error + +data SupportedVersion = V01 | V02 + +--import Lib as LX + +data HooksEnv = HooksEnv { hooksExe :: FilePath, hooksVersion :: SupportedVersion } + +type HooksM a = ReaderT HooksEnv IO a + +version :: FilePath -> IO (Maybe SupportedVersion) +version fp = do + (ver :: String) <- readHooksExe_ fp "version" () + print ver + return $ case C8.split '.' (C8.pack ver) of + ["0","1","0","0"] -> Just V01 + ["0","2","0","0"] -> Just V02 + _ -> Nothing + +withHooksExe :: FilePath -> HooksM a -> IO a +withHooksExe prog action = do + ver <- version prog + case ver of + Just sver -> runReaderT action (HooksEnv prog sver) + Nothing -> error "Hooks executable is unsupported version" + +convertA1 :: L.A -> L1.A +convertA1 (L.A {}) = L1.A +convertA1 (L.B) = L1.B + +convertA2 :: L.A -> L2.A +convertA2 (L.A x) = (L2.A x) +convertA2 L.B = L2.B + +revertA1 :: L1.A -> L.A +revertA1 L1.A = L.A 0 +revertA1 L1.B = L.B + +revertA2 :: L2.A -> L.A +revertA2 (L2.A x) = L.A x +revertA2 L2.B = L.B + + +hooks_show :: L.A -> HooksM String +hooks_show a = do + ver <- asks hooksVersion + case ver of + V01 -> readHooksExe "show" (convertA1 a) + V02 -> readHooksExe "show" (convertA2 a) + +hooks_inc :: L.A -> HooksM L.A +hooks_inc a = do + ver <- asks hooksVersion + case ver of + V01 -> revertA1 <$> (readHooksExe "inc" (convertA1 a)) + V02 -> revertA2 <$> (readHooksExe "inc" (convertA2 a)) + + + + +-- Library funcs + + +readHooksExe :: (Binary a, Binary b) => String -> a -> HooksM b +readHooksExe hook args = do + exe <- asks hooksExe + liftIO $ readHooksExe_ exe hook args + +withForkWait :: IO () -> (IO () -> IO a) -> IO a +withForkWait async body = do + waitVar <- newEmptyMVar :: IO (MVar (Either SomeException ())) + mask $ \restore -> do + tid <- forkIO $ try (restore async) >>= putMVar waitVar + let wait = takeMVar waitVar >>= either throwIO return + restore (body wait) `C.onException` killThread tid + +readHooksExe_ :: (Binary a, Binary b) => FilePath -> String -> a -> IO b +readHooksExe_ exe hook args = + let stdin_ = encode args + cp = (proc exe [hook]) { std_in = CreatePipe + , std_out = CreatePipe } + in withCreateProcess cp $ \(Just inh) (Just outh) Nothing ph -> do + -- fork off a thread to start consuming the output + hSetBuffering inh NoBuffering + hSetBuffering outh NoBuffering + output <- hGetContents outh + withForkWait (C.evaluate $ rnf output) $ \waitOut -> do + + hPutStr inh stdin_ + -- hClose performs implicit hFlush, and thus may trigger a SIGPIPE + ignoreSigPipe $ hClose inh + + -- wait on the output + waitOut + hClose outh + + -- wait on the process + _ex <- waitForProcess ph + return (decode output) + + + +-- | Ignore SIGPIPE in a subcomputation. +ignoreSigPipe :: IO () -> IO () +ignoreSigPipe = C.handle $ \case + GHC.IOError{GHC.ioe_type = GHC.ResourceVanished, GHC.ioe_errno = Just ioe} + | Errno ioe == ePIPE -> return () + e -> throwIO e diff --git a/cabal-testsuite/PackageTests/PrivateDeps/cabal-hooks-demo/hooks-lib/src/MyLib.hs b/cabal-testsuite/PackageTests/PrivateDeps/cabal-hooks-demo/hooks-lib/src/MyLib.hs new file mode 100644 index 00000000000..e657c4403f6 --- /dev/null +++ b/cabal-testsuite/PackageTests/PrivateDeps/cabal-hooks-demo/hooks-lib/src/MyLib.hs @@ -0,0 +1,4 @@ +module MyLib (someFunc) where + +someFunc :: IO () +someFunc = putStrLn "someFunc" diff --git a/cabal-testsuite/PackageTests/PrivateDeps/cabal-hooks-demo/main-prog/CHANGELOG.md b/cabal-testsuite/PackageTests/PrivateDeps/cabal-hooks-demo/main-prog/CHANGELOG.md new file mode 100644 index 00000000000..6b7696f9f1e --- /dev/null +++ b/cabal-testsuite/PackageTests/PrivateDeps/cabal-hooks-demo/main-prog/CHANGELOG.md @@ -0,0 +1,5 @@ +# Revision history for main-prog + +## 0.1.0.0 -- YYYY-mm-dd + +* First version. Released on an unsuspecting world. diff --git a/cabal-testsuite/PackageTests/PrivateDeps/cabal-hooks-demo/main-prog/app/Main.hs b/cabal-testsuite/PackageTests/PrivateDeps/cabal-hooks-demo/main-prog/app/Main.hs new file mode 100644 index 00000000000..8cd9037f565 --- /dev/null +++ b/cabal-testsuite/PackageTests/PrivateDeps/cabal-hooks-demo/main-prog/app/Main.hs @@ -0,0 +1,21 @@ +-- This is linked directly against lib, but can communicate with older versions of +-- lib via the hooks executable. +module Main where + +import System.Directory +import Lib +import HooksLib +import Control.Monad.IO.Class +import System.Environment + +main :: IO () +main = do + -- Receive the path to the hooks_exe as an argument + [hooks_exe] <- getArgs + withHooksExe hooks_exe $ do + liftIO $ putStr "hooks_show: " + rendered <- hooks_show (A 5) + liftIO $ putStrLn rendered + liftIO $ putStr "hooks_inc: " + a' <- hooks_inc (A 5) + liftIO $ print a' diff --git a/cabal-testsuite/PackageTests/PrivateDeps/cabal-hooks-demo/main-prog/main-prog.cabal b/cabal-testsuite/PackageTests/PrivateDeps/cabal-hooks-demo/main-prog/main-prog.cabal new file mode 100644 index 00000000000..56f5ddfa5e5 --- /dev/null +++ b/cabal-testsuite/PackageTests/PrivateDeps/cabal-hooks-demo/main-prog/main-prog.cabal @@ -0,0 +1,18 @@ +cabal-version: 3.0 +name: main-prog +version: 0.1.0.0 +license: NONE +author: matthewtpickering@gmail.com +maintainer: Matthew Pickering +build-type: Simple +extra-doc-files: CHANGELOG.md + +common warnings + ghc-options: -Wall + +executable main-prog + import: warnings + main-is: Main.hs + build-depends: base, lib01, directory, hooks-lib + hs-source-dirs: app + default-language: Haskell2010 diff --git a/cabal-testsuite/PackageTests/PrivateDeps/cabal-hooks-demo/repo/lib01-0.1.0.0/CHANGELOG.md b/cabal-testsuite/PackageTests/PrivateDeps/cabal-hooks-demo/repo/lib01-0.1.0.0/CHANGELOG.md new file mode 100644 index 00000000000..6a8c7fe311e --- /dev/null +++ b/cabal-testsuite/PackageTests/PrivateDeps/cabal-hooks-demo/repo/lib01-0.1.0.0/CHANGELOG.md @@ -0,0 +1,5 @@ +# Revision history for lib01 + +## 0.1.0.0 -- YYYY-mm-dd + +* First version. Released on an unsuspecting world. diff --git a/cabal-testsuite/PackageTests/PrivateDeps/cabal-hooks-demo/repo/lib01-0.1.0.0/lib01.cabal b/cabal-testsuite/PackageTests/PrivateDeps/cabal-hooks-demo/repo/lib01-0.1.0.0/lib01.cabal new file mode 100644 index 00000000000..1fc1ad750b9 --- /dev/null +++ b/cabal-testsuite/PackageTests/PrivateDeps/cabal-hooks-demo/repo/lib01-0.1.0.0/lib01.cabal @@ -0,0 +1,18 @@ +cabal-version: 3.0 +name: lib01 +version: 0.1.0.0 +license: NONE +author: matthewtpickering@gmail.com +maintainer: Matthew Pickering +build-type: Simple +extra-doc-files: CHANGELOG.md + +common warnings + ghc-options: -Wall + +library + import: warnings + exposed-modules: Lib + build-depends: base, binary + hs-source-dirs: src + default-language: Haskell2010 diff --git a/cabal-testsuite/PackageTests/PrivateDeps/cabal-hooks-demo/repo/lib01-0.1.0.0/src/Lib.hs b/cabal-testsuite/PackageTests/PrivateDeps/cabal-hooks-demo/repo/lib01-0.1.0.0/src/Lib.hs new file mode 100644 index 00000000000..5c3bf43eabc --- /dev/null +++ b/cabal-testsuite/PackageTests/PrivateDeps/cabal-hooks-demo/repo/lib01-0.1.0.0/src/Lib.hs @@ -0,0 +1,16 @@ +{-# LANGUAGE DeriveGeneric #-} +{-# LANGUAGE StandaloneDeriving #-} +{-# LANGUAGE DeriveAnyClass #-} +module Lib(A(..), inc) where + +import Data.Binary +import GHC.Generics + +data A = A | B deriving (Show, Generic) + +deriving instance Binary A + +inc :: A -> A +inc A = B +inc B = B + diff --git a/cabal-testsuite/PackageTests/PrivateDeps/cabal-hooks-demo/repo/lib01-0.2.0.0/CHANGELOG.md b/cabal-testsuite/PackageTests/PrivateDeps/cabal-hooks-demo/repo/lib01-0.2.0.0/CHANGELOG.md new file mode 100644 index 00000000000..6a8c7fe311e --- /dev/null +++ b/cabal-testsuite/PackageTests/PrivateDeps/cabal-hooks-demo/repo/lib01-0.2.0.0/CHANGELOG.md @@ -0,0 +1,5 @@ +# Revision history for lib01 + +## 0.1.0.0 -- YYYY-mm-dd + +* First version. Released on an unsuspecting world. diff --git a/cabal-testsuite/PackageTests/PrivateDeps/cabal-hooks-demo/repo/lib01-0.2.0.0/lib01.cabal b/cabal-testsuite/PackageTests/PrivateDeps/cabal-hooks-demo/repo/lib01-0.2.0.0/lib01.cabal new file mode 100644 index 00000000000..da908f3f043 --- /dev/null +++ b/cabal-testsuite/PackageTests/PrivateDeps/cabal-hooks-demo/repo/lib01-0.2.0.0/lib01.cabal @@ -0,0 +1,18 @@ +cabal-version: 3.0 +name: lib01 +version: 0.2.0.0 +license: NONE +author: matthewtpickering@gmail.com +maintainer: Matthew Pickering +build-type: Simple +extra-doc-files: CHANGELOG.md + +common warnings + ghc-options: -Wall + +library + import: warnings + exposed-modules: Lib + build-depends: base, binary + hs-source-dirs: src + default-language: Haskell2010 diff --git a/cabal-testsuite/PackageTests/PrivateDeps/cabal-hooks-demo/repo/lib01-0.2.0.0/src/Lib.hs b/cabal-testsuite/PackageTests/PrivateDeps/cabal-hooks-demo/repo/lib01-0.2.0.0/src/Lib.hs new file mode 100644 index 00000000000..24ce215cd70 --- /dev/null +++ b/cabal-testsuite/PackageTests/PrivateDeps/cabal-hooks-demo/repo/lib01-0.2.0.0/src/Lib.hs @@ -0,0 +1,16 @@ +{-# LANGUAGE DeriveGeneric #-} +{-# LANGUAGE StandaloneDeriving #-} +{-# LANGUAGE DeriveAnyClass #-} +module Lib(A(..), inc) where + +import Data.Binary +import GHC.Generics + +data A = A { value :: Int } | B deriving (Show, Generic) + +deriving instance Binary A + +inc :: A -> A +inc (A {}) = B +inc B = B + diff --git a/cabal-testsuite/PackageTests/PrivateDeps/closure-property-long-chain/cabal.project b/cabal-testsuite/PackageTests/PrivateDeps/closure-property-long-chain/cabal.project new file mode 100644 index 00000000000..fb834e2c61d --- /dev/null +++ b/cabal-testsuite/PackageTests/PrivateDeps/closure-property-long-chain/cabal.project @@ -0,0 +1 @@ +packages: libA, libB, libC, libD, libE, libH diff --git a/cabal-testsuite/PackageTests/PrivateDeps/closure-property-long-chain/cabal.test.hs b/cabal-testsuite/PackageTests/PrivateDeps/closure-property-long-chain/cabal.test.hs new file mode 100644 index 00000000000..10020c453df --- /dev/null +++ b/cabal-testsuite/PackageTests/PrivateDeps/closure-property-long-chain/cabal.test.hs @@ -0,0 +1,8 @@ +import Test.Cabal.Prelude + +main = do + cabalTest $ recordMode DoNotRecord $ do + + -- Will violate closure property + fails (cabal' "v2-build" ["libA"]) + >>= assertOutputContains "a private scope must contain its closure, but packages libC, libD, libE are not included in the private scope libA:P0" diff --git a/cabal-testsuite/PackageTests/PrivateDeps/closure-property-long-chain/libA/libA.cabal b/cabal-testsuite/PackageTests/PrivateDeps/closure-property-long-chain/libA/libA.cabal new file mode 100644 index 00000000000..e628757e45c --- /dev/null +++ b/cabal-testsuite/PackageTests/PrivateDeps/closure-property-long-chain/libA/libA.cabal @@ -0,0 +1,12 @@ +cabal-version: 3.0 +name: libA +version: 0.1.0.0 +license: NONE +build-type: Simple + +library + exposed-modules: MyLib + build-depends: base + private-build-depends: P0 with (libB, libH) + hs-source-dirs: src + default-language: Haskell2010 diff --git a/cabal-testsuite/PackageTests/PrivateDeps/closure-property-long-chain/libA/src/MyLib.hs b/cabal-testsuite/PackageTests/PrivateDeps/closure-property-long-chain/libA/src/MyLib.hs new file mode 100644 index 00000000000..e657c4403f6 --- /dev/null +++ b/cabal-testsuite/PackageTests/PrivateDeps/closure-property-long-chain/libA/src/MyLib.hs @@ -0,0 +1,4 @@ +module MyLib (someFunc) where + +someFunc :: IO () +someFunc = putStrLn "someFunc" diff --git a/cabal-testsuite/PackageTests/PrivateDeps/closure-property-long-chain/libB/libB.cabal b/cabal-testsuite/PackageTests/PrivateDeps/closure-property-long-chain/libB/libB.cabal new file mode 100644 index 00000000000..7d2d6377c14 --- /dev/null +++ b/cabal-testsuite/PackageTests/PrivateDeps/closure-property-long-chain/libB/libB.cabal @@ -0,0 +1,11 @@ +cabal-version: 3.0 +name: libB +version: 0.1.0.0 +license: NONE +build-type: Simple + +library + exposed-modules: MyLib + build-depends: base, libC + hs-source-dirs: src + default-language: Haskell2010 diff --git a/cabal-testsuite/PackageTests/PrivateDeps/closure-property-long-chain/libB/src/MyLib.hs b/cabal-testsuite/PackageTests/PrivateDeps/closure-property-long-chain/libB/src/MyLib.hs new file mode 100644 index 00000000000..e657c4403f6 --- /dev/null +++ b/cabal-testsuite/PackageTests/PrivateDeps/closure-property-long-chain/libB/src/MyLib.hs @@ -0,0 +1,4 @@ +module MyLib (someFunc) where + +someFunc :: IO () +someFunc = putStrLn "someFunc" diff --git a/cabal-testsuite/PackageTests/PrivateDeps/closure-property-long-chain/libC/libC.cabal b/cabal-testsuite/PackageTests/PrivateDeps/closure-property-long-chain/libC/libC.cabal new file mode 100644 index 00000000000..af91892fbff --- /dev/null +++ b/cabal-testsuite/PackageTests/PrivateDeps/closure-property-long-chain/libC/libC.cabal @@ -0,0 +1,11 @@ +cabal-version: 3.0 +name: libC +version: 0.1.0.0 +license: NONE +build-type: Simple + +library + exposed-modules: MyLib + build-depends: base, libD + hs-source-dirs: src + default-language: Haskell2010 diff --git a/cabal-testsuite/PackageTests/PrivateDeps/closure-property-long-chain/libC/src/MyLib.hs b/cabal-testsuite/PackageTests/PrivateDeps/closure-property-long-chain/libC/src/MyLib.hs new file mode 100644 index 00000000000..e657c4403f6 --- /dev/null +++ b/cabal-testsuite/PackageTests/PrivateDeps/closure-property-long-chain/libC/src/MyLib.hs @@ -0,0 +1,4 @@ +module MyLib (someFunc) where + +someFunc :: IO () +someFunc = putStrLn "someFunc" diff --git a/cabal-testsuite/PackageTests/PrivateDeps/closure-property-long-chain/libD/libD.cabal b/cabal-testsuite/PackageTests/PrivateDeps/closure-property-long-chain/libD/libD.cabal new file mode 100644 index 00000000000..00db1977e99 --- /dev/null +++ b/cabal-testsuite/PackageTests/PrivateDeps/closure-property-long-chain/libD/libD.cabal @@ -0,0 +1,11 @@ +cabal-version: 3.0 +name: libD +version: 0.1.0.0 +license: NONE +build-type: Simple + +library + exposed-modules: MyLib + build-depends: base, libE + hs-source-dirs: src + default-language: Haskell2010 diff --git a/cabal-testsuite/PackageTests/PrivateDeps/closure-property-long-chain/libD/src/MyLib.hs b/cabal-testsuite/PackageTests/PrivateDeps/closure-property-long-chain/libD/src/MyLib.hs new file mode 100644 index 00000000000..e657c4403f6 --- /dev/null +++ b/cabal-testsuite/PackageTests/PrivateDeps/closure-property-long-chain/libD/src/MyLib.hs @@ -0,0 +1,4 @@ +module MyLib (someFunc) where + +someFunc :: IO () +someFunc = putStrLn "someFunc" diff --git a/cabal-testsuite/PackageTests/PrivateDeps/closure-property-long-chain/libE/libE.cabal b/cabal-testsuite/PackageTests/PrivateDeps/closure-property-long-chain/libE/libE.cabal new file mode 100644 index 00000000000..d1409af1997 --- /dev/null +++ b/cabal-testsuite/PackageTests/PrivateDeps/closure-property-long-chain/libE/libE.cabal @@ -0,0 +1,11 @@ +cabal-version: 3.0 +name: libE +version: 0.1.0.0 +license: NONE +build-type: Simple + +library + exposed-modules: MyLib + build-depends: base, libH + hs-source-dirs: src + default-language: Haskell2010 diff --git a/cabal-testsuite/PackageTests/PrivateDeps/closure-property-long-chain/libE/src/MyLib.hs b/cabal-testsuite/PackageTests/PrivateDeps/closure-property-long-chain/libE/src/MyLib.hs new file mode 100644 index 00000000000..e657c4403f6 --- /dev/null +++ b/cabal-testsuite/PackageTests/PrivateDeps/closure-property-long-chain/libE/src/MyLib.hs @@ -0,0 +1,4 @@ +module MyLib (someFunc) where + +someFunc :: IO () +someFunc = putStrLn "someFunc" diff --git a/cabal-testsuite/PackageTests/PrivateDeps/closure-property-long-chain/libH/libH.cabal b/cabal-testsuite/PackageTests/PrivateDeps/closure-property-long-chain/libH/libH.cabal new file mode 100644 index 00000000000..6f4daa3351f --- /dev/null +++ b/cabal-testsuite/PackageTests/PrivateDeps/closure-property-long-chain/libH/libH.cabal @@ -0,0 +1,11 @@ +cabal-version: 3.0 +name: libH +version: 0.1.0.0 +license: NONE +build-type: Simple + +library + exposed-modules: MyLib + build-depends: base + hs-source-dirs: src + default-language: Haskell2010 diff --git a/cabal-testsuite/PackageTests/PrivateDeps/closure-property-long-chain/libH/src/MyLib.hs b/cabal-testsuite/PackageTests/PrivateDeps/closure-property-long-chain/libH/src/MyLib.hs new file mode 100644 index 00000000000..e657c4403f6 --- /dev/null +++ b/cabal-testsuite/PackageTests/PrivateDeps/closure-property-long-chain/libH/src/MyLib.hs @@ -0,0 +1,4 @@ +module MyLib (someFunc) where + +someFunc :: IO () +someFunc = putStrLn "someFunc" diff --git a/cabal-testsuite/PackageTests/PrivateDeps/closure-property-test/README.md b/cabal-testsuite/PackageTests/PrivateDeps/closure-property-test/README.md new file mode 100644 index 00000000000..573957a03fa --- /dev/null +++ b/cabal-testsuite/PackageTests/PrivateDeps/closure-property-test/README.md @@ -0,0 +1,30 @@ +Closure property test + +package a-0.1 + :private-build-depends: G0 with (b, d) + +package a-0.2 + :build-depends: c + :private-build-depends: G0 with (b, d) + +package b-0.1 + :build-depends: x + +package b-0.2 + :build-depends: x, d + +package b-0.3 + :build-depends: x, c, d + +package c-0.1 + :build-depends: x + +package c-0.2 + :build-depends: x, d + + +Closure property violated by `b == 0.3` and `c == 0.2` THEN closure property is violated. + +Need to be able to implicitly introduce c into the private scope so that the closure property holds. +Or otherwise pick an older version of C which does not depend on D + diff --git a/cabal-testsuite/PackageTests/PrivateDeps/closure-property-test/cabal.project.1 b/cabal-testsuite/PackageTests/PrivateDeps/closure-property-test/cabal.project.1 new file mode 100644 index 00000000000..1d6fdeb5c43 --- /dev/null +++ b/cabal-testsuite/PackageTests/PrivateDeps/closure-property-test/cabal.project.1 @@ -0,0 +1 @@ +packages: libA-0.1.0.0 diff --git a/cabal-testsuite/PackageTests/PrivateDeps/closure-property-test/cabal.project.2 b/cabal-testsuite/PackageTests/PrivateDeps/closure-property-test/cabal.project.2 new file mode 100644 index 00000000000..6a6ab0dcb42 --- /dev/null +++ b/cabal-testsuite/PackageTests/PrivateDeps/closure-property-test/cabal.project.2 @@ -0,0 +1 @@ +packages: libA-0.2.0.0 diff --git a/cabal-testsuite/PackageTests/PrivateDeps/closure-property-test/cabal.project.3 b/cabal-testsuite/PackageTests/PrivateDeps/closure-property-test/cabal.project.3 new file mode 100644 index 00000000000..50ad944ca45 --- /dev/null +++ b/cabal-testsuite/PackageTests/PrivateDeps/closure-property-test/cabal.project.3 @@ -0,0 +1 @@ +packages: libA-0.3.0.0 diff --git a/cabal-testsuite/PackageTests/PrivateDeps/closure-property-test/cabal.project.4 b/cabal-testsuite/PackageTests/PrivateDeps/closure-property-test/cabal.project.4 new file mode 100644 index 00000000000..a62ce97ac49 --- /dev/null +++ b/cabal-testsuite/PackageTests/PrivateDeps/closure-property-test/cabal.project.4 @@ -0,0 +1 @@ +packages: libA-0.4.0.0 diff --git a/cabal-testsuite/PackageTests/PrivateDeps/closure-property-test/cabal.test.hs b/cabal-testsuite/PackageTests/PrivateDeps/closure-property-test/cabal.test.hs new file mode 100644 index 00000000000..409e47a3174 --- /dev/null +++ b/cabal-testsuite/PackageTests/PrivateDeps/closure-property-test/cabal.test.hs @@ -0,0 +1,29 @@ +import Test.Cabal.Prelude + +main = do + cabalTest $ recordMode DoNotRecord $ do + + -- Will violate closure property + withProjectFile "cabal.project.1" $ + withRepo "repo" $ + fails (cabal' "v2-build" ["libA"]) + >>= assertOutputContains "a private scope must contain its closure, but package libC is not included in the private scope libA:G0" + + -- Must pick libC == 0.1 + withProjectFile "cabal.project.2" $ + withRepo "repo" $ + cabal' "v2-build" ["libA"] + >>= assertOutputContains "libC-0.1.0.0" + + -- Shouldn't pick libB == 0.3 because it violates closure property + withProjectFile "cabal.project.3" $ + withRepo "repo" $ + cabal' "v2-build" ["libA"] + >>= assertOutputDoesNotContain "libB-0.3.0.0" + + -- Will be OKay with libB == 0.3 and libC == 0.2 because libC is in the closure + withProjectFile "cabal.project.4" $ + withRepo "repo" $ do + o <- cabal' "v2-build" ["libA"] + assertOutputContains "libC-0.2.0.0" o + assertOutputContains "libB-0.3.0.0" o diff --git a/cabal-testsuite/PackageTests/PrivateDeps/closure-property-test/libA-0.1.0.0/MyLib.hs b/cabal-testsuite/PackageTests/PrivateDeps/closure-property-test/libA-0.1.0.0/MyLib.hs new file mode 100644 index 00000000000..dc2cb96275e --- /dev/null +++ b/cabal-testsuite/PackageTests/PrivateDeps/closure-property-test/libA-0.1.0.0/MyLib.hs @@ -0,0 +1,3 @@ +module MyLib (someFunc) where + +someFunc = "" diff --git a/cabal-testsuite/PackageTests/PrivateDeps/closure-property-test/libA-0.1.0.0/libA.cabal b/cabal-testsuite/PackageTests/PrivateDeps/closure-property-test/libA-0.1.0.0/libA.cabal new file mode 100644 index 00000000000..f92995fdacf --- /dev/null +++ b/cabal-testsuite/PackageTests/PrivateDeps/closure-property-test/libA-0.1.0.0/libA.cabal @@ -0,0 +1,13 @@ +cabal-version: 3.0 +name: libA +version: 0.1.0.0 +license: NONE +build-type: Simple + +library + exposed-modules: MyLib + -- Will violate closure property + private-build-depends: G0 with (libB == 0.1.0.0,libD) + hs-source-dirs: . + default-language: Haskell2010 + default-extensions: NoImplicitPrelude diff --git a/cabal-testsuite/PackageTests/PrivateDeps/closure-property-test/libA-0.2.0.0/MyLib.hs b/cabal-testsuite/PackageTests/PrivateDeps/closure-property-test/libA-0.2.0.0/MyLib.hs new file mode 100644 index 00000000000..6c63822a95f --- /dev/null +++ b/cabal-testsuite/PackageTests/PrivateDeps/closure-property-test/libA-0.2.0.0/MyLib.hs @@ -0,0 +1,3 @@ +module MyLib (someFunc) where + +someFunc = "someFunc" diff --git a/cabal-testsuite/PackageTests/PrivateDeps/closure-property-test/libA-0.2.0.0/libA.cabal b/cabal-testsuite/PackageTests/PrivateDeps/closure-property-test/libA-0.2.0.0/libA.cabal new file mode 100644 index 00000000000..56bdf19a058 --- /dev/null +++ b/cabal-testsuite/PackageTests/PrivateDeps/closure-property-test/libA-0.2.0.0/libA.cabal @@ -0,0 +1,14 @@ +cabal-version: 3.0 +name: libA +version: 0.2.0.0 +license: NONE +build-type: Simple + +library + exposed-modules: MyLib + build-depends: libC + -- Must pick libC == 0.1 + private-build-depends: G0 with (libB == 0.2.0.0,libD) + hs-source-dirs: . + default-language: Haskell2010 + default-extensions: NoImplicitPrelude diff --git a/cabal-testsuite/PackageTests/PrivateDeps/closure-property-test/libA-0.3.0.0/MyLib.hs b/cabal-testsuite/PackageTests/PrivateDeps/closure-property-test/libA-0.3.0.0/MyLib.hs new file mode 100644 index 00000000000..6c63822a95f --- /dev/null +++ b/cabal-testsuite/PackageTests/PrivateDeps/closure-property-test/libA-0.3.0.0/MyLib.hs @@ -0,0 +1,3 @@ +module MyLib (someFunc) where + +someFunc = "someFunc" diff --git a/cabal-testsuite/PackageTests/PrivateDeps/closure-property-test/libA-0.3.0.0/libA.cabal b/cabal-testsuite/PackageTests/PrivateDeps/closure-property-test/libA-0.3.0.0/libA.cabal new file mode 100644 index 00000000000..90f84cd5a36 --- /dev/null +++ b/cabal-testsuite/PackageTests/PrivateDeps/closure-property-test/libA-0.3.0.0/libA.cabal @@ -0,0 +1,14 @@ +cabal-version: 3.0 +name: libA +version: 0.3.0.0 +license: NONE +build-type: Simple + +library + exposed-modules: MyLib + build-depends: libC + -- Shouldn't pick libB == 0.3 because it violates closure property + private-build-depends: G0 with (libB,libD) + hs-source-dirs: . + default-language: Haskell2010 + default-extensions: NoImplicitPrelude diff --git a/cabal-testsuite/PackageTests/PrivateDeps/closure-property-test/libA-0.4.0.0/MyLib.hs b/cabal-testsuite/PackageTests/PrivateDeps/closure-property-test/libA-0.4.0.0/MyLib.hs new file mode 100644 index 00000000000..6c63822a95f --- /dev/null +++ b/cabal-testsuite/PackageTests/PrivateDeps/closure-property-test/libA-0.4.0.0/MyLib.hs @@ -0,0 +1,3 @@ +module MyLib (someFunc) where + +someFunc = "someFunc" diff --git a/cabal-testsuite/PackageTests/PrivateDeps/closure-property-test/libA-0.4.0.0/libA.cabal b/cabal-testsuite/PackageTests/PrivateDeps/closure-property-test/libA-0.4.0.0/libA.cabal new file mode 100644 index 00000000000..ec556d108ac --- /dev/null +++ b/cabal-testsuite/PackageTests/PrivateDeps/closure-property-test/libA-0.4.0.0/libA.cabal @@ -0,0 +1,13 @@ +cabal-version: 3.0 +name: libA +version: 0.4.0.0 +license: NONE +build-type: Simple + +library + exposed-modules: MyLib + -- Will be OKay with libB == 0.3 and libC == 0.2 because libC is in the closure + private-build-depends: G0 with (libB == 0.3.0.0, libC, libD) + hs-source-dirs: . + default-language: Haskell2010 + default-extensions: NoImplicitPrelude diff --git a/cabal-testsuite/PackageTests/PrivateDeps/closure-property-test/repo/libB-0.1.0.0/MyLib.hs b/cabal-testsuite/PackageTests/PrivateDeps/closure-property-test/repo/libB-0.1.0.0/MyLib.hs new file mode 100644 index 00000000000..6c63822a95f --- /dev/null +++ b/cabal-testsuite/PackageTests/PrivateDeps/closure-property-test/repo/libB-0.1.0.0/MyLib.hs @@ -0,0 +1,3 @@ +module MyLib (someFunc) where + +someFunc = "someFunc" diff --git a/cabal-testsuite/PackageTests/PrivateDeps/closure-property-test/repo/libB-0.1.0.0/libB.cabal b/cabal-testsuite/PackageTests/PrivateDeps/closure-property-test/repo/libB-0.1.0.0/libB.cabal new file mode 100644 index 00000000000..0b368f60db2 --- /dev/null +++ b/cabal-testsuite/PackageTests/PrivateDeps/closure-property-test/repo/libB-0.1.0.0/libB.cabal @@ -0,0 +1,12 @@ +cabal-version: 3.0 +name: libB +version: 0.1.0.0 +license: NONE +build-type: Simple + +library + exposed-modules: MyLib + build-depends: libC == 0.2.0.0 + hs-source-dirs: . + default-language: Haskell2010 + default-extensions: NoImplicitPrelude diff --git a/cabal-testsuite/PackageTests/PrivateDeps/closure-property-test/repo/libB-0.2.0.0/MyLib.hs b/cabal-testsuite/PackageTests/PrivateDeps/closure-property-test/repo/libB-0.2.0.0/MyLib.hs new file mode 100644 index 00000000000..6c63822a95f --- /dev/null +++ b/cabal-testsuite/PackageTests/PrivateDeps/closure-property-test/repo/libB-0.2.0.0/MyLib.hs @@ -0,0 +1,3 @@ +module MyLib (someFunc) where + +someFunc = "someFunc" diff --git a/cabal-testsuite/PackageTests/PrivateDeps/closure-property-test/repo/libB-0.2.0.0/libB.cabal b/cabal-testsuite/PackageTests/PrivateDeps/closure-property-test/repo/libB-0.2.0.0/libB.cabal new file mode 100644 index 00000000000..010de751424 --- /dev/null +++ b/cabal-testsuite/PackageTests/PrivateDeps/closure-property-test/repo/libB-0.2.0.0/libB.cabal @@ -0,0 +1,12 @@ +cabal-version: 3.0 +name: libB +version: 0.2.0.0 +license: NONE +build-type: Simple + +library + exposed-modules: MyLib + build-depends: libC + hs-source-dirs: . + default-language: Haskell2010 + default-extensions: NoImplicitPrelude diff --git a/cabal-testsuite/PackageTests/PrivateDeps/closure-property-test/repo/libB-0.3.0.0/MyLib.hs b/cabal-testsuite/PackageTests/PrivateDeps/closure-property-test/repo/libB-0.3.0.0/MyLib.hs new file mode 100644 index 00000000000..6c63822a95f --- /dev/null +++ b/cabal-testsuite/PackageTests/PrivateDeps/closure-property-test/repo/libB-0.3.0.0/MyLib.hs @@ -0,0 +1,3 @@ +module MyLib (someFunc) where + +someFunc = "someFunc" diff --git a/cabal-testsuite/PackageTests/PrivateDeps/closure-property-test/repo/libB-0.3.0.0/libB.cabal b/cabal-testsuite/PackageTests/PrivateDeps/closure-property-test/repo/libB-0.3.0.0/libB.cabal new file mode 100644 index 00000000000..cb0ff52869e --- /dev/null +++ b/cabal-testsuite/PackageTests/PrivateDeps/closure-property-test/repo/libB-0.3.0.0/libB.cabal @@ -0,0 +1,12 @@ +cabal-version: 3.0 +name: libB +version: 0.3.0.0 +license: NONE +build-type: Simple + +library + exposed-modules: MyLib + build-depends: libC == 0.2.0.0, libD + hs-source-dirs: . + default-language: Haskell2010 + default-extensions: NoImplicitPrelude diff --git a/cabal-testsuite/PackageTests/PrivateDeps/closure-property-test/repo/libC-0.1.0.0/MyLib.hs b/cabal-testsuite/PackageTests/PrivateDeps/closure-property-test/repo/libC-0.1.0.0/MyLib.hs new file mode 100644 index 00000000000..6c63822a95f --- /dev/null +++ b/cabal-testsuite/PackageTests/PrivateDeps/closure-property-test/repo/libC-0.1.0.0/MyLib.hs @@ -0,0 +1,3 @@ +module MyLib (someFunc) where + +someFunc = "someFunc" diff --git a/cabal-testsuite/PackageTests/PrivateDeps/closure-property-test/repo/libC-0.1.0.0/libC.cabal b/cabal-testsuite/PackageTests/PrivateDeps/closure-property-test/repo/libC-0.1.0.0/libC.cabal new file mode 100644 index 00000000000..abb9ae3482a --- /dev/null +++ b/cabal-testsuite/PackageTests/PrivateDeps/closure-property-test/repo/libC-0.1.0.0/libC.cabal @@ -0,0 +1,11 @@ +cabal-version: 3.0 +name: libC +version: 0.1.0.0 +license: NONE +build-type: Simple + +library + exposed-modules: MyLib + hs-source-dirs: . + default-language: Haskell2010 + default-extensions: NoImplicitPrelude diff --git a/cabal-testsuite/PackageTests/PrivateDeps/closure-property-test/repo/libC-0.2.0.0/MyLib.hs b/cabal-testsuite/PackageTests/PrivateDeps/closure-property-test/repo/libC-0.2.0.0/MyLib.hs new file mode 100644 index 00000000000..6c63822a95f --- /dev/null +++ b/cabal-testsuite/PackageTests/PrivateDeps/closure-property-test/repo/libC-0.2.0.0/MyLib.hs @@ -0,0 +1,3 @@ +module MyLib (someFunc) where + +someFunc = "someFunc" diff --git a/cabal-testsuite/PackageTests/PrivateDeps/closure-property-test/repo/libC-0.2.0.0/libC.cabal b/cabal-testsuite/PackageTests/PrivateDeps/closure-property-test/repo/libC-0.2.0.0/libC.cabal new file mode 100644 index 00000000000..3dd472acc3a --- /dev/null +++ b/cabal-testsuite/PackageTests/PrivateDeps/closure-property-test/repo/libC-0.2.0.0/libC.cabal @@ -0,0 +1,12 @@ +cabal-version: 3.0 +name: libC +version: 0.2.0.0 +license: NONE +build-type: Simple + +library + exposed-modules: MyLib + build-depends: libD + hs-source-dirs: . + default-language: Haskell2010 + default-extensions: NoImplicitPrelude diff --git a/cabal-testsuite/PackageTests/PrivateDeps/closure-property-test/repo/libD-0.1.0.0/MyLib.hs b/cabal-testsuite/PackageTests/PrivateDeps/closure-property-test/repo/libD-0.1.0.0/MyLib.hs new file mode 100644 index 00000000000..6c63822a95f --- /dev/null +++ b/cabal-testsuite/PackageTests/PrivateDeps/closure-property-test/repo/libD-0.1.0.0/MyLib.hs @@ -0,0 +1,3 @@ +module MyLib (someFunc) where + +someFunc = "someFunc" diff --git a/cabal-testsuite/PackageTests/PrivateDeps/closure-property-test/repo/libD-0.1.0.0/libD.cabal b/cabal-testsuite/PackageTests/PrivateDeps/closure-property-test/repo/libD-0.1.0.0/libD.cabal new file mode 100644 index 00000000000..117350487c7 --- /dev/null +++ b/cabal-testsuite/PackageTests/PrivateDeps/closure-property-test/repo/libD-0.1.0.0/libD.cabal @@ -0,0 +1,11 @@ +cabal-version: 3.0 +name: libD +version: 0.1.0.0 +license: NONE +build-type: Simple + +library + exposed-modules: MyLib + hs-source-dirs: . + default-language: Haskell2010 + default-extensions: NoImplicitPrelude diff --git a/cabal-testsuite/PackageTests/PrivateDeps/pd-backpack/README.md b/cabal-testsuite/PackageTests/PrivateDeps/pd-backpack/README.md new file mode 100644 index 00000000000..57d9e02f886 --- /dev/null +++ b/cabal-testsuite/PackageTests/PrivateDeps/pd-backpack/README.md @@ -0,0 +1,15 @@ +Backpack + Private Dependencies test + +exeA + main-is: Main.hs + private-build-depends: G1 with (libB == 0.1.0.0) + private-build-depends: G2 with (libB == 0.2.0.0) + build-depends: libB == 0.3.0.0 + mixins: + libA (A as A.G1) requires (AHole as G1.Fill) + libA (A as A.G2) requires (AHole as G2.Fill) + libA (A as A.NoScope) requires (AHole as Fill) + +libA + exposed-modules: A + signatures: AHole diff --git a/cabal-testsuite/PackageTests/PrivateDeps/pd-backpack/cabal.project b/cabal-testsuite/PackageTests/PrivateDeps/pd-backpack/cabal.project new file mode 100644 index 00000000000..827fcfc78cf --- /dev/null +++ b/cabal-testsuite/PackageTests/PrivateDeps/pd-backpack/cabal.project @@ -0,0 +1 @@ +packages: libA diff --git a/cabal-testsuite/PackageTests/PrivateDeps/pd-backpack/cabal.test.hs b/cabal-testsuite/PackageTests/PrivateDeps/pd-backpack/cabal.test.hs new file mode 100644 index 00000000000..c740c372052 --- /dev/null +++ b/cabal-testsuite/PackageTests/PrivateDeps/pd-backpack/cabal.test.hs @@ -0,0 +1,9 @@ +import Test.Cabal.Prelude + +main = + cabalTest $ + expectBroken 0 $ + withProjectFile "cabal.project" $ + withRepo "repo" $ + cabal "v2-build" ["libA"] + diff --git a/cabal-testsuite/PackageTests/PrivateDeps/pd-backpack/libA/app/Main.hs b/cabal-testsuite/PackageTests/PrivateDeps/pd-backpack/libA/app/Main.hs new file mode 100644 index 00000000000..6d78a77a66a --- /dev/null +++ b/cabal-testsuite/PackageTests/PrivateDeps/pd-backpack/libA/app/Main.hs @@ -0,0 +1,8 @@ +import qualified A.G1 +import qualified A.G2 +import qualified A.NoScope + +main = do + print (A.G1.fillhole) + print (A.G2.fillhole) + print (A.NoScope.fillhole) diff --git a/cabal-testsuite/PackageTests/PrivateDeps/pd-backpack/libA/libA.cabal b/cabal-testsuite/PackageTests/PrivateDeps/pd-backpack/libA/libA.cabal new file mode 100644 index 00000000000..4e9ec21c5cb --- /dev/null +++ b/cabal-testsuite/PackageTests/PrivateDeps/pd-backpack/libA/libA.cabal @@ -0,0 +1,22 @@ +cabal-version: 3.0 +name: libA +version: 0.1.0.0 +license: NONE +build-type: Simple + +executable exeA + main-is: Main.hs + build-depends: libA, libB == 0.3.0.0 + private-build-depends: G1 with (libB == 0.1.0.0) + private-build-depends: G2 with (libB == 0.2.0.0) + mixins: + libA (A as A.G1) requires (AHole as G1.Fill), + libA (A as A.G2) requires (AHole as G2.Fill), + libA (A as A.NoScope) requires (AHole as Fill) + default-extensions: NoImplicitPrelude + +library + exposed-modules: A + signatures: AHole + hs-source-dirs: src + default-extensions: NoImplicitPrelude diff --git a/cabal-testsuite/PackageTests/PrivateDeps/pd-backpack/libA/src/A.hs b/cabal-testsuite/PackageTests/PrivateDeps/pd-backpack/libA/src/A.hs new file mode 100644 index 00000000000..d1a60e710e2 --- /dev/null +++ b/cabal-testsuite/PackageTests/PrivateDeps/pd-backpack/libA/src/A.hs @@ -0,0 +1,3 @@ +module A (fillhole) where + +import AHole (fillhole) diff --git a/cabal-testsuite/PackageTests/PrivateDeps/pd-backpack/libA/src/AHole.hsig b/cabal-testsuite/PackageTests/PrivateDeps/pd-backpack/libA/src/AHole.hsig new file mode 100644 index 00000000000..9ceafbd086e --- /dev/null +++ b/cabal-testsuite/PackageTests/PrivateDeps/pd-backpack/libA/src/AHole.hsig @@ -0,0 +1,3 @@ +signature AHole where + +fillhole :: Int diff --git a/cabal-testsuite/PackageTests/PrivateDeps/pd-backpack/repo/libB-0.1.0.0/Fill.hs b/cabal-testsuite/PackageTests/PrivateDeps/pd-backpack/repo/libB-0.1.0.0/Fill.hs new file mode 100644 index 00000000000..fef98a6ce08 --- /dev/null +++ b/cabal-testsuite/PackageTests/PrivateDeps/pd-backpack/repo/libB-0.1.0.0/Fill.hs @@ -0,0 +1,4 @@ +module Fill where + +fillhole :: Int +fillhole = 1 diff --git a/cabal-testsuite/PackageTests/PrivateDeps/pd-backpack/repo/libB-0.1.0.0/libB.cabal b/cabal-testsuite/PackageTests/PrivateDeps/pd-backpack/repo/libB-0.1.0.0/libB.cabal new file mode 100644 index 00000000000..e5937452a61 --- /dev/null +++ b/cabal-testsuite/PackageTests/PrivateDeps/pd-backpack/repo/libB-0.1.0.0/libB.cabal @@ -0,0 +1,10 @@ +cabal-version: 3.0 +name: libB +version: 0.1.0.0 +license: NONE +build-type: Simple + +library + exposed-modules: Fill + default-language: Haskell2010 + default-extensions: NoImplicitPrelude diff --git a/cabal-testsuite/PackageTests/PrivateDeps/pd-backpack/repo/libB-0.1.0.0/tags b/cabal-testsuite/PackageTests/PrivateDeps/pd-backpack/repo/libB-0.1.0.0/tags new file mode 100644 index 00000000000..1a01b2d1ce5 --- /dev/null +++ b/cabal-testsuite/PackageTests/PrivateDeps/pd-backpack/repo/libB-0.1.0.0/tags @@ -0,0 +1,2 @@ +!_TAG_FILE_SORTED 1 // +fillhole Fill.hs 3;" f diff --git a/cabal-testsuite/PackageTests/PrivateDeps/pd-backpack/repo/libB-0.2.0.0/Fill.hs b/cabal-testsuite/PackageTests/PrivateDeps/pd-backpack/repo/libB-0.2.0.0/Fill.hs new file mode 100644 index 00000000000..fd4cd35d6d6 --- /dev/null +++ b/cabal-testsuite/PackageTests/PrivateDeps/pd-backpack/repo/libB-0.2.0.0/Fill.hs @@ -0,0 +1,4 @@ +module Fill where + +fillhole :: Int +fillhole = 2 diff --git a/cabal-testsuite/PackageTests/PrivateDeps/pd-backpack/repo/libB-0.2.0.0/libB.cabal b/cabal-testsuite/PackageTests/PrivateDeps/pd-backpack/repo/libB-0.2.0.0/libB.cabal new file mode 100644 index 00000000000..0f8cd48746f --- /dev/null +++ b/cabal-testsuite/PackageTests/PrivateDeps/pd-backpack/repo/libB-0.2.0.0/libB.cabal @@ -0,0 +1,10 @@ +cabal-version: 3.0 +name: libB +version: 0.2.0.0 +license: NONE +build-type: Simple + +library + exposed-modules: Fill + default-language: Haskell2010 + default-extensions: NoImplicitPrelude diff --git a/cabal-testsuite/PackageTests/PrivateDeps/pd-backpack/repo/libB-0.2.0.0/tags b/cabal-testsuite/PackageTests/PrivateDeps/pd-backpack/repo/libB-0.2.0.0/tags new file mode 100644 index 00000000000..1a01b2d1ce5 --- /dev/null +++ b/cabal-testsuite/PackageTests/PrivateDeps/pd-backpack/repo/libB-0.2.0.0/tags @@ -0,0 +1,2 @@ +!_TAG_FILE_SORTED 1 // +fillhole Fill.hs 3;" f diff --git a/cabal-testsuite/PackageTests/PrivateDeps/pd-backpack/repo/libB-0.3.0.0/Fill.hs b/cabal-testsuite/PackageTests/PrivateDeps/pd-backpack/repo/libB-0.3.0.0/Fill.hs new file mode 100644 index 00000000000..234f38660cb --- /dev/null +++ b/cabal-testsuite/PackageTests/PrivateDeps/pd-backpack/repo/libB-0.3.0.0/Fill.hs @@ -0,0 +1,4 @@ +module Fill where + +fillhole :: Int +fillhole = 3 diff --git a/cabal-testsuite/PackageTests/PrivateDeps/pd-backpack/repo/libB-0.3.0.0/libB.cabal b/cabal-testsuite/PackageTests/PrivateDeps/pd-backpack/repo/libB-0.3.0.0/libB.cabal new file mode 100644 index 00000000000..5f7b5cc4f98 --- /dev/null +++ b/cabal-testsuite/PackageTests/PrivateDeps/pd-backpack/repo/libB-0.3.0.0/libB.cabal @@ -0,0 +1,10 @@ +cabal-version: 3.0 +name: libB +version: 0.3.0.0 +license: NONE +build-type: Simple + +library + exposed-modules: Fill + default-language: Haskell2010 + default-extensions: NoImplicitPrelude diff --git a/cabal-testsuite/PackageTests/PrivateDeps/pd-backpack/repo/libB-0.3.0.0/tags b/cabal-testsuite/PackageTests/PrivateDeps/pd-backpack/repo/libB-0.3.0.0/tags new file mode 100644 index 00000000000..1a01b2d1ce5 --- /dev/null +++ b/cabal-testsuite/PackageTests/PrivateDeps/pd-backpack/repo/libB-0.3.0.0/tags @@ -0,0 +1,2 @@ +!_TAG_FILE_SORTED 1 // +fillhole Fill.hs 3;" f diff --git a/cabal-testsuite/PackageTests/PrivateDeps/same-scope-name/cabal.project.scenea b/cabal-testsuite/PackageTests/PrivateDeps/same-scope-name/cabal.project.scenea new file mode 100644 index 00000000000..7e858b21c61 --- /dev/null +++ b/cabal-testsuite/PackageTests/PrivateDeps/same-scope-name/cabal.project.scenea @@ -0,0 +1 @@ +packages: pkgA, pkgB diff --git a/cabal-testsuite/PackageTests/PrivateDeps/same-scope-name/cabal.project.sceneb b/cabal-testsuite/PackageTests/PrivateDeps/same-scope-name/cabal.project.sceneb new file mode 100644 index 00000000000..5ed273644e7 --- /dev/null +++ b/cabal-testsuite/PackageTests/PrivateDeps/same-scope-name/cabal.project.sceneb @@ -0,0 +1 @@ +packages: pkgC diff --git a/cabal-testsuite/PackageTests/PrivateDeps/same-scope-name/cabal.project.scenec b/cabal-testsuite/PackageTests/PrivateDeps/same-scope-name/cabal.project.scenec new file mode 100644 index 00000000000..932121d3d42 --- /dev/null +++ b/cabal-testsuite/PackageTests/PrivateDeps/same-scope-name/cabal.project.scenec @@ -0,0 +1 @@ +packages: pkgD diff --git a/cabal-testsuite/PackageTests/PrivateDeps/same-scope-name/cabal.test.hs b/cabal-testsuite/PackageTests/PrivateDeps/same-scope-name/cabal.test.hs new file mode 100644 index 00000000000..aa32d62b765 --- /dev/null +++ b/cabal-testsuite/PackageTests/PrivateDeps/same-scope-name/cabal.test.hs @@ -0,0 +1,37 @@ +import Test.Cabal.Prelude + +{- +Checks that: + +(a) If there are two scopes with the same name in two separate packages, the same +name shouldn't matter and should the scopes should be solved independently +because they are in different packages + +(b) If the scopes with the same name are in same package but in different +components, they should be merged together and fail because of the conflict + +(c) If the scopes are in the same component, then they should be merged and fail +because of the conflict too +-} + +main = + cabalTest $ recordMode DoNotRecord $ do + -- withProjectFile "cabal.project.scenea" $ -- For some reason this doesn't work... + + withRepo "repo" $ do + -- Succeeds because SameName from pkgA and SameName from pkgB do not collide. + out <- cabal' "build" ["pkgA", "--project-file=cabal.project.scenea"] + -- We build the two versions, one for each package's private deps. + assertOutputContains "- libA-0.1.0.0 (lib) (requires build)" out + assertOutputContains "- libA-0.2.0.0 (lib) (requires build)" out + + withRepo "repo" $ do + -- Fails because SameName from pkgC in its two separate components + fails (cabal' "build" ["pkgC", "--project-file=cabal.project.sceneb"]) + >>= assertOutputContains "rejecting: pkgC:SameName.libA-0.2.0.0 (conflict: pkgC => pkgC:SameName.libA==0.1.0.0)" + + withRepo "repo" $ do + -- Fails because SameName from pkgD in the same component + fails (cabal' "build" ["pkgD", "--project-file=cabal.project.scenec"]) + >>= assertOutputContains "rejecting: pkgD:SameName.libA-0.2.0.0 (conflict: pkgD => pkgD:SameName.libA==0.1.0.0)" + diff --git a/cabal-testsuite/PackageTests/PrivateDeps/same-scope-name/pkgA/pkgA.cabal b/cabal-testsuite/PackageTests/PrivateDeps/same-scope-name/pkgA/pkgA.cabal new file mode 100644 index 00000000000..b081ea9530b --- /dev/null +++ b/cabal-testsuite/PackageTests/PrivateDeps/same-scope-name/pkgA/pkgA.cabal @@ -0,0 +1,16 @@ +cabal-version: 3.0 +name: pkgA +version: 0.1.0.0 +license: NONE +build-type: Simple + +common warnings + ghc-options: -Wall + +library + import: warnings + exposed-modules: MyLib + private-build-depends: SameName with (libA == 0.1.0.0) + build-depends: base, pkgB + hs-source-dirs: src + default-language: Haskell2010 diff --git a/cabal-testsuite/PackageTests/PrivateDeps/same-scope-name/pkgA/src/MyLib.hs b/cabal-testsuite/PackageTests/PrivateDeps/same-scope-name/pkgA/src/MyLib.hs new file mode 100644 index 00000000000..e657c4403f6 --- /dev/null +++ b/cabal-testsuite/PackageTests/PrivateDeps/same-scope-name/pkgA/src/MyLib.hs @@ -0,0 +1,4 @@ +module MyLib (someFunc) where + +someFunc :: IO () +someFunc = putStrLn "someFunc" diff --git a/cabal-testsuite/PackageTests/PrivateDeps/same-scope-name/pkgB/pkgB.cabal b/cabal-testsuite/PackageTests/PrivateDeps/same-scope-name/pkgB/pkgB.cabal new file mode 100644 index 00000000000..d1c0dff0489 --- /dev/null +++ b/cabal-testsuite/PackageTests/PrivateDeps/same-scope-name/pkgB/pkgB.cabal @@ -0,0 +1,16 @@ +cabal-version: 3.0 +name: pkgB +version: 0.1.0.0 +license: NONE +build-type: Simple + +common warnings + ghc-options: -Wall + +library + import: warnings + exposed-modules: MyLib + private-build-depends: SameName with (libA == 0.2.0.0) + build-depends: base + hs-source-dirs: src + default-language: Haskell2010 diff --git a/cabal-testsuite/PackageTests/PrivateDeps/same-scope-name/pkgB/src/MyLib.hs b/cabal-testsuite/PackageTests/PrivateDeps/same-scope-name/pkgB/src/MyLib.hs new file mode 100644 index 00000000000..e657c4403f6 --- /dev/null +++ b/cabal-testsuite/PackageTests/PrivateDeps/same-scope-name/pkgB/src/MyLib.hs @@ -0,0 +1,4 @@ +module MyLib (someFunc) where + +someFunc :: IO () +someFunc = putStrLn "someFunc" diff --git a/cabal-testsuite/PackageTests/PrivateDeps/same-scope-name/pkgC/app/Main.hs b/cabal-testsuite/PackageTests/PrivateDeps/same-scope-name/pkgC/app/Main.hs new file mode 100644 index 00000000000..76a9bdb5d48 --- /dev/null +++ b/cabal-testsuite/PackageTests/PrivateDeps/same-scope-name/pkgC/app/Main.hs @@ -0,0 +1 @@ +main = pure () diff --git a/cabal-testsuite/PackageTests/PrivateDeps/same-scope-name/pkgC/pkgC.cabal b/cabal-testsuite/PackageTests/PrivateDeps/same-scope-name/pkgC/pkgC.cabal new file mode 100644 index 00000000000..a2798b523ee --- /dev/null +++ b/cabal-testsuite/PackageTests/PrivateDeps/same-scope-name/pkgC/pkgC.cabal @@ -0,0 +1,23 @@ +cabal-version: 3.0 +name: pkgC +version: 0.1.0.0 +license: NONE +build-type: Simple + +common warnings + ghc-options: -Wall + +library + import: warnings + exposed-modules: MyLib + private-build-depends: SameName with (libA == 0.1.0.0) + build-depends: base + hs-source-dirs: src + default-language: Haskell2010 + +executable myexe + main-is: Main.hs + hs-source-dirs: app + private-build-depends: SameName with (libA == 0.2.0.0) + default-language: Haskell2010 + build-depends: base diff --git a/cabal-testsuite/PackageTests/PrivateDeps/same-scope-name/pkgC/src/MyLib.hs b/cabal-testsuite/PackageTests/PrivateDeps/same-scope-name/pkgC/src/MyLib.hs new file mode 100644 index 00000000000..e657c4403f6 --- /dev/null +++ b/cabal-testsuite/PackageTests/PrivateDeps/same-scope-name/pkgC/src/MyLib.hs @@ -0,0 +1,4 @@ +module MyLib (someFunc) where + +someFunc :: IO () +someFunc = putStrLn "someFunc" diff --git a/cabal-testsuite/PackageTests/PrivateDeps/same-scope-name/pkgD/pkgD.cabal b/cabal-testsuite/PackageTests/PrivateDeps/same-scope-name/pkgD/pkgD.cabal new file mode 100644 index 00000000000..83b11345752 --- /dev/null +++ b/cabal-testsuite/PackageTests/PrivateDeps/same-scope-name/pkgD/pkgD.cabal @@ -0,0 +1,18 @@ +cabal-version: 3.0 +name: pkgD +version: 0.1.0.0 +license: NONE +build-type: Simple + +common warnings + ghc-options: -Wall + +library + import: warnings + exposed-modules: MyLib + private-build-depends: SameName with (libA == 0.1.0.0), + SameName with (libA == 0.2.0.0) + build-depends: base + hs-source-dirs: src + default-language: Haskell2010 + diff --git a/cabal-testsuite/PackageTests/PrivateDeps/same-scope-name/pkgD/src/MyLib.hs b/cabal-testsuite/PackageTests/PrivateDeps/same-scope-name/pkgD/src/MyLib.hs new file mode 100644 index 00000000000..e657c4403f6 --- /dev/null +++ b/cabal-testsuite/PackageTests/PrivateDeps/same-scope-name/pkgD/src/MyLib.hs @@ -0,0 +1,4 @@ +module MyLib (someFunc) where + +someFunc :: IO () +someFunc = putStrLn "someFunc" diff --git a/cabal-testsuite/PackageTests/PrivateDeps/same-scope-name/repo/libA-0.1.0.0/libA.cabal b/cabal-testsuite/PackageTests/PrivateDeps/same-scope-name/repo/libA-0.1.0.0/libA.cabal new file mode 100644 index 00000000000..8162c86fb8f --- /dev/null +++ b/cabal-testsuite/PackageTests/PrivateDeps/same-scope-name/repo/libA-0.1.0.0/libA.cabal @@ -0,0 +1,15 @@ +cabal-version: 3.0 +name: libA +version: 0.1.0.0 +license: NONE +build-type: Simple + +common warnings + ghc-options: -Wall + +library + import: warnings + exposed-modules: MyLib + build-depends: base + hs-source-dirs: src + default-language: Haskell2010 diff --git a/cabal-testsuite/PackageTests/PrivateDeps/same-scope-name/repo/libA-0.1.0.0/src/MyLib.hs b/cabal-testsuite/PackageTests/PrivateDeps/same-scope-name/repo/libA-0.1.0.0/src/MyLib.hs new file mode 100644 index 00000000000..e657c4403f6 --- /dev/null +++ b/cabal-testsuite/PackageTests/PrivateDeps/same-scope-name/repo/libA-0.1.0.0/src/MyLib.hs @@ -0,0 +1,4 @@ +module MyLib (someFunc) where + +someFunc :: IO () +someFunc = putStrLn "someFunc" diff --git a/cabal-testsuite/PackageTests/PrivateDeps/same-scope-name/repo/libA-0.2.0.0/libA.cabal b/cabal-testsuite/PackageTests/PrivateDeps/same-scope-name/repo/libA-0.2.0.0/libA.cabal new file mode 100644 index 00000000000..84a8664ca62 --- /dev/null +++ b/cabal-testsuite/PackageTests/PrivateDeps/same-scope-name/repo/libA-0.2.0.0/libA.cabal @@ -0,0 +1,15 @@ +cabal-version: 3.0 +name: libA +version: 0.2.0.0 +license: NONE +build-type: Simple + +common warnings + ghc-options: -Wall + +library + import: warnings + exposed-modules: MyLib + build-depends: base + hs-source-dirs: src + default-language: Haskell2010 diff --git a/cabal-testsuite/PackageTests/PrivateDeps/same-scope-name/repo/libA-0.2.0.0/src/MyLib.hs b/cabal-testsuite/PackageTests/PrivateDeps/same-scope-name/repo/libA-0.2.0.0/src/MyLib.hs new file mode 100644 index 00000000000..e657c4403f6 --- /dev/null +++ b/cabal-testsuite/PackageTests/PrivateDeps/same-scope-name/repo/libA-0.2.0.0/src/MyLib.hs @@ -0,0 +1,4 @@ +module MyLib (someFunc) where + +someFunc :: IO () +someFunc = putStrLn "someFunc" diff --git a/cabal-testsuite/src/Test/Cabal/Prelude.hs b/cabal-testsuite/src/Test/Cabal/Prelude.hs index 52430830014..32c6127cd78 100644 --- a/cabal-testsuite/src/Test/Cabal/Prelude.hs +++ b/cabal-testsuite/src/Test/Cabal/Prelude.hs @@ -381,7 +381,9 @@ runPlanExe' pkg_name cname args = do recordHeader [pkg_name, cname] runM exePath args Nothing -planExePath :: String {- package name -} -> String {- component name -} +-- | Get the path to an executable built from a package. Requires 'withPlan' +-- to have been run so that we can find the dist dir. +planExePath :: String {-^ package name -} -> String {-^ component name -} -> TestM FilePath planExePath pkg_name cname = do Just plan <- testPlan `fmap` getTestEnv diff --git a/doc/buildinfo-fields-reference.rst b/doc/buildinfo-fields-reference.rst index c1ccf418f81..8bd5b9fe502 100644 --- a/doc/buildinfo-fields-reference.rst +++ b/doc/buildinfo-fields-reference.rst @@ -510,6 +510,13 @@ pkgconfig-depends .. math:: \mathrm{commalist}\mathsf{\color{red}{TODO}} +private-build-depends + * Monoidal field + * Documentation of :pkg-field:`library:private-build-depends` + + .. math:: + \mathrm{commalist}\left(\mathop{\mathit{alias}}\bullet\mathop{\mathord{``}\mathtt{with}\mathord{"}}\bullet\mathop{\mathord{``}\mathtt{\text{(}}\mathord{"}}\circ{\left(\mathop{\mathit{pkg\text{-}name}}{\left(\mathop{\mathord{``}\mathtt{\text{:}}\mathord{"}}\left\{ \mathop{\mathit{unqual\text{-}name}}\mid\mathop{\mathord{``}\mathtt{\{}\mathord{"}}\circ{\mathop{\mathit{unqual\text{-}name}}}^+_{\left(\circ\mathop{\mathord{``}\mathtt{\text{,}}\mathord{"}}\circ\right)}\circ\mathop{\mathord{``}\mathtt{\}}\mathord{"}} \right\}\right)}^?{\left(\circ\mathop{\mathit{version\text{-}range}}\right)}^?\right)}^\ast_{\left(\circ\mathop{\mathord{``}\mathtt{\text{,}}\mathord{"}}\circ\right)}\circ\mathop{\mathord{``}\mathtt{\text{)}}\mathord{"}}\right) + virtual-modules * Monoidal field * Available since ``cabal-version: 2.2``. diff --git a/doc/cabal-package-description-file.rst b/doc/cabal-package-description-file.rst index 3004fed0b0b..512a87cf697 100644 --- a/doc/cabal-package-description-file.rst +++ b/doc/cabal-package-description-file.rst @@ -2143,6 +2143,30 @@ system-dependent values for these fields. supported libraries. Depending on your system you may need to adjust ``PKG_CONFIG_PATH``. +.. pkg-field:: private-build-depends: private scope + + A `private dependency ` can be introduced in a cabal file in the + ``private-build-depends`` field. The specification starts with the name of the + private dependency *scope* and then contains a list of normal dependency + specifications which dictate the packages included in that private scope. + For example, the following will create two private scopes, with a different + version of ``text`` each. + + :: + + private-build-depends: TEXT1 with (text == 1.2.*), TEXT2 with (text == 2.*) + + The package **goals in a private scope are solved independently of all other + scopes**. In this example, the ``TEXT1`` scope can choose a version of ``text`` + in the ``1.2.x`` range and the ``TEXT2`` scope can choose a version of ``text`` in the + ``2.*`` range. + + However, **private scopes do not apply transitively**, so the dependencies of + ``text`` will be solved in the normal top-level scope. If your program contains a + value of type ``Bool`` from the ``base`` package, which ``text`` also depends on, only + if the scopes are not applied transitively can the same ``Bool`` value can be + passed to functions from the ``TEXT1`` scope and ``TEXT2`` scope. + .. pkg-field:: frameworks: token list On Darwin/MacOS X, a list of frameworks to link to. See Apple's diff --git a/doc/how-to-use-private-dependencies.rst b/doc/how-to-use-private-dependencies.rst new file mode 100644 index 00000000000..0ce908ac773 --- /dev/null +++ b/doc/how-to-use-private-dependencies.rst @@ -0,0 +1,240 @@ +.. _Private dependencies: + +Private dependencies +==================== + +Historically, Cabal has enforced the restriction that a library must only link +against one version of each package it depends on. This ensures that all of the +dependencies in the build plan work together. In your application you use +different libraries together, so it's of paramount importance that they all +agree on what ``Text`` means or what a ``ByteString`` is. + +However, sometimes it's desirable to allow multiple versions of the same +library into a build plan. In this case, it's desirable to allow a library +author to specify a **private** dependency with the promise that its existence +will not leak from the interface of the library which uses it. + +The two main use cases of private dependencies are: + +* Writing benchmarks and testsuites for your library which test new versions of + your library against old versions. +* Writing libraries which can communicate with processes built against + a range of different library versions (such as ``cabal`-install` calling `./`Setup``). + +Private dependencies are a new feature in ``Cabal`` and ``cabal-install`` which +allows the Cabal solver to pick versions for private dependencies independently +from the package versions chosen for public dependencies, enabling the scenarios above. + +Private dependencies are an advanced feature which should only be used if you +know what you are doing and need a build plan which involves linking a library against +multiple versions of the same library. + +The examples used in this blog post are available in its "complete" form in +this `github repository `__. + +Using private dependencies +-------------------------- + +To explore the syntax and properties of private dependencies, consider a +testsuite which will have a private dependency on ``text-1.2`` and a +separate private dependency on ``text-2``: + +:: + + ┌──────────┐ + ┌─┤bench-text├─┐ + │ └──────────┘ │ + │ │ + ┌──▼───┐ ┌────▼─┐ + │text-1│ │text-2│ + └──────┘ └──────┘ + +This benchmark/testsuite will be able to run two different versions of +the same function from the package in the same executable, making it +much easier to e.g. detect performance regressions or improvements +across versions. + +A private dependency can be introduced in a cabal file in the +``private-build-depends`` field. The specification starts with the name +of the private dependency *scope* and then contains a list of normal +dependency specifications which dictate the packages included in that +private scope. Our example needs two private scopes, each with a +specific version of text: + +:: + + private-build-depends: TEXT1 with (text == 1.2.*), TEXT2 with (text == 2.*) + +The package **goals in a private scope are solved independently of all +other scopes**. In this example, the ``TEXT1`` scope can choose a +version of ``text`` in the ``1.2.x`` range and the ``TEXT2`` scope can +choose a version of ``text`` in the ``2.*`` range. + +However, **private scopes do not apply transitively**, so the +dependencies of ``text`` will be solved in the normal top-level scope. +If your program contains a value of type ``Bool`` from the ``base`` +package, which ``text`` also depends on, only if the scopes are not +applied transitively can the same ``Bool`` value can be passed to +functions from the ``TEXT1`` scope and ``TEXT2`` scope. Visually, the +“complete” dependency graph would look like: + +:: + + ┌──────────┐ + ┌─┤bench-text├─┐ + │ └──────────┘ │ + │ │ + ┌──▼───┐ ┌────▼─┐ + │text-1│ │text-2│ + └──┬───┘ └───┬──┘ + │ │ + │ ┌──────┐ │ + └───►base-4◄──┘ + └──────┘ + +Dependencies introduced privately can be imported into modules in the +project by prefixing the name of the private scope to an exposed module +name: + +:: + + import qualified TEXT1.Data.Text as T1 + import qualified TEXT2.Data.Text as T2 + +Now, obviously, ``T1.Text`` and ``T2.Text`` are distinct types, and it’s +the programmer’s responsibility to ensure that their program does not +mix them together. The typechecker will tell you if you attempt to use +incompatible types with each other. + +Further to this, the private dependencies contract states that you are +**not allowed to expose anything from a private scope in the public API +of your library**. Again, it’s the programmer’s responsibility to ensure +that their public API doesn’t expose any of these types. This isn’t +checked by the compiler; if you don’t ensure the public API doesn’t +expose types imported from a private scope, your package is going to be +broken. + +Once the types are imported, they are used just like any other qualified +imports. In a simple test, we check that ``text-2.*`` and ``text-1.2.*`` +agree in the length of ``"abc"``: + +:: + + main = print $ T1.length (T1.pack "abc") == T2.length (T2.pack "abc") + +Closure of Private Dependencies +------------------------------- + +A private dependency scope may contain multiple packages, and **packages +in the same private scope are solved together**. That is, you have to +pick one version per package in the scope that satisfies all constraints +of all packages in that scope. For instance, having +``private-build-depends: S0 with (pkg-a == 0.1, pkg-b == 0.2)`` will +fail if ``pkg-a`` has ``build-depends: pkg-b == 0-1`` in its cabal file. + +Specifying two (or more) packages in the same scope can be particularly +useful if these two packages are tightly coupled and you need each to +use a version compatible with the other, but still want them to be +solved independently of the top-level scope. + +A crucial property must hold true of the packages in a private scope: +**the transitive closure of the packages in the private scope must be +closed**. A scope is **closed** if, whenever we have a dependency chain +``P1 -> Q -> P2``, in which ``P1`` and ``P2`` are both in a given +private scope ``S``, then ``Q`` also belongs to the private scope ``S``. +The Cabal solver checks this property and guarantees no scope violates +this property, however, it doesn’t implicit add packages into a private +scope, so you may need to add packages violating the closure property +manually to the scope. + +Apartness of Private Dependencies +--------------------------------- + +A library using private dependencies must **assume that a privately +scoped dependency is apart from the top-level scope and from other +private scopes**. + +By coincidence (and heuristics), the solver might choose the same +version of a package to satisfy different private scopes. Conversely, it +might also not choose the same version. Therefore, in order to robustly +write a program using private dependencies, the programmer must assume +that modules in separate scopes are incompatible with other modules of +the same name, even if those modules come from the same package. + +Benchmarking using Private Dependencies +--------------------------------------- + +Using private dependencies, it is straightforward to write a benchmark +suite which tests different versions of the same library against each +other. + +Consider the task of benchmarking ``text-1.2.*`` vs ``text-2.*`` again: +private dependencies make it possible to benchmark the two versions +directly against each other in the same benchmark run. + +Working through a complete benchmarking example, let’s introduce two new +private scopes to encapsulate the different ``text`` versions which we +want to test: + +:: + + benchmark testing-text-benchmarks + import: warnings + default-language: Haskell2010 + type: exitcode-stdio-1.0 + hs-source-dirs: bench/ + main-is: Main.hs + build-depends: base ^>=4.18.0.0, tasty-bench, tasty, deepseq + private-build-depends: TEXT1 with (text == 1.2.*), TEXT2 with (text == 2.*) + +The different versions of ``text`` are made available with the +respective prefixes in ``Main.hs``: + +:: + + import qualified TEXT1.Data.Text as TEXT1 + import qualified TEXT1.Data.Text.IO as TEXT1 + + + import qualified TEXT2.Data.Text as TEXT2 + import qualified TEXT2.Data.Text.IO as TEXT2 + +The ``InputEnv`` type allows us to wrap ``TEXT1.Text`` and +``TEXT2.Text`` to provide an ``NFData`` instance for types which we just +have to force to WHNF to be sure of having evaluated fully: + +:: + + data InputEnv a = InputEnv { lorem :: !a } + + instance NFData (InputEnv a) where + rnf InputEnv{} = () + + type T1Env = InputEnv TEXT1.Text + type T2Env = InputEnv TEXT2.Text + +We declare a helper function (``mkBench``) which takes the two prepared +``Text`` values and functions from the relevant library versions, and +proceed with benchmarking as is typically done for other benchmarks +regardless of private scopes: + +:: + + mkBench :: T1Env -> T2Env -> (TEXT1.Text -> a) -> (TEXT2.Text -> b) -> [Benchmark] + mkBench t1env t2env t1 t2 = + [ bench "t1" $ whnf t1 (lorem t1env) + , bench "t2" $ whnf t2 (lorem t2env) ] + + main = + defaultMain . (:[]) $ + env (InputEnv <$> TEXT1.readFile "lorem.txt") $ \t1env -> + env (InputEnv <$> TEXT2.readFile "lorem.txt") $ \t2env -> + let mk_bench = mkBench t1env t2env + in bgroup "text" + [ bgroup "Reverse" (mk_bench TEXT1.reverse TEXT2.reverse) + , bgroup "Length" (mk_bench TEXT1.length TEXT2.length) + ] + +Running the benchmarks we can see that ``text-2.*`` performs much better +than ``text-1.2``, at least in the case of reversing and length. + diff --git a/doc/index.rst b/doc/index.rst index 69109a67685..cdfa61f45e0 100644 --- a/doc/index.rst +++ b/doc/index.rst @@ -16,6 +16,7 @@ Welcome to the Cabal User Guide how-to-package-haskell-code how-to-build-like-nix how-to-use-backpack + how-to-use-private-dependencies how-to-report-bugs .. toctree::