{-# LANGUAGE DeriveDataTypeable #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
module Distribution.Simple.PackageIndex (
InstalledPackageIndex,
PackageIndex,
fromList,
merge,
insert,
deleteUnitId,
deleteSourcePackageId,
deletePackageName,
lookupUnitId,
lookupComponentId,
lookupSourcePackageId,
lookupPackageId,
lookupPackageName,
lookupDependency,
lookupInternalDependency,
searchByName,
SearchResult(..),
searchByNameSubstring,
searchWithPredicate,
allPackages,
allPackagesByName,
allPackagesBySourcePackageId,
allPackagesBySourcePackageIdAndLibName,
brokenPackages,
dependencyClosure,
reverseDependencyClosure,
topologicalOrder,
reverseTopologicalOrder,
dependencyInconsistencies,
dependencyCycles,
dependencyGraph,
moduleNameIndex
) where
import Prelude ()
import Distribution.Compat.Prelude hiding (lookup)
import qualified Data.Map.Strict as Map
import Distribution.Package
import Distribution.Backpack
import Distribution.ModuleName
import qualified Distribution.InstalledPackageInfo as IPI
import Distribution.Version
import Distribution.Simple.Utils
import Distribution.Types.LibraryName
import Control.Exception (assert)
import Data.Array ((!))
import qualified Data.Array as Array
import qualified Data.Graph as Graph
import Data.List as List ( groupBy, deleteBy, deleteFirstsBy )
import qualified Data.List.NonEmpty as NE
import qualified Data.Tree as Tree
import Control.Monad
import Distribution.Compat.Stack
import qualified Prelude (foldr1)
data PackageIndex a = PackageIndex {
forall a. PackageIndex a -> Map UnitId a
unitIdIndex :: !(Map UnitId a),
forall a.
PackageIndex a -> Map (PackageName, LibraryName) (Map Version [a])
packageIdIndex :: !(Map (PackageName, LibraryName) (Map Version [a]))
} deriving (PackageIndex a -> PackageIndex a -> Bool
(PackageIndex a -> PackageIndex a -> Bool)
-> (PackageIndex a -> PackageIndex a -> Bool)
-> Eq (PackageIndex a)
forall a. Eq a => PackageIndex a -> PackageIndex a -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: PackageIndex a -> PackageIndex a -> Bool
$c/= :: forall a. Eq a => PackageIndex a -> PackageIndex a -> Bool
== :: PackageIndex a -> PackageIndex a -> Bool
$c== :: forall a. Eq a => PackageIndex a -> PackageIndex a -> Bool
Eq, (forall x. PackageIndex a -> Rep (PackageIndex a) x)
-> (forall x. Rep (PackageIndex a) x -> PackageIndex a)
-> Generic (PackageIndex a)
forall x. Rep (PackageIndex a) x -> PackageIndex a
forall x. PackageIndex a -> Rep (PackageIndex a) x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall a x. Rep (PackageIndex a) x -> PackageIndex a
forall a x. PackageIndex a -> Rep (PackageIndex a) x
$cto :: forall a x. Rep (PackageIndex a) x -> PackageIndex a
$cfrom :: forall a x. PackageIndex a -> Rep (PackageIndex a) x
Generic, Int -> PackageIndex a -> ShowS
[PackageIndex a] -> ShowS
PackageIndex a -> String
(Int -> PackageIndex a -> ShowS)
-> (PackageIndex a -> String)
-> ([PackageIndex a] -> ShowS)
-> Show (PackageIndex a)
forall a. Show a => Int -> PackageIndex a -> ShowS
forall a. Show a => [PackageIndex a] -> ShowS
forall a. Show a => PackageIndex a -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [PackageIndex a] -> ShowS
$cshowList :: forall a. Show a => [PackageIndex a] -> ShowS
show :: PackageIndex a -> String
$cshow :: forall a. Show a => PackageIndex a -> String
showsPrec :: Int -> PackageIndex a -> ShowS
$cshowsPrec :: forall a. Show a => Int -> PackageIndex a -> ShowS
Show, ReadPrec [PackageIndex a]
ReadPrec (PackageIndex a)
Int -> ReadS (PackageIndex a)
ReadS [PackageIndex a]
(Int -> ReadS (PackageIndex a))
-> ReadS [PackageIndex a]
-> ReadPrec (PackageIndex a)
-> ReadPrec [PackageIndex a]
-> Read (PackageIndex a)
forall a. Read a => ReadPrec [PackageIndex a]
forall a. Read a => ReadPrec (PackageIndex a)
forall a. Read a => Int -> ReadS (PackageIndex a)
forall a. Read a => ReadS [PackageIndex a]
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [PackageIndex a]
$creadListPrec :: forall a. Read a => ReadPrec [PackageIndex a]
readPrec :: ReadPrec (PackageIndex a)
$creadPrec :: forall a. Read a => ReadPrec (PackageIndex a)
readList :: ReadS [PackageIndex a]
$creadList :: forall a. Read a => ReadS [PackageIndex a]
readsPrec :: Int -> ReadS (PackageIndex a)
$creadsPrec :: forall a. Read a => Int -> ReadS (PackageIndex a)
Read, Typeable)
instance Binary a => Binary (PackageIndex a)
instance Structured a => Structured (PackageIndex a)
type InstalledPackageIndex = PackageIndex IPI.InstalledPackageInfo
instance Monoid (PackageIndex IPI.InstalledPackageInfo) where
mempty :: PackageIndex InstalledPackageInfo
mempty = Map UnitId InstalledPackageInfo
-> Map
(PackageName, LibraryName) (Map Version [InstalledPackageInfo])
-> PackageIndex InstalledPackageInfo
forall a.
Map UnitId a
-> Map (PackageName, LibraryName) (Map Version [a])
-> PackageIndex a
PackageIndex Map UnitId InstalledPackageInfo
forall k a. Map k a
Map.empty Map (PackageName, LibraryName) (Map Version [InstalledPackageInfo])
forall k a. Map k a
Map.empty
mappend :: PackageIndex InstalledPackageInfo
-> PackageIndex InstalledPackageInfo
-> PackageIndex InstalledPackageInfo
mappend = PackageIndex InstalledPackageInfo
-> PackageIndex InstalledPackageInfo
-> PackageIndex InstalledPackageInfo
forall a. Semigroup a => a -> a -> a
(<>)
mconcat :: [PackageIndex InstalledPackageInfo]
-> PackageIndex InstalledPackageInfo
mconcat [] = PackageIndex InstalledPackageInfo
forall a. Monoid a => a
mempty
mconcat [PackageIndex InstalledPackageInfo]
xs = (PackageIndex InstalledPackageInfo
-> PackageIndex InstalledPackageInfo
-> PackageIndex InstalledPackageInfo)
-> [PackageIndex InstalledPackageInfo]
-> PackageIndex InstalledPackageInfo
forall (t :: * -> *) a. Foldable t => (a -> a -> a) -> t a -> a
Prelude.foldr1 PackageIndex InstalledPackageInfo
-> PackageIndex InstalledPackageInfo
-> PackageIndex InstalledPackageInfo
forall a. Monoid a => a -> a -> a
mappend [PackageIndex InstalledPackageInfo]
xs
instance Semigroup (PackageIndex IPI.InstalledPackageInfo) where
<> :: PackageIndex InstalledPackageInfo
-> PackageIndex InstalledPackageInfo
-> PackageIndex InstalledPackageInfo
(<>) = PackageIndex InstalledPackageInfo
-> PackageIndex InstalledPackageInfo
-> PackageIndex InstalledPackageInfo
merge
{-# NOINLINE invariant #-}
invariant :: WithCallStack (InstalledPackageIndex -> Bool)
invariant :: WithCallStack (PackageIndex InstalledPackageInfo -> Bool)
invariant (PackageIndex Map UnitId InstalledPackageInfo
pids Map (PackageName, LibraryName) (Map Version [InstalledPackageInfo])
pnames) =
[UnitId]
pids' [UnitId] -> [UnitId] -> Bool
forall a. Eq a => a -> a -> Bool
== [UnitId]
pnames'
where
pids' :: [UnitId]
pids' = (InstalledPackageInfo -> UnitId)
-> [InstalledPackageInfo] -> [UnitId]
forall a b. (a -> b) -> [a] -> [b]
map InstalledPackageInfo -> UnitId
forall pkg. HasUnitId pkg => pkg -> UnitId
installedUnitId (Map UnitId InstalledPackageInfo -> [InstalledPackageInfo]
forall k a. Map k a -> [a]
Map.elems Map UnitId InstalledPackageInfo
pids)
pnames' :: [UnitId]
pnames' = [UnitId] -> [UnitId]
forall a. Ord a => [a] -> [a]
sort
[ Bool -> UnitId -> UnitId
forall a. HasCallStack => Bool -> a -> a
assert Bool
pinstOk (InstalledPackageInfo -> UnitId
forall pkg. HasUnitId pkg => pkg -> UnitId
installedUnitId InstalledPackageInfo
pinst)
| ((PackageName
pname, LibraryName
plib), Map Version [InstalledPackageInfo]
pvers) <- Map (PackageName, LibraryName) (Map Version [InstalledPackageInfo])
-> [((PackageName, LibraryName),
Map Version [InstalledPackageInfo])]
forall k a. Map k a -> [(k, a)]
Map.toList Map (PackageName, LibraryName) (Map Version [InstalledPackageInfo])
pnames
, let pversOk :: Bool
pversOk = Bool -> Bool
not (Map Version [InstalledPackageInfo] -> Bool
forall k a. Map k a -> Bool
Map.null Map Version [InstalledPackageInfo]
pvers)
, (Version
pver, [InstalledPackageInfo]
pinsts) <- Bool
-> [(Version, [InstalledPackageInfo])]
-> [(Version, [InstalledPackageInfo])]
forall a. HasCallStack => Bool -> a -> a
assert Bool
pversOk ([(Version, [InstalledPackageInfo])]
-> [(Version, [InstalledPackageInfo])])
-> [(Version, [InstalledPackageInfo])]
-> [(Version, [InstalledPackageInfo])]
forall a b. (a -> b) -> a -> b
$ Map Version [InstalledPackageInfo]
-> [(Version, [InstalledPackageInfo])]
forall k a. Map k a -> [(k, a)]
Map.toList Map Version [InstalledPackageInfo]
pvers
, let pinsts' :: [InstalledPackageInfo]
pinsts' = (InstalledPackageInfo -> InstalledPackageInfo -> Ordering)
-> [InstalledPackageInfo] -> [InstalledPackageInfo]
forall a. (a -> a -> Ordering) -> [a] -> [a]
sortBy ((InstalledPackageInfo -> UnitId)
-> InstalledPackageInfo -> InstalledPackageInfo -> Ordering
forall a b. Ord a => (b -> a) -> b -> b -> Ordering
comparing InstalledPackageInfo -> UnitId
forall pkg. HasUnitId pkg => pkg -> UnitId
installedUnitId) [InstalledPackageInfo]
pinsts
pinstsOk :: Bool
pinstsOk = ([InstalledPackageInfo] -> Bool)
-> [[InstalledPackageInfo]] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all (\[InstalledPackageInfo]
g -> [InstalledPackageInfo] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [InstalledPackageInfo]
g Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
1)
((InstalledPackageInfo -> InstalledPackageInfo -> Bool)
-> [InstalledPackageInfo] -> [[InstalledPackageInfo]]
forall a. (a -> a -> Bool) -> [a] -> [[a]]
groupBy ((InstalledPackageInfo -> UnitId)
-> InstalledPackageInfo -> InstalledPackageInfo -> Bool
forall a b. Eq a => (b -> a) -> b -> b -> Bool
equating InstalledPackageInfo -> UnitId
forall pkg. HasUnitId pkg => pkg -> UnitId
installedUnitId) [InstalledPackageInfo]
pinsts')
, InstalledPackageInfo
pinst <- Bool -> [InstalledPackageInfo] -> [InstalledPackageInfo]
forall a. HasCallStack => Bool -> a -> a
assert Bool
pinstsOk ([InstalledPackageInfo] -> [InstalledPackageInfo])
-> [InstalledPackageInfo] -> [InstalledPackageInfo]
forall a b. (a -> b) -> a -> b
$ [InstalledPackageInfo]
pinsts'
, let pinstOk :: Bool
pinstOk = InstalledPackageInfo -> PackageName
forall pkg. Package pkg => pkg -> PackageName
packageName InstalledPackageInfo
pinst PackageName -> PackageName -> Bool
forall a. Eq a => a -> a -> Bool
== PackageName
pname
Bool -> Bool -> Bool
&& InstalledPackageInfo -> Version
forall pkg. Package pkg => pkg -> Version
packageVersion InstalledPackageInfo
pinst Version -> Version -> Bool
forall a. Eq a => a -> a -> Bool
== Version
pver
Bool -> Bool -> Bool
&& InstalledPackageInfo -> LibraryName
IPI.sourceLibName InstalledPackageInfo
pinst LibraryName -> LibraryName -> Bool
forall a. Eq a => a -> a -> Bool
== LibraryName
plib
]
mkPackageIndex :: WithCallStack (Map UnitId IPI.InstalledPackageInfo
-> Map (PackageName, LibraryName)
(Map Version [IPI.InstalledPackageInfo])
-> InstalledPackageIndex)
mkPackageIndex :: WithCallStack
(Map UnitId InstalledPackageInfo
-> Map
(PackageName, LibraryName) (Map Version [InstalledPackageInfo])
-> PackageIndex InstalledPackageInfo)
mkPackageIndex Map UnitId InstalledPackageInfo
pids Map (PackageName, LibraryName) (Map Version [InstalledPackageInfo])
pnames = Bool
-> PackageIndex InstalledPackageInfo
-> PackageIndex InstalledPackageInfo
forall a. HasCallStack => Bool -> a -> a
assert (WithCallStack (PackageIndex InstalledPackageInfo -> Bool)
PackageIndex InstalledPackageInfo -> Bool
invariant PackageIndex InstalledPackageInfo
index) PackageIndex InstalledPackageInfo
index
where index :: PackageIndex InstalledPackageInfo
index = Map UnitId InstalledPackageInfo
-> Map
(PackageName, LibraryName) (Map Version [InstalledPackageInfo])
-> PackageIndex InstalledPackageInfo
forall a.
Map UnitId a
-> Map (PackageName, LibraryName) (Map Version [a])
-> PackageIndex a
PackageIndex Map UnitId InstalledPackageInfo
pids Map (PackageName, LibraryName) (Map Version [InstalledPackageInfo])
pnames
fromList :: [IPI.InstalledPackageInfo] -> InstalledPackageIndex
fromList :: [InstalledPackageInfo] -> PackageIndex InstalledPackageInfo
fromList [InstalledPackageInfo]
pkgs = WithCallStack
(Map UnitId InstalledPackageInfo
-> Map
(PackageName, LibraryName) (Map Version [InstalledPackageInfo])
-> PackageIndex InstalledPackageInfo)
Map UnitId InstalledPackageInfo
-> Map
(PackageName, LibraryName) (Map Version [InstalledPackageInfo])
-> PackageIndex InstalledPackageInfo
mkPackageIndex Map UnitId InstalledPackageInfo
pids (((Map Version (NonEmpty InstalledPackageInfo)
-> Map Version [InstalledPackageInfo])
-> Map
(PackageName, LibraryName)
(Map Version (NonEmpty InstalledPackageInfo))
-> Map
(PackageName, LibraryName) (Map Version [InstalledPackageInfo])
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((Map Version (NonEmpty InstalledPackageInfo)
-> Map Version [InstalledPackageInfo])
-> Map
(PackageName, LibraryName)
(Map Version (NonEmpty InstalledPackageInfo))
-> Map
(PackageName, LibraryName) (Map Version [InstalledPackageInfo]))
-> ((NonEmpty InstalledPackageInfo -> [InstalledPackageInfo])
-> Map Version (NonEmpty InstalledPackageInfo)
-> Map Version [InstalledPackageInfo])
-> (NonEmpty InstalledPackageInfo -> [InstalledPackageInfo])
-> Map
(PackageName, LibraryName)
(Map Version (NonEmpty InstalledPackageInfo))
-> Map
(PackageName, LibraryName) (Map Version [InstalledPackageInfo])
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (NonEmpty InstalledPackageInfo -> [InstalledPackageInfo])
-> Map Version (NonEmpty InstalledPackageInfo)
-> Map Version [InstalledPackageInfo]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap) NonEmpty InstalledPackageInfo -> [InstalledPackageInfo]
forall (t :: * -> *) a. Foldable t => t a -> [a]
toList Map
(PackageName, LibraryName)
(Map Version (NonEmpty InstalledPackageInfo))
pnames)
where
pids :: Map UnitId InstalledPackageInfo
pids = [(UnitId, InstalledPackageInfo)] -> Map UnitId InstalledPackageInfo
forall k a. Ord k => [(k, a)] -> Map k a
Map.fromList [ (InstalledPackageInfo -> UnitId
forall pkg. HasUnitId pkg => pkg -> UnitId
installedUnitId InstalledPackageInfo
pkg, InstalledPackageInfo
pkg) | InstalledPackageInfo
pkg <- [InstalledPackageInfo]
pkgs ]
pnames :: Map
(PackageName, LibraryName)
(Map Version (NonEmpty InstalledPackageInfo))
pnames =
[((PackageName, LibraryName),
Map Version (NonEmpty InstalledPackageInfo))]
-> Map
(PackageName, LibraryName)
(Map Version (NonEmpty InstalledPackageInfo))
forall k a. Ord k => [(k, a)] -> Map k a
Map.fromList
[ ((PackageName -> LibraryName -> (PackageName, LibraryName))
-> (InstalledPackageInfo -> PackageName)
-> (InstalledPackageInfo -> LibraryName)
-> InstalledPackageInfo
-> (PackageName, LibraryName)
forall (m :: * -> *) a1 a2 r.
Monad m =>
(a1 -> a2 -> r) -> m a1 -> m a2 -> m r
liftM2 (,) InstalledPackageInfo -> PackageName
forall pkg. Package pkg => pkg -> PackageName
packageName InstalledPackageInfo -> LibraryName
IPI.sourceLibName (NonEmpty InstalledPackageInfo -> InstalledPackageInfo
forall a. NonEmpty a -> a
NE.head NonEmpty InstalledPackageInfo
pkgsN), Map Version (NonEmpty InstalledPackageInfo)
pvers)
| NonEmpty InstalledPackageInfo
pkgsN <- (InstalledPackageInfo -> InstalledPackageInfo -> Bool)
-> [InstalledPackageInfo] -> [NonEmpty InstalledPackageInfo]
forall (f :: * -> *) a.
Foldable f =>
(a -> a -> Bool) -> f a -> [NonEmpty a]
NE.groupBy ((InstalledPackageInfo -> (PackageName, LibraryName))
-> InstalledPackageInfo -> InstalledPackageInfo -> Bool
forall a b. Eq a => (b -> a) -> b -> b -> Bool
equating ((PackageName -> LibraryName -> (PackageName, LibraryName))
-> (InstalledPackageInfo -> PackageName)
-> (InstalledPackageInfo -> LibraryName)
-> InstalledPackageInfo
-> (PackageName, LibraryName)
forall (m :: * -> *) a1 a2 r.
Monad m =>
(a1 -> a2 -> r) -> m a1 -> m a2 -> m r
liftM2 (,) InstalledPackageInfo -> PackageName
forall pkg. Package pkg => pkg -> PackageName
packageName InstalledPackageInfo -> LibraryName
IPI.sourceLibName))
([InstalledPackageInfo] -> [NonEmpty InstalledPackageInfo])
-> ([InstalledPackageInfo] -> [InstalledPackageInfo])
-> [InstalledPackageInfo]
-> [NonEmpty InstalledPackageInfo]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (InstalledPackageInfo -> InstalledPackageInfo -> Ordering)
-> [InstalledPackageInfo] -> [InstalledPackageInfo]
forall a. (a -> a -> Ordering) -> [a] -> [a]
sortBy ((InstalledPackageInfo -> (PackageName, LibraryName, Version))
-> InstalledPackageInfo -> InstalledPackageInfo -> Ordering
forall a b. Ord a => (b -> a) -> b -> b -> Ordering
comparing ((PackageName
-> LibraryName -> Version -> (PackageName, LibraryName, Version))
-> (InstalledPackageInfo -> PackageName)
-> (InstalledPackageInfo -> LibraryName)
-> (InstalledPackageInfo -> Version)
-> InstalledPackageInfo
-> (PackageName, LibraryName, Version)
forall (m :: * -> *) a1 a2 a3 r.
Monad m =>
(a1 -> a2 -> a3 -> r) -> m a1 -> m a2 -> m a3 -> m r
liftM3 (,,) InstalledPackageInfo -> PackageName
forall pkg. Package pkg => pkg -> PackageName
packageName InstalledPackageInfo -> LibraryName
IPI.sourceLibName InstalledPackageInfo -> Version
forall pkg. Package pkg => pkg -> Version
packageVersion))
([InstalledPackageInfo] -> [NonEmpty InstalledPackageInfo])
-> [InstalledPackageInfo] -> [NonEmpty InstalledPackageInfo]
forall a b. (a -> b) -> a -> b
$ [InstalledPackageInfo]
pkgs
, let pvers :: Map Version (NonEmpty InstalledPackageInfo)
pvers =
[(Version, NonEmpty InstalledPackageInfo)]
-> Map Version (NonEmpty InstalledPackageInfo)
forall k a. Ord k => [(k, a)] -> Map k a
Map.fromList
[ (InstalledPackageInfo -> Version
forall pkg. Package pkg => pkg -> Version
packageVersion (NonEmpty InstalledPackageInfo -> InstalledPackageInfo
forall a. NonEmpty a -> a
NE.head NonEmpty InstalledPackageInfo
pkgsNV),
(InstalledPackageInfo -> InstalledPackageInfo -> Bool)
-> NonEmpty InstalledPackageInfo -> NonEmpty InstalledPackageInfo
forall a. (a -> a -> Bool) -> NonEmpty a -> NonEmpty a
NE.nubBy ((InstalledPackageInfo -> UnitId)
-> InstalledPackageInfo -> InstalledPackageInfo -> Bool
forall a b. Eq a => (b -> a) -> b -> b -> Bool
equating InstalledPackageInfo -> UnitId
forall pkg. HasUnitId pkg => pkg -> UnitId
installedUnitId) (NonEmpty InstalledPackageInfo -> NonEmpty InstalledPackageInfo
forall a. NonEmpty a -> NonEmpty a
NE.reverse NonEmpty InstalledPackageInfo
pkgsNV))
| NonEmpty InstalledPackageInfo
pkgsNV <- (InstalledPackageInfo -> InstalledPackageInfo -> Bool)
-> NonEmpty InstalledPackageInfo -> [NonEmpty InstalledPackageInfo]
forall (f :: * -> *) a.
Foldable f =>
(a -> a -> Bool) -> f a -> [NonEmpty a]
NE.groupBy ((InstalledPackageInfo -> Version)
-> InstalledPackageInfo -> InstalledPackageInfo -> Bool
forall a b. Eq a => (b -> a) -> b -> b -> Bool
equating InstalledPackageInfo -> Version
forall pkg. Package pkg => pkg -> Version
packageVersion) NonEmpty InstalledPackageInfo
pkgsN
]
]
merge :: InstalledPackageIndex -> InstalledPackageIndex
-> InstalledPackageIndex
merge :: PackageIndex InstalledPackageInfo
-> PackageIndex InstalledPackageInfo
-> PackageIndex InstalledPackageInfo
merge (PackageIndex Map UnitId InstalledPackageInfo
pids1 Map (PackageName, LibraryName) (Map Version [InstalledPackageInfo])
pnames1) (PackageIndex Map UnitId InstalledPackageInfo
pids2 Map (PackageName, LibraryName) (Map Version [InstalledPackageInfo])
pnames2) =
WithCallStack
(Map UnitId InstalledPackageInfo
-> Map
(PackageName, LibraryName) (Map Version [InstalledPackageInfo])
-> PackageIndex InstalledPackageInfo)
Map UnitId InstalledPackageInfo
-> Map
(PackageName, LibraryName) (Map Version [InstalledPackageInfo])
-> PackageIndex InstalledPackageInfo
mkPackageIndex ((InstalledPackageInfo
-> InstalledPackageInfo -> InstalledPackageInfo)
-> Map UnitId InstalledPackageInfo
-> Map UnitId InstalledPackageInfo
-> Map UnitId InstalledPackageInfo
forall k a. Ord k => (a -> a -> a) -> Map k a -> Map k a -> Map k a
Map.unionWith (\InstalledPackageInfo
_ InstalledPackageInfo
y -> InstalledPackageInfo
y) Map UnitId InstalledPackageInfo
pids1 Map UnitId InstalledPackageInfo
pids2)
((Map Version [InstalledPackageInfo]
-> Map Version [InstalledPackageInfo]
-> Map Version [InstalledPackageInfo])
-> Map
(PackageName, LibraryName) (Map Version [InstalledPackageInfo])
-> Map
(PackageName, LibraryName) (Map Version [InstalledPackageInfo])
-> Map
(PackageName, LibraryName) (Map Version [InstalledPackageInfo])
forall k a. Ord k => (a -> a -> a) -> Map k a -> Map k a -> Map k a
Map.unionWith (([InstalledPackageInfo]
-> [InstalledPackageInfo] -> [InstalledPackageInfo])
-> Map Version [InstalledPackageInfo]
-> Map Version [InstalledPackageInfo]
-> Map Version [InstalledPackageInfo]
forall k a. Ord k => (a -> a -> a) -> Map k a -> Map k a -> Map k a
Map.unionWith [InstalledPackageInfo]
-> [InstalledPackageInfo] -> [InstalledPackageInfo]
mergeBuckets) Map (PackageName, LibraryName) (Map Version [InstalledPackageInfo])
pnames1 Map (PackageName, LibraryName) (Map Version [InstalledPackageInfo])
pnames2)
where
mergeBuckets :: [InstalledPackageInfo]
-> [InstalledPackageInfo] -> [InstalledPackageInfo]
mergeBuckets [InstalledPackageInfo]
xs [InstalledPackageInfo]
ys = [InstalledPackageInfo]
ys [InstalledPackageInfo]
-> [InstalledPackageInfo] -> [InstalledPackageInfo]
forall a. [a] -> [a] -> [a]
++ ([InstalledPackageInfo]
xs [InstalledPackageInfo]
-> [InstalledPackageInfo] -> [InstalledPackageInfo]
\\ [InstalledPackageInfo]
ys)
\\ :: [InstalledPackageInfo]
-> [InstalledPackageInfo] -> [InstalledPackageInfo]
(\\) = (InstalledPackageInfo -> InstalledPackageInfo -> Bool)
-> [InstalledPackageInfo]
-> [InstalledPackageInfo]
-> [InstalledPackageInfo]
forall a. (a -> a -> Bool) -> [a] -> [a] -> [a]
deleteFirstsBy ((InstalledPackageInfo -> UnitId)
-> InstalledPackageInfo -> InstalledPackageInfo -> Bool
forall a b. Eq a => (b -> a) -> b -> b -> Bool
equating InstalledPackageInfo -> UnitId
forall pkg. HasUnitId pkg => pkg -> UnitId
installedUnitId)
insert :: IPI.InstalledPackageInfo -> InstalledPackageIndex -> InstalledPackageIndex
insert :: InstalledPackageInfo
-> PackageIndex InstalledPackageInfo
-> PackageIndex InstalledPackageInfo
insert InstalledPackageInfo
pkg (PackageIndex Map UnitId InstalledPackageInfo
pids Map (PackageName, LibraryName) (Map Version [InstalledPackageInfo])
pnames) =
WithCallStack
(Map UnitId InstalledPackageInfo
-> Map
(PackageName, LibraryName) (Map Version [InstalledPackageInfo])
-> PackageIndex InstalledPackageInfo)
Map UnitId InstalledPackageInfo
-> Map
(PackageName, LibraryName) (Map Version [InstalledPackageInfo])
-> PackageIndex InstalledPackageInfo
mkPackageIndex Map UnitId InstalledPackageInfo
pids' Map (PackageName, LibraryName) (Map Version [InstalledPackageInfo])
pnames'
where
pids' :: Map UnitId InstalledPackageInfo
pids' = UnitId
-> InstalledPackageInfo
-> Map UnitId InstalledPackageInfo
-> Map UnitId InstalledPackageInfo
forall k a. Ord k => k -> a -> Map k a -> Map k a
Map.insert (InstalledPackageInfo -> UnitId
forall pkg. HasUnitId pkg => pkg -> UnitId
installedUnitId InstalledPackageInfo
pkg) InstalledPackageInfo
pkg Map UnitId InstalledPackageInfo
pids
pnames' :: Map (PackageName, LibraryName) (Map Version [InstalledPackageInfo])
pnames' = Map (PackageName, LibraryName) (Map Version [InstalledPackageInfo])
-> Map
(PackageName, LibraryName) (Map Version [InstalledPackageInfo])
insertPackageName Map (PackageName, LibraryName) (Map Version [InstalledPackageInfo])
pnames
insertPackageName :: Map (PackageName, LibraryName) (Map Version [InstalledPackageInfo])
-> Map
(PackageName, LibraryName) (Map Version [InstalledPackageInfo])
insertPackageName =
(Map Version [InstalledPackageInfo]
-> Map Version [InstalledPackageInfo]
-> Map Version [InstalledPackageInfo])
-> (PackageName, LibraryName)
-> Map Version [InstalledPackageInfo]
-> Map
(PackageName, LibraryName) (Map Version [InstalledPackageInfo])
-> Map
(PackageName, LibraryName) (Map Version [InstalledPackageInfo])
forall k a. Ord k => (a -> a -> a) -> k -> a -> Map k a -> Map k a
Map.insertWith (\Map Version [InstalledPackageInfo]
_ -> Map Version [InstalledPackageInfo]
-> Map Version [InstalledPackageInfo]
insertPackageVersion)
(InstalledPackageInfo -> PackageName
forall pkg. Package pkg => pkg -> PackageName
packageName InstalledPackageInfo
pkg, InstalledPackageInfo -> LibraryName
IPI.sourceLibName InstalledPackageInfo
pkg)
(Version
-> [InstalledPackageInfo] -> Map Version [InstalledPackageInfo]
forall k a. k -> a -> Map k a
Map.singleton (InstalledPackageInfo -> Version
forall pkg. Package pkg => pkg -> Version
packageVersion InstalledPackageInfo
pkg) [InstalledPackageInfo
pkg])
insertPackageVersion :: Map Version [InstalledPackageInfo]
-> Map Version [InstalledPackageInfo]
insertPackageVersion =
([InstalledPackageInfo]
-> [InstalledPackageInfo] -> [InstalledPackageInfo])
-> Version
-> [InstalledPackageInfo]
-> Map Version [InstalledPackageInfo]
-> Map Version [InstalledPackageInfo]
forall k a. Ord k => (a -> a -> a) -> k -> a -> Map k a -> Map k a
Map.insertWith (\[InstalledPackageInfo]
_ -> [InstalledPackageInfo] -> [InstalledPackageInfo]
insertPackageInstance)
(InstalledPackageInfo -> Version
forall pkg. Package pkg => pkg -> Version
packageVersion InstalledPackageInfo
pkg) [InstalledPackageInfo
pkg]
insertPackageInstance :: [InstalledPackageInfo] -> [InstalledPackageInfo]
insertPackageInstance [InstalledPackageInfo]
pkgs =
InstalledPackageInfo
pkg InstalledPackageInfo
-> [InstalledPackageInfo] -> [InstalledPackageInfo]
forall a. a -> [a] -> [a]
: (InstalledPackageInfo -> InstalledPackageInfo -> Bool)
-> InstalledPackageInfo
-> [InstalledPackageInfo]
-> [InstalledPackageInfo]
forall a. (a -> a -> Bool) -> a -> [a] -> [a]
deleteBy ((InstalledPackageInfo -> UnitId)
-> InstalledPackageInfo -> InstalledPackageInfo -> Bool
forall a b. Eq a => (b -> a) -> b -> b -> Bool
equating InstalledPackageInfo -> UnitId
forall pkg. HasUnitId pkg => pkg -> UnitId
installedUnitId) InstalledPackageInfo
pkg [InstalledPackageInfo]
pkgs
deleteUnitId :: UnitId -> InstalledPackageIndex
-> InstalledPackageIndex
deleteUnitId :: UnitId
-> PackageIndex InstalledPackageInfo
-> PackageIndex InstalledPackageInfo
deleteUnitId UnitId
ipkgid original :: PackageIndex InstalledPackageInfo
original@(PackageIndex Map UnitId InstalledPackageInfo
pids Map (PackageName, LibraryName) (Map Version [InstalledPackageInfo])
pnames) =
case (UnitId -> InstalledPackageInfo -> Maybe InstalledPackageInfo)
-> UnitId
-> Map UnitId InstalledPackageInfo
-> (Maybe InstalledPackageInfo, Map UnitId InstalledPackageInfo)
forall k a.
Ord k =>
(k -> a -> Maybe a) -> k -> Map k a -> (Maybe a, Map k a)
Map.updateLookupWithKey (\UnitId
_ InstalledPackageInfo
_ -> Maybe InstalledPackageInfo
forall a. Maybe a
Nothing) UnitId
ipkgid Map UnitId InstalledPackageInfo
pids of
(Maybe InstalledPackageInfo
Nothing, Map UnitId InstalledPackageInfo
_) -> PackageIndex InstalledPackageInfo
original
(Just InstalledPackageInfo
spkgid, Map UnitId InstalledPackageInfo
pids') -> WithCallStack
(Map UnitId InstalledPackageInfo
-> Map
(PackageName, LibraryName) (Map Version [InstalledPackageInfo])
-> PackageIndex InstalledPackageInfo)
Map UnitId InstalledPackageInfo
-> Map
(PackageName, LibraryName) (Map Version [InstalledPackageInfo])
-> PackageIndex InstalledPackageInfo
mkPackageIndex Map UnitId InstalledPackageInfo
pids'
(InstalledPackageInfo
-> Map
(PackageName, LibraryName) (Map Version [InstalledPackageInfo])
-> Map
(PackageName, LibraryName) (Map Version [InstalledPackageInfo])
deletePkgName InstalledPackageInfo
spkgid Map (PackageName, LibraryName) (Map Version [InstalledPackageInfo])
pnames)
where
deletePkgName :: InstalledPackageInfo
-> Map
(PackageName, LibraryName) (Map Version [InstalledPackageInfo])
-> Map
(PackageName, LibraryName) (Map Version [InstalledPackageInfo])
deletePkgName InstalledPackageInfo
spkgid =
(Map Version [InstalledPackageInfo]
-> Maybe (Map Version [InstalledPackageInfo]))
-> (PackageName, LibraryName)
-> Map
(PackageName, LibraryName) (Map Version [InstalledPackageInfo])
-> Map
(PackageName, LibraryName) (Map Version [InstalledPackageInfo])
forall k a. Ord k => (a -> Maybe a) -> k -> Map k a -> Map k a
Map.update (InstalledPackageInfo
-> Map Version [InstalledPackageInfo]
-> Maybe (Map Version [InstalledPackageInfo])
forall {pkg}.
Package pkg =>
pkg
-> Map Version [InstalledPackageInfo]
-> Maybe (Map Version [InstalledPackageInfo])
deletePkgVersion InstalledPackageInfo
spkgid) (InstalledPackageInfo -> PackageName
forall pkg. Package pkg => pkg -> PackageName
packageName InstalledPackageInfo
spkgid, InstalledPackageInfo -> LibraryName
IPI.sourceLibName InstalledPackageInfo
spkgid)
deletePkgVersion :: pkg
-> Map Version [InstalledPackageInfo]
-> Maybe (Map Version [InstalledPackageInfo])
deletePkgVersion pkg
spkgid =
(\Map Version [InstalledPackageInfo]
m -> if Map Version [InstalledPackageInfo] -> Bool
forall k a. Map k a -> Bool
Map.null Map Version [InstalledPackageInfo]
m then Maybe (Map Version [InstalledPackageInfo])
forall a. Maybe a
Nothing else Map Version [InstalledPackageInfo]
-> Maybe (Map Version [InstalledPackageInfo])
forall a. a -> Maybe a
Just Map Version [InstalledPackageInfo]
m)
(Map Version [InstalledPackageInfo]
-> Maybe (Map Version [InstalledPackageInfo]))
-> (Map Version [InstalledPackageInfo]
-> Map Version [InstalledPackageInfo])
-> Map Version [InstalledPackageInfo]
-> Maybe (Map Version [InstalledPackageInfo])
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ([InstalledPackageInfo] -> Maybe [InstalledPackageInfo])
-> Version
-> Map Version [InstalledPackageInfo]
-> Map Version [InstalledPackageInfo]
forall k a. Ord k => (a -> Maybe a) -> k -> Map k a -> Map k a
Map.update [InstalledPackageInfo] -> Maybe [InstalledPackageInfo]
deletePkgInstance (pkg -> Version
forall pkg. Package pkg => pkg -> Version
packageVersion pkg
spkgid)
deletePkgInstance :: [InstalledPackageInfo] -> Maybe [InstalledPackageInfo]
deletePkgInstance =
(\[InstalledPackageInfo]
xs -> if [InstalledPackageInfo] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [InstalledPackageInfo]
xs then Maybe [InstalledPackageInfo]
forall a. Maybe a
Nothing else [InstalledPackageInfo] -> Maybe [InstalledPackageInfo]
forall a. a -> Maybe a
Just [InstalledPackageInfo]
xs)
([InstalledPackageInfo] -> Maybe [InstalledPackageInfo])
-> ([InstalledPackageInfo] -> [InstalledPackageInfo])
-> [InstalledPackageInfo]
-> Maybe [InstalledPackageInfo]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (InstalledPackageInfo -> InstalledPackageInfo -> Bool)
-> InstalledPackageInfo
-> [InstalledPackageInfo]
-> [InstalledPackageInfo]
forall a. (a -> a -> Bool) -> a -> [a] -> [a]
List.deleteBy (\InstalledPackageInfo
_ InstalledPackageInfo
pkg -> InstalledPackageInfo -> UnitId
forall pkg. HasUnitId pkg => pkg -> UnitId
installedUnitId InstalledPackageInfo
pkg UnitId -> UnitId -> Bool
forall a. Eq a => a -> a -> Bool
== UnitId
ipkgid) InstalledPackageInfo
forall a. HasCallStack => a
undefined
deleteSourcePackageId :: PackageId -> InstalledPackageIndex
-> InstalledPackageIndex
deleteSourcePackageId :: PackageId
-> PackageIndex InstalledPackageInfo
-> PackageIndex InstalledPackageInfo
deleteSourcePackageId PackageId
pkgid original :: PackageIndex InstalledPackageInfo
original@(PackageIndex Map UnitId InstalledPackageInfo
pids Map (PackageName, LibraryName) (Map Version [InstalledPackageInfo])
pnames) =
case (PackageName, LibraryName)
-> Map
(PackageName, LibraryName) (Map Version [InstalledPackageInfo])
-> Maybe (Map Version [InstalledPackageInfo])
forall k a. Ord k => k -> Map k a -> Maybe a
Map.lookup (PackageId -> PackageName
forall pkg. Package pkg => pkg -> PackageName
packageName PackageId
pkgid, LibraryName
LMainLibName) Map (PackageName, LibraryName) (Map Version [InstalledPackageInfo])
pnames of
Maybe (Map Version [InstalledPackageInfo])
Nothing -> PackageIndex InstalledPackageInfo
original
Just Map Version [InstalledPackageInfo]
pvers -> case Version
-> Map Version [InstalledPackageInfo]
-> Maybe [InstalledPackageInfo]
forall k a. Ord k => k -> Map k a -> Maybe a
Map.lookup (PackageId -> Version
forall pkg. Package pkg => pkg -> Version
packageVersion PackageId
pkgid) Map Version [InstalledPackageInfo]
pvers of
Maybe [InstalledPackageInfo]
Nothing -> PackageIndex InstalledPackageInfo
original
Just [InstalledPackageInfo]
pkgs -> WithCallStack
(Map UnitId InstalledPackageInfo
-> Map
(PackageName, LibraryName) (Map Version [InstalledPackageInfo])
-> PackageIndex InstalledPackageInfo)
Map UnitId InstalledPackageInfo
-> Map
(PackageName, LibraryName) (Map Version [InstalledPackageInfo])
-> PackageIndex InstalledPackageInfo
mkPackageIndex
((Map UnitId InstalledPackageInfo
-> InstalledPackageInfo -> Map UnitId InstalledPackageInfo)
-> Map UnitId InstalledPackageInfo
-> [InstalledPackageInfo]
-> Map UnitId InstalledPackageInfo
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl' ((InstalledPackageInfo
-> Map UnitId InstalledPackageInfo
-> Map UnitId InstalledPackageInfo)
-> Map UnitId InstalledPackageInfo
-> InstalledPackageInfo
-> Map UnitId InstalledPackageInfo
forall a b c. (a -> b -> c) -> b -> a -> c
flip (UnitId
-> Map UnitId InstalledPackageInfo
-> Map UnitId InstalledPackageInfo
forall k a. Ord k => k -> Map k a -> Map k a
Map.delete (UnitId
-> Map UnitId InstalledPackageInfo
-> Map UnitId InstalledPackageInfo)
-> (InstalledPackageInfo -> UnitId)
-> InstalledPackageInfo
-> Map UnitId InstalledPackageInfo
-> Map UnitId InstalledPackageInfo
forall b c a. (b -> c) -> (a -> b) -> a -> c
. InstalledPackageInfo -> UnitId
forall pkg. HasUnitId pkg => pkg -> UnitId
installedUnitId)) Map UnitId InstalledPackageInfo
pids [InstalledPackageInfo]
pkgs)
(Map (PackageName, LibraryName) (Map Version [InstalledPackageInfo])
-> Map
(PackageName, LibraryName) (Map Version [InstalledPackageInfo])
forall {a}.
Map (PackageName, LibraryName) (Map Version a)
-> Map (PackageName, LibraryName) (Map Version a)
deletePkgName Map (PackageName, LibraryName) (Map Version [InstalledPackageInfo])
pnames)
where
deletePkgName :: Map (PackageName, LibraryName) (Map Version a)
-> Map (PackageName, LibraryName) (Map Version a)
deletePkgName =
(Map Version a -> Maybe (Map Version a))
-> (PackageName, LibraryName)
-> Map (PackageName, LibraryName) (Map Version a)
-> Map (PackageName, LibraryName) (Map Version a)
forall k a. Ord k => (a -> Maybe a) -> k -> Map k a -> Map k a
Map.update Map Version a -> Maybe (Map Version a)
forall {a}. Map Version a -> Maybe (Map Version a)
deletePkgVersion (PackageId -> PackageName
forall pkg. Package pkg => pkg -> PackageName
packageName PackageId
pkgid, LibraryName
LMainLibName)
deletePkgVersion :: Map Version a -> Maybe (Map Version a)
deletePkgVersion =
(\Map Version a
m -> if Map Version a -> Bool
forall k a. Map k a -> Bool
Map.null Map Version a
m then Maybe (Map Version a)
forall a. Maybe a
Nothing else Map Version a -> Maybe (Map Version a)
forall a. a -> Maybe a
Just Map Version a
m)
(Map Version a -> Maybe (Map Version a))
-> (Map Version a -> Map Version a)
-> Map Version a
-> Maybe (Map Version a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Version -> Map Version a -> Map Version a
forall k a. Ord k => k -> Map k a -> Map k a
Map.delete (PackageId -> Version
forall pkg. Package pkg => pkg -> Version
packageVersion PackageId
pkgid)
deletePackageName :: PackageName -> InstalledPackageIndex
-> InstalledPackageIndex
deletePackageName :: PackageName
-> PackageIndex InstalledPackageInfo
-> PackageIndex InstalledPackageInfo
deletePackageName PackageName
name original :: PackageIndex InstalledPackageInfo
original@(PackageIndex Map UnitId InstalledPackageInfo
pids Map (PackageName, LibraryName) (Map Version [InstalledPackageInfo])
pnames) =
case (PackageName, LibraryName)
-> Map
(PackageName, LibraryName) (Map Version [InstalledPackageInfo])
-> Maybe (Map Version [InstalledPackageInfo])
forall k a. Ord k => k -> Map k a -> Maybe a
Map.lookup (PackageName
name, LibraryName
LMainLibName) Map (PackageName, LibraryName) (Map Version [InstalledPackageInfo])
pnames of
Maybe (Map Version [InstalledPackageInfo])
Nothing -> PackageIndex InstalledPackageInfo
original
Just Map Version [InstalledPackageInfo]
pvers -> WithCallStack
(Map UnitId InstalledPackageInfo
-> Map
(PackageName, LibraryName) (Map Version [InstalledPackageInfo])
-> PackageIndex InstalledPackageInfo)
Map UnitId InstalledPackageInfo
-> Map
(PackageName, LibraryName) (Map Version [InstalledPackageInfo])
-> PackageIndex InstalledPackageInfo
mkPackageIndex
((Map UnitId InstalledPackageInfo
-> InstalledPackageInfo -> Map UnitId InstalledPackageInfo)
-> Map UnitId InstalledPackageInfo
-> [InstalledPackageInfo]
-> Map UnitId InstalledPackageInfo
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl' ((InstalledPackageInfo
-> Map UnitId InstalledPackageInfo
-> Map UnitId InstalledPackageInfo)
-> Map UnitId InstalledPackageInfo
-> InstalledPackageInfo
-> Map UnitId InstalledPackageInfo
forall a b c. (a -> b -> c) -> b -> a -> c
flip (UnitId
-> Map UnitId InstalledPackageInfo
-> Map UnitId InstalledPackageInfo
forall k a. Ord k => k -> Map k a -> Map k a
Map.delete (UnitId
-> Map UnitId InstalledPackageInfo
-> Map UnitId InstalledPackageInfo)
-> (InstalledPackageInfo -> UnitId)
-> InstalledPackageInfo
-> Map UnitId InstalledPackageInfo
-> Map UnitId InstalledPackageInfo
forall b c a. (b -> c) -> (a -> b) -> a -> c
. InstalledPackageInfo -> UnitId
forall pkg. HasUnitId pkg => pkg -> UnitId
installedUnitId)) Map UnitId InstalledPackageInfo
pids
([[InstalledPackageInfo]] -> [InstalledPackageInfo]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat (Map Version [InstalledPackageInfo] -> [[InstalledPackageInfo]]
forall k a. Map k a -> [a]
Map.elems Map Version [InstalledPackageInfo]
pvers)))
((PackageName, LibraryName)
-> Map
(PackageName, LibraryName) (Map Version [InstalledPackageInfo])
-> Map
(PackageName, LibraryName) (Map Version [InstalledPackageInfo])
forall k a. Ord k => k -> Map k a -> Map k a
Map.delete (PackageName
name, LibraryName
LMainLibName) Map (PackageName, LibraryName) (Map Version [InstalledPackageInfo])
pnames)
allPackages :: PackageIndex a -> [a]
allPackages :: forall a. PackageIndex a -> [a]
allPackages = Map UnitId a -> [a]
forall k a. Map k a -> [a]
Map.elems (Map UnitId a -> [a])
-> (PackageIndex a -> Map UnitId a) -> PackageIndex a -> [a]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PackageIndex a -> Map UnitId a
forall a. PackageIndex a -> Map UnitId a
unitIdIndex
allPackagesByName :: PackageIndex a -> [(PackageName, [a])]
allPackagesByName :: forall a. PackageIndex a -> [(PackageName, [a])]
allPackagesByName PackageIndex a
index =
[ (PackageName
pkgname, [[a]] -> [a]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat (Map Version [a] -> [[a]]
forall k a. Map k a -> [a]
Map.elems Map Version [a]
pvers))
| ((PackageName
pkgname, LibraryName
LMainLibName), Map Version [a]
pvers) <- Map (PackageName, LibraryName) (Map Version [a])
-> [((PackageName, LibraryName), Map Version [a])]
forall k a. Map k a -> [(k, a)]
Map.toList (PackageIndex a -> Map (PackageName, LibraryName) (Map Version [a])
forall a.
PackageIndex a -> Map (PackageName, LibraryName) (Map Version [a])
packageIdIndex PackageIndex a
index) ]
allPackagesBySourcePackageId :: HasUnitId a => PackageIndex a
-> [(PackageId, [a])]
allPackagesBySourcePackageId :: forall a. HasUnitId a => PackageIndex a -> [(PackageId, [a])]
allPackagesBySourcePackageId PackageIndex a
index =
[ (a -> PackageId
forall pkg. Package pkg => pkg -> PackageId
packageId a
ipkg, [a]
ipkgs)
| ((PackageName
_, LibraryName
LMainLibName), Map Version [a]
pvers) <- Map (PackageName, LibraryName) (Map Version [a])
-> [((PackageName, LibraryName), Map Version [a])]
forall k a. Map k a -> [(k, a)]
Map.toList (PackageIndex a -> Map (PackageName, LibraryName) (Map Version [a])
forall a.
PackageIndex a -> Map (PackageName, LibraryName) (Map Version [a])
packageIdIndex PackageIndex a
index)
, ipkgs :: [a]
ipkgs@(a
ipkg:[a]
_) <- Map Version [a] -> [[a]]
forall k a. Map k a -> [a]
Map.elems Map Version [a]
pvers ]
allPackagesBySourcePackageIdAndLibName :: HasUnitId a => PackageIndex a
-> [((PackageId, LibraryName), [a])]
allPackagesBySourcePackageIdAndLibName :: forall a.
HasUnitId a =>
PackageIndex a -> [((PackageId, LibraryName), [a])]
allPackagesBySourcePackageIdAndLibName PackageIndex a
index =
[ ((a -> PackageId
forall pkg. Package pkg => pkg -> PackageId
packageId a
ipkg, LibraryName
ln), [a]
ipkgs)
| ((PackageName
_, LibraryName
ln), Map Version [a]
pvers) <- Map (PackageName, LibraryName) (Map Version [a])
-> [((PackageName, LibraryName), Map Version [a])]
forall k a. Map k a -> [(k, a)]
Map.toList (PackageIndex a -> Map (PackageName, LibraryName) (Map Version [a])
forall a.
PackageIndex a -> Map (PackageName, LibraryName) (Map Version [a])
packageIdIndex PackageIndex a
index)
, ipkgs :: [a]
ipkgs@(a
ipkg:[a]
_) <- Map Version [a] -> [[a]]
forall k a. Map k a -> [a]
Map.elems Map Version [a]
pvers ]
lookupUnitId :: PackageIndex a -> UnitId
-> Maybe a
lookupUnitId :: forall a. PackageIndex a -> UnitId -> Maybe a
lookupUnitId PackageIndex a
index UnitId
uid = UnitId -> Map UnitId a -> Maybe a
forall k a. Ord k => k -> Map k a -> Maybe a
Map.lookup UnitId
uid (PackageIndex a -> Map UnitId a
forall a. PackageIndex a -> Map UnitId a
unitIdIndex PackageIndex a
index)
lookupComponentId :: PackageIndex a -> ComponentId
-> Maybe a
lookupComponentId :: forall a. PackageIndex a -> ComponentId -> Maybe a
lookupComponentId PackageIndex a
index ComponentId
cid =
UnitId -> Map UnitId a -> Maybe a
forall k a. Ord k => k -> Map k a -> Maybe a
Map.lookup (ComponentId -> UnitId
newSimpleUnitId ComponentId
cid) (PackageIndex a -> Map UnitId a
forall a. PackageIndex a -> Map UnitId a
unitIdIndex PackageIndex a
index)
lookupSourcePackageId :: PackageIndex a -> PackageId -> [a]
lookupSourcePackageId :: forall a. PackageIndex a -> PackageId -> [a]
lookupSourcePackageId PackageIndex a
index PackageId
pkgid =
case (PackageName, LibraryName)
-> Map (PackageName, LibraryName) (Map Version [a])
-> Maybe (Map Version [a])
forall k a. Ord k => k -> Map k a -> Maybe a
Map.lookup (PackageId -> PackageName
forall pkg. Package pkg => pkg -> PackageName
packageName PackageId
pkgid, LibraryName
LMainLibName) (PackageIndex a -> Map (PackageName, LibraryName) (Map Version [a])
forall a.
PackageIndex a -> Map (PackageName, LibraryName) (Map Version [a])
packageIdIndex PackageIndex a
index) of
Maybe (Map Version [a])
Nothing -> []
Just Map Version [a]
pvers -> case Version -> Map Version [a] -> Maybe [a]
forall k a. Ord k => k -> Map k a -> Maybe a
Map.lookup (PackageId -> Version
forall pkg. Package pkg => pkg -> Version
packageVersion PackageId
pkgid) Map Version [a]
pvers of
Maybe [a]
Nothing -> []
Just [a]
pkgs -> [a]
pkgs
lookupPackageId :: PackageIndex a -> PackageId -> Maybe a
lookupPackageId :: forall a. PackageIndex a -> PackageId -> Maybe a
lookupPackageId PackageIndex a
index PackageId
pkgid = case PackageIndex a -> PackageId -> [a]
forall a. PackageIndex a -> PackageId -> [a]
lookupSourcePackageId PackageIndex a
index PackageId
pkgid of
[] -> Maybe a
forall a. Maybe a
Nothing
[a
pkg] -> a -> Maybe a
forall a. a -> Maybe a
Just a
pkg
[a]
_ -> String -> Maybe a
forall a. HasCallStack => String -> a
error String
"Distribution.Simple.PackageIndex: multiple matches found"
lookupPackageName :: PackageIndex a -> PackageName
-> [(Version, [a])]
lookupPackageName :: forall a. PackageIndex a -> PackageName -> [(Version, [a])]
lookupPackageName PackageIndex a
index PackageName
name =
case (PackageName, LibraryName)
-> Map (PackageName, LibraryName) (Map Version [a])
-> Maybe (Map Version [a])
forall k a. Ord k => k -> Map k a -> Maybe a
Map.lookup (PackageName
name, LibraryName
LMainLibName) (PackageIndex a -> Map (PackageName, LibraryName) (Map Version [a])
forall a.
PackageIndex a -> Map (PackageName, LibraryName) (Map Version [a])
packageIdIndex PackageIndex a
index) of
Maybe (Map Version [a])
Nothing -> []
Just Map Version [a]
pvers -> Map Version [a] -> [(Version, [a])]
forall k a. Map k a -> [(k, a)]
Map.toList Map Version [a]
pvers
lookupDependency :: InstalledPackageIndex -> PackageName -> VersionRange
-> [(Version, [IPI.InstalledPackageInfo])]
lookupDependency :: PackageIndex InstalledPackageInfo
-> PackageName
-> VersionRange
-> [(Version, [InstalledPackageInfo])]
lookupDependency PackageIndex InstalledPackageInfo
index PackageName
pn VersionRange
vr =
PackageIndex InstalledPackageInfo
-> PackageName
-> VersionRange
-> LibraryName
-> [(Version, [InstalledPackageInfo])]
lookupInternalDependency PackageIndex InstalledPackageInfo
index PackageName
pn VersionRange
vr LibraryName
LMainLibName
lookupInternalDependency :: InstalledPackageIndex -> PackageName -> VersionRange
-> LibraryName
-> [(Version, [IPI.InstalledPackageInfo])]
lookupInternalDependency :: PackageIndex InstalledPackageInfo
-> PackageName
-> VersionRange
-> LibraryName
-> [(Version, [InstalledPackageInfo])]
lookupInternalDependency PackageIndex InstalledPackageInfo
index PackageName
name VersionRange
versionRange LibraryName
libn =
case (PackageName, LibraryName)
-> Map
(PackageName, LibraryName) (Map Version [InstalledPackageInfo])
-> Maybe (Map Version [InstalledPackageInfo])
forall k a. Ord k => k -> Map k a -> Maybe a
Map.lookup (PackageName
name, LibraryName
libn) (PackageIndex InstalledPackageInfo
-> Map
(PackageName, LibraryName) (Map Version [InstalledPackageInfo])
forall a.
PackageIndex a -> Map (PackageName, LibraryName) (Map Version [a])
packageIdIndex PackageIndex InstalledPackageInfo
index) of
Maybe (Map Version [InstalledPackageInfo])
Nothing -> []
Just Map Version [InstalledPackageInfo]
pvers -> [ (Version
ver, [InstalledPackageInfo]
pkgs')
| (Version
ver, [InstalledPackageInfo]
pkgs) <- Map Version [InstalledPackageInfo]
-> [(Version, [InstalledPackageInfo])]
forall k a. Map k a -> [(k, a)]
Map.toList Map Version [InstalledPackageInfo]
pvers
, Version
ver Version -> VersionRange -> Bool
`withinRange` VersionRange
versionRange
, let pkgs' :: [InstalledPackageInfo]
pkgs' = (InstalledPackageInfo -> Bool)
-> [InstalledPackageInfo] -> [InstalledPackageInfo]
forall a. (a -> Bool) -> [a] -> [a]
filter InstalledPackageInfo -> Bool
eligible [InstalledPackageInfo]
pkgs
, Bool -> Bool
not ([InstalledPackageInfo] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [InstalledPackageInfo]
pkgs')
]
where
eligible :: InstalledPackageInfo -> Bool
eligible InstalledPackageInfo
pkg = InstalledPackageInfo -> Bool
IPI.indefinite InstalledPackageInfo
pkg Bool -> Bool -> Bool
|| [(ModuleName, OpenModule)] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null (InstalledPackageInfo -> [(ModuleName, OpenModule)]
IPI.instantiatedWith InstalledPackageInfo
pkg)
searchByName :: PackageIndex a -> String -> SearchResult [a]
searchByName :: forall a. PackageIndex a -> String -> SearchResult [a]
searchByName PackageIndex a
index String
name =
case [ ((PackageName, LibraryName), Map Version [a])
pkgs | pkgs :: ((PackageName, LibraryName), Map Version [a])
pkgs@((PackageName
pname, LibraryName
LMainLibName),Map Version [a]
_) <- Map (PackageName, LibraryName) (Map Version [a])
-> [((PackageName, LibraryName), Map Version [a])]
forall k a. Map k a -> [(k, a)]
Map.toList (PackageIndex a -> Map (PackageName, LibraryName) (Map Version [a])
forall a.
PackageIndex a -> Map (PackageName, LibraryName) (Map Version [a])
packageIdIndex PackageIndex a
index)
, ShowS
lowercase (PackageName -> String
unPackageName PackageName
pname) String -> String -> Bool
forall a. Eq a => a -> a -> Bool
== String
lname ] of
[] -> SearchResult [a]
forall a. SearchResult a
None
[((PackageName, LibraryName)
_,Map Version [a]
pvers)] -> [a] -> SearchResult [a]
forall a. a -> SearchResult a
Unambiguous ([[a]] -> [a]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat (Map Version [a] -> [[a]]
forall k a. Map k a -> [a]
Map.elems Map Version [a]
pvers))
[((PackageName, LibraryName), Map Version [a])]
pkgss -> case (((PackageName, LibraryName), Map Version [a]) -> Bool)
-> [((PackageName, LibraryName), Map Version [a])]
-> Maybe ((PackageName, LibraryName), Map Version [a])
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Maybe a
find ((String -> PackageName
mkPackageName String
name PackageName -> PackageName -> Bool
forall a. Eq a => a -> a -> Bool
==) (PackageName -> Bool)
-> (((PackageName, LibraryName), Map Version [a]) -> PackageName)
-> ((PackageName, LibraryName), Map Version [a])
-> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (PackageName, LibraryName) -> PackageName
forall a b. (a, b) -> a
fst ((PackageName, LibraryName) -> PackageName)
-> (((PackageName, LibraryName), Map Version [a])
-> (PackageName, LibraryName))
-> ((PackageName, LibraryName), Map Version [a])
-> PackageName
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((PackageName, LibraryName), Map Version [a])
-> (PackageName, LibraryName)
forall a b. (a, b) -> a
fst) [((PackageName, LibraryName), Map Version [a])]
pkgss of
Just ((PackageName, LibraryName)
_,Map Version [a]
pvers) -> [a] -> SearchResult [a]
forall a. a -> SearchResult a
Unambiguous ([[a]] -> [a]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat (Map Version [a] -> [[a]]
forall k a. Map k a -> [a]
Map.elems Map Version [a]
pvers))
Maybe ((PackageName, LibraryName), Map Version [a])
Nothing -> [[a]] -> SearchResult [a]
forall a. [a] -> SearchResult a
Ambiguous ((((PackageName, LibraryName), Map Version [a]) -> [a])
-> [((PackageName, LibraryName), Map Version [a])] -> [[a]]
forall a b. (a -> b) -> [a] -> [b]
map ([[a]] -> [a]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat ([[a]] -> [a])
-> (((PackageName, LibraryName), Map Version [a]) -> [[a]])
-> ((PackageName, LibraryName), Map Version [a])
-> [a]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Map Version [a] -> [[a]]
forall k a. Map k a -> [a]
Map.elems (Map Version [a] -> [[a]])
-> (((PackageName, LibraryName), Map Version [a])
-> Map Version [a])
-> ((PackageName, LibraryName), Map Version [a])
-> [[a]]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((PackageName, LibraryName), Map Version [a]) -> Map Version [a]
forall a b. (a, b) -> b
snd) [((PackageName, LibraryName), Map Version [a])]
pkgss)
where lname :: String
lname = ShowS
lowercase String
name
data SearchResult a = None | Unambiguous a | Ambiguous [a]
searchByNameSubstring :: PackageIndex a -> String -> [a]
searchByNameSubstring :: forall a. PackageIndex a -> String -> [a]
searchByNameSubstring PackageIndex a
index String
searchterm =
PackageIndex a -> (String -> Bool) -> [a]
forall a. PackageIndex a -> (String -> Bool) -> [a]
searchWithPredicate PackageIndex a
index (\String
n -> String
lsearchterm String -> String -> Bool
forall a. Eq a => [a] -> [a] -> Bool
`isInfixOf` ShowS
lowercase String
n)
where lsearchterm :: String
lsearchterm = ShowS
lowercase String
searchterm
searchWithPredicate :: PackageIndex a -> (String -> Bool) -> [a]
searchWithPredicate :: forall a. PackageIndex a -> (String -> Bool) -> [a]
searchWithPredicate PackageIndex a
index String -> Bool
predicate =
[ a
pkg
| ((PackageName
pname, LibraryName
LMainLibName), Map Version [a]
pvers) <- Map (PackageName, LibraryName) (Map Version [a])
-> [((PackageName, LibraryName), Map Version [a])]
forall k a. Map k a -> [(k, a)]
Map.toList (PackageIndex a -> Map (PackageName, LibraryName) (Map Version [a])
forall a.
PackageIndex a -> Map (PackageName, LibraryName) (Map Version [a])
packageIdIndex PackageIndex a
index)
, String -> Bool
predicate (PackageName -> String
unPackageName PackageName
pname)
, [a]
pkgs <- Map Version [a] -> [[a]]
forall k a. Map k a -> [a]
Map.elems Map Version [a]
pvers
, a
pkg <- [a]
pkgs ]
dependencyCycles :: PackageInstalled a => PackageIndex a -> [[a]]
dependencyCycles :: forall a. PackageInstalled a => PackageIndex a -> [[a]]
dependencyCycles PackageIndex a
index =
[ [a]
vs | Graph.CyclicSCC [a]
vs <- [(a, UnitId, [UnitId])] -> [SCC a]
forall key node. Ord key => [(node, key, [key])] -> [SCC node]
Graph.stronglyConnComp [(a, UnitId, [UnitId])]
adjacencyList ]
where
adjacencyList :: [(a, UnitId, [UnitId])]
adjacencyList = [ (a
pkg, a -> UnitId
forall pkg. HasUnitId pkg => pkg -> UnitId
installedUnitId a
pkg, a -> [UnitId]
forall pkg. PackageInstalled pkg => pkg -> [UnitId]
installedDepends a
pkg)
| a
pkg <- PackageIndex a -> [a]
forall a. PackageIndex a -> [a]
allPackages PackageIndex a
index ]
brokenPackages :: PackageInstalled a => PackageIndex a
-> [(a, [UnitId])]
brokenPackages :: forall a. PackageInstalled a => PackageIndex a -> [(a, [UnitId])]
brokenPackages PackageIndex a
index =
[ (a
pkg, [UnitId]
missing)
| a
pkg <- PackageIndex a -> [a]
forall a. PackageIndex a -> [a]
allPackages PackageIndex a
index
, let missing :: [UnitId]
missing = [ UnitId
pkg' | UnitId
pkg' <- a -> [UnitId]
forall pkg. PackageInstalled pkg => pkg -> [UnitId]
installedDepends a
pkg
, Maybe a -> Bool
forall a. Maybe a -> Bool
isNothing (PackageIndex a -> UnitId -> Maybe a
forall a. PackageIndex a -> UnitId -> Maybe a
lookupUnitId PackageIndex a
index UnitId
pkg') ]
, Bool -> Bool
not ([UnitId] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [UnitId]
missing) ]
dependencyClosure :: InstalledPackageIndex
-> [UnitId]
-> Either (InstalledPackageIndex)
[(IPI.InstalledPackageInfo, [UnitId])]
dependencyClosure :: PackageIndex InstalledPackageInfo
-> [UnitId]
-> Either
(PackageIndex InstalledPackageInfo)
[(InstalledPackageInfo, [UnitId])]
dependencyClosure PackageIndex InstalledPackageInfo
index [UnitId]
pkgids0 = case PackageIndex InstalledPackageInfo
-> [UnitId]
-> [UnitId]
-> (PackageIndex InstalledPackageInfo, [UnitId])
closure PackageIndex InstalledPackageInfo
forall a. Monoid a => a
mempty [] [UnitId]
pkgids0 of
(PackageIndex InstalledPackageInfo
completed, []) -> PackageIndex InstalledPackageInfo
-> Either
(PackageIndex InstalledPackageInfo)
[(InstalledPackageInfo, [UnitId])]
forall a b. a -> Either a b
Left PackageIndex InstalledPackageInfo
completed
(PackageIndex InstalledPackageInfo
completed, [UnitId]
_) -> [(InstalledPackageInfo, [UnitId])]
-> Either
(PackageIndex InstalledPackageInfo)
[(InstalledPackageInfo, [UnitId])]
forall a b. b -> Either a b
Right (PackageIndex InstalledPackageInfo
-> [(InstalledPackageInfo, [UnitId])]
forall a. PackageInstalled a => PackageIndex a -> [(a, [UnitId])]
brokenPackages PackageIndex InstalledPackageInfo
completed)
where
closure :: PackageIndex InstalledPackageInfo
-> [UnitId]
-> [UnitId]
-> (PackageIndex InstalledPackageInfo, [UnitId])
closure PackageIndex InstalledPackageInfo
completed [UnitId]
failed [] = (PackageIndex InstalledPackageInfo
completed, [UnitId]
failed)
closure PackageIndex InstalledPackageInfo
completed [UnitId]
failed (UnitId
pkgid:[UnitId]
pkgids) = case PackageIndex InstalledPackageInfo
-> UnitId -> Maybe InstalledPackageInfo
forall a. PackageIndex a -> UnitId -> Maybe a
lookupUnitId PackageIndex InstalledPackageInfo
index UnitId
pkgid of
Maybe InstalledPackageInfo
Nothing -> PackageIndex InstalledPackageInfo
-> [UnitId]
-> [UnitId]
-> (PackageIndex InstalledPackageInfo, [UnitId])
closure PackageIndex InstalledPackageInfo
completed (UnitId
pkgidUnitId -> [UnitId] -> [UnitId]
forall a. a -> [a] -> [a]
:[UnitId]
failed) [UnitId]
pkgids
Just InstalledPackageInfo
pkg -> case PackageIndex InstalledPackageInfo
-> UnitId -> Maybe InstalledPackageInfo
forall a. PackageIndex a -> UnitId -> Maybe a
lookupUnitId PackageIndex InstalledPackageInfo
completed (InstalledPackageInfo -> UnitId
forall pkg. HasUnitId pkg => pkg -> UnitId
installedUnitId InstalledPackageInfo
pkg) of
Just InstalledPackageInfo
_ -> PackageIndex InstalledPackageInfo
-> [UnitId]
-> [UnitId]
-> (PackageIndex InstalledPackageInfo, [UnitId])
closure PackageIndex InstalledPackageInfo
completed [UnitId]
failed [UnitId]
pkgids
Maybe InstalledPackageInfo
Nothing -> PackageIndex InstalledPackageInfo
-> [UnitId]
-> [UnitId]
-> (PackageIndex InstalledPackageInfo, [UnitId])
closure PackageIndex InstalledPackageInfo
completed' [UnitId]
failed [UnitId]
pkgids'
where completed' :: PackageIndex InstalledPackageInfo
completed' = InstalledPackageInfo
-> PackageIndex InstalledPackageInfo
-> PackageIndex InstalledPackageInfo
insert InstalledPackageInfo
pkg PackageIndex InstalledPackageInfo
completed
pkgids' :: [UnitId]
pkgids' = InstalledPackageInfo -> [UnitId]
forall pkg. PackageInstalled pkg => pkg -> [UnitId]
installedDepends InstalledPackageInfo
pkg [UnitId] -> [UnitId] -> [UnitId]
forall a. [a] -> [a] -> [a]
++ [UnitId]
pkgids
reverseDependencyClosure :: PackageInstalled a => PackageIndex a
-> [UnitId]
-> [a]
reverseDependencyClosure :: forall a. PackageInstalled a => PackageIndex a -> [UnitId] -> [a]
reverseDependencyClosure PackageIndex a
index =
(Int -> a) -> [Int] -> [a]
forall a b. (a -> b) -> [a] -> [b]
map Int -> a
vertexToPkg
([Int] -> [a]) -> ([UnitId] -> [Int]) -> [UnitId] -> [a]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Tree Int -> [Int]) -> [Tree Int] -> [Int]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap Tree Int -> [Int]
forall a. Tree a -> [a]
Tree.flatten
([Tree Int] -> [Int])
-> ([UnitId] -> [Tree Int]) -> [UnitId] -> [Int]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Graph -> [Int] -> [Tree Int]
Graph.dfs Graph
reverseDepGraph
([Int] -> [Tree Int])
-> ([UnitId] -> [Int]) -> [UnitId] -> [Tree Int]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (UnitId -> Int) -> [UnitId] -> [Int]
forall a b. (a -> b) -> [a] -> [b]
map (Int -> Maybe Int -> Int
forall a. a -> Maybe a -> a
fromMaybe Int
forall {a}. a
noSuchPkgId (Maybe Int -> Int) -> (UnitId -> Maybe Int) -> UnitId -> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. UnitId -> Maybe Int
pkgIdToVertex)
where
(Graph
depGraph, Int -> a
vertexToPkg, UnitId -> Maybe Int
pkgIdToVertex) = PackageIndex a -> (Graph, Int -> a, UnitId -> Maybe Int)
forall a.
PackageInstalled a =>
PackageIndex a -> (Graph, Int -> a, UnitId -> Maybe Int)
dependencyGraph PackageIndex a
index
reverseDepGraph :: Graph
reverseDepGraph = Graph -> Graph
Graph.transposeG Graph
depGraph
noSuchPkgId :: a
noSuchPkgId = String -> a
forall a. HasCallStack => String -> a
error String
"reverseDependencyClosure: package is not in the graph"
topologicalOrder :: PackageInstalled a => PackageIndex a -> [a]
topologicalOrder :: forall a. PackageInstalled a => PackageIndex a -> [a]
topologicalOrder PackageIndex a
index = (Int -> a) -> [Int] -> [a]
forall a b. (a -> b) -> [a] -> [b]
map Int -> a
toPkgId
([Int] -> [a]) -> (Graph -> [Int]) -> Graph -> [a]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Graph -> [Int]
Graph.topSort
(Graph -> [a]) -> Graph -> [a]
forall a b. (a -> b) -> a -> b
$ Graph
graph
where (Graph
graph, Int -> a
toPkgId, UnitId -> Maybe Int
_) = PackageIndex a -> (Graph, Int -> a, UnitId -> Maybe Int)
forall a.
PackageInstalled a =>
PackageIndex a -> (Graph, Int -> a, UnitId -> Maybe Int)
dependencyGraph PackageIndex a
index
reverseTopologicalOrder :: PackageInstalled a => PackageIndex a -> [a]
reverseTopologicalOrder :: forall a. PackageInstalled a => PackageIndex a -> [a]
reverseTopologicalOrder PackageIndex a
index = (Int -> a) -> [Int] -> [a]
forall a b. (a -> b) -> [a] -> [b]
map Int -> a
toPkgId
([Int] -> [a]) -> (Graph -> [Int]) -> Graph -> [a]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Graph -> [Int]
Graph.topSort
(Graph -> [Int]) -> (Graph -> Graph) -> Graph -> [Int]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Graph -> Graph
Graph.transposeG
(Graph -> [a]) -> Graph -> [a]
forall a b. (a -> b) -> a -> b
$ Graph
graph
where (Graph
graph, Int -> a
toPkgId, UnitId -> Maybe Int
_) = PackageIndex a -> (Graph, Int -> a, UnitId -> Maybe Int)
forall a.
PackageInstalled a =>
PackageIndex a -> (Graph, Int -> a, UnitId -> Maybe Int)
dependencyGraph PackageIndex a
index
dependencyGraph :: PackageInstalled a => PackageIndex a
-> (Graph.Graph,
Graph.Vertex -> a,
UnitId -> Maybe Graph.Vertex)
dependencyGraph :: forall a.
PackageInstalled a =>
PackageIndex a -> (Graph, Int -> a, UnitId -> Maybe Int)
dependencyGraph PackageIndex a
index = (Graph
graph, Int -> a
vertex_to_pkg, UnitId -> Maybe Int
id_to_vertex)
where
graph :: Graph
graph = (Int, Int) -> [[Int]] -> Graph
forall i e. Ix i => (i, i) -> [e] -> Array i e
Array.listArray (Int, Int)
bounds
[ [ Int
v | Just Int
v <- (UnitId -> Maybe Int) -> [UnitId] -> [Maybe Int]
forall a b. (a -> b) -> [a] -> [b]
map UnitId -> Maybe Int
id_to_vertex (a -> [UnitId]
forall pkg. PackageInstalled pkg => pkg -> [UnitId]
installedDepends a
pkg) ]
| a
pkg <- [a]
pkgs ]
pkgs :: [a]
pkgs = (a -> a -> Ordering) -> [a] -> [a]
forall a. (a -> a -> Ordering) -> [a] -> [a]
sortBy ((a -> PackageId) -> a -> a -> Ordering
forall a b. Ord a => (b -> a) -> b -> b -> Ordering
comparing a -> PackageId
forall pkg. Package pkg => pkg -> PackageId
packageId) (PackageIndex a -> [a]
forall a. PackageIndex a -> [a]
allPackages PackageIndex a
index)
vertices :: [(UnitId, Int)]
vertices = [UnitId] -> [Int] -> [(UnitId, Int)]
forall a b. [a] -> [b] -> [(a, b)]
zip ((a -> UnitId) -> [a] -> [UnitId]
forall a b. (a -> b) -> [a] -> [b]
map a -> UnitId
forall pkg. HasUnitId pkg => pkg -> UnitId
installedUnitId [a]
pkgs) [Int
0..]
vertex_map :: Map UnitId Int
vertex_map = [(UnitId, Int)] -> Map UnitId Int
forall k a. Ord k => [(k, a)] -> Map k a
Map.fromList [(UnitId, Int)]
vertices
id_to_vertex :: UnitId -> Maybe Int
id_to_vertex UnitId
pid = UnitId -> Map UnitId Int -> Maybe Int
forall k a. Ord k => k -> Map k a -> Maybe a
Map.lookup UnitId
pid Map UnitId Int
vertex_map
vertex_to_pkg :: Int -> a
vertex_to_pkg Int
vertex = Array Int a
pkgTable Array Int a -> Int -> a
forall i e. Ix i => Array i e -> i -> e
! Int
vertex
pkgTable :: Array Int a
pkgTable = (Int, Int) -> [a] -> Array Int a
forall i e. Ix i => (i, i) -> [e] -> Array i e
Array.listArray (Int, Int)
bounds [a]
pkgs
topBound :: Int
topBound = [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [a]
pkgs Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1
bounds :: (Int, Int)
bounds = (Int
0, Int
topBound)
type DepUniqueKey = (PackageName, LibraryName, Map ModuleName OpenModule)
dependencyInconsistencies :: InstalledPackageIndex
-> [(DepUniqueKey,
[(UnitId,
[IPI.InstalledPackageInfo])])]
dependencyInconsistencies :: PackageIndex InstalledPackageInfo
-> [((PackageName, LibraryName, Map ModuleName OpenModule),
[(UnitId, [InstalledPackageInfo])])]
dependencyInconsistencies PackageIndex InstalledPackageInfo
index = do
((PackageName, LibraryName, Map ModuleName OpenModule)
dep_key, Map UnitId [InstalledPackageInfo]
insts_map) <- Map
(PackageName, LibraryName, Map ModuleName OpenModule)
(Map UnitId [InstalledPackageInfo])
-> [((PackageName, LibraryName, Map ModuleName OpenModule),
Map UnitId [InstalledPackageInfo])]
forall k a. Map k a -> [(k, a)]
Map.toList Map
(PackageName, LibraryName, Map ModuleName OpenModule)
(Map UnitId [InstalledPackageInfo])
inverseIndex
let insts :: [(UnitId, [InstalledPackageInfo])]
insts = Map UnitId [InstalledPackageInfo]
-> [(UnitId, [InstalledPackageInfo])]
forall k a. Map k a -> [(k, a)]
Map.toList Map UnitId [InstalledPackageInfo]
insts_map
Bool -> [()]
forall (f :: * -> *). Alternative f => Bool -> f ()
guard ([(UnitId, [InstalledPackageInfo])] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [(UnitId, [InstalledPackageInfo])]
insts Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
2)
((PackageName, LibraryName, Map ModuleName OpenModule),
[(UnitId, [InstalledPackageInfo])])
-> [((PackageName, LibraryName, Map ModuleName OpenModule),
[(UnitId, [InstalledPackageInfo])])]
forall (m :: * -> *) a. Monad m => a -> m a
return ((PackageName, LibraryName, Map ModuleName OpenModule)
dep_key, [(UnitId, [InstalledPackageInfo])]
insts)
where
inverseIndex :: Map DepUniqueKey (Map UnitId [IPI.InstalledPackageInfo])
inverseIndex :: Map
(PackageName, LibraryName, Map ModuleName OpenModule)
(Map UnitId [InstalledPackageInfo])
inverseIndex = (Map UnitId [InstalledPackageInfo]
-> Map UnitId [InstalledPackageInfo]
-> Map UnitId [InstalledPackageInfo])
-> [((PackageName, LibraryName, Map ModuleName OpenModule),
Map UnitId [InstalledPackageInfo])]
-> Map
(PackageName, LibraryName, Map ModuleName OpenModule)
(Map UnitId [InstalledPackageInfo])
forall k a. Ord k => (a -> a -> a) -> [(k, a)] -> Map k a
Map.fromListWith (([InstalledPackageInfo]
-> [InstalledPackageInfo] -> [InstalledPackageInfo])
-> Map UnitId [InstalledPackageInfo]
-> Map UnitId [InstalledPackageInfo]
-> Map UnitId [InstalledPackageInfo]
forall k a. Ord k => (a -> a -> a) -> Map k a -> Map k a -> Map k a
Map.unionWith [InstalledPackageInfo]
-> [InstalledPackageInfo] -> [InstalledPackageInfo]
forall a. [a] -> [a] -> [a]
(++)) ([((PackageName, LibraryName, Map ModuleName OpenModule),
Map UnitId [InstalledPackageInfo])]
-> Map
(PackageName, LibraryName, Map ModuleName OpenModule)
(Map UnitId [InstalledPackageInfo]))
-> [((PackageName, LibraryName, Map ModuleName OpenModule),
Map UnitId [InstalledPackageInfo])]
-> Map
(PackageName, LibraryName, Map ModuleName OpenModule)
(Map UnitId [InstalledPackageInfo])
forall a b. (a -> b) -> a -> b
$ do
InstalledPackageInfo
pkg <- PackageIndex InstalledPackageInfo -> [InstalledPackageInfo]
forall a. PackageIndex a -> [a]
allPackages PackageIndex InstalledPackageInfo
index
UnitId
dep_ipid <- InstalledPackageInfo -> [UnitId]
forall pkg. PackageInstalled pkg => pkg -> [UnitId]
installedDepends InstalledPackageInfo
pkg
Just InstalledPackageInfo
dep <- [PackageIndex InstalledPackageInfo
-> UnitId -> Maybe InstalledPackageInfo
forall a. PackageIndex a -> UnitId -> Maybe a
lookupUnitId PackageIndex InstalledPackageInfo
index UnitId
dep_ipid]
let dep_key :: (PackageName, LibraryName, Map ModuleName OpenModule)
dep_key = (InstalledPackageInfo -> PackageName
forall pkg. Package pkg => pkg -> PackageName
packageName InstalledPackageInfo
dep, InstalledPackageInfo -> LibraryName
IPI.sourceLibName InstalledPackageInfo
dep,
[(ModuleName, OpenModule)] -> Map ModuleName OpenModule
forall k a. Ord k => [(k, a)] -> Map k a
Map.fromList (InstalledPackageInfo -> [(ModuleName, OpenModule)]
IPI.instantiatedWith InstalledPackageInfo
dep))
((PackageName, LibraryName, Map ModuleName OpenModule),
Map UnitId [InstalledPackageInfo])
-> [((PackageName, LibraryName, Map ModuleName OpenModule),
Map UnitId [InstalledPackageInfo])]
forall (m :: * -> *) a. Monad m => a -> m a
return ((PackageName, LibraryName, Map ModuleName OpenModule)
dep_key, UnitId
-> [InstalledPackageInfo] -> Map UnitId [InstalledPackageInfo]
forall k a. k -> a -> Map k a
Map.singleton UnitId
dep_ipid [InstalledPackageInfo
pkg])
moduleNameIndex :: InstalledPackageIndex -> Map ModuleName [IPI.InstalledPackageInfo]
moduleNameIndex :: PackageIndex InstalledPackageInfo
-> Map ModuleName [InstalledPackageInfo]
moduleNameIndex PackageIndex InstalledPackageInfo
index =
([InstalledPackageInfo]
-> [InstalledPackageInfo] -> [InstalledPackageInfo])
-> [(ModuleName, [InstalledPackageInfo])]
-> Map ModuleName [InstalledPackageInfo]
forall k a. Ord k => (a -> a -> a) -> [(k, a)] -> Map k a
Map.fromListWith [InstalledPackageInfo]
-> [InstalledPackageInfo] -> [InstalledPackageInfo]
forall a. [a] -> [a] -> [a]
(++) ([(ModuleName, [InstalledPackageInfo])]
-> Map ModuleName [InstalledPackageInfo])
-> [(ModuleName, [InstalledPackageInfo])]
-> Map ModuleName [InstalledPackageInfo]
forall a b. (a -> b) -> a -> b
$ do
InstalledPackageInfo
pkg <- PackageIndex InstalledPackageInfo -> [InstalledPackageInfo]
forall a. PackageIndex a -> [a]
allPackages PackageIndex InstalledPackageInfo
index
IPI.ExposedModule ModuleName
m Maybe OpenModule
reexport <- InstalledPackageInfo -> [ExposedModule]
IPI.exposedModules InstalledPackageInfo
pkg
case Maybe OpenModule
reexport of
Maybe OpenModule
Nothing -> (ModuleName, [InstalledPackageInfo])
-> [(ModuleName, [InstalledPackageInfo])]
forall (m :: * -> *) a. Monad m => a -> m a
return (ModuleName
m, [InstalledPackageInfo
pkg])
Just (OpenModuleVar ModuleName
_) -> []
Just (OpenModule OpenUnitId
_ ModuleName
m') | ModuleName
m ModuleName -> ModuleName -> Bool
forall a. Eq a => a -> a -> Bool
== ModuleName
m' -> []
| Bool
otherwise -> (ModuleName, [InstalledPackageInfo])
-> [(ModuleName, [InstalledPackageInfo])]
forall (m :: * -> *) a. Monad m => a -> m a
return (ModuleName
m', [InstalledPackageInfo
pkg])