@@ -18,7 +18,7 @@ module Stackage2.BuildPlan
1818import Distribution.Package (Dependency (..))
1919import Distribution.PackageDescription
2020import Distribution.Version (withinRange, anyVersion, simplifyVersionRange)
21−import Stackage2.PackageConstraints
21+import Stackage2.BuildConstraints
2222import Stackage2.PackageIndex
2323import Stackage2.Prelude
2424import Stackage2.GithubPings
@@ -31,13 +31,9 @@ import qualified Distribution.System
3131import qualified Distribution.Compiler
3232
3333data BuildPlan desc = BuildPlan
34− { bpCore :: Map PackageName Version
35− , bpCoreExecutables :: Set ExeName
36− , bpGhcVersion :: Version
37− , bpOS :: Distribution.System.OS
38− , bpArch :: Distribution.System.Arch
34+ { bpSystemInfo :: SystemInfo
3935 , bpTools :: Vector (PackageName, Version)
40− , bpExtra :: Map PackageName (PackageBuild desc)
36+ , bpPackages :: Map PackageName (PackageBuild desc)
4137 }
4238 deriving (Functor, Foldable, Traversable, Show, Eq)
4339type instance Element (BuildPlan desc) = desc
@@ -47,58 +43,33 @@ instance MonoTraversable (BuildPlan desc)
4743
4844instance ToJSON (BuildPlan desc) where
4945 toJSON BuildPlan {..} = object
50− [ "core" .= asMap (mapFromList $ map toCore $ mapToList bpCore)
51− , "core-exes" .= bpCoreExecutables
52− , "ghc-version" .= asText (display bpGhcVersion)
53− , "os" .= asText (display bpOS)
54− , "arch" .= asText (display bpArch)
46+ [ "system-info" .= bpSystemInfo
5547 , "tools" .= map goTool bpTools
56− , "extra" .= Map.mapKeysWith const (unPackageName) bpExtra
48+ , "packages" .= Map.mapKeysWith const unPackageName bpPackages
5749 ]
5850 where
59− toCore (x, y) = (asText $ display x, asText $ display y)
60− goTool (name, version) = object
61− [ "name" .= asText (display name)
62− , "version" .= asText (display version)
51+ goTool (k, v) = object
52+ [ "name" .= display k
53+ , "version" .= display v
6354 ]
6455instance desc ~ () => FromJSON (BuildPlan desc) where
6556 parseJSON = withObject "BuildPlan" $ \o -> do
66− bpCore <- (o .: "core") >>= goCore
67− bpCoreExecutables <- o .: "core-exes"
68− bpGhcVersion <- (o .: "ghc-version") >>= either (fail . show) return . simpleParse . asText
69− bpOS <- o .: "os" >>= either (fail . show) return . simpleParse . asText
70− bpArch <- (o .: "arch") >>= either (fail . show) return . simpleParse . asText
57+ bpSystemInfo <- o .: "system-info"
7158 bpTools <- (o .: "tools") >>= mapM goTool
72− bpExtra <- goExtra <$> (o .: "extra")
59+ bpPackages <- Map.mapKeysWith const mkPackageName <$> (o .: "packages")
7360 return BuildPlan {..}
7461 where
75− goCore =
76− fmap mapFromList . mapM goCore' . mapToList . asHashMap
77− where
78− goCore' (k, v) = do
79− k' <- either (fail . show) return $ simpleParse $ asText k
80− v' <- either (fail . show) return $ simpleParse $ asText v
81− return (k', v')
82−
8362 goTool = withObject "Tool" $ \o -> (,)
8463 <$> ((o .: "name") >>=
8564 either (fail . show) return . simpleParse . asText)
8665 <*> ((o .: "version") >>=
8766 either (fail . show) return . simpleParse . asText)
8867
89− goExtra = Map.mapKeysWith const PackageName
90−
9168data PackageBuild desc = PackageBuild
9269 { pbVersion :: Version
93− , pbVersionRange :: VersionRange
94− -- ^ This is vital for ensuring old constraints are kept in place when bumping
95− , pbMaintainer :: Maybe Maintainer
9670 , pbGithubPings :: Set Text
9771 , pbUsers :: Set PackageName
98− , pbFlags :: Map FlagName Bool
99− , pbTestState :: TestState
100− , pbHaddockState :: TestState
101− , pbTryBuildBenchmark :: Bool
72+ , pbPackageConstraints :: PackageConstraints
10273 , pbDesc :: desc
10374 }
10475 deriving (Functor, Foldable, Traversable, Show, Eq)
@@ -107,69 +78,45 @@ instance MonoFunctor (PackageBuild desc)
10778instance MonoFoldable (PackageBuild desc)
10879instance MonoTraversable (PackageBuild desc)
10980
110−-- | There seems to be a bug in Cabal where serializing and deserializing
111−-- version ranges winds up with different representations. So we have a
112−-- super-simplifier to deal with that.
113−superSimplifyVersionRange :: VersionRange -> VersionRange
114−superSimplifyVersionRange vr =
115− fromMaybe (assert False vr') $ simpleParse $ asList $ display vr'
116− where
117− vr' = simplifyVersionRange vr
118−
11981instance ToJSON (PackageBuild desc) where
120− toJSON PackageBuild {..} = object $ concat
121− [ maybe [] (\m -> ["maintainer" .= m]) pbMaintainer
122− ,
123− [ "version" .= asText (display pbVersion)
124− , "version-range" .= asText (display $ superSimplifyVersionRange pbVersionRange)
125− , "github-pings" .= pbGithubPings
126− , "users" .= map unPackageName (unpack pbUsers)
127− , "flags" .= Map.mapKeysWith const (\(FlagName f) -> asText $ pack f) pbFlags
128− , "test-state" .= pbTestState
129− , "haddock-state" .= pbHaddockState
130− , "build-benchmark" .= pbTryBuildBenchmark
131− ]
82+ toJSON PackageBuild {..} = object
83+ [ "version" .= asText (display pbVersion)
84+ , "github-pings" .= pbGithubPings
85+ , "users" .= map unPackageName (unpack pbUsers)
86+ , "constraints" .= pbPackageConstraints
13287 ]
13388instance desc ~ () => FromJSON (PackageBuild desc) where
134− parseJSON = withObject "PackageBuild" $ \o -> PackageBuild
135− <$> (o .: "version" >>= efail . simpleParse . asText)
136− <*> (o .: "version-range" >>= fmap superSimplifyVersionRange . efail . simpleParse . asText)
137− <*> o .:? "maintainer"
138− <*> o .:? "github-pings" .!= mempty
139− <*> (Set.map PackageName <$> (o .:? "users" .!= mempty))
140− <*> (toFlags <$> (o .:? "flags" .!= mempty))
141− <*> o .: "test-state"
142− <*> o .: "haddock-state"
143− <*> o .: "build-benchmark"
144− <*> pure ()
89+ parseJSON = withObject "PackageBuild" $ \o -> do
90+ pbVersion <- o .: "version" >>= efail . simpleParse . asText
91+ pbGithubPings <- o .:? "github-pings" .!= mempty
92+ pbUsers <- Set.map PackageName <$> (o .:? "users" .!= mempty)
93+ pbPackageConstraints <- o .: "constraints"
94+ return PackageBuild {..}
14595 where
146− toFlags = Map.mapKeysWith const (FlagName . unpack . asText)
147−
96+ pbDesc = ()
14897 efail = either (fail . show) return
14998
150−newBuildPlan :: MonadIO m => PackageConstraints -> m (BuildPlan FlatComponent)
151−newBuildPlan pc = liftIO $ do
152− extraOrig <- getLatestDescriptions (isAllowed pc) (mkPackageBuild pc)
99+newBuildPlan :: MonadIO m => BuildConstraints -> m (BuildPlan FlatComponent)
100+newBuildPlan bc@BuildConstraints {..} = liftIO $ do
101+ extraOrig <- getLatestDescriptions (isAllowed bc) (mkPackageBuild bc)
153102 let toolMap = makeToolMap extraOrig
154− extra = populateUsers $ removeUnincluded pc toolMap extraOrig
103+ extra = populateUsers $ removeUnincluded bc toolMap extraOrig
155104 toolNames :: [ExeName]
156105 toolNames = concatMap (Map.keys . seTools . fcExtra . pbDesc) extra
157106 tools <- topologicalSortTools toolMap $ mapFromList $ do
158107 exeName <- toolNames
159− guard $ exeName `notMember` pcCoreExecutables pc
108+ guard $ exeName `notMember` siCoreExecutables
160109 packageName <- maybe mempty setToList $ lookup exeName toolMap
161110 packageBuild <- maybeToList $ lookup packageName extraOrig
162111 return (packageName, packageBuild)
163112 -- FIXME topologically sort packages? maybe just leave that to the build phase
164113 return BuildPlan
165− { bpCore = pcCorePackages pc
166− , bpCoreExecutables = pcCoreExecutables pc
167− , bpGhcVersion = pcGhcVersion pc
168− , bpOS = pcOS pc
169− , bpArch = pcArch pc
114+ { bpSystemInfo = bcSystemInfo
170115 , bpTools = tools
171− , bpExtra = extra
116+ , bpPackages = extra
172117 }
118+ where
119+ SystemInfo {..} = bcSystemInfo
173120
174121makeToolMap :: Map PackageName (PackageBuild FlatComponent)
175122 -> Map ExeName (Set PackageName)
@@ -213,18 +160,19 @@ data TopologicalSortException key = NoEmptyDeps (Map key (Set key))
213160 deriving (Show, Typeable)
214161instance (Show key, Typeable key) => Exception (TopologicalSortException key)
215162
216−removeUnincluded :: PackageConstraints
163+-- | Include only packages which are dependencies of the required packages and
164+-- their build tools.
165+removeUnincluded :: BuildConstraints
217166 -> Map ExeName (Set PackageName)
218167 -> Map PackageName (PackageBuild FlatComponent)
219168 -> Map PackageName (PackageBuild FlatComponent)
220−removeUnincluded pc toolMap orig =
169+removeUnincluded BuildConstraints {..} toolMap orig =
221170 mapFromList $ filter (\(x, _) -> x `member` included) $ mapToList orig
222171 where
223− coreExes = pcCoreExecutables pc
172+ SystemInfo {..} = bcSystemInfo
224173
225174 included :: Set PackageName
226− included = flip execState mempty $
227− mapM_ (add . fst) $ mapToList $ pcPackages pc
175+ included = flip execState mempty $ mapM_ add bcPackages
228176
229177 add name = do
230178 inc <- get
@@ -235,7 +183,7 @@ removeUnincluded pc toolMap orig =
235183 Just pb -> do
236184 mapM_ (add . fst) $ mapToList $ fcDeps $ pbDesc pb
237185 forM_ (map fst $ mapToList $ seTools $ fcExtra $ pbDesc pb) $
238− \exeName -> when (exeName `notMember` coreExes)
186+ \exeName -> when (exeName `notMember` siCoreExecutables)
239187 $ mapM_ add $ fromMaybe mempty $ lookup exeName toolMap
240188
241189populateUsers :: Map PackageName (PackageBuild FlatComponent)
@@ -249,49 +197,40 @@ populateUsers orig =
249197 | dep `member` fcDeps (pbDesc pb) = singletonSet user
250198 | otherwise = mempty
251199
252−isAllowed :: PackageConstraints
200+-- | Check whether the given package/version combo meets the constraints
201+-- currently in place.
202+isAllowed :: BuildConstraints
253203 -> PackageName -> Version -> Bool
254−isAllowed pc = \name version ->
255− case lookup name $ pcCorePackages pc of
204+isAllowed bc = \name version ->
205+ case lookup name $ siCorePackages $ bcSystemInfo bc of
256206 Just _ -> False -- never reinstall a core package
257− Nothing ->
258− case lookup name $ pcPackages pc of
259− Nothing -> True -- no constraints
260− Just (range, _) -> withinRange version range
207+ Nothing -> withinRange version $ pcVersionRange $ bcPackageConstraints bc name
261208
262209mkPackageBuild :: MonadThrow m
263− => PackageConstraints
210+ => BuildConstraints
264211 -> GenericPackageDescription
265212 -> m (PackageBuild FlatComponent)
266−mkPackageBuild pc gpd = do
267− let overrides = pcFlagOverrides pc name
268− getFlag MkFlag {..} =
269− (flagName, fromMaybe flagDefault $ lookup flagName overrides)
270− flags = mapFromList $ map getFlag $ genPackageFlags gpd
271− desc <- getFlattenedComponent
272− CheckCond
273− { ccPackageName = name
274− , ccOS = pcOS pc
275− , ccArch = pcArch pc
276− , ccCompilerFlavor = Distribution.Compiler.GHC
277− , ccCompilerVersion = pcGhcVersion pc
278− , ccFlags = flags
279− }
280− (pcTests pc name /= Don'tBuild)
281− (pcBuildBenchmark pc name)
282− gpd
283− return PackageBuild
284− { pbVersion = version
285− , pbVersionRange = superSimplifyVersionRange
286− $ maybe anyVersion fst $ lookup name $ pcPackages pc
287− , pbMaintainer = lookup name (pcPackages pc) >>= snd
288− , pbGithubPings = getGithubPings gpd
289− , pbUsers = mempty -- must be filled in later
290− , pbFlags = flags
291− , pbTestState = pcTests pc name
292− , pbHaddockState = pcHaddocks pc name
293− , pbTryBuildBenchmark = pcBuildBenchmark pc name
294− , pbDesc = desc
295− }
213+mkPackageBuild bc gpd = do
214+ pbDesc <- getFlattenedComponent CheckCond {..} gpd
215+ return PackageBuild {..}
296216 where
297− PackageIdentifier name version = package $ packageDescription gpd
217+ PackageIdentifier name pbVersion = package $ packageDescription gpd
218+ pbGithubPings = getGithubPings gpd
219+ pbPackageConstraints = bcPackageConstraints bc name
220+ pbUsers = mempty -- must be filled in later
221+
222+ ccPackageName = name
223+ ccOS = siOS
224+ ccArch = siArch
225+ ccCompilerFlavor = Distribution.Compiler.GHC
226+ ccCompilerVersion = siGhcVersion
227+ ccFlags = flags
228+ ccIncludeTests = pcTests pbPackageConstraints /= Don'tBuild
229+ ccIncludeBenchmarks = pcBuildBenchmarks pbPackageConstraints
230+
231+ SystemInfo {..} = bcSystemInfo bc
232+
233+ overrides = pcFlagOverrides pbPackageConstraints
234+ getFlag MkFlag {..} =
235+ (flagName, fromMaybe flagDefault $ lookup flagName overrides)
236+ flags = mapFromList $ map getFlag $ genPackageFlags gpd