2011-03-28 01:43:25 +00:00
|
|
|
{- Git configuration
|
|
|
|
-
|
2020-02-19 17:45:11 +00:00
|
|
|
- Copyright 2011-2020 Joey Hess <id@joeyh.name>
|
2011-03-28 01:43:25 +00:00
|
|
|
-
|
2019-03-13 19:48:14 +00:00
|
|
|
- Licensed under the GNU AGPL version 3 or higher.
|
2011-03-28 01:43:25 +00:00
|
|
|
-}
|
|
|
|
|
2015-08-17 15:21:13 +00:00
|
|
|
{-# LANGUAGE TypeSynonymInstances, FlexibleInstances #-}
|
2019-11-27 20:54:11 +00:00
|
|
|
{-# LANGUAGE OverloadedStrings #-}
|
2015-08-17 15:21:13 +00:00
|
|
|
|
2011-03-28 01:43:25 +00:00
|
|
|
module Config where
|
|
|
|
|
2016-01-20 20:36:33 +00:00
|
|
|
import Annex.Common
|
2011-06-30 17:16:57 +00:00
|
|
|
import qualified Git
|
2011-12-13 19:05:07 +00:00
|
|
|
import qualified Git.Config
|
2011-12-14 19:56:11 +00:00
|
|
|
import qualified Git.Command
|
2011-03-28 01:43:25 +00:00
|
|
|
import qualified Annex
|
2013-03-13 20:16:01 +00:00
|
|
|
import Config.Cost
|
2017-08-17 18:04:29 +00:00
|
|
|
import Config.DynamicConfig
|
2014-01-13 18:41:10 +00:00
|
|
|
import Types.Availability
|
2015-08-17 15:21:13 +00:00
|
|
|
import Git.Types
|
2017-09-19 17:05:43 +00:00
|
|
|
import qualified Types.Remote as Remote
|
2011-03-28 01:43:25 +00:00
|
|
|
|
2019-11-27 20:54:11 +00:00
|
|
|
import qualified Data.ByteString as S
|
2019-01-29 17:42:32 +00:00
|
|
|
|
2019-11-27 20:54:11 +00:00
|
|
|
type UnqualifiedConfigKey = S.ByteString
|
|
|
|
|
2017-02-03 17:40:14 +00:00
|
|
|
{- Looks up a setting in git config. This is not as efficient as using the
|
|
|
|
- GitConfig type. -}
|
2019-12-05 18:36:43 +00:00
|
|
|
getConfig :: ConfigKey -> ConfigValue -> Annex ConfigValue
|
2019-12-02 14:57:09 +00:00
|
|
|
getConfig key d = fromRepo $ Git.Config.get key d
|
2013-01-01 17:52:47 +00:00
|
|
|
|
2019-12-05 18:36:43 +00:00
|
|
|
getConfigMaybe :: ConfigKey -> Annex (Maybe ConfigValue)
|
2019-12-02 14:57:09 +00:00
|
|
|
getConfigMaybe key = fromRepo $ Git.Config.getMaybe key
|
2013-09-08 19:19:14 +00:00
|
|
|
|
2011-03-28 01:43:25 +00:00
|
|
|
{- Changes a git config setting in both internal state and .git/config -}
|
|
|
|
setConfig :: ConfigKey -> String -> Annex ()
|
2012-05-06 00:15:32 +00:00
|
|
|
setConfig (ConfigKey key) value = do
|
2019-11-27 20:54:11 +00:00
|
|
|
inRepo $ Git.Command.run
|
|
|
|
[ Param "config"
|
|
|
|
, Param (decodeBS' key)
|
|
|
|
, Param value
|
|
|
|
]
|
2014-04-08 17:41:36 +00:00
|
|
|
reloadConfig
|
|
|
|
|
|
|
|
reloadConfig :: Annex ()
|
|
|
|
reloadConfig = Annex.changeGitRepo =<< inRepo Git.Config.reRead
|
2011-03-28 01:43:25 +00:00
|
|
|
|
2015-03-02 20:43:44 +00:00
|
|
|
{- Unsets a git config setting. (Leaves it in state.) -}
|
2012-05-06 00:15:32 +00:00
|
|
|
unsetConfig :: ConfigKey -> Annex ()
|
2019-12-02 14:57:09 +00:00
|
|
|
unsetConfig key = void $ inRepo $ Git.Config.unset key
|
2012-05-06 00:15:32 +00:00
|
|
|
|
2015-08-17 15:21:13 +00:00
|
|
|
class RemoteNameable r where
|
|
|
|
getRemoteName :: r -> RemoteName
|
|
|
|
|
|
|
|
instance RemoteNameable Git.Repo where
|
|
|
|
getRemoteName r = fromMaybe "" (Git.remoteName r)
|
|
|
|
|
|
|
|
instance RemoteNameable RemoteName where
|
|
|
|
getRemoteName = id
|
|
|
|
|
2017-09-19 17:05:43 +00:00
|
|
|
instance RemoteNameable Remote where
|
|
|
|
getRemoteName = Remote.name
|
|
|
|
|
2012-01-10 03:31:44 +00:00
|
|
|
{- A per-remote config setting in git config. -}
|
2015-08-17 15:21:13 +00:00
|
|
|
remoteConfig :: RemoteNameable r => r -> UnqualifiedConfigKey -> ConfigKey
|
2012-05-06 00:15:32 +00:00
|
|
|
remoteConfig r key = ConfigKey $
|
2020-02-19 17:45:11 +00:00
|
|
|
"remote." <> encodeBS' (getRemoteName r) <> "." <> key
|
|
|
|
|
|
|
|
{- A per-remote config annex setting in git config. -}
|
|
|
|
remoteAnnexConfig :: RemoteNameable r => r -> UnqualifiedConfigKey -> ConfigKey
|
|
|
|
remoteAnnexConfig r key = remoteConfig r ("annex-" <> key)
|
2012-05-06 00:15:32 +00:00
|
|
|
|
|
|
|
{- A global annex setting in git config. -}
|
|
|
|
annexConfig :: UnqualifiedConfigKey -> ConfigKey
|
2019-11-27 20:54:11 +00:00
|
|
|
annexConfig key = ConfigKey ("annex." <> key)
|
2011-03-28 01:43:25 +00:00
|
|
|
|
2013-01-01 17:52:47 +00:00
|
|
|
{- Calculates cost for a remote. Either the specific default, or as configured
|
2011-08-18 16:26:28 +00:00
|
|
|
- by remote.<name>.annex-cost, or if remote.<name>.annex-cost-command
|
2011-11-19 19:57:08 +00:00
|
|
|
- is set and prints a number, that is used. -}
|
2013-03-13 20:16:01 +00:00
|
|
|
remoteCost :: RemoteGitConfig -> Cost -> Annex Cost
|
2015-01-28 20:11:28 +00:00
|
|
|
remoteCost c d = fromMaybe d <$> remoteCost' c
|
external special remotes mostly implemented (untested)
This has not been tested at all. It compiles!
The only known missing things are support for encryption, and for get/set
of special remote configuration, and of key state. (The latter needs
separate work to add a new per-key log file to store that state.)
Only thing I don't much like is that initremote needs to be passed both
type=external and externaltype=foo. It would be better to have just
type=foo
Most of this is quite straightforward code, that largely wrote itself given
the types. The only tricky parts were:
* Need to lock the remote when using it to eg make a request, because
in theory git-annex could have multiple threads that each try to use
a remote at the same time. I don't think that git-annex ever does
that currently, but better safe than sorry.
* Rather than starting up every external special remote program when
git-annex starts, they are started only on demand, when first used.
This will avoid slowdown, especially when running fast git-annex query
commands. Once started, they keep running until git-annex stops, currently,
which may not be ideal, but it's hard to know a better time to stop them.
* Bit of a chicken and egg problem with caching the cost of the remote,
because setting annex-cost in the git config needs the remote to already
be set up. Managed to finesse that.
This commit was sponsored by Lukas Anzinger.
2013-12-26 22:23:13 +00:00
|
|
|
|
|
|
|
remoteCost' :: RemoteGitConfig -> Annex (Maybe Cost)
|
2017-08-17 18:04:29 +00:00
|
|
|
remoteCost' = liftIO . getDynamicConfig . remoteAnnexCost
|
2011-03-30 19:15:46 +00:00
|
|
|
|
external special remotes mostly implemented (untested)
This has not been tested at all. It compiles!
The only known missing things are support for encryption, and for get/set
of special remote configuration, and of key state. (The latter needs
separate work to add a new per-key log file to store that state.)
Only thing I don't much like is that initremote needs to be passed both
type=external and externaltype=foo. It would be better to have just
type=foo
Most of this is quite straightforward code, that largely wrote itself given
the types. The only tricky parts were:
* Need to lock the remote when using it to eg make a request, because
in theory git-annex could have multiple threads that each try to use
a remote at the same time. I don't think that git-annex ever does
that currently, but better safe than sorry.
* Rather than starting up every external special remote program when
git-annex starts, they are started only on demand, when first used.
This will avoid slowdown, especially when running fast git-annex query
commands. Once started, they keep running until git-annex stops, currently,
which may not be ideal, but it's hard to know a better time to stop them.
* Bit of a chicken and egg problem with caching the cost of the remote,
because setting annex-cost in the git config needs the remote to already
be set up. Managed to finesse that.
This commit was sponsored by Lukas Anzinger.
2013-12-26 22:23:13 +00:00
|
|
|
setRemoteCost :: Git.Repo -> Cost -> Annex ()
|
2020-02-19 17:45:11 +00:00
|
|
|
setRemoteCost r c = setConfig (remoteAnnexConfig r "cost") (show c)
|
2013-03-13 18:10:29 +00:00
|
|
|
|
2014-01-13 18:41:10 +00:00
|
|
|
setRemoteAvailability :: Git.Repo -> Availability -> Annex ()
|
2020-02-19 17:45:11 +00:00
|
|
|
setRemoteAvailability r c = setConfig (remoteAnnexConfig r "availability") (show c)
|
2014-01-13 18:41:10 +00:00
|
|
|
|
2016-05-24 19:48:22 +00:00
|
|
|
setRemoteIgnore :: Git.Repo -> Bool -> Annex ()
|
2020-02-19 17:45:11 +00:00
|
|
|
setRemoteIgnore r b = setConfig (remoteAnnexConfig r "ignore") (Git.Config.boolConfig b)
|
2016-05-24 19:48:22 +00:00
|
|
|
|
|
|
|
setRemoteBare :: Git.Repo -> Bool -> Annex ()
|
2020-02-19 17:45:11 +00:00
|
|
|
setRemoteBare r b = setConfig (remoteAnnexConfig r "bare") (Git.Config.boolConfig b)
|
2016-05-24 19:48:22 +00:00
|
|
|
|
2016-06-02 20:59:15 +00:00
|
|
|
isBareRepo :: Annex Bool
|
|
|
|
isBareRepo = fromRepo Git.repoIsLocalBare
|
|
|
|
|
2012-12-07 18:40:31 +00:00
|
|
|
isDirect :: Annex Bool
|
2013-01-01 17:52:47 +00:00
|
|
|
isDirect = annexDirect <$> Annex.getGitConfig
|
2012-12-07 17:17:13 +00:00
|
|
|
|
2013-02-14 18:10:36 +00:00
|
|
|
crippledFileSystem :: Annex Bool
|
|
|
|
crippledFileSystem = annexCrippledFileSystem <$> Annex.getGitConfig
|
|
|
|
|
|
|
|
setCrippledFileSystem :: Bool -> Annex ()
|
rename changeGitConfig to overrideGitConfig and avoid unncessary calls
It's important that it be clear that it overrides a config, such that
reloading the git config won't change it, and in particular, setConfig
won't change it.
Most of the calls to changeGitConfig were actually after setConfig,
which was redundant and unncessary. So removed those.
The only remaining one, besides --debug, is in the handling of
repository-global config values. That one's ok, because the
way mergeGitConfig is implemented, it does not override any value that
is set in git config. If a value with a repo-global setting was passed
to setConfig, it would set it in the git config, reload the git config,
re-apply mergeGitConfig, and use the newly set value, which is the right
thing.
2020-02-27 05:06:35 +00:00
|
|
|
setCrippledFileSystem b =
|
2013-02-14 18:10:36 +00:00
|
|
|
setConfig (annexConfig "crippledfilesystem") (Git.Config.boolConfig b)
|
2018-10-10 15:07:49 +00:00
|
|
|
|
|
|
|
yesNo :: String -> Maybe Bool
|
|
|
|
yesNo "yes" = Just True
|
|
|
|
yesNo "no" = Just False
|
|
|
|
yesNo _ = Nothing
|