better option handling
multiple-file support for all modes
This commit is contained in:
parent
344f13394f
commit
200bc6fdb8
3 changed files with 51 additions and 35 deletions
12
Annex.hs
12
Annex.hs
|
@ -25,15 +25,14 @@ startAnnex = do
|
||||||
- the annex directory and setting up the symlink pointing to its content. -}
|
- the annex directory and setting up the symlink pointing to its content. -}
|
||||||
annexFile :: State -> FilePath -> IO ()
|
annexFile :: State -> FilePath -> IO ()
|
||||||
annexFile state file = do
|
annexFile state file = do
|
||||||
checkExists file
|
|
||||||
checkLegal file
|
|
||||||
alreadyannexed <- lookupBackend (backends state) (repo state) file
|
alreadyannexed <- lookupBackend (backends state) (repo state) file
|
||||||
case (alreadyannexed) of
|
case (alreadyannexed) of
|
||||||
Just _ -> error $ "already annexed " ++ file
|
Just _ -> error $ "already annexed: " ++ file
|
||||||
Nothing -> do
|
Nothing -> do
|
||||||
|
checkLegal file
|
||||||
stored <- storeFile (backends state) (repo state) file
|
stored <- storeFile (backends state) (repo state) file
|
||||||
case (stored) of
|
case (stored) of
|
||||||
Nothing -> error $ "no backend could store " ++ file
|
Nothing -> error $ "no backend could store: " ++ file
|
||||||
Just key -> symlink key
|
Just key -> symlink key
|
||||||
where
|
where
|
||||||
symlink key = do
|
symlink key = do
|
||||||
|
@ -42,11 +41,6 @@ annexFile state file = do
|
||||||
renameFile file dest
|
renameFile file dest
|
||||||
createSymbolicLink dest file
|
createSymbolicLink dest file
|
||||||
gitAdd (repo state) file
|
gitAdd (repo state) file
|
||||||
checkExists file = do
|
|
||||||
exists <- doesFileExist file
|
|
||||||
if (not exists)
|
|
||||||
then error $ "does not exist: " ++ file
|
|
||||||
else return ()
|
|
||||||
checkLegal file = do
|
checkLegal file = do
|
||||||
s <- getSymbolicLinkStatus file
|
s <- getSymbolicLinkStatus file
|
||||||
if ((isSymbolicLink s) || (not $ isRegularFile s))
|
if ((isSymbolicLink s) || (not $ isRegularFile s))
|
||||||
|
|
45
CmdLine.hs
45
CmdLine.hs
|
@ -10,34 +10,35 @@ import System.Console.GetOpt
|
||||||
import Types
|
import Types
|
||||||
import Annex
|
import Annex
|
||||||
|
|
||||||
data Flag = Add FilePath | Push String | Pull String | Want FilePath |
|
data Mode = Add | Push | Pull | Want | Get | Drop | Unannex
|
||||||
Get (Maybe FilePath) | Drop FilePath | Unannex FilePath
|
|
||||||
deriving Show
|
deriving Show
|
||||||
|
|
||||||
options :: [OptDescr Flag]
|
options :: [OptDescr Mode]
|
||||||
options =
|
options =
|
||||||
[ Option ['a'] ["add"] (ReqArg Add "FILE") "add file to annex"
|
[ Option ['a'] ["add"] (NoArg Add) "add files to annex"
|
||||||
, Option ['p'] ["push"] (ReqArg Push "REPO") "push annex to repo"
|
, Option ['p'] ["push"] (NoArg Push) "push annex to repos"
|
||||||
, Option ['P'] ["pull"] (ReqArg Pull "REPO") "pull annex from repo"
|
, Option ['P'] ["pull"] (NoArg Pull) "pull annex from repos"
|
||||||
, Option ['w'] ["want"] (ReqArg Want "FILE") "request file contents"
|
, Option ['w'] ["want"] (NoArg Want) "request file contents"
|
||||||
, Option ['g'] ["get"] (OptArg Get "FILE") "transfer file contents"
|
, Option ['g'] ["get"] (NoArg Get) "transfer file contents"
|
||||||
, Option ['d'] ["drop"] (ReqArg Drop "FILE") "indicate file content not needed"
|
, Option ['d'] ["drop"] (NoArg Drop) "indicate file contents not needed"
|
||||||
, Option ['u'] ["unannex"] (ReqArg Unannex "FILE") "undo --add"
|
, Option ['u'] ["unannex"] (NoArg Unannex) "undo --add"
|
||||||
]
|
]
|
||||||
|
|
||||||
argvToFlags argv = do
|
argvToMode argv = do
|
||||||
case getOpt Permute options argv of
|
case getOpt Permute options argv of
|
||||||
-- no options? add listed files
|
-- default mode is Add
|
||||||
([],p,[] ) -> return $ map (\f -> Add f) p
|
([],files,[]) -> return (Add, files)
|
||||||
-- all options parsed, return flags
|
-- one mode is normal case
|
||||||
(o,[],[] ) -> return o
|
(m:[],files,[]) -> return (m, files)
|
||||||
|
-- multiple modes is an error
|
||||||
|
(ms,files,[]) -> ioError (userError ("only one mode should be specified\n" ++ usageInfo header options))
|
||||||
-- error case
|
-- error case
|
||||||
(_,n,errs) -> ioError (userError (concat errs ++ usageInfo header options))
|
(_,files,errs) -> ioError (userError (concat errs ++ usageInfo header options))
|
||||||
where header = "Usage: git-annex [option] file"
|
where header = "Usage: git-annex [mode] file"
|
||||||
|
|
||||||
dispatch :: Flag -> State -> IO ()
|
dispatch :: State -> Mode -> FilePath -> IO ()
|
||||||
dispatch flag state = do
|
dispatch state mode file = do
|
||||||
case (flag) of
|
case (mode) of
|
||||||
Add f -> annexFile state f
|
Add -> annexFile state file
|
||||||
Unannex f -> unannexFile state f
|
Unannex -> unannexFile state file
|
||||||
_ -> error "not implemented"
|
_ -> error "not implemented"
|
||||||
|
|
29
git-annex.hs
29
git-annex.hs
|
@ -1,16 +1,37 @@
|
||||||
{- git-annex main program
|
{- git-annex main program
|
||||||
- -}
|
- -}
|
||||||
|
|
||||||
|
import System.IO
|
||||||
import System.Environment
|
import System.Environment
|
||||||
import GitRepo
|
import Control.Exception
|
||||||
import CmdLine
|
import CmdLine
|
||||||
import Annex
|
import Annex
|
||||||
import BackendList
|
|
||||||
|
|
||||||
main = do
|
main = do
|
||||||
args <- getArgs
|
args <- getArgs
|
||||||
flags <- argvToFlags args
|
(mode, files) <- argvToMode args
|
||||||
|
|
||||||
state <- startAnnex
|
state <- startAnnex
|
||||||
|
|
||||||
mapM (\f -> dispatch f state) flags
|
tryRun 0 $ map (\f -> dispatch state mode f) files
|
||||||
|
|
||||||
|
{- Tries to run a series of actions, not stopping if some error out,
|
||||||
|
- and propigating an overall error status at the end. -}
|
||||||
|
tryRun errflag [] = do
|
||||||
|
if (errflag > 0)
|
||||||
|
then error "unsuccessful"
|
||||||
|
else return ()
|
||||||
|
tryRun errflag (a:as) = do
|
||||||
|
result <- try (a)::IO (Either SomeException ())
|
||||||
|
case (result) of
|
||||||
|
Left err -> do
|
||||||
|
showErr err
|
||||||
|
tryRun 1 as
|
||||||
|
Right _ -> tryRun errflag as
|
||||||
|
|
||||||
|
{- Exception pretty-printing. -}
|
||||||
|
showErr :: SomeException -> IO ()
|
||||||
|
showErr e = do
|
||||||
|
let err = show e
|
||||||
|
hPutStrLn stderr $ "git-annex: " ++ err
|
||||||
|
return ()
|
||||||
|
|
Loading…
Reference in a new issue