finished hlinting

This commit is contained in:
Joey Hess 2010-11-22 17:51:55 -04:00
parent 57adb0347b
commit eeae910242
23 changed files with 144 additions and 159 deletions

View file

@ -30,7 +30,7 @@ module Backend (
) where ) where
import Control.Monad.State import Control.Monad.State
import IO (try) import System.IO.Error (try)
import System.FilePath import System.FilePath
import System.Posix.Files import System.Posix.Files

View file

@ -34,7 +34,7 @@ backend = Backend {
storeFileKey = dummyStore, storeFileKey = dummyStore,
retrieveKeyFile = copyKeyFile, retrieveKeyFile = copyKeyFile,
removeKey = checkRemoveKey, removeKey = checkRemoveKey,
hasKey = checkKeyFile, hasKey = inAnnex,
fsckKey = mustProvide fsckKey = mustProvide
} }
@ -42,19 +42,15 @@ mustProvide :: a
mustProvide = error "must provide this field" mustProvide = error "must provide this field"
{- Storing a key is a no-op. -} {- Storing a key is a no-op. -}
dummyStore :: FilePath -> Key -> Annex (Bool) dummyStore :: FilePath -> Key -> Annex Bool
dummyStore _ _ = return True dummyStore _ _ = return True
{- Just check if the .git/annex/ file for the key exists. -}
checkKeyFile :: Key -> Annex Bool
checkKeyFile k = inAnnex k
{- Try to find a copy of the file in one of the remotes, {- Try to find a copy of the file in one of the remotes,
- and copy it over to this one. -} - and copy it over to this one. -}
copyKeyFile :: Key -> FilePath -> Annex (Bool) copyKeyFile :: Key -> FilePath -> Annex Bool
copyKeyFile key file = do copyKeyFile key file = do
remotes <- Remotes.keyPossibilities key remotes <- Remotes.keyPossibilities key
if (null remotes) if null remotes
then do then do
showNote "not available" showNote "not available"
showLocations key showLocations key
@ -68,76 +64,72 @@ copyKeyFile key file = do
return False return False
trycopy full (r:rs) = do trycopy full (r:rs) = do
probablythere <- probablyPresent r probablythere <- probablyPresent r
if (probablythere) if probablythere
then do then do
showNote $ "copying from " ++ (Git.repoDescribe r) ++ "..." showNote $ "copying from " ++ Git.repoDescribe r ++ "..."
copied <- Remotes.copyFromRemote r key file copied <- Remotes.copyFromRemote r key file
if (copied) if copied
then return True then return True
else trycopy full rs else trycopy full rs
else trycopy full rs else trycopy full rs
probablyPresent r = do -- This check is to avoid an ugly message if a remote is a
-- This check is to avoid an ugly message if a -- drive that is not mounted. Avoid checking inAnnex for ssh
-- remote is a drive that is not mounted. -- remotes because that is unnecessarily slow, and the
-- Avoid checking inAnnex for ssh remotes because -- locationlog should be trusted. (If the ssh remote is down
-- that is unnecessarily slow, and the locationlog -- or really lacks the file, it's ok to show an ugly message
-- should be trusted. (If the ssh remote is down -- before going on to the next remote.)
-- or really lacks the file, it's ok to show probablyPresent r =
-- an ugly message before going on to the next if not $ Git.repoIsUrl r
-- remote.)
if (not $ Git.repoIsUrl r)
then liftIO $ doesFileExist $ annexLocation r key then liftIO $ doesFileExist $ annexLocation r key
else return True else return True
{- Checks remotes to verify that enough copies of a key exist to allow {- Checks remotes to verify that enough copies of a key exist to allow
- for a key to be safely removed (with no data loss), and fails with an - for a key to be safely removed (with no data loss), and fails with an
- error if not. -} - error if not. -}
checkRemoveKey :: Key -> Annex (Bool) checkRemoveKey :: Key -> Annex Bool
checkRemoveKey key = do checkRemoveKey key = do
force <- Annex.flagIsSet "force" force <- Annex.flagIsSet "force"
if (force) if force
then return True then return True
else do else do
remotes <- Remotes.keyPossibilities key remotes <- Remotes.keyPossibilities key
numcopies <- getNumCopies numcopies <- getNumCopies
if (numcopies > length remotes) if numcopies > length remotes
then notEnoughCopies numcopies (length remotes) [] then notEnoughCopies numcopies (length remotes) []
else findcopies numcopies 0 remotes [] else findcopies numcopies 0 remotes []
where where
findcopies need have [] bad = findcopies need have [] bad
if (have >= need) | have >= need = return True
then return True | otherwise = notEnoughCopies need have bad
else notEnoughCopies need have bad findcopies need have (r:rs) bad
findcopies need have (r:rs) bad = do | have >= need = return True
if (have >= need) | otherwise = do
then return True haskey <- Remotes.inAnnex r key
else do case haskey of
haskey <- Remotes.inAnnex r key Right True -> findcopies need (have+1) rs bad
case (haskey) of Right False -> findcopies need have rs bad
Right True -> findcopies need (have+1) rs bad Left _ -> findcopies need have rs (r:bad)
Right False -> findcopies need have rs bad
Left _ -> findcopies need have rs (r:bad)
notEnoughCopies need have bad = do notEnoughCopies need have bad = do
unsafe unsafe
showLongNote $ showLongNote $
"Could only verify the existence of " ++ "Could only verify the existence of " ++
(show have) ++ " out of " ++ (show need) ++ show have ++ " out of " ++ show need ++
" necessary copies" " necessary copies"
showTriedRemotes bad showTriedRemotes bad
showLocations key showLocations key
hint hint
return False return False
unsafe = showNote "unsafe" unsafe = showNote "unsafe"
hint = showLongNote $ "(Use --force to override this check, or adjust annex.numcopies.)" hint = showLongNote "(Use --force to override this check, or adjust annex.numcopies.)"
showLocations :: Key -> Annex () showLocations :: Key -> Annex ()
showLocations key = do showLocations key = do
g <- Annex.gitRepo g <- Annex.gitRepo
u <- getUUID g u <- getUUID g
uuids <- liftIO $ keyLocations g key uuids <- liftIO $ keyLocations g key
let uuidsf = filter (\v -> v /= u) uuids let uuidsf = filter (/= u) uuids
ppuuids <- prettyPrintUUIDs uuidsf ppuuids <- prettyPrintUUIDs uuidsf
if (null uuidsf) if null uuidsf
then showLongNote $ "No other repository is known to contain the file." then showLongNote $ "No other repository is known to contain the file."
else showLongNote $ "Try making some of these repositories available:\n" ++ ppuuids else showLongNote $ "Try making some of these repositories available:\n" ++ ppuuids
@ -145,7 +137,7 @@ showTriedRemotes :: [Git.Repo] -> Annex ()
showTriedRemotes [] = return () showTriedRemotes [] = return ()
showTriedRemotes remotes = showTriedRemotes remotes =
showLongNote $ "I was unable to access these remotes: " ++ showLongNote $ "I was unable to access these remotes: " ++
(Remotes.list remotes) Remotes.list remotes
getNumCopies :: Annex Int getNumCopies :: Annex Int
getNumCopies = do getNumCopies = do
@ -173,7 +165,7 @@ checkKeyNumCopies key = do
remotes <- Remotes.keyPossibilities key remotes <- Remotes.keyPossibilities key
inannex <- inAnnex key inannex <- inAnnex key
let present = length remotes + if inannex then 1 else 0 let present = length remotes + if inannex then 1 else 0
if (present < needed) if present < needed
then do then do
warning $ note present needed warning $ note present needed
return False return False

View file

@ -33,15 +33,15 @@ sha1 file = do
liftIO $ pOpen ReadFromPipe "sha1sum" [file] $ \h -> do liftIO $ pOpen ReadFromPipe "sha1sum" [file] $ \h -> do
line <- hGetLine h line <- hGetLine h
let bits = split " " line let bits = split " " line
if (null bits) if null bits
then error "sha1sum parse error" then error "sha1sum parse error"
else return $ bits !! 0 else return $ head bits
-- A key is a sha1 of its contents. -- A key is a sha1 of its contents.
keyValue :: FilePath -> Annex (Maybe Key) keyValue :: FilePath -> Annex (Maybe Key)
keyValue file = do keyValue file = do
s <- sha1 file s <- sha1 file
return $ Just $ Key ((name backend), s) return $ Just $ Key (name backend, s)
-- A key's sha1 is checked during fsck. -- A key's sha1 is checked during fsck.
checkKeySHA1 :: Key -> Annex Bool checkKeySHA1 :: Key -> Annex Bool
@ -49,11 +49,11 @@ checkKeySHA1 key = do
g <- Annex.gitRepo g <- Annex.gitRepo
let file = annexLocation g key let file = annexLocation g key
present <- liftIO $ doesFileExist file present <- liftIO $ doesFileExist file
if (not present) if not present
then return True then return True
else do else do
s <- sha1 file s <- sha1 file
if (s == keyName key) if s == keyName key
then return True then return True
else do else do
dest <- moveBad key dest <- moveBad key

View file

@ -37,11 +37,11 @@ backend = Backend.File.backend {
keyValue :: FilePath -> Annex (Maybe Key) keyValue :: FilePath -> Annex (Maybe Key)
keyValue file = do keyValue file = do
stat <- liftIO $ getFileStatus file stat <- liftIO $ getFileStatus file
return $ Just $ Key ((name backend), key stat) return $ Just $ Key (name backend, key stat)
where where
key stat = uniqueid stat ++ sep ++ base key stat = uniqueid stat ++ sep ++ base
uniqueid stat = (show $ modificationTime stat) ++ sep ++ uniqueid stat = show (modificationTime stat) ++ sep ++
(show $ fileSize stat) show (fileSize stat)
base = takeFileName file base = takeFileName file
sep = ":" sep = ":"
@ -58,11 +58,11 @@ checkKeySize key = do
g <- Annex.gitRepo g <- Annex.gitRepo
let file = annexLocation g key let file = annexLocation g key
present <- liftIO $ doesFileExist file present <- liftIO $ doesFileExist file
if (not present) if not present
then return True then return True
else do else do
s <- liftIO $ getFileStatus file s <- liftIO $ getFileStatus file
if (fileSize s == keySize key) if fileSize s == keySize key
then return True then return True
else do else do
dest <- moveBad key dest <- moveBad key

View file

@ -28,7 +28,7 @@ seek = [withFilesNotInGit start, withFilesUnlocked start]
start :: SubCmdStartBackendFile start :: SubCmdStartBackendFile
start pair@(file, _) = notAnnexed file $ do start pair@(file, _) = notAnnexed file $ do
s <- liftIO $ getSymbolicLinkStatus file s <- liftIO $ getSymbolicLinkStatus file
if ((isSymbolicLink s) || (not $ isRegularFile s)) if (isSymbolicLink s) || (not $ isRegularFile s)
then return Nothing then return Nothing
else do else do
showStart "add" file showStart "add" file
@ -37,7 +37,7 @@ start pair@(file, _) = notAnnexed file $ do
perform :: (FilePath, Maybe Backend) -> SubCmdPerform perform :: (FilePath, Maybe Backend) -> SubCmdPerform
perform (file, backend) = do perform (file, backend) = do
stored <- Backend.storeFileKey file backend stored <- Backend.storeFileKey file backend
case (stored) of case stored of
Nothing -> return Nothing Nothing -> return Nothing
Just (key, _) -> return $ Just $ cleanup file key Just (key, _) -> return $ Just $ cleanup file key

View file

@ -24,7 +24,7 @@ seek = [withFilesInGit start]
start :: SubCmdStartString start :: SubCmdStartString
start file = isAnnexed file $ \(key, backend) -> do start file = isAnnexed file $ \(key, backend) -> do
inbackend <- Backend.hasKey key inbackend <- Backend.hasKey key
if (not inbackend) if not inbackend
then return Nothing then return Nothing
else do else do
showStart "drop" file showStart "drop" file
@ -33,13 +33,13 @@ start file = isAnnexed file $ \(key, backend) -> do
perform :: Key -> Backend -> SubCmdPerform perform :: Key -> Backend -> SubCmdPerform
perform key backend = do perform key backend = do
success <- Backend.removeKey backend key success <- Backend.removeKey backend key
if (success) if success
then return $ Just $ cleanup key then return $ Just $ cleanup key
else return Nothing else return Nothing
cleanup :: Key -> SubCmdCleanup cleanup :: Key -> SubCmdCleanup
cleanup key = do cleanup key = do
inannex <- inAnnex key inannex <- inAnnex key
when (inannex) $ removeAnnex key when inannex $ removeAnnex key
logStatus key ValueMissing logStatus key ValueMissing
return True return True

View file

@ -22,12 +22,12 @@ seek = [withKeys start]
start :: SubCmdStartString start :: SubCmdStartString
start keyname = do start keyname = do
backends <- Backend.list backends <- Backend.list
let key = genKey (backends !! 0) keyname let key = genKey (head backends) keyname
present <- inAnnex key present <- inAnnex key
force <- Annex.flagIsSet "force" force <- Annex.flagIsSet "force"
if (not present) if not present
then return Nothing then return Nothing
else if (not force) else if not force
then error "dropkey is can cause data loss; use --force if you're sure you want to do this" then error "dropkey is can cause data loss; use --force if you're sure you want to do this"
else do else do
showStart "dropkey" keyname showStart "dropkey" keyname

View file

@ -20,5 +20,5 @@ seek = [withDefault "." withFilesInGit start]
start :: SubCmdStartString start :: SubCmdStartString
start file = isAnnexed file $ \(key, _) -> do start file = isAnnexed file $ \(key, _) -> do
exists <- inAnnex key exists <- inAnnex key
when (exists) $ liftIO $ putStrLn file when exists $ liftIO $ putStrLn file
return Nothing return Nothing

View file

@ -25,7 +25,7 @@ start :: SubCmdStartString
start file = isAnnexed file $ \(key, _) -> do start file = isAnnexed file $ \(key, _) -> do
link <- calcGitLink file key link <- calcGitLink file key
l <- liftIO $ readSymbolicLink file l <- liftIO $ readSymbolicLink file
if (link == l) if link == l
then return Nothing then return Nothing
else do else do
showStart "fix" file showStart "fix" file

View file

@ -29,10 +29,10 @@ start file = do
keyname <- Annex.flagGet "key" keyname <- Annex.flagGet "key"
when (null keyname) $ error "please specify the key with --key" when (null keyname) $ error "please specify the key with --key"
backends <- Backend.list backends <- Backend.list
let key = genKey (backends !! 0) keyname let key = genKey (head backends) keyname
inbackend <- Backend.hasKey key inbackend <- Backend.hasKey key
unless (inbackend) $ error $ unless inbackend $ error $
"key ("++keyname++") is not present in backend" "key ("++keyname++") is not present in backend"
showStart "fromkey" file showStart "fromkey" file
return $ Just $ perform file key return $ Just $ perform file key

View file

@ -24,6 +24,6 @@ start file = isAnnexed file $ \(key, backend) -> do
perform :: Key -> Backend -> SubCmdPerform perform :: Key -> Backend -> SubCmdPerform
perform key backend = do perform key backend = do
success <- Backend.fsckKey backend key success <- Backend.fsckKey backend key
if (success) if success
then return $ Just $ return True then return $ Just $ return True
else return Nothing else return Nothing

View file

@ -24,6 +24,6 @@ start file = isAnnexed file $ \(key, backend) -> do
perform :: Key -> Backend -> SubCmdPerform perform :: Key -> Backend -> SubCmdPerform
perform key backend = do perform key backend = do
success <- Backend.fsckKey backend key success <- Backend.fsckKey backend key
if (success) if success
then return $ Just $ return True then return $ Just $ return True
else return Nothing else return Nothing

View file

@ -20,7 +20,7 @@ seek = [withFilesInGit start]
start :: SubCmdStartString start :: SubCmdStartString
start file = isAnnexed file $ \(key, backend) -> do start file = isAnnexed file $ \(key, backend) -> do
inannex <- inAnnex key inannex <- inAnnex key
if (inannex) if inannex
then return Nothing then return Nothing
else do else do
showStart "get" file showStart "get" file
@ -29,7 +29,7 @@ start file = isAnnexed file $ \(key, backend) -> do
perform :: Key -> Backend -> SubCmdPerform perform :: Key -> Backend -> SubCmdPerform
perform key backend = do perform key backend = do
ok <- getViaTmp key (Backend.retrieveKeyFile backend key) ok <- getViaTmp key (Backend.retrieveKeyFile backend key)
if (ok) if ok
then return $ Just $ return True -- no cleanup needed then return $ Just $ return True -- no cleanup needed
else return Nothing else return Nothing

View file

@ -25,8 +25,8 @@ seek = [withString start]
{- Stores description for the repository etc. -} {- Stores description for the repository etc. -}
start :: SubCmdStartString start :: SubCmdStartString
start description = do start description = do
when (null description) $ error $ when (null description) $
"please specify a description of this repository\n" error "please specify a description of this repository\n"
showStart "init" description showStart "init" description
return $ Just $ perform description return $ Just $ perform description
@ -38,7 +38,7 @@ perform description = do
setVersion setVersion
liftIO $ gitAttributes g liftIO $ gitAttributes g
liftIO $ gitPreCommitHook g liftIO $ gitPreCommitHook g
return $ Just $ cleanup return $ Just cleanup
cleanup :: SubCmdCleanup cleanup :: SubCmdCleanup
cleanup = do cleanup = do
@ -53,7 +53,7 @@ cleanup = do
gitAttributes :: Git.Repo -> IO () gitAttributes :: Git.Repo -> IO ()
gitAttributes repo = do gitAttributes repo = do
exists <- doesFileExist attributes exists <- doesFileExist attributes
if (not exists) if not exists
then do then do
writeFile attributes $ attrLine ++ "\n" writeFile attributes $ attrLine ++ "\n"
commit commit
@ -76,7 +76,7 @@ gitPreCommitHook repo = do
let hook = Git.workTree repo ++ "/" ++ Git.gitDir repo ++ let hook = Git.workTree repo ++ "/" ++ Git.gitDir repo ++
"/hooks/pre-commit" "/hooks/pre-commit"
exists <- doesFileExist hook exists <- doesFileExist hook
if (exists) if exists
then putStrLn $ "pre-commit hook (" ++ hook ++ ") already exists, not configuring" then putStrLn $ "pre-commit hook (" ++ hook ++ ") already exists, not configuring"
else do else do
writeFile hook $ "#!/bin/sh\n" ++ writeFile hook $ "#!/bin/sh\n" ++

View file

@ -7,8 +7,7 @@
module Command.Move where module Command.Move where
import Control.Monad.State (liftIO) import Control.Monad.State (liftIO, when)
import Monad (when)
import Command import Command
import qualified Command.Drop import qualified Command.Drop
@ -53,7 +52,7 @@ start file = do
moveToStart :: SubCmdStartString moveToStart :: SubCmdStartString
moveToStart file = isAnnexed file $ \(key, _) -> do moveToStart file = isAnnexed file $ \(key, _) -> do
ishere <- inAnnex key ishere <- inAnnex key
if (not ishere) if not ishere
then return Nothing -- not here, so nothing to do then return Nothing -- not here, so nothing to do
else do else do
showStart "move" file showStart "move" file
@ -68,10 +67,10 @@ moveToPerform key = do
showNote $ show err showNote $ show err
return Nothing return Nothing
Right False -> do Right False -> do
showNote $ "moving to " ++ (Git.repoDescribe remote) ++ "..." showNote $ "moving to " ++ Git.repoDescribe remote ++ "..."
let tmpfile = (annexTmpLocation remote) ++ (keyFile key) let tmpfile = annexTmpLocation remote ++ keyFile key
ok <- Remotes.copyToRemote remote key tmpfile ok <- Remotes.copyToRemote remote key tmpfile
if (ok) if ok
then return $ Just $ moveToCleanup remote key tmpfile then return $ Just $ moveToCleanup remote key tmpfile
else return Nothing -- failed else return Nothing -- failed
Right True -> return $ Just $ Command.Drop.cleanup key Right True -> return $ Just $ Command.Drop.cleanup key
@ -79,7 +78,7 @@ moveToCleanup :: Git.Repo -> Key -> FilePath -> SubCmdCleanup
moveToCleanup remote key tmpfile = do moveToCleanup remote key tmpfile = do
-- Tell remote to use the transferred content. -- Tell remote to use the transferred content.
ok <- Remotes.runCmd remote "git-annex" ["setkey", "--quiet", ok <- Remotes.runCmd remote "git-annex" ["setkey", "--quiet",
"--backend=" ++ (backendName key), "--backend=" ++ backendName key,
"--key=" ++ keyName key, "--key=" ++ keyName key,
tmpfile] tmpfile]
if ok if ok
@ -104,7 +103,7 @@ moveFromStart :: SubCmdStartString
moveFromStart file = isAnnexed file $ \(key, _) -> do moveFromStart file = isAnnexed file $ \(key, _) -> do
remote <- Remotes.commandLineRemote remote <- Remotes.commandLineRemote
l <- Remotes.keyPossibilities key l <- Remotes.keyPossibilities key
if (null $ filter (\r -> Remotes.same r remote) l) if null $ filter (\r -> Remotes.same r remote) l
then return Nothing then return Nothing
else do else do
showStart "move" file showStart "move" file
@ -113,18 +112,18 @@ moveFromPerform :: Key -> SubCmdPerform
moveFromPerform key = do moveFromPerform key = do
remote <- Remotes.commandLineRemote remote <- Remotes.commandLineRemote
ishere <- inAnnex key ishere <- inAnnex key
if (ishere) if ishere
then return $ Just $ moveFromCleanup remote key then return $ Just $ moveFromCleanup remote key
else do else do
showNote $ "moving from " ++ (Git.repoDescribe remote) ++ "..." showNote $ "moving from " ++ Git.repoDescribe remote ++ "..."
ok <- getViaTmp key (Remotes.copyFromRemote remote key) ok <- getViaTmp key $ Remotes.copyFromRemote remote key
if (ok) if ok
then return $ Just $ moveFromCleanup remote key then return $ Just $ moveFromCleanup remote key
else return Nothing -- fail else return Nothing -- fail
moveFromCleanup :: Git.Repo -> Key -> SubCmdCleanup moveFromCleanup :: Git.Repo -> Key -> SubCmdCleanup
moveFromCleanup remote key = do moveFromCleanup remote key = do
ok <- Remotes.runCmd remote "git-annex" ["dropkey", "--quiet", "--force", ok <- Remotes.runCmd remote "git-annex" ["dropkey", "--quiet", "--force",
"--backend=" ++ (backendName key), "--backend=" ++ backendName key,
keyName key] keyName key]
when ok $ do when ok $ do
-- Record locally that the key is not on the remote. -- Record locally that the key is not on the remote.

View file

@ -28,7 +28,7 @@ start file = return $ Just $ perform file
perform :: FilePath -> SubCmdPerform perform :: FilePath -> SubCmdPerform
perform file = do perform file = do
pairs <- Backend.chooseBackends [file] pairs <- Backend.chooseBackends [file]
ok <- doSubCmd $ Command.Add.start $ pairs !! 0 ok <- doSubCmd $ Command.Add.start $ head pairs
if ok if ok
then return $ Just $ cleanup file then return $ Just $ cleanup file
else error $ "failed to add " ++ file ++ "; canceling commit" else error $ "failed to add " ++ file ++ "; canceling commit"

View file

@ -28,7 +28,7 @@ start file = do
keyname <- Annex.flagGet "key" keyname <- Annex.flagGet "key"
when (null keyname) $ error "please specify the key with --key" when (null keyname) $ error "please specify the key with --key"
backends <- Backend.list backends <- Backend.list
let key = genKey (backends !! 0) keyname let key = genKey (head backends) keyname
showStart "setkey" file showStart "setkey" file
return $ Just $ perform file key return $ Just $ perform file key
perform :: FilePath -> Key -> SubCmdPerform perform :: FilePath -> Key -> SubCmdPerform

View file

@ -34,7 +34,7 @@ perform file key backend = do
-- force backend to always remove -- force backend to always remove
Annex.flagChange "force" $ FlagBool True Annex.flagChange "force" $ FlagBool True
ok <- Backend.removeKey backend key ok <- Backend.removeKey backend key
if (ok) if ok
then return $ Just $ cleanup file key then return $ Just $ cleanup file key
else return Nothing else return Nothing

View file

@ -35,7 +35,7 @@ checkUnused :: Annex Bool
checkUnused = do checkUnused = do
showNote "checking for unused data..." showNote "checking for unused data..."
unused <- unusedKeys unused <- unusedKeys
if (null unused) if null unused
then return True then return True
else do else do
let list = number 1 unused let list = number 1 unused
@ -48,9 +48,10 @@ checkUnused = do
w u = unlines $ w u = unlines $
["Some annexed data is no longer pointed to by any files in the repository:", ["Some annexed data is no longer pointed to by any files in the repository:",
" NUMBER KEY"] " NUMBER KEY"]
++ (map (\(n, k) -> " " ++ (pad 6 $ show n) ++ " " ++ show k) u) ++ ++ map cols u ++
["(To see where data was previously used, try: git log --stat -S'KEY')", ["(To see where data was previously used, try: git log --stat -S'KEY')",
"(To remove unwanted data: git-annex dropunused NUMBER)"] "(To remove unwanted data: git-annex dropunused NUMBER)"]
cols (n,k) = " " ++ pad 6 (show n) ++ " " ++ show k
pad n s = s ++ replicate (n - length s) ' ' pad n s = s ++ replicate (n - length s) ' '
number :: Integer -> [a] -> [(Integer, a)] number :: Integer -> [a] -> [(Integer, a)]
@ -71,8 +72,7 @@ unusedKeys = do
let unused_m = remove referenced present_m let unused_m = remove referenced present_m
return $ M.keys unused_m return $ M.keys unused_m
where where
remove [] m = m remove a b = foldl (flip M.delete) b a
remove (x:xs) m = remove xs $ M.delete x m
existsMap :: Ord k => [k] -> M.Map k Int existsMap :: Ord k => [k] -> M.Map k Int
existsMap l = M.fromList $ map (\k -> (k, 1)) l existsMap l = M.fromList $ map (\k -> (k, 1)) l

View file

@ -7,7 +7,7 @@
module Core where module Core where
import IO (try) import System.IO.Error (try)
import System.Directory import System.Directory
import Control.Monad.State (liftIO) import Control.Monad.State (liftIO)
import System.Path import System.Path

View file

@ -17,16 +17,14 @@ module Remotes (
runCmd runCmd
) where ) where
import IO (bracket_) import Control.Exception.Extensible
import Control.Exception.Extensible hiding (bracket_)
import Control.Monad.State (liftIO) import Control.Monad.State (liftIO)
import Control.Monad (filterM)
import qualified Data.Map as Map import qualified Data.Map as Map
import Data.String.Utils import Data.String.Utils
import System.Directory hiding (copyFile) import System.Directory hiding (copyFile)
import System.Posix.Directory import System.Posix.Directory
import List import Data.List
import Monad (when, unless) import Control.Monad (when, unless, filterM)
import Types import Types
import qualified GitRepo as Git import qualified GitRepo as Git
@ -55,7 +53,7 @@ keyPossibilities key = do
-- But, reading the config of remotes can be expensive, so make -- But, reading the config of remotes can be expensive, so make
-- sure we only do it once per git-annex run. -- sure we only do it once per git-annex run.
remotesread <- Annex.flagIsSet "remotesread" remotesread <- Annex.flagIsSet "remotesread"
if (remotesread) if remotesread
then reposByUUID allremotes uuids then reposByUUID allremotes uuids
else do else do
-- We assume that it's cheap to read the config -- We assume that it's cheap to read the config
@ -65,11 +63,11 @@ keyPossibilities key = do
let cheap = filter (not . Git.repoIsUrl) allremotes let cheap = filter (not . Git.repoIsUrl) allremotes
let expensive = filter Git.repoIsUrl allremotes let expensive = filter Git.repoIsUrl allremotes
doexpensive <- filterM cachedUUID expensive doexpensive <- filterM cachedUUID expensive
unless (null doexpensive) $ do unless (null doexpensive) $
showNote $ "getting UUID for " ++ showNote $ "getting UUID for " ++
(list doexpensive) ++ "..." list doexpensive ++ "..."
let todo = cheap ++ doexpensive let todo = cheap ++ doexpensive
if (not $ null todo) if not $ null todo
then do then do
_ <- mapM tryGitConfigRead todo _ <- mapM tryGitConfigRead todo
Annex.flagChange "remotesread" $ FlagBool True Annex.flagChange "remotesread" $ FlagBool True
@ -84,10 +82,9 @@ keyPossibilities key = do
- If the remote cannot be accessed, returns a Left error. - If the remote cannot be accessed, returns a Left error.
-} -}
inAnnex :: Git.Repo -> Key -> Annex (Either IOException Bool) inAnnex :: Git.Repo -> Key -> Annex (Either IOException Bool)
inAnnex r key = do inAnnex r key = if Git.repoIsUrl r
if (not $ Git.repoIsUrl r) then checkremote
then liftIO $ ((try checklocal)::IO (Either IOException Bool)) else liftIO (try checklocal ::IO (Either IOException Bool))
else checkremote
where where
checklocal = do checklocal = do
-- run a local check by making an Annex monad -- run a local check by making an Annex monad
@ -112,12 +109,12 @@ reposByCost :: [Git.Repo] -> Annex [Git.Repo]
reposByCost l = do reposByCost l = do
notignored <- filterM repoNotIgnored l notignored <- filterM repoNotIgnored l
costpairs <- mapM costpair notignored costpairs <- mapM costpair notignored
return $ fst $ unzip $ sortBy bycost $ costpairs return $ fst $ unzip $ sortBy cmpcost costpairs
where where
costpair r = do costpair r = do
cost <- repoCost r cost <- repoCost r
return (r, cost) return (r, cost)
bycost (_, c1) (_, c2) = compare c1 c2 cmpcost (_, c1) (_, c2) = compare c1 c2
{- Calculates cost for a repo. {- Calculates cost for a repo.
- -
@ -127,9 +124,9 @@ reposByCost l = do
repoCost :: Git.Repo -> Annex Int repoCost :: Git.Repo -> Annex Int
repoCost r = do repoCost r = do
cost <- repoConfig r "cost" "" cost <- repoConfig r "cost" ""
if (not $ null cost) if not $ null cost
then return $ read cost then return $ read cost
else if (Git.repoIsUrl r) else if Git.repoIsUrl r
then return 200 then return 200
else return 100 else return 100
@ -141,13 +138,12 @@ repoNotIgnored r = do
ignored <- repoConfig r "ignore" "false" ignored <- repoConfig r "ignore" "false"
fromName <- Annex.flagGet "fromrepository" fromName <- Annex.flagGet "fromrepository"
toName <- Annex.flagGet "torepository" toName <- Annex.flagGet "torepository"
let name = if (not $ null fromName) then fromName else toName let name = if null fromName then toName else fromName
if (not $ null name) if not $ null name
then return $ match name then return $ match name
else return $ not $ isIgnored ignored else return $ not $ Git.configTrue ignored
where where
match name = name == Git.repoRemoteName r match name = name == Git.repoRemoteName r
isIgnored ignored = Git.configTrue ignored
{- Checks if two repos are the same, by comparing their remote names. -} {- Checks if two repos are the same, by comparing their remote names. -}
same :: Git.Repo -> Git.Repo -> Bool same :: Git.Repo -> Git.Repo -> Bool
@ -158,14 +154,14 @@ commandLineRemote :: Annex Git.Repo
commandLineRemote = do commandLineRemote = do
fromName <- Annex.flagGet "fromrepository" fromName <- Annex.flagGet "fromrepository"
toName <- Annex.flagGet "torepository" toName <- Annex.flagGet "torepository"
let name = if (not $ null fromName) then fromName else toName let name = if null fromName then toName else fromName
when (null name) $ error "no remote specified" when (null name) $ error "no remote specified"
g <- Annex.gitRepo g <- Annex.gitRepo
let match = filter (\r -> name == Git.repoRemoteName r) $ let match = filter (\r -> name == Git.repoRemoteName r) $
Git.remotes g Git.remotes g
when (null match) $ error $ when (null match) $ error $
"there is no git remote named \"" ++ name ++ "\"" "there is no git remote named \"" ++ name ++ "\""
return $ match !! 0 return $ head match
{- The git configs for the git repo's remotes is not read on startup {- The git configs for the git repo's remotes is not read on startup
- because reading it may be expensive. This function tries to read the - because reading it may be expensive. This function tries to read the
@ -174,12 +170,12 @@ commandLineRemote = do
tryGitConfigRead :: Git.Repo -> Annex (Either Git.Repo Git.Repo) tryGitConfigRead :: Git.Repo -> Annex (Either Git.Repo Git.Repo)
tryGitConfigRead r = do tryGitConfigRead r = do
sshoptions <- repoConfig r "ssh-options" "" sshoptions <- repoConfig r "ssh-options" ""
if (Map.null $ Git.configMap r) if Map.null $ Git.configMap r
then do then do
-- configRead can fail due to IO error or -- configRead can fail due to IO error or
-- for other reasons; catch all possible exceptions -- for other reasons; catch all possible exceptions
result <- liftIO $ (try (Git.configRead r $ Just $ words sshoptions)::IO (Either SomeException (Git.Repo))) result <- liftIO (try (Git.configRead r $ Just $ words sshoptions)::IO (Either SomeException Git.Repo))
case (result) of case result of
Left _ -> return $ Left r Left _ -> return $ Left r
Right r' -> do Right r' -> do
g <- Annex.gitRepo g <- Annex.gitRepo
@ -192,18 +188,16 @@ tryGitConfigRead r = do
where where
exchange [] _ = [] exchange [] _ = []
exchange (old:ls) new = exchange (old:ls) new =
if (Git.repoRemoteName old == Git.repoRemoteName new) if Git.repoRemoteName old == Git.repoRemoteName new
then new:(exchange ls new) then new : exchange ls new
else old:(exchange ls new) else old : exchange ls new
{- Tries to copy a key's content from a remote to a file. -} {- Tries to copy a key's content from a remote to a file. -}
copyFromRemote :: Git.Repo -> Key -> FilePath -> Annex Bool copyFromRemote :: Git.Repo -> Key -> FilePath -> Annex Bool
copyFromRemote r key file = do copyFromRemote r key file
if (not $ Git.repoIsUrl r) | not $ Git.repoIsUrl r = getlocal
then getlocal | Git.repoIsSsh r = getssh
else if (Git.repoIsSsh r) | otherwise = error "copying from non-ssh repo not supported"
then getssh
else error "copying from non-ssh repo not supported"
where where
getlocal = liftIO $ copyFile keyloc file getlocal = liftIO $ copyFile keyloc file
getssh = scp r [sshLocation r keyloc, file] getssh = scp r [sshLocation r keyloc, file]
@ -214,9 +208,9 @@ copyToRemote :: Git.Repo -> Key -> FilePath -> Annex Bool
copyToRemote r key file = do copyToRemote r key file = do
g <- Annex.gitRepo g <- Annex.gitRepo
let keyloc = annexLocation g key let keyloc = annexLocation g key
if (not $ Git.repoIsUrl r) if not $ Git.repoIsUrl r
then putlocal keyloc then putlocal keyloc
else if (Git.repoIsSsh r) else if Git.repoIsSsh r
then putssh keyloc then putssh keyloc
else error "copying to non-ssh repo not supported" else error "copying to non-ssh repo not supported"
where where
@ -224,7 +218,7 @@ copyToRemote r key file = do
putssh src = scp r [src, sshLocation r file] putssh src = scp r [src, sshLocation r file]
sshLocation :: Git.Repo -> FilePath -> FilePath sshLocation :: Git.Repo -> FilePath -> FilePath
sshLocation r file = (Git.urlHost r) ++ ":" ++ shellEscape file sshLocation r file = Git.urlHost r ++ ":" ++ shellEscape file
{- Runs scp against a specified remote. (Honors annex-scp-options.) -} {- Runs scp against a specified remote. (Honors annex-scp-options.) -}
scp :: Git.Repo -> [String] -> Annex Bool scp :: Git.Repo -> [String] -> Annex Bool
@ -238,21 +232,21 @@ scp r params = do
runCmd :: Git.Repo -> String -> [String] -> Annex Bool runCmd :: Git.Repo -> String -> [String] -> Annex Bool
runCmd r command params = do runCmd r command params = do
sshoptions <- repoConfig r "ssh-options" "" sshoptions <- repoConfig r "ssh-options" ""
if (not $ Git.repoIsUrl r) if not $ Git.repoIsUrl r
then do then do
cwd <- liftIO $ getCurrentDirectory cwd <- liftIO getCurrentDirectory
liftIO $ bracket_ (changeWorkingDirectory (Git.workTree r)) liftIO $ bracket_
(\_ -> changeWorkingDirectory cwd) $ (changeWorkingDirectory (Git.workTree r))
boolSystem command params (changeWorkingDirectory cwd)
else if (Git.repoIsSsh r) (boolSystem command params)
then do else if Git.repoIsSsh r
liftIO $ boolSystem "ssh" $ then liftIO $ boolSystem "ssh" $
(words sshoptions) ++ words sshoptions ++ [Git.urlHost r, sshcmd]
[Git.urlHost r, "cd " ++
(shellEscape $ Git.workTree r) ++
" && " ++ (shellEscape command) ++ " " ++
(unwords $ map shellEscape params)]
else error "running command in non-ssh repo not supported" else error "running command in non-ssh repo not supported"
where
sshcmd = "cd " ++ shellEscape (Git.workTree r) ++
" && " ++ shellEscape command ++ " " ++
unwords (map shellEscape params)
{- Looks up a per-remote config option in git config. {- Looks up a per-remote config option in git config.
- Failing that, tries looking for a global config option. -} - Failing that, tries looking for a global config option. -}
@ -262,5 +256,5 @@ repoConfig r key def = do
let def' = Git.configGet g global def let def' = Git.configGet g global def
return $ Git.configGet g local def' return $ Git.configGet g local def'
where where
local = "remote." ++ (Git.repoRemoteName r) ++ ".annex-" ++ key local = "remote." ++ Git.repoRemoteName r ++ ".annex-" ++ key
global = "annex." ++ key global = "annex." ++ key

View file

@ -35,12 +35,12 @@ hGetContentsStrict h = hGetContents h >>= \s -> length s `seq` return s
{- Returns the parent directory of a path. Parent of / is "" -} {- Returns the parent directory of a path. Parent of / is "" -}
parentDir :: String -> String parentDir :: String -> String
parentDir dir = parentDir dir =
if (not $ null dirs) if not $ null dirs
then slash ++ (join s $ take ((length dirs) - 1) dirs) then slash ++ join s (take (length dirs - 1) dirs)
else "" else ""
where where
dirs = filter (\x -> not $ null x) $ split s dir dirs = filter (not . null) $ split s dir
slash = if (not $ isAbsolute dir) then "" else s slash = if isAbsolute dir then s else ""
s = [pathSeparator] s = [pathSeparator]
{- Constructs a relative path from the CWD to a directory. {- Constructs a relative path from the CWD to a directory.
@ -58,7 +58,7 @@ relPathCwdToDir dir = do
where where
-- absolute, normalized form of the directory -- absolute, normalized form of the directory
absnorm cwd = absnorm cwd =
case (absNormPath cwd dir) of case absNormPath cwd dir of
Just d -> d Just d -> d
Nothing -> error $ "unable to normalize " ++ dir Nothing -> error $ "unable to normalize " ++ dir
@ -70,7 +70,7 @@ relPathCwdToDir dir = do
-} -}
relPathDirToDir :: FilePath -> FilePath -> FilePath relPathDirToDir :: FilePath -> FilePath -> FilePath
relPathDirToDir from to = relPathDirToDir from to =
if (not $ null path) if not $ null path
then addTrailingPathSeparator path then addTrailingPathSeparator path
else "" else ""
where where
@ -80,8 +80,8 @@ relPathDirToDir from to =
common = map fst $ filter same $ zip pfrom pto common = map fst $ filter same $ zip pfrom pto
same (c,d) = c == d same (c,d) = c == d
uncommon = drop numcommon pto uncommon = drop numcommon pto
dotdots = take ((length pfrom) - numcommon) $ repeat ".." dotdots = replicate (length pfrom - numcommon) ".."
numcommon = length $ common numcommon = length common
path = join s $ dotdots ++ uncommon path = join s $ dotdots ++ uncommon
{- Run a system command, and returns True or False {- Run a system command, and returns True or False
@ -124,4 +124,4 @@ shellEscape f = "'" ++ escaped ++ "'"
unsetFileMode :: FilePath -> FileMode -> IO () unsetFileMode :: FilePath -> FileMode -> IO ()
unsetFileMode f m = do unsetFileMode f m = do
s <- getFileStatus f s <- getFileStatus f
setFileMode f $ (fileMode s) `intersectFileModes` (complement m) setFileMode f $ fileMode s `intersectFileModes` complement m

View file

@ -25,13 +25,13 @@ getVersion :: Annex (Maybe String)
getVersion = do getVersion = do
g <- Annex.gitRepo g <- Annex.gitRepo
let v = Git.configGet g versionField "" let v = Git.configGet g versionField ""
if (not $ null v) if not $ null v
then return $ Just v then return $ Just v
else do else do
-- version 0 was not recorded in .git/config; -- version 0 was not recorded in .git/config;
-- such a repo should have an annexDir -- such a repo should have an annexDir
d <- liftIO $ doesDirectoryExist $ annexDir g d <- liftIO $ doesDirectoryExist $ annexDir g
if (d) if d
then return $ Just "0" then return $ Just "0"
else return Nothing -- no version yet else return Nothing -- no version yet