module Runner.Cli where
import Control.Lens
import Data.Monoid ( (<>) )
import Data.Text as T
import qualified Distribution.Compat.ReadP as P
import Distribution.Compiler as Compiler
import Distribution.Nixpkgs.Haskell.Stack
import Distribution.System as System
import qualified Distribution.Text as Text
import Options.Applicative as Opts
import Paths_stackage2nix ( version )
import Stack.Types
import System.Environment
import System.FilePath
data Options = Options
{ _optAllCabalHashesRepo :: !FilePath
, _optLtsHaskellRepo :: !FilePath
, _optOutStackagePackages :: !FilePath
, _optOutStackageConfig :: !FilePath
, _optOutPackagesClosure :: !Bool
, _optOutDerivation :: !FilePath
, _optDoCheckPackages :: !Bool
, _optDoHaddockPackages :: !Bool
, _optDoCheckStackage :: !Bool
, _optDoHaddockStackage :: !Bool
, _optHackageDb :: !(Maybe HackageDb)
, _optNixpkgsRepository :: !FilePath
, _optCompilerId :: !CompilerId
, _optPlatform :: !Platform
, _optStackYamlArg :: !FilePath
} deriving (Show)
makeLenses ''Options
envStackYaml :: IO (Maybe StackYaml)
envStackYaml = fmap mkStackYaml <$> lookupEnv "STACK_YAML"
optStackYaml :: Getter Options StackYaml
optStackYaml = optStackYamlArg . to mkStackYaml
mkStackYaml :: FilePath -> StackYaml
mkStackYaml p = case splitFileName p of
(dir, "") -> StackYaml dir "stack.yaml"
(dir, ".") -> StackYaml dir "stack.yaml"
(_ , "..") -> StackYaml p "stack.yaml"
(dir, file) -> StackYaml dir file
options :: Parser Options
options = Options
<$> allCabalHashesRepo
<*> ltsHaskellRepo
<*> outStackagePackages
<*> outStackageConfig
<*> outPackagesClosure
<*> outDerivation
<*> doCheckPackages
<*> doHaddockPackages
<*> doCheckStackage
<*> doHaddockStackage
<*> optional hackageDb
<*> nixpkgsRepository
<*> compilerId
<*> platform
<*> stackYamlArg
pinfo :: ParserInfo Options
pinfo = info
( helper
<*> infoOption ("stackage2nix " ++ Text.display version) (long "version" <> help "Show version")
<*> options )
( fullDesc
<> header "stackage2nix converts Stack files into build instructions for Nix." )
nixpkgsRepository :: Parser FilePath
nixpkgsRepository = option str
( long "nixpkgs"
<> metavar "NIXPKGS"
<> help "path to Nixpkgs repository"
<> value "<nixpkgs>"
<> showDefaultWith id )
allCabalHashesRepo :: Parser FilePath
allCabalHashesRepo = option str
( long "all-cabal-hashes"
<> metavar "REPO_DIR"
<> help "path to commercialhaskell/all-cabal-hashes repository" )
ltsHaskellRepo :: Parser FilePath
ltsHaskellRepo = option str
( long "lts-haskell"
<> metavar "REPO_DIR"
<> help "path to fpco/lts-haskell repository" )
outStackagePackages :: Parser FilePath
outStackagePackages = option str
( long "out-packages"
<> metavar "NIX_FILE"
<> help "output file of the stackage packages set"
<> value "packages.nix"
<> showDefaultWith id)
outStackageConfig :: Parser FilePath
outStackageConfig = option str
( long "out-config"
<> metavar "NIX_FILE"
<> help "output file of the stackage packages compiler config"
<> value "configuration-packages.nix"
<> showDefaultWith id)
outPackagesClosure :: Parser Bool
outPackagesClosure = flag True False
( long "no-packages-closure"
<> help "produce full set of stackage packages, not just dependencies" )
outDerivation :: Parser FilePath
outDerivation = option str
( long "out-derivation"
<> metavar "NIX_FILE"
<> help "path to output derivation"
<> value "default.nix"
<> showDefaultWith id )
doCheckPackages :: Parser Bool
doCheckPackages = flag True False
( long "no-check"
<> help "disable tests for project packages")
doHaddockPackages :: Parser Bool
doHaddockPackages = flag True False
( long "no-haddock"
<> help "disable haddock for project packages")
doCheckStackage :: Parser Bool
doCheckStackage = switch
( long "do-check-stackage"
<> help "enable tests for Stackage packages" )
doHaddockStackage :: Parser Bool
doHaddockStackage = switch
( long "do-haddock-stackage"
<> help "enable haddock for Stackage packages" )
stackYamlArg :: Parser FilePath
stackYamlArg = Opts.argument str
( metavar "STACK_YAML"
<> help "path to stack.yaml file or directory" )
hackageDb :: Parser HackageDb
hackageDb = HackageDb <$>
option text
( long "hackage-db"
<> metavar "HACKAGE_DB"
<> help "path to the local hackage db in tar format" )
cabalFlag :: Parser CabalFlag
cabalFlag = CabalFlag <$>
option text
( short 'f'
<> long "flag"
<> help "Cabal flag (may be specified multiple times)" )
compilerId :: Parser CompilerId
compilerId = option (readP Text.parse)
( long "compiler"
<> help "compiler to use when evaluating the Cabal file"
<> value buildCompilerId
<> showDefaultWith Text.display )
platform :: Parser Platform
platform = option (readP Text.parse)
( long "system"
<> help "target system to use when evaluating the Cabal file"
<> value buildPlatform
<> showDefaultWith Text.display )
text :: ReadM Text
text = T.pack <$> str
readP :: P.ReadP a a -> ReadM a
readP p = eitherReader $ \s ->
case [ r' | (r',"") <- P.readP_to_S p s ] of
(r:_) -> Right r
_ -> Left ("invalid value " ++ show s)