prune-juice-0.7: src/Data/Prune/Types.hs
-- |Description: Types for pruning.
module Data.Prune.Types where
import Prelude
import Data.Aeson ((.:), FromJSON, parseJSON, withObject)
import Data.Set (Set)
import Data.Text (Text, pack, unpack)
import Distribution.Types.Dependency (Dependency)
import Distribution.Types.GenericPackageDescription (GenericPackageDescription)
import Distribution.Types.UnqualComponentName (UnqualComponentName)
import qualified Distribution.Types.Dependency as Dependency
import qualified Distribution.Types.PackageName as PackageName
import qualified Distribution.Types.UnqualComponentName as UnqualComponentName
data BuildSystem = Stack | CabalProject | Cabal
deriving (Eq, Ord, Bounded, Enum)
instance Show BuildSystem where
show = \case
Stack -> "stack"
CabalProject -> "cabal-project"
Cabal -> "cabal"
parseBuildSystem :: String -> Maybe BuildSystem
parseBuildSystem = \case
"stack" -> Just Stack
"cabal-project" -> Just CabalProject
"cabal" -> Just Cabal
_ -> Nothing
allBuildSystems :: [BuildSystem]
allBuildSystems = [minBound..maxBound]
data Verbosity = Silent | Error | Info | Debug
deriving (Eq, Ord, Bounded, Enum)
instance Show Verbosity where
show = \case
Silent -> "silent"
Error -> "error"
Info -> "info"
Debug -> "debug"
parseVerbosity :: String -> Maybe Verbosity
parseVerbosity = \case
"silent" -> Just Silent
"error" -> Just Error
"info" -> Just Info
"debug" -> Just Debug
_ -> Nothing
allVerbosities :: [Verbosity]
allVerbosities = [minBound..maxBound]
-- |The type of the thing to compile.
data CompilableType
= CompilableTypeLibrary
| CompilableTypeExecutable
| CompilableTypeTest
| CompilableTypeBenchmark
deriving (Eq, Ord)
instance Show CompilableType where
show = \case
CompilableTypeLibrary -> "library"
CompilableTypeExecutable -> "executable"
CompilableTypeTest -> "test"
CompilableTypeBenchmark -> "benchmark"
-- |The name of the thing to compile.
newtype CompilableName = CompilableName { unCompilableName :: Text }
deriving (Eq, Ord)
instance Show CompilableName where
show = unpack . unCompilableName
-- |The name of the dependency as listed in package.yaml
data DependencyName = DependencyName { unDependencyName :: Text }
deriving (Eq, Ord)
instance Show DependencyName where
show = unpack . unDependencyName
-- |A qualified module name, like @Foo.Bar@
data ModuleName = ModuleName { unModuleName :: Text }
deriving (Eq, Ord)
instance Show ModuleName where
show = unpack . unModuleName
-- |A thing to compile.
data Compilable = Compilable
{ compilableName :: CompilableName
, compilableType :: CompilableType
, compilableDependencies :: Set DependencyName
-- ^ The list of dependencies less the common dependencies.
, compilableFiles :: Set FilePath
-- ^ The files under `source-dirs`.
}
deriving (Eq, Ord, Show)
data Package = Package
{ packageName :: Text
-- ^ The name of the package.
, packageFile :: FilePath
-- ^ The location of the cabal file.
, packageDescription :: GenericPackageDescription
-- ^ The path to the config file.
, packageBaseDependencies :: Set DependencyName
-- ^ The list of common dependencies.
, packageCompilables :: [Compilable]
-- ^ The things to compile in the package.
}
deriving (Eq, Show)
data StackYaml = StackYaml
{ stackYamlPackages :: [FilePath]
-- ^ The list of packages in stack.yaml. FIXME not every package is this way.
}
deriving (Eq, Ord, Show)
instance FromJSON StackYaml where
parseJSON = withObject "StackYaml" $ \obj ->
StackYaml
<$> obj .: "packages"
data ShouldApply = ShouldNotApply | ShouldApply | ShouldApplyNoVerify
deriving (Eq, Ord, Bounded, Enum)
instance Show ShouldApply where
show = \case
ShouldNotApply -> "no-apply"
ShouldApply -> "apply"
ShouldApplyNoVerify -> "apply-no-verify"
validateShouldApply :: (Bool, Bool) -> ShouldApply
validateShouldApply = \case
(_, True) -> ShouldApplyNoVerify
(True, False) -> ShouldApply
(False, False) -> ShouldNotApply
allApply :: [ShouldApply]
allApply = [minBound..maxBound]
data ApplyStrategy = ApplyStrategySafe | ApplyStrategySmart
deriving (Eq, Ord, Bounded, Enum)
instance Show ApplyStrategy where
show = \case
ApplyStrategySafe -> "safe"
ApplyStrategySmart -> "smart"
parseApplyStrategy :: String -> Maybe ApplyStrategy
parseApplyStrategy = \case
"safe" -> Just ApplyStrategySafe
"smart" -> Just ApplyStrategySmart
_ -> Nothing
allApplyStrategies :: [ApplyStrategy]
allApplyStrategies = [minBound..maxBound]
mkDependencyName :: Dependency -> DependencyName
mkDependencyName = DependencyName . pack . PackageName.unPackageName . Dependency.depPkgName
mkCompilableName :: UnqualComponentName -> CompilableName
mkCompilableName = CompilableName . pack . UnqualComponentName.unUnqualComponentName
headMay :: [a] -> Maybe a
headMay = \case
[] -> Nothing
x:_ -> Just x
lastMay :: [a] -> Maybe a
lastMay = headMay . reverse
ifM :: Monad m => m Bool -> m a -> m a -> m a
ifM b t f = do x <- b; if x then t else f
whenM :: Monad m => m Bool -> m () -> m ()
whenM b t = ifM b t (pure ())
unlessM :: Monad m => m Bool -> m () -> m ()
unlessM b = whenM (not <$> b)