Module CPM.Resolution

This module contains the dependency resolution algorithm.

Summary of exported operations:

resolveDependenciesFromLookupSet :: Config -> Package -> LookupSet -> ErrorLogger ResolutionResult  Deterministic 
Resolves the dependencies of a package using packages from a lookup set, inside an error logger.
resolve :: Config -> Package -> LookupSet -> ResolutionResult  Deterministic 
Resolves the dependencies of a package using packages from a lookup set.
resolvedPackages :: ResolutionResult -> [Package]  Deterministic 
Gives a list of all activated packages for a successful resolution.
resolutionSuccess :: ResolutionResult -> Bool  Deterministic 
Was a resolution successful?
showDependencies :: ResolutionResult -> String  Deterministic 
Renders a dependency tree from a successful resolution.
showShortDependencies :: ResolutionResult -> String  Deterministic 
Renders a dependency tree from a successful resolution in a short form where already shown packages are not fully shown again.
showConflict :: ResolutionResult -> String  Deterministic 
Renders a conflict resolution into a textual representation.
showResult :: ResolutionResult -> String  Deterministic 
Renders a resolution result into a textual representation for the user.
showShortResult :: ResolutionResult -> String  Deterministic 
Renders a resolution result into a short textual representation (where already shown packages are not shown again) for the user.
dependenciesAsGraph :: ResolutionResult -> Maybe DotGraph  Deterministic 
Shows a successful resolution as a (Graphviz) dot graph.
allTransitiveDependencies :: LookupSet -> String -> [String]  Deterministic 
transitiveDependencies :: LookupSet -> Package -> [String]  Deterministic 
isCompatibleToCompiler :: Config -> Package -> Bool  Deterministic 
isDisjunctionCompatible :: (Int,Int,Int,Maybe String) -> [[VersionConstraint]] -> Bool  Deterministic 

Exported datatypes:


ResolutionResult

Result of a resolution run. In case of success, it contains the original package as well as a list of resolved packages. If the resolution failed, it contains the conflict tree.

Constructors:


Exported operations:

resolveDependenciesFromLookupSet :: Config -> Package -> LookupSet -> ErrorLogger ResolutionResult  Deterministic 

Resolves the dependencies of a package using packages from a lookup set, inside an error logger.

resolve :: Config -> Package -> LookupSet -> ResolutionResult  Deterministic 

Resolves the dependencies of a package using packages from a lookup set. The base package of the current compiler is removed from the result set.

resolvedPackages :: ResolutionResult -> [Package]  Deterministic 

Gives a list of all activated packages for a successful resolution.

resolutionSuccess :: ResolutionResult -> Bool  Deterministic 

Was a resolution successful?

Further infos:
  • solution complete, i.e., able to compute all solutions

showDependencies :: ResolutionResult -> String  Deterministic 

Renders a dependency tree from a successful resolution.

showShortDependencies :: ResolutionResult -> String  Deterministic 

Renders a dependency tree from a successful resolution in a short form where already shown packages are not fully shown again.

showConflict :: ResolutionResult -> String  Deterministic 

Renders a conflict resolution into a textual representation.

showResult :: ResolutionResult -> String  Deterministic 

Renders a resolution result into a textual representation for the user. In case of success, the dependency tree is shown. In case of failure, information on the cause of the conflict is shown.

showShortResult :: ResolutionResult -> String  Deterministic 

Renders a resolution result into a short textual representation (where already shown packages are not shown again) for the user. In case of success, the shortened dependency tree is shown. In case of failure, information on the cause of the conflict is shown.

dependenciesAsGraph :: ResolutionResult -> Maybe DotGraph  Deterministic 

Shows a successful resolution as a (Graphviz) dot graph.

allTransitiveDependencies :: LookupSet -> String -> [String]  Deterministic 

transitiveDependencies :: LookupSet -> Package -> [String]  Deterministic 

Properties:

transitiveDependencies db pkg -=- ["B","C"] where pkg = cPackage "A" (0,0,1,Nothing) [cDep "B" ">= 1.0.0",cDep "C" "= 1.2.0"] b = cPackage "B" (1,0,9,Nothing) [] c = cPackage "C" (1,2,0,Nothing) [] db = cDB [b,c] (test_transitiveDependencies_simpleCase)
transitiveDependencies db pkg -=- ["B","C"] where pkg = cPackage "A" (0,0,1,Nothing) [cDep "B" ">= 1.0.0",cDep "C" "= 1.2.0"] b = cPackage "B" (1,0,0,Nothing) [cDep "C" "= 1.2.0"] c = cPackage "C" (1,2,0,Nothing) [cDep "B" ">= 1.0.0"] db = cDB [b,c] (test_transitiveDependencies_loop)
transitiveDependencies db pkg -=- ["B","D","C"] where pkg = cPackage "A" (0,0,1,Nothing) [cDep "B" ">= 1.0.0"] b100 = cPackage "B" (1,0,0,Nothing) [cDep "C" "= 1.0.0"] b110 = cPackage "B" (1,1,0,Nothing) [cDep "D" "= 1.0.0"] c = cPackage "C" (1,0,0,Nothing) [] d = cPackage "D" (1,0,0,Nothing) [] db = cDB [b100,b110,c,d] (test_transitiveDependencies_multipleVersions)

isCompatibleToCompiler :: Config -> Package -> Bool  Deterministic 

isDisjunctionCompatible :: (Int,Int,Int,Maybe String) -> [[VersionConstraint]] -> Bool  Deterministic 

Properties:

isDisjunctionCompatible ver dis -=- True where dis = cDisj "= 1.0.0" ver = (1,0,0,Nothing) (test_onlyConjunctionCompatible)
isDisjunctionCompatible ver dis -=- True where dis = cDisj ">= 1.0.0 || = 1.2.0" ver = (1,2,0,Nothing) (test_allConjunctionsCompatible)
isDisjunctionCompatible ver dis -=- True where ver = (1,0,0,Nothing) dis = cDisj "> 2.0.0 || = 1.0.0" (test_oneConjunctionCompatible)
isDisjunctionCompatible ver dis -=- True where ver = (1,0,0,Nothing) dis = cDisj ">= 1.0.0, < 2.0.0" (test_conjunctionWithMultipleParts)
isDisjunctionCompatible ver dis -=- False where ver = (1,0,0,Nothing) dis = cDisj "> 1.0.0" (test_reportsSimpleFailure)
isDisjunctionCompatible ver dis -=- False where ver = (1,0,0,Nothing) dis = cDisj "< 1.0.0 || > 1.0.0" (test_reportsAllConjunctionsAsFailure)
isDisjunctionCompatible ver dis -=- False where ver = (1,0,0,Nothing) dis = cDisj "< 1.0.0, > 0.5.0" (test_reportsRelevantPartOfConjunction)
isDisjunctionCompatible ver dis -=- True where ver = (0,5,9,Nothing) dis = cDisj "~> 0.5.0" (test_semverCompatible)
isDisjunctionCompatible ver dis -=- False where ver = (0,7,1,Nothing) dis = cDisj "~> 0.6.0" (test_semverIncompatible)
isDisjunctionCompatible ver dis -=- False where ver = (0,7,0,Nothing) dis = cDisj "~> 0.7.2" (test_semverMinimum)
maybeResolvedPackages (resolve defaultConfig pkg db) -=- Just [json100,pkg] where pkg = cPackage "sample" (0,0,1,Nothing) [cDep "json" "=1.0.0"] json100 = cPackage "json" (1,0,0,Nothing) [] json101 = cPackage "json" (1,0,1,Nothing) [] db = cDB [json100,json101] (test_resolvesSimpleDependency)
showResult result -=- "There seems to be no version of package json that can satisfy the constraint json = 1.0.0" where result = resolve defaultConfig pkg db pkg = cPackage "sample" (0,0,1,Nothing) [cDep "json" "= 1.0.0"] db = cDB [pkg] (test_reportsUnknownPackage)
showResult result -=- "There seems to be no version of package json that can satisfy the constraint json = 1.2.0" where result = resolve defaultConfig pkg db pkg = cPackage "sample" (0,0,1,Nothing) [cDep "json" "=1.2.0"] json = cPackage "json" (1,0,0,Nothing) [] db = cDB [json] (test_reportsMissingPackageVersion)
showResult result -=- expectedMessage where result = resolve defaultConfig pkg db pkg = cPackage "sample" (0,0,1,Nothing) [cDep "json" "= 1.0.0",cDep "b" ">= 0.0.1"] b = cPackage "b" (0,0,2,Nothing) [cDep "json" "~> 1.0.4"] json100 = cPackage "json" (1,0,0,Nothing) [] json105 = cPackage "json" (1,0,5,Nothing) [] db = cDB [pkg,b,json100,json105] expectedMessage = "There was a conflict for package json\n" ++ ("sample\n" ++ (" |- json (json = 1.0.0)\n" ++ ("sample\n" ++ (" |- b (b >= 0.0.1)\n" ++ " |- json (json ~1.0.4)")))) (test_reportsSecondaryConflict)
showResult result -=- expectedMessage where result = resolve defaultConfig pkg db pkg = cPackage "sample" (0,0,1,Nothing) [cDep "json" "= 1.0.0",cDep "b" ">= 0.0.5"] b001 = cPackage "b" (0,0,1,Nothing) [] b002 = cPackage "b" (0,0,2,Nothing) [] b003 = cPackage "b" (0,0,3,Nothing) [] b006 = cPackage "b" (0,0,6,Nothing) [cDep "json" "~> 1.0.4"] json100 = cPackage "json" (1,0,0,Nothing) [] json105 = cPackage "json" (1,0,5,Nothing) [] db = cDB [pkg,b001,b002,b003,b006,json100,json105] expectedMessage = "There was a conflict for package json\n" ++ ("sample\n" ++ (" |- json (json = 1.0.0)\n" ++ ("sample\n" ++ (" |- b (b >= 0.0.5)\n" ++ " |- json (json ~1.0.4)")))) (test_reportsSecondaryConflictInsteadOfPrimary)
showResult result -=- expectedMessage where result = resolve defaultConfig pkg db pkg = cPackage "sample" (0,0,1,Nothing) [cDep "a" "= 0.0.1",cDep "b" "> 0.0.1"] a001 = cPackage "a" (0,0,1,Nothing) [cDep "b" "= 0.0.1"] b001 = cPackage "b" (0,0,1,Nothing) [] b002 = cPackage "b" (0,0,2,Nothing) [] db = cDB [pkg,a001,b001,b002] expectedMessage = "There was a conflict for package b\n" ++ ("sample\n" ++ (" |- a (a = 0.0.1)\n" ++ (" |- b (b = 0.0.1)\n" ++ ("sample\n" ++ " |- b (b > 0.0.1)")))) (test_detectsSecondaryOnFirstActivation)
maybeResolvedPackages (resolve defaultConfig pkg db) -=- Just [json150,pkg] where pkg = cPackage "sample" (0,0,1,Nothing) [cDep "json" "> 1.0.0, < 2.0.0 || >= 4.0.0"] json150 = cPackage "json" (1,5,0,Nothing) [] json320 = cPackage "json" (3,2,0,Nothing) [] db = cDB [json150,json320] (test_makesDecisionBetweenAlternatives)
maybeResolvedPackages (resolve defaultConfig pkg db) -=- Just [json420,pkg] where pkg = cPackage "sample" (0,0,1,Nothing) [cDep "json" "> 1.0.0, < 2.0.0 || >= 4.0.0"] json150 = cPackage "json" (1,5,0,Nothing) [] json420 = cPackage "json" (4,2,0,Nothing) [] db = cDB [json150,json420] (test_alwaysChoosesNewestAlternative)
maybeResolvedPackages (resolve defaultConfig pkg db) -=- Just [b109,pkg] where pkg = cPackage "A" (0,0,1,Nothing) [cDep "B" ">= 1.0.0"] b109 = cPackage "B" (1,0,9,Nothing) [] b110b1 = cPackage "B" (1,1,0,Just "b1") [] db = cDB [b109,b110b1] (test_doesNotChoosePrereleaseByDefault)
maybeResolvedPackages (resolve defaultConfig pkg db) -=- Just [b110b1,c,pkg] where pkg = cPackage "A" (0,0,1,Nothing) [cDep "C" "= 1.2.0"] b109 = cPackage "B" (1,0,9,Nothing) [] b110b1 = cPackage "B" (1,1,0,Just "b1") [] c = cPackage "C" (1,2,0,Nothing) [cDep "B" ">= 1.1.0-b1"] db = cDB [b109,b110b1,c] (test_upgradesPackageToPrereleaseWhenNeccesary)
maybeResolvedPackages (resolve defaultConfig pkg db) -=- Just [b101,pkg] where pkg = cPackage "A" (0,0,1,Nothing) [cDep "B" ">= 1.0.0"] b101 = cPackage "B" (1,0,1,Nothing) [] b105 = cPackage "B" (1,0,5,Nothing) [] db = addPackage (addPackage emptySet b101 FromLocalCache) b105 FromRepository (test_prefersLocalPackageCacheEvenIfOlder)
showResult result -=- "The package json-1.0.0, dependency constraint json = 1.0.0, is not compatible to the current compiler. It was activated because:\nPackage dependencies:\nsample\n |- json (json = 1.0.0)" where result = resolve defaultConfig pkg db pkg = cPackage "sample" (0,0,1,Nothing) [cDep "json" "= 1.0.0"] json = cPackageCC "json" (1,0,0,Nothing) [cCC "nocompiler" "= 1.0.0"] db = cDB [json] (test_reportsCompilerIncompatibility)