summaryrefslogtreecommitdiff
path: root/Logs.hs
blob: 21908a9cf2f59cde90e0c9f1a93c7e21001b98de (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
{- git-annex log file names
 -
 - Copyright 2013-2014 Joey Hess <joey@kitenet.net>
 -
 - Licensed under the GNU GPL version 3 or higher.
 -}

module Logs where

import Common.Annex
import Types.Key

{- There are several varieties of log file formats. -}
data LogVariety
	= UUIDBasedLog
	| NewUUIDBasedLog
	| PresenceLog Key
	| OtherLog
	deriving (Show)

{- Converts a path from the git-annex branch into one of the varieties
 - of logs used by git-annex, if it's a known path. -}
getLogVariety :: FilePath -> Maybe LogVariety
getLogVariety f
	| f `elem` topLevelUUIDBasedLogs = Just UUIDBasedLog
	| isRemoteStateLog f = Just NewUUIDBasedLog
	| isMetaDataLog f || f == numcopiesLog = Just OtherLog
	| otherwise = PresenceLog <$> firstJust (presenceLogs f)

{- All the uuid-based logs stored in the top of the git-annex branch. -}
topLevelUUIDBasedLogs :: [FilePath]
topLevelUUIDBasedLogs =
	[ uuidLog
	, remoteLog
	, trustLog
	, groupLog 
	, preferredContentLog
	, scheduleLog
	]

{- All the ways to get a key from a presence log file -}
presenceLogs :: FilePath -> [Maybe Key]
presenceLogs f =
	[ urlLogFileKey f
	, locationLogFileKey f
	]

uuidLog :: FilePath
uuidLog = "uuid.log"

numcopiesLog :: FilePath
numcopiesLog = "numcopies.log"

remoteLog :: FilePath
remoteLog = "remote.log"

trustLog :: FilePath
trustLog = "trust.log"

groupLog :: FilePath
groupLog = "group.log"

preferredContentLog :: FilePath
preferredContentLog = "preferred-content.log"

scheduleLog :: FilePath
scheduleLog = "schedule.log"

{- The pathname of the location log file for a given key. -}
locationLogFile :: Key -> String
locationLogFile key = hashDirLower key ++ keyFile key ++ ".log"

{- Converts a pathname into a key if it's a location log. -}
locationLogFileKey :: FilePath -> Maybe Key
locationLogFileKey path
	| ["remote", "web"] `isPrefixOf` splitDirectories dir = Nothing
        | ext == ".log" = fileKey base
        | otherwise = Nothing
  where
	(dir, file) = splitFileName path
        (base, ext) = splitAt (length file - 4) file

{- The filename of the url log for a given key. -}
urlLogFile :: Key -> FilePath
urlLogFile key = hashDirLower key </> keyFile key ++ urlLogExt

{- Old versions stored the urls elsewhere. -}
oldurlLogs :: Key -> [FilePath]
oldurlLogs key =
	[ "remote/web" </> hashDirLower key </> key2file key ++ ".log"
	, "remote/web" </> hashDirLower key </> keyFile key ++ ".log"
	]

urlLogExt :: String
urlLogExt = ".log.web"

{- Converts a url log file into a key.
 - (Does not work on oldurlLogs.) -}
urlLogFileKey :: FilePath -> Maybe Key
urlLogFileKey path
	| ext == urlLogExt = fileKey base
	| otherwise = Nothing
  where
  	file = takeFileName path
	(base, ext) = splitAt (length file - extlen) file
	extlen = length urlLogExt

{- Does not work on oldurllogs. -}
isUrlLog :: FilePath -> Bool
isUrlLog file = urlLogExt `isSuffixOf` file

{- The filename of the remote state log for a given key. -}
remoteStateLogFile :: Key -> FilePath
remoteStateLogFile key = hashDirLower key </> keyFile key ++ remoteStateLogExt

remoteStateLogExt :: String
remoteStateLogExt = ".log.rmt"

isRemoteStateLog :: FilePath -> Bool
isRemoteStateLog path = remoteStateLogExt `isSuffixOf` path

{- The filename of the metadata log for a given key. -}
metaDataLogFile :: Key -> FilePath
metaDataLogFile key = hashDirLower key </> keyFile key ++ metaDataLogExt

metaDataLogExt :: String
metaDataLogExt = ".log.met"

isMetaDataLog :: FilePath -> Bool
isMetaDataLog path = metaDataLogExt `isSuffixOf` path

prop_logs_sane :: Key -> Bool
prop_logs_sane dummykey = and
	[ isNothing (getLogVariety "unknown")
	, expect isUUIDBasedLog (getLogVariety uuidLog)
	, expect isPresenceLog (getLogVariety $ locationLogFile dummykey)
	, expect isPresenceLog (getLogVariety $ urlLogFile dummykey)
	, expect isNewUUIDBasedLog (getLogVariety $ remoteStateLogFile dummykey)
	, expect isOtherLog (getLogVariety $ metaDataLogFile dummykey)
	, expect isOtherLog (getLogVariety $ numcopiesLog)
	]
  where
  	expect = maybe False
  	isUUIDBasedLog UUIDBasedLog = True
	isUUIDBasedLog _ = False
  	isNewUUIDBasedLog NewUUIDBasedLog = True
	isNewUUIDBasedLog _ = False
	isPresenceLog (PresenceLog k) = k == dummykey
	isPresenceLog _ = False
	isOtherLog OtherLog = True
	isOtherLog _ = False