{-# LANGUAGE RecordWildCards #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE ViewPatterns #-}

-- | Copyright: (c) 2020-2021 berberman
-- SPDX-License-Identifier: MIT
-- Maintainer: berberman <berberman@yandex.com>
-- Stability: experimental
-- Portability: portable
-- The core functions of @arch-hs@.
module Distribution.ArchHs.Core
  ( getDependencies,
    cabalToPkgBuild,
    evalConditionTree,
    subsumeGHCVersion,

    -- * Helper functions
    collectLibDeps,
    collectExeDeps,
    collectTestDeps,
    collectSubLibDeps,
    collectSetupDeps,
  )
where

import qualified Algebra.Graph.Labelled.AdjacencyMap as G
import Data.Bifunctor (second)
import Data.Containers.ListUtils (nubOrd)
import qualified Data.Map as Map
import Data.Maybe (fromMaybe)
import Data.Set (Set)
import qualified Data.Set as Set
import Distribution.ArchHs.ExtraDB (versionInExtra)
import Distribution.ArchHs.Exception
import Distribution.ArchHs.Hackage
  ( getLatestCabal,
    getLatestSHA256,
    getPackageFlag,
  )
import Distribution.ArchHs.Internal.Prelude
import Distribution.ArchHs.Local (ignoreList)
import Distribution.ArchHs.Name
import Distribution.ArchHs.PkgBuild
  ( PkgBuild (..),
    mapLicense,
    showArchLicense,
  )
import Distribution.ArchHs.Types
import Distribution.ArchHs.Utils
import Distribution.Compiler (CompilerFlavor (..))
import Distribution.PackageDescription hiding (pkgName)
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.Utils.ShortText (fromShortText)

archEnv :: Version -> FlagAssignment -> ConfVar -> Either ConfVar Bool
archEnv :: Version -> FlagAssignment -> ConfVar -> Either ConfVar Bool
archEnv Version
_ FlagAssignment
_ (OS OS
Linux) = forall a b. b -> Either a b
Right Bool
True
archEnv Version
_ FlagAssignment
_ (OS OS
_) = forall a b. b -> Either a b
Right Bool
False
archEnv Version
_ FlagAssignment
_ (Arch Arch
X86_64) = forall a b. b -> Either a b
Right Bool
True
archEnv Version
_ FlagAssignment
_ (Arch Arch
_) = forall a b. b -> Either a b
Right Bool
False
archEnv Version
ghcVersion FlagAssignment
_ (Impl CompilerFlavor
GHC VersionRange
range) = forall a b. b -> Either a b
Right forall a b. (a -> b) -> a -> b
$ Version -> VersionRange -> Bool
withinRange Version
ghcVersion VersionRange
range
archEnv Version
_ FlagAssignment
_ (Impl CompilerFlavor
_ VersionRange
_) = forall a b. b -> Either a b
Right Bool
False
archEnv Version
_ FlagAssignment
assignment f :: ConfVar
f@(PkgFlag FlagName
f') = forall {a} {b}. a -> Maybe b -> Either a b
go ConfVar
f 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) = forall a b. b -> Either a b
Right b
r
    go a
x Maybe b
Nothing = 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 ::
  (HasCallStack, Semigroup k, L.HasBuildInfo k, Members [KnownGHCVersion, FlagAssignmentsEnv, Trace] r) =>
  GenericPackageDescription ->
  CondTree ConfVar [Dependency] k ->
  Sem r BuildInfo
evalConditionTree :: forall k (r :: EffectRow).
(HasCallStack, Semigroup k, HasBuildInfo k,
 Members '[KnownGHCVersion, FlagAssignmentsEnv, Trace] r) =>
GenericPackageDescription
-> CondTree ConfVar [Dependency] k -> Sem r BuildInfo
evalConditionTree GenericPackageDescription
cabal CondTree ConfVar [Dependency] k
cond = do
  FlagAssignments
flagAssignments <- forall i (r :: EffectRow). Member (Reader i) r => Sem r i
ask
  let name :: PackageName
name = GenericPackageDescription -> PackageName
getPkgName' GenericPackageDescription
cabal
      packageFlags :: [PackageFlag]
packageFlags = GenericPackageDescription -> [PackageFlag]
genPackageFlags GenericPackageDescription
cabal
      flagAssignment :: FlagAssignment
flagAssignment = PackageName -> FlagAssignments -> FlagAssignment
getFlagAssignment PackageName
name FlagAssignments
flagAssignments
      thisFlag :: FlagAssignment
thisFlag = [PackageFlag] -> FlagAssignment -> FlagAssignment
defaultFlags [PackageFlag]
packageFlags FlagAssignment
flagAssignment
  forall (r :: EffectRow). Member Trace r => String -> Sem r ()
trace' forall a b. (a -> b) -> a -> b
$ String
"Evaluating condition tree of " forall a. Semigroup a => a -> a -> a
<> forall a. Show a => a -> String
show PackageName
name
  forall (r :: EffectRow). Member Trace r => String -> Sem r ()
trace' forall a b. (a -> b) -> a -> b
$ String
"Flags: " forall a. Semigroup a => a -> a -> a
<> forall a. Show a => a -> String
show FlagAssignment
thisFlag
  forall (r :: EffectRow). (HasCallStack, Member Trace r) => Sem r ()
traceCallStack
  Version
ghcVersion <- forall i (r :: EffectRow). Member (Reader i) r => Sem r i
ask
  forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ (forall s a. s -> Getting a s a -> a
^. forall a. HasBuildInfo a => Lens' a BuildInfo
L.buildInfo) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (a, b) -> b
snd forall a b. (a -> b) -> a -> b
$ forall a d v.
(Semigroup a, Semigroup d) =>
(v -> Either v Bool) -> CondTree v d a -> (d, a)
simplifyCondTree (Version -> FlagAssignment -> ConfVar -> Either ConfVar Bool
archEnv Version
ghcVersion 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 ::
  (HasCallStack, Members [KnownGHCVersion, HackageEnv, FlagAssignmentsEnv, WithMyErr, DependencyRecord, State (Set PackageName), Trace] r) =>
  -- | Skipped
  [UnqualComponentName] ->
  -- | Parent
  Maybe PackageName ->
  -- | Target
  PackageName ->
  Sem r (G.AdjacencyMap (Set DependencyType) PackageName, Set PackageName, Map.Map PackageName [SystemDependency])
getDependencies :: forall (r :: EffectRow).
(HasCallStack,
 Members
   '[KnownGHCVersion, HackageEnv, FlagAssignmentsEnv, WithMyErr,
     DependencyRecord, State (Set PackageName), Trace]
   r) =>
[UnqualComponentName]
-> Maybe PackageName
-> PackageName
-> Sem
     r
     (AdjacencyMap (Set DependencyType) PackageName, Set PackageName,
      Map PackageName [SystemDependency])
getDependencies [UnqualComponentName]
skip Maybe PackageName
parent PackageName
name = do
  Set PackageName
resolved <- forall s (r :: EffectRow). Member (State s) r => Sem r s
get @(Set PackageName)
  forall s (r :: EffectRow).
Member (State s) r =>
(s -> s) -> Sem r ()
modify' forall a b. (a -> b) -> a -> b
$ forall a. Ord a => a -> Set a -> Set a
Set.insert PackageName
name
  forall (r :: EffectRow). Member Trace r => String -> Sem r ()
trace' forall a b. (a -> b) -> a -> b
$ String
"Getting all dependencies of (" forall a. Semigroup a => a -> a -> a
<> forall a. Show a => a -> String
show PackageName
name forall a. Semigroup a => a -> a -> a
<> String
"), parent: (" forall a. Semigroup a => a -> a -> a
<> forall a. Show a => a -> String
show Maybe PackageName
parent forall a. Semigroup a => a -> a -> a
<> String
")"
  forall (r :: EffectRow). Member Trace r => String -> Sem r ()
trace' forall a b. (a -> b) -> a -> b
$ String
"Already resolved: " forall a. Semigroup a => a -> a -> a
<> forall a. Show a => a -> String
show Set PackageName
resolved
  forall (r :: EffectRow). (HasCallStack, Member Trace r) => Sem r ()
traceCallStack
  GenericPackageDescription
cabal <- forall (r :: EffectRow).
Members '[HackageEnv, WithMyErr] r =>
PackageName -> Sem r GenericPackageDescription
getLatestCabal PackageName
name
  let kIgnoreVersionLib :: [(b, b)] -> [b]
kIgnoreVersionLib = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall a b. (a, b) -> a
fst
      kIgnoreVersionComp :: [(a, [(b, b)])] -> [(a, [b])]
kIgnoreVersionComp = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (forall (p :: * -> * -> *) b c a.
Bifunctor p =>
(b -> c) -> p a b -> p a c
second forall a b. (a -> b) -> a -> b
$ forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall a b. (a, b) -> a
fst)
      kIgnoreVersionSetup :: [(PackageName, VersionRange)] -> [PackageName]
kIgnoreVersionSetup = forall {b} {b}. [(b, b)] -> [b]
kIgnoreVersionLib
  ([PackageName]
libDeps, [PackageName]
libToolsDeps, [SystemDependency]
libSysDeps) <- forall (r :: EffectRow) a.
(Members
   '[KnownGHCVersion, FlagAssignmentsEnv, DependencyRecord, Trace] r,
 Show a, Monoid a) =>
([(PackageName, VersionRange)] -> a)
-> GenericPackageDescription -> Sem r (a, a, [SystemDependency])
collectLibDeps forall {b} {b}. [(b, b)] -> [b]
kIgnoreVersionLib GenericPackageDescription
cabal
  ([(UnqualComponentName, [PackageName])]
subLibDeps, [(UnqualComponentName, [PackageName])]
subLibToolsDeps, [SystemDependency]
subLibSysDeps) <- forall (r :: EffectRow) a.
(HasCallStack,
 Members
   '[KnownGHCVersion, FlagAssignmentsEnv, DependencyRecord, Trace] r,
 Show a) =>
([(UnqualComponentName, [(PackageName, VersionRange)])] -> a)
-> GenericPackageDescription
-> [UnqualComponentName]
-> Sem r (a, a, [SystemDependency])
collectSubLibDeps forall {a} {b} {b}. [(a, [(b, b)])] -> [(a, [b])]
kIgnoreVersionComp GenericPackageDescription
cabal [UnqualComponentName]
skip
  ([(UnqualComponentName, [PackageName])]
exeDeps, [(UnqualComponentName, [PackageName])]
exeToolsDeps, [SystemDependency]
exeSysDeps) <- forall (r :: EffectRow) a.
(HasCallStack,
 Members
   '[KnownGHCVersion, FlagAssignmentsEnv, DependencyRecord, Trace] r,
 Show a) =>
([(UnqualComponentName, [(PackageName, VersionRange)])] -> a)
-> GenericPackageDescription
-> [UnqualComponentName]
-> Sem r (a, a, [SystemDependency])
collectExeDeps forall {a} {b} {b}. [(a, [(b, b)])] -> [(a, [b])]
kIgnoreVersionComp GenericPackageDescription
cabal [UnqualComponentName]
skip
  ([(UnqualComponentName, [PackageName])]
testDeps, [(UnqualComponentName, [PackageName])]
testToolsDeps, [SystemDependency]
testSysDeps) <- forall (r :: EffectRow) a.
(HasCallStack,
 Members
   '[KnownGHCVersion, FlagAssignmentsEnv, DependencyRecord, Trace] r,
 Show a) =>
([(UnqualComponentName, [(PackageName, VersionRange)])] -> a)
-> GenericPackageDescription
-> [UnqualComponentName]
-> Sem r (a, a, [SystemDependency])
collectTestDeps forall {a} {b} {b}. [(a, [(b, b)])] -> [(a, [b])]
kIgnoreVersionComp GenericPackageDescription
cabal [UnqualComponentName]
skip
  [PackageName]
setupDeps <- forall (r :: EffectRow) a.
(Member Trace r, Show a, Monoid a) =>
([(PackageName, VersionRange)] -> a)
-> GenericPackageDescription -> Sem r a
collectSetupDeps [(PackageName, VersionRange)] -> [PackageName]
kIgnoreVersionSetup GenericPackageDescription
cabal
  -- Ignore benchmarks
  -- (benchDeps, benchToolsDeps) <- collectBenchMarkDeps cabal skip
  let uname :: (UnqualComponentName -> DependencyType) -> ComponentPkgList -> [(DependencyType, PkgList)]
      uname :: (UnqualComponentName -> DependencyType)
-> [(UnqualComponentName, [PackageName])]
-> [(DependencyType, [PackageName])]
uname UnqualComponentName -> DependencyType
cons [(UnqualComponentName, [PackageName])]
list = forall a b. [a] -> [b] -> [(a, b)]
zip (forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (UnqualComponentName -> DependencyType
cons forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (a, b) -> a
fst) [(UnqualComponentName, [PackageName])]
list) (forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall a b. (a, b) -> b
snd [(UnqualComponentName, [PackageName])]
list)

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

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

      ignoreSingle :: PackageName -> Bool
ignoreSingle PackageName
x = PackageName
x forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`notElem` [PackageName]
ignoreList
      ignore :: [PackageName] -> [PackageName]
ignore = forall a. (a -> Bool) -> [a] -> [a]
filter PackageName -> Bool
ignoreSingle
      ignoreFlatten :: (UnqualComponentName -> DependencyType)
-> [(UnqualComponentName, [PackageName])]
-> [(DependencyType, PackageName)]
ignoreFlatten UnqualComponentName -> DependencyType
k = forall a. (a -> Bool) -> [a] -> [a]
filter (\(DependencyType
_, PackageName
x) -> PackageName -> Bool
ignoreSingle PackageName
x) forall b c a. (b -> c) -> (a -> b) -> a -> c
. [(DependencyType, [PackageName])]
-> [(DependencyType, PackageName)]
flatten forall b c a. (b -> c) -> (a -> b) -> a -> c
. (UnqualComponentName -> DependencyType)
-> [(UnqualComponentName, [PackageName])]
-> [(DependencyType, [PackageName])]
uname UnqualComponentName -> DependencyType
k

      filteredLibDeps :: [PackageName]
filteredLibDeps = [PackageName] -> [PackageName]
ignore [PackageName]
libDeps
      filteredLibToolsDeps :: [PackageName]
filteredLibToolsDeps = [PackageName] -> [PackageName]
ignore [PackageName]
libToolsDeps
      filteredExeDeps :: [(DependencyType, PackageName)]
filteredExeDeps = (UnqualComponentName -> DependencyType)
-> [(UnqualComponentName, [PackageName])]
-> [(DependencyType, PackageName)]
ignoreFlatten UnqualComponentName -> DependencyType
CExe [(UnqualComponentName, [PackageName])]
exeDeps
      filteredExeToolsDeps :: [(DependencyType, PackageName)]
filteredExeToolsDeps = (UnqualComponentName -> DependencyType)
-> [(UnqualComponentName, [PackageName])]
-> [(DependencyType, PackageName)]
ignoreFlatten UnqualComponentName -> DependencyType
CExeBuildTools [(UnqualComponentName, [PackageName])]
exeToolsDeps
      filteredTestDeps :: [(DependencyType, PackageName)]
filteredTestDeps = (UnqualComponentName -> DependencyType)
-> [(UnqualComponentName, [PackageName])]
-> [(DependencyType, PackageName)]
ignoreFlatten UnqualComponentName -> DependencyType
CTest [(UnqualComponentName, [PackageName])]
testDeps
      filteredTestToolsDeps :: [(DependencyType, PackageName)]
filteredTestToolsDeps = (UnqualComponentName -> DependencyType)
-> [(UnqualComponentName, [PackageName])]
-> [(DependencyType, PackageName)]
ignoreFlatten UnqualComponentName -> DependencyType
CTest [(UnqualComponentName, [PackageName])]
testToolsDeps
      filteredSubLibDeps :: [(DependencyType, PackageName)]
filteredSubLibDeps = (UnqualComponentName -> DependencyType)
-> [(UnqualComponentName, [PackageName])]
-> [(DependencyType, PackageName)]
ignoreFlatten UnqualComponentName -> DependencyType
CSubLibs [(UnqualComponentName, [PackageName])]
subLibDeps
      filteredSubLibToolsDeps :: [(DependencyType, PackageName)]
filteredSubLibToolsDeps = (UnqualComponentName -> DependencyType)
-> [(UnqualComponentName, [PackageName])]
-> [(DependencyType, PackageName)]
ignoreFlatten UnqualComponentName -> DependencyType
CSubLibsBuildTools [(UnqualComponentName, [PackageName])]
subLibToolsDeps
      filteredSetupDeps :: [PackageName]
filteredSetupDeps = [PackageName] -> [PackageName]
ignore [PackageName]
setupDeps

      filteredSubLibDepsNames :: [PackageName]
filteredSubLibDepsNames = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (UnqualComponentName -> PackageName
unqualComponentNameToPackageName forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (a, b) -> a
fst) [(UnqualComponentName, [PackageName])]
subLibDeps
      ignoreSubLibs :: [PackageName] -> [PackageName]
ignoreSubLibs = forall a. (a -> Bool) -> [a] -> [a]
filter (forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`notElem` [PackageName]
filteredSubLibDepsNames)
      ignoreResolved :: [PackageName] -> [PackageName]
ignoreResolved = forall a. (a -> Bool) -> [a] -> [a]
filter (forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`notElem` Set PackageName
resolved)

      currentLib :: AdjacencyMap (Set DependencyType) PackageName
currentLib = forall e a.
(Eq e, Monoid e, Ord a) =>
[(e, a, a)] -> AdjacencyMap e a
G.edges forall a b. (a -> b) -> a -> b
$ forall a b c. [a] -> [b] -> [c] -> [(a, b, c)]
zip3 (forall a. a -> [a]
repeat forall a b. (a -> b) -> a -> b
$ forall a. a -> Set a
Set.singleton DependencyType
CLib) (forall a. a -> [a]
repeat PackageName
name) [PackageName]
filteredLibDeps
      currentLibToolDeps :: AdjacencyMap (Set DependencyType) PackageName
currentLibToolDeps = forall e a.
(Eq e, Monoid e, Ord a) =>
[(e, a, a)] -> AdjacencyMap e a
G.edges forall a b. (a -> b) -> a -> b
$ forall a b c. [a] -> [b] -> [c] -> [(a, b, c)]
zip3 (forall a. a -> [a]
repeat forall a b. (a -> b) -> a -> b
$ forall a. a -> Set a
Set.singleton DependencyType
CLibBuildTools) (forall a. a -> [a]
repeat PackageName
name) [PackageName]
filteredLibToolsDeps
      currentSetupDeps :: AdjacencyMap (Set DependencyType) PackageName
currentSetupDeps = forall e a.
(Eq e, Monoid e, Ord a) =>
[(e, a, a)] -> AdjacencyMap e a
G.edges forall a b. (a -> b) -> a -> b
$ forall a b c. [a] -> [b] -> [c] -> [(a, b, c)]
zip3 (forall a. a -> [a]
repeat forall a b. (a -> b) -> a -> b
$ forall a. a -> Set a
Set.singleton DependencyType
CSetup) (forall a. a -> [a]
repeat PackageName
name) [PackageName]
filteredSetupDeps

      componentialEdges :: [(DependencyType, PackageName)]
-> AdjacencyMap (Set DependencyType) PackageName
componentialEdges =
        forall e a.
(Eq e, Monoid e, Ord a) =>
[(e, a, a)] -> AdjacencyMap e a
G.edges
          forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (\(DependencyType
x, PackageName
y, PackageName
z) -> (forall a. a -> Set a
Set.singleton DependencyType
x, PackageName
y, PackageName
z))
          forall b c a. (b -> c) -> (a -> b) -> a -> c
. [(DependencyType, PackageName)]
-> [(DependencyType, PackageName, PackageName)]
withThisName

      currentSubLibs :: AdjacencyMap (Set DependencyType) PackageName
currentSubLibs = [(DependencyType, PackageName)]
-> AdjacencyMap (Set DependencyType) PackageName
componentialEdges [(DependencyType, PackageName)]
filteredSubLibDeps
      currentSubLibsTools :: AdjacencyMap (Set DependencyType) PackageName
currentSubLibsTools = [(DependencyType, PackageName)]
-> AdjacencyMap (Set DependencyType) PackageName
componentialEdges [(DependencyType, PackageName)]
filteredSubLibToolsDeps
      currentExe :: AdjacencyMap (Set DependencyType) PackageName
currentExe = [(DependencyType, PackageName)]
-> AdjacencyMap (Set DependencyType) PackageName
componentialEdges [(DependencyType, PackageName)]
filteredExeDeps
      currentExeTools :: AdjacencyMap (Set DependencyType) PackageName
currentExeTools = [(DependencyType, PackageName)]
-> AdjacencyMap (Set DependencyType) PackageName
componentialEdges [(DependencyType, PackageName)]
filteredExeToolsDeps
      currentTest :: AdjacencyMap (Set DependencyType) PackageName
currentTest = [(DependencyType, PackageName)]
-> AdjacencyMap (Set DependencyType) PackageName
componentialEdges [(DependencyType, PackageName)]
filteredTestDeps
      currentTestTools :: AdjacencyMap (Set DependencyType) PackageName
currentTestTools = [(DependencyType, PackageName)]
-> AdjacencyMap (Set DependencyType) PackageName
componentialEdges [(DependencyType, PackageName)]
filteredTestToolsDeps

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

      currentSysDeps :: [SystemDependency]
currentSysDeps = forall a. Ord a => [a] -> [a]
nubOrd forall a b. (a -> b) -> a -> b
$ [SystemDependency]
libSysDeps forall a. Semigroup a => a -> a -> a
<> [SystemDependency]
subLibSysDeps forall a. Semigroup a => a -> a -> a
<> [SystemDependency]
exeSysDeps forall a. Semigroup a => a -> a -> a
<> [SystemDependency]
testSysDeps
      processNext :: [PackageName]
-> Sem
     r
     [(AdjacencyMap (Set DependencyType) PackageName, Set PackageName,
       Map PackageName [SystemDependency])]
processNext = forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM (forall (r :: EffectRow).
(HasCallStack,
 Members
   '[KnownGHCVersion, HackageEnv, FlagAssignmentsEnv, WithMyErr,
     DependencyRecord, State (Set PackageName), Trace]
   r) =>
[UnqualComponentName]
-> Maybe PackageName
-> PackageName
-> Sem
     r
     (AdjacencyMap (Set DependencyType) PackageName, Set PackageName,
      Map PackageName [SystemDependency])
getDependencies [UnqualComponentName]
skip (forall a. a -> Maybe a
Just PackageName
name)) forall b c a. (b -> c) -> (a -> b) -> a -> c
. [PackageName] -> [PackageName]
ignoreResolved forall b c a. (b -> c) -> (a -> b) -> a -> c
. [PackageName] -> [PackageName]
ignoreSubLibs
      <+> :: 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
  [(AdjacencyMap (Set DependencyType) PackageName, Set PackageName,
  Map PackageName [SystemDependency])]
nextLib <- [PackageName]
-> Sem
     r
     [(AdjacencyMap (Set DependencyType) PackageName, Set PackageName,
       Map PackageName [SystemDependency])]
processNext [PackageName]
filteredLibDeps
  [(AdjacencyMap (Set DependencyType) PackageName, Set PackageName,
  Map PackageName [SystemDependency])]
nextSetup <- [PackageName]
-> Sem
     r
     [(AdjacencyMap (Set DependencyType) PackageName, Set PackageName,
       Map PackageName [SystemDependency])]
processNext [PackageName]
filteredSetupDeps
  [(AdjacencyMap (Set DependencyType) PackageName, Set PackageName,
  Map PackageName [SystemDependency])]
nextExe <- [PackageName]
-> Sem
     r
     [(AdjacencyMap (Set DependencyType) PackageName, Set PackageName,
       Map PackageName [SystemDependency])]
processNext forall a b. (a -> b) -> a -> b
$ forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall a b. (a, b) -> b
snd [(DependencyType, PackageName)]
filteredExeDeps
  -- TODO: maybe unstable
  [(AdjacencyMap (Set DependencyType) PackageName, Set PackageName,
  Map PackageName [SystemDependency])]
nextTest <- [PackageName]
-> Sem
     r
     [(AdjacencyMap (Set DependencyType) PackageName, Set PackageName,
       Map PackageName [SystemDependency])]
processNext forall a b. (a -> b) -> a -> b
$ forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall a b. (a, b) -> b
snd [(DependencyType, PackageName)]
filteredTestDeps
  [(AdjacencyMap (Set DependencyType) PackageName, Set PackageName,
  Map PackageName [SystemDependency])]
nextSubLibs <- [PackageName]
-> Sem
     r
     [(AdjacencyMap (Set DependencyType) PackageName, Set PackageName,
       Map PackageName [SystemDependency])]
processNext forall a b. (a -> b) -> a -> b
$ forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall a b. (a, b) -> b
snd [(DependencyType, PackageName)]
filteredSubLibDeps
  let temp :: [[(AdjacencyMap (Set DependencyType) PackageName, Set PackageName,
   Map PackageName [SystemDependency])]]
temp = [[(AdjacencyMap (Set DependencyType) PackageName, Set PackageName,
  Map PackageName [SystemDependency])]
nextLib, [(AdjacencyMap (Set DependencyType) PackageName, Set PackageName,
  Map PackageName [SystemDependency])]
nextSetup, [(AdjacencyMap (Set DependencyType) PackageName, Set PackageName,
  Map PackageName [SystemDependency])]
nextExe, [(AdjacencyMap (Set DependencyType) PackageName, Set PackageName,
  Map PackageName [SystemDependency])]
nextTest, [(AdjacencyMap (Set DependencyType) PackageName, Set PackageName,
  Map PackageName [SystemDependency])]
nextSubLibs]
      nexts :: AdjacencyMap (Set DependencyType) PackageName
nexts = forall e a.
(Eq e, Monoid e, Ord a) =>
[AdjacencyMap e a] -> AdjacencyMap e a
G.overlays forall a b. (a -> b) -> a -> b
$ [[(AdjacencyMap (Set DependencyType) PackageName, Set PackageName,
   Map PackageName [SystemDependency])]]
temp forall s a. s -> Getting a s a -> a
^. forall s t a b. Each s t a b => Traversal s t a b
each forall s a. s -> Getting (Endo [a]) s a -> [a]
^.. forall s t a b. Each s t a b => Traversal s t a b
each forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall s t a b. Field1 s t a b => Lens s t a b
_1
      subsubs :: Set PackageName
subsubs = [[(AdjacencyMap (Set DependencyType) PackageName, Set PackageName,
   Map PackageName [SystemDependency])]]
temp forall s a. s -> Getting a s a -> a
^. forall s t a b. Each s t a b => Traversal s t a b
each forall s a. s -> Getting (Endo [a]) s a -> [a]
^.. forall s t a b. Each s t a b => Traversal s t a b
each forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall s t a b. Field2 s t a b => Lens s t a b
_2 forall s a. s -> Getting a s a -> a
^. forall s t a b. Each s t a b => Traversal s t a b
each
      nextSys :: Map PackageName [SystemDependency]
nextSys = [[(AdjacencyMap (Set DependencyType) PackageName, Set PackageName,
   Map PackageName [SystemDependency])]]
temp forall s a. s -> Getting a s a -> a
^. forall s t a b. Each s t a b => Traversal s t a b
each forall s a. s -> Getting (Endo [a]) s a -> [a]
^.. forall s t a b. Each s t a b => Traversal s t a b
each forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall s t a b. Field3 s t a b => Lens s t a b
_3 forall s a. s -> Getting a s a -> a
^. forall s t a b. Each s t a b => Traversal s t a b
each
  forall (m :: * -> *) a. Monad m => a -> m a
return
    ( AdjacencyMap (Set DependencyType) PackageName
currentLib
        AdjacencyMap (Set DependencyType) PackageName
-> AdjacencyMap (Set DependencyType) PackageName
-> AdjacencyMap (Set DependencyType) PackageName
<+> AdjacencyMap (Set DependencyType) PackageName
currentLibToolDeps
        AdjacencyMap (Set DependencyType) PackageName
-> AdjacencyMap (Set DependencyType) PackageName
-> AdjacencyMap (Set DependencyType) PackageName
<+> AdjacencyMap (Set DependencyType) PackageName
currentSetupDeps
        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
        AdjacencyMap (Set DependencyType) PackageName
-> AdjacencyMap (Set DependencyType) PackageName
-> AdjacencyMap (Set DependencyType) PackageName
<+> AdjacencyMap (Set DependencyType) PackageName
currentSubLibs
        AdjacencyMap (Set DependencyType) PackageName
-> AdjacencyMap (Set DependencyType) PackageName
-> AdjacencyMap (Set DependencyType) PackageName
<+> AdjacencyMap (Set DependencyType) PackageName
currentSubLibsTools
        -- <+> currentBench
        -- <+> currentBenchTools
        AdjacencyMap (Set DependencyType) PackageName
-> AdjacencyMap (Set DependencyType) PackageName
-> AdjacencyMap (Set DependencyType) PackageName
<+> AdjacencyMap (Set DependencyType) PackageName
nexts,
      forall a. Ord a => [a] -> Set a
Set.fromList [PackageName]
filteredSubLibDepsNames forall a. Semigroup a => a -> a -> a
<> Set PackageName
subsubs,
      (if forall (t :: * -> *) a. Foldable t => t a -> Bool
null [SystemDependency]
currentSysDeps then forall k a. Map k a
Map.empty else forall k a. k -> a -> Map k a
Map.singleton PackageName
name [SystemDependency]
currentSysDeps) forall a. Semigroup a => a -> a -> a
<> Map PackageName [SystemDependency]
nextSys
    )

collectLibDeps ::
  (Members [KnownGHCVersion, FlagAssignmentsEnv, DependencyRecord, Trace] r, Show a, Monoid a) =>
  ([(PackageName, VersionRange)] -> a) ->
  GenericPackageDescription ->
  Sem r (a, a, [SystemDependency])
collectLibDeps :: forall (r :: EffectRow) a.
(Members
   '[KnownGHCVersion, FlagAssignmentsEnv, DependencyRecord, Trace] r,
 Show a, Monoid a) =>
([(PackageName, VersionRange)] -> a)
-> GenericPackageDescription -> Sem r (a, a, [SystemDependency])
collectLibDeps [(PackageName, VersionRange)] -> a
k GenericPackageDescription
cabal = do
  case GenericPackageDescription
cabal 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
      forall (r :: EffectRow). Member Trace r => String -> Sem r ()
trace' forall a b. (a -> b) -> a -> b
$ String
"Getting libs dependencies of " forall a. Semigroup a => a -> a -> a
<> forall a. Show a => a -> String
show PackageName
name
      BuildInfo
info <- forall k (r :: EffectRow).
(HasCallStack, Semigroup k, HasBuildInfo k,
 Members '[KnownGHCVersion, FlagAssignmentsEnv, Trace] 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)
unDepV forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> BuildInfo -> [Dependency]
buildDependsIfBuild BuildInfo
info
          toolDeps :: [(PackageName, VersionRange)]
toolDeps = ([LegacyExeDependency], [ExeDependency])
-> [(PackageName, VersionRange)]
unBuildTools forall a b. (a -> b) -> a -> b
$ BuildInfo -> ([LegacyExeDependency], [ExeDependency])
buildToolsAndbuildToolDependsIfBuild BuildInfo
info
          systemDeps :: [SystemDependency]
systemDeps = ([PkgconfigDependency], [String]) -> [SystemDependency]
unSystemDependency forall a b. (a -> b) -> a -> b
$ BuildInfo -> ([PkgconfigDependency], [String])
pkgconfigDependsAndExtraLibsIfBuild BuildInfo
info
      forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ (forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry forall (r :: EffectRow).
Member DependencyRecord r =>
PackageName -> VersionRange -> Sem r ()
updateDependencyRecord) [(PackageName, VersionRange)]
libDeps
      forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ (forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry forall (r :: EffectRow).
Member DependencyRecord r =>
PackageName -> VersionRange -> Sem r ()
updateDependencyRecord) [(PackageName, VersionRange)]
toolDeps
      let result :: (a, a, [SystemDependency])
result = ([(PackageName, VersionRange)] -> a
k [(PackageName, VersionRange)]
libDeps, [(PackageName, VersionRange)] -> a
k [(PackageName, VersionRange)]
toolDeps, [SystemDependency]
systemDeps)
      forall (r :: EffectRow). Member Trace r => String -> Sem r ()
trace' forall a b. (a -> b) -> a -> b
$ String
"Found: " forall a. Semigroup a => a -> a -> a
<> forall a. Show a => a -> String
show (a, a, [SystemDependency])
result
      forall (r :: EffectRow). (HasCallStack, Member Trace r) => Sem r ()
traceCallStack
      forall (m :: * -> *) a. Monad m => a -> m a
return (a, a, [SystemDependency])
result
    Maybe (CondTree ConfVar [Dependency] Library)
Nothing -> forall (m :: * -> *) a. Monad m => a -> m a
return forall a. Monoid a => a
mempty -- 'Monoid a' comes from here

collectComponentialDeps ::
  (HasCallStack, Semigroup k, L.HasBuildInfo k, Members [KnownGHCVersion, FlagAssignmentsEnv, DependencyRecord, Trace] r, Show a) =>
  String ->
  (GenericPackageDescription -> [(UnqualComponentName, CondTree ConfVar [Dependency] k)]) ->
  ([(UnqualComponentName, [(PackageName, VersionRange)])] -> a) ->
  GenericPackageDescription ->
  [UnqualComponentName] ->
  Sem r (a, a, [SystemDependency])
collectComponentialDeps :: forall k (r :: EffectRow) a.
(HasCallStack, Semigroup k, HasBuildInfo k,
 Members
   '[KnownGHCVersion, FlagAssignmentsEnv, DependencyRecord, Trace] r,
 Show a) =>
String
-> (GenericPackageDescription
    -> [(UnqualComponentName, CondTree ConfVar [Dependency] k)])
-> ([(UnqualComponentName, [(PackageName, VersionRange)])] -> a)
-> GenericPackageDescription
-> [UnqualComponentName]
-> Sem r (a, a, [SystemDependency])
collectComponentialDeps String
tag GenericPackageDescription
-> [(UnqualComponentName, CondTree ConfVar [Dependency] k)]
f [(UnqualComponentName, [(PackageName, VersionRange)])] -> a
k GenericPackageDescription
cabal [UnqualComponentName]
skip = do
  let conds :: [(UnqualComponentName, CondTree ConfVar [Dependency] k)]
conds = GenericPackageDescription
cabal forall a b. a -> (a -> b) -> b
& GenericPackageDescription
-> [(UnqualComponentName, CondTree ConfVar [Dependency] k)]
f
      name :: PackageName
name = GenericPackageDescription -> PackageName
getPkgName' GenericPackageDescription
cabal
  forall (r :: EffectRow). Member Trace r => String -> Sem r ()
trace' forall a b. (a -> b) -> a -> b
$ String
"Getting " forall a. Semigroup a => a -> a -> a
<> String
tag forall a. Semigroup a => a -> a -> a
<> String
" dependencies of " forall a. Semigroup a => a -> a -> a
<> forall a. Show a => a -> String
show PackageName
name
  [(UnqualComponentName, BuildInfo)]
info <- forall a. (a -> Bool) -> [a] -> [a]
filter (Bool -> Bool
not forall b c a. (b -> c) -> (a -> b) -> a -> c
. (forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [UnqualComponentName]
skip) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (a, b) -> a
fst) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. [a] -> [b] -> [(a, b)]
zip ([(UnqualComponentName, CondTree ConfVar [Dependency] k)]
conds forall (f :: * -> *) a b. Functor f => f a -> (a -> b) -> f b
<&> forall a b. (a, b) -> a
fst) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM (forall k (r :: EffectRow).
(HasCallStack, Semigroup k, HasBuildInfo k,
 Members '[KnownGHCVersion, FlagAssignmentsEnv, Trace] r) =>
GenericPackageDescription
-> CondTree ConfVar [Dependency] k -> Sem r BuildInfo
evalConditionTree GenericPackageDescription
cabal forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (a, b) -> b
snd) [(UnqualComponentName, CondTree ConfVar [Dependency] k)]
conds
  let deps :: [(UnqualComponentName, [(PackageName, VersionRange)])]
deps = [(UnqualComponentName, BuildInfo)]
info forall (f :: * -> *) a b. Functor f => f a -> (a -> b) -> f b
<&> forall s t a b. Field2 s t a b => Lens s t a b
_2 forall s t a b. ASetter s t a b -> (a -> b) -> s -> t
%~ (forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Dependency -> (PackageName, VersionRange)
unDepV forall b c a. (b -> c) -> (a -> b) -> a -> c
. BuildInfo -> [Dependency]
buildDependsIfBuild)
      toolDeps :: [(UnqualComponentName, [(PackageName, VersionRange)])]
toolDeps = [(UnqualComponentName, BuildInfo)]
info forall (f :: * -> *) a b. Functor f => f a -> (a -> b) -> f b
<&> forall s t a b. Field2 s t a b => Lens s t a b
_2 forall s t a b. ASetter s t a b -> (a -> b) -> s -> t
%~ (([LegacyExeDependency], [ExeDependency])
-> [(PackageName, VersionRange)]
unBuildTools forall b c a. (b -> c) -> (a -> b) -> a -> c
. BuildInfo -> ([LegacyExeDependency], [ExeDependency])
buildToolsAndbuildToolDependsIfBuild)
      sysDeps :: [(UnqualComponentName, [SystemDependency])]
sysDeps = [(UnqualComponentName, BuildInfo)]
info forall (f :: * -> *) a b. Functor f => f a -> (a -> b) -> f b
<&> forall s t a b. Field2 s t a b => Lens s t a b
_2 forall s t a b. ASetter s t a b -> (a -> b) -> s -> t
%~ (([PkgconfigDependency], [String]) -> [SystemDependency]
unSystemDependency forall b c a. (b -> c) -> (a -> b) -> a -> c
. BuildInfo -> ([PkgconfigDependency], [String])
pkgconfigDependsAndExtraLibsIfBuild)
  forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ (forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry forall (r :: EffectRow).
Member DependencyRecord r =>
PackageName -> VersionRange -> Sem r ()
updateDependencyRecord) forall a b. (a -> b) -> a -> b
$ [(UnqualComponentName, [(PackageName, VersionRange)])]
deps forall s a. s -> Getting (Endo [a]) s a -> [a]
^.. forall s t a b. Each s t a b => Traversal s t a b
each forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall s t a b. Field2 s t a b => Lens s t a b
_2 forall s a. s -> Getting a s a -> a
^. forall s t a b. Each s t a b => Traversal s t a b
each
  forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ (forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry forall (r :: EffectRow).
Member DependencyRecord r =>
PackageName -> VersionRange -> Sem r ()
updateDependencyRecord) forall a b. (a -> b) -> a -> b
$ [(UnqualComponentName, [(PackageName, VersionRange)])]
toolDeps forall s a. s -> Getting (Endo [a]) s a -> [a]
^.. forall s t a b. Each s t a b => Traversal s t a b
each forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall s t a b. Field2 s t a b => Lens s t a b
_2 forall s a. s -> Getting a s a -> a
^. forall s t a b. Each s t a b => Traversal s t a b
each
  let result :: (a, a, [SystemDependency])
result = ([(UnqualComponentName, [(PackageName, VersionRange)])] -> a
k [(UnqualComponentName, [(PackageName, VersionRange)])]
deps, [(UnqualComponentName, [(PackageName, VersionRange)])] -> a
k [(UnqualComponentName, [(PackageName, VersionRange)])]
toolDeps, forall a. Monoid a => [a] -> a
mconcat forall a b. (a -> b) -> a -> b
$ forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall a b. (a, b) -> b
snd [(UnqualComponentName, [SystemDependency])]
sysDeps)
  forall (r :: EffectRow). Member Trace r => String -> Sem r ()
trace' forall a b. (a -> b) -> a -> b
$ String
"Found: " forall a. Semigroup a => a -> a -> a
<> forall a. Show a => a -> String
show (a, a, [SystemDependency])
result
  forall (r :: EffectRow). (HasCallStack, Member Trace r) => Sem r ()
traceCallStack
  forall (m :: * -> *) a. Monad m => a -> m a
return (a, a, [SystemDependency])
result

collectExeDeps ::
  (HasCallStack, Members [KnownGHCVersion, FlagAssignmentsEnv, DependencyRecord, Trace] r, Show a) =>
  ([(UnqualComponentName, [(PackageName, VersionRange)])] -> a) ->
  GenericPackageDescription ->
  [UnqualComponentName] ->
  Sem r (a, a, [SystemDependency])
collectExeDeps :: forall (r :: EffectRow) a.
(HasCallStack,
 Members
   '[KnownGHCVersion, FlagAssignmentsEnv, DependencyRecord, Trace] r,
 Show a) =>
([(UnqualComponentName, [(PackageName, VersionRange)])] -> a)
-> GenericPackageDescription
-> [UnqualComponentName]
-> Sem r (a, a, [SystemDependency])
collectExeDeps = forall k (r :: EffectRow) a.
(HasCallStack, Semigroup k, HasBuildInfo k,
 Members
   '[KnownGHCVersion, FlagAssignmentsEnv, DependencyRecord, Trace] r,
 Show a) =>
String
-> (GenericPackageDescription
    -> [(UnqualComponentName, CondTree ConfVar [Dependency] k)])
-> ([(UnqualComponentName, [(PackageName, VersionRange)])] -> a)
-> GenericPackageDescription
-> [UnqualComponentName]
-> Sem r (a, a, [SystemDependency])
collectComponentialDeps String
"exe" GenericPackageDescription
-> [(UnqualComponentName,
     CondTree ConfVar [Dependency] Executable)]
condExecutables

collectTestDeps ::
  (HasCallStack, Members [KnownGHCVersion, FlagAssignmentsEnv, DependencyRecord, Trace] r, Show a) =>
  ([(UnqualComponentName, [(PackageName, VersionRange)])] -> a) ->
  GenericPackageDescription ->
  [UnqualComponentName] ->
  Sem r (a, a, [SystemDependency])
collectTestDeps :: forall (r :: EffectRow) a.
(HasCallStack,
 Members
   '[KnownGHCVersion, FlagAssignmentsEnv, DependencyRecord, Trace] r,
 Show a) =>
([(UnqualComponentName, [(PackageName, VersionRange)])] -> a)
-> GenericPackageDescription
-> [UnqualComponentName]
-> Sem r (a, a, [SystemDependency])
collectTestDeps = forall k (r :: EffectRow) a.
(HasCallStack, Semigroup k, HasBuildInfo k,
 Members
   '[KnownGHCVersion, FlagAssignmentsEnv, DependencyRecord, Trace] r,
 Show a) =>
String
-> (GenericPackageDescription
    -> [(UnqualComponentName, CondTree ConfVar [Dependency] k)])
-> ([(UnqualComponentName, [(PackageName, VersionRange)])] -> a)
-> GenericPackageDescription
-> [UnqualComponentName]
-> Sem r (a, a, [SystemDependency])
collectComponentialDeps String
"test" GenericPackageDescription
-> [(UnqualComponentName, CondTree ConfVar [Dependency] TestSuite)]
condTestSuites

collectSubLibDeps ::
  (HasCallStack, Members [KnownGHCVersion, FlagAssignmentsEnv, DependencyRecord, Trace] r, Show a) =>
  ([(UnqualComponentName, [(PackageName, VersionRange)])] -> a) ->
  GenericPackageDescription ->
  [UnqualComponentName] ->
  Sem r (a, a, [SystemDependency])
collectSubLibDeps :: forall (r :: EffectRow) a.
(HasCallStack,
 Members
   '[KnownGHCVersion, FlagAssignmentsEnv, DependencyRecord, Trace] r,
 Show a) =>
([(UnqualComponentName, [(PackageName, VersionRange)])] -> a)
-> GenericPackageDescription
-> [UnqualComponentName]
-> Sem r (a, a, [SystemDependency])
collectSubLibDeps = forall k (r :: EffectRow) a.
(HasCallStack, Semigroup k, HasBuildInfo k,
 Members
   '[KnownGHCVersion, FlagAssignmentsEnv, DependencyRecord, Trace] r,
 Show a) =>
String
-> (GenericPackageDescription
    -> [(UnqualComponentName, CondTree ConfVar [Dependency] k)])
-> ([(UnqualComponentName, [(PackageName, VersionRange)])] -> a)
-> GenericPackageDescription
-> [UnqualComponentName]
-> Sem r (a, a, [SystemDependency])
collectComponentialDeps String
"sublib" GenericPackageDescription
-> [(UnqualComponentName, CondTree ConfVar [Dependency] Library)]
condSubLibraries

collectSetupDeps ::
  (Member Trace r, Show a, Monoid a) =>
  ([(PackageName, VersionRange)] -> a) ->
  GenericPackageDescription ->
  Sem r a
collectSetupDeps :: forall (r :: EffectRow) a.
(Member Trace r, Show a, Monoid a) =>
([(PackageName, VersionRange)] -> a)
-> GenericPackageDescription -> Sem r a
collectSetupDeps [(PackageName, VersionRange)] -> a
k GenericPackageDescription
cabal = do
  let name :: PackageName
name = GenericPackageDescription -> PackageName
getPkgName' GenericPackageDescription
cabal
  forall (r :: EffectRow). Member Trace r => String -> Sem r ()
trace' forall a b. (a -> b) -> a -> b
$ String
"Getting setup dependencies of " forall a. Semigroup a => a -> a -> a
<> forall a. Show a => a -> String
show PackageName
name
  case PackageDescription -> Maybe SetupBuildInfo
setupBuildInfo forall a b. (a -> b) -> a -> b
$ GenericPackageDescription -> PackageDescription
packageDescription GenericPackageDescription
cabal of
    Just (SetupBuildInfo [Dependency]
deps Bool
_) -> do
      let result :: a
result = [(PackageName, VersionRange)] -> a
k forall a b. (a -> b) -> a -> b
$ Dependency -> (PackageName, VersionRange)
unDepV forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [Dependency]
deps
      forall (r :: EffectRow). Member Trace r => String -> Sem r ()
trace' forall a b. (a -> b) -> a -> b
$ String
"Found: " forall a. Semigroup a => a -> a -> a
<> forall a. Show a => a -> String
show a
result
      forall (m :: * -> *) a. Monad m => a -> m a
return a
result
    Maybe SetupBuildInfo
_ -> forall (m :: * -> *) a. Monad m => a -> m a
return forall a. Monoid a => a
mempty

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

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

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

-- | Generate 'PkgBuild' for a 'SolvedPackage'.
cabalToPkgBuild :: Members [HackageEnv, FlagAssignmentsEnv, WithMyErr] r => SolvedPackage -> Bool -> [ArchLinuxName] -> Sem r PkgBuild
cabalToPkgBuild :: forall (r :: EffectRow).
Members '[HackageEnv, FlagAssignmentsEnv, WithMyErr] r =>
SolvedPackage -> Bool -> [ArchLinuxName] -> Sem r PkgBuild
cabalToPkgBuild SolvedPackage
pkg Bool
uusi [ArchLinuxName]
sysDeps = do
  let name :: PackageName
name = SolvedPackage
pkg forall s a. s -> Getting a s a -> a
^. Lens' SolvedPackage PackageName
pkgName
  PackageDescription
cabal <- GenericPackageDescription -> PackageDescription
packageDescription forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (r :: EffectRow).
Members '[HackageEnv, WithMyErr] r =>
PackageName -> Sem r GenericPackageDescription
getLatestCabal PackageName
name
  [PackageFlag]
pkgFlags <- forall (r :: EffectRow).
Members '[HackageEnv, WithMyErr] r =>
PackageName -> Sem r [PackageFlag]
getPackageFlag PackageName
name
  FlagAssignment
assignment <- PackageName -> FlagAssignments -> FlagAssignment
getFlagAssignment PackageName
name forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall i (r :: EffectRow). Member (Reader i) r => Sem r i
ask
  let showFlagForCmd :: (FlagName, Bool) -> String
showFlagForCmd (FlagName -> String
unFlagName -> String
fName, Bool
enabled) = String
"-f" forall a. Semigroup a => a -> a -> a
<> (if Bool
enabled then String
"" else String
"-") forall a. Semigroup a => a -> a -> a
<> String
fName
      _flags :: String
_flags = [String] -> String
unwords forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (FlagName, Bool) -> String
showFlagForCmd forall b c a. (b -> c) -> (a -> b) -> a -> c
. FlagAssignment -> [(FlagName, Bool)]
unFlagAssignment forall a b. (a -> b) -> a -> b
$ [PackageFlag] -> FlagAssignment -> FlagAssignment
defaultFlags [PackageFlag]
pkgFlags FlagAssignment
assignment
  String
_sha256sums <- (\case Just String
s -> String
"'" forall a. Semigroup a => a -> a -> a
<> String
s forall a. Semigroup a => a -> a -> a
<> String
"'"; Maybe String
Nothing -> String
"'SKIP'") forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (r :: EffectRow).
Members '[HackageEnv, WithMyErr] r =>
PackageName -> Sem r (Maybe String)
getLatestSHA256 PackageName
name
  let _hkgName :: String
_hkgName = SolvedPackage
pkg forall s a. s -> Getting a s a -> a
^. Lens' SolvedPackage PackageName
pkgName forall a b. a -> (a -> b) -> b
& PackageName -> String
unPackageName
      _pkgName :: String
_pkgName = ArchLinuxName -> String
unArchLinuxName forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall n. HasMyName n => n -> ArchLinuxName
toArchLinuxName forall a b. (a -> b) -> a -> b
$ SolvedPackage
pkg forall s a. s -> Getting a s a -> a
^. Lens' SolvedPackage PackageName
pkgName
      _pkgVer :: String
_pkgVer = forall a. Pretty a => a -> String
prettyShow forall a b. (a -> b) -> a -> b
$ PackageDescription -> Version
getPkgVersion PackageDescription
cabal
      _pkgDesc :: String
_pkgDesc = ShortText -> String
fromShortText 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
_) = License -> String
showArchLicense forall b c a. (b -> c) -> (a -> b) -> a -> c
. LicenseId -> License
mapLicense forall a b. (a -> b) -> a -> b
$ LicenseId
x
      getE (ELicense (ELicenseIdPlus LicenseId
x) Maybe LicenseExceptionId
_) = License -> String
showArchLicense forall b c a. (b -> c) -> (a -> b) -> a -> c
. LicenseId -> License
mapLicense forall a b. (a -> b) -> a -> b
$ LicenseId
x
      getE (ELicense (ELicenseRef LicenseRef
x) Maybe LicenseExceptionId
_) = String
"custom:" forall a. Semigroup a => a -> a -> a
<> LicenseRef -> String
licenseRef LicenseRef
x
      getE (EAnd LicenseExpression
x LicenseExpression
y) = LicenseExpression -> String
getE LicenseExpression
x forall a. Semigroup a => a -> a -> a
<> String
" " forall a. Semigroup a => a -> a -> a
<> LicenseExpression -> String
getE LicenseExpression
y
      getE (EOr LicenseExpression
x LicenseExpression
y) = LicenseExpression -> String
getE LicenseExpression
x forall a. Semigroup a => a -> a -> a
<> String
" " forall a. Semigroup a => a -> a -> a
<> LicenseExpression -> String
getE LicenseExpression
y

      _license :: String
_license = License -> String
getL forall b c a. (b -> c) -> (a -> b) -> a -> c
. PackageDescription -> License
license forall a b. (a -> b) -> a -> b
$ PackageDescription
cabal
      _enableCheck :: Bool
_enableCheck = forall (t :: * -> *). Foldable t => t Bool -> Bool
or forall a b. (a -> b) -> a -> b
$ (SolvedPackage
pkg forall s a. s -> Getting a s a -> a
^. Traversal' SolvedPackage [SolvedDependency]
pkgDeps) forall (f :: * -> *) a b. Functor f => f a -> (a -> b) -> f b
<&> DependencyKind -> SolvedDependency -> Bool
depIsKind DependencyKind
Test
      depends :: [SolvedDependency]
depends =
        SolvedPackage
pkg forall s a. s -> Getting a s a -> a
^. Traversal' SolvedPackage [SolvedDependency]
pkgDeps
          forall s a. s -> Getting (Endo [a]) s a -> [a]
^.. forall s t a b. Each s t a b => Traversal s t a b
each
            forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. (a -> Bool) -> Traversal' a a
filtered
              ( \SolvedDependency
x ->
                  PackageName -> SolvedDependency -> Bool
depNotMyself PackageName
name SolvedDependency
x
                    Bool -> Bool -> Bool
&& SolvedDependency -> Bool
depNotInGHCLib SolvedDependency
x
                    Bool -> Bool -> Bool
&& ( DependencyKind -> SolvedDependency -> Bool
depIsKind DependencyKind
Lib SolvedDependency
x
                           Bool -> Bool -> Bool
|| DependencyKind -> SolvedDependency -> Bool
depIsKind DependencyKind
Exe SolvedDependency
x
                           Bool -> Bool -> Bool
|| DependencyKind -> SolvedDependency -> Bool
depIsKind DependencyKind
SubLibs SolvedDependency
x
                       )
              )
      makeDepends :: [SolvedDependency]
makeDepends =
        SolvedPackage
pkg forall s a. s -> Getting a s a -> a
^. Traversal' SolvedPackage [SolvedDependency]
pkgDeps
          forall s a. s -> Getting (Endo [a]) s a -> [a]
^.. forall s t a b. Each s t a b => Traversal s t a b
each
            forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. (a -> Bool) -> Traversal' a a
filtered
              ( \SolvedDependency
x ->
                  SolvedDependency
x forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`notElem` [SolvedDependency]
depends
                    Bool -> Bool -> Bool
&& PackageName -> SolvedDependency -> Bool
depNotMyself PackageName
name SolvedDependency
x
                    Bool -> Bool -> Bool
&& SolvedDependency -> Bool
depNotInGHCLib SolvedDependency
x
                    Bool -> Bool -> Bool
&& ( DependencyKind -> SolvedDependency -> Bool
depIsKind DependencyKind
LibBuildTools SolvedDependency
x
                           Bool -> Bool -> Bool
|| DependencyKind -> SolvedDependency -> Bool
depIsKind DependencyKind
ExeBuildTools SolvedDependency
x
                           Bool -> Bool -> Bool
|| DependencyKind -> SolvedDependency -> Bool
depIsKind DependencyKind
Test SolvedDependency
x
                           Bool -> Bool -> Bool
|| DependencyKind -> SolvedDependency -> Bool
depIsKind DependencyKind
TestBuildTools SolvedDependency
x
                           Bool -> Bool -> Bool
|| DependencyKind -> SolvedDependency -> Bool
depIsKind DependencyKind
SubLibsBuildTools SolvedDependency
x
                           Bool -> Bool -> Bool
|| DependencyKind -> SolvedDependency -> Bool
depIsKind DependencyKind
Setup SolvedDependency
x
                       )
              )
      depsToString :: (a -> b) -> [a] -> String
depsToString a -> b
k [a]
deps = [a]
deps forall (f :: * -> *) a b. Functor f => f a -> (a -> b) -> f b
<&> (String -> String
wrap forall b c a. (b -> c) -> (a -> b) -> a -> c
. ArchLinuxName -> String
unArchLinuxName forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall n. HasMyName n => n -> ArchLinuxName
toArchLinuxName forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> b
k) forall a b. a -> (a -> b) -> b
& forall a. Monoid a => [a] -> a
mconcat
      _depends :: String
_depends = forall {b} {a}. HasMyName b => (a -> b) -> [a] -> String
depsToString SolvedDependency -> PackageName
_depName [SolvedDependency]
depends forall a. Semigroup a => a -> a -> a
<> forall {b} {a}. HasMyName b => (a -> b) -> [a] -> String
depsToString forall a. a -> a
id [ArchLinuxName]
sysDeps
      _makeDepends :: String
_makeDepends = (if Bool
uusi then String
" 'uusi'" else String
"") forall a. Semigroup a => a -> a -> a
<> forall {b} {a}. HasMyName b => (a -> b) -> [a] -> String
depsToString SolvedDependency -> PackageName
_depName [SolvedDependency]
makeDepends
      _url :: String
_url = PackageDescription -> String
getUrl PackageDescription
cabal
      wrap :: String -> String
wrap String
s = String
" '" forall a. Semigroup a => a -> a -> a
<> String
s forall a. Semigroup a => a -> a -> a
<> String
"'"
      _licenseFile :: Maybe String
_licenseFile = PackageDescription -> Maybe String
licenseFile PackageDescription
cabal
      _enableUusi :: Bool
_enableUusi = Bool
uusi
  forall (m :: * -> *) a. Monad m => a -> m a
return PkgBuild {Bool
String
Maybe String
_flags :: String
_enableCheck :: Bool
_enableUusi :: Bool
_licenseFile :: Maybe String
_sha256sums :: String
_makeDepends :: String
_depends :: String
_license :: String
_url :: String
_pkgDesc :: String
_pkgVer :: String
_pkgName :: String
_hkgName :: String
_enableUusi :: Bool
_licenseFile :: Maybe String
_url :: String
_makeDepends :: String
_depends :: String
_enableCheck :: Bool
_license :: String
_pkgDesc :: String
_pkgVer :: String
_pkgName :: String
_hkgName :: String
_sha256sums :: String
_flags :: String
..}

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

-- | Get the ghc version in 'ExtraDB'
subsumeGHCVersion :: Members [ExtraEnv, WithMyErr] r => InterpreterFor KnownGHCVersion r
subsumeGHCVersion :: forall (r :: EffectRow).
Members '[ExtraEnv, WithMyErr] r =>
InterpreterFor KnownGHCVersion r
subsumeGHCVersion Sem (KnownGHCVersion : r) a
m = do
  String
rawVersion <- forall n (r :: EffectRow).
(HasMyName n, Members '[ExtraEnv, WithMyErr] r) =>
n -> Sem r String
versionInExtra forall a b. (a -> b) -> a -> b
$ String -> ArchLinuxName
ArchLinuxName String
"haskell-ghc"
  let ghcVersion :: Version
ghcVersion = forall a. a -> Maybe a -> a
fromMaybe (forall a. HasCallStack => String -> a
error forall a b. (a -> b) -> a -> b
$ String
"Impossible: unable to parse ghc version from [extra]: " forall a. Semigroup a => a -> a -> a
<> String
rawVersion) forall a b. (a -> b) -> a -> b
$ forall a. Parsec a => String -> Maybe a
simpleParsec String
rawVersion
  forall i (r :: EffectRow) a. i -> Sem (Reader i : r) a -> Sem r a
runReader Version
ghcVersion Sem (KnownGHCVersion : r) a
m