Skip to content

Commit

Permalink
Fix issue with uninstallable provides.
Browse files Browse the repository at this point in the history
  • Loading branch information
RichardLake committed Jun 2, 2015
1 parent 5fa77e9 commit 6f1fcef
Show file tree
Hide file tree
Showing 2 changed files with 158 additions and 139 deletions.
55 changes: 43 additions & 12 deletions Core/Relationships/RelationshipResolver.cs
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,8 @@ public object Clone()
// If we resolved in things breadth-first order, we're less likely to encounter surprises
// where a nth-deep recommend blocks a top-level recommend.

// TODO: Add mechanism so that clients can add mods with relationshup other than UserAdded.
// Currently only made to support the with_{} options.
// TODO: Add mechanism so that clients can add mods with relationshup other than UserAdded.
// Currently only made to support the with_{} options.
public class RelationshipResolver
{
// A list of all the mods we're going to install.
Expand Down Expand Up @@ -111,7 +111,7 @@ public RelationshipResolver(ICollection<CkanModule> modules, RelationshipResolve
{
log.DebugFormat("Preparing to resolve relationships for {0} {1}", module.identifier, module.version);

var module1 = module; //Silence a warning re. closures over foreach var.
var module1 = module; //Silence a warning re. closures over foreach var.
foreach (CkanModule listed_mod in modlist.Values.Where(listed_mod => listed_mod.ConflictsWith(module1)))
{
if (options.procede_with_inconsistencies)
Expand Down Expand Up @@ -155,7 +155,7 @@ public RelationshipResolver(ICollection<CkanModule> modules, RelationshipResolve
/// <summary>
/// Returns the default options for relationship resolution.
/// </summary>

// TODO: This should just be able to return a new RelationshipResolverOptions
// and the defaults in the class definition should do the right thing.
public static RelationshipResolverOptions DefaultOpts()
Expand Down Expand Up @@ -202,10 +202,10 @@ private void Resolve(CkanModule module, RelationshipResolverOptions options)
/// Resolve a relationship stanza (a list of relationships).
/// This will add modules to be installed, if required.
/// May recurse back to Resolve for those new modules.
///
///
/// If `soft_resolve` is true, we warn rather than throw exceptions on mods we cannot find.
/// If `soft_resolve` is false (default), we throw a ModuleNotFoundKraken if we can't find a dependency.
///
///
/// Throws a TooManyModsProvideKraken if we have too many choices and
/// options.without_toomanyprovides_kraken is not set.
///
Expand All @@ -232,7 +232,8 @@ private void ResolveStanza(IEnumerable<RelationshipDescriptor> stanza, Relations
continue;
}

List<CkanModule> candidates = registry.LatestAvailableWithProvides(dep_name, kspversion);
List<CkanModule> candidates = registry.LatestAvailableWithProvides(dep_name, kspversion)
.Where(mod=>MightBeInstallable(mod)).ToList();

if (candidates.Count == 0)
{
Expand Down Expand Up @@ -334,7 +335,37 @@ private void Add(CkanModule module, Relationship reason)
}

/// <summary>
/// Returns a list of all modules to install to satisify the changes required.
/// Tests that a module might be able to be installed via checking if dependencies
/// exist for current version.
/// </summary>
/// <param name="module">The module to consider</param>
/// <param name="compatible">For internal use</param>
/// <returns>If it has dependencies compatible for the current version</returns>
private bool MightBeInstallable(CkanModule module, List<string> compatible = null)
{
if (module.depends == null) return true;
if (compatible == null)
{
compatible = new List<string>();
}
else if (compatible.Contains(module.identifier))
{
return true;
}
//When checking the dependencies we assume that this module is installable
// in case a dependent depends on it
compatible.Add(module.identifier);

var needed = module.depends.Select(depend => registry.LatestAvailableWithProvides(depend.name, kspversion));
//We need every dependency to have at least one possible module
var installable = needed.All(need => need.Any(mod => MightBeInstallable(mod, compatible)));
compatible.Remove(module.identifier);
return installable;
}


/// <summary>
/// Returns a list of all modules to install to satisfy the changes required.
/// </summary>
public List<CkanModule> ModList()
{
Expand All @@ -344,7 +375,7 @@ public List<CkanModule> ModList()

/// <summary>
/// Returns a IList consisting of keyValuePairs containing conflicting mods.
/// Note: (a,b) in the list should imply that (b,a) is in the list.
/// Note: (a,b) in the list should imply that (b,a) is in the list.
/// </summary>
public Dictionary<Module, String> ConflictList
{
Expand Down Expand Up @@ -398,14 +429,14 @@ public string ReasonStringFor(Module mod)
}

/// <summary>
/// Used to keep track of the relationships between modules in the resolver.
/// Intended to be used for displaying messages to the user.
/// Used to keep track of the relationships between modules in the resolver.
/// Intended to be used for displaying messages to the user.
/// </summary>
internal abstract class Relationship
{
//Currently assumed to exist for any relationship other than useradded
public virtual CkanModule Parent { get; protected set; }
//Should contain a newline at the end of the string.
//Should contain a newline at the end of the string.
public abstract String Reason { get; }


Expand Down
Loading

0 comments on commit 6f1fcef

Please sign in to comment.