git.iko.soy/typeable/stackage2nix
on master help sign in
Upd make all-cabal-hashes and lts-haskell optional
6d71d97Dmitry Bushev
src/Runner.hs+67−44
@@ -3,6 +3,8 @@ module Runner ( run ) where
3import Control.Lens
3import Control.Lens
4import Data.Foldable as F
4import Data.Foldable as F
5import Data.List as L
5import Data.List as L
6+import Data.Maybe (fromMaybe)
7+import Data.Semigroup ((<>))
6import Distribution.Nixpkgs.Haskell.FromStack
8import Distribution.Nixpkgs.Haskell.FromStack
7import Distribution.Nixpkgs.Haskell.FromStack.Package
9import Distribution.Nixpkgs.Haskell.FromStack.Package
8import Distribution.Nixpkgs.Haskell.Stack
10import Distribution.Nixpkgs.Haskell.Stack
@@ -25,44 +27,43 @@ import qualified Data.Set as Set
25import qualified Data.Map as Map
27import qualified Data.Map as Map
26import qualified LtsHaskell as LH
28import qualified LtsHaskell as LH
27
29
28−
29run :: IO ()
30run :: IO ()
30run = do
31run = do
31 opts <- execParser pinfo
32 opts <- execParser pinfo
33+ let
34+ -- With optparse-applicative it seems there's no way to make
35+ -- 'StackageOptions' optional for stackage override and required in
36+ -- other cases
37+ missingErr = error . ("Missing required parameter: " <>)
38+ sopts = StackageOptions
39+ (fromMaybe (missingErr "--all-cabal-hashes") (opts ^. optAllCabalHashesRepo) )
40+ (fromMaybe (missingErr "--lts-haskell") (opts ^. optLtsHaskellRepo))
41+
32 case opts ^. optConfigOrigin of
42 case opts ^. optConfigOrigin of
33− -- Generate build derivation from stack.yaml file
43+ -- Generate Stackage packages from stack.yaml resolver
34− OriginStackYaml stackYaml -> do
44+ OriginStackYaml stackYaml buildTarget -> do
35 stackConf <- either fail pure =<< readStackConfig stackYaml
45 stackConf <- either fail pure =<< readStackConfig stackYaml
36 let
46 let
37− generateStackage = opts ^. optWithStackage || opts ^. optWithStackageClosure
47+ stackResolver = stackConf ^. scResolver
38 stackPackagesConfig = mkStackPackagesConfig opts
48 stackPackagesConfig = mkStackPackagesConfig opts
39− stackConfPackages <- traverse (packageDerivation stackPackagesConfig (opts ^. optHackageDb)) $ stackConf ^. scPackages
49+ stackConfPackages <- traverse (packageDerivation stackPackagesConfig (opts ^. optHackageDb))
50+ $ stackConf ^. scPackages
51+ let
52+ reachable = Set.map mkPackageName
53+ $ F.foldr1 Set.union
54+ $ nodeDepends . mkNode <$> stackConfPackages
40
55
41− case generateStackage of
56+ case buildTarget of
42− -- Generate Stackage packages from stack.yaml resolver
57+ TargetStackageClosure -> do
43− True -> do
58+ (buildPlanFile, buildPlan, packageSetConfig) <- loadStackageBuildPlan stackResolver opts sopts
44− let buildPlanFile = LH.buildPlanFilePath (opts ^. optLtsHaskellRepo) (stackConf ^. scResolver)
45− buildPlan <- LH.loadBuildPlan buildPlanFile
46− packageSetConfig <- LH.buildPackageSetConfig
47− (opts ^. optHackageDb)
48− (opts ^. optAllCabalHashesRepo)
49− (opts ^. optNixpkgsRepository)
50− buildPlan
51 let
59 let
52 overrideConfig = mkOverrideConfig opts (siGhcVersion $ bpSystemInfo buildPlan)
60 overrideConfig = mkOverrideConfig opts (siGhcVersion $ bpSystemInfo buildPlan)
53− reachable = Set.map mkPackageName
54− $ F.foldr1 Set.union
55− $ nodeDepends . mkNode <$> stackConfPackages
56− s2nLoader mHash pkgId =
61+ stackageLoader mHash pkgId =
57 if pkgName pkgId `Set.member` reachable
62 if pkgName pkgId `Set.member` reachable
58 then packageLoader packageSetConfig Nothing pkgId
63 then packageLoader packageSetConfig Nothing pkgId
59 else packageLoader packageSetConfig mHash pkgId
64 else packageLoader packageSetConfig mHash pkgId
60− s2nPackageSetConfig = packageSetConfig { packageLoader = s2nLoader }
65+ stackageSetConfig = packageSetConfig { packageLoader = stackageLoader }
61− s2nPackageConfig = PackageConfig
66+ stackagePackages <- buildStackagePackages stackageSetConfig buildPlan
62− { enableCheck = True
63− , enableHaddock = True }
64− stackagePackages <- traverse (uncurry (buildNode s2nPackageSetConfig s2nPackageConfig))
65− $ Map.toAscList (bpPackages buildPlan)
66 let
67 let
67 -- Nixpkgs generic-builder puts hscolour on path for all libraries
68 -- Nixpkgs generic-builder puts hscolour on path for all libraries
68 withHscolour pkgs =
69 withHscolour pkgs =
@@ -75,13 +76,11 @@ run = do
75 -- does: pruning only after generating full set of packages allows
76 -- does: pruning only after generating full set of packages allows
76 -- us to make sure all those extra dependencies are explicitly
77 -- us to make sure all those extra dependencies are explicitly
77 -- listed as well.
78 -- listed as well.
78− nodes = case opts ^. optWithStackageClosure of
79− True -> Set.toAscList
79+ nodes = Set.toAscList
80 $ withHscolour
80 $ withHscolour
81 $ flip reachableDependencies stackagePackages
81 $ flip reachableDependencies stackagePackages
82 -- Originally reachable nodes are root nodes
82 -- Originally reachable nodes are root nodes
83 $ L.filter (\n -> mkPackageName (nodeName n) `Set.member` reachable) stackagePackages
83 $ L.filter (\n -> mkPackageName (nodeName n) `Set.member` reachable) stackagePackages
84− False -> stackagePackages
85 writeOutFile buildPlanFile (opts ^. optOutStackagePackages)
84 writeOutFile buildPlanFile (opts ^. optOutStackagePackages)
86 $ pPrintOutPackages (view nodeDerivation <$> nodes)
85 $ pPrintOutPackages (view nodeDerivation <$> nodes)
87 writeOutFile buildPlanFile (opts ^. optOutStackageConfig)
86 writeOutFile buildPlanFile (opts ^. optOutStackageConfig)
@@ -89,28 +88,32 @@ run = do
89 writeOutFile (stackYaml ^. syFilePath) (opts ^. optOutDerivation)
88 writeOutFile (stackYaml ^. syFilePath) (opts ^. optOutDerivation)
90 $ PP.overrideHaskellPackages overrideConfig stackConfPackages
89 $ PP.overrideHaskellPackages overrideConfig stackConfPackages
91
90
92− -- Generate Stackage override only
91+ TargetStackagePackages -> do
93− False ->
92+ (buildPlanFile, buildPlan, packageSetConfig) <- loadStackageBuildPlan stackResolver opts sopts
93+ let
94+ overrideConfig = mkOverrideConfig opts (siGhcVersion $ bpSystemInfo buildPlan)
95+ stackageLoader mHash pkgId =
96+ if pkgName pkgId `Set.member` reachable
97+ then packageLoader packageSetConfig Nothing pkgId
98+ else packageLoader packageSetConfig mHash pkgId
99+ stackageSetConfig = packageSetConfig { packageLoader = stackageLoader }
100+ nodes <- buildStackagePackages stackageSetConfig buildPlan
101+ writeOutFile buildPlanFile (opts ^. optOutStackagePackages)
102+ $ pPrintOutPackages (view nodeDerivation <$> nodes)
103+ writeOutFile buildPlanFile (opts ^. optOutStackageConfig)
104+ $ pPrintOutConfig (bpSystemInfo buildPlan) nodes
105+ writeOutFile (stackYaml ^. syFilePath) (opts ^. optOutDerivation)
106+ $ PP.overrideHaskellPackages overrideConfig stackConfPackages
107+
108+ TargetStackageOverride ->
94 writeOutFile (stackYaml ^. syFilePath) (opts ^. optOutDerivation)
109 writeOutFile (stackYaml ^. syFilePath) (opts ^. optOutDerivation)
95 $ PP.overrideStackage (stackConf ^. scResolver) (opts ^. optNixpkgsRepository) stackConfPackages
110 $ PP.overrideStackage (stackConf ^. scResolver) (opts ^. optNixpkgsRepository) stackConfPackages
96
111
97 -- Generate Stackage packages from resolver
112 -- Generate Stackage packages from resolver
98 OriginResolver stackResolver -> do
113 OriginResolver stackResolver -> do
99− let
114+ (buildPlanFile, buildPlan, packageSetConfig) <- loadStackageBuildPlan stackResolver opts sopts
100− buildPlanFile = LH.buildPlanFilePath (opts ^. optLtsHaskellRepo) stackResolver
115+ nodes <- buildStackagePackages packageSetConfig buildPlan
101− packageConfig = PackageConfig
102− { enableCheck = True
103− , enableHaddock = True }
104− buildPlan <- LH.loadBuildPlan buildPlanFile
105− packageSetConfig <- LH.buildPackageSetConfig
106− (opts ^. optHackageDb)
107− (opts ^. optAllCabalHashesRepo)
108− (opts ^. optNixpkgsRepository)
109− buildPlan
110− nodes <- traverse (uncurry (buildNode packageSetConfig packageConfig))
111− $ Map.toAscList (bpPackages buildPlan)
112 let overrideConfig = mkOverrideConfig opts (siGhcVersion $ bpSystemInfo buildPlan)
116 let overrideConfig = mkOverrideConfig opts (siGhcVersion $ bpSystemInfo buildPlan)
113−
114 writeOutFile buildPlanFile (opts ^. optOutStackagePackages)
117 writeOutFile buildPlanFile (opts ^. optOutStackagePackages)
115 $ pPrintOutPackages (view nodeDerivation <$> nodes)
118 $ pPrintOutPackages (view nodeDerivation <$> nodes)
116 writeOutFile buildPlanFile (opts ^. optOutStackageConfig)
119 writeOutFile buildPlanFile (opts ^. optOutStackageConfig)
@@ -118,6 +121,26 @@ run = do
118 writeOutFile buildPlanFile (opts ^. optOutDerivation)
121 writeOutFile buildPlanFile (opts ^. optOutDerivation)
119 $ PP.pPrintHaskellPackages overrideConfig
122 $ PP.pPrintHaskellPackages overrideConfig
120
123
124+loadStackageBuildPlan :: StackResolver -> Options -> StackageOptions -> IO (FilePath, BuildPlan, PackageSetConfig)
125+loadStackageBuildPlan stackResolver opts sopts = do
126+ let buildPlanFile = LH.buildPlanFilePath (sopts ^. soptLtsHaskellRepo) stackResolver
127+ buildPlan <- LH.loadBuildPlan buildPlanFile
128+ packageSetConfig <- LH.buildPackageSetConfig
129+ (opts ^. optHackageDb)
130+ (sopts ^. soptAllCabalHashesRepo)
131+ (opts ^. optNixpkgsRepository)
132+ buildPlan
133+ return (buildPlanFile, buildPlan, packageSetConfig)
134+
135+buildStackagePackages :: PackageSetConfig -> BuildPlan -> IO [Node]
136+buildStackagePackages packageSetConfig buildPlan = do
137+ let
138+ stackagePackageConfig = PackageConfig
139+ { enableCheck = True
140+ , enableHaddock = True }
141+ traverse (uncurry (buildNode packageSetConfig stackagePackageConfig))
142+ $ Map.toAscList (bpPackages buildPlan)
143+
121writeOutFile :: Show source => source -> FilePath -> Doc -> IO ()
144writeOutFile :: Show source => source -> FilePath -> Doc -> IO ()
122writeOutFile source filePath contents =
145writeOutFile source filePath contents =
123 withFile filePath WriteMode $ \h -> do
146 withFile filePath WriteMode $ \h -> do
src/Runner/Cli.hs+35−16
@@ -15,26 +15,40 @@ import Stack.Types
15import System.Environment
15import System.Environment
16import System.FilePath
16import System.FilePath
17
17
18+-- | What will be generated
19+data Target
20+ = TargetStackagePackages
21+ | TargetStackageClosure
22+ | TargetStackageOverride
23+ deriving (Show)
24+
25+makePrisms ''Target
26+
18-- | Source that would be used to produce target derivation
27-- | Source that would be used to produce target derivation
19data ConfigOrigin
28data ConfigOrigin
20 = OriginResolver StackResolver
29 = OriginResolver StackResolver
21 -- ^ Resolver to generate Stackage LTS
30 -- ^ Resolver to generate Stackage LTS
22− | OriginStackYaml StackYaml
31+ | OriginStackYaml StackYaml Target
23 -- ^ Stack config to generate build derivation
32 -- ^ Stack config to generate build derivation
24 deriving (Show)
33 deriving (Show)
25
34
26makePrisms ''ConfigOrigin
35makePrisms ''ConfigOrigin
27
36
37+data StackageOptions = StackageOptions
38+ { _soptAllCabalHashesRepo :: FilePath
39+ , _soptLtsHaskellRepo :: FilePath
40+ } deriving (Show)
41+
42+makeLenses ''StackageOptions
43+
28data Options = Options
44data Options = Options
29− { _optAllCabalHashesRepo :: FilePath
45+ { _optAllCabalHashesRepo :: Maybe FilePath
30− , _optLtsHaskellRepo :: FilePath
46+ , _optLtsHaskellRepo :: Maybe FilePath
31 , _optOutStackagePackages :: FilePath
47 , _optOutStackagePackages :: FilePath
32 , _optOutStackageConfig :: FilePath
48 , _optOutStackageConfig :: FilePath
33 , _optOutDerivation :: FilePath
49 , _optOutDerivation :: FilePath
34 , _optDoCheckPackages :: Bool
50 , _optDoCheckPackages :: Bool
35 , _optDoHaddockPackages :: Bool
51 , _optDoHaddockPackages :: Bool
36− , _optWithStackage :: Bool
37− , _optWithStackageClosure :: Bool
38 , _optHackageDb :: Maybe HackageDb
52 , _optHackageDb :: Maybe HackageDb
39 , _optNixpkgsRepository :: FilePath
53 , _optNixpkgsRepository :: FilePath
40 , _optCompilerId :: CompilerId
54 , _optCompilerId :: CompilerId
@@ -56,15 +70,13 @@ mkStackYaml p = case splitFileName p of
56
70
57options :: Parser Options
71options :: Parser Options
58options = Options
72options = Options
59− <$> allCabalHashesRepo
73+ <$> optional allCabalHashesRepo
60− <*> ltsHaskellRepo
74+ <*> optional ltsHaskellRepo
61 <*> outStackagePackages
75 <*> outStackagePackages
62 <*> outStackageConfig
76 <*> outStackageConfig
63 <*> outDerivation
77 <*> outDerivation
64 <*> doCheckPackages
78 <*> doCheckPackages
65 <*> doHaddockPackages
79 <*> doHaddockPackages
66− <*> withStackage
67− <*> withStackageClosure
68 <*> optional hackageDb
80 <*> optional hackageDb
69 <*> nixpkgsRepository
81 <*> nixpkgsRepository
70 <*> compilerId
82 <*> compilerId
@@ -133,13 +145,13 @@ doHaddockPackages = flag True False
133 ( long "no-haddock"
145 ( long "no-haddock"
134 <> help "disable haddock for project packages")
146 <> help "disable haddock for project packages")
135
147
136−withStackage :: Parser Bool
148+withStackage :: Parser ()
137−withStackage = switch
149+withStackage = flag' ()
138 ( long "with-stackage"
150 ( long "with-stackage"
139 <> help "generate full Stackage" )
151 <> help "generate full Stackage" )
140
152
141−withStackageClosure :: Parser Bool
153+withStackageClosure :: Parser ()
142−withStackageClosure = switch
154+withStackageClosure = flag' ()
143 ( long "with-stackage-closure"
155 ( long "with-stackage-closure"
144 <> help "generate Stackage subset containing only build dependencies" )
156 <> help "generate Stackage subset containing only build dependencies" )
145
157
@@ -153,11 +165,18 @@ stackYamlArg = mkStackYaml <$> Opts.argument str
153 ( metavar "STACK_YAML"
165 ( metavar "STACK_YAML"
154 <> help "path to stack.yaml file or directory" )
166 <> help "path to stack.yaml file or directory" )
155
167
168+target :: Parser Target
169+target =
170+ withStackage *> pure TargetStackagePackages <|>
171+ withStackageClosure *> pure TargetStackageClosure <|>
172+ pure TargetStackageOverride
173+
156configOrigin :: Parser ConfigOrigin
174configOrigin :: Parser ConfigOrigin
175+configOrigin =
176+ OriginStackYaml <$> stackYamlArg <*> target <|>
157−configOrigin = OriginResolver <$> resolver
177+ OriginResolver <$> resolver
158− <|> OriginStackYaml <$> stackYamlArg
159
178
160−-- inherited from cabal2nix
179+-- required for cabal2nix
161
180
162hackageDb :: Parser HackageDb
181hackageDb :: Parser HackageDb
163hackageDb = HackageDb <$>
182hackageDb = HackageDb <$>