예제 #1
0
        /// <summary>
        /// Searches for the term in the list of compatible or incompatible modules for the ksp instance.
        /// Looks in name, identifier and description fields, and if given, restricts to authors matching the author term.
        /// </summary>
        /// <returns>List of matching modules.</returns>
        /// <param name="ksp">The KSP instance to perform the search for.</param>
        /// <param name="term">The search term. Case insensitive.</param>
        /// <param name="author">Name of author to find</param>
        /// <param name="searchIncompatible">True to look for incompatible modules, false (default) to look for compatible</param>
        public List <CkanModule> PerformSearch(CKAN.GameInstance ksp, string term, string author = null, bool searchIncompatible = false)
        {
            // Remove spaces and special characters from the search term.
            term   = String.IsNullOrWhiteSpace(term)   ? string.Empty : CkanModule.nonAlphaNums.Replace(term, "");
            author = String.IsNullOrWhiteSpace(author) ? string.Empty : CkanModule.nonAlphaNums.Replace(author, "");

            var registry = RegistryManager.Instance(ksp).registry;

            if (!searchIncompatible)
            {
                return(registry
                       .CompatibleModules(ksp.VersionCriteria())
                       // Look for a match in each string.
                       .Where(module => (module.SearchableName.IndexOf(term, StringComparison.OrdinalIgnoreCase) > -1 ||
                                         module.SearchableIdentifier.IndexOf(term, StringComparison.OrdinalIgnoreCase) > -1 ||
                                         module.SearchableAbstract.IndexOf(term, StringComparison.OrdinalIgnoreCase) > -1 ||
                                         module.SearchableDescription.IndexOf(term, StringComparison.OrdinalIgnoreCase) > -1) &&
                              module.SearchableAuthors.Any((auth) => auth.IndexOf(author, StringComparison.OrdinalIgnoreCase) > -1))
                       .ToList());
            }
            else
            {
                return(registry
                       .IncompatibleModules(ksp.VersionCriteria())
                       // Look for a match in each string.
                       .Where(module => (module.SearchableName.IndexOf(term, StringComparison.OrdinalIgnoreCase) > -1 ||
                                         module.SearchableIdentifier.IndexOf(term, StringComparison.OrdinalIgnoreCase) > -1 ||
                                         module.SearchableAbstract.IndexOf(term, StringComparison.OrdinalIgnoreCase) > -1 ||
                                         module.SearchableDescription.IndexOf(term, StringComparison.OrdinalIgnoreCase) > -1) &&
                              module.SearchableAuthors.Any((auth) => auth.IndexOf(author, StringComparison.OrdinalIgnoreCase) > -1))
                       .ToList());
            }
        }
예제 #2
0
        /// <summary>
        /// Update the registry
        /// </summary>
        /// <param name="ksp">Game instance to update</param>
        /// <param name="raw_options">Command line options object</param>
        /// <returns>
        /// Exit code for shell environment
        /// </returns>
        public int RunCommand(CKAN.GameInstance ksp, object raw_options)
        {
            UpdateOptions options = (UpdateOptions)raw_options;

            List <CkanModule> compatible_prior = null;

            if (options.list_changes)
            {
                // Get a list of compatible modules prior to the update.
                var registry = RegistryManager.Instance(ksp).registry;
                compatible_prior = registry.CompatibleModules(ksp.VersionCriteria()).ToList();
            }

            // If no repository is selected, select all.
            if (options.repo == null)
            {
                options.update_all = true;
            }

            try
            {
                if (options.update_all)
                {
                    UpdateRepository(ksp);
                }
                else
                {
                    UpdateRepository(ksp, options.repo);
                }
            }
            catch (ReinstallModuleKraken rmk)
            {
                Upgrade.UpgradeModules(manager, user, ksp, false, rmk.Modules);
            }
            catch (MissingCertificateKraken kraken)
            {
                // Handling the kraken means we have prettier output.
                user.RaiseMessage(kraken.ToString());
                return(Exit.ERROR);
            }

            if (options.list_changes)
            {
                var registry = RegistryManager.Instance(ksp).registry;
                PrintChanges(compatible_prior, registry.CompatibleModules(ksp.VersionCriteria()).ToList());
            }

            return(Exit.OK);
        }
예제 #3
0
        public int RunCommand(CKAN.GameInstance ksp, object raw_options)
        {
            AvailableOptions opts     = (AvailableOptions)raw_options;
            IRegistryQuerier registry = RegistryManager.Instance(ksp).registry;

            var compatible = registry
                             .CompatibleModules(ksp.VersionCriteria())
                             .Where(m => !m.IsDLC);

            user.RaiseMessage("Modules compatible with KSP {0}", ksp.Version());
            user.RaiseMessage("");

            if (opts.detail)
            {
                foreach (CkanModule module in compatible)
                {
                    user.RaiseMessage("* {0} ({1}) - {2} - {3}", module.identifier, module.version, module.name, module.@abstract);
                }
            }
            else
            {
                foreach (CkanModule module in compatible)
                {
                    user.RaiseMessage("* {0} ({1}) - {2}", module.identifier, module.version, module.name);
                }
            }

            return(Exit.OK);
        }
예제 #4
0
        /// <summary>
        /// Convert case insensitive mod names from the user to case sensitive identifiers
        /// </summary>
        /// <param name="ksp">Game instance forgetting the mods</param>
        /// <param name="modules">List of strings to convert, format 'identifier' or 'identifier=version'</param>
        public static void AdjustModulesCase(CKAN.GameInstance ksp, List <string> modules)
        {
            IRegistryQuerier registry = RegistryManager.Instance(ksp).registry;
            // Get the list of all compatible and incompatible mods
            List <CkanModule> mods = registry.CompatibleModules(ksp.VersionCriteria()).ToList();

            mods.AddRange(registry.IncompatibleModules(ksp.VersionCriteria()));
            for (int i = 0; i < modules.Count; ++i)
            {
                Match match = CkanModule.idAndVersionMatcher.Match(modules[i]);
                if (match.Success)
                {
                    // Handle name=version format
                    string ident   = match.Groups["mod"].Value;
                    string version = match.Groups["version"].Value;
                    modules[i] = $"{CaseInsensitiveExactMatch(mods, ident)}={version}";
                }
                else
                {
                    modules[i] = CaseInsensitiveExactMatch(mods, modules[i]);
                }
            }
        }
예제 #5
0
파일: List.cs 프로젝트: zxasqwsss/CKAN
        public int RunCommand(CKAN.GameInstance ksp, object raw_options)
        {
            ListOptions options = (ListOptions)raw_options;

            IRegistryQuerier registry = RegistryManager.Instance(ksp).registry;

            ExportFileType?exportFileType = null;

            if (!string.IsNullOrWhiteSpace(options.export))
            {
                exportFileType = GetExportFileType(options.export);

                if (exportFileType == null)
                {
                    user.RaiseError("Unknown export format: {0}", options.export);
                }
            }

            if (!(options.porcelain) && exportFileType == null)
            {
                user.RaiseMessage("\r\nKSP found at {0}\r\n", ksp.GameDir());
                user.RaiseMessage("KSP Version: {0}\r\n", ksp.Version());

                user.RaiseMessage("Installed Modules:\r\n");
            }

            if (exportFileType == null)
            {
                var installed = new SortedDictionary <string, ModuleVersion>(registry.Installed());

                foreach (KeyValuePair <string, ModuleVersion> mod in installed)
                {
                    ModuleVersion current_version = mod.Value;
                    string        modInfo         = string.Format("{0} {1}", mod.Key, mod.Value);
                    string        bullet          = "*";

                    if (current_version is ProvidesModuleVersion)
                    {
                        // Skip virtuals for now.
                        continue;
                    }
                    else if (current_version is UnmanagedModuleVersion)
                    {
                        // Autodetected dll
                        bullet = "A";
                    }
                    else
                    {
                        try
                        {
                            // Check if upgrades are available, and show appropriately.
                            log.DebugFormat("Check if upgrades are available for {0}", mod.Key);
                            CkanModule      latest  = registry.LatestAvailable(mod.Key, ksp.VersionCriteria());
                            CkanModule      current = registry.GetInstalledVersion(mod.Key);
                            InstalledModule inst    = registry.InstalledModule(mod.Key);

                            if (latest == null)
                            {
                                // Not compatible!
                                log.InfoFormat("Latest {0} is not compatible", mod.Key);
                                bullet = "X";
                                if (current == null)
                                {
                                    log.DebugFormat(" {0} installed version not found in registry", mod.Key);
                                }

                                // Check if mod is replaceable
                                if (current.replaced_by != null)
                                {
                                    ModuleReplacement replacement = registry.GetReplacement(mod.Key, ksp.VersionCriteria());
                                    if (replacement != null)
                                    {
                                        // Replaceable!
                                        bullet  = ">";
                                        modInfo = string.Format("{0} > {1} {2}", modInfo, replacement.ReplaceWith.name, replacement.ReplaceWith.version);
                                    }
                                }
                            }
                            else if (latest.version.IsEqualTo(current_version))
                            {
                                // Up to date
                                log.InfoFormat("Latest {0} is {1}", mod.Key, latest.version);
                                bullet = (inst?.AutoInstalled ?? false) ? "+" : "-";
                                // Check if mod is replaceable
                                if (current.replaced_by != null)
                                {
                                    ModuleReplacement replacement = registry.GetReplacement(latest.identifier, ksp.VersionCriteria());
                                    if (replacement != null)
                                    {
                                        // Replaceable!
                                        bullet  = ">";
                                        modInfo = string.Format("{0} > {1} {2}", modInfo, replacement.ReplaceWith.name, replacement.ReplaceWith.version);
                                    }
                                }
                            }
                            else if (latest.version.IsGreaterThan(mod.Value))
                            {
                                // Upgradable
                                bullet = "^";
                            }
                        }
                        catch (ModuleNotFoundKraken)
                        {
                            log.InfoFormat("{0} is installed, but no longer in the registry", mod.Key);
                            bullet = "?";
                        }
                    }

                    user.RaiseMessage("{0} {1}", bullet, modInfo);
                }
            }
            else
            {
                var stream = Console.OpenStandardOutput();
                new Exporter(exportFileType.Value).Export(registry, stream);
                stream.Flush();
            }

            if (!(options.porcelain) && exportFileType == null)
            {
                user.RaiseMessage("\r\nLegend: -: Up to date. +:Auto-installed. X: Incompatible. ^: Upgradable. >: Replaceable\r\n        A: Autodetected. ?: Unknown. *: Broken. ");
                // Broken mods are in a state that CKAN doesn't understand, and therefore can't handle automatically
            }

            return(Exit.OK);
        }
예제 #6
0
        public int RunCommand(CKAN.GameInstance ksp, object raw_options)
        {
            ReplaceOptions options = (ReplaceOptions)raw_options;

            if (options.ckan_file != null)
            {
                options.modules.Add(MainClass.LoadCkanFromFile(ksp, options.ckan_file).identifier);
            }

            if (options.modules.Count == 0 && !options.replace_all)
            {
                // What? No mods specified?
                User.RaiseMessage("Usage: ckan replace Mod [Mod2, ...]");
                User.RaiseMessage("  or   ckan replace --all");
                return(Exit.BADOPT);
            }

            // Prepare options. Can these all be done in the new() somehow?
            var replace_ops = new RelationshipResolverOptions
            {
                with_all_suggests  = options.with_all_suggests,
                with_suggests      = options.with_suggests,
                with_recommends    = !options.no_recommends,
                allow_incompatible = options.allow_incompatible
            };

            var regMgr     = RegistryManager.Instance(ksp);
            var registry   = regMgr.registry;
            var to_replace = new List <ModuleReplacement>();

            if (options.replace_all)
            {
                log.Debug("Running Replace all");
                var installed = new Dictionary <string, ModuleVersion>(registry.Installed());

                foreach (KeyValuePair <string, ModuleVersion> mod in installed)
                {
                    ModuleVersion current_version = mod.Value;

                    if ((current_version is ProvidesModuleVersion) || (current_version is UnmanagedModuleVersion))
                    {
                        continue;
                    }
                    else
                    {
                        try
                        {
                            log.DebugFormat("Testing {0} {1} for possible replacement", mod.Key, mod.Value);
                            // Check if replacement is available

                            ModuleReplacement replacement = registry.GetReplacement(mod.Key, ksp.VersionCriteria());
                            if (replacement != null)
                            {
                                // Replaceable
                                log.InfoFormat("Replacement {0} {1} found for {2} {3}",
                                               replacement.ReplaceWith.identifier, replacement.ReplaceWith.version,
                                               replacement.ToReplace.identifier, replacement.ToReplace.version);
                                to_replace.Add(replacement);
                            }
                        }
                        catch (ModuleNotFoundKraken)
                        {
                            log.InfoFormat("{0} is installed, but it or its replacement is not in the registry",
                                           mod.Key);
                        }
                    }
                }
            }
            else
            {
                foreach (string mod in options.modules)
                {
                    try
                    {
                        log.DebugFormat("Checking that {0} is installed", mod);
                        CkanModule modToReplace = registry.GetInstalledVersion(mod);
                        if (modToReplace != null)
                        {
                            log.DebugFormat("Testing {0} {1} for possible replacement", modToReplace.identifier, modToReplace.version);
                            try
                            {
                                // Check if replacement is available
                                ModuleReplacement replacement = registry.GetReplacement(modToReplace.identifier, ksp.VersionCriteria());
                                if (replacement != null)
                                {
                                    // Replaceable
                                    log.InfoFormat("Replacement {0} {1} found for {2} {3}",
                                                   replacement.ReplaceWith.identifier, replacement.ReplaceWith.version,
                                                   replacement.ToReplace.identifier, replacement.ToReplace.version);
                                    to_replace.Add(replacement);
                                }
                                if (modToReplace.replaced_by != null)
                                {
                                    log.InfoFormat("Attempt to replace {0} failed, replacement {1} is not compatible",
                                                   mod, modToReplace.replaced_by.name);
                                }
                                else
                                {
                                    log.InfoFormat("Mod {0} has no replacement defined for the current version {1}",
                                                   modToReplace.identifier, modToReplace.version);
                                }
                            }
                            catch (ModuleNotFoundKraken)
                            {
                                log.InfoFormat("{0} is installed, but its replacement {1} is not in the registry",
                                               mod, modToReplace.replaced_by.name);
                            }
                        }
                    }
                    catch (ModuleNotFoundKraken kraken)
                    {
                        User.RaiseMessage("Module {0} not found", kraken.module);
                    }
                }
            }
            if (to_replace.Count() != 0)
            {
                User.RaiseMessage("\r\nReplacing modules...\r\n");
                foreach (ModuleReplacement r in to_replace)
                {
                    User.RaiseMessage("Replacement {0} {1} found for {2} {3}",
                                      r.ReplaceWith.identifier, r.ReplaceWith.version,
                                      r.ToReplace.identifier, r.ToReplace.version);
                }

                bool ok = User.RaiseYesNoDialog("Continue?");

                if (!ok)
                {
                    User.RaiseMessage("Replacements canceled at user request.");
                    return(Exit.ERROR);
                }

                // TODO: These instances all need to go.
                try
                {
                    HashSet <string> possibleConfigOnlyDirs = null;
                    new ModuleInstaller(ksp, manager.Cache, User).Replace(to_replace, replace_ops, new NetAsyncModulesDownloader(User, manager.Cache), ref possibleConfigOnlyDirs, regMgr);
                    User.RaiseMessage("");
                }
                catch (DependencyNotSatisfiedKraken ex)
                {
                    User.RaiseMessage("Dependencies not satisfied for replacement, {0} requires {1} {2} but it is not listed in the index, or not available for your version of KSP.", ex.parent, ex.module, ex.version);
                }
            }
            else
            {
                User.RaiseMessage("No replacements found.");
                return(Exit.OK);
            }

            return(Exit.OK);
        }
예제 #7
0
파일: Show.cs 프로젝트: zxasqwsss/CKAN
        public int RunCommand(CKAN.GameInstance ksp, object raw_options)
        {
            ShowOptions options = (ShowOptions)raw_options;

            if (options.Modname == null)
            {
                // empty argument
                user.RaiseMessage("show <module> - module name argument missing, perhaps you forgot it?");
                return(Exit.BADOPT);
            }

            // Check installed modules for an exact match.
            var registry = RegistryManager.Instance(ksp).registry;
            var installedModuleToShow = registry.InstalledModule(options.Modname);

            if (installedModuleToShow != null)
            {
                // Show the installed module.
                return(ShowMod(installedModuleToShow));
            }

            // Module was not installed, look for an exact match in the available modules,
            // either by "name" (the user-friendly display name) or by identifier
            CkanModule moduleToShow = registry
                                      .CompatibleModules(ksp.VersionCriteria())
                                      .SingleOrDefault(
                mod => mod.name == options.Modname ||
                mod.identifier == options.Modname
                );

            if (moduleToShow == null)
            {
                // No exact match found. Try to look for a close match for this KSP version.
                user.RaiseMessage("{0} not found or installed.", options.Modname);
                user.RaiseMessage("Looking for close matches in mods compatible with KSP {0}.", ksp.Version());

                Search search  = new Search(user);
                var    matches = search.PerformSearch(ksp, options.Modname);

                // Display the results of the search.
                if (!matches.Any())
                {
                    // No matches found.
                    user.RaiseMessage("No close matches found.");
                    return(Exit.BADOPT);
                }
                else if (matches.Count() == 1)
                {
                    // If there is only 1 match, display it.
                    user.RaiseMessage("Found 1 close match: {0}", matches[0].name);
                    user.RaiseMessage("");

                    moduleToShow = matches[0];
                }
                else
                {
                    // Display the found close matches.
                    string[] strings_matches = new string[matches.Count];

                    for (int i = 0; i < matches.Count; i++)
                    {
                        strings_matches[i] = matches[i].name;
                    }

                    int selection = user.RaiseSelectionDialog("Close matches", strings_matches);

                    if (selection < 0)
                    {
                        return(Exit.BADOPT);
                    }

                    // Mark the selection as the one to show.
                    moduleToShow = matches[selection];
                }
            }

            return(ShowMod(moduleToShow));
        }
예제 #8
0
파일: Update.cs 프로젝트: zxasqwsss/CKAN
        /// <summary>
        /// Updates the repository.
        /// </summary>
        /// <param name="ksp">The KSP instance to work on.</param>
        /// <param name="repository">Repository to update. If null all repositories are used.</param>
        private void UpdateRepository(CKAN.GameInstance ksp, string repository = null)
        {
            RegistryManager registry_manager = RegistryManager.Instance(ksp);

            var updated = repository == null
                ? CKAN.Repo.UpdateAllRepositories(registry_manager, ksp, manager.Cache, user) != CKAN.RepoUpdateResult.Failed
                : CKAN.Repo.Update(registry_manager, ksp, user, repository);

            user.RaiseMessage("Updated information on {0} compatible modules", registry_manager.registry.CompatibleModules(ksp.VersionCriteria()).Count());
        }
예제 #9
0
        public int RunCommand(CKAN.GameInstance ksp, object raw_options)
        {
            ShowOptions options = (ShowOptions)raw_options;

            if (options.modules == null || options.modules.Count < 1)
            {
                // empty argument
                user.RaiseMessage("show <module> - module name argument missing, perhaps you forgot it?");
                return(Exit.BADOPT);
            }

            int combined_exit_code = Exit.OK;
            // Check installed modules for an exact match.
            var registry = RegistryManager.Instance(ksp).registry;

            foreach (string modName in options.modules)
            {
                var installedModuleToShow = registry.InstalledModule(modName);
                if (installedModuleToShow != null)
                {
                    // Show the installed module.
                    combined_exit_code = CombineExitCodes(
                        combined_exit_code,
                        ShowMod(installedModuleToShow)
                        );
                    if (options.with_versions)
                    {
                        ShowVersionTable(ksp, registry.AvailableByIdentifier(installedModuleToShow.identifier).ToList());
                    }
                    user.RaiseMessage("");
                    continue;
                }

                // Module was not installed, look for an exact match in the available modules,
                // either by "name" (the user-friendly display name) or by identifier
                CkanModule moduleToShow = registry
                                          .CompatibleModules(ksp.VersionCriteria())
                                          .SingleOrDefault(
                    mod => mod.name == modName ||
                    mod.identifier == modName
                    );
                if (moduleToShow == null)
                {
                    // No exact match found. Try to look for a close match for this KSP version.
                    user.RaiseMessage(
                        "{0} not installed or compatible with {1} {2}.",
                        modName,
                        ksp.game.ShortName,
                        string.Join(", ", ksp.VersionCriteria().Versions.Select(v => v.ToString()))
                        );
                    user.RaiseMessage("Looking for close matches in compatible mods...");

                    Search search  = new Search(user);
                    var    matches = search.PerformSearch(ksp, modName);

                    // Display the results of the search.
                    if (!matches.Any())
                    {
                        // No matches found.
                        user.RaiseMessage("No close matches found.");
                        combined_exit_code = CombineExitCodes(combined_exit_code, Exit.BADOPT);
                        user.RaiseMessage("");
                        continue;
                    }
                    else if (matches.Count() == 1)
                    {
                        // If there is only 1 match, display it.
                        user.RaiseMessage("Found 1 close match: {0}", matches[0].name);
                        user.RaiseMessage("");

                        moduleToShow = matches[0];
                    }
                    else
                    {
                        // Display the found close matches.
                        int selection = user.RaiseSelectionDialog(
                            "Close matches:",
                            matches.Select(m => m.name).ToArray()
                            );
                        user.RaiseMessage("");
                        if (selection < 0)
                        {
                            combined_exit_code = CombineExitCodes(combined_exit_code, Exit.BADOPT);
                            continue;
                        }

                        // Mark the selection as the one to show.
                        moduleToShow = matches[selection];
                    }
                }

                combined_exit_code = CombineExitCodes(
                    combined_exit_code,
                    ShowMod(moduleToShow)
                    );
                if (options.with_versions)
                {
                    ShowVersionTable(ksp, registry.AvailableByIdentifier(moduleToShow.identifier).ToList());
                }
                user.RaiseMessage("");
            }
            return(combined_exit_code);
        }
예제 #10
0
파일: Upgrade.cs 프로젝트: embix/CKAN
        /// <summary>
        /// Upgrade an installed module
        /// </summary>
        /// <param name="ksp">Game instance from which to remove</param>
        /// <param name="raw_options">Command line options object</param>
        /// <returns>
        /// Exit code for shell environment
        /// </returns>
        public int RunCommand(CKAN.GameInstance ksp, object raw_options)
        {
            UpgradeOptions options = (UpgradeOptions)raw_options;

            if (options.ckan_file != null)
            {
                options.modules.Add(MainClass.LoadCkanFromFile(ksp, options.ckan_file).identifier);
            }

            if (options.modules.Count == 0 && !options.upgrade_all)
            {
                // What? No files specified?
                User.RaiseMessage("Usage: ckan upgrade Mod [Mod2, ...]");
                User.RaiseMessage("  or   ckan upgrade --all");
                if (AutoUpdate.CanUpdate)
                {
                    User.RaiseMessage("  or   ckan upgrade ckan");
                }
                return(Exit.BADOPT);
            }

            if (!options.upgrade_all && options.modules[0] == "ckan" && AutoUpdate.CanUpdate)
            {
                User.RaiseMessage("Querying the latest CKAN version");
                AutoUpdate.Instance.FetchLatestReleaseInfo();
                var latestVersion  = AutoUpdate.Instance.latestUpdate.Version;
                var currentVersion = new ModuleVersion(Meta.GetVersion(VersionFormat.Short));

                if (latestVersion.IsGreaterThan(currentVersion))
                {
                    User.RaiseMessage("New CKAN version available - " + latestVersion);
                    var releaseNotes = AutoUpdate.Instance.latestUpdate.ReleaseNotes;
                    User.RaiseMessage(releaseNotes);
                    User.RaiseMessage("\r\n");

                    if (User.RaiseYesNoDialog("Proceed with install?"))
                    {
                        User.RaiseMessage("Upgrading CKAN, please wait..");
                        AutoUpdate.Instance.StartUpdateProcess(false);
                    }
                }
                else
                {
                    User.RaiseMessage("You already have the latest version.");
                }

                return(Exit.OK);
            }

            try
            {
                var regMgr   = RegistryManager.Instance(ksp);
                var registry = regMgr.registry;
                if (options.upgrade_all)
                {
                    var to_upgrade = new List <CkanModule>();

                    foreach (KeyValuePair <string, ModuleVersion> mod in registry.Installed(false))
                    {
                        try
                        {
                            // Check if upgrades are available
                            var latest = registry.LatestAvailable(mod.Key, ksp.VersionCriteria());

                            // This may be an unindexed mod. If so,
                            // skip rather than crash. See KSP-CKAN/CKAN#841.
                            if (latest == null || latest.IsDLC)
                            {
                                continue;
                            }

                            if (latest.version.IsGreaterThan(mod.Value))
                            {
                                // Upgradable
                                log.InfoFormat("New version {0} found for {1}",
                                               latest.version, latest.identifier);
                                to_upgrade.Add(latest);
                            }
                        }
                        catch (ModuleNotFoundKraken)
                        {
                            log.InfoFormat("{0} is installed, but no longer in the registry",
                                           mod.Key);
                        }
                    }
                    UpgradeModules(manager, User, ksp, true, to_upgrade);
                }
                else
                {
                    Search.AdjustModulesCase(ksp, options.modules);
                    UpgradeModules(manager, User, ksp, options.modules);
                }
                User.RaiseMessage("");
            }
            catch (CancelledActionKraken k)
            {
                User.RaiseMessage("Upgrade aborted: {0}", k.Message);
                return(Exit.ERROR);
            }
            catch (ModuleNotFoundKraken kraken)
            {
                User.RaiseMessage("Module {0} not found", kraken.module);
                return(Exit.ERROR);
            }
            catch (InconsistentKraken kraken)
            {
                User.RaiseMessage(kraken.ToString());
                return(Exit.ERROR);
            }
            catch (ModuleIsDLCKraken kraken)
            {
                User.RaiseMessage($"CKAN can't upgrade expansion '{kraken.module.name}' for you.");
                var res           = kraken?.module?.resources;
                var storePagesMsg = new Uri[] { res?.store, res?.steamstore }
                .Where(u => u != null)
                .Aggregate("", (a, b) => $"{a}\r\n- {b}");
                if (!string.IsNullOrEmpty(storePagesMsg))
                {
                    User.RaiseMessage($"To upgrade this expansion, download any updates from the store page from which you purchased it:\r\n{storePagesMsg}");
                }
                return(Exit.ERROR);
            }

            return(Exit.OK);
        }