git.iko.soy/typeable/stackage2nix
on master help sign in
Merge stack2nix and stackage2nix executables
commit4028855d9fd87177a90c0c66dfddef2591752d9c authorDmitry Bushev <bushevdv@gmail.com> dateThu 17 Aug 2017, 00:30 (9 years ago) parentce44008
6 files changed+114−230
src/Distribution/Nixpkgs/Haskell/FromStack.hs+12−11 src/LtsHaskell.hs+68 src/Runner.hs+30−34 src/Stackage2nix.hs−167 stack2nix.cabal+4−12 stackage2nix/Main.hs−6
src/Distribution/Nixpkgs/Haskell/FromStack.hs+12−11
@@ -23,10 +23,11 @@ data PackageSetConfig = PackageSetConfig
2323 , nixpkgsResolver :: NixpkgsResolver
2424 , packageLoader :: Maybe SHA1Hash -> PackageIdentifier -> IO Package
2525 , targetPlatform :: Platform
26− , targetCompiler :: CompilerInfo
27− , enableCheck :: Bool
28− , enableHaddock :: Bool
29− }
26+ , targetCompiler :: CompilerInfo }
27+
28+data PackageConfig = PackageConfig
29+ { enableCheck :: Bool
30+ , enableHaddock :: Bool }
3031
3132removeTests :: GenericPackageDescription -> GenericPackageDescription
3233removeTests gd = gd { condTestSuites = [] }
@@ -36,23 +37,23 @@ planDependencies = map makeDependency . Map.toList . sdPackages . ppDesc
3637 where
3738 makeDependency (name, depInfo) = Dependency name (diRange depInfo)
3839
39−buildNodeM :: PackageSetConfig -> PackageName -> PackagePlan -> IO Node
40−buildNodeM conf name plan = do
40+buildNodeM :: PackageSetConfig -> PackageConfig -> PackageName -> PackagePlan -> IO Node
41+buildNodeM conf pconf name plan = do
4142 let
4243 cabalHashes = maybe mempty cfiHashes $ ppCabalFileInfo plan
4344 mGitSha1 = Map.lookup "GitSHA1" cabalHashes
4445 pkg <- packageLoader conf mGitSha1 $ PackageIdentifier name (ppVersion plan)
45− pure . mkNode $ fromPackage conf plan pkg
46+ pure . mkNode $ fromPackage conf pconf plan pkg
4647
47−fromPackage :: PackageSetConfig -> PackagePlan -> Package -> Derivation
48−fromPackage conf plan pkg =
48+fromPackage :: PackageSetConfig -> PackageConfig -> PackagePlan -> Package -> Derivation
49+fromPackage conf pconf plan pkg =
4950 let
5051 constraints = ppConstraints plan
5152 testsEnabled =
52− enableCheck conf &&
53+ enableCheck pconf &&
5354 pcTests constraints == ExpectSuccess
5455 haddocksEnabled =
55− enableHaddock conf &&
56+ enableHaddock pconf &&
5657 pcHaddocks constraints == ExpectSuccess &&
5758 not (Set.null (sdModules (ppDesc plan)))
5859 configureTests
src/LtsHaskell.hsnew file+68
@@ -0,0 +1,68 @@
1+module LtsHaskell where
2+
3+import AllCabalHashes
4+import Stackage.BuildPlan
5+import Stackage.Types (SystemInfo(..))
6+import Distribution.Text (display)
7+import Control.Monad
8+import Distribution.Compiler (CompilerInfo(..), AbiTag(NoAbiTag), CompilerId(..), CompilerFlavor(GHC))
9+import Distribution.System (Platform(..))
10+import Distribution.Package (PackageName, PackageIdentifier(..), Dependency(..))
11+import Distribution.Nixpkgs.Haskell.PackageSourceSpec
12+import Distribution.Nixpkgs.Haskell.FromStack
13+import Distribution.Nixpkgs.Fetch
14+import Distribution.Nixpkgs.PackageMap (readNixpkgPackageMap, resolve)
15+import Distribution.Version (Version, withinRange)
16+import Language.Haskell.Extension (Language(Haskell98, Haskell2010))
17+import Language.Nix
18+import Control.Lens
19+import Data.Maybe
20+
21+import qualified Data.Yaml as Yaml
22+import qualified Data.Map as Map
23+import qualified Data.Set as Set
24+
25+
26+loadBuildPlan :: FilePath -> IO BuildPlan
27+loadBuildPlan = Yaml.decodeFileEither >=> \case
28+ Left err -> fail $ "Failed to parse stackage build plan: " ++ show err
29+ Right bp -> return bp
30+
31+loadPackage :: FilePath -> Maybe SHA1Hash -> PackageIdentifier -> IO Package
32+loadPackage allCabalHashesPath mSha1Hash pkgId = do
33+ (pkgDesc, _) <- case mSha1Hash of
34+ Just sha1 -> readPackageByHash allCabalHashesPath sha1
35+ Nothing -> readPackageByName allCabalHashesPath pkgId
36+ meta <- readPackageMeta allCabalHashesPath pkgId
37+ let
38+ tarballSHA256 = fromMaybe
39+ (error (display pkgId ++ ": meta data has no SHA256 hash for the tarball"))
40+ (view (mHashes . at "SHA256") meta)
41+ source = DerivationSource "url" ("mirror://hackage/" ++ display pkgId ++ ".tar.gz") "" tarballSHA256
42+ return $ Package source pkgDesc
43+
44+ghcCompilerInfo :: Version -> CompilerInfo
45+ghcCompilerInfo v = CompilerInfo
46+ { compilerInfoId = CompilerId GHC v
47+ , compilerInfoAbiTag = NoAbiTag
48+ , compilerInfoCompat = Just []
49+ , compilerInfoLanguages = Just [Haskell98, Haskell2010]
50+ , compilerInfoExtensions = Nothing
51+ }
52+
53+buildPlanContainsDependency :: Map.Map PackageName Version -> Dependency -> Bool
54+buildPlanContainsDependency packageVersions (Dependency depName versionRange) =
55+ maybe False (`withinRange` versionRange) $ Map.lookup depName packageVersions
56+
57+buildPackageSetConfig :: FilePath -> FilePath -> BuildPlan -> IO PackageSetConfig
58+buildPackageSetConfig optAllCabalHashes optNixpkgsRepository buildPlan = do
59+ nixpkgs <- readNixpkgPackageMap optNixpkgsRepository Nothing
60+ let
61+ systemInfo = bpSystemInfo buildPlan
62+ packageVersions = fmap ppVersion (bpPackages buildPlan) `Map.union` siCorePackages systemInfo
63+ return PackageSetConfig
64+ { packageLoader = loadPackage optAllCabalHashes
65+ , targetPlatform = Platform (siArch systemInfo) (siOS systemInfo)
66+ , targetCompiler = ghcCompilerInfo (siGhcVersion systemInfo)
67+ , nixpkgsResolver = resolve (Map.map (Set.map (over path ("pkgs":))) nixpkgs)
68+ , haskellResolver = buildPlanContainsDependency packageVersions }
src/Runner.hs+30−34
@@ -22,7 +22,7 @@ import Text.PrettyPrint.HughesPJClass (render)
2222
2323import qualified Data.Set as Set
2424import qualified Data.Map as Map
25−import qualified Stackage2nix as S2n
25+import qualified LtsHaskell as LH
2626
2727
2828run :: IO ()
@@ -33,23 +33,20 @@ run = do
3333 Nothing -> pure $ opts ^. optStackYaml
3434 stackConf <- either fail pure =<< readStackConfig stackYaml
3535 let
36− s2nOpts = mkS2nOptions stackConf opts
37− (buildPlan, packageSetConfig) <- S2n.run s2nOpts
36+ buildPlanFile =
37+ (opts ^. optLtsHaskellRepo) Path.</>
38+ (stackConf ^. scResolver . to unStackResolver) Path.<.>
39+ ".yaml"
40+ buildPlan <- LH.loadBuildPlan buildPlanFile
41+ packageSetConfig <- LH.buildPackageSetConfig
42+ (opts ^. optAllCabalHashesRepo)
43+ (opts ^. optNixpkgsRepository)
44+ buildPlan
3845 -- generate haskell packages override
3946 let
4047 overrideConfig = mkOverrideConfig opts (siGhcVersion $ bpSystemInfo buildPlan)
41− pkgConfig = StackPackagesConfig
42− { _spcHaskellResolver = const True
43− , _spcNixpkgsResolver = \i -> Just (Nix.binding # (i, Nix.path # [i]))
44− , _spcTargetPlatform = opts ^. optPlatform
45− , _spcTargetCompiler = unknownCompilerInfo (opts ^. optCompilerId) NoAbiTag
46− , _spcFlagAssignment = []
47− , _spcDoCheckPackages = opts ^. optDoCheckPackages
48− , _spcDoHaddockPackages = opts ^. optDoHaddockPackages
49− , _spcDoCheckStackage = opts ^. optDoCheckStackage
50− , _spcDoHaddockStackage = opts ^. optDoHaddockStackage
51− }
52− packages <- traverse (packageDerivation pkgConfig (opts ^. optHackageDb))
48+ stackPackagesConfig = mkStackPackagesConfig opts
49+ packages <- traverse (packageDerivation stackPackagesConfig (opts ^. optHackageDb))
5350 $ stackConf ^. scPackages
5451 let out = PP.overrideHaskellPackages overrideConfig packages
5552 withFile (opts ^. optOutDerivation) WriteMode $ \h -> do
@@ -64,14 +61,17 @@ run = do
6461 then packageLoader packageSetConfig Nothing pkgId
6562 else packageLoader packageSetConfig mHash pkgId
6663 s2nPackageSetConfig = packageSetConfig { packageLoader = s2nLoader }
64+ s2nPackageConfig = PackageConfig
65+ { enableCheck = opts ^. optDoCheckStackage
66+ , enableHaddock = opts ^. optDoHaddockStackage }
6767 -- generate stackage packages
68− nodes <- traverse (uncurry (buildNodeM s2nPackageSetConfig))
68+ nodes <- traverse (uncurry (buildNodeM s2nPackageSetConfig s2nPackageConfig))
6969 $ Map.toList (bpPackages buildPlan)
7070 withFile (opts ^. optOutStackagePackages) WriteMode $ \h -> do
71− hPutStrLn h ("# Generated by stack2nix from " ++ S2n.optBuildPlanFile s2nOpts)
71+ hPutStrLn h ("# Generated by stack2nix from " ++ buildPlanFile)
7272 hPutStrLn h $ render $ pPrintOutPackages (view nodeDerivation <$> nodes)
7373 withFile (opts ^. optOutStackageConfig) WriteMode $ \h -> do
74− hPutStrLn h ("# Generated by stack2nix from " ++ S2n.optBuildPlanFile s2nOpts)
74+ hPutStrLn h ("# Generated by stack2nix from " ++ buildPlanFile)
7575 hPutStrLn h $ render $ pPrintOutConfig (bpSystemInfo buildPlan) nodes
7676
7777mkOverrideConfig :: Options -> Version -> OverrideConfig
@@ -79,20 +79,16 @@ mkOverrideConfig opts ghcVersion = OverrideConfig
7979 { _ocGhc = ghcVersion
8080 , _ocStackagePackages = opts ^. optOutStackagePackages
8181 , _ocStackageConfig = opts ^. optOutStackageConfig
82− , _ocNixpkgs = opts ^. optNixpkgsRepository
83− }
82+ , _ocNixpkgs = opts ^. optNixpkgsRepository }
8483
85−mkS2nOptions :: StackConfig -> Options -> S2n.Options
86−mkS2nOptions conf opts = S2n.Options
87− { S2n.optBuildPlanFile =
88− (opts ^. optLtsHaskellRepo) Path.</>
89− (conf ^. scResolver . to unStackResolver) Path.<.>
90− ".yaml"
91− , S2n.optAllCabalHashes = opts ^. optAllCabalHashesRepo
92− , S2n.optNixpkgsRepository = opts ^. optNixpkgsRepository
93− , S2n.optNixpkgsMap = Nothing
94− , S2n.optOutPackages = opts ^. optOutStackagePackages
95− , S2n.optOutConfig = opts ^. optOutStackageConfig
96− , S2n.optDoCheck = opts ^. optDoCheckStackage
97− , S2n.optDoHaddock = opts ^. optDoHaddockStackage
98− }
84+mkStackPackagesConfig :: Options -> StackPackagesConfig
85+mkStackPackagesConfig opts = StackPackagesConfig
86+ { _spcHaskellResolver = const True
87+ , _spcNixpkgsResolver = \i -> Just (Nix.binding # (i, Nix.path # [i]))
88+ , _spcTargetPlatform = opts ^. optPlatform
89+ , _spcTargetCompiler = unknownCompilerInfo (opts ^. optCompilerId) NoAbiTag
90+ , _spcFlagAssignment = []
91+ , _spcDoCheckPackages = opts ^. optDoCheckPackages
92+ , _spcDoHaddockPackages = opts ^. optDoHaddockPackages
93+ , _spcDoCheckStackage = opts ^. optDoCheckStackage
94+ , _spcDoHaddockStackage = opts ^. optDoHaddockStackage }
src/Stackage2nix.hsdeleted−167
@@ -1,167 +0,0 @@
1−{-# LANGUAGE FlexibleContexts #-}
2−{-# LANGUAGE PartialTypeSignatures #-}
3−{-# LANGUAGE ScopedTypeVariables #-}
4−
5−module Stackage2nix where
6−
7−import AllCabalHashes
8−import Data.Monoid
9−import Options.Applicative
10−import Stackage.BuildPlan
11−import Stackage.Types (SystemInfo(..))
12−import Paths_stack2nix as Main
13−import Distribution.Text (display)
14−import Control.Monad
15−import Text.PrettyPrint.HughesPJClass hiding ((<>))
16−import Distribution.Compiler (CompilerInfo(..), AbiTag(NoAbiTag), CompilerId(..), CompilerFlavor(GHC))
17−import Distribution.System (Platform(..))
18−import Distribution.Package (PackageName, PackageIdentifier(..), Dependency(..))
19−import Distribution.Nixpkgs.Haskell.PackageSourceSpec
20−import Distribution.Nixpkgs.Haskell.FromStack
21−import Distribution.Nixpkgs.Haskell.FromStack.Package
22−import Distribution.Nixpkgs.Fetch
23−import Distribution.Nixpkgs.PackageMap (readNixpkgPackageMap, resolve, PackageMap)
24−import Distribution.Version (Version, withinRange)
25−import Language.Haskell.Extension (Language(Haskell98, Haskell2010))
26−import Language.Nix
27−import Control.Lens
28−import Data.Maybe
29−import System.IO (withFile, IOMode(..), hPutStrLn)
30−
31−import qualified Data.Aeson as Aeson
32−import qualified Data.Yaml as Yaml
33−import qualified Data.Map as Map
34−import qualified Data.Set as Set
35−import qualified Data.ByteString as ByteString
36−import qualified Data.Text as Text
37−import qualified Data.HashMap.Strict as HashMap
38−
39−
40−data Options = Options
41− { optBuildPlanFile :: FilePath
42− , optAllCabalHashes :: FilePath
43− , optDoCheck :: Bool
44− , optDoHaddock :: Bool
45− , optNixpkgsRepository :: FilePath
46− , optNixpkgsMap :: Maybe FilePath
47− , optOutPackages :: FilePath
48− , optOutConfig :: FilePath
49− }
50−
51−options :: Parser Options
52−options = Options
53− <$> strArgument (metavar "PLAN" <> help "stackage build plan (YAML)")
54− <*> strArgument (metavar "CABALFILES" <> help "path to checkout of all-cabal-hashes")
55− <*> switch (long "do-check" <> help "enable tests for Stackage packages")
56− <*> switch (long "do-haddock" <> help "enable haddock for Stackage packages")
57− <*> strOption (long "nixpkgs" <> help "path to Nixpkgs repository" <> value "<nixpkgs>" <> showDefaultWith id <> metavar "PATH")
58− <*> optional (strOption (long "package-map" <> help "path to a serialized nixpkgs package map" <> metavar "PATH"))
59− <*> strOption (long "out-packages" <> help "name of the output file for the package set" <> value "packages.nix" <> metavar "PATH")
60− <*> strOption (long "out-config" <> help "name of the output file for the package set configuration" <> value "configuration-packages.nix" <> metavar "PATH")
61−
62−pinfo :: ParserInfo Options
63−pinfo = info
64− ( helper
65− <*> infoOption ("stackage2nix " ++ display Main.version) (long "version" <> help "Show version number")
66− <*> options
67− )
68− ( fullDesc
69− <> header "stackage2nix converts stackage snapshots into a nix package set"
70− )
71−
72−loadBuildPlan :: FilePath -> IO BuildPlan
73−loadBuildPlan = Yaml.decodeFileEither >=> \case
74− Left err -> fail $ "Failed to parse stackage build plan: " ++ show err
75− Right bp -> return bp
76−
77−loadPackage :: FilePath -> Maybe SHA1Hash -> PackageIdentifier -> IO Package
78−loadPackage allCabalHashesPath mSha1Hash pkgId = do
79− (pkgDesc, _) <- case mSha1Hash of
80− Just sha1 -> readPackageByHash allCabalHashesPath sha1
81− Nothing -> readPackageByName allCabalHashesPath pkgId
82− meta <- readPackageMeta allCabalHashesPath pkgId
83− let
84− tarballSHA256 = fromMaybe
85− (error (display pkgId ++ ": meta data has no SHA256 hash for the tarball"))
86− (view (mHashes . at "SHA256") meta)
87− source = DerivationSource "url" ("mirror://hackage/" ++ display pkgId ++ ".tar.gz") "" tarballSHA256
88− return $ Package source pkgDesc
89−
90−ghcCompilerInfo :: Version -> CompilerInfo
91−ghcCompilerInfo v = CompilerInfo
92− { compilerInfoId = CompilerId GHC v
93− , compilerInfoAbiTag = NoAbiTag
94− , compilerInfoCompat = Just []
95− , compilerInfoLanguages = Just [Haskell98, Haskell2010]
96− , compilerInfoExtensions = Nothing
97− }
98−
99−buildPlanContainsDependency :: Map.Map PackageName Version -> Dependency -> Bool
100−buildPlanContainsDependency packageVersions (Dependency depName versionRange) =
101− maybe False (`withinRange` versionRange) $ Map.lookup depName packageVersions
102−
103−newtype SerializablePackageMap = SerializablePackageMap { getPackageMap :: PackageMap }
104−
105−instance Aeson.ToJSON SerializablePackageMap where
106− toJSON (SerializablePackageMap m) = Aeson.object . map makeEntry $ Map.toList m
107− where
108− makeEntry (i, s) = (Text.pack (view ident i), Aeson.toJSON . map makePath $ Set.toList s)
109− makePath = view (path . mapping ident)
110−
111−instance Aeson.FromJSON SerializablePackageMap where
112− parseJSON = Aeson.withObject "package map object" $
113− fmap (SerializablePackageMap . Map.fromList) . traverse makeEntry . HashMap.toList
114− where
115− makeEntry (i, s) = Aeson.parseJSON s <&> \s' -> (ident # Text.unpack i, Set.fromList (map makePath s'))
116− makePath = review (path . mapping ident)
117−
118−run :: Options -> IO (BuildPlan, PackageSetConfig)
119−run Options{..} = do
120− nixpkgs <- fromMaybe (readNixpkgPackageMap optNixpkgsRepository Nothing) $ do
121− mapFile <- optNixpkgsMap
122− return $ do
123− contents <- ByteString.readFile mapFile
124− case Aeson.eitherDecodeStrict contents of
125− Left err -> fail $ "Failed to decode package map " ++ show mapFile ++ ": " ++ err
126− Right v -> return $ getPackageMap v
127−
128− buildPlan <- loadBuildPlan optBuildPlanFile
129−
130− let
131− systemInfo = bpSystemInfo buildPlan
132− packageVersions = fmap ppVersion (bpPackages buildPlan) `Map.union` siCorePackages systemInfo
133− conf = PackageSetConfig
134− { packageLoader = loadPackage optAllCabalHashes
135− , targetPlatform = Platform (siArch systemInfo) (siOS systemInfo)
136− , targetCompiler = ghcCompilerInfo (siGhcVersion systemInfo)
137− , nixpkgsResolver = resolve (Map.map (Set.map (over path ("pkgs":))) nixpkgs)
138− , haskellResolver = buildPlanContainsDependency packageVersions
139− , enableCheck = optDoCheck
140− , enableHaddock = optDoHaddock
141− }
142− return (buildPlan, conf)
143−
144−writeOutPackages :: FilePath -> FilePath -> [Node] -> IO ()
145−writeOutPackages optBuildPlanFile optOutPackages nodes =
146− withFile optOutPackages WriteMode $ \h -> do
147− hPutStrLn h ("# Generated by stackage2nix from " ++ optBuildPlanFile)
148− hPutStrLn h $ render $ pPrintOutPackages (view nodeDerivation <$> nodes)
149−
150−writeOutConfig :: FilePath -> FilePath -> SystemInfo -> [Node] -> IO ()
151−writeOutConfig optBuildPlanFile optOutConfig systemInfo nodes =
152− withFile optOutConfig WriteMode $ \h -> do
153− hPutStrLn h ("# Generated by stackage2nix from " ++ optBuildPlanFile)
154− hPutStrLn h $ render $ pPrintOutConfig systemInfo nodes
155−
156−main :: IO ()
157−main = do
158− opts@Options{..} <- execParser pinfo
159− (buildPlan, conf) <- run opts
160− let systemInfo = bpSystemInfo buildPlan
161− nodes <- traverse (uncurry $ buildNodeM conf) $ Map.toList (bpPackages buildPlan)
162− withFile optOutPackages WriteMode $ \h -> do
163− hPutStrLn h ("# Generated by stackage2nix from " ++ optBuildPlanFile)
164− hPutStrLn h $ render $ pPrintOutPackages (view nodeDerivation <$> nodes)
165− withFile optOutConfig WriteMode $ \h -> do
166− hPutStrLn h ("# Generated by stackage2nix from " ++ optBuildPlanFile)
167− hPutStrLn h $ render $ pPrintOutConfig systemInfo nodes
stack2nix.cabal+4−12
@@ -13,8 +13,7 @@ cabal-version: >=1.10
1313
1414library
1515 hs-source-dirs: src
16− exposed-modules: AllCabalHashes
17− , Distribution.Nixpkgs.Haskell.FromStack
16+ exposed-modules: Distribution.Nixpkgs.Haskell.FromStack
1817 , Distribution.Nixpkgs.Haskell.FromStack.Package
1918 , Distribution.Nixpkgs.Haskell.Packages.PrettyPrinting
2019 , Distribution.Nixpkgs.Haskell.Stack
@@ -26,8 +25,9 @@ library
2625 , Stack.Config.TH
2726 , Stack.Config.Yaml
2827 , Stack.Types
29− , Stackage2nix
30− other-modules: Paths_stack2nix
28+ other-modules: AllCabalHashes
29+ , LtsHaskell
30+ , Paths_stack2nix
3131 build-depends: base > 4.7 && < 5
3232 , Cabal > 1.24
3333 , QuickCheck
@@ -58,14 +58,6 @@ library
5858 default-language: Haskell2010
5959 ghc-options: -Wall -funbox-strict-fields
6060
61−executable stackage2nix
62− hs-source-dirs: stackage2nix
63− main-is: Main.hs
64− ghc-options: -Wall -threaded -rtsopts -with-rtsopts=-N
65− build-depends: base
66− , stack2nix
67− default-language: Haskell2010
68−
6961executable stack2nix
7062 hs-source-dirs: stack2nix
7163 main-is: Main.hs
stackage2nix/Main.hsdeleted−6
@@ -1,6 +0,0 @@
1−module Main ( main ) where
2−
3−import qualified Stackage2nix as S
4−
5−main :: IO ()
6−main = S.main