policeman-0.0.0.0: src/Policeman/Diff.hs
module Policeman.Diff
( comparePackageStructures
, prettyPrintDiff
) where
import Data.Set ((\\))
import Policeman.ColorTerminal (boldText, errorMessage, infoMessage, skipMessage, successMessage)
import Policeman.Core.Diff (Diff (..), PackageDiff (..), emptyDiff, hasDiffAdded, hasDiffDeleted)
import Policeman.Core.Package (Export, Module (..), ModuleStructure (..), PackageStructure (..))
import Policeman.Core.Version (Version, versionToText)
import Policeman.Evaluate (Evaluation (..))
import qualified Data.HashMap.Strict as HM
{- | Compares the structure of the previous version with the current one.
Returns the `PackageDiff` between them.
-}
comparePackageStructures :: PackageStructure -> PackageStructure -> PackageDiff
comparePackageStructures psPrev psCur = PackageDiff {..}
where
setAddedRemoved :: (Ord a) => Set a -> Set a -> Diff a
setAddedRemoved x y = Diff
{ diffAdded = y \\ x
, diffDeleted = x \\ y
}
pdModule :: Diff Module
pdModule = setAddedRemoved (psModules psPrev) (psModules psCur)
pdExport :: HashMap Module (Diff Export)
pdExport = foldl' go HM.empty oldModules
where
go :: HashMap Module (Diff Export) -> (Module, ModuleStructure) -> HashMap Module (Diff Export)
go hm (modul, msPrev) = case HM.lookup modul (psModulesMap psCur) of
Just msCur -> HM.insert modul (moduleDiffExport msPrev msCur) hm
Nothing -> hm
oldModules :: [(Module, ModuleStructure)]
oldModules = HM.toList $ psModulesMap psPrev
moduleDiffExport :: ModuleStructure -> ModuleStructure -> Diff Export
moduleDiffExport msPrev msCur = setAddedRemoved (msExports msPrev) (msExports msCur)
{- | This function takes previous version of package, diff evaluation
result, the diff itself, and prints new suggested version based on
diff and evaluation.
-}
prettyPrintDiff :: Version -> Evaluation -> PackageDiff -> IO ()
prettyPrintDiff prevVersion Evaluation{..} PackageDiff{..} = do
when (hasDiffDeleted pdModule) $ do
errorMessage "Deleted modules:"
printModule $ diffDeleted pdModule
when (hasDiffAdded pdModule) $ do
successMessage "New modules:"
printModule $ diffAdded pdModule
infoMessage "Per module diff:"
forM_ (HM.toList pdExport) $ \(moduleName, diff@Diff{..}) ->
when (diff /= emptyDiff) $ do
skipMessage $ " * " <> unModule moduleName
when (hasDiffDeleted diff) $ do
errorMessage " Deleted exports:"
printExport diffDeleted
when (hasDiffAdded diff) $ do
successMessage " Added exports:"
printExport diffAdded
putTextLn ""
putText "🔄 Type of change: " *> boldText (show evaluationChange <> "\n")
putTextLn $ "👵 Previous version: " <> versionToText prevVersion
putTextLn $ "💎 Suggested new version: " <> versionToText evaluationVersion
where
printModule :: Set Module -> IO ()
printModule = mapM_ (putTextLn . (" " <>) . unModule)
printExport :: Set Export -> IO ()
printExport = mapM_ (putTextLn . (" " <> ) . show)