@@ -2,7 +2,7 @@ module Runner ( run ) where
3import Control.Lens
3import Control.Lens
4import Data.Foldable as F
4import Data.Foldable as F
5−import Data.Functor
5+import Data.List as L
6import Distribution.Nixpkgs.Haskell.FromStack
6import Distribution.Nixpkgs.Haskell.FromStack
7import Distribution.Nixpkgs.Haskell.FromStack.Package
7import Distribution.Nixpkgs.Haskell.FromStack.Package
8import Distribution.Nixpkgs.Haskell.Stack
8import Distribution.Nixpkgs.Haskell.Stack
@@ -18,8 +18,8 @@ import Runner.Cli
18import Stack.Config
18import Stack.Config
19import Stack.Types
19import Stack.Types
20import Stackage.Types
20import Stackage.Types
21−import System.IO (withFile, IOMode(..), hPutStrLn, hPrint)
21+import System.IO (withFile, IOMode(..), hPutStrLn)
22−import Text.PrettyPrint.HughesPJClass (render)
22+import Text.PrettyPrint.HughesPJClass (Doc, render)
24import qualified Data.Set as Set
24import qualified Data.Set as Set
25import qualified Data.Map as Map
25import qualified Data.Map as Map
@@ -29,60 +29,80 @@ import qualified LtsHaskell as LH
29run :: IO ()
29run :: IO ()
31 opts <- execParser pinfo
31 opts <- execParser pinfo
32− stackYaml <- envStackYaml >>= \case
32+ case opts ^. optConfigOrigin of
33− Just p -> putStrLn "Getting project config file from STACK_YAML environment" $> p
33+ -- Generate build derivation from stack.yaml file
34− Nothing -> pure $ opts ^. optStackYaml
34+ OriginStackYaml stackYaml -> do
35− stackConf <- either fail pure =<< readStackConfig stackYaml
35+ stackConf <- either fail pure =<< readStackConfig stackYaml
36− let buildPlanFile = LH.buildPlanFilePath (opts ^. optLtsHaskellRepo) (stackConf ^. scResolver)
36+ let buildPlanFile = LH.buildPlanFilePath (opts ^. optLtsHaskellRepo) (stackConf ^. scResolver)
37− buildPlan <- LH.loadBuildPlan buildPlanFile
37+ buildPlan <- LH.loadBuildPlan buildPlanFile
38− packageSetConfig <- LH.buildPackageSetConfig
38+ packageSetConfig <- LH.buildPackageSetConfig
39− (opts ^. optAllCabalHashesRepo)
39+ (opts ^. optAllCabalHashesRepo)
40− (opts ^. optNixpkgsRepository)
40+ (opts ^. optNixpkgsRepository)
41− buildPlan
41+ buildPlan
42− -- generate haskell packages override
44− overrideConfig = mkOverrideConfig opts (siGhcVersion $ bpSystemInfo buildPlan)
43+ overrideConfig = mkOverrideConfig opts (siGhcVersion $ bpSystemInfo buildPlan)
45− stackPackagesConfig = mkStackPackagesConfig opts
44+ stackPackagesConfig = mkStackPackagesConfig opts
46− packages <- traverse (packageDerivation stackPackagesConfig (opts ^. optHackageDb))
45+ stackConfPackages <- traverse (packageDerivation stackPackagesConfig (opts ^. optHackageDb))
47− $ stackConf ^. scPackages
46+ $ stackConf ^. scPackages
48− let out = PP.overrideHaskellPackages overrideConfig packages
47+ let
49− withFile (opts ^. optOutDerivation) WriteMode $ \h -> do
50− hPutStrLn h ("# Generated by stackage2nix " ++ Text.display version ++ " from " ++ stackYaml ^. syFilePath)
53− reachable = Set.map mkPackageName
48+ reachable = Set.map mkPackageName
54− $ F.foldr1 Set.union
49+ $ F.foldr1 Set.union
55− $ nodeDepends . mkNode <$> packages
50+ $ nodeDepends . mkNode <$> stackConfPackages
56− s2nLoader mHash pkgId =
51+ s2nLoader mHash pkgId =
57− if pkgName pkgId `Set.member` reachable
52+ if pkgName pkgId `Set.member` reachable
58− then packageLoader packageSetConfig Nothing pkgId
53+ then packageLoader packageSetConfig Nothing pkgId
59− else packageLoader packageSetConfig mHash pkgId
54+ else packageLoader packageSetConfig mHash pkgId
60− s2nPackageSetConfig = packageSetConfig { packageLoader = s2nLoader }
55+ s2nPackageSetConfig = packageSetConfig { packageLoader = s2nLoader }
61− s2nPackageConfig = PackageConfig
56+ s2nPackageConfig = PackageConfig
62− { enableCheck = opts ^. optDoCheckStackage
57+ { enableCheck = opts ^. optDoCheckStackage
63− , enableHaddock = opts ^. optDoHaddockStackage }
58+ , enableHaddock = opts ^. optDoHaddockStackage }
64− allNodes <- traverse (uncurry (buildNodeM s2nPackageSetConfig s2nPackageConfig))
59+ stackagePackages <- traverse (uncurry (buildNodeM s2nPackageSetConfig s2nPackageConfig))
65− $ Map.toList (bpPackages buildPlan)
60+ $ Map.toList (bpPackages buildPlan)
67− -- Find all reachable dependencies in stackage set to stick into
62+ -- Find all reachable dependencies in stackage set to stick into
68− -- stackage packages file. This is performed on the full stackage
63+ -- stackage packages file. This is performed on the full stackage
69− -- set rather than pruning stackage packages beforehand because
64+ -- set rather than pruning stackage packages beforehand because
70− -- stackage does not concern itself with build tools while cabal2nix
65+ -- stackage does not concern itself with build tools while cabal2nix
71− -- does: pruning only after generating full set of packages allows
66+ -- does: pruning only after generating full set of packages allows
72− -- us to make sure all those extra dependencies are explicitly
67+ -- us to make sure all those extra dependencies are explicitly
73− -- listed as well.
68+ -- listed as well.
74− let nodes = case opts ^. optOutPackagesClosure of
69+ let reachableStackagePackages = case opts ^. optOutPackagesClosure of
75− True -> flip reachableDependencies allNodes
70+ True -> flip reachableDependencies stackagePackages
76− -- Originally reachable nodes are root nodes
71+ -- Originally reachable nodes are root nodes
77− $ filter (\n -> mkPackageName (nodeName n) `Set.member` reachable) allNodes
72+ $ L.filter (\n -> mkPackageName (nodeName n) `Set.member` reachable) stackagePackages
78− False -> allNodes
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
81+ -- Generate Stackage packages from resolver
82+ OriginResolver stackResolver -> do
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)
93+ nodes <- traverse (uncurry (buildNodeM packageSetConfig packageConfig))
94+ $ Map.toList (bpPackages buildPlan)
80− withFile (opts ^. optOutStackagePackages) WriteMode $ \h -> do
96+ writeOutFile buildPlanFile (opts ^. optOutStackagePackages)
81− hPutStrLn h ("# Generated by stackage2nix " ++ Text.display version ++ " from " ++ buildPlanFile)
82− hPutStrLn h $ render $ pPrintOutPackages (view nodeDerivation <$> nodes)
97+ $ pPrintOutPackages (view nodeDerivation <$> nodes)
83− withFile (opts ^. optOutStackageConfig) WriteMode $ \h -> do
98+ writeOutFile buildPlanFile (opts ^. optOutStackageConfig)
84− hPutStrLn h ("# Generated by stackage2nix " ++ Text.display version ++ " from " ++ buildPlanFile)
85− hPutStrLn h $ render $ pPrintOutConfig (bpSystemInfo buildPlan) nodes
99+ $ pPrintOutConfig (bpSystemInfo buildPlan) nodes
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
87mkOverrideConfig :: Options -> Version -> OverrideConfig
107mkOverrideConfig :: Options -> Version -> OverrideConfig
88mkOverrideConfig opts ghcVersion = OverrideConfig
108mkOverrideConfig opts ghcVersion = OverrideConfig