{-# LANGUAGE OverloadedStrings #-}

module Poseidon.CLI.Rectify (
    runRectify, RectifyOptions (..), PackageVersionUpdate (..), ChecksumsToRectify (..)
    ) where

import           Poseidon.Contributor   (ContributorSpec (..))
import           Poseidon.EntityTypes   (HasNameAndVersion (..),
                                         PacNameAndVersion (..),
                                         renderNameWithVersion)
import           Poseidon.GenotypeData  (GenotypeDataSpec (..),
                                         GenotypeFileSpec (..))
import           Poseidon.Package       (PackageReadOptions (..),
                                         PoseidonPackage (..),
                                         defaultPackageReadOptions,
                                         readPoseidonPackageCollection,
                                         writePoseidonPackage)
import           Poseidon.Utils         (PoseidonIO, getChecksum, logDebug,
                                         logInfo)
import           Poseidon.Version       (VersionComponent (..),
                                         updateThreeComponentVersion)

import           Control.DeepSeq        ((<$!!>))
import           Control.Monad.IO.Class (MonadIO, liftIO)
import           Data.List              (nub)
import           Data.Maybe             (fromJust)
import           Data.Time              (UTCTime (..), getCurrentTime)
import           Data.Version           (Version (..), makeVersion, showVersion)
import           System.Directory       (doesFileExist, removeFile)
import           System.FilePath        ((</>))

data RectifyOptions = RectifyOptions
    { RectifyOptions -> [[Char]]
_rectifyBaseDirs              :: [FilePath]
    , RectifyOptions -> Bool
_rectifyIgnorePoseidonVersion :: Bool
    , RectifyOptions -> Maybe Version
_rectifyPoseidonVersion       :: Maybe Version
    , RectifyOptions -> Maybe PackageVersionUpdate
_rectifyPackageVersionUpdate  :: Maybe PackageVersionUpdate
    , RectifyOptions -> ChecksumsToRectify
_rectifyChecksums             :: ChecksumsToRectify
    , RectifyOptions -> Maybe [ContributorSpec]
_rectifyNewContributors       :: Maybe [ContributorSpec]
    , RectifyOptions -> Bool
_rectifyOnlyLatest            :: Bool
    }

data PackageVersionUpdate = PackageVersionUpdate
    { PackageVersionUpdate -> VersionComponent
_pacVerUpVersionComponent :: VersionComponent
    , PackageVersionUpdate -> Maybe [Char]
_pacVerUpLog              :: Maybe String
    }

data ChecksumsToRectify =
    ChecksumNone |
    ChecksumAll |
    ChecksumsDetail
    { ChecksumsToRectify -> Bool
_rectifyChecksumGeno  :: Bool
    , ChecksumsToRectify -> Bool
_rectifyChecksumJanno :: Bool
    , ChecksumsToRectify -> Bool
_rectifyChecksumSSF   :: Bool
    , ChecksumsToRectify -> Bool
_rectifyChecksumBib   :: Bool
    }

runRectify :: RectifyOptions -> PoseidonIO ()
runRectify :: RectifyOptions -> PoseidonIO ()
runRectify (RectifyOptions [[Char]]
baseDirs Bool
ignorePosVer Maybe Version
newPosVer Maybe PackageVersionUpdate
pacVerUpdate ChecksumsToRectify
checksumUpdate Maybe [ContributorSpec]
newContributors Bool
onlyLatest) = do
    let pacReadOpts :: PackageReadOptions
pacReadOpts = PackageReadOptions
defaultPackageReadOptions {
          _readOptIgnoreChecksums :: Bool
_readOptIgnoreChecksums  = Bool
True
        , _readOptIgnoreGeno :: Bool
_readOptIgnoreGeno       = Bool
True
        , _readOptGenoCheck :: Bool
_readOptGenoCheck        = Bool
False
        , _readOptOnlyLatest :: Bool
_readOptOnlyLatest       = Bool
onlyLatest
    }
    [PoseidonPackage]
allPackages <- PackageReadOptions -> [[Char]] -> PoseidonIO [PoseidonPackage]
readPoseidonPackageCollection
        PackageReadOptions
pacReadOpts {_readOptIgnorePosVersion :: Bool
_readOptIgnorePosVersion = Bool
ignorePosVer}
        [[Char]]
baseDirs
    [Char] -> PoseidonIO ()
logInfo [Char]
"Starting per-package update procedure"
    (PoseidonPackage -> PoseidonIO ())
-> [PoseidonPackage] -> PoseidonIO ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ PoseidonPackage -> PoseidonIO ()
rectifyOnePackage [PoseidonPackage]
allPackages
    [Char] -> PoseidonIO ()
logInfo [Char]
"Done"
    where
        rectifyOnePackage :: PoseidonPackage -> PoseidonIO ()
        rectifyOnePackage :: PoseidonPackage -> PoseidonIO ()
rectifyOnePackage PoseidonPackage
inPac = do
            [Char] -> PoseidonIO ()
logInfo ([Char] -> PoseidonIO ()) -> [Char] -> PoseidonIO ()
forall a b. (a -> b) -> a -> b
$ [Char]
"Rectifying package: " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ PoseidonPackage -> [Char]
forall a. HasNameAndVersion a => a -> [Char]
renderNameWithVersion PoseidonPackage
inPac
            PoseidonPackage
updatedPacPosVer <- Maybe Version -> PoseidonPackage -> PoseidonIO PoseidonPackage
updatePoseidonVersion Maybe Version
newPosVer PoseidonPackage
inPac
            PoseidonPackage
updatedPacContri <- Maybe [ContributorSpec]
-> PoseidonPackage -> PoseidonIO PoseidonPackage
addContributors Maybe [ContributorSpec]
newContributors PoseidonPackage
updatedPacPosVer
            PoseidonPackage
updatedPacChecksums <- ChecksumsToRectify -> PoseidonPackage -> PoseidonIO PoseidonPackage
updateChecksums ChecksumsToRectify
checksumUpdate PoseidonPackage
updatedPacContri
            Maybe PackageVersionUpdate -> PoseidonPackage -> PoseidonIO ()
completeAndWritePackage Maybe PackageVersionUpdate
pacVerUpdate PoseidonPackage
updatedPacChecksums

updatePoseidonVersion :: Maybe Version -> PoseidonPackage -> PoseidonIO PoseidonPackage
updatePoseidonVersion :: Maybe Version -> PoseidonPackage -> PoseidonIO PoseidonPackage
updatePoseidonVersion Maybe Version
Nothing    PoseidonPackage
pac = PoseidonPackage -> PoseidonIO PoseidonPackage
forall a. a -> ReaderT Env IO a
forall (m :: * -> *) a. Monad m => a -> m a
return PoseidonPackage
pac
updatePoseidonVersion (Just Version
ver) PoseidonPackage
pac = do
    [Char] -> PoseidonIO ()
logDebug [Char]
"Updating Poseidon version"
    PoseidonPackage -> PoseidonIO PoseidonPackage
forall a. a -> ReaderT Env IO a
forall (m :: * -> *) a. Monad m => a -> m a
return PoseidonPackage
pac { posPacPoseidonVersion :: Version
posPacPoseidonVersion = Version
ver }

addContributors :: Maybe [ContributorSpec] -> PoseidonPackage -> PoseidonIO PoseidonPackage
addContributors :: Maybe [ContributorSpec]
-> PoseidonPackage -> PoseidonIO PoseidonPackage
addContributors Maybe [ContributorSpec]
Nothing PoseidonPackage
pac = PoseidonPackage -> PoseidonIO PoseidonPackage
forall a. a -> ReaderT Env IO a
forall (m :: * -> *) a. Monad m => a -> m a
return PoseidonPackage
pac
addContributors (Just [ContributorSpec]
cs) PoseidonPackage
pac = do
    [Char] -> PoseidonIO ()
logDebug [Char]
"Updating list of contributors"
    PoseidonPackage -> PoseidonIO PoseidonPackage
forall a. a -> ReaderT Env IO a
forall (m :: * -> *) a. Monad m => a -> m a
return PoseidonPackage
pac { posPacContributor :: [ContributorSpec]
posPacContributor = [ContributorSpec] -> [ContributorSpec]
forall a. Eq a => [a] -> [a]
nub (PoseidonPackage -> [ContributorSpec]
posPacContributor PoseidonPackage
pac [ContributorSpec] -> [ContributorSpec] -> [ContributorSpec]
forall a. [a] -> [a] -> [a]
++ [ContributorSpec]
cs) }

updateChecksums :: ChecksumsToRectify -> PoseidonPackage -> PoseidonIO PoseidonPackage
updateChecksums :: ChecksumsToRectify -> PoseidonPackage -> PoseidonIO PoseidonPackage
updateChecksums ChecksumsToRectify
checksumSetting PoseidonPackage
pac = do
    case ChecksumsToRectify
checksumSetting of
        ChecksumsToRectify
ChecksumNone            -> [Char] -> PoseidonIO ()
logDebug [Char]
"Update no checksums" PoseidonIO ()
-> PoseidonIO PoseidonPackage -> PoseidonIO PoseidonPackage
forall a b.
ReaderT Env IO a -> ReaderT Env IO b -> ReaderT Env IO b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> PoseidonPackage -> PoseidonIO PoseidonPackage
forall a. a -> ReaderT Env IO a
forall (m :: * -> *) a. Monad m => a -> m a
return PoseidonPackage
pac
        ChecksumsToRectify
ChecksumAll             -> Bool -> Bool -> Bool -> Bool -> PoseidonIO PoseidonPackage
update Bool
True Bool
True Bool
True Bool
True
        ChecksumsDetail Bool
g Bool
j Bool
s Bool
b -> Bool -> Bool -> Bool -> Bool -> PoseidonIO PoseidonPackage
update Bool
g Bool
j Bool
s Bool
b
    where
        update :: Bool -> Bool -> Bool -> Bool -> PoseidonIO PoseidonPackage
        update :: Bool -> Bool -> Bool -> Bool -> PoseidonIO PoseidonPackage
update Bool
g Bool
j Bool
s Bool
b = do
            let d :: [Char]
d = PoseidonPackage -> [Char]
posPacBaseDir PoseidonPackage
pac
            let gFileSpec :: GenotypeFileSpec
gFileSpec = GenotypeDataSpec -> GenotypeFileSpec
genotypeFileSpec (GenotypeDataSpec -> GenotypeFileSpec)
-> (PoseidonPackage -> GenotypeDataSpec)
-> PoseidonPackage
-> GenotypeFileSpec
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PoseidonPackage -> GenotypeDataSpec
posPacGenotypeData (PoseidonPackage -> GenotypeFileSpec)
-> PoseidonPackage -> GenotypeFileSpec
forall a b. (a -> b) -> a -> b
$ PoseidonPackage
pac
            GenotypeFileSpec
newGenotypeFileSpec <-
                if Bool
g
                then do
                    [Char] -> PoseidonIO ()
logDebug [Char]
"Updating genotype data checksums"
                    case GenotypeFileSpec
gFileSpec of
                        GenotypeEigenstrat [Char]
gf Maybe [Char]
gfc [Char]
sf Maybe [Char]
sfc [Char]
if_ Maybe [Char]
ifc -> do
                            [Maybe [Char]
genoChkSum, Maybe [Char]
snpChkSum, Maybe [Char]
indChkSum] <-
                                [ReaderT Env IO (Maybe [Char])] -> ReaderT Env IO [Maybe [Char]]
forall (t :: * -> *) (m :: * -> *) a.
(Traversable t, Monad m) =>
t (m a) -> m (t a)
forall (m :: * -> *) a. Monad m => [m a] -> m [a]
sequence [[Char] -> Maybe [Char] -> ReaderT Env IO (Maybe [Char])
forall (m :: * -> *).
MonadIO m =>
[Char] -> Maybe [Char] -> m (Maybe [Char])
testAndGetChecksum [Char]
f Maybe [Char]
c | ([Char]
f, Maybe [Char]
c) <- [[Char]] -> [Maybe [Char]] -> [([Char], Maybe [Char])]
forall a b. [a] -> [b] -> [(a, b)]
zip [[Char]
gf, [Char]
sf, [Char]
if_] [Maybe [Char]
gfc, Maybe [Char]
sfc, Maybe [Char]
ifc]]
                            GenotypeFileSpec -> ReaderT Env IO GenotypeFileSpec
forall a. a -> ReaderT Env IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (GenotypeFileSpec -> ReaderT Env IO GenotypeFileSpec)
-> GenotypeFileSpec -> ReaderT Env IO GenotypeFileSpec
forall a b. (a -> b) -> a -> b
$ [Char]
-> Maybe [Char]
-> [Char]
-> Maybe [Char]
-> [Char]
-> Maybe [Char]
-> GenotypeFileSpec
GenotypeEigenstrat [Char]
gf Maybe [Char]
genoChkSum [Char]
sf Maybe [Char]
snpChkSum [Char]
if_ Maybe [Char]
indChkSum
                        GenotypePlink [Char]
gf Maybe [Char]
gfc [Char]
sf Maybe [Char]
sfc [Char]
if_ Maybe [Char]
ifc -> do
                            [Maybe [Char]
genoChkSum, Maybe [Char]
snpChkSum, Maybe [Char]
indChkSum] <-
                                [ReaderT Env IO (Maybe [Char])] -> ReaderT Env IO [Maybe [Char]]
forall (t :: * -> *) (m :: * -> *) a.
(Traversable t, Monad m) =>
t (m a) -> m (t a)
forall (m :: * -> *) a. Monad m => [m a] -> m [a]
sequence [[Char] -> Maybe [Char] -> ReaderT Env IO (Maybe [Char])
forall (m :: * -> *).
MonadIO m =>
[Char] -> Maybe [Char] -> m (Maybe [Char])
testAndGetChecksum [Char]
f Maybe [Char]
c | ([Char]
f, Maybe [Char]
c) <- [[Char]] -> [Maybe [Char]] -> [([Char], Maybe [Char])]
forall a b. [a] -> [b] -> [(a, b)]
zip [[Char]
gf, [Char]
sf, [Char]
if_] [Maybe [Char]
gfc, Maybe [Char]
sfc, Maybe [Char]
ifc]]
                            GenotypeFileSpec -> ReaderT Env IO GenotypeFileSpec
forall a. a -> ReaderT Env IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (GenotypeFileSpec -> ReaderT Env IO GenotypeFileSpec)
-> GenotypeFileSpec -> ReaderT Env IO GenotypeFileSpec
forall a b. (a -> b) -> a -> b
$ [Char]
-> Maybe [Char]
-> [Char]
-> Maybe [Char]
-> [Char]
-> Maybe [Char]
-> GenotypeFileSpec
GenotypePlink [Char]
gf Maybe [Char]
genoChkSum [Char]
sf Maybe [Char]
snpChkSum [Char]
if_ Maybe [Char]
indChkSum
                        GenotypeVCF [Char]
gf Maybe [Char]
gfc -> do
                            Maybe [Char]
genoChkSum <- [Char] -> Maybe [Char] -> ReaderT Env IO (Maybe [Char])
forall (m :: * -> *).
MonadIO m =>
[Char] -> Maybe [Char] -> m (Maybe [Char])
testAndGetChecksum [Char]
gf Maybe [Char]
gfc
                            GenotypeFileSpec -> ReaderT Env IO GenotypeFileSpec
forall a. a -> ReaderT Env IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (GenotypeFileSpec -> ReaderT Env IO GenotypeFileSpec)
-> GenotypeFileSpec -> ReaderT Env IO GenotypeFileSpec
forall a b. (a -> b) -> a -> b
$ [Char] -> Maybe [Char] -> GenotypeFileSpec
GenotypeVCF [Char]
gf Maybe [Char]
genoChkSum
                else GenotypeFileSpec -> ReaderT Env IO GenotypeFileSpec
forall a. a -> ReaderT Env IO a
forall (m :: * -> *) a. Monad m => a -> m a
return GenotypeFileSpec
gFileSpec
            Maybe [Char]
newJannoChkSum <-
                if Bool
j
                then do
                    [Char] -> PoseidonIO ()
logDebug [Char]
"Updating .janno file checksums"
                    case PoseidonPackage -> Maybe [Char]
posPacJannoFile PoseidonPackage
pac of
                        Maybe [Char]
Nothing -> Maybe [Char] -> ReaderT Env IO (Maybe [Char])
forall a. a -> ReaderT Env IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (Maybe [Char] -> ReaderT Env IO (Maybe [Char]))
-> Maybe [Char] -> ReaderT Env IO (Maybe [Char])
forall a b. (a -> b) -> a -> b
$ PoseidonPackage -> Maybe [Char]
posPacJannoFileChkSum PoseidonPackage
pac
                        Just [Char]
fn -> [Char] -> Maybe [Char]
forall a. a -> Maybe a
Just ([Char] -> Maybe [Char])
-> ReaderT Env IO [Char] -> ReaderT Env IO (Maybe [Char])
forall (m :: * -> *) b a.
(Monad m, NFData b) =>
(a -> b) -> m a -> m b
<$!!> [Char] -> ReaderT Env IO [Char]
forall (m :: * -> *). MonadIO m => [Char] -> m [Char]
getChk ([Char]
d [Char] -> [Char] -> [Char]
</> [Char]
fn)
                else Maybe [Char] -> ReaderT Env IO (Maybe [Char])
forall a. a -> ReaderT Env IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (Maybe [Char] -> ReaderT Env IO (Maybe [Char]))
-> Maybe [Char] -> ReaderT Env IO (Maybe [Char])
forall a b. (a -> b) -> a -> b
$ PoseidonPackage -> Maybe [Char]
posPacJannoFileChkSum PoseidonPackage
pac
            Maybe [Char]
newSeqSourceChkSum <-
                if Bool
s
                then do
                    [Char] -> PoseidonIO ()
logDebug [Char]
"Updating .ssf file checksums"
                    case PoseidonPackage -> Maybe [Char]
posPacSeqSourceFile PoseidonPackage
pac of
                        Maybe [Char]
Nothing -> Maybe [Char] -> ReaderT Env IO (Maybe [Char])
forall a. a -> ReaderT Env IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (Maybe [Char] -> ReaderT Env IO (Maybe [Char]))
-> Maybe [Char] -> ReaderT Env IO (Maybe [Char])
forall a b. (a -> b) -> a -> b
$ PoseidonPackage -> Maybe [Char]
posPacSeqSourceFileChkSum PoseidonPackage
pac
                        Just [Char]
fn -> [Char] -> Maybe [Char]
forall a. a -> Maybe a
Just ([Char] -> Maybe [Char])
-> ReaderT Env IO [Char] -> ReaderT Env IO (Maybe [Char])
forall (m :: * -> *) b a.
(Monad m, NFData b) =>
(a -> b) -> m a -> m b
<$!!> [Char] -> ReaderT Env IO [Char]
forall (m :: * -> *). MonadIO m => [Char] -> m [Char]
getChk ([Char]
d [Char] -> [Char] -> [Char]
</> [Char]
fn)
                else Maybe [Char] -> ReaderT Env IO (Maybe [Char])
forall a. a -> ReaderT Env IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (Maybe [Char] -> ReaderT Env IO (Maybe [Char]))
-> Maybe [Char] -> ReaderT Env IO (Maybe [Char])
forall a b. (a -> b) -> a -> b
$ PoseidonPackage -> Maybe [Char]
posPacSeqSourceFileChkSum PoseidonPackage
pac
            Maybe [Char]
newBibChkSum <-
                if Bool
b
                then do
                    [Char] -> PoseidonIO ()
logDebug [Char]
"Updating .bib file checksums"
                    case PoseidonPackage -> Maybe [Char]
posPacBibFile PoseidonPackage
pac of
                        Maybe [Char]
Nothing -> Maybe [Char] -> ReaderT Env IO (Maybe [Char])
forall a. a -> ReaderT Env IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (Maybe [Char] -> ReaderT Env IO (Maybe [Char]))
-> Maybe [Char] -> ReaderT Env IO (Maybe [Char])
forall a b. (a -> b) -> a -> b
$ PoseidonPackage -> Maybe [Char]
posPacBibFileChkSum PoseidonPackage
pac
                        Just [Char]
fn -> [Char] -> Maybe [Char]
forall a. a -> Maybe a
Just ([Char] -> Maybe [Char])
-> ReaderT Env IO [Char] -> ReaderT Env IO (Maybe [Char])
forall (m :: * -> *) b a.
(Monad m, NFData b) =>
(a -> b) -> m a -> m b
<$!!> [Char] -> ReaderT Env IO [Char]
forall (m :: * -> *). MonadIO m => [Char] -> m [Char]
getChk ([Char]
d [Char] -> [Char] -> [Char]
</> [Char]
fn)
                else Maybe [Char] -> ReaderT Env IO (Maybe [Char])
forall a. a -> ReaderT Env IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (Maybe [Char] -> ReaderT Env IO (Maybe [Char]))
-> Maybe [Char] -> ReaderT Env IO (Maybe [Char])
forall a b. (a -> b) -> a -> b
$ PoseidonPackage -> Maybe [Char]
posPacBibFileChkSum PoseidonPackage
pac
            let gd :: GenotypeDataSpec
gd = PoseidonPackage -> GenotypeDataSpec
posPacGenotypeData PoseidonPackage
pac
            PoseidonPackage -> PoseidonIO PoseidonPackage
forall a. a -> ReaderT Env IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (PoseidonPackage -> PoseidonIO PoseidonPackage)
-> PoseidonPackage -> PoseidonIO PoseidonPackage
forall a b. (a -> b) -> a -> b
$ PoseidonPackage
pac {
                    posPacGenotypeData :: GenotypeDataSpec
posPacGenotypeData = GenotypeDataSpec
gd {genotypeFileSpec :: GenotypeFileSpec
genotypeFileSpec = GenotypeFileSpec
newGenotypeFileSpec},
                    posPacJannoFileChkSum :: Maybe [Char]
posPacJannoFileChkSum = Maybe [Char]
newJannoChkSum,
                    posPacSeqSourceFileChkSum :: Maybe [Char]
posPacSeqSourceFileChkSum = Maybe [Char]
newSeqSourceChkSum,
                    posPacBibFileChkSum :: Maybe [Char]
posPacBibFileChkSum = Maybe [Char]
newBibChkSum
                }
        getChk :: (MonadIO m) => FilePath -> m String
        getChk :: forall (m :: * -> *). MonadIO m => [Char] -> m [Char]
getChk = IO [Char] -> m [Char]
forall a. IO a -> m a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO [Char] -> m [Char])
-> ([Char] -> IO [Char]) -> [Char] -> m [Char]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Char] -> IO [Char]
getChecksum
        testAndGetChecksum :: (MonadIO m) => FilePath -> Maybe String -> m (Maybe String)
        testAndGetChecksum :: forall (m :: * -> *).
MonadIO m =>
[Char] -> Maybe [Char] -> m (Maybe [Char])
testAndGetChecksum [Char]
file Maybe [Char]
defaultChkSum = do
            Bool
e <- IO Bool -> m Bool
forall a. IO a -> m a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO Bool -> m Bool) -> ([Char] -> IO Bool) -> [Char] -> m Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Char] -> IO Bool
doesFileExist ([Char] -> m Bool) -> [Char] -> m Bool
forall a b. (a -> b) -> a -> b
$ [Char]
file
            if Bool
e then [Char] -> Maybe [Char]
forall a. a -> Maybe a
Just ([Char] -> Maybe [Char]) -> m [Char] -> m (Maybe [Char])
forall (m :: * -> *) b a.
(Monad m, NFData b) =>
(a -> b) -> m a -> m b
<$!!> [Char] -> m [Char]
forall (m :: * -> *). MonadIO m => [Char] -> m [Char]
getChk [Char]
file else Maybe [Char] -> m (Maybe [Char])
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe [Char]
defaultChkSum



completeAndWritePackage :: Maybe PackageVersionUpdate -> PoseidonPackage -> PoseidonIO ()
completeAndWritePackage :: Maybe PackageVersionUpdate -> PoseidonPackage -> PoseidonIO ()
completeAndWritePackage Maybe PackageVersionUpdate
Nothing PoseidonPackage
pac = do
    [Char] -> PoseidonIO ()
logDebug [Char]
"Writing rectified POSEIDON.yml file"
    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
$ PoseidonPackage -> IO ()
writePoseidonPackage PoseidonPackage
pac
completeAndWritePackage (Just (PackageVersionUpdate VersionComponent
component Maybe [Char]
logText)) PoseidonPackage
pac = do
    PoseidonPackage
updatedPacPacVer <- VersionComponent -> PoseidonPackage -> PoseidonIO PoseidonPackage
updatePackageVersion VersionComponent
component PoseidonPackage
pac
    PoseidonPackage
updatePacChangeLog <- Maybe [Char] -> PoseidonPackage -> PoseidonIO PoseidonPackage
writeOrUpdateChangelogFile Maybe [Char]
logText PoseidonPackage
updatedPacPacVer
    [Char] -> PoseidonIO ()
logDebug [Char]
"Writing rectified POSEIDON.yml file"
    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
$ PoseidonPackage -> IO ()
writePoseidonPackage PoseidonPackage
updatePacChangeLog

updatePackageVersion :: VersionComponent -> PoseidonPackage -> PoseidonIO PoseidonPackage
updatePackageVersion :: VersionComponent -> PoseidonPackage -> PoseidonIO PoseidonPackage
updatePackageVersion VersionComponent
component PoseidonPackage
pac = do
    [Char] -> PoseidonIO ()
logDebug [Char]
"Updating package version"
    (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
    let pacNameAndVer :: PacNameAndVersion
pacNameAndVer = PoseidonPackage -> PacNameAndVersion
posPacNameAndVersion PoseidonPackage
pac
    let outPac :: PoseidonPackage
outPac = PoseidonPackage
pac {
        posPacNameAndVersion :: PacNameAndVersion
posPacNameAndVersion = PacNameAndVersion
pacNameAndVer {panavVersion :: Maybe Version
panavVersion = Maybe Version
-> (Version -> Maybe Version) -> Maybe Version -> Maybe Version
forall b a. b -> (a -> b) -> Maybe a -> b
maybe (Version -> Maybe Version
forall a. a -> Maybe a
Just (Version -> Maybe Version) -> Version -> Maybe Version
forall a b. (a -> b) -> a -> b
$ [Int] -> Version
makeVersion [Int
0, Int
1, Int
0])
                (Version -> Maybe Version
forall a. a -> Maybe a
Just (Version -> Maybe Version)
-> (Version -> Version) -> Version -> Maybe Version
forall b c a. (b -> c) -> (a -> b) -> a -> c
. VersionComponent -> Version -> Version
updateThreeComponentVersion VersionComponent
component)
                (PoseidonPackage -> Maybe Version
forall a. HasNameAndVersion a => a -> Maybe Version
getPacVersion PoseidonPackage
pac)
            }
        , posPacLastModified :: Maybe Day
posPacLastModified = Day -> Maybe Day
forall a. a -> Maybe a
Just Day
today
        }
    PoseidonPackage -> PoseidonIO PoseidonPackage
forall a. a -> ReaderT Env IO a
forall (m :: * -> *) a. Monad m => a -> m a
return PoseidonPackage
outPac

writeOrUpdateChangelogFile :: Maybe String -> PoseidonPackage -> PoseidonIO PoseidonPackage
writeOrUpdateChangelogFile :: Maybe [Char] -> PoseidonPackage -> PoseidonIO PoseidonPackage
writeOrUpdateChangelogFile Maybe [Char]
Nothing PoseidonPackage
pac = PoseidonPackage -> PoseidonIO PoseidonPackage
forall a. a -> ReaderT Env IO a
forall (m :: * -> *) a. Monad m => a -> m a
return PoseidonPackage
pac
writeOrUpdateChangelogFile (Just [Char]
logText) PoseidonPackage
pac = do
    case PoseidonPackage -> Maybe [Char]
posPacChangelogFile PoseidonPackage
pac of
        Maybe [Char]
Nothing -> do
            [Char] -> PoseidonIO ()
logDebug [Char]
"Creating CHANGELOG.md"
            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
$ [Char] -> [Char] -> IO ()
writeFile (PoseidonPackage -> [Char]
posPacBaseDir PoseidonPackage
pac [Char] -> [Char] -> [Char]
</> [Char]
"CHANGELOG.md") ([Char] -> IO ()) -> [Char] -> IO ()
forall a b. (a -> b) -> a -> b
$
                [Char]
"- V " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ Version -> [Char]
showVersion (Maybe Version -> Version
forall a. HasCallStack => Maybe a -> a
fromJust (Maybe Version -> Version) -> Maybe Version -> Version
forall a b. (a -> b) -> a -> b
$ PoseidonPackage -> Maybe Version
forall a. HasNameAndVersion a => a -> Maybe Version
getPacVersion PoseidonPackage
pac) [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
": " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++
                [Char]
logText [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
"\n"
            PoseidonPackage -> PoseidonIO PoseidonPackage
forall a. a -> ReaderT Env IO a
forall (m :: * -> *) a. Monad m => a -> m a
return PoseidonPackage
pac { posPacChangelogFile :: Maybe [Char]
posPacChangelogFile = [Char] -> Maybe [Char]
forall a. a -> Maybe a
Just [Char]
"CHANGELOG.md" }
        Just [Char]
x -> do
            [Char] -> PoseidonIO ()
logDebug [Char]
"Updating CHANGELOG.md"
            [Char]
changelogFile <- IO [Char] -> ReaderT Env IO [Char]
forall a. IO a -> ReaderT Env IO a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO [Char] -> ReaderT Env IO [Char])
-> IO [Char] -> ReaderT Env IO [Char]
forall a b. (a -> b) -> a -> b
$ [Char] -> IO [Char]
readFile (PoseidonPackage -> [Char]
posPacBaseDir PoseidonPackage
pac [Char] -> [Char] -> [Char]
</> [Char]
x)
            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
$ [Char] -> IO ()
removeFile (PoseidonPackage -> [Char]
posPacBaseDir PoseidonPackage
pac [Char] -> [Char] -> [Char]
</> [Char]
x)
            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
$ [Char] -> [Char] -> IO ()
writeFile (PoseidonPackage -> [Char]
posPacBaseDir PoseidonPackage
pac [Char] -> [Char] -> [Char]
</> [Char]
x) ([Char] -> IO ()) -> [Char] -> IO ()
forall a b. (a -> b) -> a -> b
$
                [Char]
"- V " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ Version -> [Char]
showVersion (Maybe Version -> Version
forall a. HasCallStack => Maybe a -> a
fromJust (Maybe Version -> Version) -> Maybe Version -> Version
forall a b. (a -> b) -> a -> b
$ PoseidonPackage -> Maybe Version
forall a. HasNameAndVersion a => a -> Maybe Version
getPacVersion PoseidonPackage
pac) [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
": "
                [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
logText [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
"\n" [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
changelogFile
            PoseidonPackage -> PoseidonIO PoseidonPackage
forall a. a -> ReaderT Env IO a
forall (m :: * -> *) a. Monad m => a -> m a
return PoseidonPackage
pac