life-sync-1.0: app/Options.hs
{-# LANGUAGE ApplicativeDo #-}
-- | Command line options for Importify
module Options
( LifeCommand (..)
, PathOptions (..)
, PullOptions (..)
, parseCommand
) where
import Options.Applicative (Parser, ParserInfo, command, execParser, fullDesc, help, helper, info,
long, metavar, progDesc, short, strArgument, strOption, subparser)
import Life.Configuration (LifePath (..))
import Life.Github (Owner (..))
-- | Commands to execute
data LifeCommand
= Init Owner
| Add PathOptions
| Remove PathOptions
| Push
| Pull PullOptions
deriving (Show)
---------------------------------------------------------------------------
-- Boilerplate
----------------------------------------------------------------------------
commandParser :: Parser LifeCommand
commandParser = subparser $
command "init"
(info (helper <*> fmap Init ownerParser)
(fullDesc <> progDesc "Initialize GitHub repository named 'dotfiles' if you don't have one."))
<> command "add"
(info (helper <*> fmap Add pathOptionsParser)
(fullDesc <> progDesc "Add file or directory to the life configuration."))
<> command "remove"
(info (helper <*> fmap Remove pathOptionsParser)
(fullDesc <> progDesc "Remove file or directory from the life configuration."))
<> command "push"
(info (helper <*> pure Push)
(fullDesc <> progDesc "Updates GitHub repository from local state and push the latest version."))
<> command "pull"
(info (helper <*> fmap Pull pullOptionsParser)
(fullDesc <> progDesc "Updates local state of '.life' and 'dotfiles' from GitHub repository."))
optionsInfo :: ParserInfo LifeCommand
optionsInfo = info
(helper <*> commandParser)
(fullDesc <> progDesc "life-sync synchronize your personal configs")
parseCommand :: IO LifeCommand
parseCommand = execParser optionsInfo
ownerParser :: Parser Owner
ownerParser = fmap Owner
$ strArgument
$ metavar "OWNER"
<> help "Your github user name"
----------------------------------------------------------------------------
-- life pull
----------------------------------------------------------------------------
data PullOptions = PullOptions
{ pullOptionsOwner :: Owner
, pullOptionsNoFiles :: [FilePath]
, pullOptionsNoDirs :: [FilePath]
} deriving (Show)
pullOptionsParser :: Parser PullOptions
pullOptionsParser = do
pullOptionsOwner <- ownerParser
-- TODO: reuse LifePath parser here?...
pullOptionsNoFiles <- many $ strOption
$ metavar "FILE_PATH"
<> long "no-file"
<> short 'f'
<> help "Excluding these specific files from copying"
pullOptionsNoDirs <- many $ strOption
$ metavar "FILE_PATH"
<> long "no-dir"
<> short 'd'
<> help "Excluding these specific directories from copying"
pure PullOptions{..}
----------------------------------------------------------------------------
-- life add and remove
----------------------------------------------------------------------------
data PathOptions = PathOptions
{ pathOptionsPath :: LifePath
} deriving (Show)
pathOptionsParser :: Parser PathOptions
pathOptionsParser = do
pathOptionsPath <- fileParser <|> dirParser
pure PathOptions{..}
where
fileParser :: Parser LifePath
fileParser = File <$> strOption
( metavar "FILE_PATH"
<> long "file"
<> short 'f'
)
dirParser :: Parser LifePath
dirParser = Dir <$> strOption
( metavar "DIRECTORY_PATH"
<> long "dir"
<> short 'd'
)