{-# 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 (..))
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 (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
            GenotypeDataSpec
newGenotypeDataSection <-
                if Bool
g
                then do
                    [Char] -> PoseidonIO ()
logDebug [Char]
"Updating genotype data checksums"
                    let gd :: GenotypeDataSpec
gd = PoseidonPackage -> GenotypeDataSpec
posPacGenotypeData PoseidonPackage
pac
                    Bool
genoExists <- [Char] -> ReaderT Env IO Bool
exists ([Char]
d [Char] -> [Char] -> [Char]
</> GenotypeDataSpec -> [Char]
genoFile GenotypeDataSpec
gd)
                    Maybe [Char]
genoChkSum <- if Bool
genoExists
                        then [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]
getChk ([Char]
d [Char] -> [Char] -> [Char]
</> GenotypeDataSpec -> [Char]
genoFile GenotypeDataSpec
gd)
                        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
$ GenotypeDataSpec -> Maybe [Char]
genoFileChkSum GenotypeDataSpec
gd
                    Bool
snpExists <-  [Char] -> ReaderT Env IO Bool
exists ([Char]
d [Char] -> [Char] -> [Char]
</> GenotypeDataSpec -> [Char]
snpFile GenotypeDataSpec
gd)
                    Maybe [Char]
snpChkSum <-  if Bool
snpExists
                        then [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]
getChk ([Char]
d [Char] -> [Char] -> [Char]
</> GenotypeDataSpec -> [Char]
snpFile GenotypeDataSpec
gd)
                        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
$ GenotypeDataSpec -> Maybe [Char]
snpFileChkSum GenotypeDataSpec
gd
                    Bool
indExists <-  [Char] -> ReaderT Env IO Bool
exists ([Char]
d [Char] -> [Char] -> [Char]
</> GenotypeDataSpec -> [Char]
indFile GenotypeDataSpec
gd)
                    Maybe [Char]
indChkSum <-  if Bool
indExists
                        then [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]
getChk ([Char]
d [Char] -> [Char] -> [Char]
</> GenotypeDataSpec -> [Char]
indFile GenotypeDataSpec
gd)
                        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
$ GenotypeDataSpec -> Maybe [Char]
indFileChkSum GenotypeDataSpec
gd
                    GenotypeDataSpec -> ReaderT Env IO GenotypeDataSpec
forall a. a -> ReaderT Env IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (GenotypeDataSpec -> ReaderT Env IO GenotypeDataSpec)
-> GenotypeDataSpec -> ReaderT Env IO GenotypeDataSpec
forall a b. (a -> b) -> a -> b
$ GenotypeDataSpec
gd {
                        genoFileChkSum :: Maybe [Char]
genoFileChkSum = Maybe [Char]
genoChkSum,
                        snpFileChkSum :: Maybe [Char]
snpFileChkSum  = Maybe [Char]
snpChkSum,
                        indFileChkSum :: Maybe [Char]
indFileChkSum  = Maybe [Char]
indChkSum
                    }
                else GenotypeDataSpec -> ReaderT Env IO GenotypeDataSpec
forall a. a -> ReaderT Env IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (GenotypeDataSpec -> ReaderT Env IO GenotypeDataSpec)
-> GenotypeDataSpec -> ReaderT Env IO GenotypeDataSpec
forall a b. (a -> b) -> a -> b
$ PoseidonPackage -> GenotypeDataSpec
posPacGenotypeData PoseidonPackage
pac
            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]
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]
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]
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
            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
newGenotypeDataSection,
                    posPacJannoFileChkSum :: Maybe [Char]
posPacJannoFileChkSum = Maybe [Char]
newJannoChkSum,
                    posPacSeqSourceFileChkSum :: Maybe [Char]
posPacSeqSourceFileChkSum = Maybe [Char]
newSeqSourceChkSum,
                    posPacBibFileChkSum :: Maybe [Char]
posPacBibFileChkSum = Maybe [Char]
newBibChkSum
                }
        getChk :: [Char] -> ReaderT Env IO [Char]
getChk = 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])
-> ([Char] -> IO [Char]) -> [Char] -> ReaderT Env IO [Char]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Char] -> IO [Char]
getChecksum
        exists :: [Char] -> ReaderT Env IO Bool
exists = IO Bool -> ReaderT Env IO Bool
forall a. IO a -> ReaderT Env IO a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO Bool -> ReaderT Env IO Bool)
-> ([Char] -> IO Bool) -> [Char] -> ReaderT Env IO Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Char] -> IO Bool
doesFileExist

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