{-# LANGUAGE NoImplicitPrelude          #-}
{-# LANGUAGE DataKinds                  #-}
{-# LANGUAGE OverloadedStrings          #-}

module Stack.Types.Package
  ( BuildInfoOpts (..)
  , ExeName (..)
  , FileCacheInfo (..)
  , GetPackageOpts (..)
  , InstallLocation (..)
  , InstallMap
  , Installed (..)
  , InstalledPackageLocation (..)
  , InstalledMap
  , LocalPackage (..)
  , MemoizedWith (..)
  , Package (..)
  , PackageConfig (..)
  , PackageException (..)
  , PackageLibraries (..)
  , PackageSource (..)
  , dotCabalCFilePath
  , dotCabalGetPath
  , dotCabalMain
  , dotCabalMainPath
  , dotCabalModule
  , dotCabalModulePath
  , installedPackageIdentifier
  , installedVersion
  , lpFiles
  , lpFilesForComponents
  , memoizeRefWith
  , packageDefinedFlags
  , packageIdent
  , packageIdentifier
  , psVersion
  , runMemoizedWith
  ) where

import           Data.Aeson
                   ( ToJSON (..), FromJSON (..), (.=), (.:), object, withObject
                   )
import qualified Data.Map as M
import qualified Data.Set as Set
import           Distribution.CabalSpecVersion
import           Distribution.Parsec ( PError (..), PWarning (..), showPos )
import qualified Distribution.SPDX.License as SPDX
import           Distribution.License ( License )
import           Distribution.ModuleName ( ModuleName )
import           Distribution.PackageDescription
                   ( TestSuiteInterface, BuildType )
import           Distribution.System ( Platform (..) )
import qualified RIO.Text as T
import           Stack.Prelude
import           Stack.Types.Compiler ( ActualCompiler )
import           Stack.Types.Dependency ( DepValue )
import           Stack.Types.EnvConfig ( EnvConfig, HasEnvConfig (..) )
import           Stack.Types.GhcPkgId ( GhcPkgId )
import           Stack.Types.NamedComponent ( NamedComponent )
import           Stack.Types.PackageFile
                   ( GetPackageFiles (..), DotCabalDescriptor (..)
                   , DotCabalPath (..)
                   )
import           Stack.Types.SourceMap ( CommonPackage, FromSnapshot )
import           Stack.Types.Version ( VersionRange )

-- | Type representing exceptions thrown by functions exported by the

-- "Stack.Package" module.

data PackageException
  = PackageInvalidCabalFile
      !(Either PackageIdentifierRevision (Path Abs File))
      !(Maybe Version)
      ![PError]
      ![PWarning]
  | MismatchedCabalIdentifier !PackageIdentifierRevision !PackageIdentifier
  | CabalFileNameParseFail FilePath
  | CabalFileNameInvalidPackageName FilePath
  | ComponentNotParsedBug
  deriving (Int -> PackageException -> ShowS
[PackageException] -> ShowS
PackageException -> String
(Int -> PackageException -> ShowS)
-> (PackageException -> String)
-> ([PackageException] -> ShowS)
-> Show PackageException
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> PackageException -> ShowS
showsPrec :: Int -> PackageException -> ShowS
$cshow :: PackageException -> String
show :: PackageException -> String
$cshowList :: [PackageException] -> ShowS
showList :: [PackageException] -> ShowS
Show, Typeable)

instance Exception PackageException where
  displayException :: PackageException -> String
displayException (PackageInvalidCabalFile Either PackageIdentifierRevision (Path Abs File)
loc Maybe Version
_mversion [PError]
errs [PWarning]
warnings) = [String] -> String
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat
    [ String
"Error: [S-8072]\n"
    , String
"Unable to parse Cabal file "
    , case Either PackageIdentifierRevision (Path Abs File)
loc of
        Left PackageIdentifierRevision
pir -> String
"for " String -> ShowS
forall a. [a] -> [a] -> [a]
++ Text -> String
T.unpack (Utf8Builder -> Text
utf8BuilderToText (PackageIdentifierRevision -> Utf8Builder
forall a. Display a => a -> Utf8Builder
display PackageIdentifierRevision
pir))
        Right Path Abs File
fp -> Path Abs File -> String
forall b t. Path b t -> String
toFilePath Path Abs File
fp
    {-
     Not actually needed, the errors will indicate if a newer version exists.
     Also, it seems that this is set to Just the version even if we support it.
    , case mversion of
        Nothing -> ""
        Just version -> "\nRequires newer Cabal file parser version: " ++
                        versionString version
    -}
    , String
"\n\n"
    , [String] -> String
unlines ([String] -> String) -> [String] -> String
forall a b. (a -> b) -> a -> b
$ (PError -> String) -> [PError] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map
        (\(PError Position
pos String
msg) -> [String] -> String
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat
            [ String
"- "
            , Position -> String
showPos Position
pos
            , String
": "
            , String
msg
            ])
        [PError]
errs
    , [String] -> String
unlines ([String] -> String) -> [String] -> String
forall a b. (a -> b) -> a -> b
$ (PWarning -> String) -> [PWarning] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map
        (\(PWarning PWarnType
_ Position
pos String
msg) -> [String] -> String
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat
            [ String
"- "
            , Position -> String
showPos Position
pos
            , String
": "
            , String
msg
            ])
        [PWarning]
warnings
    ]
  displayException (MismatchedCabalIdentifier PackageIdentifierRevision
pir PackageIdentifier
ident) = [String] -> String
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat
    [ String
"Error: [S-5394]\n"
    , String
"Mismatched package identifier."
    , String
"\nFound:    "
    , PackageIdentifier -> String
packageIdentifierString PackageIdentifier
ident
    , String
"\nExpected: "
    , Text -> String
T.unpack (Text -> String) -> Text -> String
forall a b. (a -> b) -> a -> b
$ Utf8Builder -> Text
utf8BuilderToText (Utf8Builder -> Text) -> Utf8Builder -> Text
forall a b. (a -> b) -> a -> b
$ PackageIdentifierRevision -> Utf8Builder
forall a. Display a => a -> Utf8Builder
display PackageIdentifierRevision
pir
    ]
  displayException (CabalFileNameParseFail String
fp) = [String] -> String
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat
    [ String
"Error: [S-2203]\n"
    , String
"Invalid file path for Cabal file, must have a .cabal extension: "
    , String
fp
    ]
  displayException (CabalFileNameInvalidPackageName String
fp) = [String] -> String
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat
    [ String
"Error: [S-8854]\n"
    , String
"Cabal file names must use valid package names followed by a .cabal \
      \extension, the following is invalid: "
    , String
fp
    ]
  displayException PackageException
ComponentNotParsedBug = String -> ShowS
bugReport String
"[S-4623]"
    String
"Component names should always parse as directory names."

-- | Libraries in a package. Since Cabal 2.0, internal libraries are a

-- thing.

data PackageLibraries
  = NoLibraries
  | HasLibraries !(Set Text)
    -- ^ the foreign library names, sub libraries get built automatically

    -- without explicit component name passing

 deriving (Int -> PackageLibraries -> ShowS
[PackageLibraries] -> ShowS
PackageLibraries -> String
(Int -> PackageLibraries -> ShowS)
-> (PackageLibraries -> String)
-> ([PackageLibraries] -> ShowS)
-> Show PackageLibraries
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> PackageLibraries -> ShowS
showsPrec :: Int -> PackageLibraries -> ShowS
$cshow :: PackageLibraries -> String
show :: PackageLibraries -> String
$cshowList :: [PackageLibraries] -> ShowS
showList :: [PackageLibraries] -> ShowS
Show, Typeable)

-- | Name of an executable.

newtype ExeName
  = ExeName { ExeName -> Text
unExeName :: Text }
  deriving (Typeable ExeName
Typeable ExeName
-> (forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> ExeName -> c ExeName)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c ExeName)
-> (ExeName -> Constr)
-> (ExeName -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c ExeName))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c ExeName))
-> ((forall b. Data b => b -> b) -> ExeName -> ExeName)
-> (forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> ExeName -> r)
-> (forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> ExeName -> r)
-> (forall u. (forall d. Data d => d -> u) -> ExeName -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> ExeName -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> ExeName -> m ExeName)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> ExeName -> m ExeName)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> ExeName -> m ExeName)
-> Data ExeName
ExeName -> Constr
ExeName -> DataType
(forall b. Data b => b -> b) -> ExeName -> ExeName
forall a.
Typeable a
-> (forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> a -> c a)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c a)
-> (a -> Constr)
-> (a -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c a))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c a))
-> ((forall b. Data b => b -> b) -> a -> a)
-> (forall r r'.
    (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall r r'.
    (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall u. (forall d. Data d => d -> u) -> a -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> a -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> Data a
forall u. Int -> (forall d. Data d => d -> u) -> ExeName -> u
forall u. (forall d. Data d => d -> u) -> ExeName -> [u]
forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> ExeName -> r
forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> ExeName -> r
forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> ExeName -> m ExeName
forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> ExeName -> m ExeName
forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c ExeName
forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> ExeName -> c ExeName
forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c ExeName)
forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c ExeName)
$cgfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> ExeName -> c ExeName
gfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> ExeName -> c ExeName
$cgunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c ExeName
gunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c ExeName
$ctoConstr :: ExeName -> Constr
toConstr :: ExeName -> Constr
$cdataTypeOf :: ExeName -> DataType
dataTypeOf :: ExeName -> DataType
$cdataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c ExeName)
dataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c ExeName)
$cdataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c ExeName)
dataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c ExeName)
$cgmapT :: (forall b. Data b => b -> b) -> ExeName -> ExeName
gmapT :: (forall b. Data b => b -> b) -> ExeName -> ExeName
$cgmapQl :: forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> ExeName -> r
gmapQl :: forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> ExeName -> r
$cgmapQr :: forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> ExeName -> r
gmapQr :: forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> ExeName -> r
$cgmapQ :: forall u. (forall d. Data d => d -> u) -> ExeName -> [u]
gmapQ :: forall u. (forall d. Data d => d -> u) -> ExeName -> [u]
$cgmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> ExeName -> u
gmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> ExeName -> u
$cgmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> ExeName -> m ExeName
gmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> ExeName -> m ExeName
$cgmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> ExeName -> m ExeName
gmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> ExeName -> m ExeName
$cgmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> ExeName -> m ExeName
gmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> ExeName -> m ExeName
Data, ExeName -> ExeName -> Bool
(ExeName -> ExeName -> Bool)
-> (ExeName -> ExeName -> Bool) -> Eq ExeName
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: ExeName -> ExeName -> Bool
== :: ExeName -> ExeName -> Bool
$c/= :: ExeName -> ExeName -> Bool
/= :: ExeName -> ExeName -> Bool
Eq, (forall x. ExeName -> Rep ExeName x)
-> (forall x. Rep ExeName x -> ExeName) -> Generic ExeName
forall x. Rep ExeName x -> ExeName
forall x. ExeName -> Rep ExeName x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. ExeName -> Rep ExeName x
from :: forall x. ExeName -> Rep ExeName x
$cto :: forall x. Rep ExeName x -> ExeName
to :: forall x. Rep ExeName x -> ExeName
Generic, Eq ExeName
Eq ExeName
-> (Int -> ExeName -> Int) -> (ExeName -> Int) -> Hashable ExeName
Int -> ExeName -> Int
ExeName -> Int
forall a. Eq a -> (Int -> a -> Int) -> (a -> Int) -> Hashable a
$chashWithSalt :: Int -> ExeName -> Int
hashWithSalt :: Int -> ExeName -> Int
$chash :: ExeName -> Int
hash :: ExeName -> Int
Hashable, String -> ExeName
(String -> ExeName) -> IsString ExeName
forall a. (String -> a) -> IsString a
$cfromString :: String -> ExeName
fromString :: String -> ExeName
IsString, ExeName -> ()
(ExeName -> ()) -> NFData ExeName
forall a. (a -> ()) -> NFData a
$crnf :: ExeName -> ()
rnf :: ExeName -> ()
NFData, Eq ExeName
Eq ExeName
-> (ExeName -> ExeName -> Ordering)
-> (ExeName -> ExeName -> Bool)
-> (ExeName -> ExeName -> Bool)
-> (ExeName -> ExeName -> Bool)
-> (ExeName -> ExeName -> Bool)
-> (ExeName -> ExeName -> ExeName)
-> (ExeName -> ExeName -> ExeName)
-> Ord ExeName
ExeName -> ExeName -> Bool
ExeName -> ExeName -> Ordering
ExeName -> ExeName -> ExeName
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: ExeName -> ExeName -> Ordering
compare :: ExeName -> ExeName -> Ordering
$c< :: ExeName -> ExeName -> Bool
< :: ExeName -> ExeName -> Bool
$c<= :: ExeName -> ExeName -> Bool
<= :: ExeName -> ExeName -> Bool
$c> :: ExeName -> ExeName -> Bool
> :: ExeName -> ExeName -> Bool
$c>= :: ExeName -> ExeName -> Bool
>= :: ExeName -> ExeName -> Bool
$cmax :: ExeName -> ExeName -> ExeName
max :: ExeName -> ExeName -> ExeName
$cmin :: ExeName -> ExeName -> ExeName
min :: ExeName -> ExeName -> ExeName
Ord, Int -> ExeName -> ShowS
[ExeName] -> ShowS
ExeName -> String
(Int -> ExeName -> ShowS)
-> (ExeName -> String) -> ([ExeName] -> ShowS) -> Show ExeName
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> ExeName -> ShowS
showsPrec :: Int -> ExeName -> ShowS
$cshow :: ExeName -> String
show :: ExeName -> String
$cshowList :: [ExeName] -> ShowS
showList :: [ExeName] -> ShowS
Show, Typeable)

-- | Some package info.

data Package = Package
  { Package -> PackageName
packageName :: !PackageName
    -- ^ Name of the package.

  , Package -> Version
packageVersion :: !Version
    -- ^ Version of the package

  , Package -> Either License License
packageLicense :: !(Either SPDX.License License)
    -- ^ The license the package was released under.

  , Package -> GetPackageFiles
packageFiles :: !GetPackageFiles
    -- ^ Get all files of the package.

  , Package -> Map PackageName DepValue
packageDeps :: !(Map PackageName DepValue)
    -- ^ Packages that the package depends on, both as libraries and build tools.

  , Package -> Set ExeName
packageUnknownTools :: !(Set ExeName)
    -- ^ Build tools specified in the legacy manner (build-tools:) that failed

    -- the hard-coded lookup.

  , Package -> Set PackageName
packageAllDeps :: !(Set PackageName)
    -- ^ Original dependencies (not sieved).

  , Package -> Map MungedPackageName DepValue
packageSubLibDeps :: !(Map MungedPackageName DepValue)
    -- ^ Original sub-library dependencies (not sieved).

  , Package -> [Text]
packageGhcOptions :: ![Text]
    -- ^ Ghc options used on package.

  , Package -> [Text]
packageCabalConfigOpts :: ![Text]
    -- ^ Additional options passed to ./Setup.hs configure

  , Package -> Map FlagName Bool
packageFlags :: !(Map FlagName Bool)
    -- ^ Flags used on package.

  , Package -> Map FlagName Bool
packageDefaultFlags :: !(Map FlagName Bool)
    -- ^ Defaults for unspecified flags.

  , Package -> PackageLibraries
packageLibraries :: !PackageLibraries
    -- ^ does the package have a buildable library stanza?

  , Package -> Set Text
packageInternalLibraries :: !(Set Text)
    -- ^ names of internal libraries

  , Package -> Map Text TestSuiteInterface
packageTests :: !(Map Text TestSuiteInterface)
    -- ^ names and interfaces of test suites

  , Package -> Set Text
packageBenchmarks :: !(Set Text)
    -- ^ names of benchmarks

  , Package -> Set Text
packageExes :: !(Set Text)
    -- ^ names of executables

  , Package -> GetPackageOpts
packageOpts :: !GetPackageOpts
    -- ^ Args to pass to GHC.

  , Package -> Bool
packageHasExposedModules :: !Bool
    -- ^ Does the package have exposed modules?

  , Package -> BuildType
packageBuildType :: !BuildType
    -- ^ Package build-type.

  , Package -> Maybe (Map PackageName VersionRange)
packageSetupDeps :: !(Maybe (Map PackageName VersionRange))
    -- ^ If present: custom-setup dependencies

  , Package -> CabalSpecVersion
packageCabalSpec :: !CabalSpecVersion
    -- ^ Cabal spec range

  }
  deriving (Int -> Package -> ShowS
[Package] -> ShowS
Package -> String
(Int -> Package -> ShowS)
-> (Package -> String) -> ([Package] -> ShowS) -> Show Package
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Package -> ShowS
showsPrec :: Int -> Package -> ShowS
$cshow :: Package -> String
show :: Package -> String
$cshowList :: [Package] -> ShowS
showList :: [Package] -> ShowS
Show, Typeable)

packageIdent :: Package -> PackageIdentifier
packageIdent :: Package -> PackageIdentifier
packageIdent Package
p = PackageName -> Version -> PackageIdentifier
PackageIdentifier (Package -> PackageName
packageName Package
p) (Package -> Version
packageVersion Package
p)

packageIdentifier :: Package -> PackageIdentifier
packageIdentifier :: Package -> PackageIdentifier
packageIdentifier Package
pkg =
  PackageName -> Version -> PackageIdentifier
PackageIdentifier (Package -> PackageName
packageName Package
pkg) (Package -> Version
packageVersion Package
pkg)

packageDefinedFlags :: Package -> Set FlagName
packageDefinedFlags :: Package -> Set FlagName
packageDefinedFlags = Map FlagName Bool -> Set FlagName
forall k a. Map k a -> Set k
M.keysSet (Map FlagName Bool -> Set FlagName)
-> (Package -> Map FlagName Bool) -> Package -> Set FlagName
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Package -> Map FlagName Bool
packageDefaultFlags

type InstallMap = Map PackageName (InstallLocation, Version)

-- | Files that the package depends on, relative to package directory.

-- Argument is the location of the Cabal file

newtype GetPackageOpts = GetPackageOpts
  { GetPackageOpts
-> forall env.
   HasEnvConfig env =>
   InstallMap
   -> InstalledMap
   -> [PackageName]
   -> [PackageName]
   -> Path Abs File
   -> RIO
        env
        (Map NamedComponent (Map ModuleName (Path Abs File)),
         Map NamedComponent [DotCabalPath],
         Map NamedComponent BuildInfoOpts)
getPackageOpts :: forall env. HasEnvConfig env
                   => InstallMap
                   -> InstalledMap
                   -> [PackageName]
                   -> [PackageName]
                   -> Path Abs File
                   -> RIO env
                        ( Map NamedComponent (Map ModuleName (Path Abs File))
                        , Map NamedComponent [DotCabalPath]
                        , Map NamedComponent BuildInfoOpts
                        )
  }

instance Show GetPackageOpts where
  show :: GetPackageOpts -> String
show GetPackageOpts
_ = String
"<GetPackageOpts>"

-- | GHC options based on cabal information and ghc-options.

data BuildInfoOpts = BuildInfoOpts
  { BuildInfoOpts -> [String]
bioOpts :: [String]
  , BuildInfoOpts -> [String]
bioOneWordOpts :: [String]
  , BuildInfoOpts -> [String]
bioPackageFlags :: [String]
    -- ^ These options can safely have 'nubOrd' applied to them, as there are no

    -- multi-word options (see

    -- https://github.com/commercialhaskell/stack/issues/1255)

  , BuildInfoOpts -> Path Abs File
bioCabalMacros :: Path Abs File
  }
  deriving Int -> BuildInfoOpts -> ShowS
[BuildInfoOpts] -> ShowS
BuildInfoOpts -> String
(Int -> BuildInfoOpts -> ShowS)
-> (BuildInfoOpts -> String)
-> ([BuildInfoOpts] -> ShowS)
-> Show BuildInfoOpts
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> BuildInfoOpts -> ShowS
showsPrec :: Int -> BuildInfoOpts -> ShowS
$cshow :: BuildInfoOpts -> String
show :: BuildInfoOpts -> String
$cshowList :: [BuildInfoOpts] -> ShowS
showList :: [BuildInfoOpts] -> ShowS
Show

-- | Package build configuration

data PackageConfig = PackageConfig
  { PackageConfig -> Bool
packageConfigEnableTests :: !Bool
    -- ^ Are tests enabled?

  , PackageConfig -> Bool
packageConfigEnableBenchmarks :: !Bool
    -- ^ Are benchmarks enabled?

  , PackageConfig -> Map FlagName Bool
packageConfigFlags :: !(Map FlagName Bool)
    -- ^ Configured flags.

  , PackageConfig -> [Text]
packageConfigGhcOptions :: ![Text]
    -- ^ Configured ghc options.

  , PackageConfig -> [Text]
packageConfigCabalConfigOpts :: ![Text]
    -- ^ ./Setup.hs configure options

  , PackageConfig -> ActualCompiler
packageConfigCompilerVersion :: ActualCompiler
    -- ^ GHC version

  , PackageConfig -> Platform
packageConfigPlatform :: !Platform
    -- ^ host platform

  }
 deriving (Int -> PackageConfig -> ShowS
[PackageConfig] -> ShowS
PackageConfig -> String
(Int -> PackageConfig -> ShowS)
-> (PackageConfig -> String)
-> ([PackageConfig] -> ShowS)
-> Show PackageConfig
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> PackageConfig -> ShowS
showsPrec :: Int -> PackageConfig -> ShowS
$cshow :: PackageConfig -> String
show :: PackageConfig -> String
$cshowList :: [PackageConfig] -> ShowS
showList :: [PackageConfig] -> ShowS
Show, Typeable)

-- | Compares the package name.

instance Ord Package where
  compare :: Package -> Package -> Ordering
compare = (PackageName -> PackageName -> Ordering)
-> (Package -> PackageName) -> Package -> Package -> Ordering
forall b c a. (b -> b -> c) -> (a -> b) -> a -> a -> c
on PackageName -> PackageName -> Ordering
forall a. Ord a => a -> a -> Ordering
compare Package -> PackageName
packageName

-- | Compares the package name.

instance Eq Package where
  == :: Package -> Package -> Bool
(==) = (PackageName -> PackageName -> Bool)
-> (Package -> PackageName) -> Package -> Package -> Bool
forall b c a. (b -> b -> c) -> (a -> b) -> a -> a -> c
on PackageName -> PackageName -> Bool
forall a. Eq a => a -> a -> Bool
(==) Package -> PackageName
packageName

-- | Where the package's source is located: local directory or package index

data PackageSource
  = PSFilePath LocalPackage
    -- ^ Package which exist on the filesystem

  | PSRemote PackageLocationImmutable Version FromSnapshot CommonPackage
    -- ^ Package which is downloaded remotely.


instance Show PackageSource where
  show :: PackageSource -> String
show (PSFilePath LocalPackage
lp) = [String] -> String
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat [String
"PSFilePath (", LocalPackage -> String
forall a. Show a => a -> String
show LocalPackage
lp, String
")"]
  show (PSRemote PackageLocationImmutable
pli Version
v FromSnapshot
fromSnapshot CommonPackage
_) =
    [String] -> String
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat
      [ String
"PSRemote"
      , String
"(", PackageLocationImmutable -> String
forall a. Show a => a -> String
show PackageLocationImmutable
pli, String
")"
      , String
"(", Version -> String
forall a. Show a => a -> String
show Version
v, String
")"
      , FromSnapshot -> String
forall a. Show a => a -> String
show FromSnapshot
fromSnapshot
      , String
"<CommonPackage>"
      ]


psVersion :: PackageSource -> Version
psVersion :: PackageSource -> Version
psVersion (PSFilePath LocalPackage
lp) = Package -> Version
packageVersion (Package -> Version) -> Package -> Version
forall a b. (a -> b) -> a -> b
$ LocalPackage -> Package
lpPackage LocalPackage
lp
psVersion (PSRemote PackageLocationImmutable
_ Version
v FromSnapshot
_ CommonPackage
_) = Version
v

-- | Information on a locally available package of source code.

data LocalPackage = LocalPackage
  { LocalPackage -> Package
lpPackage       :: !Package
     -- ^ The @Package@ info itself, after resolution with package flags, with

     -- tests and benchmarks disabled

  , LocalPackage -> Set NamedComponent
lpComponents    :: !(Set NamedComponent)
    -- ^ Components to build, not including the library component.

  , LocalPackage -> Set NamedComponent
lpUnbuildable   :: !(Set NamedComponent)
    -- ^ Components explicitly requested for build, that are marked

    -- "buildable: false".

  , LocalPackage -> Bool
lpWanted        :: !Bool -- FIXME Should completely drop this "wanted"

                             -- terminology, it's unclear

    -- ^ Whether this package is wanted as a target.

  , LocalPackage -> Maybe Package
lpTestBench     :: !(Maybe Package)
    -- ^ This stores the 'Package' with tests and benchmarks enabled, if either

    -- is asked for by the user.

  , LocalPackage -> Path Abs File
lpCabalFile     :: !(Path Abs File)
    -- ^ The Cabal file

  , LocalPackage -> Bool
lpBuildHaddocks :: !Bool
    -- ^ Is Haddock documentation being built for this package?

  , LocalPackage -> Bool
lpForceDirty    :: !Bool
  , LocalPackage -> MemoizedWith EnvConfig (Maybe (Set String))
lpDirtyFiles    :: !(MemoizedWith EnvConfig (Maybe (Set FilePath)))
    -- ^ Nothing == not dirty, Just == dirty. Note that the Set may be empty if

    -- we forced the build to treat packages as dirty. Also, the Set may not

    -- include all modified files.

  , LocalPackage
-> MemoizedWith
     EnvConfig (Map NamedComponent (Map String FileCacheInfo))
lpNewBuildCaches :: !( MemoizedWith
                             EnvConfig
                             (Map NamedComponent (Map FilePath FileCacheInfo))
                         )
    -- ^ current state of the files

  , LocalPackage
-> MemoizedWith
     EnvConfig (Map NamedComponent (Set (Path Abs File)))
lpComponentFiles :: !( MemoizedWith
                             EnvConfig
                             (Map NamedComponent (Set (Path Abs File)))
                         )
    -- ^ all files used by this package

  }
  deriving Int -> LocalPackage -> ShowS
[LocalPackage] -> ShowS
LocalPackage -> String
(Int -> LocalPackage -> ShowS)
-> (LocalPackage -> String)
-> ([LocalPackage] -> ShowS)
-> Show LocalPackage
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> LocalPackage -> ShowS
showsPrec :: Int -> LocalPackage -> ShowS
$cshow :: LocalPackage -> String
show :: LocalPackage -> String
$cshowList :: [LocalPackage] -> ShowS
showList :: [LocalPackage] -> ShowS
Show

newtype MemoizedWith env a
  = MemoizedWith { forall env a. MemoizedWith env a -> RIO env a
unMemoizedWith :: RIO env a }
  deriving (Functor (MemoizedWith env)
Functor (MemoizedWith env)
-> (forall a. a -> MemoizedWith env a)
-> (forall a b.
    MemoizedWith env (a -> b)
    -> MemoizedWith env a -> MemoizedWith env b)
-> (forall a b c.
    (a -> b -> c)
    -> MemoizedWith env a -> MemoizedWith env b -> MemoizedWith env c)
-> (forall a b.
    MemoizedWith env a -> MemoizedWith env b -> MemoizedWith env b)
-> (forall a b.
    MemoizedWith env a -> MemoizedWith env b -> MemoizedWith env a)
-> Applicative (MemoizedWith env)
forall {env}. Functor (MemoizedWith env)
forall a. a -> MemoizedWith env a
forall env a. a -> MemoizedWith env a
forall a b.
MemoizedWith env a -> MemoizedWith env b -> MemoizedWith env a
forall a b.
MemoizedWith env a -> MemoizedWith env b -> MemoizedWith env b
forall a b.
MemoizedWith env (a -> b)
-> MemoizedWith env a -> MemoizedWith env b
forall env a b.
MemoizedWith env a -> MemoizedWith env b -> MemoizedWith env a
forall env a b.
MemoizedWith env a -> MemoizedWith env b -> MemoizedWith env b
forall env a b.
MemoizedWith env (a -> b)
-> MemoizedWith env a -> MemoizedWith env b
forall a b c.
(a -> b -> c)
-> MemoizedWith env a -> MemoizedWith env b -> MemoizedWith env c
forall env a b c.
(a -> b -> c)
-> MemoizedWith env a -> MemoizedWith env b -> MemoizedWith env c
forall (f :: * -> *).
Functor f
-> (forall a. a -> f a)
-> (forall a b. f (a -> b) -> f a -> f b)
-> (forall a b c. (a -> b -> c) -> f a -> f b -> f c)
-> (forall a b. f a -> f b -> f b)
-> (forall a b. f a -> f b -> f a)
-> Applicative f
$cpure :: forall env a. a -> MemoizedWith env a
pure :: forall a. a -> MemoizedWith env a
$c<*> :: forall env a b.
MemoizedWith env (a -> b)
-> MemoizedWith env a -> MemoizedWith env b
<*> :: forall a b.
MemoizedWith env (a -> b)
-> MemoizedWith env a -> MemoizedWith env b
$cliftA2 :: forall env a b c.
(a -> b -> c)
-> MemoizedWith env a -> MemoizedWith env b -> MemoizedWith env c
liftA2 :: forall a b c.
(a -> b -> c)
-> MemoizedWith env a -> MemoizedWith env b -> MemoizedWith env c
$c*> :: forall env a b.
MemoizedWith env a -> MemoizedWith env b -> MemoizedWith env b
*> :: forall a b.
MemoizedWith env a -> MemoizedWith env b -> MemoizedWith env b
$c<* :: forall env a b.
MemoizedWith env a -> MemoizedWith env b -> MemoizedWith env a
<* :: forall a b.
MemoizedWith env a -> MemoizedWith env b -> MemoizedWith env a
Applicative, (forall a b. (a -> b) -> MemoizedWith env a -> MemoizedWith env b)
-> (forall a b. a -> MemoizedWith env b -> MemoizedWith env a)
-> Functor (MemoizedWith env)
forall a b. a -> MemoizedWith env b -> MemoizedWith env a
forall a b. (a -> b) -> MemoizedWith env a -> MemoizedWith env b
forall env a b. a -> MemoizedWith env b -> MemoizedWith env a
forall env a b.
(a -> b) -> MemoizedWith env a -> MemoizedWith env b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
$cfmap :: forall env a b.
(a -> b) -> MemoizedWith env a -> MemoizedWith env b
fmap :: forall a b. (a -> b) -> MemoizedWith env a -> MemoizedWith env b
$c<$ :: forall env a b. a -> MemoizedWith env b -> MemoizedWith env a
<$ :: forall a b. a -> MemoizedWith env b -> MemoizedWith env a
Functor, Applicative (MemoizedWith env)
Applicative (MemoizedWith env)
-> (forall a b.
    MemoizedWith env a
    -> (a -> MemoizedWith env b) -> MemoizedWith env b)
-> (forall a b.
    MemoizedWith env a -> MemoizedWith env b -> MemoizedWith env b)
-> (forall a. a -> MemoizedWith env a)
-> Monad (MemoizedWith env)
forall env. Applicative (MemoizedWith env)
forall a. a -> MemoizedWith env a
forall env a. a -> MemoizedWith env a
forall a b.
MemoizedWith env a -> MemoizedWith env b -> MemoizedWith env b
forall a b.
MemoizedWith env a
-> (a -> MemoizedWith env b) -> MemoizedWith env b
forall env a b.
MemoizedWith env a -> MemoizedWith env b -> MemoizedWith env b
forall env a b.
MemoizedWith env a
-> (a -> MemoizedWith env b) -> MemoizedWith env b
forall (m :: * -> *).
Applicative m
-> (forall a b. m a -> (a -> m b) -> m b)
-> (forall a b. m a -> m b -> m b)
-> (forall a. a -> m a)
-> Monad m
$c>>= :: forall env a b.
MemoizedWith env a
-> (a -> MemoizedWith env b) -> MemoizedWith env b
>>= :: forall a b.
MemoizedWith env a
-> (a -> MemoizedWith env b) -> MemoizedWith env b
$c>> :: forall env a b.
MemoizedWith env a -> MemoizedWith env b -> MemoizedWith env b
>> :: forall a b.
MemoizedWith env a -> MemoizedWith env b -> MemoizedWith env b
$creturn :: forall env a. a -> MemoizedWith env a
return :: forall a. a -> MemoizedWith env a
Monad)

memoizeRefWith :: MonadIO m => RIO env a -> m (MemoizedWith env a)
memoizeRefWith :: forall (m :: * -> *) env a.
MonadIO m =>
RIO env a -> m (MemoizedWith env a)
memoizeRefWith RIO env a
action = do
  IORef (Maybe (Either SomeException a))
ref <- Maybe (Either SomeException a)
-> m (IORef (Maybe (Either SomeException a)))
forall (m :: * -> *) a. MonadIO m => a -> m (IORef a)
newIORef Maybe (Either SomeException a)
forall a. Maybe a
Nothing
  MemoizedWith env a -> m (MemoizedWith env a)
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (MemoizedWith env a -> m (MemoizedWith env a))
-> MemoizedWith env a -> m (MemoizedWith env a)
forall a b. (a -> b) -> a -> b
$ RIO env a -> MemoizedWith env a
forall env a. RIO env a -> MemoizedWith env a
MemoizedWith (RIO env a -> MemoizedWith env a)
-> RIO env a -> MemoizedWith env a
forall a b. (a -> b) -> a -> b
$ do
    Maybe (Either SomeException a)
mres <- IORef (Maybe (Either SomeException a))
-> RIO env (Maybe (Either SomeException a))
forall (m :: * -> *) a. MonadIO m => IORef a -> m a
readIORef IORef (Maybe (Either SomeException a))
ref
    Either SomeException a
res <-
      case Maybe (Either SomeException a)
mres of
        Just Either SomeException a
res -> Either SomeException a -> RIO env (Either SomeException a)
forall a. a -> RIO env a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Either SomeException a
res
        Maybe (Either SomeException a)
Nothing -> do
          Either SomeException a
res <- RIO env a -> RIO env (Either SomeException a)
forall (m :: * -> *) a.
MonadUnliftIO m =>
m a -> m (Either SomeException a)
tryAny RIO env a
action
          IORef (Maybe (Either SomeException a))
-> Maybe (Either SomeException a) -> RIO env ()
forall (m :: * -> *) a. MonadIO m => IORef a -> a -> m ()
writeIORef IORef (Maybe (Either SomeException a))
ref (Maybe (Either SomeException a) -> RIO env ())
-> Maybe (Either SomeException a) -> RIO env ()
forall a b. (a -> b) -> a -> b
$ Either SomeException a -> Maybe (Either SomeException a)
forall a. a -> Maybe a
Just Either SomeException a
res
          Either SomeException a -> RIO env (Either SomeException a)
forall a. a -> RIO env a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Either SomeException a
res
    (SomeException -> RIO env a)
-> (a -> RIO env a) -> Either SomeException a -> RIO env a
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either SomeException -> RIO env a
forall (m :: * -> *) e a. (MonadIO m, Exception e) => e -> m a
throwIO a -> RIO env a
forall a. a -> RIO env a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Either SomeException a
res

runMemoizedWith ::
     (HasEnvConfig env, MonadReader env m, MonadIO m)
  => MemoizedWith EnvConfig a
  -> m a
runMemoizedWith :: forall env (m :: * -> *) a.
(HasEnvConfig env, MonadReader env m, MonadIO m) =>
MemoizedWith EnvConfig a -> m a
runMemoizedWith (MemoizedWith RIO EnvConfig a
action) = do
  EnvConfig
envConfig <- Getting EnvConfig env EnvConfig -> m EnvConfig
forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view Getting EnvConfig env EnvConfig
forall env. HasEnvConfig env => Lens' env EnvConfig
Lens' env EnvConfig
envConfigL
  EnvConfig -> RIO EnvConfig a -> m a
forall (m :: * -> *) env a. MonadIO m => env -> RIO env a -> m a
runRIO EnvConfig
envConfig RIO EnvConfig a
action

instance Show (MemoizedWith env a) where
  show :: MemoizedWith env a -> String
show MemoizedWith env a
_ = String
"<<MemoizedWith>>"

lpFiles :: HasEnvConfig env => LocalPackage -> RIO env (Set.Set (Path Abs File))
lpFiles :: forall env.
HasEnvConfig env =>
LocalPackage -> RIO env (Set (Path Abs File))
lpFiles = MemoizedWith EnvConfig (Set (Path Abs File))
-> RIO env (Set (Path Abs File))
forall env (m :: * -> *) a.
(HasEnvConfig env, MonadReader env m, MonadIO m) =>
MemoizedWith EnvConfig a -> m a
runMemoizedWith (MemoizedWith EnvConfig (Set (Path Abs File))
 -> RIO env (Set (Path Abs File)))
-> (LocalPackage -> MemoizedWith EnvConfig (Set (Path Abs File)))
-> LocalPackage
-> RIO env (Set (Path Abs File))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Map NamedComponent (Set (Path Abs File)) -> Set (Path Abs File))
-> MemoizedWith
     EnvConfig (Map NamedComponent (Set (Path Abs File)))
-> MemoizedWith EnvConfig (Set (Path Abs File))
forall a b.
(a -> b) -> MemoizedWith EnvConfig a -> MemoizedWith EnvConfig b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ([Set (Path Abs File)] -> Set (Path Abs File)
forall (f :: * -> *) a. (Foldable f, Ord a) => f (Set a) -> Set a
Set.unions ([Set (Path Abs File)] -> Set (Path Abs File))
-> (Map NamedComponent (Set (Path Abs File))
    -> [Set (Path Abs File)])
-> Map NamedComponent (Set (Path Abs File))
-> Set (Path Abs File)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Map NamedComponent (Set (Path Abs File)) -> [Set (Path Abs File)]
forall k a. Map k a -> [a]
M.elems) (MemoizedWith EnvConfig (Map NamedComponent (Set (Path Abs File)))
 -> MemoizedWith EnvConfig (Set (Path Abs File)))
-> (LocalPackage
    -> MemoizedWith
         EnvConfig (Map NamedComponent (Set (Path Abs File))))
-> LocalPackage
-> MemoizedWith EnvConfig (Set (Path Abs File))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. LocalPackage
-> MemoizedWith
     EnvConfig (Map NamedComponent (Set (Path Abs File)))
lpComponentFiles

lpFilesForComponents :: HasEnvConfig env
                     => Set NamedComponent
                     -> LocalPackage
                     -> RIO env (Set.Set (Path Abs File))
lpFilesForComponents :: forall env.
HasEnvConfig env =>
Set NamedComponent -> LocalPackage -> RIO env (Set (Path Abs File))
lpFilesForComponents Set NamedComponent
components LocalPackage
lp = MemoizedWith EnvConfig (Set (Path Abs File))
-> RIO env (Set (Path Abs File))
forall env (m :: * -> *) a.
(HasEnvConfig env, MonadReader env m, MonadIO m) =>
MemoizedWith EnvConfig a -> m a
runMemoizedWith (MemoizedWith EnvConfig (Set (Path Abs File))
 -> RIO env (Set (Path Abs File)))
-> MemoizedWith EnvConfig (Set (Path Abs File))
-> RIO env (Set (Path Abs File))
forall a b. (a -> b) -> a -> b
$ do
  Map NamedComponent (Set (Path Abs File))
componentFiles <- LocalPackage
-> MemoizedWith
     EnvConfig (Map NamedComponent (Set (Path Abs File)))
lpComponentFiles LocalPackage
lp
  Set (Path Abs File) -> MemoizedWith EnvConfig (Set (Path Abs File))
forall a. a -> MemoizedWith EnvConfig a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Set (Path Abs File)
 -> MemoizedWith EnvConfig (Set (Path Abs File)))
-> Set (Path Abs File)
-> MemoizedWith EnvConfig (Set (Path Abs File))
forall a b. (a -> b) -> a -> b
$ [Set (Path Abs File)] -> Set (Path Abs File)
forall a. Monoid a => [a] -> a
mconcat (Map NamedComponent (Set (Path Abs File)) -> [Set (Path Abs File)]
forall k a. Map k a -> [a]
M.elems (Map NamedComponent (Set (Path Abs File))
-> Set NamedComponent -> Map NamedComponent (Set (Path Abs File))
forall k a. Ord k => Map k a -> Set k -> Map k a
M.restrictKeys Map NamedComponent (Set (Path Abs File))
componentFiles Set NamedComponent
components))

-- | A location to install a package into, either snapshot or local

data InstallLocation
  = Snap
  | Local
  deriving (InstallLocation -> InstallLocation -> Bool
(InstallLocation -> InstallLocation -> Bool)
-> (InstallLocation -> InstallLocation -> Bool)
-> Eq InstallLocation
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: InstallLocation -> InstallLocation -> Bool
== :: InstallLocation -> InstallLocation -> Bool
$c/= :: InstallLocation -> InstallLocation -> Bool
/= :: InstallLocation -> InstallLocation -> Bool
Eq, Int -> InstallLocation -> ShowS
[InstallLocation] -> ShowS
InstallLocation -> String
(Int -> InstallLocation -> ShowS)
-> (InstallLocation -> String)
-> ([InstallLocation] -> ShowS)
-> Show InstallLocation
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> InstallLocation -> ShowS
showsPrec :: Int -> InstallLocation -> ShowS
$cshow :: InstallLocation -> String
show :: InstallLocation -> String
$cshowList :: [InstallLocation] -> ShowS
showList :: [InstallLocation] -> ShowS
Show)

instance Semigroup InstallLocation where
  InstallLocation
Local <> :: InstallLocation -> InstallLocation -> InstallLocation
<> InstallLocation
_ = InstallLocation
Local
  InstallLocation
_ <> InstallLocation
Local = InstallLocation
Local
  InstallLocation
Snap <> InstallLocation
Snap = InstallLocation
Snap

instance Monoid InstallLocation where
  mempty :: InstallLocation
mempty = InstallLocation
Snap
  mappend :: InstallLocation -> InstallLocation -> InstallLocation
mappend = InstallLocation -> InstallLocation -> InstallLocation
forall a. Semigroup a => a -> a -> a
(<>)

data InstalledPackageLocation
  = InstalledTo InstallLocation | ExtraGlobal
  deriving (InstalledPackageLocation -> InstalledPackageLocation -> Bool
(InstalledPackageLocation -> InstalledPackageLocation -> Bool)
-> (InstalledPackageLocation -> InstalledPackageLocation -> Bool)
-> Eq InstalledPackageLocation
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: InstalledPackageLocation -> InstalledPackageLocation -> Bool
== :: InstalledPackageLocation -> InstalledPackageLocation -> Bool
$c/= :: InstalledPackageLocation -> InstalledPackageLocation -> Bool
/= :: InstalledPackageLocation -> InstalledPackageLocation -> Bool
Eq, Int -> InstalledPackageLocation -> ShowS
[InstalledPackageLocation] -> ShowS
InstalledPackageLocation -> String
(Int -> InstalledPackageLocation -> ShowS)
-> (InstalledPackageLocation -> String)
-> ([InstalledPackageLocation] -> ShowS)
-> Show InstalledPackageLocation
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> InstalledPackageLocation -> ShowS
showsPrec :: Int -> InstalledPackageLocation -> ShowS
$cshow :: InstalledPackageLocation -> String
show :: InstalledPackageLocation -> String
$cshowList :: [InstalledPackageLocation] -> ShowS
showList :: [InstalledPackageLocation] -> ShowS
Show)

newtype FileCacheInfo = FileCacheInfo
  { FileCacheInfo -> SHA256
fciHash :: SHA256
  }
  deriving (FileCacheInfo -> FileCacheInfo -> Bool
(FileCacheInfo -> FileCacheInfo -> Bool)
-> (FileCacheInfo -> FileCacheInfo -> Bool) -> Eq FileCacheInfo
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: FileCacheInfo -> FileCacheInfo -> Bool
== :: FileCacheInfo -> FileCacheInfo -> Bool
$c/= :: FileCacheInfo -> FileCacheInfo -> Bool
/= :: FileCacheInfo -> FileCacheInfo -> Bool
Eq, (forall x. FileCacheInfo -> Rep FileCacheInfo x)
-> (forall x. Rep FileCacheInfo x -> FileCacheInfo)
-> Generic FileCacheInfo
forall x. Rep FileCacheInfo x -> FileCacheInfo
forall x. FileCacheInfo -> Rep FileCacheInfo x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. FileCacheInfo -> Rep FileCacheInfo x
from :: forall x. FileCacheInfo -> Rep FileCacheInfo x
$cto :: forall x. Rep FileCacheInfo x -> FileCacheInfo
to :: forall x. Rep FileCacheInfo x -> FileCacheInfo
Generic, Int -> FileCacheInfo -> ShowS
[FileCacheInfo] -> ShowS
FileCacheInfo -> String
(Int -> FileCacheInfo -> ShowS)
-> (FileCacheInfo -> String)
-> ([FileCacheInfo] -> ShowS)
-> Show FileCacheInfo
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> FileCacheInfo -> ShowS
showsPrec :: Int -> FileCacheInfo -> ShowS
$cshow :: FileCacheInfo -> String
show :: FileCacheInfo -> String
$cshowList :: [FileCacheInfo] -> ShowS
showList :: [FileCacheInfo] -> ShowS
Show, Typeable)

instance NFData FileCacheInfo

-- Provided for storing the BuildCache values in a file. But maybe JSON/YAML

-- isn't the right choice here, worth considering.

instance ToJSON FileCacheInfo where
  toJSON :: FileCacheInfo -> Value
toJSON (FileCacheInfo SHA256
hash') = [Pair] -> Value
object
    [ Key
"hash" Key -> SHA256 -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Key -> v -> kv
forall v. ToJSON v => Key -> v -> Pair
.= SHA256
hash'
    ]
instance FromJSON FileCacheInfo where
  parseJSON :: Value -> Parser FileCacheInfo
parseJSON = String
-> (Object -> Parser FileCacheInfo)
-> Value
-> Parser FileCacheInfo
forall a. String -> (Object -> Parser a) -> Value -> Parser a
withObject String
"FileCacheInfo" ((Object -> Parser FileCacheInfo) -> Value -> Parser FileCacheInfo)
-> (Object -> Parser FileCacheInfo)
-> Value
-> Parser FileCacheInfo
forall a b. (a -> b) -> a -> b
$ \Object
o -> SHA256 -> FileCacheInfo
FileCacheInfo
    (SHA256 -> FileCacheInfo) -> Parser SHA256 -> Parser FileCacheInfo
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Object
o Object -> Key -> Parser SHA256
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"hash"

-- | Maybe get the module name from the .cabal descriptor.

dotCabalModule :: DotCabalDescriptor -> Maybe ModuleName
dotCabalModule :: DotCabalDescriptor -> Maybe ModuleName
dotCabalModule (DotCabalModule ModuleName
m) = ModuleName -> Maybe ModuleName
forall a. a -> Maybe a
Just ModuleName
m
dotCabalModule DotCabalDescriptor
_ = Maybe ModuleName
forall a. Maybe a
Nothing

-- | Maybe get the main name from the .cabal descriptor.

dotCabalMain :: DotCabalDescriptor -> Maybe FilePath
dotCabalMain :: DotCabalDescriptor -> Maybe String
dotCabalMain (DotCabalMain String
m) = String -> Maybe String
forall a. a -> Maybe a
Just String
m
dotCabalMain DotCabalDescriptor
_ = Maybe String
forall a. Maybe a
Nothing

-- | Get the module path.

dotCabalModulePath :: DotCabalPath -> Maybe (Path Abs File)
dotCabalModulePath :: DotCabalPath -> Maybe (Path Abs File)
dotCabalModulePath (DotCabalModulePath Path Abs File
fp) = Path Abs File -> Maybe (Path Abs File)
forall a. a -> Maybe a
Just Path Abs File
fp
dotCabalModulePath DotCabalPath
_ = Maybe (Path Abs File)
forall a. Maybe a
Nothing

-- | Get the main path.

dotCabalMainPath :: DotCabalPath -> Maybe (Path Abs File)
dotCabalMainPath :: DotCabalPath -> Maybe (Path Abs File)
dotCabalMainPath (DotCabalMainPath Path Abs File
fp) = Path Abs File -> Maybe (Path Abs File)
forall a. a -> Maybe a
Just Path Abs File
fp
dotCabalMainPath DotCabalPath
_ = Maybe (Path Abs File)
forall a. Maybe a
Nothing

-- | Get the c file path.

dotCabalCFilePath :: DotCabalPath -> Maybe (Path Abs File)
dotCabalCFilePath :: DotCabalPath -> Maybe (Path Abs File)
dotCabalCFilePath (DotCabalCFilePath Path Abs File
fp) = Path Abs File -> Maybe (Path Abs File)
forall a. a -> Maybe a
Just Path Abs File
fp
dotCabalCFilePath DotCabalPath
_ = Maybe (Path Abs File)
forall a. Maybe a
Nothing

-- | Get the path.

dotCabalGetPath :: DotCabalPath -> Path Abs File
dotCabalGetPath :: DotCabalPath -> Path Abs File
dotCabalGetPath DotCabalPath
dcp =
  case DotCabalPath
dcp of
    DotCabalModulePath Path Abs File
fp -> Path Abs File
fp
    DotCabalMainPath Path Abs File
fp -> Path Abs File
fp
    DotCabalFilePath Path Abs File
fp -> Path Abs File
fp
    DotCabalCFilePath Path Abs File
fp -> Path Abs File
fp

type InstalledMap = Map PackageName (InstallLocation, Installed)

data Installed
  = Library PackageIdentifier GhcPkgId (Maybe (Either SPDX.License License))
  | Executable PackageIdentifier
  deriving (Installed -> Installed -> Bool
(Installed -> Installed -> Bool)
-> (Installed -> Installed -> Bool) -> Eq Installed
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Installed -> Installed -> Bool
== :: Installed -> Installed -> Bool
$c/= :: Installed -> Installed -> Bool
/= :: Installed -> Installed -> Bool
Eq, Int -> Installed -> ShowS
[Installed] -> ShowS
Installed -> String
(Int -> Installed -> ShowS)
-> (Installed -> String)
-> ([Installed] -> ShowS)
-> Show Installed
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Installed -> ShowS
showsPrec :: Int -> Installed -> ShowS
$cshow :: Installed -> String
show :: Installed -> String
$cshowList :: [Installed] -> ShowS
showList :: [Installed] -> ShowS
Show)

installedPackageIdentifier :: Installed -> PackageIdentifier
installedPackageIdentifier :: Installed -> PackageIdentifier
installedPackageIdentifier (Library PackageIdentifier
pid GhcPkgId
_ Maybe (Either License License)
_) = PackageIdentifier
pid
installedPackageIdentifier (Executable PackageIdentifier
pid) = PackageIdentifier
pid

-- | Get the installed Version.

installedVersion :: Installed -> Version
installedVersion :: Installed -> Version
installedVersion Installed
i =
  let PackageIdentifier PackageName
_ Version
version = Installed -> PackageIdentifier
installedPackageIdentifier Installed
i
  in  Version
version