2015-01-27 21:38:06 +00:00
|
|
|
{- git-annex repository differences
|
|
|
|
-
|
2024-09-06 18:23:29 +00:00
|
|
|
- Copyright 2015-2024 Joey Hess <id@joeyh.name>
|
2015-01-27 21:38:06 +00:00
|
|
|
-
|
2019-03-13 19:48:14 +00:00
|
|
|
- Licensed under the GNU AGPL version 3 or higher.
|
2015-01-27 21:38:06 +00:00
|
|
|
-}
|
|
|
|
|
2019-11-27 20:54:11 +00:00
|
|
|
{-# LANGUAGE OverloadedStrings #-}
|
|
|
|
|
2015-01-27 21:38:06 +00:00
|
|
|
module Types.Difference (
|
|
|
|
Difference(..),
|
|
|
|
Differences(..),
|
2015-01-28 17:55:46 +00:00
|
|
|
readDifferences,
|
2015-06-11 20:25:37 +00:00
|
|
|
showDifferences,
|
2015-01-27 21:38:06 +00:00
|
|
|
getDifferences,
|
|
|
|
differenceConfigKey,
|
|
|
|
differenceConfigVal,
|
|
|
|
hasDifference,
|
2015-01-28 22:17:10 +00:00
|
|
|
listDifferences,
|
2024-05-13 15:37:47 +00:00
|
|
|
mkDifferences,
|
2015-01-27 21:38:06 +00:00
|
|
|
) where
|
|
|
|
|
2015-01-28 17:55:46 +00:00
|
|
|
import Utility.PartialPrelude
|
2015-01-27 21:38:06 +00:00
|
|
|
import qualified Git
|
|
|
|
import qualified Git.Config
|
2019-12-02 14:57:09 +00:00
|
|
|
import Git.Types
|
2015-01-27 21:38:06 +00:00
|
|
|
|
|
|
|
import Data.Maybe
|
|
|
|
import Data.Monoid
|
2019-11-27 20:54:11 +00:00
|
|
|
import qualified Data.ByteString as B
|
2015-06-11 20:25:37 +00:00
|
|
|
import qualified Data.Set as S
|
Fix build with ghc 8.4+, which broke due to the Semigroup Monoid change
https://prime.haskell.org/wiki/Libraries/Proposals/SemigroupMonoid
I am not happy with the fragile pile of CPP boilerplate required to support
ghc back to 7.0, which git-annex still targets for both the android build
and the standalone build targeting old linux kernels. It makes me unlikely
to want to use Semigroup more in git-annex, because the benefit of the
abstraction is swamped by the ugliness. I actually considered ripping out
all the Semigroup instances, but some are needed to use
optparse-applicative.
The problem, I think, is they made this transaction on too fast a timeline.
(Although ironically, work on it started in 2015 or earlier!)
In particular, Debian oldstable is not out of security support, and it's
not possible to follow the simpler workarounds documented on the wiki and
have it build on oldstable (because the semigroups package in it is too
old).
I have only tested this build with ghc 8.2.2, not the newer and older
versions that branches of the CPP support. So there could be typoes, we'll
see.
This commit was sponsored by Brock Spratlen on Patreon.
2018-05-30 16:28:43 +00:00
|
|
|
import qualified Data.Semigroup as Sem
|
|
|
|
import Prelude
|
2015-01-27 21:38:06 +00:00
|
|
|
|
2024-09-03 18:23:32 +00:00
|
|
|
-- Describes differences from the standard repository format.
|
2015-01-27 21:38:06 +00:00
|
|
|
--
|
2015-01-28 17:47:41 +00:00
|
|
|
-- The serialization is stored in difference.log, so avoid changes that
|
2023-03-14 02:39:16 +00:00
|
|
|
-- would break compatibility.
|
2015-01-27 21:38:06 +00:00
|
|
|
--
|
2023-03-14 02:39:16 +00:00
|
|
|
-- Not breaking compatibility is why a list of Differences is used, rather
|
2015-06-11 20:25:37 +00:00
|
|
|
-- than a record type. With a record type, adding a new field for some future
|
2015-01-27 21:38:06 +00:00
|
|
|
-- difference would serialize to a value that an older version could not
|
|
|
|
-- parse, even if that new field was not used. With the Differences list,
|
|
|
|
-- old versions can still parse it, unless the new Difference constructor
|
|
|
|
-- is used.
|
2015-01-28 17:47:41 +00:00
|
|
|
--
|
|
|
|
-- The constructors intentionally do not have parameters; this is to
|
|
|
|
-- ensure that any Difference that can be expressed is supported.
|
|
|
|
-- So, a new repository version would be Version6, rather than Version Int.
|
2015-01-27 21:38:06 +00:00
|
|
|
data Difference
|
2015-01-28 17:47:41 +00:00
|
|
|
= ObjectHashLower
|
|
|
|
| OneLevelObjectHash
|
|
|
|
| OneLevelBranchHash
|
2024-09-06 18:23:29 +00:00
|
|
|
| Simulation
|
2015-06-11 20:25:37 +00:00
|
|
|
deriving (Show, Read, Eq, Ord, Enum, Bounded)
|
2015-01-27 21:38:06 +00:00
|
|
|
|
2015-06-11 20:25:37 +00:00
|
|
|
-- This type is used internally for efficient checking for differences,
|
|
|
|
-- but converted to S.Set Difference for serialization.
|
2015-01-27 21:38:06 +00:00
|
|
|
data Differences
|
2015-06-11 20:25:37 +00:00
|
|
|
= Differences
|
|
|
|
{ objectHashLower :: Bool
|
|
|
|
, oneLevelObjectHash :: Bool
|
|
|
|
, oneLevelBranchHash :: Bool
|
2024-09-06 18:23:29 +00:00
|
|
|
, simulation :: Bool
|
2015-06-11 20:25:37 +00:00
|
|
|
}
|
2015-01-27 21:38:06 +00:00
|
|
|
| UnknownDifferences
|
|
|
|
|
2015-06-11 20:25:37 +00:00
|
|
|
-- UnknownDifferences cannot be equal
|
2015-01-27 21:38:06 +00:00
|
|
|
instance Eq Differences where
|
2015-06-11 20:25:37 +00:00
|
|
|
UnknownDifferences == _ = False
|
|
|
|
_ == UnknownDifferences = False
|
|
|
|
a == b = all (\f -> f a == f b)
|
|
|
|
[ objectHashLower
|
|
|
|
, oneLevelObjectHash
|
|
|
|
, oneLevelBranchHash
|
2024-09-06 18:23:29 +00:00
|
|
|
, simulation
|
2015-06-11 20:25:37 +00:00
|
|
|
]
|
2015-01-27 21:38:06 +00:00
|
|
|
|
Fix build with ghc 8.4+, which broke due to the Semigroup Monoid change
https://prime.haskell.org/wiki/Libraries/Proposals/SemigroupMonoid
I am not happy with the fragile pile of CPP boilerplate required to support
ghc back to 7.0, which git-annex still targets for both the android build
and the standalone build targeting old linux kernels. It makes me unlikely
to want to use Semigroup more in git-annex, because the benefit of the
abstraction is swamped by the ugliness. I actually considered ripping out
all the Semigroup instances, but some are needed to use
optparse-applicative.
The problem, I think, is they made this transaction on too fast a timeline.
(Although ironically, work on it started in 2015 or earlier!)
In particular, Debian oldstable is not out of security support, and it's
not possible to follow the simpler workarounds documented on the wiki and
have it build on oldstable (because the semigroups package in it is too
old).
I have only tested this build with ghc 8.2.2, not the newer and older
versions that branches of the CPP support. So there could be typoes, we'll
see.
This commit was sponsored by Brock Spratlen on Patreon.
2018-05-30 16:28:43 +00:00
|
|
|
appendDifferences :: Differences -> Differences -> Differences
|
|
|
|
appendDifferences a@(Differences {}) b@(Differences {}) = a
|
|
|
|
{ objectHashLower = objectHashLower a || objectHashLower b
|
|
|
|
, oneLevelObjectHash = oneLevelObjectHash a || oneLevelObjectHash b
|
|
|
|
, oneLevelBranchHash = oneLevelBranchHash a || oneLevelBranchHash b
|
2024-09-06 18:23:29 +00:00
|
|
|
, simulation = simulation a || simulation b
|
Fix build with ghc 8.4+, which broke due to the Semigroup Monoid change
https://prime.haskell.org/wiki/Libraries/Proposals/SemigroupMonoid
I am not happy with the fragile pile of CPP boilerplate required to support
ghc back to 7.0, which git-annex still targets for both the android build
and the standalone build targeting old linux kernels. It makes me unlikely
to want to use Semigroup more in git-annex, because the benefit of the
abstraction is swamped by the ugliness. I actually considered ripping out
all the Semigroup instances, but some are needed to use
optparse-applicative.
The problem, I think, is they made this transaction on too fast a timeline.
(Although ironically, work on it started in 2015 or earlier!)
In particular, Debian oldstable is not out of security support, and it's
not possible to follow the simpler workarounds documented on the wiki and
have it build on oldstable (because the semigroups package in it is too
old).
I have only tested this build with ghc 8.2.2, not the newer and older
versions that branches of the CPP support. So there could be typoes, we'll
see.
This commit was sponsored by Brock Spratlen on Patreon.
2018-05-30 16:28:43 +00:00
|
|
|
}
|
|
|
|
appendDifferences _ _ = UnknownDifferences
|
|
|
|
|
|
|
|
instance Sem.Semigroup Differences where
|
|
|
|
(<>) = appendDifferences
|
|
|
|
|
2015-01-27 21:38:06 +00:00
|
|
|
instance Monoid Differences where
|
2024-09-06 18:23:29 +00:00
|
|
|
mempty = Differences False False False False
|
2015-01-27 21:38:06 +00:00
|
|
|
|
2015-01-28 17:55:46 +00:00
|
|
|
readDifferences :: String -> Differences
|
2015-06-11 20:25:37 +00:00
|
|
|
readDifferences = maybe UnknownDifferences mkDifferences . readish
|
|
|
|
|
|
|
|
showDifferences :: Differences -> String
|
|
|
|
showDifferences = show . S.fromList . listDifferences
|
2015-01-28 17:55:46 +00:00
|
|
|
|
2015-01-27 21:38:06 +00:00
|
|
|
getDifferences :: Git.Repo -> Differences
|
2015-06-11 20:25:37 +00:00
|
|
|
getDifferences r = mkDifferences $ S.fromList $
|
2015-04-11 04:10:34 +00:00
|
|
|
mapMaybe getmaybe [minBound .. maxBound]
|
2015-01-27 21:38:06 +00:00
|
|
|
where
|
2024-09-06 18:23:29 +00:00
|
|
|
getmaybe d = case Git.Config.isTrueFalse' =<< flip Git.Config.getMaybe r =<< differenceConfigKey d of
|
2015-01-28 17:47:41 +00:00
|
|
|
Just True -> Just d
|
|
|
|
_ -> Nothing
|
2015-01-27 21:38:06 +00:00
|
|
|
|
2024-09-06 18:23:29 +00:00
|
|
|
differenceConfigKey :: Difference -> Maybe ConfigKey
|
2015-01-28 17:47:41 +00:00
|
|
|
differenceConfigKey ObjectHashLower = tunable "objecthashlower"
|
|
|
|
differenceConfigKey OneLevelObjectHash = tunable "objecthash1"
|
|
|
|
differenceConfigKey OneLevelBranchHash = tunable "branchhash1"
|
2024-09-06 18:23:29 +00:00
|
|
|
differenceConfigKey Simulation = Nothing
|
2015-01-27 21:38:06 +00:00
|
|
|
|
|
|
|
differenceConfigVal :: Difference -> String
|
2015-01-28 17:47:41 +00:00
|
|
|
differenceConfigVal _ = Git.Config.boolConfig True
|
2015-01-27 21:38:06 +00:00
|
|
|
|
2024-09-06 18:23:29 +00:00
|
|
|
tunable :: B.ByteString -> Maybe ConfigKey
|
|
|
|
tunable k = Just $ ConfigKey ("annex.tune." <> k)
|
2015-01-27 21:38:06 +00:00
|
|
|
|
2015-01-28 22:17:10 +00:00
|
|
|
hasDifference :: Difference -> Differences -> Bool
|
2015-01-27 21:38:06 +00:00
|
|
|
hasDifference _ UnknownDifferences = False
|
2015-06-11 20:25:37 +00:00
|
|
|
hasDifference ObjectHashLower ds = objectHashLower ds
|
|
|
|
hasDifference OneLevelObjectHash ds = oneLevelObjectHash ds
|
|
|
|
hasDifference OneLevelBranchHash ds = oneLevelBranchHash ds
|
2024-09-06 18:23:29 +00:00
|
|
|
hasDifference Simulation ds = simulation ds
|
2015-01-28 22:17:10 +00:00
|
|
|
|
|
|
|
listDifferences :: Differences -> [Difference]
|
2015-06-11 20:25:37 +00:00
|
|
|
listDifferences d@(Differences {}) = map snd $
|
|
|
|
filter (\(f, _) -> f d)
|
|
|
|
[ (objectHashLower, ObjectHashLower)
|
|
|
|
, (oneLevelObjectHash, OneLevelObjectHash)
|
|
|
|
, (oneLevelBranchHash, OneLevelBranchHash)
|
2024-09-06 18:23:29 +00:00
|
|
|
, (simulation, Simulation)
|
2015-06-11 20:25:37 +00:00
|
|
|
]
|
2015-01-28 22:17:10 +00:00
|
|
|
listDifferences UnknownDifferences = []
|
2015-06-11 20:25:37 +00:00
|
|
|
|
|
|
|
mkDifferences :: S.Set Difference -> Differences
|
|
|
|
mkDifferences s = Differences
|
|
|
|
{ objectHashLower = check ObjectHashLower
|
|
|
|
, oneLevelObjectHash = check OneLevelObjectHash
|
|
|
|
, oneLevelBranchHash = check OneLevelBranchHash
|
2024-09-06 18:23:29 +00:00
|
|
|
, simulation = check Simulation
|
2015-06-11 20:25:37 +00:00
|
|
|
}
|
|
|
|
where
|
|
|
|
check f = f `S.member` s
|