/// <summary> /// detects issues and prints them to the log. use filterPackages if its wanted to filter the issues based on newly installed packages. /// </summary> private static Issue CheckPackages(IEnumerable <PackageDef> packages, IEnumerable <PackageDef> newPackages, LogEventType severity) { var tree = DependencyAnalyzer.BuildAnalyzerContext(packages.ToList()); if (newPackages != null) { tree = tree.FilterRelated(newPackages.ToList()); } if (tree.BrokenPackages.Count == 0) { return(Issue.None); } foreach (var pkg in tree.BrokenPackages) { foreach (var issue in tree.GetIssues(pkg)) { switch (issue.IssueType) { case DependencyIssueType.Missing: log.TraceEvent(severity, 0, $"Package '{pkg.Name}' depends on '{issue.PackageName}' which will not be installed."); break; case DependencyIssueType.DependencyMissing: log.TraceEvent(severity, 0, $"Package '{pkg.Name}' depends on '{issue.PackageName} which itself will be broken (See message related to other plugin)."); break; case DependencyIssueType.IncompatibleVersion: log.TraceEvent(severity, 0, $"Package '{pkg.Name}' depends on '{issue.PackageName}' version '{issue.ExpectedVersion}', but '{issue.LoadedVersion}' will be installed."); break; } } } return(Issue.BrokenPackages); }
/// <summary> /// detects issues and prints them to the log. use filterPackages if its wanted to filter the issues based on newly installed packages. /// </summary> public static Issue CheckInstalledPackages(string installDir) { var packages = new Installation(installDir).GetPackages(); var tree = DependencyAnalyzer.BuildAnalyzerContext(packages.ToList()); if (tree.BrokenPackages.Count == 0) { return(Issue.None); } log.Error("Package Dependency Warning"); foreach (var pkg in tree.BrokenPackages) { log.Warning("The Package '{0}' has the following dependency issues:", pkg.Name); foreach (var issue in tree.GetIssues(pkg)) { switch (issue.IssueType) { case DependencyIssueType.Missing: log.Info(" * The package depends on '{0}' (v{1}) which is not installed.", issue.PackageName, issue.ExpectedVersion); break; case DependencyIssueType.DependencyMissing: log.Info(" * The package depends on '{0} which has issues.", issue.PackageName); log.Info(" See message related to other packages."); break; case DependencyIssueType.IncompatibleVersion: log.Info(" * The package depends on '{0}' version '{1}', but '{2}' was installed.", issue.PackageName, issue.ExpectedVersion, issue.LoadedVersion); break; } } } return(Issue.BrokenPackages); }
private bool CheckPackageAndDependencies(List <PackageDef> installed, List <string> packagePaths) { var packages = packagePaths.Select(PackageDef.FromXml).ToList(); installed.RemoveIf(i => packages.Any(u => u.Name == i.Name && u.Version == i.Version)); var analyzer = DependencyAnalyzer.BuildAnalyzerContext(installed); var packagesWithIssues = new List <PackageDef>(); foreach (var inst in installed) { if (analyzer.GetIssues(inst).Any(i => packages.Any(p => p.Name == i.PackageName))) { packagesWithIssues.Add(inst); } } if (packages.Any(p => p.Files.Any(f => f.FileName.ToLower().EndsWith("OpenTap.dll")))) { log.Error("OpenTAP cannot be uninstalled."); return(false); } if (packagesWithIssues.Any()) { log.Warning("Plugin Dependecy Conflict."); var question = string.Format("One or more installed packages depend on {0}. Uninstalling might cause these packages to break:\n{1}", string.Join(" and ", packages.Select(p => p.Name)), string.Join("\n", packagesWithIssues.Select(p => p.Name + " " + p.Version))); var req = new ContinueRequest { message = question, Response = ContinueResponse.Continue }; UserInput.Request(req, true); return(req.Response == ContinueResponse.Continue); } else { foreach (var bundle in packages.Where(p => p.IsBundle()).ToList()) { log.Warning("Package '{0}' is a bundle and has installed:\n{1}\n\nThese packages must be uninstalled separately.\n", bundle.Name, string.Join("\n", bundle.Dependencies.Select(d => d.Name))); } return(true); } }
private void GetPackageInfo(PackageDef package, List <PackageVersion> packageVersions, Installation installation) { var allPackages = installation.GetPackages(); var latestVersion = packageVersions?.Max(p => p.Version); var packageInstalled = allPackages.Contains(package); if (!packageInstalled) { allPackages.Add(package); } var tree = DependencyAnalyzer.BuildAnalyzerContext(allPackages); var issues = tree.GetIssues(package); ParseDescription(package.Description); // Get similar releases to get available platforms and architectures var similarReleases = packageVersions.Where(x => x.Version.Major == package.Version.Major && x.Version.Minor == package.Version.Minor).ToList(); AddWritePair("Package Name", package.Name); AddWritePair("Group", package.Group); var installedVersion = installation.GetPackages().Where(x => x.Name == package.Name)?.FirstOrDefault()?.Version; var installedString = installedVersion == null ? "(not installed)" : $"({installedVersion} installed)"; AddWritePair("Version", $"{package.Version} {installedString}"); if (latestVersion != null && installedVersion != null && latestVersion != installedVersion) { AddWritePair("Newest Version in Repository", $"{latestVersion}"); } AddWritePair("Compatible Architectures", string.Join(Environment.NewLine, similarReleases.Select(x => x.Architecture).Distinct())); AddWritePair("Compatible Platforms", string.Join(Environment.NewLine, similarReleases.Select(x => x.OS).Distinct())); if (packageInstalled == false) { AddWritePair("Compatibility Issues", issues.Any() ? $"{(string.Join(Environment.NewLine, issues.Select(x => $"{x.PackageName} - {x.IssueType.ToString()}")))}" : "none"); } AddWritePair("Owner", package.Owner); var licenseString = (package.LicenseRequired ?? "").Replace("&", " and ").Replace("|", " or "); AddWritePair("License Required", licenseString); AddWritePair("SourceUrl", package.SourceUrl); if (package.PackageSource is IRepositoryPackageDefSource repoPkg) { AddWritePair("Repository", repoPkg.RepositoryUrl); } AddWritePair("Package Type", package.FileType); AddWritePair("Package Class", package.Class); var tags = package.Tags?.Split(new string[] { " ", "," }, StringSplitOptions.RemoveEmptyEntries); if (tags?.Length > 0) { AddWritePair("Package Tags", string.Join(" ", tags)); } if (package.Dependencies.Count > 0) { AddWritePair("Dependencies", string.Join(Environment.NewLine, package.Dependencies.Select(x => x.Name))); } foreach (var(key, value) in SubTags) { AddWritePair(key, value); } AddWritePair("Description", Description); if (IncludeFiles) { if (package.Files.Count > 0) { AddWritePair("Files", string.Join(Environment.NewLine, package.Files.Select(x => x.RelativeDestinationPath.Replace("\\", "/")))); } } if (IncludePlugins) { var plugins = package.Files.Select(x => x.Plugins); var sb = new StringBuilder(); foreach (var plugin in plugins) { foreach (var p in plugin) { var name = p.Name; var desc = p.Description; sb.Append(!string.IsNullOrWhiteSpace(desc) ? $"{name} ({desc}){Environment.NewLine}" : $"{name}{Environment.NewLine}"); } } AddWritePair("Plugins", sb.ToString()); } WritePairs(); }