Exemple #1
0
        public int RunCommand(CKAN.KSP 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);
            }

            // Look for the module in the registry.
            List <CkanModule> modules = ksp.Registry.Available(ksp.Version());
            CkanModule        module  = null;

            foreach (CkanModule mod in modules)
            {
                if (mod.name == options.Modname)
                {
                    module = mod;
                }
            }

            if (module == null)
            {
                // No exact match found. Try to look for a close match.
                user.RaiseMessage("{0} not found.", options.Modname);
                user.RaiseMessage("Looking for close matches.");

                Search            search  = new Search(user);
                List <CkanModule> matches = search.PerformSearch(ksp, options.Modname);

                if (matches.Count == 0)
                {
                    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("");

                    module = 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;
                    }

                    string message = "Close matches";

                    int selection = user.RaiseSelectionDialog(message, strings_matches);

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

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

            // Is the selected module already installed?
            InstalledModule installed_module = ksp.Registry.InstalledModule(module.identifier);

            if (installed_module != null)
            {
                ShowMod(installed_module);
            }
            else
            {
                ShowMod(module);
            }

            return(Exit.OK);
        }
Exemple #2
0
        public int RunCommand(CKAN.KSP ksp, object raw_options)
        {
            SearchOptions options = (SearchOptions)raw_options;

            // Check the input.
            if (String.IsNullOrWhiteSpace(options.search_term) && String.IsNullOrWhiteSpace(options.author_term))
            {
                user.RaiseError("No search term?");

                return(Exit.BADOPT);
            }

            List <CkanModule> matching_compatible   = PerformSearch(ksp, options.search_term, options.author_term, false);
            List <CkanModule> matching_incompatible = new List <CkanModule>();

            if (options.all)
            {
                matching_incompatible = PerformSearch(ksp, options.search_term, options.author_term, true);
            }

            // Show how many matches we have.
            if (options.all && !String.IsNullOrWhiteSpace(options.author_term))
            {
                user.RaiseMessage("Found {0} compatible and {1} incompatible mods matching \"{2}\" by \"{3}\".",
                                  matching_compatible.Count().ToString(),
                                  matching_incompatible.Count().ToString(),
                                  options.search_term,
                                  options.author_term);
            }
            else if (options.all && String.IsNullOrWhiteSpace(options.author_term))
            {
                user.RaiseMessage("Found {0} compatible and {1} incompatible mods matching \"{2}\".",
                                  matching_compatible.Count().ToString(),
                                  matching_incompatible.Count().ToString(),
                                  options.search_term);
            }
            else if (!options.all && !String.IsNullOrWhiteSpace(options.author_term))
            {
                user.RaiseMessage("Found {0} compatible mods matching \"{1}\" by \"{2}\".",
                                  matching_compatible.Count().ToString(),
                                  options.search_term,
                                  options.author_term);
            }
            else if (!options.all && String.IsNullOrWhiteSpace(options.author_term))
            {
                user.RaiseMessage("Found {0} compatible mods matching \"{1}\".",
                                  matching_compatible.Count().ToString(),
                                  options.search_term);
            }

            // Present the results.
            if (!matching_compatible.Any() && (!options.all || !matching_incompatible.Any()))
            {
                return(Exit.OK);
            }

            if (options.detail)
            {
                user.RaiseMessage("Matching compatible mods:");
                foreach (CkanModule mod in matching_compatible)
                {
                    user.RaiseMessage("* {0} ({1}) - {2} by {3} - {4}",
                                      mod.identifier,
                                      mod.version,
                                      mod.name,
                                      mod.author == null ? "N/A" : String.Join(", ", mod.author),
                                      mod.@abstract);
                }

                if (matching_incompatible.Any())
                {
                    user.RaiseMessage("Matching incompatible mods:");
                    foreach (CkanModule mod in matching_incompatible)
                    {
                        Registry.GetMinMaxVersions(new List <CkanModule> {
                            mod
                        }, out _, out _, out var minKsp, out var maxKsp);
                        string kspVersion = Versioning.KspVersionRange.VersionSpan(minKsp, maxKsp).ToString();

                        user.RaiseMessage("* {0} ({1} - {2}) - {3} by {4} - {5}",
                                          mod.identifier,
                                          mod.version,
                                          kspVersion,
                                          mod.name,
                                          mod.author == null ? "N/A" : String.Join(", ", mod.author),
                                          mod.@abstract);
                    }
                }
            }
            else
            {
                List <CkanModule> matching = matching_compatible.Concat(matching_incompatible).ToList();
                matching.Sort((x, y) => string.Compare(x.identifier, y.identifier, StringComparison.Ordinal));

                foreach (CkanModule mod in matching)
                {
                    user.RaiseMessage(mod.identifier);
                }
            }

            return(Exit.OK);
        }
Exemple #3
0
 private static int Clean(CKAN.KSP current_instance)
 {
     current_instance.CleanCache();
     return(Exit.OK);
 }
Exemple #4
0
        /// <summary>
        /// Uninstalls a module, if it exists.
        /// </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)
        {
            RemoveOptions   options = (RemoveOptions)raw_options;
            RegistryManager regMgr  = RegistryManager.Instance(ksp);

            // Use one (or more!) regex to select the modules to remove
            if (options.regex)
            {
                log.Debug("Attempting Regex");
                // Parse every "module" as a grumpy regex
                var justins = options.modules.Select(s => new Regex(s));

                // Modules that have been selected by one regex
                List <string> selectedModules = new List <string>();

                // Get the list of installed modules
                // Try every regex on every installed module:
                // if it matches, select for removal
                foreach (string mod in regMgr.registry.InstalledModules.Select(mod => mod.identifier))
                {
                    if (justins.Any(re => re.IsMatch(mod)))
                    {
                        selectedModules.Add(mod);
                    }
                }

                // Replace the regular expressions with the selected modules
                // and continue removal as usual
                options.modules = selectedModules;
            }

            if (options.rmall)
            {
                log.Debug("Removing all mods");
                // Add the list of installed modules to the list that should be uninstalled
                options.modules.AddRange(
                    regMgr.registry.InstalledModules
                    .Where(mod => !mod.Module.IsDLC)
                    .Select(mod => mod.identifier)
                    );
            }

            if (options.modules != null && options.modules.Count > 0)
            {
                try
                {
                    HashSet <string> possibleConfigOnlyDirs = null;
                    var installer = ModuleInstaller.GetInstance(ksp, manager.Cache, user);
                    Search.AdjustModulesCase(ksp, options.modules);
                    installer.UninstallList(options.modules, ref possibleConfigOnlyDirs, regMgr);
                    user.RaiseMessage("");
                }
                catch (ModNotInstalledKraken kraken)
                {
                    user.RaiseMessage("I can't do that, {0} isn't installed.", kraken.mod);
                    user.RaiseMessage("Try `ckan list` for a list of installed mods.");
                    return(Exit.BADOPT);
                }
                catch (ModuleIsDLCKraken kraken)
                {
                    user.RaiseMessage($"CKAN can't remove 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 remove this expansion, follow the instructions for the store page from which you purchased it:\r\n{storePagesMsg}");
                    }
                    return(Exit.BADOPT);
                }
                catch (CancelledActionKraken k)
                {
                    user.RaiseMessage("Remove aborted: {0}", k.Message);
                    return(Exit.ERROR);
                }
            }
            else
            {
                user.RaiseMessage("No mod selected, nothing to do");
                return(Exit.BADOPT);
            }

            return(Exit.OK);
        }
Exemple #5
0
        // TODO: We should have a command (probably this one) that shows
        // info about uninstalled modules.
        private static int Show(ShowOptions options, CKAN.KSP current_instance, IUser user)
        {
            if (options.Modname == null)
            {
                // empty argument
                user.RaiseMessage("show <module> - module name argument missing, perhaps you forgot it?");
                return(Exit.BADOPT);
            }

            RegistryManager registry_manager = RegistryManager.Instance(current_instance);
            InstalledModule module           = registry_manager.registry.InstalledModule(options.Modname);

            if (module == null)
            {
                user.RaiseMessage("{0} not installed.", options.Modname);
                user.RaiseMessage("Try `ckan list` to show installed modules");
                return(Exit.BADOPT);
            }

            // TODO: Print *lots* of information out; I should never have to dig through JSON

            #region Abstract and description
            if (!string.IsNullOrEmpty(module.Module.@abstract))
            {
                user.RaiseMessage("{0}: {1}", module.Module.name, module.Module.@abstract);
            }
            else
            {
                user.RaiseMessage("{0}", module.Module.name);
            }

            if (!string.IsNullOrEmpty(module.Module.description))
            {
                user.RaiseMessage("\n{0}\n", module.Module.description);
            }
            #endregion

            #region General info (author, version...)
            user.RaiseMessage("\nModule info:");
            user.RaiseMessage("- version:\t{0}", module.Module.version);
            user.RaiseMessage("- authors:\t{0}", string.Join(", ", module.Module.author));
            user.RaiseMessage("- status:\t{0}", module.Module.release_status);
            user.RaiseMessage("- license:\t{0}", module.Module.license);
            #endregion

            #region Relationships
            if (module.Module.depends != null && module.Module.depends.Count > 0)
            {
                user.RaiseMessage("\nDepends:");
                foreach (RelationshipDescriptor dep in module.Module.depends)
                {
                    user.RaiseMessage("- {0}", RelationshipToPrintableString(dep));
                }
            }

            if (module.Module.recommends != null && module.Module.recommends.Count > 0)
            {
                user.RaiseMessage("\nRecommends:");
                foreach (RelationshipDescriptor dep in module.Module.recommends)
                {
                    user.RaiseMessage("- {0}", RelationshipToPrintableString(dep));
                }
            }

            if (module.Module.suggests != null && module.Module.suggests.Count > 0)
            {
                user.RaiseMessage("\nSuggests:");
                foreach (RelationshipDescriptor dep in module.Module.suggests)
                {
                    user.RaiseMessage("- {0}", RelationshipToPrintableString(dep));
                }
            }

            if (module.Module.ProvidesList != null && module.Module.ProvidesList.Count > 0)
            {
                user.RaiseMessage("\nProvides:");
                foreach (string prov in module.Module.ProvidesList)
                {
                    user.RaiseMessage("- {0}", prov);
                }
            }
            #endregion

            user.RaiseMessage("\nResources:");
            if (module.Module.resources.bugtracker != null)
            {
                user.RaiseMessage("- bugtracker: {0}", module.Module.resources.bugtracker.ToString());
            }
            if (module.Module.resources.homepage != null)
            {
                user.RaiseMessage("- homepage: {0}", module.Module.resources.homepage.ToString());
            }
            if (module.Module.resources.kerbalstuff != null)
            {
                user.RaiseMessage("- kerbalstuff: {0}", module.Module.resources.kerbalstuff.ToString());
            }
            if (module.Module.resources.repository != null)
            {
                user.RaiseMessage("- repository: {0}", module.Module.resources.repository.ToString());
            }


            ICollection <string> files = module.Files as ICollection <string>;
            if (files == null)
            {
                throw new InvalidCastException();
            }

            user.RaiseMessage("\nShowing {0} installed files:", files.Count);
            foreach (string file in files)
            {
                user.RaiseMessage("- {0}", file);
            }

            return(Exit.OK);
        }
Exemple #6
0
 private static int Scan(CKAN.KSP current_instance)
 {
     current_instance.ScanGameData();
     return(Exit.OK);
 }
Exemple #7
0
        public int RunCommand(CKAN.KSP ksp, object raw_options)
        {
            UpgradeOptions options = (UpgradeOptions)raw_options;

            if (options.ckan_file != null)
            {
                options.modules.Add(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");
                User.RaiseMessage("  or   ckan upgrade ckan");
                return(Exit.BADOPT);
            }

            if (!options.upgrade_all && options.modules[0] == "ckan")
            {
                User.RaiseMessage("Querying the latest CKAN version");
                var latestVersion  = AutoUpdate.FetchLatestCkanVersion();
                var currentVersion = new Version(Meta.Version());

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

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

                return(Exit.OK);
            }

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

            try
            {
                if (options.upgrade_all)
                {
                    var installed  = new Dictionary <string, Version>(ksp.Registry.Installed());
                    var to_upgrade = new List <CkanModule>();

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

                        if ((current_version is ProvidesVersion) || (current_version is DllVersion))
                        {
                            continue;
                        }
                        else
                        {
                            try
                            {
                                // Check if upgrades are available
                                CkanModule latest = ksp.Registry.LatestAvailable(mod.Key, ksp.Version());

                                // 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, User).Upgrade(to_upgrade, new NetAsyncDownloader(User));
                }
                else
                {
                    // TODO: These instances all need to go.
                    ModuleInstaller.GetInstance(ksp, User).Upgrade(options.modules, new NetAsyncDownloader(User));
                }
            }
            catch (ModuleNotFoundKraken kraken)
            {
                User.RaiseMessage(kraken.Message);
                return(Exit.ERROR);
            }
            User.RaiseMessage("\nDone!\n");

            return(Exit.OK);
        }
Exemple #8
0
        public static int Main(string[] args)
        {
            BasicConfigurator.Configure();
            LogManager.GetRepository().Threshold = Level.Warn;
            log.Debug("CKAN started");

            // If we're starting with no options then invoke the GUI instead.

            if (args.Length == 0)
            {
                return(Gui());
            }

            IUser   user = new ConsoleUser();
            Options cmdline;

            try
            {
                cmdline = new Options(args);
            }
            catch (BadCommandKraken)
            {
                // Our help screen will already be shown. Let's add some extra data.
                user.RaiseMessage("You are using CKAN version {0}", Meta.Version());

                return(Exit.BADOPT);
            }

            // Process commandline options.

            var options = (CommonOptions)cmdline.options;

            if (options.Debug)
            {
                LogManager.GetRepository().Threshold = Level.Debug;
                log.Info("Debug logging enabled");
            }
            else if (options.Verbose)
            {
                LogManager.GetRepository().Threshold = Level.Info;
                log.Info("Verbose logging enabled");
            }

            // Assign user-agent string if user has given us one
            if (options.NetUserAgent != null)
            {
                Net.UserAgentString = options.NetUserAgent;
            }

            // TODO: Allow the user to specify just a directory.
            // User provided KSP instance

            if (options.KSPdir != null && options.KSP != null)
            {
                user.RaiseMessage("--ksp and --kspdir can't be specified at the same time");
                return(Exit.BADOPT);
            }
            KSPManager manager = new KSPManager(user);

            if (options.KSP != null)
            {
                // Set a KSP directory by its alias.

                try
                {
                    manager.SetCurrentInstance(options.KSP);
                }
                catch (InvalidKSPInstanceKraken)
                {
                    user.RaiseMessage("Invalid KSP installation specified \"{0}\", use '--kspdir' to specify by path, or 'list-installs' to see known KSP installations", options.KSP);
                    return(Exit.BADOPT);
                }
            }
            else if (options.KSPdir != null)
            {
                // Set a KSP directory by its path

                manager.SetCurrentInstanceByPath(options.KSPdir);
            }
            else if (!(cmdline.action == "ksp" || cmdline.action == "version"))
            {
                // Find whatever our preferred instance is.
                // We don't do this on `ksp/version` commands, they don't need it.
                CKAN.KSP ksp = manager.GetPreferredInstance();

                if (ksp == null)
                {
                    user.RaiseMessage("I don't know where KSP is installed.");
                    user.RaiseMessage("Use 'ckan ksp help' for assistance on setting this.");
                    return(Exit.ERROR);
                }
                else
                {
                    log.InfoFormat("Using KSP install at {0}", ksp.GameDir());
                }
            }

            #region Aliases

            switch (cmdline.action)
            {
            case "add":
                cmdline.action = "install";
                break;

            case "uninstall":
                cmdline.action = "remove";
                break;

            default:
                break;
            }

            #endregion

            switch (cmdline.action)
            {
            case "gui":
                return(Gui());

            case "version":
                return(Version(user));

            case "update":
                return(Update((UpdateOptions)options, RegistryManager.Instance(manager.CurrentInstance), manager.CurrentInstance, user));

            case "available":
                return(Available(manager.CurrentInstance, user));

            case "install":
                return(Install((InstallOptions)cmdline.options, manager.CurrentInstance, user));

            case "scan":
                return(Scan(manager.CurrentInstance));

            case "list":
                return(List(user, manager.CurrentInstance));

            case "show":
                return(Show((ShowOptions)cmdline.options, manager.CurrentInstance, user));

            case "remove":
                return(Remove((RemoveOptions)cmdline.options, manager.CurrentInstance, user));

            case "upgrade":
                var upgrade = new Upgrade(user);
                return(upgrade.RunCommand(manager.CurrentInstance, cmdline.options));

            case "clean":
                return(Clean(manager.CurrentInstance));

            case "repair":
                var repair = new Repair(manager.CurrentInstance, user);
                return(repair.RunSubCommand((SubCommandOptions)cmdline.options));

            case "ksp":
                var ksp = new KSP(manager, user);
                return(ksp.RunSubCommand((SubCommandOptions)cmdline.options));

            default:
                user.RaiseMessage("Unknown command, try --help");
                return(Exit.BADOPT);
            }
        }
Exemple #9
0
        public int RunCommand(CKAN.KSP ksp, object raw_options)
        {
            UpgradeOptions options = (UpgradeOptions)raw_options;

            if (options.ckan_file != null)
            {
                User.RaiseMessage("\nUnsupported option at this time.");
                return(Exit.BADOPT);
            }

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

            var to_upgrade = new List <CkanModule> ();

            foreach (string mod in options.modules)
            {
                Match match = Regex.Match(mod, @"^(?<mod>[^=]*)=(?<version>.*)$");

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

                    CkanModule module = ksp.Registry.GetModuleByVersion(ident, version);

                    if (module == null)
                    {
                        User.RaiseMessage("Cannot install {0}, version {1} not available", ident, version);
                        return(Exit.ERROR);
                    }

                    to_upgrade.Add(module);
                }
                else
                {
                    to_upgrade.Add(
                        ksp.Registry.LatestAvailable(mod, ksp.Version())
                        );
                }
            }


            var auto_detected_modules = to_upgrade.Where(module => ksp.Registry.IsAutodetected(module.identifier)).ToList();

            foreach (var module in auto_detected_modules.Select(mod => mod.identifier))
            {
                User.RaiseMessage("Cannot upgrade {0} as it was not installed by CKAN. \n Please remove manually before trying again", module);
            }
            //Exit if any are auto_detected
            if (auto_detected_modules.Any())
            {
                return(Exit.ERROR);
            }

            User.RaiseMessage("\nUpgrading modules...\n");
            // TODO: These instances all need to go.
            ModuleInstaller.GetInstance(ksp, User).Upgrade(to_upgrade, new NetAsyncDownloader(User));
            User.RaiseMessage("\nDone!\n");
            return(Exit.OK);
        }
Exemple #10
0
        public static int Main(string[] args)
        {
            BasicConfigurator.Configure();
            LogManager.GetRepository().Threshold = Level.Warn;
            log.Debug("CKAN started");

            // If we're starting with no options, and this isn't
            // a stable build, then invoke the GUI instead.

            if (args.Length == 0)
            {
                if (Meta.IsStable())
                {
                    args = new string[] { "--help" };
                }
                else
                {
                    return(Gui());
                }
            }

            Options cmdline;

            try
            {
                cmdline = new Options(args);
            }
            catch (BadCommandKraken)
            {
                // Our help screen will already be shown. Let's add some extra data.
                User.WriteLine("You are using CKAN version {0}", Meta.Version());

                return(Exit.BADOPT);
            }

            // Process commandline options.

            var options = (CommonOptions)cmdline.options;

            if (options.Debug)
            {
                LogManager.GetRepository().Threshold = Level.Debug;
                log.Info("Debug logging enabled");
            }
            else if (options.Verbose)
            {
                LogManager.GetRepository().Threshold = Level.Info;
                log.Info("Verbose logging enabled");
            }

            // TODO: Allow the user to specify just a directory.
            // User provided KSP instance

            if (options.KSPdir != null && options.KSP != null)
            {
                User.WriteLine("--ksp and --kspdir can't be specified at the same time");
                return(Exit.BADOPT);
            }

            if (options.KSP != null)
            {
                // Set a KSP directory by its alias.

                try
                {
                    KSPManager.SetCurrentInstance(options.KSP);
                }
                catch (InvalidKSPInstanceKraken)
                {
                    User.WriteLine("Invalid KSP installation specified \"{0}\", use '--kspdir' to specify by path, or 'list-installs' to see known KSP installations", options.KSP);
                    return(Exit.BADOPT);
                }
            }
            else if (options.KSPdir != null)
            {
                // Set a KSP directory by its path

                KSPManager.SetCurrentInstanceByPath(options.KSPdir);
            }
            else if (!(cmdline.action == "ksp" || cmdline.action == "version"))
            {
                // Find whatever our preferred instance is.
                // We don't do this on `ksp/version` commands, they don't need it.
                CKAN.KSP ksp = KSPManager.GetPreferredInstance();

                if (ksp == null)
                {
                    User.WriteLine("I don't know where KSP is installed.");
                    User.WriteLine("Use 'ckan ksp help' for assistance on setting this.");
                    return(Exit.ERROR);
                }
                else
                {
                    log.InfoFormat("Using KSP install at {0}", ksp.GameDir());
                }
            }

            switch (cmdline.action)
            {
            case "gui":
                return(Gui());

            case "version":
                return(Version());

            case "update":
                return(Update((UpdateOptions)options));

            case "available":
                return(Available());

            case "install":
                return(Install((InstallOptions)cmdline.options));

            case "scan":
                return(Scan());

            case "list":
                return(List());

            case "show":
                return(Show((ShowOptions)cmdline.options));

            case "remove":
                return(Remove((RemoveOptions)cmdline.options));

            case "upgrade":
                return(Upgrade((UpgradeOptions)cmdline.options));

            case "clean":
                return(Clean());

            case "repair":
                return(RunSubCommand <Repair>((SubCommandOptions)cmdline.options));

            case "ksp":
                return(RunSubCommand <KSP>((SubCommandOptions)cmdline.options));

            default:
                User.WriteLine("Unknown command, try --help");
                return(Exit.BADOPT);
            }
        }
Exemple #11
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 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 || 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);
                }
                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, manager.Cache), ref possibleConfigOnlyDirs, regMgr);
                }
            }
            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);
        }
Exemple #12
0
        public int RunCommand(CKAN.KSP 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 registry   = RegistryManager.Instance(ksp).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("\r\nContinue?");

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

                // TODO: These instances all need to go.
                try
                {
                    ModuleInstaller.GetInstance(ksp, manager.Cache, User).Replace(to_replace, replace_ops, new NetAsyncModulesDownloader(User));
                    User.RaiseMessage("\r\nDone!\r\n");
                }
                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);
        }
Exemple #13
0
        // Uninstalls a module, if it exists.
        public int RunCommand(CKAN.KSP ksp, object raw_options)
        {
            RemoveOptions options = (RemoveOptions)raw_options;

            // Use one (or more!) regex to select the modules to remove
            if (options.regex)
            {
                log.Debug("Attempting Regex");
                // Parse every "module" as a grumpy regex
                var justins = options.modules.Select(s => new Regex(s));

                // Modules that have been selected by one regex
                List <string> selectedModules = new List <string>();

                // Get the list of installed modules
                IRegistryQuerier registry = RegistryManager.Instance(ksp).registry;

                // Try every regex on every installed module:
                // if it matches, select for removal
                foreach (string mod in registry.InstalledModules.Select(mod => mod.identifier))
                {
                    if (justins.Any(re => re.IsMatch(mod)))
                    {
                        selectedModules.Add(mod);
                    }
                }

                // Replace the regular expressions with the selected modules
                // and continue removal as usual
                options.modules = selectedModules;
            }

            if (options.rmall)
            {
                log.Debug("Removing all mods");
                // Add the list of installed modules to the list that should be uninstalled
                IRegistryQuerier registry = RegistryManager.Instance(ksp).registry;
                options.modules.AddRange(
                    registry.InstalledModules.Select(mod => mod.identifier)
                    );
            }

            if (options.modules != null && options.modules.Count > 0)
            {
                try
                {
                    var installer = ModuleInstaller.GetInstance(ksp, user);
                    Search.AdjustModulesCase(ksp, options.modules);
                    installer.UninstallList(options.modules);
                }
                catch (ModNotInstalledKraken kraken)
                {
                    user.RaiseMessage("I can't do that, {0} isn't installed.", kraken.mod);
                    user.RaiseMessage("Try `ckan list` for a list of installed mods.");
                    return(Exit.BADOPT);
                }
            }
            else
            {
                user.RaiseMessage("No mod selected, nothing to do");
                return(Exit.BADOPT);
            }

            return(Exit.OK);
        }
Exemple #14
0
        private static int Update(UpdateOptions options, RegistryManager registry_manager, CKAN.KSP current_instance, IUser user)
        {
            user.RaiseMessage("Downloading updates...");

            try
            {
                int updated = Repo.Update(registry_manager, current_instance.Version(), options.repo);
                user.RaiseMessage("Updated information on {0} available modules", updated);
            }
            catch (MissingCertificateKraken kraken)
            {
                // Handling the kraken means we have prettier output.
                user.RaiseMessage(kraken.ToString());
                return(Exit.ERROR);
            }

            return(Exit.OK);
        }
Exemple #15
0
        public int RunCommand(CKAN.KSP 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.
            InstalledModule installedModuleToShow = ksp.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 = ksp.Registry
                                      .Available(ksp.Version())
                                      .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 available mods for KSP {0}.", ksp.Version());

                Search            search  = new Search(user);
                List <CkanModule> matches = search.PerformSearch(ksp, options.Modname);

                // Display the results of the search.
                if (matches.Count == 0)
                {
                    // 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));
        }
Exemple #16
0
        private static int List(IUser user, CKAN.KSP current_instance)
        {
            CKAN.KSP ksp = current_instance;

            user.RaiseMessage("\nKSP found at {0}\n", ksp.GameDir());
            user.RaiseMessage("KSP Version: {0}\n", ksp.Version());

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

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

            var installed = new SortedDictionary <string, Version>(registry.Installed());

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

                string bullet = "*";

                if (current_version is ProvidesVersion)
                {
                    // Skip virtuals for now.
                    continue;
                }
                else if (current_version is DllVersion)
                {
                    // Autodetected dll
                    bullet = "-";
                }
                else
                {
                    try
                    {
                        // Check if upgrades are available, and show appropriately.
                        CkanModule latest = registry.LatestAvailable(mod.Key, ksp.Version());

                        log.InfoFormat("Latest {0} is {1}", mod.Key, latest);

                        if (latest == null)
                        {
                            // Not compatible!
                            bullet = "✗";
                        }
                        else if (latest.version.IsEqualTo(current_version))
                        {
                            // Up to date
                            bullet = "✓";
                        }
                        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} {2}", bullet, mod.Key, mod.Value);
            }

            user.RaiseMessage("\nLegend: ✓ - Up to date. ✗ - Incompatible. ↑ - Upgradable. ? - Unknown ");

            return(Exit.OK);
        }
Exemple #17
0
        public static int Main(string[] args)
        {
            // Launch debugger if the "--debugger" flag is present in the command line arguments.
            // We want to do this as early as possible so just check the flag manually, rather than doing the
            // more robust argument parsing.
            if (args.Any(i => i == "--debugger"))
            {
                Debugger.Launch();
            }

            if (args.Length == 1 && args.Any(i => i == "--verbose" || i == "--debug"))
            {
                // Start the gui with logging enabled #437
                var guiCommand = args.ToList();
                guiCommand.Insert(0, "gui");
                args = guiCommand.ToArray();
            }

            Logging.Initialize();
            log.Debug("CKAN started");

            Options cmdline;

            // If we're starting with no options then invoke the GUI instead.
            if (args.Length == 0)
            {
                return(Gui(new GuiOptions(), args));
            }

            IUser user;

            try
            {
                cmdline = new Options(args);
            }
            catch (BadCommandKraken)
            {
                // Our help screen will already be shown. Let's add some extra data.
                user = new ConsoleUser(false);
                user.RaiseMessage("You are using CKAN version {0}", Meta.Version());

                return(Exit.BADOPT);
            }

            // Process commandline options.

            var options = (CommonOptions)cmdline.options;

            user = new ConsoleUser(options.Headless);
            CheckMonoVersion(user, 3, 1, 0);

            // Processes in Docker containers normally run as root.
            // If we are running in a Docker container, do not require --asroot.
            // Docker creates a .dockerenv file in the root of each container.
            if ((Platform.IsUnix || Platform.IsMac) && CmdLineUtil.GetUID() == 0 && !File.Exists("/.dockerenv"))
            {
                if (!options.AsRoot)
                {
                    user.RaiseError(@"You are trying to run CKAN as root.
This is a bad idea and there is absolutely no good reason to do it. Please run CKAN from a user account (or use --asroot if you are feeling brave).");
                    return(Exit.ERROR);
                }
                else
                {
                    user.RaiseMessage("Warning: Running CKAN as root!");
                }
            }

            if (options.Debug)
            {
                LogManager.GetRepository().Threshold = Level.Debug;
                log.Info("Debug logging enabled");
            }
            else if (options.Verbose)
            {
                LogManager.GetRepository().Threshold = Level.Info;
                log.Info("Verbose logging enabled");
            }

            // Assign user-agent string if user has given us one
            if (options.NetUserAgent != null)
            {
                Net.UserAgentString = options.NetUserAgent;
            }

            // User provided KSP instance

            if (options.KSPdir != null && options.KSP != null)
            {
                user.RaiseMessage("--ksp and --kspdir can't be specified at the same time");
                return(Exit.BADOPT);
            }

            var manager = new KSPManager(user);

            if (options.KSP != null)
            {
                // Set a KSP directory by its alias.

                try
                {
                    manager.SetCurrentInstance(options.KSP);
                }
                catch (InvalidKSPInstanceKraken)
                {
                    user.RaiseMessage("Invalid KSP installation specified \"{0}\", use '--kspdir' to specify by path, or 'list-installs' to see known KSP installations", options.KSP);
                    return(Exit.BADOPT);
                }
            }
            else if (options.KSPdir != null)
            {
                // Set a KSP directory by its path
                manager.SetCurrentInstanceByPath(options.KSPdir);
            }
            else if (!(cmdline.action == "ksp" || cmdline.action == "version" || cmdline.action == "gui"))
            {
                // Find whatever our preferred instance is.
                // We don't do this on `ksp/version/gui` commands, they don't need it.
                CKAN.KSP ksp = manager.GetPreferredInstance();

                if (ksp == null)
                {
                    user.RaiseMessage("I don't know where KSP is installed.");
                    user.RaiseMessage("Use 'ckan ksp help' for assistance on setting this.");
                    return(Exit.ERROR);
                }
                else
                {
                    log.InfoFormat("Using KSP install at {0}", ksp.GameDir());
                }
            }

            #region Aliases

            switch (cmdline.action)
            {
            case "add":
                cmdline.action = "install";
                break;

            case "uninstall":
                cmdline.action = "remove";
                break;
            }

            #endregion

            //If we have found a preferred KSP instance, try to lock the registry
            if (manager.CurrentInstance != null)
            {
                try
                {
                    using (var registry = RegistryManager.Instance(manager.CurrentInstance))
                    {
                        log.InfoFormat("About to run action {0}", cmdline.action);
                        return(RunAction(cmdline, options, args, user, manager));
                    }
                }
                catch (RegistryInUseKraken kraken)
                {
                    log.Info("Registry in use detected");
                    user.RaiseMessage(kraken.ToString());
                    return(Exit.ERROR);
                }
            }
            else // we have no preferred KSP instance, so no need to lock the registry
            {
                return(RunAction(cmdline, options, args, user, manager));
            }
        }
Exemple #18
0
        private static int Install(InstallOptions options, CKAN.KSP current_instance, IUser user)
        {
            if (options.ckan_file != null)
            {
                // Oooh! We're installing from a CKAN file.
                log.InfoFormat("Installing from CKAN file {0}", options.ckan_file);

                CkanModule module = CkanModule.FromFile(options.ckan_file);

                // We'll need to make some registry changes to do this.
                RegistryManager registry_manager = RegistryManager.Instance(current_instance);

                // Remove this version of the module in the registry, if it exists.
                registry_manager.registry.RemoveAvailable(module);

                // Sneakily add our version in...
                registry_manager.registry.AddAvailable(module);

                // Add our module to the things we should install...
                options.modules.Add(module.identifier);

                // And continue with our install as per normal.
            }

            if (options.modules.Count == 0)
            {
                // What? No files specified?
                user.RaiseMessage(
                    "Usage: ckan install [--with-suggests] [--with-all-suggests] [--no-recommends] 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
            };

            // Install everything requested. :)
            try
            {
                var installer = ModuleInstaller.GetInstance(current_instance, user);
                installer.InstallList(options.modules, install_ops);
            }
            catch (ModuleNotFoundKraken ex)
            {
                user.RaiseMessage("Module {0} required, but not listed in index, or not available for your version of KSP", ex.module);
                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");
                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)
            {
                user.RaiseMessage("Too many mods provide {0}. Please pick from the following:\n", ex.requested);

                foreach (CkanModule mod in ex.modules)
                {
                    user.RaiseMessage("* {0} ({1})", mod.identifier, mod.name);
                }

                user.RaiseMessage(String.Empty); // Looks tidier.

                return(Exit.ERROR);
            }
            catch (FileExistsKraken ex)
            {
                if (ex.owning_module != null)
                {
                    user.RaiseMessage(
                        "\nOh no! We tried to overwrite a file owned by another mod!\n" +
                        "Please try a `ckan update` and try again.\n\n" +
                        "If this problem re-occurs, then it maybe a packaging bug.\n" +
                        "Please report it at:\n\n" +
                        "https://github.com/KSP-CKAN/CKAN-meta/issues/new\n\n" +
                        "Please including the following information in your report:\n\n" +
                        "File           : {0}\n" +
                        "Installing Mod : {1}\n" +
                        "Owning Mod     : {2}\n" +
                        "CKAN Version   : {3}\n",
                        ex.filename, ex.installing_module, ex.owning_module,
                        Meta.Version()
                        );
                }
                else
                {
                    user.RaiseMessage(
                        "\n\nOh no!\n\n" +
                        "It looks like you're trying to install a mod which is already installed,\n" +
                        "or which conflicts with another mod which is already installed.\n\n" +
                        "As a safety feature, the CKAN will *never* overwrite or alter a file\n" +
                        "that it did not install itself.\n\n" +
                        "If you wish to install {0} via the CKAN,\n" +
                        "then please manually uninstall the mod which owns:\n\n" +
                        "{1}\n\n" + "and try again.\n",
                        ex.installing_module, ex.filename
                        );
                }

                user.RaiseMessage("Your GameData has been returned to its original state.\n");
                return(Exit.ERROR);
            }
            catch (InconsistentKraken ex)
            {
                // The prettiest Kraken formats itself for us.
                user.RaiseMessage(ex.InconsistenciesPretty);
                return(Exit.ERROR);
            }
            catch (CancelledActionKraken)
            {
                user.RaiseMessage("Installation cancelled at user request.");
                return(Exit.ERROR);
            }
            catch (MissingCertificateKraken kraken)
            {
                // Another very pretty kraken.
                user.RaiseMessage(kraken.ToString());
                return(Exit.ERROR);
            }
            catch (DownloadErrorsKraken)
            {
                user.RaiseMessage("One or more files failed to download, stopped.");
                return(Exit.ERROR);
            }

            return(Exit.OK);
        }
Exemple #19
0
        public int RunCommand(CKAN.KSP ksp, object raw_options)
        {
            UpgradeOptions options = (UpgradeOptions)raw_options;

            if (options.ckan_file != null)
            {
                options.modules.Add(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");
                return(Exit.BADOPT);
            }

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

            try
            {
                if (options.upgrade_all)
                {
                    var installed  = new Dictionary <string, Version>(ksp.Registry.Installed());
                    var to_upgrade = new List <CkanModule>();

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

                        if ((current_version is ProvidesVersion) || (current_version is DllVersion))
                        {
                            continue;
                        }
                        else
                        {
                            try
                            {
                                // Check if upgrades are available
                                CkanModule latest = ksp.Registry.LatestAvailable(mod.Key, ksp.Version());

                                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, User).Upgrade(to_upgrade, new NetAsyncDownloader(User));
                }
                else
                {
                    // TODO: These instances all need to go.
                    ModuleInstaller.GetInstance(ksp, User).Upgrade(options.modules, new NetAsyncDownloader(User));
                }
            }
            catch (ModuleNotFoundKraken kraken)
            {
                User.RaiseMessage(kraken.Message);
                return(Exit.ERROR);
            }
            User.RaiseMessage("\nDone!\n");

            return(Exit.OK);
        }
Exemple #20
0
        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 = 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;
            }

            // Install everything requested. :)
            try
            {
                var installer = ModuleInstaller.GetInstance(ksp, user);
                installer.InstallList(options.modules, install_ops);
            }
            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.
                options.modules.Add(ex.modules[result].identifier);

                return(new Install(user).RunCommand(ksp, options));
            }
            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 (DownloadErrorsKraken)
            {
                user.RaiseMessage("One or more files failed to download, stopped.");
                return(Exit.ERROR);
            }
            catch (DirectoryNotFoundKraken kraken)
            {
                user.RaiseMessage("\r\n{0}", kraken.Message);
                return(Exit.ERROR);
            }

            return(Exit.OK);
        }
Exemple #21
0
        public int RunCommand(CKAN.KSP 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);

                            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 = "-";
                                //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. 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);
        }
Exemple #22
0
        public static int Main(string[] args)
        {
            BasicConfigurator.Configure();
            LogManager.GetRepository().Threshold = Level.Warn;
            log.Debug("CKAN started");

            Options cmdline;
            IUser   user = null;

            // If we're starting with no options then invoke the GUI instead.
            if (args.Length == 0)
            {
                return(Gui(new GuiOptions(), args));
            }

            try
            {
                cmdline = new Options(args);
            }
            catch (BadCommandKraken)
            {
                // Our help screen will already be shown. Let's add some extra data.
                user = new ConsoleUser(false);
                user.RaiseMessage("You are using CKAN version {0}", Meta.Version());

                return(Exit.BADOPT);
            }

            // Process commandline options.

            var options = (CommonOptions)cmdline.options;

            user = new ConsoleUser(options.Headless);
            CheckMonoVersion(user, 3, 1, 0);

            if ((Platform.IsUnix || Platform.IsMac) && CmdLineUtil.GetUID() == 0)
            {
                if (!options.AsRoot)
                {
                    user.RaiseError(@"You are trying to run CKAN as root. 
This is a bad idea and there is absolutely no good reason to do it. Please run CKAN from a user account (or use --asroot if you are feeling brave).");
                    return(Exit.ERROR);
                }
                else
                {
                    user.RaiseMessage("Warning: Running CKAN as root!");
                }
            }

            if (options.Debug)
            {
                LogManager.GetRepository().Threshold = Level.Debug;
                log.Info("Debug logging enabled");
            }
            else if (options.Verbose)
            {
                LogManager.GetRepository().Threshold = Level.Info;
                log.Info("Verbose logging enabled");
            }

            // Assign user-agent string if user has given us one
            if (options.NetUserAgent != null)
            {
                Net.UserAgentString = options.NetUserAgent;
            }

            // TODO: Allow the user to specify just a directory.
            // User provided KSP instance

            if (options.KSPdir != null && options.KSP != null)
            {
                user.RaiseMessage("--ksp and --kspdir can't be specified at the same time");
                return(Exit.BADOPT);
            }
            KSPManager manager = new KSPManager(user);

            if (options.KSP != null)
            {
                // Set a KSP directory by its alias.

                try
                {
                    manager.SetCurrentInstance(options.KSP);
                }
                catch (InvalidKSPInstanceKraken)
                {
                    user.RaiseMessage("Invalid KSP installation specified \"{0}\", use '--kspdir' to specify by path, or 'list-installs' to see known KSP installations", options.KSP);
                    return(Exit.BADOPT);
                }
            }
            else if (options.KSPdir != null)
            {
                // Set a KSP directory by its path

                manager.SetCurrentInstanceByPath(options.KSPdir);
            }
            else if (!(cmdline.action == "ksp" || cmdline.action == "version"))
            {
                // Find whatever our preferred instance is.
                // We don't do this on `ksp/version` commands, they don't need it.
                CKAN.KSP ksp = manager.GetPreferredInstance();

                if (ksp == null)
                {
                    user.RaiseMessage("I don't know where KSP is installed.");
                    user.RaiseMessage("Use 'ckan ksp help' for assistance on setting this.");
                    return(Exit.ERROR);
                }
                else
                {
                    log.InfoFormat("Using KSP install at {0}", ksp.GameDir());
                }
            }

            #region Aliases

            switch (cmdline.action)
            {
            case "add":
                cmdline.action = "install";
                break;

            case "uninstall":
                cmdline.action = "remove";
                break;

            default:
                break;
            }

            #endregion

            switch (cmdline.action)
            {
            case "gui":
                return(Gui((GuiOptions)options, args));

            case "version":
                return(Version(user));

            case "update":
                return((new Update(user)).RunCommand(manager.CurrentInstance, (UpdateOptions)cmdline.options));

            case "available":
                return(Available(manager.CurrentInstance, user));

            case "install":
                Scan(manager.CurrentInstance);
                return((new Install(user)).RunCommand(manager.CurrentInstance, (InstallOptions)cmdline.options));

            case "scan":
                return(Scan(manager.CurrentInstance));

            case "list":
                return((new List(user)).RunCommand(manager.CurrentInstance, (ListOptions)cmdline.options));

            case "show":
                return((new Show(user)).RunCommand(manager.CurrentInstance, (ShowOptions)cmdline.options));

            case "search":
                return((new Search(user)).RunCommand(manager.CurrentInstance, options));

            case "remove":
                return((new Remove(user)).RunCommand(manager.CurrentInstance, cmdline.options));

            case "upgrade":
                Scan(manager.CurrentInstance);
                return((new Upgrade(user)).RunCommand(manager.CurrentInstance, cmdline.options));

            case "clean":
                return(Clean(manager.CurrentInstance));

            case "repair":
                var repair = new Repair(manager.CurrentInstance, user);
                return(repair.RunSubCommand((SubCommandOptions)cmdline.options));

            case "ksp":
                var ksp = new KSP(manager, user);
                return(ksp.RunSubCommand((SubCommandOptions)cmdline.options));

            case "repo":
                var repo = new Repo(manager, user);
                return(repo.RunSubCommand((SubCommandOptions)cmdline.options));

            case "compare":
                return((new Compare()).RunCommand(manager.CurrentInstance, cmdline.options));

            default:
                user.RaiseMessage("Unknown command, try --help");
                return(Exit.BADOPT);
            }
        }
Exemple #23
0
 public Repair(CKAN.KSP current_instance, IUser user)
 {
     CurrentInstance = current_instance;
     User            = user;
 }
Exemple #24
0
        public int RunCommand(CKAN.KSP 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("\nKSP found at {0}\n", ksp.GameDir());
                user.RaiseMessage("KSP Version: {0}\n", ksp.Version());

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

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

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

                    string bullet = "*";

                    if (current_version is ProvidesVersion)
                    {
                        // Skip virtuals for now.
                        continue;
                    }
                    else if (current_version is DllVersion)
                    {
                        // Autodetected dll
                        bullet = "-";
                    }
                    else
                    {
                        try
                        {
                            // Check if upgrades are available, and show appropriately.
                            CkanModule latest = registry.LatestAvailable(mod.Key, ksp.Version());

                            log.InfoFormat("Latest {0} is {1}", mod.Key, latest);

                            if (latest == null)
                            {
                                // Not compatible!
                                bullet = "X";
                            }
                            else if (latest.version.IsEqualTo(current_version))
                            {
                                // Up to date
                                bullet = "-";
                            }
                            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} {2}", bullet, mod.Key, mod.Value);
                }
            }
            else
            {
                var stream = Console.OpenStandardOutput();
                new Exporter(exportFileType.Value).Export(registry, stream);
                stream.Flush();
            }

            if (!(options.porcelain) && exportFileType == null)
            {
                user.RaiseMessage("\nLegend: -: Up to date. X: Incompatible. ^: Upgradable. ?: Unknown ");
            }

            return(Exit.OK);
        }
Exemple #25
0
 public void Dispose()
 {
     Directory.Delete(disposable_dir, true);
     _ksp = null; // In case .Dispose() was called manually.
 }