From 63054d2a8647ab8e2322df261ffa11518cbd791a Mon Sep 17 00:00:00 2001 From: Richard Lake Date: Mon, 1 Jun 2015 16:04:06 +0930 Subject: [PATCH] Fix issue with uninstallable provides. See https://github.com/KSP-CKAN/CKAN-GUI/pull/137#issuecomment-107031168 for description --- Core/Relationships/RelationshipResolver.cs | 32 ++- .../Relationships/RelationshipResolver.cs | 242 +++++++++--------- 2 files changed, 136 insertions(+), 138 deletions(-) diff --git a/Core/Relationships/RelationshipResolver.cs b/Core/Relationships/RelationshipResolver.cs index 331ee597f0..aa303a7c45 100644 --- a/Core/Relationships/RelationshipResolver.cs +++ b/Core/Relationships/RelationshipResolver.cs @@ -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. @@ -111,7 +111,7 @@ public RelationshipResolver(ICollection 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) @@ -155,7 +155,7 @@ public RelationshipResolver(ICollection modules, RelationshipResolve /// /// Returns the default options for relationship resolution. /// - + // 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() @@ -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. /// @@ -232,7 +232,8 @@ private void ResolveStanza(IEnumerable stanza, Relations continue; } - List candidates = registry.LatestAvailableWithProvides(dep_name, kspversion); + List candidates = registry.LatestAvailableWithProvides(dep_name, kspversion) + .Where(MightBeInstallable).ToList(); if (candidates.Count == 0) { @@ -333,6 +334,15 @@ private void Add(CkanModule module, Relationship reason) } } + private bool MightBeInstallable(CkanModule module) + { + if(module.depends==null) return true; + var needed = module.depends.Select(depend => registry.LatestAvailableWithProvides(depend.name, kspversion)); + //We need every dependency to have at least one possible module + return needed.All(need => need.Any(MightBeInstallable)); + } + + /// /// Returns a list of all modules to install to satisify the changes required. /// @@ -344,7 +354,7 @@ public List ModList() /// /// 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. /// public Dictionary ConflictList { @@ -398,14 +408,14 @@ public string ReasonStringFor(Module mod) } /// - /// 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. /// 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; } diff --git a/Tests/Core/Relationships/RelationshipResolver.cs b/Tests/Core/Relationships/RelationshipResolver.cs index b2a84ab4c8..82553ceb7c 100644 --- a/Tests/Core/Relationships/RelationshipResolver.cs +++ b/Tests/Core/Relationships/RelationshipResolver.cs @@ -8,8 +8,7 @@ namespace Tests.Core.Relationships { - [TestFixture] - public class RelationshipResolverTests + [TestFixture] public class RelationshipResolverTests { private CKAN.Registry registry; private RelationshipResolverOptions options; @@ -43,13 +42,13 @@ public void Constructor_WithConflictingModules() var mod_a = generator.GeneratorRandomModule(); var mod_b = generator.GeneratorRandomModule(conflicts: new List { - new RelationshipDescriptor {name=mod_a.identifier} + new RelationshipDescriptor {name = mod_a.identifier} }); list.Add(mod_a.identifier); list.Add(mod_b.identifier); AddToRegistry(mod_a, mod_b); - + Assert.Throws(() => new RelationshipResolver( list, options, @@ -65,16 +64,14 @@ public void Constructor_WithConflictingModules() Assert.That(resolver.ConflictList, Has.Count.EqualTo(2)); } - [Test] - [Category("Version")] - [Explicit("Versions relationships not implemented")] + [Test, Category("Version"), Explicit("Versions relationships not implemented")] public void Constructor_WithConflictingModulesVersion_Throws() { var list = new List(); var mod_a = generator.GeneratorRandomModule(); var mod_b = generator.GeneratorRandomModule(conflicts: new List { - new RelationshipDescriptor {name=mod_a.identifier, version=mod_a.version.ToString()} + new RelationshipDescriptor {name = mod_a.identifier, version = mod_a.version.ToString()} }); list.Add(mod_a.identifier); @@ -88,18 +85,16 @@ public void Constructor_WithConflictingModulesVersion_Throws() null)); } - [Test] - [Category("Version")] - [Explicit("Versions relationships not implemented")] - [TestCase("1.0", "0.5")] - [TestCase("1.0", "1.0")] + [Test, Category("Version"), Explicit("Versions relationships not implemented")] + [TestCase("1.0", "0.5"), + TestCase("1.0", "1.0")] public void Constructor_WithConflictingModulesVersionMin_Throws(string ver, string conf_min) { var list = new List(); var mod_a = generator.GeneratorRandomModule(version: new Version(ver)); var mod_b = generator.GeneratorRandomModule(conflicts: new List { - new RelationshipDescriptor {name=mod_a.identifier, min_version=conf_min} + new RelationshipDescriptor {name = mod_a.identifier, min_version = conf_min} }); list.Add(mod_a.identifier); @@ -113,18 +108,16 @@ public void Constructor_WithConflictingModulesVersionMin_Throws(string ver, stri null)); } - [Test] - [Category("Version")] - [Explicit("Versions relationships not implemented")] - [TestCase("1.0", "2.0")] - [TestCase("1.0", "1.0")] + [Test, Category("Version"), Explicit("Versions relationships not implemented")] + [TestCase("1.0", "2.0"), + TestCase("1.0", "1.0")] public void Constructor_WithConflictingModulesVersionMax_Throws(string ver, string conf_max) { var list = new List(); var mod_a = generator.GeneratorRandomModule(version: new Version(ver)); var mod_b = generator.GeneratorRandomModule(conflicts: new List { - new RelationshipDescriptor {name=mod_a.identifier, max_version=conf_max} + new RelationshipDescriptor {name = mod_a.identifier, max_version = conf_max} }); list.Add(mod_a.identifier); @@ -138,19 +131,17 @@ public void Constructor_WithConflictingModulesVersionMax_Throws(string ver, stri null)); } - [Test] - [Category("Version")] - [Explicit("Versions relationships not implemented")] - [TestCase("1.0", "0.5", "2.0")] - [TestCase("1.0", "1.0", "2.0")] - [TestCase("1.0", "0.5", "1.0")] + [Test, Category("Version"), Explicit("Versions relationships not implemented")] + [TestCase("1.0", "0.5", "2.0"), + TestCase("1.0", "1.0", "2.0"), + TestCase("1.0", "0.5", "1.0")] public void Constructor_WithConflictingModulesVersionMinMax_Throws(string ver, string conf_min, string conf_max) { var list = new List(); var mod_a = generator.GeneratorRandomModule(version: new Version(ver)); var mod_b = generator.GeneratorRandomModule(conflicts: new List { - new RelationshipDescriptor {name=mod_a.identifier, min_version=conf_min, max_version=conf_max} + new RelationshipDescriptor {name = mod_a.identifier, min_version = conf_min, max_version = conf_max} }); list.Add(mod_a.identifier); @@ -164,18 +155,16 @@ public void Constructor_WithConflictingModulesVersionMinMax_Throws(string ver, s null)); } - [Test] - [Category("Version")] - [Explicit("Versions relationships not implemented")] - [TestCase("1.0", "0.5")] - [TestCase("1.0", "2.0")] + [Test, Category("Version"), Explicit("Versions relationships not implemented")] + [TestCase("1.0", "0.5"), + TestCase("1.0", "2.0")] public void Constructor_WithNonConflictingModulesVersion_DoesNotThrows(string ver, string conf) { var list = new List(); var mod_a = generator.GeneratorRandomModule(version: new Version(ver)); var mod_b = generator.GeneratorRandomModule(conflicts: new List { - new RelationshipDescriptor {name=mod_a.identifier, version=conf} + new RelationshipDescriptor {name = mod_a.identifier, version = conf} }); list.Add(mod_a.identifier); @@ -189,9 +178,7 @@ public void Constructor_WithNonConflictingModulesVersion_DoesNotThrows(string ve null)); } - [Test] - [Category("Version")] - [Explicit("Versions relationships not implemented")] + [Test, Category("Version"), Explicit("Versions relationships not implemented")] [TestCase("1.0", "2.0")] public void Constructor_WithConflictingModulesVersionMin_DoesNotThrows(string ver, string conf_min) { @@ -199,7 +186,7 @@ public void Constructor_WithConflictingModulesVersionMin_DoesNotThrows(string ve var mod_a = generator.GeneratorRandomModule(version: new Version(ver)); var mod_b = generator.GeneratorRandomModule(conflicts: new List { - new RelationshipDescriptor {name=mod_a.identifier, min_version="2.0"} + new RelationshipDescriptor {name = mod_a.identifier, min_version = "2.0"} }); list.Add(mod_a.identifier); @@ -213,9 +200,7 @@ public void Constructor_WithConflictingModulesVersionMin_DoesNotThrows(string ve null)); } - [Test] - [Category("Version")] - [Explicit("Versions relationships not implemented")] + [Test, Category("Version"), Explicit("Versions relationships not implemented")] [TestCase("1.0", "2.0")] public void Constructor_WithConflictingModulesVersionMax_DoesNotThrows(string ver, string conf_max) { @@ -223,7 +208,7 @@ public void Constructor_WithConflictingModulesVersionMax_DoesNotThrows(string ve var mod_a = generator.GeneratorRandomModule(version: new Version(ver)); var mod_b = generator.GeneratorRandomModule(conflicts: new List { - new RelationshipDescriptor {name=mod_a.identifier, max_version=conf_max} + new RelationshipDescriptor {name = mod_a.identifier, max_version = conf_max} }); list.Add(mod_a.identifier); @@ -237,18 +222,17 @@ public void Constructor_WithConflictingModulesVersionMax_DoesNotThrows(string ve null)); } - [Test] - [Category("Version")] - [Explicit("Versions relationships not implemented")] - [TestCase("1.0", "2.0", "3.0")] - [TestCase("4.0", "2.0", "3.0")] - public void Constructor_WithConflictingModulesVersionMinMax_DoesNotThrows(string ver, string conf_min, string conf_max) + [Test, Category("Version"), Explicit("Versions relationships not implemented")] + [TestCase("1.0", "2.0", "3.0"), + TestCase("4.0", "2.0", "3.0")] + public void Constructor_WithConflictingModulesVersionMinMax_DoesNotThrows(string ver, string conf_min, + string conf_max) { var list = new List(); var mod_a = generator.GeneratorRandomModule(version: new Version(ver)); var mod_b = generator.GeneratorRandomModule(conflicts: new List { - new RelationshipDescriptor {name=mod_a.identifier, min_version=conf_min, max_version=conf_max} + new RelationshipDescriptor {name = mod_a.identifier, min_version = conf_min, max_version = conf_max} }); list.Add(mod_a.identifier); @@ -279,7 +263,7 @@ public void Constructor_WithMultipleModulesProviding_Throws() }); var mod_d = generator.GeneratorRandomModule(depends: new List { - new RelationshipDescriptor {name=mod_a.identifier} + new RelationshipDescriptor {name = mod_a.identifier} }); list.Add(mod_d.identifier); @@ -289,7 +273,32 @@ public void Constructor_WithMultipleModulesProviding_Throws() options, registry, null)); + } + [Test] + public void WithMultipleModulesProviding_AllButOneHasUnmatchDependancy_DoesNotThrow() + { + options.without_toomanyprovides_kraken = false; + + var list = new List(); + var mod_a = generator.GeneratorRandomModule(); + var mod_b = generator.GeneratorRandomModule(provides: new List + { + mod_a.identifier + }); + var mod_c = generator.GeneratorRandomModule(provides: new List + { + mod_a.identifier + }, depends: new List {new RelationshipDescriptor {name = "invaild"}}); + var mod_d = generator.GeneratorRandomModule(depends: new List + { + new RelationshipDescriptor {name = mod_a.identifier} + }); + + list.Add(mod_d.identifier); + AddToRegistry(mod_b, mod_c, mod_d); + var mod_list = new RelationshipResolver(list,options,registry,null).ModList(); + Assert.That(mod_list,Contains.Item(mod_b)); } [Test] @@ -304,7 +313,6 @@ public void Constructor_WithMissingModules_Throws() options, registry, null)); - } // Right now our RR always returns the modules it was provided. However @@ -312,7 +320,7 @@ public void Constructor_WithMissingModules_Throws() // return a list *without* them. This isn't a hard error at the moment, // since ModuleInstaller.InstallList will ignore already installed mods, but // it would be nice to have. Discussed a little in GH #521. - [Test][Category("TODO")][Explicit] + [Test, Category("TODO"), Explicit] public void ModList_WithInstalledModules_DoesNotContainThem() { var list = new List(); @@ -378,7 +386,7 @@ public void Constructor_WithConflictingModulesInDependancies_ThrowUnderDefaultSe }); var conflicts_with_dependant = generator.GeneratorRandomModule(conflicts: new List { - new RelationshipDescriptor {name=dependant.identifier} + new RelationshipDescriptor {name = dependant.identifier} }); @@ -460,7 +468,6 @@ public void Constructor_ProvidesSatisfyDependencies() mod_b, depender }); - } @@ -481,16 +488,13 @@ public void Constructor_WithMissingDependants_Throws() options, registry, null)); - } - [Test] - [Category("Version")] - [Explicit("Versions relationships not implemented")] - [TestCase("1.0", "2.0")] - [TestCase("1.0", "0.2")] - [TestCase("0", "0.2")] - [TestCase("1.0", "0")] + [Test, Category("Version"), Explicit("Versions relationships not implemented")] + [TestCase("1.0", "2.0"), + TestCase("1.0", "0.2"), + TestCase("0", "0.2"), + TestCase("1.0", "0")] public void Constructor_WithMissingDependantsVersion_Throws(string ver, string dep) { var list = new List(); @@ -508,12 +512,9 @@ public void Constructor_WithMissingDependantsVersion_Throws(string ver, string d options, registry, null)); - } - [Test] - [Category("Version")] - [Explicit("Versions relationships not implemented")] + [Test, Category("Version"), Explicit("Versions relationships not implemented")] [TestCase("1.0", "2.0")] public void Constructor_WithMissingDependantsVersionMin_Throws(string ver, string dep_min) { @@ -532,12 +533,9 @@ public void Constructor_WithMissingDependantsVersionMin_Throws(string ver, strin options, registry, null)); - } - [Test] - [Category("Version")] - [Explicit("Versions relationships not implemented")] + [Test, Category("Version"), Explicit("Versions relationships not implemented")] [TestCase("1.0", "0.5")] public void Constructor_WithMissingDependantsVersionMax_Throws(string ver, string dep_max) { @@ -556,14 +554,11 @@ public void Constructor_WithMissingDependantsVersionMax_Throws(string ver, strin options, registry, null)); - } - [Test] - [Category("Version")] - [Explicit("Versions relationships not implemented")] - [TestCase("1.0", "2.0", "3.0")] - [TestCase("4.0", "2.0", "3.0")] + [Test, Category("Version"), Explicit("Versions relationships not implemented")] + [TestCase("1.0", "2.0", "3.0"), + TestCase("4.0", "2.0", "3.0")] public void Constructor_WithMissingDependantsVersionMinMax_Throws(string ver, string dep_min, string dep_max) { var list = new List(); @@ -581,19 +576,18 @@ public void Constructor_WithMissingDependantsVersionMinMax_Throws(string ver, st options, registry, null)); - } - [Test] - [Category("Version")] - [Explicit("Versions relationships not implemented")] - [TestCase("1.0", "1.0", "2.0")] - [TestCase("1.0", "1.0", "0.5")]//what to do if a mod is present twice with the same version ? + [Test, Category("Version"), Explicit("Versions relationships not implemented")] + [TestCase("1.0", "1.0", "2.0"), + TestCase("1.0", "1.0", "0.5")] + //what to do if a mod is present twice with the same version ? public void Constructor_WithDependantVersion_ChooseCorrectly(string ver, string dep, string other) { var list = new List(); var dependant = generator.GeneratorRandomModule(version: new Version(ver)); - var other_dependant = generator.GeneratorRandomModule(identifier: dependant.identifier, version: new Version(other)); + var other_dependant = generator.GeneratorRandomModule(identifier: dependant.identifier, + version: new Version(other)); var depender = generator.GeneratorRandomModule(depends: new List { @@ -611,20 +605,18 @@ public void Constructor_WithDependantVersion_ChooseCorrectly(string ver, string dependant, depender }); - } - [Test] - [Category("Version")] - [Explicit("Versions relationships not implemented")] - [TestCase("2.0", "1.0", "0.5")] - [TestCase("2.0", "1.0", "1.5")] - [TestCase("2.0", "2.0", "0.5")] + [Test, Category("Version"), Explicit("Versions relationships not implemented")] + [TestCase("2.0", "1.0", "0.5"), + TestCase("2.0", "1.0", "1.5"), + TestCase("2.0", "2.0", "0.5")] public void Constructor_WithDependantVersionMin_ChooseCorrectly(string ver, string dep_min, string other) { var list = new List(); var dependant = generator.GeneratorRandomModule(version: new Version(ver)); - var other_dependant = generator.GeneratorRandomModule(identifier: dependant.identifier, version: new Version(other)); + var other_dependant = generator.GeneratorRandomModule(identifier: dependant.identifier, + version: new Version(other)); var depender = generator.GeneratorRandomModule(depends: new List { @@ -641,20 +633,18 @@ public void Constructor_WithDependantVersionMin_ChooseCorrectly(string ver, stri dependant, depender }); - } - [Test] - [Category("Version")] - [Explicit("Versions relationships not implemented")] - [TestCase("2.0", "2.0", "0.5")] - [TestCase("2.0", "3.0", "0.5")] - [TestCase("2.0", "3.0", "4.0")] + [Test, Category("Version"), Explicit("Versions relationships not implemented")] + [TestCase("2.0", "2.0", "0.5"), + TestCase("2.0", "3.0", "0.5"), + TestCase("2.0", "3.0", "4.0")] public void Constructor_WithDependantVersionMax_ChooseCorrectly(string ver, string dep_max, string other) { var list = new List(); var dependant = generator.GeneratorRandomModule(version: new Version(ver)); - var other_dependant = generator.GeneratorRandomModule(identifier: dependant.identifier, version: new Version(other)); + var other_dependant = generator.GeneratorRandomModule(identifier: dependant.identifier, + version: new Version(other)); var depender = generator.GeneratorRandomModule(depends: new List { @@ -671,20 +661,19 @@ public void Constructor_WithDependantVersionMax_ChooseCorrectly(string ver, stri dependant, depender }); - } - [Test] - [Category("Version")] - [Explicit("Versions relationships not implemented")] - [TestCase("2.0", "1.0", "3.0", "0.5")] - [TestCase("2.0", "1.0", "3.0", "1.5")] - [TestCase("2.0", "1.0", "3.0", "3.5")] - public void Constructor_WithDependantVersionMinMax_ChooseCorrectly(string ver, string dep_min, string dep_max, string other) + [Test, Category("Version"), Explicit("Versions relationships not implemented"), + TestCase("2.0", "1.0", "3.0", "0.5"), + TestCase("2.0", "1.0", "3.0", "1.5"), + TestCase("2.0", "1.0", "3.0", "3.5")] + public void Constructor_WithDependantVersionMinMax_ChooseCorrectly(string ver, string dep_min, string dep_max, + string other) { var list = new List(); var dependant = generator.GeneratorRandomModule(version: new Version(ver)); - var other_dependant = generator.GeneratorRandomModule(identifier: dependant.identifier, version: new Version(other)); + var other_dependant = generator.GeneratorRandomModule(identifier: dependant.identifier, + version: new Version(other)); var depender = generator.GeneratorRandomModule(depends: new List { @@ -701,7 +690,6 @@ public void Constructor_WithDependantVersionMinMax_ChooseCorrectly(string ver, s dependant, depender }); - } [Test] @@ -733,23 +721,22 @@ public void ReasonFor_WithModsNotInList_ThrowsArgumentException() var relationship_resolver = new RelationshipResolver(list, options, registry, null); var mod_not_in_resolver_list = generator.GeneratorRandomModule(); - CollectionAssert.DoesNotContain(relationship_resolver.ModList(),mod_not_in_resolver_list); + CollectionAssert.DoesNotContain(relationship_resolver.ModList(), mod_not_in_resolver_list); Assert.Throws(() => relationship_resolver.ReasonFor(mod_not_in_resolver_list)); - } [Test] public void ReasonFor_WithUserAddedMods_GivesReasonUserAdded() { var list = new List(); - var mod = generator.GeneratorRandomModule(); + var mod = generator.GeneratorRandomModule(); list.Add(mod.identifier); registry.AddAvailable(mod); AddToRegistry(mod); var relationship_resolver = new RelationshipResolver(list, options, registry, null); var reason = relationship_resolver.ReasonFor(mod); - Assert.That(reason,Is.AssignableTo()); + Assert.That(reason, Is.AssignableTo()); } [Test] @@ -757,31 +744,37 @@ public void ReasonFor_WithSugestedMods_GivesCorrectParent() { var list = new List(); var sugested = generator.GeneratorRandomModule(); - var mod = generator.GeneratorRandomModule(sugests: new List {new RelationshipDescriptor { name = sugested.identifier } } ); - list.Add(mod.identifier); - AddToRegistry(mod,sugested); + var mod = + generator.GeneratorRandomModule(sugests: + new List {new RelationshipDescriptor {name = sugested.identifier}}); + list.Add(mod.identifier); + AddToRegistry(mod, sugested); options.with_all_suggests = true; var relationship_resolver = new RelationshipResolver(list, options, registry, null); var reason = relationship_resolver.ReasonFor(sugested); Assert.That(reason, Is.AssignableTo()); - Assert.That(reason.Parent,Is.EqualTo(mod)); + Assert.That(reason.Parent, Is.EqualTo(mod)); } [Test] public void ReasonFor_WithTreeOfMods_GivesCorrectParents() { - var list = new List(); + var list = new List(); var sugested = generator.GeneratorRandomModule(); var recommendedA = generator.GeneratorRandomModule(); var recommendedB = generator.GeneratorRandomModule(); - var mod = generator.GeneratorRandomModule(sugests: new List { new RelationshipDescriptor { name = sugested.identifier}}); + var mod = + generator.GeneratorRandomModule(sugests: + new List {new RelationshipDescriptor {name = sugested.identifier}}); list.Add(mod.identifier); sugested.recommends = new List - { new RelationshipDescriptor {name=recommendedA.identifier}, - new RelationshipDescriptor { name = recommendedB.identifier}}; + { + new RelationshipDescriptor {name = recommendedA.identifier}, + new RelationshipDescriptor {name = recommendedB.identifier} + }; - AddToRegistry(mod, sugested,recommendedA,recommendedB); + AddToRegistry(mod, sugested, recommendedA, recommendedB); options.with_all_suggests = true; @@ -797,11 +790,6 @@ public void ReasonFor_WithTreeOfMods_GivesCorrectParents() } - - - - - private void AddToRegistry(params CkanModule[] modules) { foreach (var module in modules) @@ -810,4 +798,4 @@ private void AddToRegistry(params CkanModule[] modules) } } } -} +} \ No newline at end of file