/// <summary> /// Locates the changes between the prior and post state of the modules.. /// </summary> /// <param name="modules_prior">List of the available modules prior to the update.</param> /// <param name="modules_post">List of the available modules after the update.</param> private void PrintChanges(List<CkanModule> modules_prior, List<CkanModule> modules_post) { var prior = new HashSet<CkanModule>(modules_prior, new NameComparer()); var post = new HashSet<CkanModule>(modules_post, new NameComparer()); var added = new HashSet<CkanModule>(post.Except(prior, new NameComparer())); var removed = new HashSet<CkanModule>(prior.Except(post, new NameComparer())); var unchanged = post.Intersect(prior);//Default compare includes versions var updated = post.Except(unchanged).Except(added).Except(removed).ToList(); // Print the changes. user.RaiseMessage("Found {0} new modules, {1} removed modules and {2} updated modules.", added.Count(), removed.Count(), updated.Count()); if (added.Count > 0) { PrintModules("New modules [Name (CKAN identifier)]:", added); } if (removed.Count > 0) { PrintModules("Removed modules [Name (CKAN identifier)]:", removed); } if (updated.Count > 0) { PrintModules("Updated modules [Name (CKAN identifier)]:", updated); } }
/// <summary> /// Searches for the term in the list of available modules for the ksp instance. Looks in name, identifier and description fields. /// </summary> /// <returns>List of mathcing modules.</returns> /// <param name="ksp">The KSP instance to perform the search for.</param> /// <param name="term">The search term. Case insensitive.</param> public List<CkanModule> PerformSearch(CKAN.KSP ksp, string term) { List<CkanModule> matching_mods = new List<CkanModule>(); // Get a list of available mods. List<CkanModule> available_mods = ksp.Registry.Available(ksp.Version()); // Look for the search term in the list. foreach (CkanModule mod in available_mods) { // Extract the description. This is an optional field and may be null. string mod_description = String.Empty; if (!String.IsNullOrEmpty(mod.description)) { mod_description = mod.description; } // Look for a match in each string. if (mod.name.IndexOf(term, StringComparison.OrdinalIgnoreCase) > -1 || mod.identifier.IndexOf(term, StringComparison.OrdinalIgnoreCase) > -1 || mod_description.IndexOf(term, StringComparison.OrdinalIgnoreCase) > -1) { matching_mods.Add(mod); } } return matching_mods; }
// 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 Registry registry = RegistryManager.Instance(ksp).registry; var installed = new SortedDictionary<string, Version>(registry.Installed(false)); // Try every regex on every installed module: // if it matches, select for removal foreach (string mod in installed.Keys) { 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.modules != null && options.modules.Count > 0) { try { var installer = ModuleInstaller.GetInstance(ksp, user); 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; }
/// <summary> /// Locates the changes between the prior and post state of the modules.. /// </summary> /// <param name="modules_prior">List of the available modules prior to the update.</param> /// <param name="modules_post">List of the available modules after the update.</param> private void PrintChanges(List<CkanModule> modules_prior, List<CkanModule> modules_post) { // Check for new modules. List<CkanModule> added = modules_post.Where(a => !modules_prior.Select(b => b.name).Contains(a.name)).ToList(); // Check for removed modules. List<CkanModule> removed = modules_prior.Where(a => !modules_post.Select(b => b.name).Contains(a.name)).ToList(); // Check for updated modules. // TODO: There is most likely a better way of doing this in a single statement using LINQ. List<CkanModule> updated = new List<CkanModule>(); // First, get the identifiers and version of all the mods. Dictionary<string, Version> identifiers_prior = (from a in modules_prior select new {a.identifier, a.version}).ToDictionary(x => x.identifier, x => x.version); Dictionary<string, Version> identifiers_post = (from b in modules_post select new {b.identifier, b.version}).ToDictionary(x => x.identifier, x => x.version); // Compare the two lists. foreach (var a in identifiers_prior) { // Check that the mod is still there after the update. if (identifiers_post.ContainsKey(a.Key)) { // Check that the version has increased. if (identifiers_post[a.Key].IsGreaterThan(a.Value)) { // Extract the mod information from the updated modules list. updated.Add(modules_post.Where(b => b.identifier == a.Key).First()); } } } // Print the changes. user.RaiseMessage("Found {0} new modules, {1} removed modules and {2} updated modules.", added.Count, removed.Count, updated.Count); if (added.Count > 0) { PrintModules("New modules [Name (CKAN identifier)]:", added); } if (removed.Count > 0) { PrintModules("Removed modules [Name (CKAN identifier)]:", removed); } if (updated.Count > 0) { PrintModules("Updated modules [Name (CKAN identifier)]:", updated); } }
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"); AutoUpdate.Instance.FetchLatestReleaseInfo(); var latestVersion = AutoUpdate.Instance.LatestVersion; var currentVersion = new Version(Meta.GetVersion(VersionFormat.Short)); if (latestVersion.IsGreaterThan(currentVersion)) { User.RaiseMessage("New CKAN version available - " + latestVersion); var releaseNotes = AutoUpdate.Instance.ReleaseNotes; User.RaiseMessage(releaseNotes); User.RaiseMessage("\r\n"); if (User.RaiseYesNoDialog("Proceed with install?")) { User.RaiseMessage("Upgrading CKAN, please wait.."); AutoUpdate.Instance.StartUpdateProcess(false); } } else { User.RaiseMessage("You already have the latest version."); } return Exit.OK; } User.RaiseMessage("\r\nUpgrading modules...\r\n"); try { if (options.upgrade_all) { var registry = RegistryManager.Instance(ksp).registry; var installed = new Dictionary<string, Version>(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 var latest = registry.LatestAvailable(mod.Key, ksp.VersionCriteria()); // This may be an unindexed mod. If so, // skip rather than crash. See KSP-CKAN/CKAN#841. if (latest == null) { continue; } if (latest.version.IsGreaterThan(mod.Value)) { // Upgradable log.InfoFormat("New version {0} found for {1}", latest.version, latest.identifier); to_upgrade.Add(latest); } } catch (ModuleNotFoundKraken) { log.InfoFormat("{0} is installed, but no longer in the registry", mod.Key); } } } ModuleInstaller.GetInstance(ksp, User).Upgrade(to_upgrade, new NetAsyncModulesDownloader(User)); } else { // TODO: These instances all need to go. ModuleInstaller.GetInstance(ksp, User).Upgrade(options.modules, new NetAsyncModulesDownloader(User)); } } catch (ModuleNotFoundKraken kraken) { User.RaiseMessage("Module {0} not found", kraken.module); return Exit.ERROR; } User.RaiseMessage("\r\nDone!\r\n"); return Exit.OK; }
/// <summary> /// Prints a message and a list of modules. Ends with a blank line. /// </summary> /// <param name="message">The message to print.</param> /// <param name="modules">The modules to list.</param> private void PrintModules(string message, List<CkanModule> modules) { // Check input. if (message == null) { throw new BadCommandKraken("Message cannot be null."); } if (modules == null) { throw new BadCommandKraken("List of modules cannot be null."); } user.RaiseMessage(message); foreach(CkanModule module in modules) { user.RaiseMessage("{0} ({1})", module.name, module.identifier); } user.RaiseMessage(""); }