diff --git a/package.yaml b/package.yaml index 56bceaa..b249498 100644 --- a/package.yaml +++ b/package.yaml @@ -75,6 +75,7 @@ library: - http-types - lens - mtl + - optparse-applicative - template-haskell - text - time diff --git a/src/Taskell/Config.hs b/src/Taskell/Config.hs index d4f811f..1938dcf 100644 --- a/src/Taskell/Config.hs +++ b/src/Taskell/Config.hs @@ -17,6 +17,3 @@ trelloUsage = decodeUtf8 $(embedFile "templates/trello-token.txt") githubUsage :: Text githubUsage = decodeUtf8 $(embedFile "templates/github-token.txt") - -usage :: Text -usage = decodeUtf8 $(embedFile "templates/usage.txt") diff --git a/src/Taskell/IO.hs b/src/Taskell/IO.hs index 62a2d66..f6cb95d 100644 --- a/src/Taskell/IO.hs +++ b/src/Taskell/IO.hs @@ -9,7 +9,11 @@ import Data.Either (fromRight) import Data.Time.Zones (TZ) -import Taskell.Config (githubUsage, trelloUsage, usage, version) +import Options.Applicative (Parser, ParserInfo, ParserPrefs (..), + switch, strOption, strArgument, long, short, metavar, help, + info, helper, headerDoc, customExecParser, defaultPrefs) + +import Taskell.Config (githubUsage, trelloUsage, version) import Taskell.Data.Lists (Lists, analyse, initial) import Taskell.IO.Config (Config, general, getDir, github, markdown, templatePath, @@ -48,18 +52,58 @@ getPath path = do isDir <- lift $ doesDirectoryExist canonicial pure $ if isDir then canonicial defaultFilename else canonicial -parseArgs :: [Text] -> ReaderConfig Next -parseArgs ["-v"] = pure $ Output version -parseArgs ["-h"] = pure $ Output usage -parseArgs ["-t", boardID, file] = getPath file >>= loadTrello boardID -parseArgs ["-g", identifier, file] = getPath file >>= loadGitHub identifier -parseArgs ["-i", file] = getPath file >>= fileInfo -parseArgs [file] = getPath file >>= loadFile -parseArgs [] = getPath "" >>= loadFile -parseArgs _ = pure $ Error (unlines ["Invalid options", "", usage]) +-- | Parse command-line arguments to an action +commandLineArgsParser :: Parser (ReaderConfig Next) +commandLineArgsParser = foldl' (<|>) noArgs + [ openBoardFile <$> fileParser + + , pure (Output version) <$ + switch (short 'v' <> long "version" <> help "Show version number") + + , (\boardID file -> getPath file >>= loadTrello boardID) + <$> strOption + ( short 't' + <> long "trello" + <> metavar "" + <> help "Create a new taskell file from the given Trello board ID" + ) + <*> fileParser + + , (\identifier file -> getPath file >>= loadGitHub identifier) + <$> strOption + ( short 'g' + <> long "github" + <> metavar "[orgs/ | repos//]" + <> help "Create a new taskell file from the given GitHub identifier" + ) + <*> fileParser + + , fmap (getPath >=> fileInfo) $ + switch + ( short 'i' + <> long "info" + <> help "Display information about a file" + ) + *> fileParser + ] + where + fileParser = strArgument $ metavar "file" + openBoardFile = getPath >=> loadFile + + -- | Open default board file + noArgs = pure $ openBoardFile mempty + +commandLineArgsParserInfo :: ParserInfo (ReaderConfig Next) +commandLineArgsParserInfo = + info (helper <*> commandLineArgsParser) $ + headerDoc (Just "Taskell - A CLI kanban board/task manager") load :: ReaderConfig Next -load = getArgs >>= parseArgs +load = + join . liftIO $ + customExecParser + defaultPrefs { prefShowHelpOnError = True } + commandLineArgsParserInfo colonic :: FilePath -> Text -> Text colonic path = ((pack path <> ": ") <>) diff --git a/templates/usage.txt b/templates/usage.txt deleted file mode 100644 index adcd399..0000000 --- a/templates/usage.txt +++ /dev/null @@ -1,9 +0,0 @@ -Usage: taskell ([options] | [-i | -t | -g [orgs/ | repos//]] file) - -Options: - --h Help --v Version number --i file Display information about a file --t file Create a new taskell file from the given Trello board ID --g [orgs/ | repos//] file Create a new taskell file from the given GitHub identifier