2012-01-06 19:40:04 +00:00
|
|
|
{- git-annex command
|
|
|
|
-
|
|
|
|
- Copyright 2012 Joey Hess <joey@kitenet.net>
|
|
|
|
-
|
|
|
|
- Licensed under the GNU GPL version 3 or higher.
|
|
|
|
-}
|
|
|
|
|
|
|
|
module Command.Log where
|
|
|
|
|
|
|
|
import qualified Data.Set as S
|
|
|
|
import qualified Data.ByteString.Lazy.Char8 as L
|
|
|
|
import Data.Time.Clock.POSIX
|
|
|
|
import Data.Time
|
|
|
|
import System.Locale
|
|
|
|
import Data.Char
|
|
|
|
|
|
|
|
import Common.Annex
|
|
|
|
import Command
|
|
|
|
import qualified Logs.Location
|
|
|
|
import qualified Logs.Presence
|
|
|
|
import Annex.CatFile
|
|
|
|
import qualified Annex.Branch
|
|
|
|
import qualified Git
|
|
|
|
import Git.Command
|
|
|
|
import qualified Remote
|
2012-01-06 21:24:03 +00:00
|
|
|
import qualified Option
|
2012-01-06 19:40:04 +00:00
|
|
|
|
|
|
|
def :: [Command]
|
2012-01-06 21:24:03 +00:00
|
|
|
def = [withOptions [afterOption] $
|
|
|
|
command "log" paramPaths seek "shows location log"]
|
|
|
|
|
|
|
|
afterOption :: Option
|
|
|
|
afterOption = Option.field [] "after" paramDate "show log after date"
|
2012-01-06 19:40:04 +00:00
|
|
|
|
|
|
|
seek :: [CommandSeek]
|
2012-01-06 21:24:03 +00:00
|
|
|
seek = [withField afterOption return $ \afteropt ->
|
|
|
|
withFilesInGit $ whenAnnexed $ start afteropt]
|
2012-01-06 19:40:04 +00:00
|
|
|
|
2012-01-06 21:24:03 +00:00
|
|
|
start :: Maybe String -> FilePath -> (Key, Backend) -> CommandStart
|
|
|
|
start afteropt file (key, _) = do
|
|
|
|
let ps = case afteropt of
|
|
|
|
Nothing -> []
|
|
|
|
Just date -> [Param "--after", Param date]
|
2012-01-06 21:30:48 +00:00
|
|
|
showLog file =<< (readLog <$> getLog key ps)
|
2012-01-06 19:40:04 +00:00
|
|
|
stop
|
|
|
|
|
2012-01-06 21:30:48 +00:00
|
|
|
showLog :: FilePath -> [(POSIXTime, (Git.Ref, Git.Ref))] -> Annex ()
|
|
|
|
showLog file ps = do
|
2012-01-06 20:24:40 +00:00
|
|
|
zone <- liftIO getCurrentTimeZone
|
2012-01-06 21:24:03 +00:00
|
|
|
sets <- mapM (getset snd) ps
|
|
|
|
previous <- maybe (return genesis) (getset fst) (lastMaybe ps)
|
|
|
|
mapM_ (diff zone) $ zip sets (drop 1 sets ++ [previous])
|
2012-01-06 19:40:04 +00:00
|
|
|
where
|
2012-01-06 21:24:03 +00:00
|
|
|
genesis = (0, S.empty)
|
|
|
|
getset select (ts, refs) = do
|
|
|
|
s <- S.fromList <$> get (select refs)
|
2012-01-06 20:24:40 +00:00
|
|
|
return (ts, s)
|
2012-01-06 19:40:04 +00:00
|
|
|
get ref = map toUUID . Logs.Presence.getLog . L.unpack <$>
|
|
|
|
catObject ref
|
2012-01-06 20:24:40 +00:00
|
|
|
diff zone ((ts, new), (_, old)) = do
|
2012-01-06 19:40:04 +00:00
|
|
|
let time = show $ utcToLocalTime zone $
|
|
|
|
posixSecondsToUTCTime ts
|
|
|
|
output time True added
|
|
|
|
output time False removed
|
|
|
|
where
|
2012-01-06 20:24:40 +00:00
|
|
|
added = S.difference new old
|
|
|
|
removed = S.difference old new
|
2012-01-06 19:40:04 +00:00
|
|
|
output time present s = do
|
|
|
|
rs <- map (dropWhile isSpace) . lines <$>
|
|
|
|
Remote.prettyPrintUUIDs "log" (S.toList s)
|
2012-01-06 21:30:48 +00:00
|
|
|
liftIO $ mapM_ (putStrLn . format) rs
|
2012-01-06 19:40:04 +00:00
|
|
|
where
|
|
|
|
format r = unwords
|
2012-01-06 21:30:48 +00:00
|
|
|
[ if present then "+" else "-"
|
|
|
|
, time
|
|
|
|
, file
|
|
|
|
, "|"
|
2012-01-06 19:40:04 +00:00
|
|
|
, r
|
|
|
|
]
|
|
|
|
|
2012-01-06 21:24:03 +00:00
|
|
|
getLog :: Key -> [CommandParam] -> Annex [String]
|
|
|
|
getLog key ps = do
|
2012-01-06 19:40:04 +00:00
|
|
|
top <- fromRepo Git.workTree
|
|
|
|
p <- liftIO $ relPathCwdToFile top
|
|
|
|
let logfile = p </> Logs.Location.logFile key
|
2012-01-06 21:24:03 +00:00
|
|
|
inRepo $ pipeNullSplit $
|
2012-01-06 19:40:04 +00:00
|
|
|
[ Params "log -z --pretty=format:%ct --raw --abbrev=40"
|
2012-01-06 21:24:03 +00:00
|
|
|
, Param "--boundary"
|
|
|
|
] ++ ps ++
|
|
|
|
[ Param $ show Annex.Branch.fullname
|
2012-01-06 19:40:04 +00:00
|
|
|
, Param "--"
|
|
|
|
, Param logfile
|
|
|
|
]
|
|
|
|
|
2012-01-06 21:24:03 +00:00
|
|
|
readLog :: [String] -> [(POSIXTime, (Git.Ref, Git.Ref))]
|
|
|
|
readLog = mapMaybe (parse . lines)
|
2012-01-06 19:40:04 +00:00
|
|
|
where
|
|
|
|
parse (ts:raw:[]) = Just (parseTimeStamp ts, parseRaw raw)
|
|
|
|
parse _ = Nothing
|
|
|
|
|
|
|
|
-- Parses something like ":100644 100644 oldsha newsha M"
|
2012-01-06 21:24:03 +00:00
|
|
|
parseRaw :: String -> (Git.Ref, Git.Ref)
|
|
|
|
parseRaw l = (Git.Ref oldsha, Git.Ref newsha)
|
|
|
|
where
|
|
|
|
ws = words l
|
|
|
|
oldsha = ws !! 2
|
|
|
|
newsha = ws !! 3
|
2012-01-06 19:40:04 +00:00
|
|
|
|
|
|
|
parseTimeStamp :: String -> POSIXTime
|
|
|
|
parseTimeStamp = utcTimeToPOSIXSeconds . fromMaybe (error "bad timestamp") .
|
|
|
|
parseTime defaultTimeLocale "%s"
|