git.iko.soy/typeable/stackage2nix
on master help sign in
240 lines 7.2 kB history raw
1module Runner.Cli where
3import Control.Lens
4import Data.Monoid ( (<>) )
5import Data.Text as T
6import qualified Distribution.Compat.ReadP as P
7import Distribution.Compiler as Compiler
8import Distribution.System as System
9import qualified Distribution.Text as Text
10import Options.Applicative as Opts
11import Paths_stackage2nix ( version )
12import Stack.Config
13import Stack.Types
14import System.FilePath
16data Tweaks = Tweaks
17 { _tExtraDepsRevisionLatest :: Bool
18 } deriving (Show)
20makeLenses ''Tweaks
22-- | What will be generated
23data Target
24 = TargetStackagePackages
25 | TargetStackageClosure
26 | TargetStackageOverride
27 deriving (Show)
29makePrisms ''Target
31-- | Source that would be used to produce target derivation
32data ConfigOrigin
33 = OriginResolver StackResolver
34 -- ^ Resolver to generate Stackage LTS
35 | OriginStackYaml StackYaml Target
36 -- ^ Stack config to generate build derivation
37 deriving (Show)
39makePrisms ''ConfigOrigin
41data StackageOptions = StackageOptions
42 { _soptAllCabalHashesRepo :: FilePath
43 , _soptLtsHaskellRepo :: FilePath
44 } deriving (Show)
46makeLenses ''StackageOptions
48data Options = Options
49 { _optAllCabalHashesRepo :: Maybe FilePath
50 , _optLtsHaskellRepo :: Maybe FilePath
51 , _optOutStackagePackages :: FilePath
52 , _optOutStackageConfig :: FilePath
53 , _optOutDerivation :: FilePath
54 , _optOutStackYamlPackages :: FilePath
55 , _optDoCheckPackages :: Bool
56 , _optDoHaddockPackages :: Bool
57 , _optTweaks :: Tweaks
58 , _optHackageDb :: Maybe FilePath
59 , _optNixpkgsRepository :: FilePath
60 , _optCompilerId :: CompilerId
61 , _optPlatform :: Platform
62 , _optConfigOrigin :: ConfigOrigin
63 } deriving (Show)
65makeLenses ''Options
67mkStackYaml :: FilePath -> StackYaml
68mkStackYaml p = case splitFileName p of
69 (dir, "") -> StackYaml dir "stack.yaml"
70 (dir, ".") -> StackYaml dir "stack.yaml"
71 (_ , "..") -> StackYaml p "stack.yaml"
72 (dir, file) -> case splitExtension file of
73 (_, "") -> StackYaml p "stack.yaml"
74 _ -> StackYaml dir file
76options :: Parser Options
77options = Options
78 <$> optional allCabalHashesRepo
79 <*> optional ltsHaskellRepo
80 <*> outStackagePackages
81 <*> outStackageConfig
82 <*> outDerivation
83 <*> outStackYamlPackages
84 <*> doCheckPackages
85 <*> doHaddockPackages
86 <*> tweaks
87 <*> optional optionHackageDb
88 <*> nixpkgsRepository
89 <*> compilerId
90 <*> platform
91 <*> configOrigin
93pinfo :: ParserInfo Options
94pinfo = info
95 ( helper
96 <*> infoOption ("stackage2nix " ++ Text.display version) (long "version" <> help "Show version")
97 <*> options )
98 ( fullDesc
99 <> header "stackage2nix converts Stack files into build instructions for Nix." )
101nixpkgsRepository :: Parser FilePath
102nixpkgsRepository = option str
103 ( long "nixpkgs"
104 <> metavar "NIXPKGS"
105 <> help "path to Nixpkgs repository"
106 <> value "<nixpkgs>"
107 <> showDefaultWith id )
109allCabalHashesRepo :: Parser FilePath
110allCabalHashesRepo = option str
111 ( long "all-cabal-hashes"
112 <> metavar "REPO_DIR"
113 <> help "path to commercialhaskell/all-cabal-hashes repository" )
115ltsHaskellRepo :: Parser FilePath
116ltsHaskellRepo = option str
117 ( long "lts-haskell"
118 <> metavar "REPO_DIR"
119 <> help "path to fpco/lts-haskell repository" )
121outStackagePackages :: Parser FilePath
122outStackagePackages = option str
123 ( long "out-packages"
124 <> metavar "NIX_FILE"
125 <> help "output file of the stackage packages set"
126 <> value "packages.nix"
127 <> showDefaultWith id)
129outStackageConfig :: Parser FilePath
130outStackageConfig = option str
131 ( long "out-config"
132 <> metavar "NIX_FILE"
133 <> help "output file of the stackage packages compiler config"
134 <> value "configuration-packages.nix"
135 <> showDefaultWith id)
137outDerivation :: Parser FilePath
138outDerivation = option str
139 ( long "out-derivation"
140 <> metavar "NIX_FILE"
141 <> help "path to output derivation"
142 <> value "default.nix"
143 <> showDefaultWith id )
145outStackYamlPackages :: Parser FilePath
146outStackYamlPackages = option str
147 ( long "out-stack-yaml-packages"
148 <> metavar "NIX_FILE"
149 <> help "path to output stackage.yaml packages list"
150 <> value "stack-yaml-packages.nix"
151 <> showDefaultWith id )
153doCheckPackages :: Parser Bool
154doCheckPackages = flag True False
155 ( long "no-check"
156 <> help "disable tests for project packages")
158doHaddockPackages :: Parser Bool
159doHaddockPackages = flag True False
160 ( long "no-haddock"
161 <> help "disable haddock for project packages")
163withStackage :: Parser ()
164withStackage = flag' ()
165 ( long "with-stackage"
166 <> help "generate full Stackage" )
168withStackageClosure :: Parser ()
169withStackageClosure = flag' ()
170 ( long "with-stackage-closure"
171 <> help "generate Stackage subset containing only build dependencies" )
173extraDepsRevisionLatest :: Parser Bool
174extraDepsRevisionLatest = switch
175 ( long "extra-deps-revision-latest"
176 <> help "Changes algorithm for the dependencies generation of the stack.yaml extra-deps. Default one is to generate exact revision defined in the Stackage config. With this flag enabled, direct dependencies of the stack.yaml extra-deps will be generated with the latest revision available on Hackage. This may help when Cabal fails to resolve dependencies of extra-deps, and dependences are fixed in the latest revision" )
178tweaks :: Parser Tweaks
179tweaks = Tweaks <$> extraDepsRevisionLatest
181resolver :: Parser StackResolver
182resolver = StackResolver <$> option text
183 ( long "resolver"
184 <> help "stackage LTS resolver" )
186stackYamlArg :: Parser StackYaml
187stackYamlArg = mkStackYaml <$> Opts.argument str
188 ( metavar "STACK_YAML"
189 <> help "path to stack.yaml file or directory" )
191target :: Parser Target
192target =
193 withStackage *> pure TargetStackagePackages <|>
194 withStackageClosure *> pure TargetStackageClosure <|>
195 pure TargetStackageOverride
197configOrigin :: Parser ConfigOrigin
198configOrigin =
199 OriginStackYaml <$> stackYamlArg <*> target <|>
200 OriginResolver <$> resolver
202-- required for cabal2nix
204optionHackageDb :: Parser FilePath
205optionHackageDb = option str
206 ( long "hackage-db"
207 <> metavar "HACKAGE_DB"
208 <> help "path to the local hackage db in tar format" )
210cabalFlag :: Parser CabalFlag
211cabalFlag = CabalFlag <$>
212 option text
213 ( short 'f'
214 <> long "flag"
215 <> help "Cabal flag (may be specified multiple times)" )
217compilerId :: Parser CompilerId
218compilerId = option (readP Text.parse)
219 ( long "compiler"
220 <> help "compiler to use when evaluating the Cabal file"
221 <> value buildCompilerId
222 <> showDefaultWith Text.display )
224platform :: Parser Platform
225platform = option (readP Text.parse)
226 ( long "system"
227 <> help "target system to use when evaluating the Cabal file"
228 <> value buildPlatform
229 <> showDefaultWith Text.display )
231-- utils
233text :: ReadM Text
234text = T.pack <$> str
236readP :: P.ReadP a a -> ReadM a
237readP p = eitherReader $ \s ->
238 case [ r' | (r',"") <- P.readP_to_S p s ] of
239 (r:_) -> Right r
240 _ -> Left ("invalid value " ++ show s)