{-# LANGUAGE RecordWildCards #-}

-- | Copyright: (c) 2020 berberman
-- SPDX-License-Identifier: MIT
-- Maintainer: berberman <1793913507@qq.com>
-- The core functions of @arch-hs@.
module Distribution.ArchHs.Core
  ( getDependencies,
    cabalToPkgBuild,
    evalConditionTree,
  )
where

import qualified Algebra.Graph.Labelled.AdjacencyMap as G
import Data.List (intercalate, stripPrefix)
import qualified Data.Map as Map
import Data.Set (Set)
import qualified Data.Set as Set
import Distribution.ArchHs.Hackage
import Distribution.ArchHs.Local
import Distribution.ArchHs.PkgBuild
import Distribution.ArchHs.Types
import Distribution.ArchHs.Utils
import Distribution.Compiler (CompilerFlavor (..))
import Distribution.PackageDescription
import Distribution.Pretty (prettyShow)
import Distribution.SPDX
import Distribution.System (Arch (X86_64), OS (Linux))
import qualified Distribution.Types.BuildInfo.Lens as L
import Distribution.Types.CondTree (simplifyCondTree)
import Distribution.Types.Dependency (Dependency)
import Distribution.Types.PackageName (PackageName, unPackageName)
import Distribution.Types.UnqualComponentName (UnqualComponentName)
import Distribution.Types.Version (mkVersion)
import Distribution.Types.VersionRange
import Distribution.Utils.ShortText (fromShortText)

archEnv :: FlagAssignment -> ConfVar -> Either ConfVar Bool
archEnv :: FlagAssignment -> ConfVar -> Either ConfVar Bool
archEnv FlagAssignment
_ (OS OS
Linux) = Bool -> Either ConfVar Bool
forall a b. b -> Either a b
Right Bool
True
archEnv FlagAssignment
_ (OS OS
_) = Bool -> Either ConfVar Bool
forall a b. b -> Either a b
Right Bool
False
archEnv FlagAssignment
_ (Arch Arch
X86_64) = Bool -> Either ConfVar Bool
forall a b. b -> Either a b
Right Bool
True
archEnv FlagAssignment
_ (Arch Arch
_) = Bool -> Either ConfVar Bool
forall a b. b -> Either a b
Right Bool
False
archEnv FlagAssignment
_ (Impl CompilerFlavor
GHC VersionRange
range) = Bool -> Either ConfVar Bool
forall a b. b -> Either a b
Right (Bool -> Either ConfVar Bool) -> Bool -> Either ConfVar Bool
forall a b. (a -> b) -> a -> b
$ Version -> VersionRange -> Bool
withinRange ([Int] -> Version
mkVersion [Int
8, Int
10, Int
2]) VersionRange
range
archEnv FlagAssignment
_ (Impl CompilerFlavor
_ VersionRange
_) = Bool -> Either ConfVar Bool
forall a b. b -> Either a b
Right Bool
False
archEnv FlagAssignment
assignment f :: ConfVar
f@(Flag FlagName
f') = ConfVar -> Maybe Bool -> Either ConfVar Bool
forall a b. a -> Maybe b -> Either a b
go ConfVar
f (Maybe Bool -> Either ConfVar Bool)
-> Maybe Bool -> Either ConfVar Bool
forall a b. (a -> b) -> a -> b
$ FlagName -> FlagAssignment -> Maybe Bool
lookupFlagAssignment FlagName
f' FlagAssignment
assignment
  where
    go :: a -> Maybe b -> Either a b
go a
_ (Just b
r) = b -> Either a b
forall a b. b -> Either a b
Right b
r
    go a
x Maybe b
Nothing = a -> Either a b
forall a b. a -> Either a b
Left a
x

-- | Simplify the condition tree from 'GenericPackageDescription' with given flag assignments and archlinux system assumption.
evalConditionTree ::
  (Semigroup k, L.HasBuildInfo k, Member FlagAssignmentsEnv r) =>
  GenericPackageDescription ->
  CondTree ConfVar [Dependency] k ->
  Sem r BuildInfo
evalConditionTree :: GenericPackageDescription
-> CondTree ConfVar [Dependency] k -> Sem r BuildInfo
evalConditionTree GenericPackageDescription
cabal CondTree ConfVar [Dependency] k
cond = do
  Map PackageName FlagAssignment
flagAssignments <- Sem r (Map PackageName FlagAssignment)
forall i (r :: [Effect]). MemberWithError (Reader i) r => Sem r i
ask
  let name :: PackageName
name = GenericPackageDescription -> PackageName
getPkgName' GenericPackageDescription
cabal
      packageFlags :: [Flag]
packageFlags = GenericPackageDescription -> [Flag]
genPackageFlags GenericPackageDescription
cabal
      defaultFlagAssignments :: FlagAssignment
defaultFlagAssignments =
        (Flag -> FlagAssignment -> FlagAssignment)
-> FlagAssignment -> [Flag] -> FlagAssignment
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr (\Flag
f FlagAssignment
acc -> FlagName -> Bool -> FlagAssignment -> FlagAssignment
insertFlagAssignment (Flag -> FlagName
flagName Flag
f) (Flag -> Bool
flagDefault Flag
f) FlagAssignment
acc) ([(FlagName, Bool)] -> FlagAssignment
mkFlagAssignment []) [Flag]
packageFlags
      flagAssignment :: [(FlagName, Bool)]
flagAssignment = case PackageName
-> Map PackageName FlagAssignment -> Maybe FlagAssignment
forall k a. Ord k => k -> Map k a -> Maybe a
Map.lookup PackageName
name Map PackageName FlagAssignment
flagAssignments of
        Just FlagAssignment
f -> FlagAssignment -> [(FlagName, Bool)]
unFlagAssignment FlagAssignment
f
        Maybe FlagAssignment
_ -> []
      flagNames :: [FlagName]
flagNames = ((FlagName, Bool) -> FlagName) -> [(FlagName, Bool)] -> [FlagName]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (FlagName, Bool) -> FlagName
forall a b. (a, b) -> a
fst [(FlagName, Bool)]
flagAssignment
      thisFlag :: FlagAssignment
thisFlag =
        [(FlagName, Bool)] -> FlagAssignment
mkFlagAssignment
          ([(FlagName, Bool)] -> FlagAssignment)
-> ([(FlagName, Bool)] -> [(FlagName, Bool)])
-> [(FlagName, Bool)]
-> FlagAssignment
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ([(FlagName, Bool)] -> [(FlagName, Bool)] -> [(FlagName, Bool)]
forall a. Semigroup a => a -> a -> a
<> [(FlagName, Bool)]
flagAssignment)
          ([(FlagName, Bool)] -> [(FlagName, Bool)])
-> ([(FlagName, Bool)] -> [(FlagName, Bool)])
-> [(FlagName, Bool)]
-> [(FlagName, Bool)]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((FlagName, Bool) -> Bool)
-> [(FlagName, Bool)] -> [(FlagName, Bool)]
forall a. (a -> Bool) -> [a] -> [a]
filter (\(FlagName
fName, Bool
_) -> FlagName
fName FlagName -> [FlagName] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`notElem` [FlagName]
flagNames)
          ([(FlagName, Bool)] -> FlagAssignment)
-> [(FlagName, Bool)] -> FlagAssignment
forall a b. (a -> b) -> a -> b
$ (FlagAssignment -> [(FlagName, Bool)]
unFlagAssignment FlagAssignment
defaultFlagAssignments)
  BuildInfo -> Sem r BuildInfo
forall (m :: * -> *) a. Monad m => a -> m a
return (BuildInfo -> Sem r BuildInfo) -> BuildInfo -> Sem r BuildInfo
forall a b. (a -> b) -> a -> b
$ (k -> Getting BuildInfo k BuildInfo -> BuildInfo
forall s a. s -> Getting a s a -> a
^. Getting BuildInfo k BuildInfo
forall a. HasBuildInfo a => Lens' a BuildInfo
L.buildInfo) (k -> BuildInfo)
-> (([Dependency], k) -> k) -> ([Dependency], k) -> BuildInfo
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ([Dependency], k) -> k
forall a b. (a, b) -> b
snd (([Dependency], k) -> BuildInfo) -> ([Dependency], k) -> BuildInfo
forall a b. (a -> b) -> a -> b
$ (ConfVar -> Either ConfVar Bool)
-> CondTree ConfVar [Dependency] k -> ([Dependency], k)
forall a d v.
(Semigroup a, Semigroup d) =>
(v -> Either v Bool) -> CondTree v d a -> (d, a)
simplifyCondTree (FlagAssignment -> ConfVar -> Either ConfVar Bool
archEnv FlagAssignment
thisFlag) CondTree ConfVar [Dependency] k
cond

-----------------------------------------------------------------------------

-- | Get dependencies of a package recursively.
-- All version constraints will be discarded,
-- and only packages depended by executables, libraries, and test suits will be collected.
getDependencies ::
  Members [HackageEnv, FlagAssignmentsEnv, WithMyErr, DependencyRecord] r =>
  -- | Resolved
  Set PackageName ->
  -- | Skipped
  [UnqualComponentName] ->
  -- | Whether recursive
  Bool ->
  -- | Target
  PackageName ->
  Sem r (G.AdjacencyMap (Set DependencyType) PackageName)
getDependencies :: Set PackageName
-> [UnqualComponentName]
-> Bool
-> PackageName
-> Sem r (AdjacencyMap (Set DependencyType) PackageName)
getDependencies Set PackageName
resolved [UnqualComponentName]
skip Bool
recursive PackageName
name = do
  GenericPackageDescription
cabal <- PackageName -> Sem r GenericPackageDescription
forall (r :: [Effect]).
Members '[HackageEnv, WithMyErr] r =>
PackageName -> Sem r GenericPackageDescription
getLatestCabal PackageName
name
  -- Ignore subLibraries
  (PkgList
libDeps, PkgList
libToolsDeps) <- GenericPackageDescription -> Sem r (PkgList, PkgList)
forall (r :: [Effect]).
Members '[FlagAssignmentsEnv, DependencyRecord] r =>
GenericPackageDescription -> Sem r (PkgList, PkgList)
collectLibDeps GenericPackageDescription
cabal
  (ComponentPkgList
exeDeps, ComponentPkgList
exeToolsDeps) <- GenericPackageDescription
-> [UnqualComponentName]
-> Sem r (ComponentPkgList, ComponentPkgList)
forall (r :: [Effect]).
Members '[FlagAssignmentsEnv, DependencyRecord] r =>
GenericPackageDescription
-> [UnqualComponentName]
-> Sem r (ComponentPkgList, ComponentPkgList)
collectExeDeps GenericPackageDescription
cabal [UnqualComponentName]
skip
  (ComponentPkgList
testDeps, ComponentPkgList
testToolsDeps) <- GenericPackageDescription
-> [UnqualComponentName]
-> Sem r (ComponentPkgList, ComponentPkgList)
forall (r :: [Effect]).
Members '[FlagAssignmentsEnv, DependencyRecord] r =>
GenericPackageDescription
-> [UnqualComponentName]
-> Sem r (ComponentPkgList, ComponentPkgList)
collectTestDeps GenericPackageDescription
cabal [UnqualComponentName]
skip
  -- Ignore benchmarks
  -- (benchDeps, benchToolsDeps) <- collectBenchMarkDeps cabal skip
  let uname :: (UnqualComponentName -> DependencyType) -> ComponentPkgList -> [(DependencyType, PkgList)]
      uname :: (UnqualComponentName -> DependencyType)
-> ComponentPkgList -> [(DependencyType, PkgList)]
uname UnqualComponentName -> DependencyType
cons ComponentPkgList
list = [DependencyType] -> [PkgList] -> [(DependencyType, PkgList)]
forall a b. [a] -> [b] -> [(a, b)]
zip (((UnqualComponentName, PkgList) -> DependencyType)
-> ComponentPkgList -> [DependencyType]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (UnqualComponentName -> DependencyType
cons (UnqualComponentName -> DependencyType)
-> ((UnqualComponentName, PkgList) -> UnqualComponentName)
-> (UnqualComponentName, PkgList)
-> DependencyType
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (UnqualComponentName, PkgList) -> UnqualComponentName
forall a b. (a, b) -> a
fst) ComponentPkgList
list) (((UnqualComponentName, PkgList) -> PkgList)
-> ComponentPkgList -> [PkgList]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (UnqualComponentName, PkgList) -> PkgList
forall a b. (a, b) -> b
snd ComponentPkgList
list)

      flatten :: [(DependencyType, PkgList)] -> [(DependencyType, PackageName)]
      flatten :: [(DependencyType, PkgList)] -> [(DependencyType, PackageName)]
flatten [(DependencyType, PkgList)]
list = [[(DependencyType, PackageName)]]
-> [(DependencyType, PackageName)]
forall a. Monoid a => [a] -> a
mconcat ([[(DependencyType, PackageName)]]
 -> [(DependencyType, PackageName)])
-> [[(DependencyType, PackageName)]]
-> [(DependencyType, PackageName)]
forall a b. (a -> b) -> a -> b
$ ((DependencyType, PkgList) -> [(DependencyType, PackageName)])
-> [(DependencyType, PkgList)] -> [[(DependencyType, PackageName)]]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (\(DependencyType
t, PkgList
pkgs) -> [DependencyType] -> PkgList -> [(DependencyType, PackageName)]
forall a b. [a] -> [b] -> [(a, b)]
zip (DependencyType -> [DependencyType]
forall a. a -> [a]
repeat DependencyType
t) PkgList
pkgs) [(DependencyType, PkgList)]
list

      withThisName :: [(DependencyType, PackageName)] -> [(DependencyType, PackageName, PackageName)]
      withThisName :: [(DependencyType, PackageName)]
-> [(DependencyType, PackageName, PackageName)]
withThisName = ((DependencyType, PackageName)
 -> (DependencyType, PackageName, PackageName))
-> [(DependencyType, PackageName)]
-> [(DependencyType, PackageName, PackageName)]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (\(DependencyType
t, PackageName
pkg) -> (DependencyType
t, PackageName
name, PackageName
pkg))

      ignored :: PkgList -> PkgList
ignored = (PackageName -> Bool) -> PkgList -> PkgList
forall a. (a -> Bool) -> [a] -> [a]
filter (\PackageName
x -> Bool -> Bool
not (Bool -> Bool) -> Bool -> Bool
forall a b. (a -> b) -> a -> b
$ PackageName
x PackageName -> PkgList -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` PkgList
ignoreList Bool -> Bool -> Bool
|| PackageName
x PackageName -> PackageName -> Bool
forall a. Eq a => a -> a -> Bool
== PackageName
name Bool -> Bool -> Bool
|| PackageName
x PackageName -> Set PackageName -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` Set PackageName
resolved)
      filterNot :: (a -> Bool) -> [a] -> [a]
filterNot a -> Bool
p = (a -> Bool) -> [a] -> [a]
forall a. (a -> Bool) -> [a] -> [a]
filter (Bool -> Bool
not (Bool -> Bool) -> (a -> Bool) -> a -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> Bool
p)

      currentLib :: AdjacencyMap (Set DependencyType) PackageName
currentLib = [(Set DependencyType, PackageName, PackageName)]
-> AdjacencyMap (Set DependencyType) PackageName
forall e a.
(Eq e, Monoid e, Ord a) =>
[(e, a, a)] -> AdjacencyMap e a
G.edges ([(Set DependencyType, PackageName, PackageName)]
 -> AdjacencyMap (Set DependencyType) PackageName)
-> [(Set DependencyType, PackageName, PackageName)]
-> AdjacencyMap (Set DependencyType) PackageName
forall a b. (a -> b) -> a -> b
$ [Set DependencyType]
-> PkgList
-> PkgList
-> [(Set DependencyType, PackageName, PackageName)]
forall a b c. [a] -> [b] -> [c] -> [(a, b, c)]
zip3 (Set DependencyType -> [Set DependencyType]
forall a. a -> [a]
repeat (Set DependencyType -> [Set DependencyType])
-> Set DependencyType -> [Set DependencyType]
forall a b. (a -> b) -> a -> b
$ DependencyType -> Set DependencyType
forall a. a -> Set a
Set.singleton DependencyType
CLib) (PackageName -> PkgList
forall a. a -> [a]
repeat PackageName
name) (PkgList -> [(Set DependencyType, PackageName, PackageName)])
-> PkgList -> [(Set DependencyType, PackageName, PackageName)]
forall a b. (a -> b) -> a -> b
$ (PackageName -> Bool) -> PkgList -> PkgList
forall a. (a -> Bool) -> [a] -> [a]
filterNot (PackageName -> PkgList -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` PkgList
ignoreList) PkgList
libDeps
      currentLibDeps :: AdjacencyMap (Set DependencyType) PackageName
currentLibDeps = [(Set DependencyType, PackageName, PackageName)]
-> AdjacencyMap (Set DependencyType) PackageName
forall e a.
(Eq e, Monoid e, Ord a) =>
[(e, a, a)] -> AdjacencyMap e a
G.edges ([(Set DependencyType, PackageName, PackageName)]
 -> AdjacencyMap (Set DependencyType) PackageName)
-> [(Set DependencyType, PackageName, PackageName)]
-> AdjacencyMap (Set DependencyType) PackageName
forall a b. (a -> b) -> a -> b
$ [Set DependencyType]
-> PkgList
-> PkgList
-> [(Set DependencyType, PackageName, PackageName)]
forall a b c. [a] -> [b] -> [c] -> [(a, b, c)]
zip3 (Set DependencyType -> [Set DependencyType]
forall a. a -> [a]
repeat (Set DependencyType -> [Set DependencyType])
-> Set DependencyType -> [Set DependencyType]
forall a b. (a -> b) -> a -> b
$ DependencyType -> Set DependencyType
forall a. a -> Set a
Set.singleton DependencyType
CLibBuildTools) (PackageName -> PkgList
forall a. a -> [a]
repeat PackageName
name) (PkgList -> [(Set DependencyType, PackageName, PackageName)])
-> PkgList -> [(Set DependencyType, PackageName, PackageName)]
forall a b. (a -> b) -> a -> b
$ (PackageName -> Bool) -> PkgList -> PkgList
forall a. (a -> Bool) -> [a] -> [a]
filterNot (PackageName -> PkgList -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` PkgList
ignoreList) PkgList
libToolsDeps

      runnableEdges :: (UnqualComponentName -> DependencyType)
-> ComponentPkgList
-> AdjacencyMap (Set DependencyType) PackageName
runnableEdges UnqualComponentName -> DependencyType
k ComponentPkgList
l = [(Set DependencyType, PackageName, PackageName)]
-> AdjacencyMap (Set DependencyType) PackageName
forall e a.
(Eq e, Monoid e, Ord a) =>
[(e, a, a)] -> AdjacencyMap e a
G.edges ([(Set DependencyType, PackageName, PackageName)]
 -> AdjacencyMap (Set DependencyType) PackageName)
-> [(Set DependencyType, PackageName, PackageName)]
-> AdjacencyMap (Set DependencyType) PackageName
forall a b. (a -> b) -> a -> b
$ ((DependencyType, PackageName, PackageName)
 -> (Set DependencyType, PackageName, PackageName))
-> [(DependencyType, PackageName, PackageName)]
-> [(Set DependencyType, PackageName, PackageName)]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (\(DependencyType
x, PackageName
y, PackageName
z) -> (DependencyType -> Set DependencyType
forall a. a -> Set a
Set.singleton DependencyType
x, PackageName
y, PackageName
z)) ([(DependencyType, PackageName, PackageName)]
 -> [(Set DependencyType, PackageName, PackageName)])
-> (ComponentPkgList
    -> [(DependencyType, PackageName, PackageName)])
-> ComponentPkgList
-> [(Set DependencyType, PackageName, PackageName)]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [(DependencyType, PackageName)]
-> [(DependencyType, PackageName, PackageName)]
withThisName ([(DependencyType, PackageName)]
 -> [(DependencyType, PackageName, PackageName)])
-> (ComponentPkgList -> [(DependencyType, PackageName)])
-> ComponentPkgList
-> [(DependencyType, PackageName, PackageName)]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((DependencyType, PackageName) -> Bool)
-> [(DependencyType, PackageName)]
-> [(DependencyType, PackageName)]
forall a. (a -> Bool) -> [a] -> [a]
filterNot (\(DependencyType
_, PackageName
x) -> PackageName
x PackageName -> PkgList -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` PkgList
ignoreList) ([(DependencyType, PackageName)]
 -> [(DependencyType, PackageName)])
-> (ComponentPkgList -> [(DependencyType, PackageName)])
-> ComponentPkgList
-> [(DependencyType, PackageName)]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [(DependencyType, PkgList)] -> [(DependencyType, PackageName)]
flatten ([(DependencyType, PkgList)] -> [(DependencyType, PackageName)])
-> (ComponentPkgList -> [(DependencyType, PkgList)])
-> ComponentPkgList
-> [(DependencyType, PackageName)]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (UnqualComponentName -> DependencyType)
-> ComponentPkgList -> [(DependencyType, PkgList)]
uname UnqualComponentName -> DependencyType
k (ComponentPkgList
 -> [(Set DependencyType, PackageName, PackageName)])
-> ComponentPkgList
-> [(Set DependencyType, PackageName, PackageName)]
forall a b. (a -> b) -> a -> b
$ ComponentPkgList
l

      currentExe :: AdjacencyMap (Set DependencyType) PackageName
currentExe = (UnqualComponentName -> DependencyType)
-> ComponentPkgList
-> AdjacencyMap (Set DependencyType) PackageName
runnableEdges UnqualComponentName -> DependencyType
CExe ComponentPkgList
exeDeps
      currentExeTools :: AdjacencyMap (Set DependencyType) PackageName
currentExeTools = (UnqualComponentName -> DependencyType)
-> ComponentPkgList
-> AdjacencyMap (Set DependencyType) PackageName
runnableEdges UnqualComponentName -> DependencyType
CExeBuildTools ComponentPkgList
exeToolsDeps
      currentTest :: AdjacencyMap (Set DependencyType) PackageName
currentTest = (UnqualComponentName -> DependencyType)
-> ComponentPkgList
-> AdjacencyMap (Set DependencyType) PackageName
runnableEdges UnqualComponentName -> DependencyType
CTest ComponentPkgList
testDeps
      currentTestTools :: AdjacencyMap (Set DependencyType) PackageName
currentTestTools = (UnqualComponentName -> DependencyType)
-> ComponentPkgList
-> AdjacencyMap (Set DependencyType) PackageName
runnableEdges UnqualComponentName -> DependencyType
CTestBuildTools ComponentPkgList
testToolsDeps

      -- currentBench = runnableEdges Types.Benchmark benchDeps
      -- currentBenchTools = runnableEdges BenchmarkBuildTools benchToolsDeps

      <+> :: AdjacencyMap (Set DependencyType) PackageName
-> AdjacencyMap (Set DependencyType) PackageName
-> AdjacencyMap (Set DependencyType) PackageName
(<+>) = AdjacencyMap (Set DependencyType) PackageName
-> AdjacencyMap (Set DependencyType) PackageName
-> AdjacencyMap (Set DependencyType) PackageName
forall e a.
(Eq e, Monoid e, Ord a) =>
AdjacencyMap e a -> AdjacencyMap e a -> AdjacencyMap e a
G.overlay
  -- Only solve lib & exe deps recursively.
  [AdjacencyMap (Set DependencyType) PackageName]
nextLib <- (PackageName
 -> Sem r (AdjacencyMap (Set DependencyType) PackageName))
-> PkgList -> Sem r [AdjacencyMap (Set DependencyType) PackageName]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM (Set PackageName
-> [UnqualComponentName]
-> Bool
-> PackageName
-> Sem r (AdjacencyMap (Set DependencyType) PackageName)
forall (r :: [Effect]).
Members
  '[HackageEnv, FlagAssignmentsEnv, WithMyErr, DependencyRecord] r =>
Set PackageName
-> [UnqualComponentName]
-> Bool
-> PackageName
-> Sem r (AdjacencyMap (Set DependencyType) PackageName)
getDependencies (PackageName -> Set PackageName -> Set PackageName
forall a. Ord a => a -> Set a -> Set a
Set.insert PackageName
name Set PackageName
resolved) [UnqualComponentName]
skip Bool
recursive) (PkgList -> Sem r [AdjacencyMap (Set DependencyType) PackageName])
-> PkgList -> Sem r [AdjacencyMap (Set DependencyType) PackageName]
forall a b. (a -> b) -> a -> b
$ PkgList -> PkgList
ignored PkgList
libDeps
  [AdjacencyMap (Set DependencyType) PackageName]
nextExe <- (PackageName
 -> Sem r (AdjacencyMap (Set DependencyType) PackageName))
-> PkgList -> Sem r [AdjacencyMap (Set DependencyType) PackageName]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM (Set PackageName
-> [UnqualComponentName]
-> Bool
-> PackageName
-> Sem r (AdjacencyMap (Set DependencyType) PackageName)
forall (r :: [Effect]).
Members
  '[HackageEnv, FlagAssignmentsEnv, WithMyErr, DependencyRecord] r =>
Set PackageName
-> [UnqualComponentName]
-> Bool
-> PackageName
-> Sem r (AdjacencyMap (Set DependencyType) PackageName)
getDependencies (PackageName -> Set PackageName -> Set PackageName
forall a. Ord a => a -> Set a -> Set a
Set.insert PackageName
name Set PackageName
resolved) [UnqualComponentName]
skip Bool
recursive) (PkgList -> Sem r [AdjacencyMap (Set DependencyType) PackageName])
-> PkgList -> Sem r [AdjacencyMap (Set DependencyType) PackageName]
forall a b. (a -> b) -> a -> b
$ PkgList -> PkgList
ignored (PkgList -> PkgList)
-> (ComponentPkgList -> PkgList) -> ComponentPkgList -> PkgList
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((DependencyType, PackageName) -> PackageName)
-> [(DependencyType, PackageName)] -> PkgList
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (DependencyType, PackageName) -> PackageName
forall a b. (a, b) -> b
snd ([(DependencyType, PackageName)] -> PkgList)
-> (ComponentPkgList -> [(DependencyType, PackageName)])
-> ComponentPkgList
-> PkgList
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [(DependencyType, PkgList)] -> [(DependencyType, PackageName)]
flatten ([(DependencyType, PkgList)] -> [(DependencyType, PackageName)])
-> (ComponentPkgList -> [(DependencyType, PkgList)])
-> ComponentPkgList
-> [(DependencyType, PackageName)]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (UnqualComponentName -> DependencyType)
-> ComponentPkgList -> [(DependencyType, PkgList)]
uname UnqualComponentName -> DependencyType
CExe (ComponentPkgList -> PkgList) -> ComponentPkgList -> PkgList
forall a b. (a -> b) -> a -> b
$ ComponentPkgList
exeDeps
  AdjacencyMap (Set DependencyType) PackageName
-> Sem r (AdjacencyMap (Set DependencyType) PackageName)
forall (m :: * -> *) a. Monad m => a -> m a
return (AdjacencyMap (Set DependencyType) PackageName
 -> Sem r (AdjacencyMap (Set DependencyType) PackageName))
-> AdjacencyMap (Set DependencyType) PackageName
-> Sem r (AdjacencyMap (Set DependencyType) PackageName)
forall a b. (a -> b) -> a -> b
$
    AdjacencyMap (Set DependencyType) PackageName
currentLib
      AdjacencyMap (Set DependencyType) PackageName
-> AdjacencyMap (Set DependencyType) PackageName
-> AdjacencyMap (Set DependencyType) PackageName
<+> AdjacencyMap (Set DependencyType) PackageName
currentLibDeps
      AdjacencyMap (Set DependencyType) PackageName
-> AdjacencyMap (Set DependencyType) PackageName
-> AdjacencyMap (Set DependencyType) PackageName
<+> AdjacencyMap (Set DependencyType) PackageName
currentExe
      AdjacencyMap (Set DependencyType) PackageName
-> AdjacencyMap (Set DependencyType) PackageName
-> AdjacencyMap (Set DependencyType) PackageName
<+> AdjacencyMap (Set DependencyType) PackageName
currentExeTools
      AdjacencyMap (Set DependencyType) PackageName
-> AdjacencyMap (Set DependencyType) PackageName
-> AdjacencyMap (Set DependencyType) PackageName
<+> AdjacencyMap (Set DependencyType) PackageName
currentTest
      AdjacencyMap (Set DependencyType) PackageName
-> AdjacencyMap (Set DependencyType) PackageName
-> AdjacencyMap (Set DependencyType) PackageName
<+> AdjacencyMap (Set DependencyType) PackageName
currentTestTools
      -- <+> currentBench
      -- <+> currentBenchTools
      AdjacencyMap (Set DependencyType) PackageName
-> AdjacencyMap (Set DependencyType) PackageName
-> AdjacencyMap (Set DependencyType) PackageName
<+> if Bool
recursive
        then ([AdjacencyMap (Set DependencyType) PackageName]
-> AdjacencyMap (Set DependencyType) PackageName
forall e a.
(Eq e, Monoid e, Ord a) =>
[AdjacencyMap e a] -> AdjacencyMap e a
G.overlays [AdjacencyMap (Set DependencyType) PackageName]
nextLib) AdjacencyMap (Set DependencyType) PackageName
-> AdjacencyMap (Set DependencyType) PackageName
-> AdjacencyMap (Set DependencyType) PackageName
<+> ([AdjacencyMap (Set DependencyType) PackageName]
-> AdjacencyMap (Set DependencyType) PackageName
forall e a.
(Eq e, Monoid e, Ord a) =>
[AdjacencyMap e a] -> AdjacencyMap e a
G.overlays [AdjacencyMap (Set DependencyType) PackageName]
nextExe)
        else AdjacencyMap (Set DependencyType) PackageName
forall e a. AdjacencyMap e a
G.empty

collectLibDeps :: Members [FlagAssignmentsEnv, DependencyRecord] r => GenericPackageDescription -> Sem r (PkgList, PkgList)
collectLibDeps :: GenericPackageDescription -> Sem r (PkgList, PkgList)
collectLibDeps GenericPackageDescription
cabal = do
  case GenericPackageDescription
cabal GenericPackageDescription
-> (GenericPackageDescription
    -> Maybe (CondTree ConfVar [Dependency] Library))
-> Maybe (CondTree ConfVar [Dependency] Library)
forall a b. a -> (a -> b) -> b
& GenericPackageDescription
-> Maybe (CondTree ConfVar [Dependency] Library)
condLibrary of
    Just CondTree ConfVar [Dependency] Library
lib -> do
      let name :: PackageName
name = GenericPackageDescription -> PackageName
getPkgName' GenericPackageDescription
cabal
      BuildInfo
info <- GenericPackageDescription
-> CondTree ConfVar [Dependency] Library -> Sem r BuildInfo
forall k (r :: [Effect]).
(Semigroup k, HasBuildInfo k, Member FlagAssignmentsEnv r) =>
GenericPackageDescription
-> CondTree ConfVar [Dependency] k -> Sem r BuildInfo
evalConditionTree GenericPackageDescription
cabal CondTree ConfVar [Dependency] Library
lib
      let libDeps :: [(PackageName, VersionRange)]
libDeps = (Dependency -> (PackageName, VersionRange))
-> [Dependency] -> [(PackageName, VersionRange)]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Dependency -> (PackageName, VersionRange)
unDepV ([Dependency] -> [(PackageName, VersionRange)])
-> [Dependency] -> [(PackageName, VersionRange)]
forall a b. (a -> b) -> a -> b
$ BuildInfo -> [Dependency]
buildDependsIfBuild BuildInfo
info
          toolDeps :: [(PackageName, VersionRange)]
toolDeps = (ExeDependency -> (PackageName, VersionRange))
-> [ExeDependency] -> [(PackageName, VersionRange)]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ExeDependency -> (PackageName, VersionRange)
unExeV ([ExeDependency] -> [(PackageName, VersionRange)])
-> [ExeDependency] -> [(PackageName, VersionRange)]
forall a b. (a -> b) -> a -> b
$ BuildInfo -> [ExeDependency]
buildToolDependsIfBuild BuildInfo
info
      PackageName -> [(PackageName, VersionRange)] -> Sem r ()
forall (r :: [Effect]).
Member DependencyRecord r =>
PackageName -> [(PackageName, VersionRange)] -> Sem r ()
updateDependencyRecord PackageName
name [(PackageName, VersionRange)]
libDeps
      PackageName -> [(PackageName, VersionRange)] -> Sem r ()
forall (r :: [Effect]).
Member DependencyRecord r =>
PackageName -> [(PackageName, VersionRange)] -> Sem r ()
updateDependencyRecord PackageName
name [(PackageName, VersionRange)]
toolDeps
      (PkgList, PkgList) -> Sem r (PkgList, PkgList)
forall (m :: * -> *) a. Monad m => a -> m a
return (((PackageName, VersionRange) -> PackageName)
-> [(PackageName, VersionRange)] -> PkgList
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (PackageName, VersionRange) -> PackageName
forall a b. (a, b) -> a
fst [(PackageName, VersionRange)]
libDeps, ((PackageName, VersionRange) -> PackageName)
-> [(PackageName, VersionRange)] -> PkgList
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (PackageName, VersionRange) -> PackageName
forall a b. (a, b) -> a
fst [(PackageName, VersionRange)]
toolDeps)
    Maybe (CondTree ConfVar [Dependency] Library)
Nothing -> (PkgList, PkgList) -> Sem r (PkgList, PkgList)
forall (m :: * -> *) a. Monad m => a -> m a
return ([], [])

collectRunnableDeps ::
  (Semigroup k, L.HasBuildInfo k, Members [FlagAssignmentsEnv, DependencyRecord] r) =>
  (GenericPackageDescription -> [(UnqualComponentName, CondTree ConfVar [Dependency] k)]) ->
  GenericPackageDescription ->
  [UnqualComponentName] ->
  Sem r (ComponentPkgList, ComponentPkgList)
collectRunnableDeps :: (GenericPackageDescription
 -> [(UnqualComponentName, CondTree ConfVar [Dependency] k)])
-> GenericPackageDescription
-> [UnqualComponentName]
-> Sem r (ComponentPkgList, ComponentPkgList)
collectRunnableDeps GenericPackageDescription
-> [(UnqualComponentName, CondTree ConfVar [Dependency] k)]
f GenericPackageDescription
cabal [UnqualComponentName]
skip = do
  let exes :: [(UnqualComponentName, CondTree ConfVar [Dependency] k)]
exes = GenericPackageDescription
cabal GenericPackageDescription
-> (GenericPackageDescription
    -> [(UnqualComponentName, CondTree ConfVar [Dependency] k)])
-> [(UnqualComponentName, CondTree ConfVar [Dependency] k)]
forall a b. a -> (a -> b) -> b
& GenericPackageDescription
-> [(UnqualComponentName, CondTree ConfVar [Dependency] k)]
f
      name :: PackageName
name = GenericPackageDescription -> PackageName
getPkgName' GenericPackageDescription
cabal
  [(UnqualComponentName, BuildInfo)]
info <- ((UnqualComponentName, BuildInfo) -> Bool)
-> [(UnqualComponentName, BuildInfo)]
-> [(UnqualComponentName, BuildInfo)]
forall a. (a -> Bool) -> [a] -> [a]
filter (Bool -> Bool
not (Bool -> Bool)
-> ((UnqualComponentName, BuildInfo) -> Bool)
-> (UnqualComponentName, BuildInfo)
-> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (UnqualComponentName -> [UnqualComponentName] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [UnqualComponentName]
skip) (UnqualComponentName -> Bool)
-> ((UnqualComponentName, BuildInfo) -> UnqualComponentName)
-> (UnqualComponentName, BuildInfo)
-> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (UnqualComponentName, BuildInfo) -> UnqualComponentName
forall a b. (a, b) -> a
fst) ([(UnqualComponentName, BuildInfo)]
 -> [(UnqualComponentName, BuildInfo)])
-> ([BuildInfo] -> [(UnqualComponentName, BuildInfo)])
-> [BuildInfo]
-> [(UnqualComponentName, BuildInfo)]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [UnqualComponentName]
-> [BuildInfo] -> [(UnqualComponentName, BuildInfo)]
forall a b. [a] -> [b] -> [(a, b)]
zip ([(UnqualComponentName, CondTree ConfVar [Dependency] k)]
exes [(UnqualComponentName, CondTree ConfVar [Dependency] k)]
-> ((UnqualComponentName, CondTree ConfVar [Dependency] k)
    -> UnqualComponentName)
-> [UnqualComponentName]
forall (f :: * -> *) a b. Functor f => f a -> (a -> b) -> f b
<&> (UnqualComponentName, CondTree ConfVar [Dependency] k)
-> UnqualComponentName
forall a b. (a, b) -> a
fst) ([BuildInfo] -> [(UnqualComponentName, BuildInfo)])
-> Sem r [BuildInfo] -> Sem r [(UnqualComponentName, BuildInfo)]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ((UnqualComponentName, CondTree ConfVar [Dependency] k)
 -> Sem r BuildInfo)
-> [(UnqualComponentName, CondTree ConfVar [Dependency] k)]
-> Sem r [BuildInfo]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM (GenericPackageDescription
-> CondTree ConfVar [Dependency] k -> Sem r BuildInfo
forall k (r :: [Effect]).
(Semigroup k, HasBuildInfo k, Member FlagAssignmentsEnv r) =>
GenericPackageDescription
-> CondTree ConfVar [Dependency] k -> Sem r BuildInfo
evalConditionTree GenericPackageDescription
cabal (CondTree ConfVar [Dependency] k -> Sem r BuildInfo)
-> ((UnqualComponentName, CondTree ConfVar [Dependency] k)
    -> CondTree ConfVar [Dependency] k)
-> (UnqualComponentName, CondTree ConfVar [Dependency] k)
-> Sem r BuildInfo
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (UnqualComponentName, CondTree ConfVar [Dependency] k)
-> CondTree ConfVar [Dependency] k
forall a b. (a, b) -> b
snd) [(UnqualComponentName, CondTree ConfVar [Dependency] k)]
exes
  let runnableDeps :: [(UnqualComponentName, [(PackageName, VersionRange)])]
runnableDeps = [(UnqualComponentName, BuildInfo)]
info [(UnqualComponentName, BuildInfo)]
-> ((UnqualComponentName, BuildInfo)
    -> (UnqualComponentName, [(PackageName, VersionRange)]))
-> [(UnqualComponentName, [(PackageName, VersionRange)])]
forall (f :: * -> *) a b. Functor f => f a -> (a -> b) -> f b
<&> (((BuildInfo -> Identity [(PackageName, VersionRange)])
-> (UnqualComponentName, BuildInfo)
-> Identity (UnqualComponentName, [(PackageName, VersionRange)])
forall s t a b. Field2 s t a b => Lens s t a b
_2 ((BuildInfo -> Identity [(PackageName, VersionRange)])
 -> (UnqualComponentName, BuildInfo)
 -> Identity (UnqualComponentName, [(PackageName, VersionRange)]))
-> (BuildInfo -> [(PackageName, VersionRange)])
-> (UnqualComponentName, BuildInfo)
-> (UnqualComponentName, [(PackageName, VersionRange)])
forall s t a b. ASetter s t a b -> (a -> b) -> s -> t
%~) ((BuildInfo -> [(PackageName, VersionRange)])
 -> (UnqualComponentName, BuildInfo)
 -> (UnqualComponentName, [(PackageName, VersionRange)]))
-> (BuildInfo -> [(PackageName, VersionRange)])
-> (UnqualComponentName, BuildInfo)
-> (UnqualComponentName, [(PackageName, VersionRange)])
forall a b. (a -> b) -> a -> b
$ (Dependency -> (PackageName, VersionRange))
-> [Dependency] -> [(PackageName, VersionRange)]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Dependency -> (PackageName, VersionRange)
unDepV ([Dependency] -> [(PackageName, VersionRange)])
-> (BuildInfo -> [Dependency])
-> BuildInfo
-> [(PackageName, VersionRange)]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. BuildInfo -> [Dependency]
buildDependsIfBuild)
      toolDeps :: [(UnqualComponentName, [(PackageName, VersionRange)])]
toolDeps = [(UnqualComponentName, BuildInfo)]
info [(UnqualComponentName, BuildInfo)]
-> ((UnqualComponentName, BuildInfo)
    -> (UnqualComponentName, [(PackageName, VersionRange)]))
-> [(UnqualComponentName, [(PackageName, VersionRange)])]
forall (f :: * -> *) a b. Functor f => f a -> (a -> b) -> f b
<&> (((BuildInfo -> Identity [(PackageName, VersionRange)])
-> (UnqualComponentName, BuildInfo)
-> Identity (UnqualComponentName, [(PackageName, VersionRange)])
forall s t a b. Field2 s t a b => Lens s t a b
_2 ((BuildInfo -> Identity [(PackageName, VersionRange)])
 -> (UnqualComponentName, BuildInfo)
 -> Identity (UnqualComponentName, [(PackageName, VersionRange)]))
-> (BuildInfo -> [(PackageName, VersionRange)])
-> (UnqualComponentName, BuildInfo)
-> (UnqualComponentName, [(PackageName, VersionRange)])
forall s t a b. ASetter s t a b -> (a -> b) -> s -> t
%~) ((BuildInfo -> [(PackageName, VersionRange)])
 -> (UnqualComponentName, BuildInfo)
 -> (UnqualComponentName, [(PackageName, VersionRange)]))
-> (BuildInfo -> [(PackageName, VersionRange)])
-> (UnqualComponentName, BuildInfo)
-> (UnqualComponentName, [(PackageName, VersionRange)])
forall a b. (a -> b) -> a -> b
$ (ExeDependency -> (PackageName, VersionRange))
-> [ExeDependency] -> [(PackageName, VersionRange)]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ExeDependency -> (PackageName, VersionRange)
unExeV ([ExeDependency] -> [(PackageName, VersionRange)])
-> (BuildInfo -> [ExeDependency])
-> BuildInfo
-> [(PackageName, VersionRange)]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. BuildInfo -> [ExeDependency]
buildToolDependsIfBuild)
      k :: [(a, [(b, b)])] -> [(a, [b])]
k = ((a, [(b, b)]) -> (a, [b])) -> [(a, [(b, b)])] -> [(a, [b])]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (\(a
c, [(b, b)]
l) -> (a
c, ((b, b) -> b) -> [(b, b)] -> [b]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (b, b) -> b
forall a b. (a, b) -> a
fst [(b, b)]
l))
  ([(PackageName, VersionRange)] -> Sem r ())
-> [[(PackageName, VersionRange)]] -> Sem r ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ (PackageName -> [(PackageName, VersionRange)] -> Sem r ()
forall (r :: [Effect]).
Member DependencyRecord r =>
PackageName -> [(PackageName, VersionRange)] -> Sem r ()
updateDependencyRecord PackageName
name) ([[(PackageName, VersionRange)]] -> Sem r ())
-> [[(PackageName, VersionRange)]] -> Sem r ()
forall a b. (a -> b) -> a -> b
$ ((UnqualComponentName, [(PackageName, VersionRange)])
 -> [(PackageName, VersionRange)])
-> [(UnqualComponentName, [(PackageName, VersionRange)])]
-> [[(PackageName, VersionRange)]]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (UnqualComponentName, [(PackageName, VersionRange)])
-> [(PackageName, VersionRange)]
forall a b. (a, b) -> b
snd [(UnqualComponentName, [(PackageName, VersionRange)])]
runnableDeps
  ([(PackageName, VersionRange)] -> Sem r ())
-> [[(PackageName, VersionRange)]] -> Sem r ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ (PackageName -> [(PackageName, VersionRange)] -> Sem r ()
forall (r :: [Effect]).
Member DependencyRecord r =>
PackageName -> [(PackageName, VersionRange)] -> Sem r ()
updateDependencyRecord PackageName
name) ([[(PackageName, VersionRange)]] -> Sem r ())
-> [[(PackageName, VersionRange)]] -> Sem r ()
forall a b. (a -> b) -> a -> b
$ ((UnqualComponentName, [(PackageName, VersionRange)])
 -> [(PackageName, VersionRange)])
-> [(UnqualComponentName, [(PackageName, VersionRange)])]
-> [[(PackageName, VersionRange)]]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (UnqualComponentName, [(PackageName, VersionRange)])
-> [(PackageName, VersionRange)]
forall a b. (a, b) -> b
snd [(UnqualComponentName, [(PackageName, VersionRange)])]
toolDeps
  (ComponentPkgList, ComponentPkgList)
-> Sem r (ComponentPkgList, ComponentPkgList)
forall (m :: * -> *) a. Monad m => a -> m a
return ([(UnqualComponentName, [(PackageName, VersionRange)])]
-> ComponentPkgList
forall a b b. [(a, [(b, b)])] -> [(a, [b])]
k [(UnqualComponentName, [(PackageName, VersionRange)])]
runnableDeps, [(UnqualComponentName, [(PackageName, VersionRange)])]
-> ComponentPkgList
forall a b b. [(a, [(b, b)])] -> [(a, [b])]
k [(UnqualComponentName, [(PackageName, VersionRange)])]
toolDeps)

collectExeDeps :: Members [FlagAssignmentsEnv, DependencyRecord] r => GenericPackageDescription -> [UnqualComponentName] -> Sem r (ComponentPkgList, ComponentPkgList)
collectExeDeps :: GenericPackageDescription
-> [UnqualComponentName]
-> Sem r (ComponentPkgList, ComponentPkgList)
collectExeDeps = (GenericPackageDescription
 -> [(UnqualComponentName,
      CondTree ConfVar [Dependency] Executable)])
-> GenericPackageDescription
-> [UnqualComponentName]
-> Sem r (ComponentPkgList, ComponentPkgList)
forall k (r :: [Effect]).
(Semigroup k, HasBuildInfo k,
 Members '[FlagAssignmentsEnv, DependencyRecord] r) =>
(GenericPackageDescription
 -> [(UnqualComponentName, CondTree ConfVar [Dependency] k)])
-> GenericPackageDescription
-> [UnqualComponentName]
-> Sem r (ComponentPkgList, ComponentPkgList)
collectRunnableDeps GenericPackageDescription
-> [(UnqualComponentName,
     CondTree ConfVar [Dependency] Executable)]
condExecutables

collectTestDeps :: Members [FlagAssignmentsEnv, DependencyRecord] r => GenericPackageDescription -> [UnqualComponentName] -> Sem r (ComponentPkgList, ComponentPkgList)
collectTestDeps :: GenericPackageDescription
-> [UnqualComponentName]
-> Sem r (ComponentPkgList, ComponentPkgList)
collectTestDeps = (GenericPackageDescription
 -> [(UnqualComponentName,
      CondTree ConfVar [Dependency] TestSuite)])
-> GenericPackageDescription
-> [UnqualComponentName]
-> Sem r (ComponentPkgList, ComponentPkgList)
forall k (r :: [Effect]).
(Semigroup k, HasBuildInfo k,
 Members '[FlagAssignmentsEnv, DependencyRecord] r) =>
(GenericPackageDescription
 -> [(UnqualComponentName, CondTree ConfVar [Dependency] k)])
-> GenericPackageDescription
-> [UnqualComponentName]
-> Sem r (ComponentPkgList, ComponentPkgList)
collectRunnableDeps GenericPackageDescription
-> [(UnqualComponentName, CondTree ConfVar [Dependency] TestSuite)]
condTestSuites

updateDependencyRecord :: Member DependencyRecord r => PackageName -> [(PackageName, VersionRange)] -> Sem r ()
updateDependencyRecord :: PackageName -> [(PackageName, VersionRange)] -> Sem r ()
updateDependencyRecord PackageName
parent [(PackageName, VersionRange)]
deps = (Map PackageName [(PackageName, VersionRange)]
 -> Map PackageName [(PackageName, VersionRange)])
-> Sem r ()
forall s (r :: [Effect]).
Member (State s) r =>
(s -> s) -> Sem r ()
modify' ((Map PackageName [(PackageName, VersionRange)]
  -> Map PackageName [(PackageName, VersionRange)])
 -> Sem r ())
-> (Map PackageName [(PackageName, VersionRange)]
    -> Map PackageName [(PackageName, VersionRange)])
-> Sem r ()
forall a b. (a -> b) -> a -> b
$ ([(PackageName, VersionRange)]
 -> [(PackageName, VersionRange)] -> [(PackageName, VersionRange)])
-> PackageName
-> [(PackageName, VersionRange)]
-> Map PackageName [(PackageName, VersionRange)]
-> Map PackageName [(PackageName, VersionRange)]
forall k a. Ord k => (a -> a -> a) -> k -> a -> Map k a -> Map k a
Map.insertWith [(PackageName, VersionRange)]
-> [(PackageName, VersionRange)] -> [(PackageName, VersionRange)]
forall a. Semigroup a => a -> a -> a
(<>) PackageName
parent [(PackageName, VersionRange)]
deps

-- collectBenchMarkDeps :: Members [HackageEnv, FlagAssignmentEnv] r => GenericPackageDescription -> [UnqualComponentName] -> Sem r (ComponentPkgList, ComponentPkgList)
-- collectBenchMarkDeps = collectRunnableDeps condBenchmarks

-----------------------------------------------------------------------------

-- | Generate 'PkgBuild' for a 'SolvedPackage'.
cabalToPkgBuild :: Members [HackageEnv, FlagAssignmentsEnv, WithMyErr] r => SolvedPackage -> Sem r PkgBuild
cabalToPkgBuild :: SolvedPackage -> Sem r PkgBuild
cabalToPkgBuild SolvedPackage
pkg = do
  let name :: PackageName
name = SolvedPackage
pkg SolvedPackage
-> Getting PackageName SolvedPackage PackageName -> PackageName
forall s a. s -> Getting a s a -> a
^. Getting PackageName SolvedPackage PackageName
Lens' SolvedPackage PackageName
pkgName
  PackageDescription
cabal <- GenericPackageDescription -> PackageDescription
packageDescription (GenericPackageDescription -> PackageDescription)
-> Sem r GenericPackageDescription -> Sem r PackageDescription
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (PackageName -> Sem r GenericPackageDescription
forall (r :: [Effect]).
Members '[HackageEnv, WithMyErr] r =>
PackageName -> Sem r GenericPackageDescription
getLatestCabal PackageName
name)
  let _hkgName :: String
_hkgName = SolvedPackage
pkg SolvedPackage
-> Getting PackageName SolvedPackage PackageName -> PackageName
forall s a. s -> Getting a s a -> a
^. Getting PackageName SolvedPackage PackageName
Lens' SolvedPackage PackageName
pkgName PackageName -> (PackageName -> String) -> String
forall a b. a -> (a -> b) -> b
& PackageName -> String
unPackageName
      rawName :: String
rawName = String -> String
toLower' String
_hkgName
      _pkgName :: String
_pkgName = String -> (String -> String) -> Maybe String -> String
forall b a. b -> (a -> b) -> Maybe a -> b
maybe String
rawName String -> String
forall a. a -> a
id (Maybe String -> String) -> Maybe String -> String
forall a b. (a -> b) -> a -> b
$ String -> String -> Maybe String
forall a. Eq a => [a] -> [a] -> Maybe [a]
stripPrefix String
"haskell-" String
rawName
      _pkgVer :: String
_pkgVer = Version -> String
forall a. Pretty a => a -> String
prettyShow (Version -> String) -> Version -> String
forall a b. (a -> b) -> a -> b
$ PackageDescription -> Version
getPkgVersion PackageDescription
cabal
      _pkgDesc :: String
_pkgDesc = ShortText -> String
fromShortText (ShortText -> String) -> ShortText -> String
forall a b. (a -> b) -> a -> b
$ PackageDescription -> ShortText
synopsis PackageDescription
cabal
      getL :: License -> String
getL (License
NONE) = String
""
      getL (License LicenseExpression
e) = LicenseExpression -> String
getE LicenseExpression
e
      getE :: LicenseExpression -> String
getE (ELicense (ELicenseId LicenseId
x) Maybe LicenseExceptionId
_) = ArchLicense -> String
forall a. Show a => a -> String
show (ArchLicense -> String)
-> (LicenseId -> ArchLicense) -> LicenseId -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. LicenseId -> ArchLicense
mapLicense (LicenseId -> String) -> LicenseId -> String
forall a b. (a -> b) -> a -> b
$ LicenseId
x
      getE (ELicense (ELicenseIdPlus LicenseId
x) Maybe LicenseExceptionId
_) = ArchLicense -> String
forall a. Show a => a -> String
show (ArchLicense -> String)
-> (LicenseId -> ArchLicense) -> LicenseId -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. LicenseId -> ArchLicense
mapLicense (LicenseId -> String) -> LicenseId -> String
forall a b. (a -> b) -> a -> b
$ LicenseId
x
      getE (ELicense (ELicenseRef LicenseRef
x) Maybe LicenseExceptionId
_) = String
"custom:" String -> String -> String
forall a. Semigroup a => a -> a -> a
<> LicenseRef -> String
licenseRef LicenseRef
x
      getE (EAnd LicenseExpression
x LicenseExpression
y) = LicenseExpression -> String
getE LicenseExpression
x String -> String -> String
forall a. Semigroup a => a -> a -> a
<> String
" " String -> String -> String
forall a. Semigroup a => a -> a -> a
<> LicenseExpression -> String
getE LicenseExpression
y
      getE (EOr LicenseExpression
x LicenseExpression
y) = LicenseExpression -> String
getE LicenseExpression
x String -> String -> String
forall a. Semigroup a => a -> a -> a
<> String
" " String -> String -> String
forall a. Semigroup a => a -> a -> a
<> LicenseExpression -> String
getE LicenseExpression
y

      _license :: String
_license = License -> String
getL (License -> String)
-> (PackageDescription -> License) -> PackageDescription -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PackageDescription -> License
license (PackageDescription -> String) -> PackageDescription -> String
forall a b. (a -> b) -> a -> b
$ PackageDescription
cabal
      _enableCheck :: Bool
_enableCheck = (Bool -> Bool) -> [Bool] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
any Bool -> Bool
forall a. a -> a
id ([Bool] -> Bool) -> [Bool] -> Bool
forall a b. (a -> b) -> a -> b
$ SolvedPackage
pkg SolvedPackage
-> Getting [SolvedDependency] SolvedPackage [SolvedDependency]
-> [SolvedDependency]
forall s a. s -> Getting a s a -> a
^. Getting [SolvedDependency] SolvedPackage [SolvedDependency]
Traversal' SolvedPackage [SolvedDependency]
pkgDeps [SolvedDependency] -> ([SolvedDependency] -> [Bool]) -> [Bool]
forall a b. a -> (a -> b) -> b
& ASetter [SolvedDependency] [Bool] SolvedDependency Bool
forall (f :: * -> *) a b. Functor f => ASetter (f a) (f b) a b
mapped ASetter [SolvedDependency] [Bool] SolvedDependency Bool
-> (SolvedDependency -> Bool) -> [SolvedDependency] -> [Bool]
forall s t a b. ASetter s t a b -> (a -> b) -> s -> t
%~ (\SolvedDependency
dep -> DependencyKind -> SolvedDependency -> Bool
selectDepKind DependencyKind
Test SolvedDependency
dep Bool -> Bool -> Bool
&& SolvedDependency
dep SolvedDependency
-> Getting PackageName SolvedDependency PackageName -> PackageName
forall s a. s -> Getting a s a -> a
^. Getting PackageName SolvedDependency PackageName
Lens' SolvedDependency PackageName
depName PackageName -> PackageName -> Bool
forall a. Eq a => a -> a -> Bool
== SolvedPackage
pkg SolvedPackage
-> Getting PackageName SolvedPackage PackageName -> PackageName
forall s a. s -> Getting a s a -> a
^. Getting PackageName SolvedPackage PackageName
Lens' SolvedPackage PackageName
pkgName)
      depends :: [SolvedDependency]
depends = SolvedPackage
pkg SolvedPackage
-> Getting [SolvedDependency] SolvedPackage [SolvedDependency]
-> [SolvedDependency]
forall s a. s -> Getting a s a -> a
^. Getting [SolvedDependency] SolvedPackage [SolvedDependency]
Traversal' SolvedPackage [SolvedDependency]
pkgDeps [SolvedDependency]
-> Getting
     (Endo [SolvedDependency]) [SolvedDependency] SolvedDependency
-> [SolvedDependency]
forall s a. s -> Getting (Endo [a]) s a -> [a]
^.. Getting
  (Endo [SolvedDependency]) [SolvedDependency] SolvedDependency
forall s t a b. Each s t a b => Traversal s t a b
each Getting
  (Endo [SolvedDependency]) [SolvedDependency] SolvedDependency
-> ((SolvedDependency
     -> Const (Endo [SolvedDependency]) SolvedDependency)
    -> SolvedDependency
    -> Const (Endo [SolvedDependency]) SolvedDependency)
-> Getting
     (Endo [SolvedDependency]) [SolvedDependency] SolvedDependency
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (SolvedDependency -> Bool)
-> Traversal' SolvedDependency SolvedDependency
forall a. (a -> Bool) -> Traversal' a a
filtered (\SolvedDependency
x -> SolvedDependency -> Bool
notMyself SolvedDependency
x Bool -> Bool -> Bool
&& SolvedDependency -> Bool
notInGHCLib SolvedDependency
x Bool -> Bool -> Bool
&& (DependencyKind -> SolvedDependency -> Bool
selectDepKind DependencyKind
Lib SolvedDependency
x Bool -> Bool -> Bool
|| DependencyKind -> SolvedDependency -> Bool
selectDepKind DependencyKind
Exe SolvedDependency
x))
      makeDepends :: [SolvedDependency]
makeDepends =
        SolvedPackage
pkg SolvedPackage
-> Getting [SolvedDependency] SolvedPackage [SolvedDependency]
-> [SolvedDependency]
forall s a. s -> Getting a s a -> a
^. Getting [SolvedDependency] SolvedPackage [SolvedDependency]
Traversal' SolvedPackage [SolvedDependency]
pkgDeps
          [SolvedDependency]
-> Getting
     (Endo [SolvedDependency]) [SolvedDependency] SolvedDependency
-> [SolvedDependency]
forall s a. s -> Getting (Endo [a]) s a -> [a]
^.. Getting
  (Endo [SolvedDependency]) [SolvedDependency] SolvedDependency
forall s t a b. Each s t a b => Traversal s t a b
each
            Getting
  (Endo [SolvedDependency]) [SolvedDependency] SolvedDependency
-> ((SolvedDependency
     -> Const (Endo [SolvedDependency]) SolvedDependency)
    -> SolvedDependency
    -> Const (Endo [SolvedDependency]) SolvedDependency)
-> Getting
     (Endo [SolvedDependency]) [SolvedDependency] SolvedDependency
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (SolvedDependency -> Bool)
-> Traversal' SolvedDependency SolvedDependency
forall a. (a -> Bool) -> Traversal' a a
filtered
              ( \SolvedDependency
x ->
                  SolvedDependency
x SolvedDependency -> [SolvedDependency] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`notElem` [SolvedDependency]
depends
                    Bool -> Bool -> Bool
&& SolvedDependency -> Bool
notMyself SolvedDependency
x
                    Bool -> Bool -> Bool
&& SolvedDependency -> Bool
notInGHCLib SolvedDependency
x
                    Bool -> Bool -> Bool
&& ( DependencyKind -> SolvedDependency -> Bool
selectDepKind DependencyKind
LibBuildTools SolvedDependency
x
                           Bool -> Bool -> Bool
|| DependencyKind -> SolvedDependency -> Bool
selectDepKind DependencyKind
Test SolvedDependency
x
                           Bool -> Bool -> Bool
|| DependencyKind -> SolvedDependency -> Bool
selectDepKind DependencyKind
TestBuildTools SolvedDependency
x
                       )
              )
      depsToString :: [SolvedDependency] -> String
depsToString [SolvedDependency]
deps = [SolvedDependency]
deps [SolvedDependency] -> (SolvedDependency -> String) -> [String]
forall (f :: * -> *) a b. Functor f => f a -> (a -> b) -> f b
<&> (String -> String
wrap (String -> String)
-> (SolvedDependency -> String) -> SolvedDependency -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> String
fixName (String -> String)
-> (SolvedDependency -> String) -> SolvedDependency -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PackageName -> String
unPackageName (PackageName -> String)
-> (SolvedDependency -> PackageName) -> SolvedDependency -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. SolvedDependency -> PackageName
_depName) [String] -> ([String] -> String) -> String
forall a b. a -> (a -> b) -> b
& String -> [String] -> String
forall a. [a] -> [[a]] -> [a]
intercalate String
" "
      _depends :: String
_depends = [SolvedDependency] -> String
depsToString [SolvedDependency]
depends
      _makeDepends :: String
_makeDepends = [SolvedDependency] -> String
depsToString [SolvedDependency]
makeDepends
      _url :: String
_url = PackageDescription -> String
getUrl PackageDescription
cabal
      wrap :: String -> String
wrap String
s = Char
'\'' Char -> String -> String
forall a. a -> [a] -> [a]
: String
s String -> String -> String
forall a. Semigroup a => a -> a -> a
<> String
"\'"
      notInGHCLib :: SolvedDependency -> Bool
notInGHCLib SolvedDependency
x = (SolvedDependency
x SolvedDependency
-> Getting PackageName SolvedDependency PackageName -> PackageName
forall s a. s -> Getting a s a -> a
^. Getting PackageName SolvedDependency PackageName
Lens' SolvedDependency PackageName
depName) PackageName -> PkgList -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`notElem` PkgList
ghcLibList
      notMyself :: SolvedDependency -> Bool
notMyself SolvedDependency
x = SolvedDependency
x SolvedDependency
-> Getting PackageName SolvedDependency PackageName -> PackageName
forall s a. s -> Getting a s a -> a
^. Getting PackageName SolvedDependency PackageName
Lens' SolvedDependency PackageName
depName PackageName -> PackageName -> Bool
forall a. Eq a => a -> a -> Bool
/= PackageName
name
      selectDepKind :: DependencyKind -> SolvedDependency -> Bool
selectDepKind DependencyKind
k SolvedDependency
x = DependencyKind
k DependencyKind -> [DependencyKind] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` (SolvedDependency
x SolvedDependency
-> Getting [DependencyType] SolvedDependency [DependencyType]
-> [DependencyType]
forall s a. s -> Getting a s a -> a
^. Getting [DependencyType] SolvedDependency [DependencyType]
Lens' SolvedDependency [DependencyType]
depType [DependencyType]
-> ([DependencyType] -> [DependencyKind]) -> [DependencyKind]
forall a b. a -> (a -> b) -> b
& ASetter
  [DependencyType] [DependencyKind] DependencyType DependencyKind
forall (f :: * -> *) a b. Functor f => ASetter (f a) (f b) a b
mapped ASetter
  [DependencyType] [DependencyKind] DependencyType DependencyKind
-> (DependencyType -> DependencyKind)
-> [DependencyType]
-> [DependencyKind]
forall s t a b. ASetter s t a b -> (a -> b) -> s -> t
%~ DependencyType -> DependencyKind
dependencyTypeToKind)
  PkgBuild -> Sem r PkgBuild
forall (m :: * -> *) a. Monad m => a -> m a
return PkgBuild :: String
-> String
-> String
-> String
-> String
-> String
-> String
-> String
-> Bool
-> PkgBuild
PkgBuild {Bool
String
_enableCheck :: Bool
_makeDepends :: String
_depends :: String
_license :: String
_url :: String
_pkgDesc :: String
_pkgVer :: String
_pkgName :: String
_hkgName :: String
_url :: String
_makeDepends :: String
_depends :: String
_enableCheck :: Bool
_license :: String
_pkgDesc :: String
_pkgVer :: String
_pkgName :: String
_hkgName :: String
..}