Ejemplo n.º 1
0
 public override List <CkanModule> LatestAvailableWithProvides(
     IRegistryQuerier registry, GameVersionCriteria crit, IEnumerable <CkanModule> installed = null,
     IEnumerable <CkanModule> toInstall = null
     )
 {
     return(registry.LatestAvailableWithProvides(name, crit, this, installed, toInstall));
 }
Ejemplo n.º 2
0
        private TreeNode findDependencyShallow(IRegistryQuerier registry, string identifier, RelationshipType relationship, KspVersionCriteria crit)
        {
            try
            {
                CkanModule dependencyModule = registry.LatestAvailable(identifier, crit);
                if (dependencyModule != null)
                {
                    return(indexedNode(registry, dependencyModule, relationship, crit != null));
                }
            }
            catch (ModuleNotFoundKraken)
            {
                // Maybe it's a DLC?
                ModuleVersion installedVersion = registry.InstalledVersion(identifier, false);
                if (installedVersion != null)
                {
                    return(nonModuleNode(identifier, installedVersion, relationship));
                }

                // If we don't find a module by this name, look for other modules that provide it.
                List <CkanModule> dependencyModules = registry.LatestAvailableWithProvides(identifier, crit);
                if (dependencyModules != null && dependencyModules.Count > 0)
                {
                    List <TreeNode> children = new List <TreeNode>();
                    foreach (CkanModule dep in dependencyModules)
                    {
                        children.Add(indexedNode(registry, dep, relationship, crit != null));
                    }
                    return(providesNode(identifier, relationship, children));
                }
            }
            return(null);
        }
Ejemplo n.º 3
0
        private TreeNode findDependencyShallow(IRegistryQuerier registry, string identifier, RelationshipType relationship, KspVersionCriteria crit)
        {
            // Maybe it's a DLC?
            ModuleVersion installedVersion = registry.InstalledVersion(identifier, false);

            if (installedVersion != null)
            {
                return(nonModuleNode(identifier, installedVersion, relationship));
            }

            // Find modules that satisfy this dependency
            List <CkanModule> dependencyModules = registry.LatestAvailableWithProvides(identifier, crit);

            if (dependencyModules.Count == 0)
            {
                // Nothing found, don't return a node
                return(null);
            }
            else if (dependencyModules.Count == 1 && dependencyModules[0].identifier == identifier)
            {
                // Only one exact match module, return a simple node
                return(indexedNode(registry, dependencyModules[0], relationship, crit != null));
            }
            else
            {
                // Several found or not same id, return a "provides" node
                return(providesNode(identifier, relationship,
                                    dependencyModules.Select(dep => indexedNode(registry, dep, relationship, crit != null))
                                    ));
            }
        }
Ejemplo n.º 4
0
 private void AddMod(IEnumerable <RelationshipDescriptor> relations, Dictionary <string, List <string> > chooseAble,
                     string identifier, IRegistryQuerier registry)
 {
     if (relations == null)
     {
         return;
     }
     foreach (RelationshipDescriptor mod in relations)
     {
         try
         {
             // if the mod is available for the current KSP version _and_
             // the mod is not installed _and_
             // the mod is not already in the install list
             if (registry.LatestAvailable(mod.name, CurrentInstance.VersionCriteria()) != null &&
                 !registry.IsInstalled(mod.name) &&
                 !toInstall.Any(m => m.identifier == mod.name))
             {
                 // add it to the list of chooseAble mods we display to the user
                 if (!chooseAble.ContainsKey(mod.name))
                 {
                     chooseAble.Add(mod.name, new List <string>());
                 }
                 chooseAble[mod.name].Add(identifier);
             }
         }
         catch (ModuleNotFoundKraken)
         {
             List <CkanModule> providers = registry.LatestAvailableWithProvides(
                 mod.name,
                 CurrentInstance.VersionCriteria(),
                 mod
                 );
             foreach (CkanModule provider in providers)
             {
                 if (!registry.IsInstalled(provider.identifier) &&
                     !toInstall.Any(m => m.identifier == provider.identifier))
                 {
                     // We want to show this mod to the user. Add it.
                     if (!chooseAble.ContainsKey(provider.identifier))
                     {
                         // Add a new entry if this provider isn't listed yet.
                         chooseAble.Add(provider.identifier, new List <string>());
                     }
                     // Add the dependent mod to the list of reasons this dependency is shown.
                     chooseAble[provider.identifier].Add(identifier);
                 }
             }
         }
         catch (Kraken)
         {
         }
     }
 }
Ejemplo n.º 5
0
 private void AddMod(
     IEnumerable <RelationshipDescriptor> relations,
     Dictionary <CkanModule, List <string> > chooseAble,
     string identifier,
     IRegistryQuerier registry,
     HashSet <CkanModule> toInstall)
 {
     if (relations == null)
     {
         return;
     }
     foreach (RelationshipDescriptor rel in relations)
     {
         List <CkanModule> providers = registry.LatestAvailableWithProvides(
             rel.name,
             CurrentInstance.VersionCriteria(),
             rel
             );
         foreach (CkanModule provider in providers)
         {
             if (!registry.IsInstalled(provider.identifier) &&
                 !toInstall.Any(m => m.identifier == provider.identifier))
             {
                 // We want to show this mod to the user. Add it.
                 List <string> dependers;
                 if (chooseAble.TryGetValue(provider, out dependers))
                 {
                     // Add the dependent mod to the list of reasons this dependency is shown.
                     dependers.Add(identifier);
                 }
                 else
                 {
                     // Add a new entry if this provider isn't listed yet.
                     chooseAble.Add(provider, new List <string>()
                     {
                         identifier
                     });
                 }
             }
         }
     }
 }
Ejemplo n.º 6
0
        /// <summary>
        /// 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.
        ///
        /// See RelationshipResolverOptions for further adjustments that can be made.
        ///
        /// </summary>

        private void ResolveStanza(IEnumerable <RelationshipDescriptor> stanza, SelectionReason reason,
                                   RelationshipResolverOptions options, bool soft_resolve = false, IEnumerable <RelationshipDescriptor> old_stanza = null)
        {
            if (stanza == null)
            {
                return;
            }

            foreach (var descriptor in stanza)
            {
                string dep_name = descriptor.name;
                log.DebugFormat("Considering {0}", dep_name);

                // If we already have this dependency covered, skip.
                // If it's already installed, skip.

                if (modlist.ContainsKey(dep_name))
                {
                    var module = modlist[dep_name];
                    if (descriptor.version_within_bounds(module.version))
                    {
                        continue;
                    }
                    //TODO Ideally we could check here if it can be replaced by the version we want.
                    if (options.procede_with_inconsistencies)
                    {
                        conflicts.Add(new KeyValuePair <CkanModule, CkanModule>(module, reason.Parent));
                        conflicts.Add(new KeyValuePair <CkanModule, CkanModule>(reason.Parent, module));
                        continue;
                    }
                    throw new InconsistentKraken(
                              string.Format(
                                  "{0} requires a version {1}. However a incompatible version, {2}, is in the resolver",
                                  dep_name, descriptor.RequiredVersion, module.version));
                }

                if (registry.IsInstalled(dep_name))
                {
                    if (descriptor.version_within_bounds(registry.InstalledVersion(dep_name)))
                    {
                        continue;
                    }
                    var module = registry.InstalledModule(dep_name).Module;

                    //TODO Ideally we could check here if it can be replaced by the version we want.
                    if (options.procede_with_inconsistencies)
                    {
                        conflicts.Add(new KeyValuePair <CkanModule, CkanModule>(module, reason.Parent));
                        conflicts.Add(new KeyValuePair <CkanModule, CkanModule>(reason.Parent, module));
                        continue;
                    }
                    throw new InconsistentKraken(
                              string.Format(
                                  "{0} requires a version {1}. However a incompatible version, {2}, is already installed",
                                  dep_name, descriptor.RequiredVersion, registry.InstalledVersion(dep_name)));
                }

                var descriptor1 = descriptor;
                List <CkanModule> candidates = registry.LatestAvailableWithProvides(dep_name, kspversion, descriptor)
                                               .Where(mod => descriptor1.version_within_bounds(mod.version) && MightBeInstallable(mod)).ToList();

                if (candidates.Count == 0)
                {
                    if (!soft_resolve)
                    {
                        log.ErrorFormat("Dependency on {0} found, but nothing provides it.", dep_name);
                        throw new ModuleNotFoundKraken(dep_name);
                    }
                    log.InfoFormat("{0} is recommended/suggested, but nothing provides it.", dep_name);
                    continue;
                }
                if (candidates.Count > 1)
                {
                    // Oh no, too many to pick from!
                    // TODO: It would be great if instead we picked the one with the
                    // most recommendations.
                    if (options.without_toomanyprovides_kraken)
                    {
                        continue;
                    }

                    // If we've got a parent stanza that has a relationship on a mod that provides what
                    // we need, then select that.
                    if (old_stanza != null)
                    {
                        List <CkanModule> provide = candidates.Where(can => old_stanza.Where(relation => can.identifier == relation.name).Any()).ToList();
                        if (!provide.Any() || provide.Count() > 1)
                        {
                            //We still have either nothing, or too my to pick from
                            //Just throw the TMP now
                            throw new TooManyModsProvideKraken(dep_name, candidates);
                        }
                        candidates[0] = provide.First();
                    }
                    else
                    {
                        throw new TooManyModsProvideKraken(dep_name, candidates);
                    }
                }

                CkanModule candidate = candidates[0];

                // Finally, check our candidate against everything which might object
                // to it being installed; that's all the mods which are fixed in our
                // list thus far, as well as everything on the system.

                var fixed_mods = new HashSet <CkanModule>(modlist.Values);
                fixed_mods.UnionWith(installed_modules);

                var conflicting_mod = fixed_mods.FirstOrDefault(mod => mod.ConflictsWith(candidate));
                if (conflicting_mod == null)
                {
                    // Okay, looks like we want this one. Adding.
                    Add(candidate, reason);
                    Resolve(candidate, options, stanza);
                }
                else if (soft_resolve)
                {
                    log.InfoFormat("{0} would cause conflicts, excluding it from consideration", candidate);
                }
                else
                {
                    if (options.procede_with_inconsistencies)
                    {
                        Add(candidate, reason);
                        conflicts.Add(new KeyValuePair <CkanModule, CkanModule>(conflicting_mod, candidate));
                        conflicts.Add(new KeyValuePair <CkanModule, CkanModule>(candidate, conflicting_mod));
                    }
                    else
                    {
                        throw new InconsistentKraken(string.Format("{0} conflicts with {1}, can't install both.", conflicting_mod,
                                                                   candidate));
                    }
                }
            }
        }
Ejemplo n.º 7
0
        private TreeNode UpdateModDependencyGraphRecursively(TreeNode parentNode, CfanModule module, RelationshipType relationship, int depth, bool virtualProvides = false)
        {
            if (module == null ||
                (depth > 0 && dependencyGraphRootModule == module) ||
                (alreadyVisited.Contains(module)))
            {
                return(null);
            }

            alreadyVisited.Add(module);

            string nodeText = module.title;

            if (virtualProvides)
            {
                nodeText = String.Format("provided by - {0}", module.title);
            }

            var node = parentNode == null ? new TreeNode(nodeText) : parentNode.Nodes.Add(nodeText);

            node.Name = module.title;

            IEnumerable <ModDependency> relationships = null;

            switch (relationship)
            {
            case RelationshipType.Depends:
                relationships = module.depends;
                break;

            case RelationshipType.Recommends:
                relationships = module.recommends;
                break;

            case RelationshipType.Suggests:
                relationships = module.suggests;
                break;

            case RelationshipType.Supports:
                relationships = module.supports;
                break;

            case RelationshipType.Conflicts:
                relationships = module.conflicts;
                break;
            }

            if (relationships == null)
            {
                return(node);
            }

            foreach (ModDependency dependency in relationships)
            {
                IRegistryQuerier registry = RegistryManager.Instance(manager.CurrentInstance).registry;

                try
                {
                    try
                    {
                        var dependencyModule = registry.LatestAvailable
                                                   (dependency.modName, manager.CurrentInstance.Version());
                        UpdateModDependencyGraphRecursively(node, dependencyModule, relationship, depth + 1);
                    }
                    catch (ModuleNotFoundKraken)
                    {
                        List <CfanModule> dependencyModules = registry.LatestAvailableWithProvides
                                                                  (dependency.modName, manager.CurrentInstance.Version());

                        if (dependencyModules == null)
                        {
                            continue;
                        }

                        var newNode = node.Nodes.Add(dependency.modName + " (virtual)");
                        newNode.ForeColor = Color.Gray;

                        foreach (var dep in dependencyModules)
                        {
                            UpdateModDependencyGraphRecursively(newNode, dep, relationship, depth + 1, true);
                        }
                    }
                }
                catch (Exception)
                {
                }
            }

            if (virtualProvides)
            {
                node.Collapse(true);
            }
            else
            {
                node.ExpandAll();
            }

            return(node);
        }