2010-10-27 20:53:54 +00:00
|
|
|
|
{- git-annex monad
|
|
|
|
|
-
|
|
|
|
|
- Copyright 2010 Joey Hess <joey@kitenet.net>
|
|
|
|
|
-
|
|
|
|
|
- Licensed under the GNU GPL version 3 or higher.
|
|
|
|
|
-}
|
2010-10-10 19:04:07 +00:00
|
|
|
|
|
2010-10-11 21:52:46 +00:00
|
|
|
|
module Annex (
|
2011-01-26 01:49:04 +00:00
|
|
|
|
Annex,
|
|
|
|
|
AnnexState(..),
|
2010-10-14 07:18:11 +00:00
|
|
|
|
new,
|
|
|
|
|
run,
|
2010-11-01 03:24:16 +00:00
|
|
|
|
eval,
|
2011-01-26 04:17:38 +00:00
|
|
|
|
getState,
|
|
|
|
|
changeState,
|
2010-10-14 07:18:11 +00:00
|
|
|
|
gitRepo,
|
2010-10-26 19:59:50 +00:00
|
|
|
|
queue,
|
2010-11-08 20:40:02 +00:00
|
|
|
|
queueRun,
|
2011-03-05 19:31:46 +00:00
|
|
|
|
setConfig,
|
|
|
|
|
repoConfig
|
2010-10-11 21:52:46 +00:00
|
|
|
|
) where
|
2010-10-10 19:04:07 +00:00
|
|
|
|
|
2010-10-14 07:18:11 +00:00
|
|
|
|
import Control.Monad.State
|
2011-03-05 19:31:46 +00:00
|
|
|
|
import Data.Maybe
|
2010-10-16 20:20:49 +00:00
|
|
|
|
|
2010-10-14 06:36:41 +00:00
|
|
|
|
import qualified GitRepo as Git
|
2010-10-26 19:59:50 +00:00
|
|
|
|
import qualified GitQueue
|
2011-03-16 02:04:50 +00:00
|
|
|
|
import qualified BackendClass
|
2011-02-28 20:10:16 +00:00
|
|
|
|
import Utility
|
2011-01-26 01:49:04 +00:00
|
|
|
|
|
|
|
|
|
-- git-annex's monad
|
|
|
|
|
type Annex = StateT AnnexState IO
|
|
|
|
|
|
|
|
|
|
-- internal state storage
|
2011-01-26 04:17:38 +00:00
|
|
|
|
data AnnexState = AnnexState
|
|
|
|
|
{ repo :: Git.Repo
|
2011-03-16 02:04:50 +00:00
|
|
|
|
, backends :: [BackendClass.Backend Annex]
|
|
|
|
|
, supportedBackends :: [BackendClass.Backend Annex]
|
2011-01-26 04:17:38 +00:00
|
|
|
|
, repoqueue :: GitQueue.Queue
|
|
|
|
|
, quiet :: Bool
|
|
|
|
|
, force :: Bool
|
|
|
|
|
, defaultbackend :: Maybe String
|
|
|
|
|
, defaultkey :: Maybe String
|
|
|
|
|
, toremote :: Maybe String
|
|
|
|
|
, fromremote :: Maybe String
|
|
|
|
|
, exclude :: [String]
|
|
|
|
|
, remotesread :: Bool
|
|
|
|
|
} deriving (Show)
|
|
|
|
|
|
2011-03-16 02:04:50 +00:00
|
|
|
|
newState :: Git.Repo -> [BackendClass.Backend Annex] -> AnnexState
|
2011-01-26 04:17:38 +00:00
|
|
|
|
newState gitrepo allbackends = AnnexState
|
|
|
|
|
{ repo = gitrepo
|
|
|
|
|
, backends = []
|
|
|
|
|
, supportedBackends = allbackends
|
|
|
|
|
, repoqueue = GitQueue.empty
|
|
|
|
|
, quiet = False
|
|
|
|
|
, force = False
|
|
|
|
|
, defaultbackend = Nothing
|
|
|
|
|
, defaultkey = Nothing
|
|
|
|
|
, toremote = Nothing
|
|
|
|
|
, fromremote = Nothing
|
|
|
|
|
, exclude = []
|
|
|
|
|
, remotesread = False
|
|
|
|
|
}
|
2010-10-14 07:18:11 +00:00
|
|
|
|
|
2010-10-26 19:59:50 +00:00
|
|
|
|
{- Create and returns an Annex state object for the specified git repo. -}
|
2011-03-16 02:04:50 +00:00
|
|
|
|
new :: Git.Repo -> [BackendClass.Backend Annex] -> IO AnnexState
|
2010-10-17 15:47:36 +00:00
|
|
|
|
new gitrepo allbackends = do
|
2011-01-26 04:17:38 +00:00
|
|
|
|
gitrepo' <- liftIO $ Git.configRead gitrepo
|
|
|
|
|
return $ newState gitrepo' allbackends
|
2010-10-14 07:18:11 +00:00
|
|
|
|
|
2010-10-26 19:59:50 +00:00
|
|
|
|
{- performs an action in the Annex monad -}
|
2011-01-11 22:13:26 +00:00
|
|
|
|
run :: AnnexState -> Annex a -> IO (a, AnnexState)
|
2010-11-06 21:07:11 +00:00
|
|
|
|
run state action = runStateT action state
|
2011-01-11 22:13:26 +00:00
|
|
|
|
eval :: AnnexState -> Annex a -> IO a
|
2010-11-06 21:07:11 +00:00
|
|
|
|
eval state action = evalStateT action state
|
2010-10-14 07:18:11 +00:00
|
|
|
|
|
2011-01-26 04:17:38 +00:00
|
|
|
|
{- Gets a value from the internal state, selected by the passed value
|
|
|
|
|
- constructor. -}
|
2011-01-26 01:49:04 +00:00
|
|
|
|
getState :: (AnnexState -> a) -> Annex a
|
2011-02-19 21:00:40 +00:00
|
|
|
|
getState c = liftM c get
|
2011-01-26 04:17:38 +00:00
|
|
|
|
|
|
|
|
|
{- Applies a state mutation function to change the internal state.
|
|
|
|
|
-
|
|
|
|
|
- Example: changeState (\s -> s { quiet = True })
|
|
|
|
|
-}
|
|
|
|
|
changeState :: (AnnexState -> AnnexState) -> Annex ()
|
|
|
|
|
changeState a = do
|
|
|
|
|
state <- get
|
|
|
|
|
put (a state)
|
2011-01-26 01:49:04 +00:00
|
|
|
|
|
2010-10-26 19:59:50 +00:00
|
|
|
|
{- Returns the git repository being acted on -}
|
2010-10-14 07:18:11 +00:00
|
|
|
|
gitRepo :: Annex Git.Repo
|
2011-01-26 01:49:04 +00:00
|
|
|
|
gitRepo = getState repo
|
2010-10-26 19:59:50 +00:00
|
|
|
|
|
|
|
|
|
{- Adds a git command to the queue. -}
|
2011-02-28 20:25:31 +00:00
|
|
|
|
queue :: String -> [CommandParam] -> FilePath -> Annex ()
|
2010-12-30 18:19:16 +00:00
|
|
|
|
queue command params file = do
|
2010-10-26 19:59:50 +00:00
|
|
|
|
state <- get
|
2011-01-26 01:49:04 +00:00
|
|
|
|
let q = repoqueue state
|
|
|
|
|
put state { repoqueue = GitQueue.add q command params file }
|
2010-10-26 19:59:50 +00:00
|
|
|
|
|
2010-11-08 20:40:02 +00:00
|
|
|
|
{- Runs (and empties) the queue. -}
|
|
|
|
|
queueRun :: Annex ()
|
|
|
|
|
queueRun = do
|
|
|
|
|
state <- get
|
2011-01-26 01:49:04 +00:00
|
|
|
|
let q = repoqueue state
|
2010-11-08 20:40:02 +00:00
|
|
|
|
g <- gitRepo
|
|
|
|
|
liftIO $ GitQueue.run g q
|
2011-01-26 01:49:04 +00:00
|
|
|
|
put state { repoqueue = GitQueue.empty }
|
2010-11-08 20:40:02 +00:00
|
|
|
|
|
2010-11-08 18:39:12 +00:00
|
|
|
|
{- Changes a git config setting in both internal state and .git/config -}
|
|
|
|
|
setConfig :: String -> String -> Annex ()
|
2011-01-26 04:17:38 +00:00
|
|
|
|
setConfig k value = do
|
2010-11-08 18:39:12 +00:00
|
|
|
|
g <- Annex.gitRepo
|
2011-02-28 20:10:16 +00:00
|
|
|
|
liftIO $ Git.run g "config" [Param k, Param value]
|
2010-11-08 18:39:12 +00:00
|
|
|
|
-- re-read git config and update the repo's state
|
2010-12-31 19:46:33 +00:00
|
|
|
|
g' <- liftIO $ Git.configRead g
|
2011-01-26 04:17:38 +00:00
|
|
|
|
Annex.changeState $ \s -> s { Annex.repo = g' }
|
2011-03-05 19:31:46 +00:00
|
|
|
|
|
|
|
|
|
{- Looks up a per-remote config option in git config.
|
|
|
|
|
- Failing that, tries looking for a global config option. -}
|
|
|
|
|
repoConfig :: Git.Repo -> String -> String -> Annex String
|
|
|
|
|
repoConfig r key def = do
|
|
|
|
|
g <- Annex.gitRepo
|
|
|
|
|
let def' = Git.configGet g global def
|
|
|
|
|
return $ Git.configGet g local def'
|
|
|
|
|
where
|
|
|
|
|
local = "remote." ++ fromMaybe "" (Git.repoRemoteName r) ++ ".annex-" ++ key
|
|
|
|
|
global = "annex." ++ key
|