@@ -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