This avoids 4 uses of head.
-{- git-annex file locations
+{- git-annex object file locations
-
- Copyright 2010-2019 Joey Hess <id@joeyh.name>
-
import Data.Default
import Data.Bits
+import qualified Data.List.NonEmpty as NE
import qualified Data.ByteArray as BA
import qualified Data.ByteArray.Encoding as BA
import qualified Data.ByteString as S
- To support that, some git-annex repositories use the lower case-hash.
- All special remotes use the lower-case hash for new data, but old data
- may still use the mixed case hash. -}
-dirHashes :: [HashLevels -> Hasher]
-dirHashes = [hashDirLower, hashDirMixed]
+dirHashes :: NE.NonEmpty (HashLevels -> Hasher)
+dirHashes = hashDirLower NE.:| [hashDirMixed]
hashDirs :: HashLevels -> Int -> S.ByteString -> RawFilePath
hashDirs (HashLevels 1) sz s = P.addTrailingPathSeparator $ S.take sz s
import Data.Char
import Data.Default
+import qualified Data.List.NonEmpty as NE
import qualified Data.ByteString.Char8 as S8
import qualified System.FilePath.ByteString as P
- This is compatible with the annexLocationsNonBare and annexLocationsBare,
- for interoperability between special remotes and git-annex repos.
-}
-keyPaths :: Key -> [RawFilePath]
-keyPaths key = map (\h -> keyPath key (h def)) dirHashes
+keyPaths :: Key -> NE.NonEmpty RawFilePath
+keyPaths key = NE.map (\h -> keyPath key (h def)) dirHashes
import Utility.Gpg
import Utility.UserInfo
+import Utility.PartialPrelude
import Types.Remote (RemoteConfigField)
import Annex.SpecialRemote.Config
import Types.ProposedAccepted
+import Data.Maybe
import qualified Data.Map as M
import Control.Applicative
import Prelude
oldkeys <- secretKeys cmd
username <- either (const "unknown") id <$> myUserName
let basekeyname = username ++ "'s git-annex encryption key"
- return $ Prelude.head $ filter (\n -> M.null $ M.filter (== n) oldkeys)
- ( basekeyname
- : map (\n -> basekeyname ++ show n) ([2..] :: [Int])
- )
+ return $ fromMaybe (error "internal") $ headMaybe $
+ filter (\n -> M.null $ M.filter (== n) oldkeys)
+ ( basekeyname
+ : map (\n -> basekeyname ++ show n) ([2..] :: [Int])
+ )
data EnableEncryption = HybridEncryption | SharedEncryption | NoEncryption
deriving (Eq)
| otherwise = Git.Construct.fromUrl $ "ssh://" ++ host ++ slash dir
where
bits = splitc ':' r
- host = Prelude.head bits
+ host = fromMaybe "" $ headMaybe bits
dir = intercalate ":" $ drop 1 bits
-- "host:~user/dir" is not supported specially by bup;
-- "host:dir" is relative to the home directory;
import qualified Data.ByteString.Lazy as L
import qualified Data.Map as M
+import qualified Data.List.NonEmpty as NE
import qualified System.FilePath.ByteString as P
import Data.Default
import System.PosixCompat.Files (isRegularFile, deviceID)
{- Locations to try to access a given Key in the directory.
- We try more than one since we used to write to different hash
- directories. -}
-locations :: RawFilePath -> Key -> [RawFilePath]
-locations d k = map (d P.</>) (keyPaths k)
+locations :: RawFilePath -> Key -> NE.NonEmpty RawFilePath
+locations d k = NE.map (d P.</>) (keyPaths k)
+
+locations' :: RawFilePath -> Key -> [RawFilePath]
+locations' d k = NE.toList (locations d k)
{- Returns the location off a Key in the directory. If the key is
- present, returns the location that is actually used, otherwise
getLocation :: RawFilePath -> Key -> IO RawFilePath
getLocation d k = do
let locs = locations d k
- fromMaybe (Prelude.head locs)
- <$> firstM (doesFileExist . fromRawFilePath) locs
+ fromMaybe (NE.head locs)
+ <$> firstM (doesFileExist . fromRawFilePath)
+ (NE.toList locs)
{- Directory where the file(s) for a key are stored. -}
storeDir :: RawFilePath -> Key -> RawFilePath
dest' = fromRawFilePath dest
retrieveKeyFileM :: RawFilePath -> ChunkConfig -> CopyCoWTried -> Retriever
-retrieveKeyFileM d (LegacyChunks _) _ = Legacy.retrieve locations d
+retrieveKeyFileM d (LegacyChunks _) _ = Legacy.retrieve locations' d
retrieveKeyFileM d NoChunks cow = fileRetriever' $ \dest k p iv -> do
src <- liftIO $ fromRawFilePath <$> getLocation d k
void $ liftIO $ fileCopier cow src (fromRawFilePath dest) p iv
goparents (upFrom subdir) =<< tryIO (removeDirectory d)
checkPresentM :: RawFilePath -> ChunkConfig -> CheckPresent
-checkPresentM d (LegacyChunks _) k = Legacy.checkKey d locations k
-checkPresentM d _ k = checkPresentGeneric d (locations d k)
+checkPresentM d (LegacyChunks _) k = Legacy.checkKey d locations' k
+checkPresentM d _ k = checkPresentGeneric d (locations' d k)
checkPresentGeneric :: RawFilePath -> [RawFilePath] -> Annex Bool
checkPresentGeneric d ps = checkPresentGeneric' d $
import qualified Utility.RawFilePath as R
import qualified Data.Map as M
+import qualified Data.List.NonEmpty as NE
remote :: RemoteType
remote = specialRemoteType $ RemoteType
store :: RsyncOpts -> Key -> FilePath -> MeterUpdate -> Annex ()
store o k src meterupdate = storeGeneric o meterupdate basedest populatedest
where
- basedest = fromRawFilePath $ Prelude.head (keyPaths k)
+ basedest = fromRawFilePath $ NE.head (keyPaths k)
populatedest dest = liftIO $ if canrename
then do
R.rename (toRawFilePath src) (toRawFilePath dest)
import Data.Default
import System.FilePath.Posix
+import qualified Data.List.NonEmpty as NE
type RsyncUrl = String
mkRsyncUrl o f = rsyncUrl o </> rsyncEscape o f
rsyncUrls :: RsyncOpts -> Key -> [RsyncUrl]
-rsyncUrls o k = map use dirHashes
+rsyncUrls o k = map use (NE.toList dirHashes)
where
use h = rsyncUrl o </> hash h </> rsyncEscape o (f </> f)
f = fromRawFilePath (keyFile k)
checkFile mvariant filename =
Utility.Gpg.checkEncryptionFile gpgcmd (Just environ) filename $
if mvariant == Just Types.Crypto.PubKey then ks else Nothing
- serializeKeys cipher = map fromRawFilePath .
- Annex.Locations.keyPaths .
- Crypto.encryptKey Types.Crypto.HmacSha1 cipher
+ serializeKeys cipher = map fromRawFilePath . NE.toList
+ . Annex.Locations.keyPaths
+ . Crypto.encryptKey Types.Crypto.HmacSha1 cipher
#else
test_gpg_crypto = putStrLn "gpg testing not implemented on Windows"
#endif