Ejemplo n.º 1
0
        // TODO: This needs work! See GH #160.
        private static int Upgrade(UpgradeOptions options)
        {
            if (options.ckan_file == null)
            {
                // Typical case, install from cached CKAN info.

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

                // Do our un-installs and re-installs in a transaction. If something goes wrong,
                // we put the user's data back the way it was. (Both Install and Uninstall support transactions.)
                using (var transaction = new TransactionScope()) {
                    var installer = ModuleInstaller.Instance;

                    try
                    {
                        installer.UninstallList(options.modules);
                    }
                    catch (ModNotInstalledKraken kraken)
                    {
                        User.WriteLine("I can't do that, {0} is not installed.", kraken.mod);
                        return(Exit.BADOPT);
                    }

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

                    // Install everything requested. :)
                    try
                    {
                        installer.InstallList(options.modules, install_ops);
                    }
                    catch (ModuleNotFoundKraken ex)
                    {
                        User.WriteLine("Module {0} required, but not listed in index.", ex.module);
                        User.WriteLine("If you're lucky, you can do a `ckan update` and try again.");
                        return(Exit.ERROR);
                    }

                    transaction.Complete();
                }

                User.WriteLine("\nDone!\n");

                return(Exit.OK);
            }

            User.WriteLine("\nUnsupported option at this time.");

            return(Exit.BADOPT);
        }
Ejemplo n.º 2
0
 public void Setup()
 {
     registry  = CKAN.Registry.Empty();
     options   = RelationshipResolver.DefaultOpts();
     generator = new RandomModuleGenerator(new Random(0451));
     //Sanity checker means even incorrect RelationshipResolver logic was passing
     options.without_enforce_consistency = true;
 }
Ejemplo n.º 3
0
 public void Constructor_WithoutModules_AlwaysReturns()
 {
     registry = Registry.Empty();
     options  = RelationshipResolver.DefaultOpts();
     Assert.DoesNotThrow(() => new RelationshipResolver(new List <string>(),
                                                        options,
                                                        registry));
 }
Ejemplo n.º 4
0
 public void Constructor_WithoutModules_AlwaysReturns()
 {
     registry = CKAN.Registry.Empty();
     options  = RelationshipResolver.DefaultOpts();
     Assert.DoesNotThrow(() => new RelationshipResolver(new List <CfanModuleIdAndVersion>(),
                                                        options,
                                                        registry,
                                                        null));
 }
Ejemplo n.º 5
0
Archivo: Main.cs Proyecto: pjf/CKAN
        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;
        }
Ejemplo n.º 6
0
        void MigrateMods(object sender, DoWorkEventArgs e)
        {
            SetStatus("Starting mod migration process");
            SetProgressMarquee();

            var registry = Main.Instance.CurrentInstance.Registry;

            var identifiers =
                (List <string>)e.Argument;

            foreach (var identifier in identifiers)
            {
                CkanModule module = null;

                try
                {
                    module = registry.LatestAvailable(identifier, Main.Instance.CurrentInstance.Version());
                }
                catch (Exception ex)
                {
                    e.Result = ex;
                    return;
                }

                if (module == null)
                {
                    e.Result = null;
                    return;
                }

                var installer = ModuleInstaller.GetInstance(Main.Instance.CurrentInstance, Main.Instance.m_User);
                SetStatus(String.Format("Downloading mod - {0}", identifier));
                string zip = installer.CachedOrDownload(module);

                var files = ModuleInstaller.FindInstallableFiles(module, new ZipFile(zip), Main.Instance.CurrentInstance);

                SetStatus(String.Format("Removing existing files for {0}", identifier));

                foreach (var file in files)
                {
                    if (File.Exists(file.destination))
                    {
                        try
                        {
                            File.Delete(file.destination);
                            log.InfoFormat("Deleted \"{0}\"", file);
                        }
                        catch (Exception ex)
                        {
                            log.WarnFormat("Failed to delete \"{0}\" - {1}", file, ex.Message);
                            break;
                        }
                    }
                }

                SetStatus("Scanning GameData");
                Main.Instance.CurrentInstance.ScanGameData();

                SetStatus("Unregistering auto-detected module");
                // registry.DeregisterModule(Main.Instance.CurrentInstance, identifier);

                var opts = new RelationshipResolverOptions()
                {
                    with_all_suggests = false,
                    with_recommends   = true,
                    with_suggests     = false,
                    without_toomanyprovides_kraken = true
                };

                SetStatus(String.Format("Installing {0} using CKAN", identifier));
                installer.User = new NullUser();

                bool success = false;
                while (!success)
                {
                    try
                    {
                        installer.InstallList(new List <string>()
                        {
                            identifier
                        }, opts);
                        success = true;
                    }
                    catch (FileExistsKraken ex)
                    {
                        File.Delete(Path.Combine(Main.Instance.CurrentInstance.GameDir(), ex.filename));
                    }
                    catch (Exception ex)
                    {
                        e.Result = ex;
                        return;
                    }
                }
            }
        }
Ejemplo n.º 7
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 (DownloadThrottledKraken kraken)
            {
                user.RaiseMessage(kraken.ToString());
                user.RaiseMessage($"Try the authtoken command. See {kraken.infoUrl} for details.");
                return(Exit.ERROR);
            }
            catch (DownloadErrorsKraken)
            {
                user.RaiseMessage("One or more files failed to download, stopped.");
                return(Exit.ERROR);
            }
            catch (ModuleDownloadErrorsKraken kraken)
            {
                user.RaiseMessage(kraken.ToString());
                return(Exit.ERROR);
            }
            catch (DirectoryNotFoundKraken kraken)
            {
                user.RaiseMessage("\r\n{0}", kraken.Message);
                return(Exit.ERROR);
            }

            return(Exit.OK);
        }
Ejemplo n.º 8
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)
                    {
                        log.InfoFormat("Installing from local CKAN file \"{0}\"", filename);
                        filename = ckan_uri.LocalPath;
                    }
                    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.
                    options.modules.Add(LoadCkanFromFile(ksp, filename).identifier);
                }

                // 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;
            }

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

            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 (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)
            {
                // 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.Version()
                    );
                }
                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;
        }
Ejemplo n.º 9
0
        public int RunCommand(CKAN.GameInstance ksp, object raw_options)
        {
            ReplaceOptions options = (ReplaceOptions)raw_options;

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

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

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

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

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

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

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

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

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

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

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

            return(Exit.OK);
        }
Ejemplo n.º 10
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)
                    {
                        log.InfoFormat("Installing from local CFAN file \"{0}\"", filename);
                        filename = ckan_uri.LocalPath;
                    }
                    else
                    {
                        log.InfoFormat("Installing from remote CFAN 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.
                    options.modules.Add(LoadCkanFromFile(ksp, filename).identifier);
                }

                // 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;
            }

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

            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);
                var modules   = options.modules.Select(p => new CfanModuleIdAndVersion(p));
                installer.InstallList(modules, install_ops);
            }
            catch (ModuleAndVersionStringInvalidKraken ex)
            {
                user.RaiseMessage("One of mod names given was invalid, it has to be a module identifier, or in a format of <modId>=<modVersion>.");
                user.RaiseMessage("Mod identifier can only contain letters, digits, hyphen, space and underscore");
                user.RaiseMessage("Mod version must be in the format x.y.z");
                user.RaiseMessage($"Invalid string was: {ex.givenString}.");
                return(Exit.ERROR);
            }
            catch (ModuleNotFoundKraken ex)
            {
                user.RaiseMessage("Module {0} required, but not listed in index, or not available for your version of Factorio", ex.module);
                user.RaiseMessage("If you're lucky, you can do a `cfan update` and try again.");
                user.RaiseMessage("Try `cfan 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)
            {
                // 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].title);
                }

                string message = String.Format("Too many mods provide {0}. Please pick from the following:\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.owning_module != null)
                {
                    user.RaiseMessage(
                        "\nOh no! We tried to overwrite a file owned by another mod!\n" +
                        "Please try a `cfan update` and try again.\n\n" +
                        "If this problem re-occurs, then it maybe a packaging bug.\n" +
                        "Please report it at:\n\n" +
                        // @todo: add link here
                        "(here should be a link to my github issues)\n" +
                        "(but I screwed up and forgot to add it, sorry)\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" +
                        "CFAN 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 CFAN will *never* overwrite or alter a file\n" +
                        "that it did not install itself.\n\n" +
                        "If you wish to install {0} via the CFAN,\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);
                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("\n{0}", kraken.Message);
                return(Exit.ERROR);
            }

            return(Exit.OK);
        }