{-# 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