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.Monoid (Monoid (..))
8import Data.Set (member)
9import qualified Data.Set as Set
10import Distribution.Package (Dependency (Dependency))
11import Distribution.PackageDescription (condExecutables,
15 condTreeConstraints, condTreeComponents, ConfVar (..), Condition(..), flagName, flagDefault, genPackageFlags)
16import Distribution.PackageDescription.Parse (ParseResult (ParseOk),
17 parsePackageDescription)
18import Distribution.Version (withinRange)
22import Data.Maybe (mapMaybe)
23import Distribution.System (buildOS, buildArch)
24import Distribution.Compiler (CompilerFlavor (GHC))
26-- | Load the raw package database.
28-- We want to put in some restrictions:
30-- * Drop all core packages. We never want to install a new version of
31-- those, nor include them in the package list.
33-- * For packages with a specific version bound, find the maximum matching
36-- * For other packages, select the maximum version number.
37loadPackageDB :: Set PackageName -- ^ core packages
38 -> Map PackageName (VersionRange, Maintainer) -- ^ additional deps
40loadPackageDB core deps = do
41 tarName <- getTarballName
42 lbs <- L.readFile tarName
43 addEntries mempty $ Tar.read lbs
45 addEntries _ (Tar.Fail e) = error $ show e
46 addEntries db Tar.Done = return db
47 addEntries db (Tar.Next e es) = addEntry db e >>= flip addEntries es
49 addEntry :: PackageDB -> Tar.Entry -> IO PackageDB
51 case getPackageVersion e of
54 | p `member` core -> return pdb
56 case Map.lookup p deps of
57 Just (vrange, _maintainer)
58 | not $ withinRange v vrange -> return pdb
60 case Tar.entryContent e of
61 Tar.NormalFile bs _ -> do
62 let (deps', hasTests) = parseDeps bs
63 return $ mappend pdb $ PackageDB $ Map.singleton p PackageInfo
66 , piHasTests = hasTests
71 case parsePackageDescription $ L8.unpack lbs of
72 ParseOk _ gpd -> (mconcat
73 [ maybe mempty (go gpd) $ condLibrary gpd
74 , mconcat $ map (go gpd . snd) $ condExecutables gpd
75 , mconcat $ map (go gpd . snd) $ condTestSuites gpd
76 , mconcat $ map (go gpd . snd) $ condBenchmarks gpd
77 ], not $ null $ condTestSuites gpd)
78 _ -> (mempty, defaultHasTestSuites)
82 $ Set.fromList (map (\(Dependency p _) -> p) $ condTreeConstraints tree)
83 : map (go gpd) (mapMaybe (checkCond gpd) $ condTreeComponents tree)
85 checkCond gpd (cond, tree, melse)
86 | checkCond' cond = Just tree
89 checkCond' (Var (OS os)) = os == buildOS
90 checkCond' (Var (Arch arch)) = arch == buildArch
91 checkCond' (Var (Flag flag)) = flag `elem` flags
92 checkCond' (Var (Impl compiler range)) =
93 compiler == GHC && withinRange targetCompilerVersion range
94 checkCond' (Lit b) = b
95 checkCond' (CNot c) = not $ checkCond' c
96 checkCond' (COr c1 c2) = checkCond' c1 || checkCond' c2
97 checkCond' (CAnd c1 c2) = checkCond' c1 && checkCond' c2
99 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