From 8066a1c3ccf20666229347d51234267698f45b5b Mon Sep 17 00:00:00 2001 From: Joey Hess Date: Fri, 6 Feb 2015 17:08:14 -0400 Subject: [PATCH] The file matching options are now only accepted by commands that can actually use them. --- CmdLine/GitAnnex/Options.hs | 113 +++++++++++++++++++++++++----------- CmdLine/Option.hs | 15 +---- Command.hs | 2 +- Command/Add.hs | 8 ++- Command/Drop.hs | 5 +- Command/Find.hs | 3 +- Command/FindRef.hs | 5 +- Command/Fix.hs | 5 +- Command/Fsck.hs | 2 +- Command/Get.hs | 2 +- Command/Import.hs | 2 +- Command/Info.hs | 2 +- Command/List.hs | 5 +- Command/Lock.hs | 3 +- Command/Log.hs | 2 +- Command/MetaData.hs | 2 +- Command/Migrate.hs | 2 +- Command/Mirror.hs | 2 +- Command/Move.hs | 2 +- Command/Unannex.hs | 3 +- Command/Unlock.hs | 3 +- Command/Whereis.hs | 2 +- debian/changelog | 2 + doc/git-annex.mdwn | 3 - 24 files changed, 118 insertions(+), 77 deletions(-) diff --git a/CmdLine/GitAnnex/Options.hs b/CmdLine/GitAnnex/Options.hs index aaa77c92c8..add29d8dae 100644 --- a/CmdLine/GitAnnex/Options.hs +++ b/CmdLine/GitAnnex/Options.hs @@ -1,6 +1,6 @@ {- git-annex options - - - Copyright 2010, 2013 Joey Hess + - Copyright 2010-2015 Joey Hess - - Licensed under the GNU GPL version 3 or higher. -} @@ -22,6 +22,8 @@ import qualified Limit.Wanted import CmdLine.Option import CmdLine.Usage +-- Options that are accepted by all git-annex sub-commands, +-- although not always used. gitAnnexOptions :: [Option] gitAnnexOptions = commonOptions ++ [ Option ['N'] ["numcopies"] (ReqArg setnumcopies paramNumber) @@ -34,11 +36,48 @@ gitAnnexOptions = commonOptions ++ "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) - "limit to files matching the glob pattern" - , Option ['i'] ["in"] (ReqArg Limit.addIn paramRemote) + , Option [] ["user-agent"] (ReqArg setuseragent paramName) + "override default User-Agent" + , Option [] ["trust-glacier"] (NoArg (Annex.setFlag "trustglacier")) + "Trust Amazon Glacier inventory" + ] + where + trustArg t = ReqArg (Remote.forceTrust t) paramRemote + setnumcopies v = maybe noop + (\n -> Annex.changeState $ \s -> s { Annex.forcenumcopies = Just $ NumCopies n }) + (readish v) + setuseragent v = Annex.changeState $ \s -> s { Annex.useragent = Just v } + setgitconfig v = inRepo (Git.Config.store v) + >>= pure . (\r -> r { gitGlobalOpts = gitGlobalOpts r ++ [Param "-c", Param v] }) + >>= Annex.changeGitRepo + +-- Options for matching on annexed keys, rather than work tree files. +keyOptions :: [Option] +keyOptions = + [ Option ['A'] ["all"] (NoArg (Annex.setFlag "all")) + "operate on all versions of all files" + , Option ['U'] ["unused"] (NoArg (Annex.setFlag "unused")) + "operate on files found by last run of git-annex unused" + , Option [] ["key"] (ReqArg (Annex.setField "key") paramKey) + "operate on specified key" + ] + +-- Options to match properties of annexed files. +annexedMatchingOptions :: [Option] +annexedMatchingOptions = concat + [ nonWorkTreeMatchingOptions' + , fileMatchingOptions' + , combiningOptions + , [timeLimitOption] + ] + +-- Matching options that don't need to examine work tree files. +nonWorkTreeMatchingOptions :: [Option] +nonWorkTreeMatchingOptions = nonWorkTreeMatchingOptions' ++ combiningOptions + +nonWorkTreeMatchingOptions' :: [Option] +nonWorkTreeMatchingOptions' = + [ Option ['i'] ["in"] (ReqArg Limit.addIn paramRemote) "match files present in a remote" , Option ['C'] ["copies"] (ReqArg Limit.addCopies paramNumber) "skip files with fewer copies" @@ -50,43 +89,42 @@ gitAnnexOptions = commonOptions ++ "match files using a key-value backend" , Option [] ["inallgroup"] (ReqArg Limit.addInAllGroup paramGroup) "match files present in all remotes in a group" - , Option [] ["largerthan"] (ReqArg Limit.addLargerThan paramSize) - "match files larger than a size" - , Option [] ["smallerthan"] (ReqArg Limit.addSmallerThan paramSize) - "match files smaller than a size" , Option [] ["metadata"] (ReqArg Limit.addMetaData "FIELD=VALUE") "match files with attached metadata" , Option [] ["want-get"] (NoArg Limit.Wanted.addWantGet) "match files the repository wants to get" , Option [] ["want-drop"] (NoArg Limit.Wanted.addWantDrop) "match files the repository wants to drop" - , Option ['T'] ["time-limit"] (ReqArg Limit.addTimeLimit paramTime) - "stop after the specified amount of time" - , Option [] ["user-agent"] (ReqArg setuseragent paramName) - "override default User-Agent" - , Option [] ["trust-glacier"] (NoArg (Annex.setFlag "trustglacier")) - "Trust Amazon Glacier inventory" - ] ++ matcherOptions - where - trustArg t = ReqArg (Remote.forceTrust t) paramRemote - setnumcopies v = maybe noop - (\n -> Annex.changeState $ \s -> s { Annex.forcenumcopies = Just $ NumCopies n }) - (readish v) - setuseragent v = Annex.changeState $ \s -> s { Annex.useragent = Just v } - setgitconfig v = inRepo (Git.Config.store v) - >>= pure . (\r -> r { gitGlobalOpts = gitGlobalOpts r ++ [Param "-c", Param v] }) - >>= Annex.changeGitRepo - -keyOptions :: [Option] -keyOptions = - [ Option ['A'] ["all"] (NoArg (Annex.setFlag "all")) - "operate on all versions of all files" - , Option ['U'] ["unused"] (NoArg (Annex.setFlag "unused")) - "operate on files found by last run of git-annex unused" - , Option [] ["key"] (ReqArg (Annex.setField "key") paramKey) - "operate on specified key" ] +-- Options to match files which may not yet be annexed. +fileMatchingOptions :: [Option] +fileMatchingOptions = fileMatchingOptions' ++ combiningOptions + +fileMatchingOptions' :: [Option] +fileMatchingOptions' = + [ Option ['x'] ["exclude"] (ReqArg Limit.addExclude paramGlob) + "skip files matching the glob pattern" + , Option ['I'] ["include"] (ReqArg Limit.addInclude paramGlob) + "limit to files matching the glob pattern" + , Option [] ["largerthan"] (ReqArg Limit.addLargerThan paramSize) + "match files larger than a size" + , Option [] ["smallerthan"] (ReqArg Limit.addSmallerThan paramSize) + "match files smaller than a size" + ] + +combiningOptions :: [Option] +combiningOptions = + [ longopt "not" "negate next option" + , longopt "and" "both previous and next option must match" + , longopt "or" "either previous or next option must match" + , shortopt "(" "open group of options" + , shortopt ")" "close group of options" + ] + where + longopt o = Option [] [o] $ NoArg $ Limit.addToken o + shortopt o = Option o [] $ NoArg $ Limit.addToken o + fromOption :: Option fromOption = fieldOption ['f'] "from" paramRemote "source remote" @@ -99,3 +137,8 @@ fromToOptions = [fromOption, toOption] jsonOption :: Option jsonOption = Option ['j'] ["json"] (NoArg (Annex.setOutput JSONOutput)) "enable JSON output" + +timeLimitOption :: Option +timeLimitOption = Option ['T'] ["time-limit"] + (ReqArg Limit.addTimeLimit paramTime) + "stop after the specified amount of time" diff --git a/CmdLine/Option.hs b/CmdLine/Option.hs index 1c1331aab9..1b82dc83eb 100644 --- a/CmdLine/Option.hs +++ b/CmdLine/Option.hs @@ -7,7 +7,6 @@ module CmdLine.Option ( commonOptions, - matcherOptions, flagOption, fieldOption, optionName, @@ -21,9 +20,9 @@ import Common.Annex import qualified Annex import Types.Messages import Types.DesktopNotify -import Limit import CmdLine.Usage +-- Options accepted by both git-annex and git-annex-shell sub-commands. commonOptions :: [Option] commonOptions = [ Option [] ["force"] (NoArg (setforce True)) @@ -56,18 +55,6 @@ commonOptions = unsetdebug = Annex.changeGitConfig $ \c -> c { annexDebug = False } setdesktopnotify v = Annex.changeState $ \s -> s { Annex.desktopnotify = Annex.desktopnotify s <> v } -matcherOptions :: [Option] -matcherOptions = - [ longopt "not" "negate next option" - , longopt "and" "both previous and next option must match" - , longopt "or" "either previous or next option must match" - , shortopt "(" "open group of options" - , shortopt ")" "close group of options" - ] - where - longopt o = Option [] [o] $ NoArg $ addToken o - shortopt o = Option o [] $ NoArg $ addToken o - {- An option that sets a flag. -} flagOption :: String -> String -> String -> Option flagOption short opt description = diff --git a/Command.hs b/Command.hs index 56e895caea..fd12991a41 100644 --- a/Command.hs +++ b/Command.hs @@ -55,7 +55,7 @@ noRepo a c = c { cmdnorepo = Just a } {- Adds options to a command. -} withOptions :: [Option] -> Command -> Command -withOptions o c = c { cmdoptions = o } +withOptions o c = c { cmdoptions = cmdoptions c ++ o } {- For start and perform stages to indicate what step to run next. -} next :: a -> Annex (Maybe a) diff --git a/Command/Add.hs b/Command/Add.hs index 51921fbc3f..7faa7c80d3 100644 --- a/Command/Add.hs +++ b/Command/Add.hs @@ -35,9 +35,11 @@ import Utility.Tmp import Control.Exception (IOException) cmd :: [Command] -cmd = [notBareRepo $ withOptions [includeDotFilesOption] $ - command "add" paramPaths seek SectionCommon - "add files to annex"] +cmd = [notBareRepo $ withOptions addOptions $ + command "add" paramPaths seek SectionCommon "add files to annex"] + +addOptions :: [Option] +addOptions = includeDotFilesOption : fileMatchingOptions includeDotFilesOption :: Option includeDotFilesOption = flagOption [] "include-dotfiles" "don't skip dotfiles" diff --git a/Command/Drop.hs b/Command/Drop.hs index 6adc13ca5a..35c2f5cf42 100644 --- a/Command/Drop.hs +++ b/Command/Drop.hs @@ -23,9 +23,12 @@ import Annex.Notification import qualified Data.Set as S cmd :: [Command] -cmd = [withOptions [dropFromOption] $ command "drop" paramPaths seek +cmd = [withOptions (dropOptions) $ command "drop" paramPaths seek SectionCommon "indicate content of files not currently wanted"] +dropOptions :: [Option] +dropOptions = dropFromOption : annexedMatchingOptions + dropFromOption :: Option dropFromOption = fieldOption ['f'] "from" paramRemote "drop content from a remote" diff --git a/Command/Find.hs b/Command/Find.hs index 55124d8387..236824643e 100644 --- a/Command/Find.hs +++ b/Command/Find.hs @@ -20,7 +20,8 @@ import Utility.DataUnits import Types.Key cmd :: [Command] -cmd = [mkCommand $ command "find" paramPaths seek SectionQuery "lists available files"] +cmd = [withOptions annexedMatchingOptions $ mkCommand $ + command "find" paramPaths seek SectionQuery "lists available files"] mkCommand :: Command -> Command mkCommand = noCommit . noMessages . withOptions [formatOption, print0Option, jsonOption] diff --git a/Command/FindRef.hs b/Command/FindRef.hs index 2e3d859fa8..e7f7eae6de 100644 --- a/Command/FindRef.hs +++ b/Command/FindRef.hs @@ -11,8 +11,9 @@ import Command import qualified Command.Find as Find cmd :: [Command] -cmd = [Find.mkCommand $ command "findref" paramRef seek SectionPlumbing - "lists files in a git ref"] +cmd = [withOptions nonWorkTreeMatchingOptions $ Find.mkCommand $ + command "findref" paramRef seek SectionPlumbing + "lists files in a git ref"] seek :: CommandSeek seek refs = do diff --git a/Command/Fix.hs b/Command/Fix.hs index c981d23ae3..c4e5e52ee9 100644 --- a/Command/Fix.hs +++ b/Command/Fix.hs @@ -19,8 +19,9 @@ import Utility.Touch #endif cmd :: [Command] -cmd = [notDirect $ noCommit $ command "fix" paramPaths seek - SectionMaintenance "fix up symlinks to point to annexed content"] +cmd = [notDirect $ noCommit $ withOptions annexedMatchingOptions $ + command "fix" paramPaths seek + SectionMaintenance "fix up symlinks to point to annexed content"] seek :: CommandSeek seek = withFilesInGit $ whenAnnexed start diff --git a/Command/Fsck.hs b/Command/Fsck.hs index 0242a1f756..e8b1d240c0 100644 --- a/Command/Fsck.hs +++ b/Command/Fsck.hs @@ -62,7 +62,7 @@ fsckOptions = , startIncrementalOption , moreIncrementalOption , incrementalScheduleOption - ] ++ keyOptions + ] ++ keyOptions ++ annexedMatchingOptions seek :: CommandSeek seek ps = do diff --git a/Command/Get.hs b/Command/Get.hs index b1929a79c1..85960fc1a4 100644 --- a/Command/Get.hs +++ b/Command/Get.hs @@ -21,7 +21,7 @@ cmd = [withOptions getOptions $ command "get" paramPaths seek SectionCommon "make content of annexed files available"] getOptions :: [Option] -getOptions = fromOption : keyOptions +getOptions = fromOption : annexedMatchingOptions ++ keyOptions seek :: CommandSeek seek ps = do diff --git a/Command/Import.hs b/Command/Import.hs index 29c139eb65..196f277382 100644 --- a/Command/Import.hs +++ b/Command/Import.hs @@ -26,7 +26,7 @@ opts = , deduplicateOption , cleanDuplicatesOption , skipDuplicatesOption - ] + ] ++ fileMatchingOptions duplicateOption :: Option duplicateOption = flagOption [] "duplicate" "do not delete source files" diff --git a/Command/Info.hs b/Command/Info.hs index 6fb411ec34..e04a72a3cb 100644 --- a/Command/Info.hs +++ b/Command/Info.hs @@ -77,7 +77,7 @@ emptyStatInfo = StatInfo Nothing Nothing M.empty Nothing type StatState = StateT StatInfo Annex cmd :: [Command] -cmd = [noCommit $ dontCheck repoExists $ withOptions [jsonOption] $ +cmd = [noCommit $ dontCheck repoExists $ withOptions (jsonOption : annexedMatchingOptions) $ command "info" (paramOptional $ paramRepeating paramItem) seek SectionQuery "shows information about the specified item or the repository as a whole"] diff --git a/Command/List.hs b/Command/List.hs index bc4e3edecd..b9b3a376c2 100644 --- a/Command/List.hs +++ b/Command/List.hs @@ -24,8 +24,9 @@ import qualified Annex import Git.Types (RemoteName) cmd :: [Command] -cmd = [noCommit $ withOptions [allrepos] $ command "list" paramPaths seek - SectionQuery "show which remotes contain files"] +cmd = [noCommit $ withOptions (allrepos : annexedMatchingOptions) $ + command "list" paramPaths seek + SectionQuery "show which remotes contain files"] allrepos :: Option allrepos = flagOption [] "allrepos" "show all repositories, not only remotes" diff --git a/Command/Lock.hs b/Command/Lock.hs index 574e747c4b..720169506e 100644 --- a/Command/Lock.hs +++ b/Command/Lock.hs @@ -13,7 +13,8 @@ import qualified Annex.Queue import qualified Annex cmd :: [Command] -cmd = [notDirect $ command "lock" paramPaths seek SectionCommon +cmd = [notDirect $ withOptions annexedMatchingOptions $ + command "lock" paramPaths seek SectionCommon "undo unlock command"] seek :: CommandSeek diff --git a/Command/Log.hs b/Command/Log.hs index 7c48388c2b..4bc7bb89ad 100644 --- a/Command/Log.hs +++ b/Command/Log.hs @@ -39,7 +39,7 @@ cmd = [withOptions options $ command "log" paramPaths seek SectionQuery "shows location log"] options :: [Option] -options = passthruOptions ++ [gourceOption] +options = passthruOptions ++ [gourceOption] ++ annexedMatchingOptions passthruOptions :: [Option] passthruOptions = map odate ["since", "after", "until", "before"] ++ diff --git a/Command/MetaData.hs b/Command/MetaData.hs index 0956379593..a16f4214a7 100644 --- a/Command/MetaData.hs +++ b/Command/MetaData.hs @@ -28,7 +28,7 @@ metaDataOptions = , untagOption , getOption , jsonOption - ] ++ keyOptions + ] ++ keyOptions ++ annexedMatchingOptions storeModMeta :: ModMeta -> Annex () storeModMeta modmeta = Annex.changeState $ diff --git a/Command/Migrate.hs b/Command/Migrate.hs index 9c7dec9ef9..46c0eb675f 100644 --- a/Command/Migrate.hs +++ b/Command/Migrate.hs @@ -18,7 +18,7 @@ import qualified Command.ReKey import qualified Command.Fsck cmd :: [Command] -cmd = [notDirect $ +cmd = [notDirect $ withOptions annexedMatchingOptions $ command "migrate" paramPaths seek SectionUtility "switch data to different backend"] diff --git a/Command/Mirror.hs b/Command/Mirror.hs index 558f906c5b..7d3a7ef67c 100644 --- a/Command/Mirror.hs +++ b/Command/Mirror.hs @@ -18,7 +18,7 @@ import qualified Annex import Config.NumCopies cmd :: [Command] -cmd = [withOptions (fromToOptions ++ keyOptions) $ +cmd = [withOptions (fromToOptions ++ annexedMatchingOptions ++ keyOptions) $ command "mirror" paramPaths seek SectionCommon "mirror content of files to/from another repository"] diff --git a/Command/Move.hs b/Command/Move.hs index 4a3633e8f3..5317cefdda 100644 --- a/Command/Move.hs +++ b/Command/Move.hs @@ -22,7 +22,7 @@ cmd = [withOptions moveOptions $ command "move" paramPaths seek SectionCommon "move content of files to/from another repository"] moveOptions :: [Option] -moveOptions = fromToOptions ++ keyOptions +moveOptions = fromToOptions ++ keyOptions ++ annexedMatchingOptions seek :: CommandSeek seek ps = do diff --git a/Command/Unannex.hs b/Command/Unannex.hs index a88b07c8b3..3fe4cf69ca 100644 --- a/Command/Unannex.hs +++ b/Command/Unannex.hs @@ -23,7 +23,8 @@ import Utility.CopyFile import Command.PreCommit (lockPreCommitHook) cmd :: [Command] -cmd = [command "unannex" paramPaths seek SectionUtility +cmd = [withOptions annexedMatchingOptions $ + command "unannex" paramPaths seek SectionUtility "undo accidential add command"] seek :: CommandSeek diff --git a/Command/Unlock.hs b/Command/Unlock.hs index 31bc1f2e2d..2083819300 100644 --- a/Command/Unlock.hs +++ b/Command/Unlock.hs @@ -19,7 +19,8 @@ cmd = , c "edit" "same as unlock" ] where - c n = notDirect . command n paramPaths seek SectionCommon + c n = notDirect . withOptions annexedMatchingOptions + . command n paramPaths seek SectionCommon seek :: CommandSeek seek = withFilesInGit $ whenAnnexed start diff --git a/Command/Whereis.hs b/Command/Whereis.hs index d612ce4f03..5f31998c51 100644 --- a/Command/Whereis.hs +++ b/Command/Whereis.hs @@ -16,7 +16,7 @@ import Logs.Trust import Logs.Web cmd :: [Command] -cmd = [noCommit $ withOptions (jsonOption : keyOptions) $ +cmd = [noCommit $ withOptions (jsonOption : annexedMatchingOptions ++ keyOptions) $ command "whereis" paramPaths seek SectionQuery "lists repositories that have file content"] diff --git a/debian/changelog b/debian/changelog index 58c9519e2d..2d3312787a 100644 --- a/debian/changelog +++ b/debian/changelog @@ -8,6 +8,8 @@ git-annex (5.20150206) UNRELEASED; urgency=medium expression. * import: Support file matching options such as --exclude, --include, --smallerthan, --largerthan + * The file matching options are now only accepted by commands that + can actually use them, instead of by all commands. -- Joey Hess Fri, 06 Feb 2015 13:57:08 -0400 diff --git a/doc/git-annex.mdwn b/doc/git-annex.mdwn index d0064b20e4..d9d515d418 100644 --- a/doc/git-annex.mdwn +++ b/doc/git-annex.mdwn @@ -992,9 +992,6 @@ subdirectories). This is similar to the find command, but instead of finding files in the current work tree, it finds files in the specified git ref. - Most MATCHING OPTIONS can be used with findref, to limit the files it - finds. However, the --include and --exclude options will not work. - * `proxy -- git cmd [options]` Only useful in a direct mode repository, this runs the specified git