public async Task<IEnumerable<PackageAction>> ResolveActionsAsync( PackageIdentity packageIdentity, PackageActionType operation, InstallationTarget target) { // Construct the Action Resolver var oldResolver = new OldResolver(); if (Logger != null) { oldResolver.Logger = new ShimLogger(Logger); } // Apply context settings ApplyContext(oldResolver); var packageManager = target.GetRequiredFeature<IPackageManager>(); var nullProjectManager = new NullProjectManager( new CoreInteropPackageManager( packageManager.LocalRepository, _dependencyResolver, new CoreInteropSourceRepository(_source))); oldResolver.AddOperation( MapNewToOldActionType(operation), await CreateVirtualPackage(packageIdentity.Id, packageIdentity.Version), nullProjectManager); // Resolve actions! var actions = await Task.Factory.StartNew(() => oldResolver.ResolveActions()); // Convert the actions var converted = from action in actions select new PackageAction( MapOldToNewActionType(action.ActionType), new PackageIdentity( action.Package.Id, new NuGetVersion( action.Package.Version.Version, action.Package.Version.SpecialVersion)), UnwrapPackage(action.Package), target, _source, packageIdentity); // Identify update operations so we can mark them as such. foreach (var group in converted.GroupBy(c => c.PackageIdentity.Id)) { var installs = group.Where(p => p.ActionType == PackageActionType.Install).ToList(); var uninstalls = group.Where(p => p.ActionType == PackageActionType.Uninstall).ToList(); if (installs.Count > 0 && uninstalls.Count > 0) { var maxInstall = installs.OrderByDescending(a => a.PackageIdentity.Version).First(); maxInstall.IsUpdate = true; } } return converted; }
/// <summary> /// Returns true if package install is needed. /// Package install is not needed if /// - AllowMultipleVersions is false; /// - there is an existing package, and its version is newer than or equal to the /// package to be installed. /// </summary> /// <param name="packageManager">The pacakge manager.</param> /// <param name="packageId">The id of the package to install.</param> /// <param name="version">The version of the package to install.</param> /// <returns>True if package install is neede; otherwise, false.</returns> private bool PackageInstallNeeded( IPackageManager packageManager, string packageId, SemanticVersion version) { if (AllowMultipleVersions) { return true; } var installedPackage = packageManager.LocalRepository.FindPackage(packageId); if (installedPackage == null) { return true; } if (version == null) { // need to query the source repository to get the version to be installed. IPackage package = packageManager.SourceRepository.FindPackage( packageId, version, NullConstraintProvider.Instance, allowPrereleaseVersions: Prerelease, allowUnlisted: false); if (package == null) { return false; } version = package.Version; } if (installedPackage.Version >= version) { // If the installed pacakge has newer version, no install is needed. return false; } // install is needed. In this case, uninstall the existing pacakge. var resolver = new ActionResolver() { Logger = packageManager.Logger, RemoveDependencies = true, ForceRemove = false }; var projectManager = new NullProjectManager(packageManager); foreach (var package in packageManager.LocalRepository.GetPackages()) { projectManager.LocalRepository.AddPackage(package); } resolver.AddOperation( PackageAction.Uninstall, installedPackage, projectManager); var projectActions = resolver.ResolveActions(); // because the projectManager's LocalRepository is not a PackageReferenceRepository, // the packages in the packages folder are not referenced. Thus, the resolved actions // are all PackageProjectActions. We need to create packages folder actions // from those PackageProjectActions. var solutionActions = new List<Resolver.PackageSolutionAction>(); foreach (var action in projectActions) { var projectAction = action as PackageProjectAction; if (projectAction == null) { continue; } var solutioAction = projectAction.ActionType == PackageActionType.Install ? PackageActionType.AddToPackagesFolder : PackageActionType.DeleteFromPackagesFolder; solutionActions.Add(new PackageSolutionAction( solutioAction, projectAction.Package, packageManager)); } var userOperationExecutor = new ActionExecutor() { Logger = packageManager.Logger }; userOperationExecutor.Execute(solutionActions); return true; }