{-# LANGUAGE OverloadedStrings #-}
module Poseidon.Chronicle where
import Poseidon.EntityTypes (HasNameAndVersion (..))
import Poseidon.Package (PoseidonPackage (..))
import Poseidon.Utils (Env (..), PoseidonException (..),
PoseidonIO, TestMode (..))
import Poseidon.Version (VersionComponent (..),
updateThreeComponentVersion)
import Control.Monad.Catch (throwM)
import Control.Monad.IO.Class (liftIO)
import Control.Monad.Reader (asks)
import Data.Aeson (FromJSON, ToJSON, object, parseJSON,
toJSON, withObject, (.!=), (.:), (.:?),
(.=))
import qualified Data.ByteString as B
import Data.Function (on)
import Data.List (elemIndex)
import Data.Maybe (fromMaybe)
import qualified Data.Set as S
import Data.Time (Day, UTCTime (..), getCurrentTime)
import Data.Version (Version, makeVersion)
import Data.Yaml (decodeEither')
import Data.Yaml.Pretty (defConfig, encodePretty,
setConfCompare, setConfDropNull)
import GitHash (getGitInfo, giHash)
import System.Directory (createDirectoryIfMissing, makeAbsolute)
import System.FilePath (makeRelative, takeDirectory)
data PoseidonPackageChronicle = PoseidonPackageChronicle
{ PoseidonPackageChronicle -> String
snapYamlTitle :: String
, PoseidonPackageChronicle -> Maybe String
snapYamlDescription :: Maybe String
, PoseidonPackageChronicle -> Version
snapYamlChronicleVersion :: Version
, PoseidonPackageChronicle -> Day
snapYamlLastModified :: Day
, PoseidonPackageChronicle -> Set PackageIteration
snapYamlPackages :: S.Set PackageIteration
}
deriving (Int -> PoseidonPackageChronicle -> ShowS
[PoseidonPackageChronicle] -> ShowS
PoseidonPackageChronicle -> String
(Int -> PoseidonPackageChronicle -> ShowS)
-> (PoseidonPackageChronicle -> String)
-> ([PoseidonPackageChronicle] -> ShowS)
-> Show PoseidonPackageChronicle
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> PoseidonPackageChronicle -> ShowS
showsPrec :: Int -> PoseidonPackageChronicle -> ShowS
$cshow :: PoseidonPackageChronicle -> String
show :: PoseidonPackageChronicle -> String
$cshowList :: [PoseidonPackageChronicle] -> ShowS
showList :: [PoseidonPackageChronicle] -> ShowS
Show, PoseidonPackageChronicle -> PoseidonPackageChronicle -> Bool
(PoseidonPackageChronicle -> PoseidonPackageChronicle -> Bool)
-> (PoseidonPackageChronicle -> PoseidonPackageChronicle -> Bool)
-> Eq PoseidonPackageChronicle
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: PoseidonPackageChronicle -> PoseidonPackageChronicle -> Bool
== :: PoseidonPackageChronicle -> PoseidonPackageChronicle -> Bool
$c/= :: PoseidonPackageChronicle -> PoseidonPackageChronicle -> Bool
/= :: PoseidonPackageChronicle -> PoseidonPackageChronicle -> Bool
Eq)
instance FromJSON PoseidonPackageChronicle where
parseJSON :: Value -> Parser PoseidonPackageChronicle
parseJSON = String
-> (Object -> Parser PoseidonPackageChronicle)
-> Value
-> Parser PoseidonPackageChronicle
forall a. String -> (Object -> Parser a) -> Value -> Parser a
withObject String
"PoseidonYamlStruct" ((Object -> Parser PoseidonPackageChronicle)
-> Value -> Parser PoseidonPackageChronicle)
-> (Object -> Parser PoseidonPackageChronicle)
-> Value
-> Parser PoseidonPackageChronicle
forall a b. (a -> b) -> a -> b
$ \Object
v -> String
-> Maybe String
-> Version
-> Day
-> Set PackageIteration
-> PoseidonPackageChronicle
PoseidonPackageChronicle
(String
-> Maybe String
-> Version
-> Day
-> Set PackageIteration
-> PoseidonPackageChronicle)
-> Parser String
-> Parser
(Maybe String
-> Version
-> Day
-> Set PackageIteration
-> PoseidonPackageChronicle)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Object
v Object -> Key -> Parser String
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"title"
Parser
(Maybe String
-> Version
-> Day
-> Set PackageIteration
-> PoseidonPackageChronicle)
-> Parser (Maybe String)
-> Parser
(Version
-> Day -> Set PackageIteration -> PoseidonPackageChronicle)
forall a b. Parser (a -> b) -> Parser a -> Parser b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Object
v Object -> Key -> Parser (Maybe String)
forall a. FromJSON a => Object -> Key -> Parser (Maybe a)
.:? Key
"description"
Parser
(Version
-> Day -> Set PackageIteration -> PoseidonPackageChronicle)
-> Parser Version
-> Parser (Day -> Set PackageIteration -> PoseidonPackageChronicle)
forall a b. Parser (a -> b) -> Parser a -> Parser b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Object
v Object -> Key -> Parser Version
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"chronicleVersion"
Parser (Day -> Set PackageIteration -> PoseidonPackageChronicle)
-> Parser Day
-> Parser (Set PackageIteration -> PoseidonPackageChronicle)
forall a b. Parser (a -> b) -> Parser a -> Parser b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Object
v Object -> Key -> Parser Day
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"lastModified"
Parser (Set PackageIteration -> PoseidonPackageChronicle)
-> Parser (Set PackageIteration) -> Parser PoseidonPackageChronicle
forall a b. Parser (a -> b) -> Parser a -> Parser b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Object
v Object -> Key -> Parser (Maybe (Set PackageIteration))
forall a. FromJSON a => Object -> Key -> Parser (Maybe a)
.:? Key
"packages" Parser (Maybe (Set PackageIteration))
-> Set PackageIteration -> Parser (Set PackageIteration)
forall a. Parser (Maybe a) -> a -> Parser a
.!= Set PackageIteration
forall a. Set a
S.empty
instance ToJSON PoseidonPackageChronicle where
toJSON :: PoseidonPackageChronicle -> Value
toJSON PoseidonPackageChronicle
x = [Pair] -> Value
object ([Pair] -> Value) -> [Pair] -> Value
forall a b. (a -> b) -> a -> b
$ [
Key
"title" Key -> String -> Pair
forall v. ToJSON v => Key -> v -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Key -> v -> kv
.= PoseidonPackageChronicle -> String
snapYamlTitle PoseidonPackageChronicle
x,
Key
"description" Key -> Maybe String -> Pair
forall v. ToJSON v => Key -> v -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Key -> v -> kv
.= PoseidonPackageChronicle -> Maybe String
snapYamlDescription PoseidonPackageChronicle
x,
Key
"chronicleVersion" Key -> Version -> Pair
forall v. ToJSON v => Key -> v -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Key -> v -> kv
.= PoseidonPackageChronicle -> Version
snapYamlChronicleVersion PoseidonPackageChronicle
x,
Key
"lastModified" Key -> Day -> Pair
forall v. ToJSON v => Key -> v -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Key -> v -> kv
.= PoseidonPackageChronicle -> Day
snapYamlLastModified PoseidonPackageChronicle
x] [Pair] -> [Pair] -> [Pair]
forall a. [a] -> [a] -> [a]
++
if Bool -> Bool
not (Bool -> Bool) -> Bool -> Bool
forall a b. (a -> b) -> a -> b
$ Set PackageIteration -> Bool
forall a. Set a -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null (PoseidonPackageChronicle -> Set PackageIteration
snapYamlPackages PoseidonPackageChronicle
x) then [Key
"packages" Key -> Set PackageIteration -> Pair
forall v. ToJSON v => Key -> v -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Key -> v -> kv
.= PoseidonPackageChronicle -> Set PackageIteration
snapYamlPackages PoseidonPackageChronicle
x] else []
data PackageIteration = PackageIteration
{ PackageIteration -> String
pacStateTitle :: String
, PackageIteration -> Version
pacStateVersion :: Version
, PackageIteration -> String
pacStateCommit :: String
, PackageIteration -> String
pacStatePath :: FilePath
}
deriving (Int -> PackageIteration -> ShowS
[PackageIteration] -> ShowS
PackageIteration -> String
(Int -> PackageIteration -> ShowS)
-> (PackageIteration -> String)
-> ([PackageIteration] -> ShowS)
-> Show PackageIteration
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> PackageIteration -> ShowS
showsPrec :: Int -> PackageIteration -> ShowS
$cshow :: PackageIteration -> String
show :: PackageIteration -> String
$cshowList :: [PackageIteration] -> ShowS
showList :: [PackageIteration] -> ShowS
Show)
instance Eq PackageIteration where
(PackageIteration String
t1 Version
v1 String
_ String
_) == :: PackageIteration -> PackageIteration -> Bool
== (PackageIteration String
t2 Version
v2 String
_ String
_) = (String
t1 String -> String -> Bool
forall a. Eq a => a -> a -> Bool
== String
t2) Bool -> Bool -> Bool
&& (Version
v1 Version -> Version -> Bool
forall a. Eq a => a -> a -> Bool
== Version
v2)
instance Ord PackageIteration where
(PackageIteration String
t1 Version
v1 String
_ String
_) compare :: PackageIteration -> PackageIteration -> Ordering
`compare` (PackageIteration String
t2 Version
v2 String
_ String
_) = (String
t1,Version
v1) (String, Version) -> (String, Version) -> Ordering
forall a. Ord a => a -> a -> Ordering
`compare` (String
t2,Version
v2)
instance FromJSON PackageIteration where
parseJSON :: Value -> Parser PackageIteration
parseJSON = String
-> (Object -> Parser PackageIteration)
-> Value
-> Parser PackageIteration
forall a. String -> (Object -> Parser a) -> Value -> Parser a
withObject String
"packages" ((Object -> Parser PackageIteration)
-> Value -> Parser PackageIteration)
-> (Object -> Parser PackageIteration)
-> Value
-> Parser PackageIteration
forall a b. (a -> b) -> a -> b
$ \Object
v -> String -> Version -> String -> String -> PackageIteration
PackageIteration
(String -> Version -> String -> String -> PackageIteration)
-> Parser String
-> Parser (Version -> String -> String -> PackageIteration)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Object
v Object -> Key -> Parser String
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"title"
Parser (Version -> String -> String -> PackageIteration)
-> Parser Version -> Parser (String -> String -> PackageIteration)
forall a b. Parser (a -> b) -> Parser a -> Parser b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Object
v Object -> Key -> Parser Version
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"version"
Parser (String -> String -> PackageIteration)
-> Parser String -> Parser (String -> PackageIteration)
forall a b. Parser (a -> b) -> Parser a -> Parser b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Object
v Object -> Key -> Parser String
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"commit"
Parser (String -> PackageIteration)
-> Parser String -> Parser PackageIteration
forall a b. Parser (a -> b) -> Parser a -> Parser b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Object
v Object -> Key -> Parser String
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"path"
instance ToJSON PackageIteration where
toJSON :: PackageIteration -> Value
toJSON PackageIteration
x = [Pair] -> Value
object [
Key
"title" Key -> String -> Pair
forall v. ToJSON v => Key -> v -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Key -> v -> kv
.= PackageIteration -> String
pacStateTitle PackageIteration
x
, Key
"version" Key -> Version -> Pair
forall v. ToJSON v => Key -> v -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Key -> v -> kv
.= PackageIteration -> Version
pacStateVersion PackageIteration
x
, Key
"commit" Key -> String -> Pair
forall v. ToJSON v => Key -> v -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Key -> v -> kv
.= PackageIteration -> String
pacStateCommit PackageIteration
x
, Key
"path" Key -> String -> Pair
forall v. ToJSON v => Key -> v -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Key -> v -> kv
.= PackageIteration -> String
pacStatePath PackageIteration
x
]
instance HasNameAndVersion PackageIteration where
getPacName :: PackageIteration -> String
getPacName (PackageIteration String
t Version
_ String
_ String
_) = String
t
getPacVersion :: PackageIteration -> Maybe Version
getPacVersion (PackageIteration String
_ Version
v String
_ String
_) = Version -> Maybe Version
forall a. a -> Maybe a
Just Version
v
updateChronicle :: PoseidonPackageChronicle -> PoseidonPackageChronicle -> PoseidonPackageChronicle
updateChronicle :: PoseidonPackageChronicle
-> PoseidonPackageChronicle -> PoseidonPackageChronicle
updateChronicle PoseidonPackageChronicle
oldChronicle PoseidonPackageChronicle
newChronicle =
let oldPackageSet :: Set PackageIteration
oldPackageSet = PoseidonPackageChronicle -> Set PackageIteration
snapYamlPackages PoseidonPackageChronicle
oldChronicle
newPackageSet :: Set PackageIteration
newPackageSet = PoseidonPackageChronicle -> Set PackageIteration
snapYamlPackages PoseidonPackageChronicle
newChronicle
mergedPacSet :: Set PackageIteration
mergedPacSet = Set PackageIteration
-> Set PackageIteration -> Set PackageIteration
forall a. Ord a => Set a -> Set a -> Set a
S.union Set PackageIteration
oldPackageSet Set PackageIteration
newPackageSet
oldChronicleVersion :: Version
oldChronicleVersion = PoseidonPackageChronicle -> Version
snapYamlChronicleVersion PoseidonPackageChronicle
oldChronicle
in
if Set PackageIteration
mergedPacSet Set PackageIteration -> Set PackageIteration -> Bool
forall a. Eq a => a -> a -> Bool
== Set PackageIteration
oldPackageSet
then PoseidonPackageChronicle
oldChronicle
else PoseidonPackageChronicle {
snapYamlTitle :: String
snapYamlTitle = PoseidonPackageChronicle -> String
snapYamlTitle PoseidonPackageChronicle
oldChronicle
, snapYamlDescription :: Maybe String
snapYamlDescription = PoseidonPackageChronicle -> Maybe String
snapYamlDescription PoseidonPackageChronicle
oldChronicle
, snapYamlChronicleVersion :: Version
snapYamlChronicleVersion = VersionComponent -> Version -> Version
updateThreeComponentVersion VersionComponent
Minor Version
oldChronicleVersion
, snapYamlLastModified :: Day
snapYamlLastModified = PoseidonPackageChronicle -> Day
snapYamlLastModified PoseidonPackageChronicle
newChronicle
, snapYamlPackages :: Set PackageIteration
snapYamlPackages = Set PackageIteration
mergedPacSet
}
readChronicle :: FilePath -> PoseidonIO PoseidonPackageChronicle
readChronicle :: String -> PoseidonIO PoseidonPackageChronicle
readChronicle String
p = do
ByteString
bs <- IO ByteString -> ReaderT Env IO ByteString
forall a. IO a -> ReaderT Env IO a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO ByteString -> ReaderT Env IO ByteString)
-> IO ByteString -> ReaderT Env IO ByteString
forall a b. (a -> b) -> a -> b
$ String -> IO ByteString
B.readFile String
p
case ByteString -> Either ParseException PoseidonPackageChronicle
forall a. FromJSON a => ByteString -> Either ParseException a
decodeEither' ByteString
bs of
Left ParseException
err -> PoseidonException -> PoseidonIO PoseidonPackageChronicle
forall e a. Exception e => e -> ReaderT Env IO a
forall (m :: * -> *) e a. (MonadThrow m, Exception e) => e -> m a
throwM (PoseidonException -> PoseidonIO PoseidonPackageChronicle)
-> PoseidonException -> PoseidonIO PoseidonPackageChronicle
forall a b. (a -> b) -> a -> b
$ String -> ParseException -> PoseidonException
PoseidonYamlParseException String
p ParseException
err
Right PoseidonPackageChronicle
snap -> PoseidonPackageChronicle -> PoseidonIO PoseidonPackageChronicle
forall a. a -> ReaderT Env IO a
forall (m :: * -> *) a. Monad m => a -> m a
return PoseidonPackageChronicle
snap
writeChronicle :: FilePath -> PoseidonPackageChronicle -> PoseidonIO ()
writeChronicle :: String -> PoseidonPackageChronicle -> PoseidonIO ()
writeChronicle String
p PoseidonPackageChronicle
snapShot = do
IO () -> PoseidonIO ()
forall a. IO a -> ReaderT Env IO a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> PoseidonIO ()) -> IO () -> PoseidonIO ()
forall a b. (a -> b) -> a -> b
$ Bool -> String -> IO ()
createDirectoryIfMissing Bool
True (String -> IO ()) -> String -> IO ()
forall a b. (a -> b) -> a -> b
$ ShowS
takeDirectory String
p
IO () -> PoseidonIO ()
forall a. IO a -> ReaderT Env IO a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> PoseidonIO ()) -> IO () -> PoseidonIO ()
forall a b. (a -> b) -> a -> b
$ String -> ByteString -> IO ()
B.writeFile String
p (Config -> PoseidonPackageChronicle -> ByteString
forall a. ToJSON a => Config -> a -> ByteString
encodePretty Config
opts PoseidonPackageChronicle
snapShot)
where
opts :: Config
opts = Bool -> Config -> Config
setConfDropNull Bool
True (Config -> Config) -> Config -> Config
forall a b. (a -> b) -> a -> b
$ (Text -> Text -> Ordering) -> Config -> Config
setConfCompare (Int -> Int -> Ordering
forall a. Ord a => a -> a -> Ordering
compare (Int -> Int -> Ordering)
-> (Text -> Int) -> Text -> Text -> Ordering
forall b c a. (b -> b -> c) -> (a -> b) -> a -> a -> c
`on` Text -> Int
fieldIndex) Config
defConfig
fieldIndex :: Text -> Int
fieldIndex Text
s = Int -> Maybe Int -> Int
forall a. a -> Maybe a -> a
fromMaybe ([Text] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Text]
fields) (Maybe Int -> Int) -> Maybe Int -> Int
forall a b. (a -> b) -> a -> b
$ Text
s Text -> [Text] -> Maybe Int
forall a. Eq a => a -> [a] -> Maybe Int
`elemIndex` [Text]
fields
fields :: [Text]
fields = [
Text
"title",
Text
"description",
Text
"chronicleVersion",
Text
"lastModified",
Text
"packages",
Text
"title",
Text
"version",
Text
"commit",
Text
"path"
]
makeChronicle :: FilePath -> [PoseidonPackage] -> PoseidonIO PoseidonPackageChronicle
makeChronicle :: String -> [PoseidonPackage] -> PoseidonIO PoseidonPackageChronicle
makeChronicle String
pathToChronicleFile [PoseidonPackage]
pacs = do
Set PackageIteration
pacChronicles <- String -> [PoseidonPackage] -> PoseidonIO (Set PackageIteration)
chroniclePackages String
pathToChronicleFile [PoseidonPackage]
pacs
(UTCTime Day
today DiffTime
_) <- IO UTCTime -> ReaderT Env IO UTCTime
forall a. IO a -> ReaderT Env IO a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO IO UTCTime
getCurrentTime
PoseidonPackageChronicle -> PoseidonIO PoseidonPackageChronicle
forall a. a -> ReaderT Env IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (PoseidonPackageChronicle -> PoseidonIO PoseidonPackageChronicle)
-> PoseidonPackageChronicle -> PoseidonIO PoseidonPackageChronicle
forall a b. (a -> b) -> a -> b
$ PoseidonPackageChronicle {
snapYamlTitle :: String
snapYamlTitle = String
"Chronicle title"
, snapYamlDescription :: Maybe String
snapYamlDescription = String -> Maybe String
forall a. a -> Maybe a
Just String
"Chronicle description"
, snapYamlChronicleVersion :: Version
snapYamlChronicleVersion = [Int] -> Version
makeVersion [Int
0, Int
1, Int
0]
, snapYamlLastModified :: Day
snapYamlLastModified = Day
today
, snapYamlPackages :: Set PackageIteration
snapYamlPackages = Set PackageIteration
pacChronicles
}
chroniclePackages :: FilePath -> [PoseidonPackage] -> PoseidonIO (S.Set PackageIteration)
chroniclePackages :: String -> [PoseidonPackage] -> PoseidonIO (Set PackageIteration)
chroniclePackages String
pathToChronicleFile [PoseidonPackage]
pacs = do
[PackageIteration]
pacStateList <- (PoseidonPackage -> ReaderT Env IO PackageIteration)
-> [PoseidonPackage] -> ReaderT Env IO [PackageIteration]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> [a] -> m [b]
mapM PoseidonPackage -> ReaderT Env IO PackageIteration
snapOne [PoseidonPackage]
pacs
Set PackageIteration -> PoseidonIO (Set PackageIteration)
forall a. a -> ReaderT Env IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (Set PackageIteration -> PoseidonIO (Set PackageIteration))
-> Set PackageIteration -> PoseidonIO (Set PackageIteration)
forall a b. (a -> b) -> a -> b
$ [PackageIteration] -> Set PackageIteration
forall a. Ord a => [a] -> Set a
S.fromList [PackageIteration]
pacStateList
where
snapOne :: PoseidonPackage -> PoseidonIO PackageIteration
snapOne :: PoseidonPackage -> ReaderT Env IO PackageIteration
snapOne PoseidonPackage
pac = do
Version
version <- PoseidonPackage -> PoseidonIO Version
getPackageVersion PoseidonPackage
pac
String
commit <- String -> PoseidonIO String
getGitCommitHash (String -> PoseidonIO String) -> String -> PoseidonIO String
forall a b. (a -> b) -> a -> b
$ PoseidonPackage -> String
posPacBaseDir PoseidonPackage
pac
PackageIteration -> ReaderT Env IO PackageIteration
forall a. a -> ReaderT Env IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (PackageIteration -> ReaderT Env IO PackageIteration)
-> PackageIteration -> ReaderT Env IO PackageIteration
forall a b. (a -> b) -> a -> b
$ PackageIteration {
pacStateTitle :: String
pacStateTitle = PoseidonPackage -> String
forall a. HasNameAndVersion a => a -> String
getPacName PoseidonPackage
pac,
pacStateVersion :: Version
pacStateVersion = Version
version,
pacStateCommit :: String
pacStateCommit = String
commit,
pacStatePath :: String
pacStatePath = String -> ShowS
makeRelative (ShowS
takeDirectory String
pathToChronicleFile) ShowS -> ShowS
forall a b. (a -> b) -> a -> b
$ PoseidonPackage -> String
posPacBaseDir PoseidonPackage
pac
}
getPackageVersion :: PoseidonPackage -> PoseidonIO Version
getPackageVersion :: PoseidonPackage -> PoseidonIO Version
getPackageVersion PoseidonPackage
pac =
case PoseidonPackage -> Maybe Version
forall a. HasNameAndVersion a => a -> Maybe Version
getPacVersion PoseidonPackage
pac of
Just Version
v -> Version -> PoseidonIO Version
forall a. a -> ReaderT Env IO a
forall (m :: * -> *) a. Monad m => a -> m a
return Version
v
Maybe Version
Nothing -> do
TestMode
testMode <- (Env -> TestMode) -> ReaderT Env IO TestMode
forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
asks Env -> TestMode
_envTestMode
case TestMode
testMode of
TestMode
Testing -> Version -> PoseidonIO Version
forall a. a -> ReaderT Env IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (Version -> PoseidonIO Version) -> Version -> PoseidonIO Version
forall a b. (a -> b) -> a -> b
$ [Int] -> Version
makeVersion [Int
0, Int
0, Int
0]
TestMode
Production -> do
PoseidonException -> PoseidonIO Version
forall e a. Exception e => e -> ReaderT Env IO a
forall (m :: * -> *) e a. (MonadThrow m, Exception e) => e -> m a
throwM (PoseidonException -> PoseidonIO Version)
-> PoseidonException -> PoseidonIO Version
forall a b. (a -> b) -> a -> b
$ String -> PoseidonException
PoseidonChronicleException (String -> PoseidonException) -> String -> PoseidonException
forall a b. (a -> b) -> a -> b
$
String
"Package " String -> ShowS
forall a. [a] -> [a] -> [a]
++ ShowS
forall a. Show a => a -> String
show (PoseidonPackage -> String
forall a. HasNameAndVersion a => a -> String
getPacName PoseidonPackage
pac) String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
" has no version."
getGitCommitHash :: FilePath -> PoseidonIO String
getGitCommitHash :: String -> PoseidonIO String
getGitCommitHash String
p = do
TestMode
testMode <- (Env -> TestMode) -> ReaderT Env IO TestMode
forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
asks Env -> TestMode
_envTestMode
case TestMode
testMode of
TestMode
Testing -> String -> PoseidonIO String
forall a. a -> ReaderT Env IO a
forall (m :: * -> *) a. Monad m => a -> m a
return String
"TestMode Git hash"
TestMode
Production -> do
Either GitHashException GitInfo
eitherGit <- IO (Either GitHashException GitInfo)
-> ReaderT Env IO (Either GitHashException GitInfo)
forall a. IO a -> ReaderT Env IO a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO (Either GitHashException GitInfo)
-> ReaderT Env IO (Either GitHashException GitInfo))
-> IO (Either GitHashException GitInfo)
-> ReaderT Env IO (Either GitHashException GitInfo)
forall a b. (a -> b) -> a -> b
$ String -> IO (Either GitHashException GitInfo)
getGitInfo String
p
case Either GitHashException GitInfo
eitherGit of
Left GitHashException
_ -> do
String
pAbsolute <- IO String -> PoseidonIO String
forall a. IO a -> ReaderT Env IO a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO String -> PoseidonIO String) -> IO String -> PoseidonIO String
forall a b. (a -> b) -> a -> b
$ String -> IO String
makeAbsolute String
p
let oneLevelUp :: String
oneLevelUp = ShowS
takeDirectory String
pAbsolute
if String
oneLevelUp String -> String -> Bool
forall a. Eq a => a -> a -> Bool
== ShowS
takeDirectory String
oneLevelUp
then do String -> PoseidonIO String
forall a. a -> ReaderT Env IO a
forall (m :: * -> *) a. Monad m => a -> m a
return String
"No Git repository found"
else String -> PoseidonIO String
getGitCommitHash String
oneLevelUp
Right GitInfo
info -> do
String -> PoseidonIO String
forall a. a -> ReaderT Env IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (String -> PoseidonIO String) -> String -> PoseidonIO String
forall a b. (a -> b) -> a -> b
$ GitInfo -> String
giHash GitInfo
info