/// <summary> /// Determines compatibility between the current package installs and the specified target package. /// Works for both updates and new installs. /// </summary> /// <param name="target"></param> /// <returns></returns> public PackageCompatibility GetCompatibilityLevel(PackageInfo target) { // If the target package is already installed in the matching version, assume compatibility if (this.localPackages.Any(local => local.Id == target.Id && local.Version == target.Version)) { return(PackageCompatibility.Definite); } // Determine all packages that might be updated or installed PackageInfo[] touchedPackages = this.GetDeepDependencies(new[] { target }).ToArray(); // Generate a mapping to already installed packages Dictionary <PackageInfo, LocalPackage> localMap = new Dictionary <PackageInfo, LocalPackage>(); foreach (PackageInfo package in touchedPackages) { LocalPackage local = this.localPackages.FirstOrDefault(p => p.Id == package.Id); if (local == null) { continue; } localMap.Add(package, local); } // Determine the maximum version difference between target and installed PackageCompatibility compatibility = PackageCompatibility.Definite; foreach (var pair in localMap) { Version targetVersion = pair.Key.Version; Version localVersion = pair.Value.Version; if (localVersion.Major != targetVersion.Major) { compatibility = compatibility.Combine(PackageCompatibility.Unlikely); } else if (localVersion.Minor != targetVersion.Minor) { compatibility = compatibility.Combine(PackageCompatibility.Likely); } } return(compatibility); }
private bool ConfirmCompatibility(IEnumerable <PackageInfo> packages) { PackageCompatibility compatibility = PackageCompatibility.Definite; foreach (PackageInfo package in packages) { PackageCompatibility otherCompat = this.packageManager.GetCompatibilityLevel(package); compatibility = compatibility.Combine(otherCompat); } return(this.ConfirmCompatibility(compatibility)); }
/// <summary> /// Determines compatibility between the current package installs and the specified target package. /// Works for both updates and new installs. /// </summary> /// <param name="target"></param> /// <returns></returns> public PackageCompatibility GetCompatibilityLevel(PackageInfo target) { // If the target package is already installed in the matching version, assume compatibility if (this.setup.GetPackage(target.Id, target.Version) != null) { return(PackageCompatibility.Definite); } // Determine all packages that might be updated or installed this.dependencyWalker.Clear(); this.dependencyWalker.WalkGraph(target); List <PackageInfo> touchedPackages = this.dependencyWalker.VisitedPackages.ToList(); // Verify properly specified dependencies for Duality packages if (target.IsDualityPackage) { // If none of the targets deep dependencies is anyhow related to Duality, assume they're incomplete and potentially incompatible bool anyDualityDependency = false; foreach (PackageInfo package in touchedPackages) { if (DualityPackageNames.Any(name => string.Equals(name, package.Id))) { anyDualityDependency = true; break; } } if (!anyDualityDependency) { return(PackageCompatibility.None); } } // Generate a mapping to already installed packages Dictionary <PackageInfo, LocalPackage> localMap = new Dictionary <PackageInfo, LocalPackage>(); foreach (PackageInfo package in touchedPackages) { LocalPackage local = this.setup.GetPackage(package.Id); if (local == null) { continue; } localMap.Add(package, local); } // Determine the maximum version difference between target and installed PackageCompatibility compatibility = PackageCompatibility.Definite; foreach (var pair in localMap) { Version targetVersion = pair.Key.Version; Version localVersion = pair.Value.Version; if (localVersion.Major != targetVersion.Major) { compatibility = compatibility.Combine(PackageCompatibility.Unlikely); } else if (localVersion.Minor != targetVersion.Minor) { compatibility = compatibility.Combine(PackageCompatibility.Likely); } } return(compatibility); }