From 50e2ea38256f2992abe43beb3c7e8a7984559ecb Mon Sep 17 00:00:00 2001 From: Joey Hess Date: Wed, 27 Mar 2013 13:51:24 -0400 Subject: [PATCH] Per-command usage messages. --- CmdLine.hs | 11 ++++++--- Command/Help.hs | 19 ++++++++++---- GitAnnex.hs | 53 ++------------------------------------- GitAnnex/Options.hs | 60 +++++++++++++++++++++++++++++++++++++++++++++ GitAnnexShell.hs | 2 +- Option.hs | 2 +- Usage.hs | 21 +++++++++++++++- debian/changelog | 1 + 8 files changed, 106 insertions(+), 63 deletions(-) create mode 100644 GitAnnex/Options.hs diff --git a/CmdLine.hs b/CmdLine.hs index 4899354536..db46cba823 100644 --- a/CmdLine.hs +++ b/CmdLine.hs @@ -48,7 +48,7 @@ dispatch fuzzyok allargs allcmds commonoptions fields header getgitrepo = do err msg = msg ++ "\n\n" ++ usage header allcmds cmd = Prelude.head cmds (fuzzy, cmds, name, args) = findCmd fuzzyok allargs allcmds err - (flags, params) = getOptCmd args cmd commonoptions err + (flags, params) = getOptCmd args cmd commonoptions checkfuzzy = when fuzzy $ inRepo $ Git.AutoCorrect.prepare name cmdname cmds @@ -74,12 +74,15 @@ findCmd fuzzyok argv cmds err {- Parses command line options, and returns actions to run to configure flags - and the remaining parameters for the command. -} -getOptCmd :: Params -> Command -> [Option] -> (String -> String) -> (Flags, Params) -getOptCmd argv cmd commonoptions err = check $ +getOptCmd :: Params -> Command -> [Option] -> (Flags, Params) +getOptCmd argv cmd commonoptions = check $ getOpt Permute (commonoptions ++ cmdoptions cmd) argv where check (flags, rest, []) = (flags, rest) - check (_, _, errs) = error $ err $ concat errs + check (_, _, errs) = error $ unlines + [ concat errs + , commandUsage cmd + ] {- Runs a list of Annex actions. Catches IO errors and continues - (but explicitly thrown errors terminate the whole command). diff --git a/Command/Help.hs b/Command/Help.hs index 9f7bb34aec..5762982269 100644 --- a/Command/Help.hs +++ b/Command/Help.hs @@ -18,21 +18,30 @@ import qualified Command.Copy import qualified Command.Sync import qualified Command.Whereis import qualified Command.Fsck +import GitAnnex.Options + +import System.Console.GetOpt def :: [Command] -def = [noCommit $ noRepo showHelp $ dontCheck repoExists $ +def = [noCommit $ noRepo showGeneralHelp $ dontCheck repoExists $ command "help" paramNothing seek SectionUtility "display help"] seek :: [CommandSeek] seek = [withWords start] start :: [String] -> CommandStart +start ["options"] = do + liftIO showCommonOptions + stop start _ = do - liftIO showHelp + liftIO showGeneralHelp stop -showHelp :: IO () -showHelp = liftIO $ putStrLn $ unlines +showCommonOptions :: IO () +showCommonOptions = putStrLn $ usageInfo "Common options:" options + +showGeneralHelp :: IO () +showGeneralHelp = putStrLn $ unlines [ "The most commonly used git-annex commands are:" , unlines $ map cmdline $ concat [ Command.Init.def @@ -45,7 +54,7 @@ showHelp = liftIO $ putStrLn $ unlines , Command.Whereis.def , Command.Fsck.def ] - , "Run git-annex without any options for a complete command and option list." + , "Run git-annex without any options for a complete command list." ] where cmdline c = "\t" ++ cmdname c ++ "\t" ++ cmddesc c diff --git a/GitAnnex.hs b/GitAnnex.hs index 6a0139dcec..b78493dfc4 100644 --- a/GitAnnex.hs +++ b/GitAnnex.hs @@ -9,18 +9,10 @@ module GitAnnex where -import System.Console.GetOpt - -import Common.Annex -import qualified Git.Config import qualified Git.CurrentRepo import CmdLine import Command -import Types.TrustLevel -import qualified Annex -import qualified Remote -import qualified Limit -import qualified Option +import GitAnnex.Options import qualified Command.Add import qualified Command.Unannex @@ -145,49 +137,8 @@ cmds = concat #endif ] -options :: [Option] -options = Option.common ++ - [ Option ['N'] ["numcopies"] (ReqArg setnumcopies paramNumber) - "override default number of copies" - , Option [] ["trust"] (trustArg Trusted) - "override trust setting" - , Option [] ["semitrust"] (trustArg SemiTrusted) - "override trust setting back to default" - , Option [] ["untrust"] (trustArg UnTrusted) - "override trust setting to untrusted" - , Option ['c'] ["config"] (ReqArg setgitconfig "NAME=VALUE") - "override git configuration setting" - , Option ['x'] ["exclude"] (ReqArg Limit.addExclude paramGlob) - "skip files matching the glob pattern" - , Option ['I'] ["include"] (ReqArg Limit.addInclude paramGlob) - "don't skip files matching the glob pattern" - , Option ['i'] ["in"] (ReqArg Limit.addIn paramRemote) - "skip files not present in a remote" - , Option ['C'] ["copies"] (ReqArg Limit.addCopies paramNumber) - "skip files with fewer copies" - , Option ['B'] ["inbackend"] (ReqArg Limit.addInBackend paramName) - "skip files not using a key-value backend" - , Option [] ["inallgroup"] (ReqArg Limit.addInAllGroup paramGroup) - "skip files not present in all remotes in a group" - , Option [] ["largerthan"] (ReqArg Limit.addLargerThan paramSize) - "skip files larger than a size" - , Option [] ["smallerthan"] (ReqArg Limit.addSmallerThan paramSize) - "skip files smaller than a size" - , Option ['T'] ["time-limit"] (ReqArg Limit.addTimeLimit paramTime) - "stop after the specified amount of time" - , Option [] ["trust-glacier"] (NoArg (Annex.setFlag "trustglacier")) - "Trust Amazon Glacier inventory" - ] ++ Option.matcher - where - setnumcopies v = maybe noop - (\n -> Annex.changeGitConfig $ \c -> c { annexNumCopies = n }) - (readish v) - setgitconfig v = Annex.changeGitRepo =<< inRepo (Git.Config.store v) - - trustArg t = ReqArg (Remote.forceTrust t) paramRemote - header :: String -header = "Usage: git-annex command [option ..]" +header = "git-annex command [option ...]" run :: [String] -> IO () run args = dispatch True args cmds options [] header Git.CurrentRepo.get diff --git a/GitAnnex/Options.hs b/GitAnnex/Options.hs new file mode 100644 index 0000000000..7710c2ff26 --- /dev/null +++ b/GitAnnex/Options.hs @@ -0,0 +1,60 @@ +{- git-annex options + - + - Copyright 2010, 2013 Joey Hess + - + - Licensed under the GNU GPL version 3 or higher. + -} + +module GitAnnex.Options where + +import System.Console.GetOpt + +import Common.Annex +import qualified Git.Config +import Command +import Types.TrustLevel +import qualified Annex +import qualified Remote +import qualified Limit +import qualified Option + +options :: [Option] +options = Option.common ++ + [ Option ['N'] ["numcopies"] (ReqArg setnumcopies paramNumber) + "override default number of copies" + , Option [] ["trust"] (trustArg Trusted) + "override trust setting" + , Option [] ["semitrust"] (trustArg SemiTrusted) + "override trust setting back to default" + , Option [] ["untrust"] (trustArg UnTrusted) + "override trust setting to untrusted" + , Option ['c'] ["config"] (ReqArg setgitconfig "NAME=VALUE") + "override git configuration setting" + , Option ['x'] ["exclude"] (ReqArg Limit.addExclude paramGlob) + "skip files matching the glob pattern" + , Option ['I'] ["include"] (ReqArg Limit.addInclude paramGlob) + "don't skip files matching the glob pattern" + , Option ['i'] ["in"] (ReqArg Limit.addIn paramRemote) + "skip files not present in a remote" + , Option ['C'] ["copies"] (ReqArg Limit.addCopies paramNumber) + "skip files with fewer copies" + , Option ['B'] ["inbackend"] (ReqArg Limit.addInBackend paramName) + "skip files not using a key-value backend" + , Option [] ["inallgroup"] (ReqArg Limit.addInAllGroup paramGroup) + "skip files not present in all remotes in a group" + , Option [] ["largerthan"] (ReqArg Limit.addLargerThan paramSize) + "skip files larger than a size" + , Option [] ["smallerthan"] (ReqArg Limit.addSmallerThan paramSize) + "skip files smaller than a size" + , Option ['T'] ["time-limit"] (ReqArg Limit.addTimeLimit paramTime) + "stop after the specified amount of time" + , Option [] ["trust-glacier"] (NoArg (Annex.setFlag "trustglacier")) + "Trust Amazon Glacier inventory" + ] ++ Option.matcher + where + setnumcopies v = maybe noop + (\n -> Annex.changeGitConfig $ \c -> c { annexNumCopies = n }) + (readish v) + setgitconfig v = Annex.changeGitRepo =<< inRepo (Git.Config.store v) + + trustArg t = ReqArg (Remote.forceTrust t) paramRemote diff --git a/GitAnnexShell.hs b/GitAnnexShell.hs index 0431b06f21..2661d52e81 100644 --- a/GitAnnexShell.hs +++ b/GitAnnexShell.hs @@ -62,7 +62,7 @@ options = Option.common ++ expected ++ " but found " ++ s header :: String -header = "Usage: git-annex-shell [-c] command [parameters ...] [option ..]" +header = "git-annex-shell [-c] command [parameters ...] [option ...]" run :: [String] -> IO () run [] = failure diff --git a/Option.hs b/Option.hs index 78fc43438b..d59af43c7a 100644 --- a/Option.hs +++ b/Option.hs @@ -1,4 +1,4 @@ -{- git-annex command-line options +{- common command-line options - - Copyright 2010-2011 Joey Hess - diff --git a/Usage.hs b/Usage.hs index 32d8b28293..a9c8fa7f2a 100644 --- a/Usage.hs +++ b/Usage.hs @@ -11,9 +11,14 @@ import Common.Annex import Types.Command +import System.Console.GetOpt + +usageMessage :: String -> String +usageMessage s = "Usage: " ++ s + {- Usage message with lists of commands by section. -} usage :: String -> [Command] -> String -usage header cmds = unlines $ header : concatMap go [minBound..] +usage header cmds = unlines $ usageMessage header : concatMap go [minBound..] where go section | null cs = [] @@ -37,6 +42,20 @@ usage header cmds = unlines $ header : concatMap go [minBound..] longest f = foldl max 0 $ map (length . f) cmds scmds = sort cmds +{- Usage message for a single command. -} +commandUsage :: Command -> String +commandUsage cmd = unlines + [ usageInfo header (cmdoptions cmd) + , "To see additional options common to all commands, run: git annex help options" + ] + where + header = usageMessage $ unwords + [ "git-annex" + , cmdname cmd + , cmdparamdesc cmd + , "[option ...]" + ] + {- Descriptions of params used in usage messages. -} paramPaths :: String paramPaths = paramOptional $ paramRepeating paramPath -- most often used diff --git a/debian/changelog b/debian/changelog index 885fca35ae..a37eec4212 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,6 +1,7 @@ git-annex (4.20130324) UNRELEASED; urgency=low * Group subcommands into sections in usage. Closes: #703797 + * Per-command usage messages. -- Joey Hess Mon, 25 Mar 2013 10:21:46 -0400