cachix-0.5.0: src/Cachix/Client/OptionsParser.hs
module Cachix.Client.OptionsParser
( CachixCommand (..),
CachixOptions (..),
PushArguments (..),
PushOptions (..),
BinaryCacheName,
getOpts,
)
where
import qualified Cachix.Client.Config as Config
import qualified Cachix.Client.InstallationMode as InstallationMode
import Cachix.Client.URI (defaultCachixURI)
import Options.Applicative
import Protolude hiding (option)
import URI.ByteString
( Absolute,
URIRef,
parseURI,
serializeURIRef',
strictURIParserOptions,
)
data CachixOptions
= CachixOptions
{ host :: URIRef Absolute,
configPath :: Config.ConfigPath,
verbose :: Bool
}
deriving (Show)
parserCachixOptions :: Config.ConfigPath -> Parser CachixOptions
parserCachixOptions defaultConfigPath =
CachixOptions
<$> option
uriOption
( long "host"
<> value defaultCachixURI
<> metavar "URI"
<> showDefaultWith (toS . serializeURIRef')
<> help "Host to connect to"
)
<*> strOption
( long "config"
<> short 'c'
<> value defaultConfigPath
<> metavar "CONFIGPATH"
<> showDefault
<> help "Cachix configuration file"
)
<*> switch
( long "verbose"
<> short 'v'
<> help "Verbose mode"
)
uriOption :: ReadM (URIRef Absolute)
uriOption = eitherReader $ \s ->
first show $ parseURI strictURIParserOptions $ toS s
type BinaryCacheName = Text
data CachixCommand
= AuthToken Text
| Create BinaryCacheName
| GenerateKeypair BinaryCacheName
| Push PushArguments
| Use BinaryCacheName InstallationMode.UseOptions
| Version
deriving (Show)
data PushArguments
= PushPaths PushOptions Text [Text]
| PushWatchStore PushOptions Text
deriving (Show)
data PushOptions
= PushOptions
{ compressionLevel :: Int,
numJobs :: Int,
omitDeriver :: Bool
}
deriving (Show)
parserCachixCommand :: Parser CachixCommand
parserCachixCommand =
subparser $
command "authtoken" (infoH authtoken (progDesc "Configure authentication token for communication to cachix.org API"))
<> command "create" (infoH create (progDesc "DEPRECATED: Go to https://cachix.org instead"))
<> command "generate-keypair" (infoH generateKeypair (progDesc "Generate keypair for a binary cache"))
<> command "push" (infoH push (progDesc "Upload Nix store paths to a binary cache"))
<> command "use" (infoH use (progDesc "Configure a binary cache by writing nix.conf and netrc files."))
where
nameArg = strArgument (metavar "CACHE-NAME")
authtoken = AuthToken <$> strArgument (metavar "AUTHTOKEN")
create = Create <$> nameArg
generateKeypair = GenerateKeypair <$> nameArg
validatedLevel l =
l <$ unless (l `elem` [0 .. 9]) (readerError $ "value " <> show l <> " not in expected range: [0..9]")
pushOptions :: Parser PushOptions
pushOptions =
PushOptions
<$> option
(auto >>= validatedLevel)
( long "compression-level"
<> short 'c'
<> metavar "[0..9]"
<> help
"The compression level for XZ compression.\
\ Take compressor *and* decompressor memory usage into account before using [7..9]!"
<> showDefault
<> value 2
)
<*> option
auto
( long "jobs"
<> short 'j'
<> help "Number of threads used for pushing store paths."
<> showDefault
<> value 4
)
<*> switch (long "omit-deriver" <> help "Do not publish which derivations built the store paths.")
push = (\opts cache f -> Push $ f opts cache) <$> pushOptions <*> nameArg <*> (pushPaths <|> pushWatchStore)
pushPaths =
(\paths opts cache -> PushPaths opts cache paths)
<$> many (strArgument (metavar "PATHS..."))
pushWatchStore =
(\() opts cache -> PushWatchStore opts cache)
<$> flag'
()
( long "watch-store"
<> short 'w'
<> help "Run in daemon mode and push store paths as they are added to /nix/store"
)
use =
Use <$> nameArg
<*> ( InstallationMode.UseOptions
<$> optional
( option
(maybeReader InstallationMode.fromString)
( long "mode"
<> short 'm'
<> help "Mode in which to configure binary caches for Nix. Supported values: nixos, root-nixconf, user-nixconf"
)
)
<*> strOption
( long "nixos-folder"
<> short 'd'
<> help "Base directory for NixOS configuration generation"
<> value "/etc/nixos/"
<> showDefault
)
<*> optional
( strOption
( long "output-directory"
<> short 'O'
<> help "Output directory where nix.conf and netrc will be updated."
)
)
)
getOpts :: IO (CachixOptions, CachixCommand)
getOpts = do
configpath <- Config.getDefaultFilename
customExecParser (prefs showHelpOnEmpty) (optsInfo configpath)
optsInfo :: Config.ConfigPath -> ParserInfo (CachixOptions, CachixCommand)
optsInfo configpath = infoH parser desc
where
parser = (,) <$> parserCachixOptions configpath <*> (parserCachixCommand <|> versionParser)
versionParser :: Parser CachixCommand
versionParser =
flag'
Version
( long "version"
<> short 'V'
<> help "Show cachix version"
)
desc :: InfoMod a
desc =
fullDesc
<> progDesc "Sign into https://cachix.org to get started."
<> header "cachix.org command interface"
-- TODO: usage footer
infoH :: Parser a -> InfoMod a -> ParserInfo a
infoH a = info (helper <*> a)