1module Stackage.LoadDatabase where
3import qualified Codec.Archive.Tar as Tar
4import qualified Data.ByteString.Lazy as L
5import qualified Data.ByteString.Lazy.Char8 as L8
6import qualified Data.Map as Map
7import Data.Maybe (mapMaybe)
8import Data.Monoid (Monoid (..))
9import Data.Set (member)
10import qualified Data.Set as Set
11import Distribution.Compiler (CompilerFlavor (GHC))
12import Distribution.Package (Dependency (Dependency))
13import Distribution.PackageDescription (Condition (..),
17 buildInfo, buildTools,
25 flagDefault, flagName,
30import Distribution.PackageDescription.Parse (ParseResult (ParseOk),
31 parsePackageDescription)
32import Distribution.System (buildArch, buildOS)
33import Distribution.Version (withinRange, unionVersionRanges)
38-- | Load the raw package database.
40-- We want to put in some restrictions:
42-- * Drop all core packages. We never want to install a new version of
43-- those, nor include them in the package list.
45-- * For packages with a specific version bound, find the maximum matching
48-- * For other packages, select the maximum version number.
49loadPackageDB :: Set PackageName -- ^ core packages
50 -> Map PackageName (VersionRange, Maintainer) -- ^ additional deps
52loadPackageDB core deps = do
53 tarName <- getTarballName
54 lbs <- L.readFile tarName
55 addEntries mempty $ Tar.read lbs
57 addEntries _ (Tar.Fail e) = error $ show e
58 addEntries db Tar.Done = return db
59 addEntries db (Tar.Next e es) = addEntry db e >>= flip addEntries es
61 addEntry :: PackageDB -> Tar.Entry -> IO PackageDB
63 case getPackageVersion e of
66 | p `member` core -> return pdb
68 case Map.lookup p deps of
69 Just (vrange, _maintainer)
70 | not $ withinRange v vrange -> return pdb
72 case Tar.entryContent e of
73 Tar.NormalFile bs _ -> do
74 let (deps', hasTests, buildTools) = parseDeps bs
75 return $ mappend pdb $ PackageDB $ Map.singleton p PackageInfo
78 , piHasTests = hasTests
79 , piBuildTools = buildTools
84 case parsePackageDescription $ L8.unpack lbs of
85 ParseOk _ gpd -> (mconcat
86 [ maybe mempty (go gpd) $ condLibrary gpd
87 , mconcat $ map (go gpd . snd) $ condExecutables gpd
88 , mconcat $ map (go gpd . snd) $ condTestSuites gpd
89 , mconcat $ map (go gpd . snd) $ condBenchmarks gpd
90 ], not $ null $ condTestSuites gpd
91 , Set.fromList $ map depName $ allBuildInfo gpd)
92 _ -> (mempty, defaultHasTestSuites, Set.empty)
94 allBuildInfo gpd = concat
95 [ maybe mempty (goBI libBuildInfo) $ condLibrary gpd
96 , concat $ map (goBI buildInfo . snd) $ condExecutables gpd
97 , concat $ map (goBI testBuildInfo . snd) $ condTestSuites gpd
98 , concat $ map (goBI benchmarkBuildInfo . snd) $ condBenchmarks gpd
101 goBI f x = buildTools $ f $ condTreeData x
102 depName (Dependency p _) = p
104 = Map.unionsWith unionVersionRanges
105 $ Map.fromList (map (\(Dependency p vr) -> (p, vr)) $ condTreeConstraints tree)
106 : map (go gpd) (mapMaybe (checkCond gpd) $ condTreeComponents tree)
108 checkCond gpd (cond, tree, melse)
109 | checkCond' cond = Just tree
112 checkCond' (Var (OS os)) = os == buildOS
113 checkCond' (Var (Arch arch)) = arch == buildArch
114 checkCond' (Var (Flag flag)) = flag `elem` flags
115 checkCond' (Var (Impl compiler range)) =
116 compiler == GHC && withinRange targetCompilerVersion range
117 checkCond' (Lit b) = b
118 checkCond' (CNot c) = not $ checkCond' c
119 checkCond' (COr c1 c2) = checkCond' c1 || checkCond' c2
120 checkCond' (CAnd c1 c2) = checkCond' c1 && checkCond' c2
122 flags = map flagName $ filter flagDefault $ genPackageFlags gpd
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