2011-11-26 12:39:47 +00:00
|
|
|
{-# LANGUAGE BangPatterns #-}
|
|
|
|
|
2010-10-09 23:22:40 +00:00
|
|
|
{- git-annex location log
|
|
|
|
-
|
2011-04-02 19:50:51 +00:00
|
|
|
- git-annex keeps track of which repositories have the contents of annexed
|
|
|
|
- files.
|
2010-10-09 23:22:40 +00:00
|
|
|
-
|
2010-10-12 22:06:34 +00:00
|
|
|
- Repositories record their UUID and the date when they --get or --drop
|
2010-10-13 00:04:36 +00:00
|
|
|
- a value.
|
2010-10-10 16:31:14 +00:00
|
|
|
-
|
2015-06-09 18:08:57 +00:00
|
|
|
- Copyright 2010-2015 Joey Hess <id@joeyh.name>
|
2010-10-27 20:53:54 +00:00
|
|
|
-
|
|
|
|
- Licensed under the GNU GPL version 3 or higher.
|
2010-10-09 23:22:40 +00:00
|
|
|
-}
|
|
|
|
|
2011-10-15 20:21:08 +00:00
|
|
|
module Logs.Location (
|
2010-10-12 22:25:41 +00:00
|
|
|
LogStatus(..),
|
2012-12-12 23:20:38 +00:00
|
|
|
logStatus,
|
2010-10-13 19:55:18 +00:00
|
|
|
logChange,
|
2012-01-10 17:11:16 +00:00
|
|
|
loggedLocations,
|
2014-02-06 16:43:56 +00:00
|
|
|
loggedLocationsHistorical,
|
2016-07-17 19:15:08 +00:00
|
|
|
loggedLocationsRef,
|
2016-04-22 17:49:32 +00:00
|
|
|
isKnownKey,
|
2015-06-09 18:08:57 +00:00
|
|
|
checkDead,
|
|
|
|
setDead,
|
2011-07-01 21:23:01 +00:00
|
|
|
loggedKeys,
|
2011-10-29 21:49:37 +00:00
|
|
|
loggedKeysFor,
|
2010-10-11 21:52:46 +00:00
|
|
|
) where
|
2010-10-09 23:22:40 +00:00
|
|
|
|
2016-01-20 20:36:33 +00:00
|
|
|
import Annex.Common
|
2011-10-04 04:40:47 +00:00
|
|
|
import qualified Annex.Branch
|
2013-08-29 22:51:22 +00:00
|
|
|
import Logs
|
2011-10-15 20:21:08 +00:00
|
|
|
import Logs.Presence
|
2012-12-12 23:20:38 +00:00
|
|
|
import Annex.UUID
|
2016-07-17 19:15:08 +00:00
|
|
|
import Annex.CatFile
|
|
|
|
import Git.Types (RefDate, Ref)
|
2015-01-28 21:17:26 +00:00
|
|
|
import qualified Annex
|
2012-12-12 23:20:38 +00:00
|
|
|
|
2015-06-09 18:52:05 +00:00
|
|
|
import Data.Time.Clock
|
2016-07-17 19:15:08 +00:00
|
|
|
import qualified Data.ByteString.Lazy.Char8 as L
|
2015-06-09 18:52:05 +00:00
|
|
|
|
2012-12-12 23:20:38 +00:00
|
|
|
{- Log a change in the presence of a key's value in current repository. -}
|
|
|
|
logStatus :: Key -> LogStatus -> Annex ()
|
2013-09-05 01:37:13 +00:00
|
|
|
logStatus key s = do
|
2012-12-12 23:20:38 +00:00
|
|
|
u <- getUUID
|
2013-09-05 01:37:13 +00:00
|
|
|
logChange key u s
|
2010-10-09 23:22:40 +00:00
|
|
|
|
2011-06-22 20:01:32 +00:00
|
|
|
{- Log a change in the presence of a key's value in a repository. -}
|
2011-11-09 05:15:51 +00:00
|
|
|
logChange :: Key -> UUID -> LogStatus -> Annex ()
|
2015-04-01 21:53:16 +00:00
|
|
|
logChange = logChange' logNow
|
|
|
|
|
|
|
|
logChange' :: (LogStatus -> String -> Annex LogLine) -> Key -> UUID -> LogStatus -> Annex ()
|
|
|
|
logChange' mklog key (UUID u) s = do
|
2015-01-28 21:17:26 +00:00
|
|
|
config <- Annex.getGitConfig
|
2015-10-12 18:46:28 +00:00
|
|
|
maybeAddLog (locationLogFile config key) =<< mklog s u
|
2015-04-01 21:53:16 +00:00
|
|
|
logChange' _ _ NoUUID _ = noop
|
2010-10-12 22:25:41 +00:00
|
|
|
|
|
|
|
{- Returns a list of repository UUIDs that, according to the log, have
|
2014-02-06 16:43:56 +00:00
|
|
|
- the value of a key. -}
|
2012-01-10 17:11:16 +00:00
|
|
|
loggedLocations :: Key -> Annex [UUID]
|
2015-04-01 21:53:16 +00:00
|
|
|
loggedLocations = getLoggedLocations currentLogInfo
|
2014-02-06 16:43:56 +00:00
|
|
|
|
|
|
|
{- Gets the location log on a particular date. -}
|
|
|
|
loggedLocationsHistorical :: RefDate -> Key -> Annex [UUID]
|
2015-04-01 21:53:16 +00:00
|
|
|
loggedLocationsHistorical = getLoggedLocations . historicalLogInfo
|
2014-02-06 16:43:56 +00:00
|
|
|
|
2016-07-17 19:15:08 +00:00
|
|
|
{- Gets the locations contained in a git ref. -}
|
|
|
|
loggedLocationsRef :: Ref -> Annex [UUID]
|
|
|
|
loggedLocationsRef ref = map toUUID . getLog . L.unpack <$> catObject ref
|
|
|
|
|
2014-02-06 16:43:56 +00:00
|
|
|
getLoggedLocations :: (FilePath -> Annex [String]) -> Key -> Annex [UUID]
|
2015-01-28 21:17:26 +00:00
|
|
|
getLoggedLocations getter key = do
|
|
|
|
config <- Annex.getGitConfig
|
2015-04-01 21:53:16 +00:00
|
|
|
map toUUID <$> getter (locationLogFile config key)
|
|
|
|
|
2016-04-22 17:49:32 +00:00
|
|
|
{- Is there a location log for the key? True even for keys with no
|
|
|
|
- remaining locations. -}
|
|
|
|
isKnownKey :: Key -> Annex Bool
|
|
|
|
isKnownKey key = do
|
|
|
|
config <- Annex.getGitConfig
|
|
|
|
not . null <$> readLog (locationLogFile config key)
|
|
|
|
|
2015-06-09 18:08:57 +00:00
|
|
|
{- For a key to be dead, all locations that have location status for the key
|
|
|
|
- must have InfoDead set. -}
|
|
|
|
checkDead :: Key -> Annex Bool
|
|
|
|
checkDead key = do
|
2015-04-01 21:53:16 +00:00
|
|
|
config <- Annex.getGitConfig
|
2015-06-09 18:08:57 +00:00
|
|
|
ls <- compactLog <$> readLog (locationLogFile config key)
|
|
|
|
return $ all (\l -> status l == InfoDead) ls
|
|
|
|
|
2015-06-09 18:52:05 +00:00
|
|
|
{- Updates the log to say that a key is dead.
|
|
|
|
-
|
|
|
|
- Changes all logged lines for the key, in any location, that are
|
|
|
|
- currently InfoMissing, to be InfoDead.
|
|
|
|
-}
|
2015-06-09 18:08:57 +00:00
|
|
|
setDead :: Key -> Annex ()
|
2015-06-09 18:52:05 +00:00
|
|
|
setDead key = do
|
|
|
|
config <- Annex.getGitConfig
|
|
|
|
let logfile = locationLogFile config key
|
|
|
|
ls <- compactLog <$> readLog logfile
|
|
|
|
mapM_ (go logfile) (filter (\l -> status l == InfoMissing) ls)
|
|
|
|
where
|
|
|
|
go logfile l = addLog logfile $ setDead' l
|
|
|
|
|
|
|
|
{- Note that the timestamp in the log is updated minimally, so that this
|
|
|
|
- can be overruled by other location log changes. -}
|
|
|
|
setDead' :: LogLine -> LogLine
|
|
|
|
setDead' l = l
|
|
|
|
{ status = InfoDead
|
|
|
|
, date = date l + realToFrac (picosecondsToDiffTime 1)
|
|
|
|
}
|
2011-04-02 19:50:51 +00:00
|
|
|
|
2011-04-03 00:36:01 +00:00
|
|
|
{- Finds all keys that have location log information.
|
|
|
|
- (There may be duplicate keys in the list.) -}
|
2011-06-23 03:24:14 +00:00
|
|
|
loggedKeys :: Annex [Key]
|
2013-08-29 22:51:22 +00:00
|
|
|
loggedKeys = mapMaybe locationLogFileKey <$> Annex.Branch.files
|
2011-07-01 21:23:01 +00:00
|
|
|
|
2011-10-29 21:49:37 +00:00
|
|
|
{- Finds all keys that have location log information indicating
|
|
|
|
- they are present for the specified repository. -}
|
|
|
|
loggedKeysFor :: UUID -> Annex [Key]
|
|
|
|
loggedKeysFor u = filterM isthere =<< loggedKeys
|
2012-11-11 04:51:07 +00:00
|
|
|
where
|
|
|
|
{- This should run strictly to avoid the filterM
|
|
|
|
- building many thunks containing keyLocations data. -}
|
|
|
|
isthere k = do
|
|
|
|
us <- loggedLocations k
|
|
|
|
let !there = u `elem` us
|
|
|
|
return there
|