1module Runner ( run ) where
4import Data.Foldable as F
6import Data.Maybe (fromMaybe)
7import Data.Semigroup ((<>))
8import Distribution.Nixpkgs.Haskell.FromStack
9import Distribution.Nixpkgs.Haskell.FromStack.Package
10import Distribution.Nixpkgs.Haskell.Hackage as DB
11import Distribution.Nixpkgs.Haskell.PackageSourceSpec (loadHackageDB)
12import Distribution.Nixpkgs.Haskell.Stack
13import Distribution.Nixpkgs.Haskell.Stack.PrettyPrinting as PP
14import Distribution.Version (Version)
15import Distribution.Compiler (AbiTag(..), unknownCompilerInfo)
16import Distribution.Package (PackageName, mkPackageName, pkgName)
17import Distribution.Text as Text (display)
18import Language.Nix as Nix
19import Options.Applicative
20import Paths_stackage2nix ( version )
25import System.IO (withFile, IOMode(..), hPutStrLn)
26import Text.PrettyPrint.HughesPJClass (Doc, render)
28import qualified Data.List.NonEmpty as NE
29import qualified Data.Map as Map
30import qualified Data.Set as Set
31import qualified LtsHaskell as LH
35 opts <- execParser pinfo
36 hackageDb <- loadHackageDB (opts ^. optHackageDb) Nothing
38 -- With optparse-applicative it seems there's no way to make
39 -- 'StackageOptions' optional for Stackage override and required in
41 missingErr = error . ("Missing required parameter: " <>)
42 sopts = StackageOptions
43 (fromMaybe (missingErr "--all-cabal-hashes") (opts ^. optAllCabalHashesRepo) )
44 (fromMaybe (missingErr "--lts-haskell") (opts ^. optLtsHaskellRepo))
46 case opts ^. optConfigOrigin of
47 -- Generate Stackage packages from stack.yaml resolver
48 OriginStackYaml stackYaml buildTarget -> do
49 stackConf <- either fail pure =<< readStackConfig stackYaml
51 stackResolver = stackConf ^. scResolver
52 stackPackagesConfig = mkStackPackagesConfig opts
53 stackExtraDepsConfig = stackPackagesConfig
54 & spcDoCheckPackages .~ False
55 & spcDoHaddockPackages .~ False
56 stackConfPackages <- traverse (fmap mkNode . packageDerivation stackPackagesConfig hackageDb)
57 $ stackConf ^. scPackages
58 stackConfExtraDeps <- traverse (fmap mkNode . packageDerivation stackExtraDepsConfig hackageDb)
59 $ stackConf ^. scExtraDeps
61 stackConfAllPackages = maybe stackConfPackages ((<>) stackConfPackages)
62 $ NE.nonEmpty stackConfExtraDeps
65 TargetStackageClosure -> do
66 (buildPlanFile, buildPlan, packageSetConfig) <- loadStackageBuildPlan hackageDb stackResolver opts sopts
68 overrideConfig = mkOverrideConfig opts (siGhcVersion $ bpSystemInfo buildPlan)
69 stackageSetConfig = if opts ^. optTweaks . tExtraDepsRevisionLatest
70 then extraDepsLatestConfig stackConfAllPackages packageSetConfig
72 stackagePackages <- buildStackagePackages stackageSetConfig buildPlan
74 reachable = reachableDeps stackConfAllPackages
75 -- Nixpkgs generic-builder puts hscolour on path for all libraries
77 let hscolour = F.find ((== "hscolour") . nodeName) stackagePackages
78 in maybe pkgs (`Set.insert` pkgs) hscolour
79 -- Find all reachable dependencies in stackage set to stick into
80 -- stackage packages file. This is performed on the full stackage
81 -- set rather than pruning stackage packages beforehand because
82 -- stackage does not concern itself with build tools while cabal2nix
83 -- does: pruning only after generating full set of packages allows
84 -- us to make sure all those extra dependencies are explicitly
88 $ flip reachableDependencies stackagePackages
89 -- Originally reachable nodes are root nodes
90 $ L.filter (\n -> mkPackageName (nodeName n) `Set.member` reachable) stackagePackages
91 writeOutFile buildPlanFile (opts ^. optOutStackagePackages)
92 $ pPrintOutPackages (view nodeDerivation <$> nodes)
93 writeOutFile buildPlanFile (opts ^. optOutStackageConfig)
94 $ pPrintOutConfig (bpSystemInfo buildPlan) nodes
95 writeOutFile (stackYaml ^. syFilePath) (opts ^. optOutDerivation)
96 $ PP.overrideHaskellPackages overrideConfig (view nodeDerivation <$> stackConfAllPackages)
98 TargetStackagePackages -> do
99 (buildPlanFile, buildPlan, packageSetConfig) <- loadStackageBuildPlan hackageDb stackResolver opts sopts
101 overrideConfig = mkOverrideConfig opts (siGhcVersion $ bpSystemInfo buildPlan)
102 stackageSetConfig = if opts ^. optTweaks . tExtraDepsRevisionLatest
103 then extraDepsLatestConfig stackConfAllPackages packageSetConfig
104 else packageSetConfig
105 -- stackageLoader mHash pkgId =
106 -- if pkgName pkgId `Set.member` reachable
107 -- then packageLoader packageSetConfig Nothing pkgId
108 -- else packageLoader packageSetConfig mHash pkgId
109 -- stackageSetConfig = packageSetConfig { packageLoader = stackageLoader }
110 nodes <- buildStackagePackages stackageSetConfig buildPlan
111 writeOutFile buildPlanFile (opts ^. optOutStackagePackages)
112 $ pPrintOutPackages (view nodeDerivation <$> nodes)
113 writeOutFile buildPlanFile (opts ^. optOutStackageConfig)
114 $ pPrintOutConfig (bpSystemInfo buildPlan) nodes
115 writeOutFile (stackYaml ^. syFilePath) (opts ^. optOutDerivation)
116 $ PP.overrideHaskellPackages overrideConfig (view nodeDerivation <$> stackConfAllPackages)
118 TargetStackageOverride -> do
119 writeOutFile (stackYaml ^. syFilePath) (opts ^. optOutDerivation)
120 $ PP.overrideStackage
121 (stackConf ^. scResolver)
122 (opts ^. optNixpkgsRepository)
123 (view nodeDerivation <$> stackConfAllPackages)
124 writeOutFile (stackYaml ^. syFilePath) (opts ^. optOutStackYamlPackages)
125 $ PP.stackYamlPackages (view nodeDerivation <$> stackConfPackages)
127 -- Generate Stackage packages from resolver
128 OriginResolver stackResolver -> do
129 (buildPlanFile, buildPlan, packageSetConfig) <- loadStackageBuildPlan hackageDb stackResolver opts sopts
130 nodes <- buildStackagePackages packageSetConfig buildPlan
131 let overrideConfig = mkOverrideConfig opts (siGhcVersion $ bpSystemInfo buildPlan)
132 writeOutFile buildPlanFile (opts ^. optOutStackagePackages)
133 $ pPrintOutPackages (view nodeDerivation <$> nodes)
134 writeOutFile buildPlanFile (opts ^. optOutStackageConfig)
135 $ pPrintOutConfig (bpSystemInfo buildPlan) nodes
136 writeOutFile buildPlanFile (opts ^. optOutDerivation)
137 $ PP.pPrintHaskellPackages overrideConfig
139loadStackageBuildPlan :: DB.HackageDB -> StackResolver -> Options -> StackageOptions -> IO (FilePath, BuildPlan, PackageSetConfig)
140loadStackageBuildPlan hackageDb stackResolver opts sopts = do
141 let buildPlanFile = LH.buildPlanFilePath (sopts ^. soptLtsHaskellRepo) stackResolver
142 buildPlan <- LH.loadBuildPlan buildPlanFile
143 packageSetConfig <- LH.buildPackageSetConfig
145 (sopts ^. soptAllCabalHashesRepo)
146 (opts ^. optNixpkgsRepository)
148 return (buildPlanFile, buildPlan, packageSetConfig)
150buildStackagePackages :: PackageSetConfig -> BuildPlan -> IO [Node]
151buildStackagePackages packageSetConfig buildPlan = do
153 stackagePackageConfig = PackageConfig
155 , enableHaddock = True }
156 traverse (uncurry (buildNode packageSetConfig stackagePackageConfig))
157 $ Map.toAscList (bpPackages buildPlan)
159reachableDeps :: Traversable t => t Node -> Set.Set PackageName
160reachableDeps = Set.map mkPackageName
164-- Return 'PackageSetConfig' with package loader that loads latest Hackage
165-- revison for direct (reachable) dependencies of input packages
166extraDepsLatestConfig :: Traversable t => t Node -> PackageSetConfig -> PackageSetConfig
167extraDepsLatestConfig packages packageSetConfig =
169 reachable = reachableDeps packages
170 stackageLoader mHash pkgId =
171 if pkgName pkgId `Set.member` reachable
172 then packageLoader packageSetConfig Nothing pkgId
173 else packageLoader packageSetConfig mHash pkgId
174 in packageSetConfig { packageLoader = stackageLoader }
176writeOutFile :: Show source => source -> FilePath -> Doc -> IO ()
177writeOutFile source filePath contents =
178 withFile filePath WriteMode $ \h -> do
179 hPutStrLn h ("# Generated by stackage2nix " ++ Text.display version ++ " from " ++ show source)
180 hPutStrLn h $ render contents
182mkOverrideConfig :: Options -> Version -> OverrideConfig
183mkOverrideConfig opts ghcVersion = OverrideConfig
184 { _ocGhc = ghcVersion
185 , _ocStackagePackages = opts ^. optOutStackagePackages
186 , _ocStackageConfig = opts ^. optOutStackageConfig
187 , _ocNixpkgs = opts ^. optNixpkgsRepository }
189mkStackPackagesConfig :: Options -> StackPackagesConfig
190mkStackPackagesConfig opts = StackPackagesConfig
191 { _spcHaskellResolver = const True
192 , _spcNixpkgsResolver = \i -> Just (Nix.binding # (i, Nix.path # [i]))
193 , _spcTargetPlatform = opts ^. optPlatform
194 , _spcTargetCompiler = unknownCompilerInfo (opts ^. optCompilerId) NoAbiTag
195 , _spcFlagAssignment = mempty
196 , _spcDoCheckPackages = opts ^. optDoCheckPackages
197 , _spcDoHaddockPackages = opts ^. optDoHaddockPackages }
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list