1{-# LANGUAGE RecordWildCards #-}
2{-# LANGUAGE TupleSections #-}
3module Stackage.InstallInfo
8import Control.Monad (forM_, unless)
9import Data.List (foldl')
10import qualified Data.Map as Map
11import qualified Data.Set as Set
12import Data.Time (getCurrentTime, formatTime)
13import Data.Version (showVersion)
14import qualified Distribution.Text
15import Distribution.Version (simplifyVersionRange, withinRange)
17import Stackage.HaskellPlatform
18import Stackage.LoadDatabase
19import Stackage.NarrowDatabase
20import Stackage.ServerFiles
23import System.Directory (createDirectoryIfMissing)
24import System.FilePath ((</>))
25import qualified System.IO as IO
26import qualified System.IO.UTF8
27import System.Locale (defaultTimeLocale)
28import System.Exit (exitFailure)
30dropExcluded :: SelectSettings
31 -> Map PackageName (VersionRange, Maintainer)
32 -> Map PackageName (VersionRange, Maintainer)
34 foldl' (flip Map.delete) m0 (Set.toList $ excludedPackages bs)
36getInstallInfo :: SelectSettings -> IO InstallInfo
37getInstallInfo settings = do
38 putStrLn "Loading Haskell Platform"
39 mhp <- loadHaskellPlatform settings
43 Just hp | not (useGlobalDatabase settings) -> return $ hpcore hp
45 putStrLn "Loading core packages from global database"
46 getGlobalPackages $ selectGhcVersion settings
47 let coreMap = Map.unions
48 $ map (\(PackageIdentifier k v) -> Map.singleton k v)
53 Just hp | requireHaskellPlatform settings ->
54 Map.union (stablePackages settings $ requireHaskellPlatform settings)
55 $ identsToRanges (hplibs hp)
56 _ -> stablePackages settings $ requireHaskellPlatform settings
57 allPackages = dropExcluded settings allPackages'
59 | ignoreUpgradeableCore settings =
60 Map.fromList $ map (\n -> (PackageName n, Nothing)) $ words "base containers template-haskell"
62 Map.fromList (map (\(PackageIdentifier p v) -> (p, Just v)) (Set.toList core))
63 `Map.union` Map.fromList (map (, Nothing) (Set.toList $ extraCore settings))
65 putStrLn "Loading package database"
66 pdb <- loadPackageDB settings coreMap (Map.keysSet totalCore) allPackages
68 putStrLn "Narrowing package database"
69 (final, errs) <- narrowPackageDB settings (Map.keysSet totalCore) pdb $ Set.fromList $ Map.toList $ Map.map snd $ allPackages
71 putStrLn "Printing build plan to build-plan.log"
72 System.IO.UTF8.writeFile "build-plan.log" $ unlines $ map showDep $ Map.toList final
73 System.IO.UTF8.writeFile "hackage-map.txt" $ unlines $ map showHackageMap $ Map.toList final
75 unless (Set.null errs) $ do
76 putStrLn "Build plan requires some disallowed packages"
77 mapM_ putStrLn $ Set.toList errs
80 putStrLn "Checking for bad versions"
81 case checkBadVersions settings coreMap pdb final of
83 | Map.null badVersions -> return ()
85 forM_ (Map.toList badVersions) $ \(user, badDeps) -> do
86 putStrLn $ user ++ " cannot use: "
87 forM_ (Map.toList badDeps) $ \(name, (version, range)) -> do
90 , packageVersionString (name, version)
92 , Distribution.Text.display $ simplifyVersionRange range
96 error "Conflicting build plan, exiting"
100 , iiPackages = Map.map biToSPI final
101 , iiOptionalCore = maybe
103 (Map.fromList . map (\(PackageIdentifier p v) -> (p, v)) . Set.toList . hplibs)
108 forM_ [False, True] $ \isInc -> do
109 let incexc = if isInc then "inclusive" else "exclusive"
111 now <- getCurrentTime
113 let GhcMajorVersion x y = selectGhcVersion settings
114 in show x ++ "." ++ show y
115 date = formatTime defaultTimeLocale "%Y-%m-%d" now
117 createDirectoryIfMissing True incexc
119 putStrLn $ "Inclusive/exclusive: " ++ incexc
121 putStrLn "Creating hackage file (for publishing to Stackage server)"
122 IO.withBinaryFile (incexc </> "hackage") IO.WriteMode $ \hackageH ->
123 IO.withBinaryFile (incexc </> "create-snapshot.sh") IO.WriteMode
124 (createHackageFile isInc ii ghcVer date hackageH)
126 putStrLn "Creating desc file (for publishing to Stackage server)"
127 System.IO.UTF8.writeFile (incexc </> "desc") $ concat
128 [ "Stackage build for GHC "
140biToSPI :: BuildInfo -> SelectedPackageInfo
141biToSPI BuildInfo {..} = SelectedPackageInfo
142 { spiVersion = biVersion
143 , spiMaintainer = biMaintainer
144 , spiGithubUser = biGithubUser
145 , spiHasTests = biHasTests
148showDep :: (PackageName, BuildInfo) -> String
149showDep (PackageName name, BuildInfo {..}) =
153 , showVersion biVersion
155 , unMaintainer biMaintainer
156 , " " ++ githubMentions biGithubUser
159 , unwords $ map unP biUsers
162 unP (PackageName p) = p
164-- | Convert to format used by Hackage for displaying distribution versions.
165-- For more info, see https://github.com/fpco/stackage/issues/38.
166showHackageMap :: (PackageName, BuildInfo) -> String
167showHackageMap (PackageName name, BuildInfo {..}) =
168 show (name, showVersion biVersion, Nothing :: Maybe String)
170bpPackageList :: BuildPlan -> [String]
171bpPackageList = map packageVersionString . Map.toList . Map.map spiVersion . bpPackages
173-- | Check for internal mismatches in required and actual package versions.
174checkBadVersions :: SelectSettings
175 -> Map PackageName Version -- ^ core
177 -> Map PackageName BuildInfo
178 -> Map String (Map PackageName (Version, VersionRange))
179checkBadVersions settings core (PackageDB pdb) buildPlan =
180 Map.unions $ map getBadVersions $ Map.toList $ Map.filterWithKey unexpectedFailure buildPlan
182 unexpectedFailure name _ = name `Set.notMember` expectedFailuresSelect settings
184 getBadVersions :: (PackageName, BuildInfo) -> Map String (Map PackageName (Version, VersionRange))
185 getBadVersions (name, bi)
186 | Map.null badVersions = Map.empty
187 | otherwise = Map.singleton display badVersions
189 badVersions = Map.unions $ map (uncurry checkPackage) $ Map.toList $ biDeps bi
191 [ packageVersionString (name, biVersion bi)
193 , unMaintainer $ biMaintainer bi
194 , case Map.lookup name pdb of
195 Just PackageInfo { piGithubUser = gus } -> " " ++ githubMentions gus
200 checkPackage :: PackageName -> VersionRange -> Map PackageName (Version, VersionRange)
201 checkPackage name vr =
202 case Map.lookup name buildPlan of
204 case Map.lookup name core of
205 -- Might be part of extra-core
208 | version `withinRange` vr -> Map.empty
209 | otherwise -> Map.singleton name (version, vr)
211 | biVersion bi `withinRange` vr -> Map.empty
212 | otherwise -> Map.singleton name (biVersion bi, vr)
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list