Example #1
0
        // This is required by ISubCommand
        public int RunSubCommand(KSPManager manager, CommonOptions opts, SubCommandOptions unparsed)
        {
            string[] args = unparsed.options.ToArray();

            #region Aliases

            for (int i = 0; i < args.Length; i++)
            {
                switch (args[i])
                {
                case "use":
                    args[i] = "default";
                    break;

                default:
                    break;
                }
            }

            #endregion

            int exitCode = Exit.OK;
            // Parse and process our sub-verbs
            Parser.Default.ParseArgumentsStrict(args, new KSPSubOptions(), (string option, object suboptions) =>
            {
                // ParseArgumentsStrict calls us unconditionally, even with bad arguments
                if (!string.IsNullOrEmpty(option) && suboptions != null)
                {
                    CommonOptions options = (CommonOptions)suboptions;
                    options.Merge(opts);
                    User     = new ConsoleUser(options.Headless);
                    Manager  = manager ?? new KSPManager(User);
                    exitCode = options.Handle(Manager, User);
                    if (exitCode != Exit.OK)
                    {
                        return;
                    }

                    switch (option)
                    {
                    case "list":
                        exitCode = ListInstalls();
                        break;

                    case "add":
                        exitCode = AddInstall((AddOptions)suboptions);
                        break;

                    case "clone":
                        exitCode = CloneInstall((CloneOptions)suboptions);
                        break;

                    case "rename":
                        exitCode = RenameInstall((RenameOptions)suboptions);
                        break;

                    case "forget":
                        exitCode = ForgetInstall((ForgetOptions)suboptions);
                        break;

                    case "use":
                    case "default":
                        exitCode = SetDefaultInstall((DefaultOptions)suboptions);
                        break;

                    case "fake":
                        exitCode = FakeNewKSPInstall((FakeOptions)suboptions);
                        break;

                    default:
                        User.RaiseMessage("Unknown command: ksp {0}", option);
                        exitCode = Exit.BADOPT;
                        break;
                    }
                }
            }, () => { exitCode = MainClass.AfterHelp(); });
            return(exitCode);
        }
Example #2
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;
                    ModuleInstaller.GetInstance(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);
        }
Example #3
0
        /// <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.KSP 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);
            }

            User.RaiseMessage("\r\nUpgrading modules...\r\n");

            try
            {
                HashSet <string> possibleConfigOnlyDirs = null;
                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);
                        }
                    }

                    ModuleInstaller.GetInstance(ksp, manager.Cache, User).Upgrade(to_upgrade, new NetAsyncModulesDownloader(User, manager.Cache), ref possibleConfigOnlyDirs, regMgr, true, true);
                }
                else
                {
                    Search.AdjustModulesCase(ksp, options.modules);
                    ModuleInstaller.GetInstance(ksp, manager.Cache, User).Upgrade(options.modules, new NetAsyncModulesDownloader(User, manager.Cache), ref possibleConfigOnlyDirs, regMgr);
                }
            }
            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);
            }
            User.RaiseMessage("\r\nDone!\r\n");

            return(Exit.OK);
        }
Example #4
0
        private int AvailableRepositories()
        {
            User.RaiseMessage("Listing all (canonical) available CKAN repositories:");
            RepositoryList repositories;

            try
            {
                repositories = FetchMasterRepositoryList();
            }
            catch
            {
                User.RaiseError("Couldn't fetch CKAN repositories master list from {0}", MainClass.GetGameInstance(Manager).game.RepositoryListURL.ToString());
                return(Exit.ERROR);
            }

            int maxNameLen = 0;

            foreach (Repository repository in repositories.repositories)
            {
                maxNameLen = Math.Max(maxNameLen, repository.name.Length);
            }

            foreach (Repository repository in repositories.repositories)
            {
                User.RaiseMessage("  {0}: {1}", repository.name.PadRight(maxNameLen), repository.uri);
            }

            return(Exit.OK);
        }
Example #5
0
        /// <summary>
        /// Installs a module, if available
        /// </summary>
        /// <param name="ksp">Game instance into which to install</param>
        /// <param name="raw_options">Command line options object</param>
        /// <returns>
        /// Exit code for shell environment
        /// </returns>
        public int RunCommand(CKAN.KSP ksp, object raw_options)
        {
            InstallOptions options = (InstallOptions)raw_options;

            if (options.ckan_files != null)
            {
                // Oooh! We're installing from a CKAN file.
                foreach (string ckan_file in options.ckan_files)
                {
                    Uri ckan_uri;

                    // Check if the argument if a wellformatted Uri.
                    if (!Uri.IsWellFormedUriString(ckan_file, UriKind.Absolute))
                    {
                        // Assume it is a local file, check if the file exists.
                        if (File.Exists(ckan_file))
                        {
                            // Get the full path of the file.
                            ckan_uri = new Uri(Path.GetFullPath(ckan_file));
                        }
                        else
                        {
                            // We have no further ideas as what we can do with this Uri, tell the user.
                            user.RaiseError("Can not find file \"{0}\".", ckan_file);
                            user.RaiseError("Exiting.");
                            return(Exit.ERROR);
                        }
                    }
                    else
                    {
                        ckan_uri = new Uri(ckan_file);
                    }

                    string filename = String.Empty;

                    // If it is a local file, we already know the filename. If it is remote, create a temporary file and download the remote resource.
                    if (ckan_uri.IsFile)
                    {
                        filename = ckan_uri.LocalPath;
                        log.InfoFormat("Installing from local CKAN file \"{0}\"", filename);
                    }
                    else
                    {
                        log.InfoFormat("Installing from remote CKAN file \"{0}\"", ckan_uri);
                        filename = Net.Download(ckan_uri, null, user);

                        log.DebugFormat("Temporary file for \"{0}\" is at \"{1}\".", ckan_uri, filename);
                    }

                    // Parse the JSON file.
                    try
                    {
                        CkanModule m = MainClass.LoadCkanFromFile(ksp, filename);
                        options.modules.Add($"{m.identifier}={m.version}");
                    }
                    catch (Kraken kraken)
                    {
                        user.RaiseError(kraken.InnerException == null
                            ? kraken.Message
                            : $"{kraken.Message}: {kraken.InnerException.Message}");
                    }
                }

                // At times RunCommand() calls itself recursively - in this case we do
                // not want to be doing this again, so "consume" the option
                options.ckan_files = null;
            }
            else
            {
                Search.AdjustModulesCase(ksp, options.modules);
            }

            if (options.modules.Count == 0)
            {
                // What? No files specified?
                user.RaiseMessage(
                    "Usage: ckan install [--with-suggests] [--with-all-suggests] [--no-recommends] [--headless] Mod [Mod2, ...]");
                return(Exit.BADOPT);
            }

            // Prepare options. Can these all be done in the new() somehow?
            var install_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
            };

            if (user.Headless)
            {
                install_ops.without_toomanyprovides_kraken = true;
                install_ops.without_enforce_consistency    = true;
            }

            RegistryManager regMgr  = RegistryManager.Instance(ksp);
            List <string>   modules = options.modules;

            for (bool done = false; !done;)
            {
                // Install everything requested. :)
                try
                {
                    HashSet <string> possibleConfigOnlyDirs = null;
                    var installer = ModuleInstaller.GetInstance(ksp, manager.Cache, user);
                    installer.InstallList(modules, install_ops, regMgr, ref possibleConfigOnlyDirs);
                    user.RaiseMessage("\r\n");
                    done = true;
                }
                catch (DependencyNotSatisfiedKraken ex)
                {
                    if (ex.version == null)
                    {
                        user.RaiseMessage("{0} requires {1} but it is not listed in the index, or not available for your version of KSP.", ex.parent, ex.module);
                    }
                    else
                    {
                        user.RaiseMessage("{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);
                    }
                    user.RaiseMessage("If you're lucky, you can do a `ckan update` and try again.");
                    user.RaiseMessage("Try `ckan install --no-recommends` to skip installation of recommended modules.");
                    user.RaiseMessage("Or `ckan install --allow-incompatible` to ignore module compatibility.");
                    return(Exit.ERROR);
                }
                catch (ModuleNotFoundKraken ex)
                {
                    if (ex.version == null)
                    {
                        user.RaiseMessage("Module {0} required but it is not listed in the index, or not available for your version of KSP.", ex.module);
                    }
                    else
                    {
                        user.RaiseMessage("Module {0} {1} required but it is not listed in the index, or not available for your version of KSP.", ex.module, ex.version);
                    }
                    user.RaiseMessage("If you're lucky, you can do a `ckan update` and try again.");
                    user.RaiseMessage("Try `ckan install --no-recommends` to skip installation of recommended modules.");
                    user.RaiseMessage("Or `ckan install --allow-incompatible` to ignore module compatibility.");
                    return(Exit.ERROR);
                }
                catch (BadMetadataKraken ex)
                {
                    user.RaiseMessage("Bad metadata detected for module {0}.", ex.module);
                    user.RaiseMessage(ex.Message);
                    return(Exit.ERROR);
                }
                catch (TooManyModsProvideKraken ex)
                {
                    // Request the user selects one of the mods.
                    string[] mods = new string[ex.modules.Count];

                    for (int i = 0; i < ex.modules.Count; i++)
                    {
                        mods[i] = String.Format("{0} ({1})", ex.modules[i].identifier, ex.modules[i].name);
                    }

                    string message = String.Format("Too many mods provide {0}. Please pick from the following:\r\n", ex.requested);

                    int result;

                    try
                    {
                        result = user.RaiseSelectionDialog(message, mods);
                    }
                    catch (Kraken e)
                    {
                        user.RaiseMessage(e.Message);

                        return(Exit.ERROR);
                    }

                    if (result < 0)
                    {
                        user.RaiseMessage(String.Empty); // Looks tidier.

                        return(Exit.ERROR);
                    }

                    // Add the module to the list.
                    modules.Add($"{ex.modules[result].identifier}={ex.modules[result].version}");
                    // DON'T return so we can loop around and try again
                }
                catch (FileExistsKraken ex)
                {
                    if (ex.owningModule != null)
                    {
                        user.RaiseMessage(
                            "\r\nOh no! We tried to overwrite a file owned by another mod!\r\n" +
                            "Please try a `ckan update` and try again.\r\n\r\n" +
                            "If this problem re-occurs, then it maybe a packaging bug.\r\n" +
                            "Please report it at:\r\n\r\n" +
                            "https://github.com/KSP-CKAN/NetKAN/issues/new\r\n\r\n" +
                            "Please including the following information in your report:\r\n\r\n" +
                            "File           : {0}\r\n" +
                            "Installing Mod : {1}\r\n" +
                            "Owning Mod     : {2}\r\n" +
                            "CKAN Version   : {3}\r\n",
                            ex.filename, ex.installingModule, ex.owningModule,
                            Meta.GetVersion(VersionFormat.Full)
                            );
                    }
                    else
                    {
                        user.RaiseMessage(
                            "\r\n\r\nOh no!\r\n\r\n" +
                            "It looks like you're trying to install a mod which is already installed,\r\n" +
                            "or which conflicts with another mod which is already installed.\r\n\r\n" +
                            "As a safety feature, the CKAN will *never* overwrite or alter a file\r\n" +
                            "that it did not install itself.\r\n\r\n" +
                            "If you wish to install {0} via the CKAN,\r\n" +
                            "then please manually uninstall the mod which owns:\r\n\r\n" +
                            "{1}\r\n\r\n" + "and try again.\r\n",
                            ex.installingModule, ex.filename
                            );
                    }

                    user.RaiseMessage("Your GameData has been returned to its original state.\r\n");
                    return(Exit.ERROR);
                }
                catch (InconsistentKraken ex)
                {
                    // The prettiest Kraken formats itself for us.
                    user.RaiseMessage(ex.InconsistenciesPretty);
                    user.RaiseMessage("Install canceled. Your files have been returned to their initial state.");
                    return(Exit.ERROR);
                }
                catch (CancelledActionKraken)
                {
                    user.RaiseMessage("Installation canceled at user request.");
                    return(Exit.ERROR);
                }
                catch (MissingCertificateKraken kraken)
                {
                    // Another very pretty kraken.
                    user.RaiseMessage(kraken.ToString());
                    return(Exit.ERROR);
                }
                catch (DownloadThrottledKraken kraken)
                {
                    user.RaiseMessage(kraken.ToString());
                    user.RaiseMessage($"Try the authtoken command. See {kraken.infoUrl} for details.");
                    return(Exit.ERROR);
                }
                catch (DownloadErrorsKraken)
                {
                    user.RaiseMessage("One or more files failed to download, stopped.");
                    return(Exit.ERROR);
                }
                catch (ModuleDownloadErrorsKraken kraken)
                {
                    user.RaiseMessage(kraken.ToString());
                    return(Exit.ERROR);
                }
                catch (DirectoryNotFoundKraken kraken)
                {
                    user.RaiseMessage("\r\n{0}", kraken.Message);
                    return(Exit.ERROR);
                }
                catch (ModuleIsDLCKraken kraken)
                {
                    user.RaiseMessage($"CKAN can't install 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 install this expansion, purchase it from one of its store pages:\r\n{storePagesMsg}");
                    }
                    return(Exit.ERROR);
                }
            }

            return(Exit.OK);
        }
Example #6
0
        /// <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.KSP 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);
            }

            User.RaiseMessage("\r\nUpgrading modules...\r\n");

            try
            {
                if (options.upgrade_all)
                {
                    var registry   = RegistryManager.Instance(ksp).registry;
                    var installed  = new Dictionary <string, ModuleVersion>(registry.Installed());
                    var to_upgrade = new List <CkanModule>();

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

                        if ((current_version is ProvidesModuleVersion) || (current_version is UnmanagedModuleVersion))
                        {
                            continue;
                        }
                        else
                        {
                            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)
                                {
                                    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);
                            }
                        }
                    }

                    ModuleInstaller.GetInstance(ksp, manager.Cache, User).Upgrade(to_upgrade, new NetAsyncModulesDownloader(User));
                }
                else
                {
                    // TODO: These instances all need to go.
                    Search.AdjustModulesCase(ksp, options.modules);
                    ModuleInstaller.GetInstance(ksp, manager.Cache, User).Upgrade(options.modules, new NetAsyncModulesDownloader(User));
                }
            }
            catch (ModuleNotFoundKraken kraken)
            {
                User.RaiseMessage("Module {0} not found", kraken.module);
                return(Exit.ERROR);
            }
            catch (InconsistentKraken kraken)
            {
                User.RaiseMessage(kraken.ToString());
                return(Exit.ERROR);
            }
            User.RaiseMessage("\r\nDone!\r\n");

            return(Exit.OK);
        }