Deprecated: The each() function is deprecated. This message will be suppressed on further calls in /home/zhenxiangba/zhenxiangba.com/public_html/phproxy-improved-master/index.php on line 456
----------------------------------------------------------------------------- -- | -- Module : Hackage.DependencySet -- Copyright : (c) Duncan Coutts 2008 -- License : BSD-like -- -- Maintainer : duncan@haskell.org -- Stability : provisional -- Portability : portable -- -- A set of satisfiable dependencies (package version constraints). -- ----------------------------------------------------------------------------- module Hackage.DependencySet ( DependencySet, empty, insert, Satisfiable(..), ) where import Distribution.Package import Distribution.Version import Distribution.Simple.PackageIndex (PackageIndex) import qualified Distribution.Simple.PackageIndex as PackageIndex import Data.Map (Map) import qualified Data.Map as Map import Control.Exception (assert) -- | A set of constraints on package versions. For each package name we record -- what other packages depends on it and what constraints they impose on the -- version of the package. -- data Package pkg => DependencySet pkg = DependencySet (PackageIndex pkg) (Map String [(PackageIdentifier, VersionRange)]) invariant :: Package pkg => DependencySet pkg -> Bool invariant (DependencySet pkgs constraints) = all satisfiable [ Dependency pkgname (foldr1 IntersectVersionRanges (map snd constraints')) | (pkgname, constraints') <- Map.toList constraints ] where satisfiable = not . null . PackageIndex.lookupDependency pkgs -- | We construct a 'DependencySet' with an initial 'PackageIndex' -- of all the packages available. This will enable us to determine when adding -- constraints wether the new constraint is satisfiable or not. -- empty :: Package pkg => PackageIndex pkg -> DependencySet pkg empty pkgs = DependencySet pkgs Map.empty data Satisfiable a = Satisfiable a | Unsatisfiable | ConflictsWith [(PackageIdentifier, VersionRange)] insert :: Package pkg => Dependency -- ^ The subject of the dependency -> PackageIdentifier -- ^ The package imposing the dependency. -- We record this merely so we can report better errors. -> DependencySet pkg -> Satisfiable (DependencySet pkg) insert dep@(Dependency pkgid constraint) pkgid' depset@(DependencySet pkgs constraints) = assert (invariant depset) $ case PackageIndex.lookupDependency pkgs dep of [] -> Unsatisfiable pkgs' -> case Map.lookup pkgid constraints of Just existingConstraints -- We have some existing constraints on the version of pkg. We check -- if our new constraint conflicts with any of the existing ones: | constraint `confilctsWith` foldr1 IntersectVersionRanges (map snd existingConstraints) -- Since we know none of the existing constraints conflicted with each -- other then we know our new constraint must conflict with one or more -- of the existing ones: -> assert (not (null conflicts)) $ ConflictsWith conflicts where conflicts = filter (confilctsWith constraint . snd) existingConstraints _ -> assert (invariant depset') $ Satisfiable depset' where depset' = DependencySet pkgs constraints' constraints' = Map.insertWith (++) pkgid [(pkgid', constraint)] constraints where confilctsWith vr1 vr2 = not . any (`withinRange` IntersectVersionRanges vr1 vr2) . map (pkgVersion . packageId) $ pkgs'