Beispiel #1
0
        public void SingleDownload()
        {
            // Force log4net on.
            // BasicConfigurator.Configure();
            // LogManager.GetRepository().Threshold = Level.Debug;
            log.Info("Performing single download test.");

            // We know kOS is in the TestKAN data, and hosted in KS. Let's get it.

            var modules = new List <CfanModule>();

            CfanModule kOS = registry.LatestAvailable("kOS", null);

            Assert.IsNotNull(kOS);

            modules.Add(kOS);

            // Make sure we don't alread have kOS somehow.
            Assert.IsFalse(cache.IsCached(kOS.download));

            //
            log.InfoFormat("Downloading kOS from {0}", kOS.download);

            // Download our module.
            async.DownloadModules(
                ksp.KSP.Cache,
                modules
                );

            // Assert that we have it, and it passes zip validation.
            Assert.IsTrue(cache.IsCachedZip(kOS.download));
        }
        public void SingleDownload()
        {
            log.Info("Performing single download test.");

            // We know kOS is in the TestKAN data, and hosted in KS. Let's get it.

            var modules = new List <CkanModule>();

            CkanModule kOS = registry.LatestAvailable("kOS", null);

            Assert.IsNotNull(kOS);

            modules.Add(kOS);

            // Make sure we don't alread have kOS somehow.
            Assert.IsFalse(cache.IsCached(kOS));

            //
            log.InfoFormat("Downloading kOS from {0}", kOS.download);

            // Download our module.
            async.DownloadModules(modules);

            // Assert that we have it, and it passes zip validation.
            Assert.IsTrue(cache.IsCachedZip(kOS));
        }
Beispiel #3
0
        public void UpdateRegistryTarGz()
        {
            CKAN.Repo.UpdateRegistry(TestData.TestKANTarGz(), registry, ksp.KSP, new NullUser());

            // Test we've got an expected module.
            CkanModule far = registry.LatestAvailable("FerramAerospaceResearch", KspVersion.Parse("0.25.0"));

            Assert.AreEqual("v0.14.3.2", far.version.ToString());
        }
Beispiel #4
0
        public void UpdateRegistryTarGz()
        {
            CKAN.Repo.UpdateRegistry(TestData.TestKANTarGz(), registry, ksp.KSP, new NullUser());

            // Test we've got an expected module.
            CfanModule far = registry.LatestAvailable("FARL", new FactorioVersion("0.12.99"));

            Assert.AreEqual("0.5.25", far.modVersion.ToString());
        }
Beispiel #5
0
        /// <summary>
        /// Tries to parse an identifier in the format Modname=version
        /// If the module cannot be found in the registry, throws a ModuleNotFoundKraken.
        /// </summary>
        public static CkanModule FromIDandVersion(Registry registry, string mod, KSPVersion ksp_version)
        {
            CkanModule module;

            Match match = Regex.Match(mod, @"^(?<mod>[^=]*)=(?<version>.*)$");

            if (match.Success)
            {
                string ident   = match.Groups["mod"].Value;
                string version = match.Groups["version"].Value;

                module = registry.GetModuleByVersion(ident, version);

                if (module == null)
                {
                    throw new ModuleNotFoundKraken(ident, version, string.Format("Cannot install {0}, version {1} not available", ident, version));
                }
            }
            else
            {
                module = registry.LatestAvailable(mod, ksp_version);
            }

            if (module == null)
            {
                throw new ModuleNotFoundKraken(mod, null, string.Format("Cannot install {0}, module not available", mod));
            }
            else
            {
                return(module);
            }
        }
Beispiel #6
0
        public GUIMod(CkanModule mod, Registry registry, KSPVersion current_ksp_version)
        {
            //Currently anything which could alter these causes a full reload of the modlist
            // If this is ever changed these could be moved into the properties
            Mod              = mod;
            IsInstalled      = registry.IsInstalled(mod.identifier);
            IsInstallChecked = IsInstalled;
            HasUpdate        = registry.HasUpdate(mod.identifier, current_ksp_version);
            IsIncompatible   = !mod.IsCompatibleKSP(current_ksp_version);
            IsAutodetected   = registry.IsAutodetected(mod.identifier);
            Authors          = mod.author == null ? "N/A" : String.Join(",", mod.author);

            var installedVersion = registry.InstalledVersion(mod.identifier);
            var latestVersion    = registry.LatestAvailable(mod.identifier, current_ksp_version);
            var kspVersion       = mod.ksp_version;

            InstalledVersion = installedVersion != null?installedVersion.ToString() : "-";

            LatestVersion = latestVersion != null?latestVersion.version.ToString() : "-";

            KSPversion = kspVersion != null?kspVersion.ToString() : "-";

            Abstract = mod.@abstract;
            Homepage = mod.resources != null && mod.resources.homepage != null
                ? (object)mod.resources.homepage
                : "N/A";

            Identifier = mod.identifier;
        }
Beispiel #7
0
        /// <summary>
        /// Create a CkanModule object that represents the currently installed
        /// mod list as a metapackage.
        /// </summary>
        /// <param name="recommends">If true, put the mods in the recommends relationship, otherwise use depends</param>
        /// <param name="with_versions">If true, set the installed mod versions in the relationships</param>
        /// <returns>
        /// The CkanModule object
        /// </returns>
        public CkanModule GenerateModpack(bool recommends = false, bool with_versions = true)
        {
            string kspInstanceName = ksp.Name;
            string name            = $"installed-{kspInstanceName}";
            var    module          = new CkanModule(
                // v1.18 to allow Unlicense
                new ModuleVersion("v1.18"),
                Identifier.Sanitize(name),
                name,
                $"A list of modules installed on the {kspInstanceName} KSP instance",
                null,
                new List <string>()
            {
                System.Environment.UserName
            },
                new List <License>()
            {
                new License("unknown")
            },
                new ModuleVersion(DateTime.UtcNow.ToString("yyyy.MM.dd.hh.mm.ss")),
                null,
                "metapackage"
                )
            {
                download_content_type = "application/zip",
                release_date          = DateTime.Now,
            };

            List <RelationshipDescriptor> mods = registry.Installed(false, false)
                                                 .Where(kvp => {
                // Skip unavailable modules (custom .ckan files)
                try
                {
                    var avail = registry.LatestAvailable(kvp.Key, null, null);
                    return(!avail.IsDLC);
                }
                catch
                {
                    return(false);
                }
            })
                                                 .Select(kvp => (RelationshipDescriptor) new ModuleRelationshipDescriptor()
            {
                name    = kvp.Key,
                version = with_versions ? kvp.Value : null
            })
                                                 .ToList();

            if (recommends)
            {
                module.recommends = mods;
            }
            else
            {
                module.depends = mods;
            }

            return(module);
        }
Beispiel #8
0
        public void LatestAvailable()
        {
            CkanModule module =
                registry.LatestAvailable("AGExt", temp_ksp.KSP.Version());

            Assert.AreEqual("AGExt", module.identifier);
            Assert.AreEqual("1.24a", module.version.ToString());
        }
Beispiel #9
0
        /// <summary>
        /// Creates a new resolver that will find a way to install all the modules specified.
        /// </summary>
        public RelationshipResolver(List <string> modules, RelationshipResolverOptions options, Registry registry)
        {
            this.registry = registry;

            // Start by figuring out what versions we're installing, and then
            // adding them to the list. This *must* be pre-populated with all
            // user-specified modules, as they may be supplying things that provide
            // virtual packages.

            var user_requested_mods = new List <CkanModule>();

            log.DebugFormat("Processing relationships for {0} modules", modules.Count);

            foreach (string module in modules)
            {
                CkanModule mod = registry.LatestAvailable(module);
                if (mod == null)
                {
                    throw new ModuleNotFoundKraken(module);
                }

                log.DebugFormat("Preparing to resolve relationships for {0} {1}", mod.identifier, mod.version);

                foreach (CkanModule listed_mod in this.modlist.Values)
                {
                    if (listed_mod.ConflictsWith(mod))
                    {
                        throw new InconsistentKraken(string.Format("{0} conflicts with {1}, can't install both.", mod, listed_mod));
                    }
                }

                user_requested_mods.Add(mod);
                this.Add(mod);
            }

            // Now that we've already pre-populated modlist, we can resolve
            // the rest of our dependencies.

            foreach (CkanModule module in user_requested_mods)
            {
                log.InfoFormat("Resolving relationships for {0}", module.identifier);
                Resolve(module, options);
            }

            var final_modules = new List <Module>(modlist.Values);

            final_modules.AddRange(registry.InstalledModules.Select(x => x.Module));

            if (!options.without_enforce_consistency)
            {
                // Finally, let's do a sanity check that our solution is actually sane.
                SanityChecker.EnforceConsistency(
                    final_modules,
                    registry.InstalledDlls
                    );
            }
        }
Beispiel #10
0
        /// <summary>
        /// This function returns a changeset based on the selections of the user.
        /// Currently returns null if a conflict is detected.
        /// </summary>
        /// <param name="registry"></param>
        /// <param name="current_instance"></param>
        public static IEnumerable <KeyValuePair <CkanModule, GUIModChangeType> > ComputeChangeSetFromModList(
            Registry registry, HashSet <KeyValuePair <CkanModule, GUIModChangeType> > changeSet, ModuleInstaller installer,
            KSPVersion version)
        {
            var modules_to_install = new HashSet <string>();
            var modules_to_remove  = new HashSet <string>();
            var options            = new RelationshipResolverOptions()
            {
                without_toomanyprovides_kraken = true,
                with_recommends = false
            };

            foreach (var change in changeSet)
            {
                switch (change.Value)
                {
                case GUIModChangeType.None:
                    break;

                case GUIModChangeType.Install:
                    modules_to_install.Add(change.Key.identifier);
                    break;

                case GUIModChangeType.Remove:
                    modules_to_remove.Add(change.Key.identifier);
                    break;

                case GUIModChangeType.Update:
                    break;

                default:
                    throw new ArgumentOutOfRangeException();
                }
            }

            //May throw InconsistentKraken
            var resolver = new RelationshipResolver(modules_to_install.ToList(), options, registry, version);

            changeSet.UnionWith(
                resolver.ModList()
                .Select(mod => new KeyValuePair <CkanModule, GUIModChangeType>(mod, GUIModChangeType.Install)));


            foreach (var reverse_dependencies in modules_to_remove.Select(installer.FindReverseDependencies))
            {
                //TODO This would be a good place to have a event that alters the row's graphics to show it will be removed
                //TODO This currently gets the latest version. This may cause the displayed version to wrong in the changset.
                var modules = reverse_dependencies.Select(rDep => registry.LatestAvailable(rDep, null));
                changeSet.UnionWith(
                    modules.Select(mod => new KeyValuePair <CkanModule, GUIModChangeType>(mod, GUIModChangeType.Remove)));
            }
            return(changeSet);
        }
Beispiel #11
0
        private TreeNode UpdateModDependencyGraphRecursively(TreeNode parentNode, CkanModule module, RelationshipType relationship, int depth, bool virtualProvides = false)
        {
            TreeNode node = null;

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

            if (depth > 0 && dependencyGraphRootModule == module)
            {
                return(node);
            }

            if (alreadyVisited.Contains(module))
            {
                return(node);
            }

            alreadyVisited.Add(module);

            if (parentNode == null)
            {
                node = new TreeNode(module.name);
            }
            else
            {
                node = parentNode.Nodes.Add(module.name);
            }

            IEnumerable <RelationshipDescriptor> 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;
            }

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

            int i = 0;

            foreach (RelationshipDescriptor dependency in relationships)
            {
                Registry registry = RegistryManager.Instance(KSPManager.CurrentInstance).registry;

                try
                {
                    CkanModule dependencyModule = null;

                    try
                    {
                        dependencyModule = registry.LatestAvailable
                                               (dependency.name.ToString(), KSPManager.CurrentInstance.Version());
                        UpdateModDependencyGraphRecursively(node, dependencyModule, relationship, depth + 1);
                    }
                    catch (ModuleNotFoundKraken)
                    {
                        List <CkanModule> dependencyModules = registry.LatestAvailableWithProvides
                                                                  (dependency.name.ToString(), KSPManager.CurrentInstance.Version());

                        if (dependencyModules == null)
                        {
                            continue;
                        }

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

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

            return(node);
        }
Beispiel #12
0
        public void DogeCoin()
        {
            // Test with a module that depends and conflicts with nothing.
            var mods = new List <CkanModule> {
                registry.LatestAvailable("DogeCoinFlag", null)
            };

            Assert.IsTrue(CKAN.SanityChecker.IsConsistent(mods), "DogeCoinFlag");
        }
Beispiel #13
0
        public void RemoveAvailableByName()
        {
            // Add our module and test it's there.
            registry.AddAvailable(module);
            Assert.IsNotNull(registry.LatestAvailable(identifier, v0_24_2));

            // Remove it, and make sure it's gone.
            registry.RemoveAvailable(identifier, module.version);

            Assert.IsNull(registry.LatestAvailable(identifier, v0_24_2));
        }
Beispiel #14
0
        // this functions computes a changeset from the user's choices in the GUI
        private List <KeyValuePair <CkanModule, GUIModChangeType> > ComputeChangeSetFromModList()
        // this probably needs to be refactored
        {
            var changeset = new HashSet <KeyValuePair <CkanModule, GUIModChangeType> >();

            // these are the lists
            var modulesToInstall = new HashSet <string>();
            var modulesToRemove  = new HashSet <string>();

            Registry registry = RegistryManager.Instance(KSPManager.CurrentInstance).registry;

            foreach (DataGridViewRow row in ModList.Rows)
            {
                var mod = (CkanModule)row.Tag;
                if (mod == null)
                {
                    continue;
                }

                bool isInstalled        = registry.IsInstalled(mod.identifier);
                var  isInstalledCell    = row.Cells[0] as DataGridViewCheckBoxCell;
                var  isInstalledChecked = (bool)isInstalledCell.Value;

                if (!isInstalled && isInstalledChecked)
                {
                    modulesToInstall.Add(mod.identifier);
                }
                else if (isInstalled && !isInstalledChecked)
                {
                    modulesToRemove.Add(mod.identifier);
                }
            }

            RelationshipResolverOptions options = RelationshipResolver.DefaultOpts();

            options.with_recommends = false;
            options.without_toomanyprovides_kraken = true;
            options.without_enforce_consistency    = true;

            RelationshipResolver resolver = null;

            try
            {
                resolver = new RelationshipResolver(modulesToInstall.ToList(), options, registry);
            }
            catch (Exception e)
            {
                return(null);
            }

            foreach (CkanModule mod in resolver.ModList())
            {
                changeset.Add(new KeyValuePair <CkanModule, GUIModChangeType>(mod, GUIModChangeType.Install));
            }

            ModuleInstaller installer = ModuleInstaller.Instance;

            foreach (string moduleName in modulesToRemove)
            {
                var reverseDependencies = installer.FindReverseDependencies(moduleName);
                foreach (string reverseDependency in reverseDependencies)
                {
                    CkanModule mod = registry.LatestAvailable(reverseDependency);
                    changeset.Add(new KeyValuePair <CkanModule, GUIModChangeType>(mod, GUIModChangeType.Remove));
                }
            }

            foreach (DataGridViewRow row in ModList.Rows)
            {
                var mod = (CkanModule)row.Tag;
                if (mod == null)
                {
                    continue;
                }

                bool             isInstalled         = registry.IsInstalled(mod.identifier);
                var              isInstalledCell     = row.Cells[0] as DataGridViewCheckBoxCell;
                var              isInstalledChecked  = (bool)isInstalledCell.Value;
                DataGridViewCell shouldBeUpdatedCell = row.Cells[1];
                bool             shouldBeUpdated     = false;
                if (shouldBeUpdatedCell is DataGridViewCheckBoxCell && shouldBeUpdatedCell.Value != null)
                {
                    shouldBeUpdated = (bool)shouldBeUpdatedCell.Value;
                }

                if (isInstalled && !isInstalledChecked)
                {
                    changeset.Add(new KeyValuePair <CkanModule, GUIModChangeType>(mod, GUIModChangeType.Remove));
                }
                else if (isInstalled && isInstalledChecked &&
                         mod.version.IsGreaterThan(registry.InstalledVersion(mod.identifier)) && shouldBeUpdated)
                {
                    changeset.Add(new KeyValuePair <CkanModule, GUIModChangeType>(mod, GUIModChangeType.Update));
                }
            }

            return(changeset.ToList());
        }
Beispiel #15
0
        /// <summary>
        /// This function returns a changeset based on the selections of the user.
        /// Currently returns null if a conflict is detected.
        /// </summary>
        /// <param name="registry"></param>
        /// <param name="current_instance"></param>
        public List <KeyValuePair <CkanModule, GUIModChangeType> > ComputeChangeSetFromModList(Registry registry, KSP current_instance)
        {
            var changeset        = new HashSet <KeyValuePair <CkanModule, GUIModChangeType> >();
            var modulesToInstall = new HashSet <string>();
            var modulesToRemove  = new HashSet <string>();

            foreach (var mod in Modules.Where(mod => mod.IsInstallable()))
            {
                if (mod.IsInstalled)
                {
                    if (!mod.IsInstallChecked)
                    {
                        modulesToRemove.Add(mod.Identifier);
                        changeset.Add(new KeyValuePair <CkanModule, GUIModChangeType>(mod.ToCkanModule(),
                                                                                      GUIModChangeType.Remove));
                    }
                    else if (mod.IsInstallChecked && mod.HasUpdate && mod.IsUpgradeChecked)
                    {
                        changeset.Add(new KeyValuePair <CkanModule, GUIModChangeType>(mod.ToCkanModule(),
                                                                                      GUIModChangeType.Update));
                    }
                }
                else if (mod.IsInstallChecked)
                {
                    modulesToInstall.Add(mod.Identifier);
                }
            }

            RelationshipResolverOptions options = RelationshipResolver.DefaultOpts();

            options.with_recommends = false;
            options.without_toomanyprovides_kraken = true;
            options.without_enforce_consistency    = true;

            RelationshipResolver resolver;

            try
            {
                resolver = new RelationshipResolver(modulesToInstall.ToList(), options, registry);
            }
            catch (Exception)
            {
                //TODO FIX this so the UI reacts.
                return(null);
            }

            changeset.UnionWith(
                resolver.ModList()
                .Select(mod => new KeyValuePair <CkanModule, GUIModChangeType>(mod, GUIModChangeType.Install)));


            ModuleInstaller installer = ModuleInstaller.GetInstance(current_instance, GUI.user);

            foreach (var reverseDependencies in modulesToRemove.Select(mod => installer.FindReverseDependencies(mod)))
            {
                //TODO This would be a good place to have a event that alters the row's graphics to show it will be removed
                var modules = reverseDependencies.Select(rDep => registry.LatestAvailable(rDep));
                changeset.UnionWith(
                    modules.Select(mod => new KeyValuePair <CkanModule, GUIModChangeType>(mod, GUIModChangeType.Remove)));
            }

            return(changeset.ToList());
        }
Beispiel #16
0
        private TreeNode UpdateModDependencyGraphRecursively(TreeNode parentNode, CkanModule 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.name;

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

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

            IEnumerable <RelationshipDescriptor> 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;
            }

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

            foreach (RelationshipDescriptor dependency in relationships)
            {
                Registry registry = RegistryManager.Instance(manager.CurrentInstance).registry;

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

                        if (dependencyModules == null)
                        {
                            continue;
                        }

                        var newNode = node.Nodes.Add(dependency.name + " (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);
        }