@@ -0,0 +1,87 @@
1+module Cli where
2+
3+import Data.Monoid ( (<>) )
4+import Data.Text as T
5+import qualified Distribution.Compat.ReadP as P
6+import Distribution.Compiler as Compiler
7+import Distribution.Nixpkgs.Haskell.Stack
8+import Distribution.System as System
9+import qualified Distribution.Text as Text
10+import Options.Applicative
11+import Stack.Config
12+import Stack.Types
13+
14+
15+data Options = Options
16+ { optStackResolver :: Maybe StackResolver
17+ , optHackageDb :: Maybe HackageDb
18+ , optFlags :: [CabalFlag]
19+ , optCompilerId :: CompilerId
20+ , optPlatform :: Platform
21+ , optStackYaml :: FilePath
22+ } deriving (Show)
23+
24+options :: Parser Options
25+options = Options
26+ <$> optional stackResolver
27+ <*> optional hackageDb
28+ <*> many cabalFlag
29+ <*> compilerId
30+ <*> platform
31+ <*> stackYamlArg
32+
33+pinfo :: ParserInfo Options
34+pinfo = info
35+ ( helper
36+ <*> options )
37+ ( fullDesc
38+ <> header "stack2nix converts Stack files into build instructions for Nix." )
39+
40+stackResolver :: Parser StackResolver
41+stackResolver = StackResolver <$>
42+ option text
43+ ( long "resolver"
44+ <> metavar "RESOLVER"
45+ <> help "override stack resolver" )
46+
47+stackYamlArg :: Parser FilePath
48+stackYamlArg = argument str
49+ ( metavar "STACK_YAML"
50+ <> value "stack.yaml" )
51+
52+hackageDb :: Parser HackageDb
53+hackageDb = HackageDb <$>
54+ option text
55+ ( long "hackage-db"
56+ <> metavar "HACKAGE_DB"
57+ <> help "path to the local hackage db in tar format" )
58+
59+cabalFlag :: Parser CabalFlag
60+cabalFlag = CabalFlag <$>
61+ option text
62+ ( short 'f'
63+ <> long "flag"
64+ <> help "Cabal flag (may be specified multiple times)" )
65+
66+compilerId :: Parser CompilerId
67+compilerId = option (readP Text.parse)
68+ ( long "compiler"
69+ <> help "compiler to use when evaluating the Cabal file"
70+ <> value buildCompilerId
71+ <> showDefaultWith Text.display )
72+
73+platform :: Parser Platform
74+platform = option (readP Text.parse)
75+ ( long "system"
76+ <> help "target system to use when evaluating the Cabal file"
77+ <> value buildPlatform
78+ <> showDefaultWith Text.display )
79+
80+text :: ReadM Text
81+text = T.pack <$> str
82+
83+readP :: P.ReadP a a -> ReadM a
84+readP p = eitherReader $ \s ->
85+ case [ r' | (r',"") <- P.readP_to_S p s ] of
86+ (r:_) -> Right r
87+ _ -> Left ("invalid value " ++ show s)