git-annex/Trust.hs
Joey Hess f77979b8b5 improved git-annex branch changing
All changes to files in the branch are now made via pure functions that
transform the old file into the new. This will allow adding locking
to prevent read/write races. It also makes the code nicer, and purer.

I noticed a behavior change, really a sort of bug fix. Before,
'git annex untrust foo --trust bar' would change both trust levels
permanantly, now the --trust doesn't get stored.
2011-10-03 15:41:25 -04:00

78 lines
2.1 KiB
Haskell

{- git-annex trust
-
- Copyright 2010 Joey Hess <joey@kitenet.net>
-
- Licensed under the GNU GPL version 3 or higher.
-}
module Trust (
TrustLevel(..),
trustLog,
trustGet,
trustSet,
trustPartition
) where
import Control.Monad.State
import qualified Data.Map as M
import Data.List
import Types.TrustLevel
import qualified Branch
import Types
import UUID
import qualified Annex
{- Filename of trust.log. -}
trustLog :: FilePath
trustLog = "trust.log"
{- Returns a list of UUIDs at the specified trust level. -}
trustGet :: TrustLevel -> Annex [UUID]
trustGet level = do
m <- trustMap
return $ M.keys $ M.filter (== level) m
{- Read the trustLog into a map, overriding with any
- values from forcetrust. The map is cached for speed. -}
trustMap :: Annex TrustMap
trustMap = do
cached <- Annex.getState Annex.trustmap
case cached of
Just m -> return m
Nothing -> do
overrides <- Annex.getState Annex.forcetrust
l <- Branch.get trustLog
let m = M.fromList $ trustMapParse l ++ overrides
Annex.changeState $ \s -> s { Annex.trustmap = Just m }
return m
{- Trust map parser. -}
trustMapParse :: String -> [(UUID, TrustLevel)]
trustMapParse s = map pair $ filter (not . null) $ lines s
where
pair l
| length w > 1 = (w !! 0, read (w !! 1) :: TrustLevel)
-- for back-compat; the trust log used to only
-- list trusted uuids
| otherwise = (w !! 0, Trusted)
where
w = words l
{- Changes the trust level for a uuid in the trustLog. -}
trustSet :: UUID -> TrustLevel -> Annex ()
trustSet uuid level = do
when (null uuid) $
error "unknown UUID; cannot modify trust level"
Branch.change trustLog $
serialize . M.insert uuid level . M.fromList . trustMapParse
Annex.changeState $ \s -> s { Annex.trustmap = Nothing }
where
serialize m = unlines $ map showpair $ M.toList m
showpair (u, t) = u ++ " " ++ show t
{- Partitions a list of UUIDs to those matching a TrustLevel and not. -}
trustPartition :: TrustLevel -> [UUID] -> Annex ([UUID], [UUID])
trustPartition level ls = do
candidates <- trustGet level
return $ partition (`elem` candidates) ls