git.iko.soy/typeable/stackage2nix
on master help sign in
Build Stackage packages from resolver (#33)

* Feature: build LTS from resolver flag * Rename Target to Origin * Cleanup

commitbbb88413885486b17f8ec6dd5ee0a417850294fb authorDmitry Bushev <bushevdv@gmail.com> dateWed 13 Sep 2017, 23:29 (9 years ago) parent89af70d
4 files changed+100−62
.gitignore+1 src/Runner.hs+75−55 src/Runner/Cli.hs+23−7 src/Stack/Types.hs+1
.gitignore+1
@@ -1,2 +1,3 @@
11.stack-work
2+Paths_stackage2nix.hs
23/*.nix
src/Runner.hs+75−55
@@ -2,7 +2,7 @@ module Runner ( run ) where
22
33import Control.Lens
44import Data.Foldable as F
5−import Data.Functor
5+import Data.List as L
66import Distribution.Nixpkgs.Haskell.FromStack
77import Distribution.Nixpkgs.Haskell.FromStack.Package
88import Distribution.Nixpkgs.Haskell.Stack
@@ -18,8 +18,8 @@ import Runner.Cli
1818import Stack.Config
1919import Stack.Types
2020import Stackage.Types
21−import System.IO (withFile, IOMode(..), hPutStrLn, hPrint)
22−import Text.PrettyPrint.HughesPJClass (render)
21+import System.IO (withFile, IOMode(..), hPutStrLn)
22+import Text.PrettyPrint.HughesPJClass (Doc, render)
2323
2424import qualified Data.Set as Set
2525import qualified Data.Map as Map
@@ -29,60 +29,80 @@ import qualified LtsHaskell as LH
2929run :: IO ()
3030run = do
3131 opts <- execParser pinfo
32− stackYaml <- envStackYaml >>= \case
33− Just p -> putStrLn "Getting project config file from STACK_YAML environment" $> p
34− Nothing -> pure $ opts ^. optStackYaml
35− stackConf <- either fail pure =<< readStackConfig stackYaml
36− let buildPlanFile = LH.buildPlanFilePath (opts ^. optLtsHaskellRepo) (stackConf ^. scResolver)
37− buildPlan <- LH.loadBuildPlan buildPlanFile
38− packageSetConfig <- LH.buildPackageSetConfig
39− (opts ^. optAllCabalHashesRepo)
40− (opts ^. optNixpkgsRepository)
41− buildPlan
42− -- generate haskell packages override
43− let
44− overrideConfig = mkOverrideConfig opts (siGhcVersion $ bpSystemInfo buildPlan)
45− stackPackagesConfig = mkStackPackagesConfig opts
46− packages <- traverse (packageDerivation stackPackagesConfig (opts ^. optHackageDb))
47− $ stackConf ^. scPackages
48− let out = PP.overrideHaskellPackages overrideConfig packages
49− withFile (opts ^. optOutDerivation) WriteMode $ \h -> do
50− hPutStrLn h ("# Generated by stackage2nix " ++ Text.display version ++ " from " ++ stackYaml ^. syFilePath)
51− hPrint h out
52− let
53− reachable = Set.map mkPackageName
54− $ F.foldr1 Set.union
55− $ nodeDepends . mkNode <$> packages
56− s2nLoader mHash pkgId =
57− if pkgName pkgId `Set.member` reachable
58− then packageLoader packageSetConfig Nothing pkgId
59− else packageLoader packageSetConfig mHash pkgId
60− s2nPackageSetConfig = packageSetConfig { packageLoader = s2nLoader }
61− s2nPackageConfig = PackageConfig
62− { enableCheck = opts ^. optDoCheckStackage
63− , enableHaddock = opts ^. optDoHaddockStackage }
64− allNodes <- traverse (uncurry (buildNodeM s2nPackageSetConfig s2nPackageConfig))
65− $ Map.toList (bpPackages buildPlan)
32+ case opts ^. optConfigOrigin of
33+ -- Generate build derivation from stack.yaml file
34+ OriginStackYaml stackYaml -> do
35+ stackConf <- either fail pure =<< readStackConfig stackYaml
36+ let buildPlanFile = LH.buildPlanFilePath (opts ^. optLtsHaskellRepo) (stackConf ^. scResolver)
37+ buildPlan <- LH.loadBuildPlan buildPlanFile
38+ packageSetConfig <- LH.buildPackageSetConfig
39+ (opts ^. optAllCabalHashesRepo)
40+ (opts ^. optNixpkgsRepository)
41+ buildPlan
42+ let
43+ overrideConfig = mkOverrideConfig opts (siGhcVersion $ bpSystemInfo buildPlan)
44+ stackPackagesConfig = mkStackPackagesConfig opts
45+ stackConfPackages <- traverse (packageDerivation stackPackagesConfig (opts ^. optHackageDb))
46+ $ stackConf ^. scPackages
47+ let
48+ reachable = Set.map mkPackageName
49+ $ F.foldr1 Set.union
50+ $ nodeDepends . mkNode <$> stackConfPackages
51+ s2nLoader mHash pkgId =
52+ if pkgName pkgId `Set.member` reachable
53+ then packageLoader packageSetConfig Nothing pkgId
54+ else packageLoader packageSetConfig mHash pkgId
55+ s2nPackageSetConfig = packageSetConfig { packageLoader = s2nLoader }
56+ s2nPackageConfig = PackageConfig
57+ { enableCheck = opts ^. optDoCheckStackage
58+ , enableHaddock = opts ^. optDoHaddockStackage }
59+ stackagePackages <- traverse (uncurry (buildNodeM s2nPackageSetConfig s2nPackageConfig))
60+ $ Map.toList (bpPackages buildPlan)
6661
67− -- Find all reachable dependencies in stackage set to stick into
68− -- stackage packages file. This is performed on the full stackage
69− -- set rather than pruning stackage packages beforehand because
70− -- stackage does not concern itself with build tools while cabal2nix
71− -- does: pruning only after generating full set of packages allows
72− -- us to make sure all those extra dependencies are explicitly
73− -- listed as well.
74− let nodes = case opts ^. optOutPackagesClosure of
75− True -> flip reachableDependencies allNodes
76− -- Originally reachable nodes are root nodes
77− $ filter (\n -> mkPackageName (nodeName n) `Set.member` reachable) allNodes
78− False -> allNodes
62+ -- Find all reachable dependencies in stackage set to stick into
63+ -- stackage packages file. This is performed on the full stackage
64+ -- set rather than pruning stackage packages beforehand because
65+ -- stackage does not concern itself with build tools while cabal2nix
66+ -- does: pruning only after generating full set of packages allows
67+ -- us to make sure all those extra dependencies are explicitly
68+ -- listed as well.
69+ let reachableStackagePackages = case opts ^. optOutPackagesClosure of
70+ True -> flip reachableDependencies stackagePackages
71+ -- Originally reachable nodes are root nodes
72+ $ L.filter (\n -> mkPackageName (nodeName n) `Set.member` reachable) stackagePackages
73+ False -> stackagePackages
74+ writeOutFile buildPlanFile (opts ^. optOutStackagePackages)
75+ $ pPrintOutPackages (view nodeDerivation <$> reachableStackagePackages)
76+ writeOutFile buildPlanFile (opts ^. optOutStackageConfig)
77+ $ pPrintOutConfig (bpSystemInfo buildPlan) reachableStackagePackages
78+ writeOutFile (stackYaml ^. syFilePath) (opts ^. optOutDerivation)
79+ $ PP.overrideHaskellPackages overrideConfig stackConfPackages
7980
80− withFile (opts ^. optOutStackagePackages) WriteMode $ \h -> do
81− hPutStrLn h ("# Generated by stackage2nix " ++ Text.display version ++ " from " ++ buildPlanFile)
82− hPutStrLn h $ render $ pPrintOutPackages (view nodeDerivation <$> nodes)
83− withFile (opts ^. optOutStackageConfig) WriteMode $ \h -> do
84− hPutStrLn h ("# Generated by stackage2nix " ++ Text.display version ++ " from " ++ buildPlanFile)
85− hPutStrLn h $ render $ pPrintOutConfig (bpSystemInfo buildPlan) nodes
81+ -- Generate Stackage packages from resolver
82+ OriginResolver stackResolver -> do
83+ let
84+ buildPlanFile = LH.buildPlanFilePath (opts ^. optLtsHaskellRepo) stackResolver
85+ packageConfig = PackageConfig
86+ { enableCheck = opts ^. optDoCheckStackage
87+ , enableHaddock = opts ^. optDoHaddockStackage }
88+ buildPlan <- LH.loadBuildPlan buildPlanFile
89+ packageSetConfig <- LH.buildPackageSetConfig
90+ (opts ^. optAllCabalHashesRepo)
91+ (opts ^. optNixpkgsRepository)
92+ buildPlan
93+ nodes <- traverse (uncurry (buildNodeM packageSetConfig packageConfig))
94+ $ Map.toList (bpPackages buildPlan)
95+
96+ writeOutFile buildPlanFile (opts ^. optOutStackagePackages)
97+ $ pPrintOutPackages (view nodeDerivation <$> nodes)
98+ writeOutFile buildPlanFile (opts ^. optOutStackageConfig)
99+ $ pPrintOutConfig (bpSystemInfo buildPlan) nodes
100+
101+writeOutFile :: Show source => source -> FilePath -> Doc -> IO ()
102+writeOutFile source filePath contents =
103+ withFile filePath WriteMode $ \h -> do
104+ hPutStrLn h ("# Generated by stackage2nix " ++ Text.display version ++ " from " ++ show source)
105+ hPutStrLn h $ render contents
86106
87107mkOverrideConfig :: Options -> Version -> OverrideConfig
88108mkOverrideConfig opts ghcVersion = OverrideConfig
src/Runner/Cli.hs+23−7
@@ -10,10 +10,20 @@ import Distribution.System as System
1010import qualified Distribution.Text as Text
1111import Options.Applicative as Opts
1212import Paths_stackage2nix ( version )
13+import Stack.Config
1314import Stack.Types
1415import System.Environment
1516import System.FilePath
1617
18+-- | Source that would be used to produce target derivation
19+data ConfigOrigin
20+ = OriginResolver StackResolver
21+ -- ^ Resolver to generate Stackage LTS
22+ | OriginStackYaml StackYaml
23+ -- ^ Stack config to generate build derivation
24+ deriving (Show)
25+
26+makePrisms ''ConfigOrigin
1727
1828data Options = Options
1929 { _optAllCabalHashesRepo :: !FilePath
@@ -30,7 +40,7 @@ data Options = Options
3040 , _optNixpkgsRepository :: !FilePath
3141 , _optCompilerId :: !CompilerId
3242 , _optPlatform :: !Platform
33− , _optStackYamlArg :: !FilePath
43+ , _optConfigOrigin :: !ConfigOrigin
3444 } deriving (Show)
3545
3646makeLenses ''Options
@@ -38,9 +48,6 @@ makeLenses ''Options
3848envStackYaml :: IO (Maybe StackYaml)
3949envStackYaml = fmap mkStackYaml <$> lookupEnv "STACK_YAML"
4050
41−optStackYaml :: Getter Options StackYaml
42−optStackYaml = optStackYamlArg . to mkStackYaml
43−
4451mkStackYaml :: FilePath -> StackYaml
4552mkStackYaml p = case splitFileName p of
4653 (dir, "") -> StackYaml dir "stack.yaml"
@@ -64,7 +71,7 @@ options = Options
6471 <*> nixpkgsRepository
6572 <*> compilerId
6673 <*> platform
67− <*> stackYamlArg
74+ <*> configOrigin
6875
6976pinfo :: ParserInfo Options
7077pinfo = info
@@ -143,11 +150,20 @@ doHaddockStackage = switch
143150 ( long "do-haddock-stackage"
144151 <> help "enable haddock for Stackage packages" )
145152
146−stackYamlArg :: Parser FilePath
147−stackYamlArg = Opts.argument str
153+resolver :: Parser StackResolver
154+resolver = StackResolver <$> option text
155+ ( long "resolver"
156+ <> help "stackage LTS resolver" )
157+
158+stackYamlArg :: Parser StackYaml
159+stackYamlArg = mkStackYaml <$> Opts.argument str
148160 ( metavar "STACK_YAML"
149161 <> help "path to stack.yaml file or directory" )
150162
163+configOrigin :: Parser ConfigOrigin
164+configOrigin = OriginResolver <$> resolver
165+ <|> OriginStackYaml <$> stackYamlArg
166+
151167-- inherited from cabal2nix
152168
153169hackageDb :: Parser HackageDb
src/Stack/Types.hs+1
@@ -10,6 +10,7 @@ import System.FilePath
1010data StackYaml = StackYaml
1111 { _syDirName :: !FilePath
1212 , _syFileName :: !FilePath }
13+ deriving (Ord, Eq, Show)
1314
1415makeLenses ''StackYaml
1516