public async Task EnsurePackageCompatibility_WithInvalidProjectActions_Fails() { // Arrange using (var userPackageFolder = TestDirectory.Create()) { var tc = new TestContext(userPackageFolder); await SimpleTestPackageUtility.CreateFolderFeedV3Async( userPackageFolder, PackageSaveMode.Defaultv3, new[] { new SimpleTestPackageContext(tc.PackageIdentityA) { PackageTypes = { tc.InvalidPackageType } } }); // Act & Assert var ex = Assert.Throws <PackagingException>(() => tc.Target.EnsurePackageCompatibility( tc.ProjectKProject, tc.NuGetPathContext.Object, new NuGetProjectAction[] { NuGetProjectAction.CreateInstallProjectAction(tc.PackageIdentityA, tc.SourceRepository, tc.ProjectKProject) }, tc.GetRestoreResult(new[] { tc.PackageIdentityA }))); Assert.Equal( "Package 'PackageA 1.0.0' has a package type 'Invalid 1.2' that is not supported by project 'TestProjectKNuGetProject'.", ex.Message); } }
public void ProjectActionsExecuted_WhenSolutionManagerActionsExecutedEventRaised_IsRaised() { NuGetUIContext context = CreateNuGetUIContext(); var project = new TestNuGetProject(); var projectAction = NuGetProjectAction.CreateInstallProjectAction( PackageIdentity, sourceRepository: null, project); var resolvedActions = new ResolvedAction[] { new ResolvedAction(project, projectAction) }; var wasEventRaised = false; string[] expectedProjectIds = resolvedActions .Select(resolvedAction => resolvedAction.Project.GetMetadata <string>(NuGetProjectMetadataKeys.ProjectId)) .ToArray(); context.ProjectActionsExecuted += (object sender, IReadOnlyCollection <string> actualProjectIds) => { wasEventRaised = true; Assert.Equal(expectedProjectIds, actualProjectIds); }; _solutionManager.Raise(s => s.ActionsExecuted += null, new ActionsExecutedEventArgs(resolvedActions)); Assert.True(wasEventRaised); }
/// <summary> /// Install package by Identity /// </summary> /// <param name="project"></param> /// <param name="identity"></param> /// <param name="resolutionContext"></param> /// <param name="projectContext"></param> /// <param name="isPreview"></param> /// <param name="isForce"></param> /// <param name="uninstallContext"></param> /// <returns></returns> protected async Task InstallPackageByIdentityAsync(NuGetProject project, PackageIdentity identity, ResolutionContext resolutionContext, INuGetProjectContext projectContext, bool isPreview, bool isForce = false, UninstallationContext uninstallContext = null) { List <NuGetProjectAction> actions = new List <NuGetProjectAction>(); // For Install-Package -Force if (isForce) { PackageReference installedReference = project.GetInstalledPackagesAsync(CancellationToken.None).Result.Where(p => StringComparer.OrdinalIgnoreCase.Equals(identity.Id, p.PackageIdentity.Id)).FirstOrDefault(); if (installedReference != null) { actions.AddRange(await PackageManager.PreviewUninstallPackageAsync(project, installedReference.PackageIdentity, uninstallContext, projectContext, CancellationToken.None)); } NuGetProjectAction installAction = NuGetProjectAction.CreateInstallProjectAction(identity, ActiveSourceRepository); actions.Add(installAction); } else { actions.AddRange(await PackageManager.PreviewInstallPackageAsync(project, identity, resolutionContext, projectContext, ActiveSourceRepository, null, CancellationToken.None)); } if (isPreview) { PreviewNuGetPackageActions(actions); } else { await PackageManager.ExecuteNuGetProjectActionsAsync(project, actions, this, CancellationToken.None); } }
/// <summary> /// Install package by Id /// </summary> /// <param name="project"></param> /// <param name="packageId"></param> /// <param name="resolutionContext"></param> /// <param name="projectContext"></param> /// <param name="isPreview"></param> /// <param name="isForce"></param> /// <param name="uninstallContext"></param> /// <returns></returns> protected async Task InstallPackageByIdAsync(NuGetProject project, string packageId, ResolutionContext resolutionContext, INuGetProjectContext projectContext, bool isPreview, bool isForce = false, UninstallationContext uninstallContext = null) { List <NuGetProjectAction> actions = new List <NuGetProjectAction>(); // For Install-Package -Force if (isForce) { PackageReference installedReference = project.GetInstalledPackagesAsync(CancellationToken.None).Result.Where(p => StringComparer.OrdinalIgnoreCase.Equals(packageId, p.PackageIdentity.Id)).FirstOrDefault(); if (installedReference != null) { actions.AddRange(await PackageManager.PreviewUninstallPackageAsync(project, packageId, uninstallContext, projectContext, CancellationToken.None)); } NuGetVersion nVersion = PowerShellCmdletsUtility.GetLastestVersionForPackageId(ActiveSourceRepository, packageId, project, resolutionContext.IncludePrerelease); if (nVersion != null) { PackageIdentity identityToInstall = new PackageIdentity(packageId, nVersion); NuGetProjectAction installAction = NuGetProjectAction.CreateInstallProjectAction(identityToInstall, ActiveSourceRepository); actions.Add(installAction); } } else { actions.AddRange(await PackageManager.PreviewInstallPackageAsync(project, packageId, resolutionContext, projectContext, ActiveSourceRepository, null, CancellationToken.None)); } if (isPreview) { PreviewNuGetPackageActions(actions); } else { await PackageManager.ExecuteNuGetProjectActionsAsync(project, actions, this, CancellationToken.None); } }
public void ApplyChanges_AddInstalledPackage() { // Arrange var lockFile = new PackagesLockFile { Targets = new List <PackagesLockFileTarget> { new PackagesLockFileTarget() } }; var actionList = new List <NuGetProjectAction> { NuGetProjectAction.CreateInstallProjectAction(new PackageIdentity("packageA", NuGetVersion.Parse("1.0.0")), null, null) }; var contentHashUtility = new Mock <IPackagesConfigContentHashProvider>(); // Act PackagesConfigLockFileUtility.ApplyChanges(lockFile, actionList, contentHashUtility.Object, CancellationToken.None); // Assert Assert.Equal(1, lockFile.Targets[0].Dependencies.Count); Assert.Equal(actionList[0].PackageIdentity.Id, lockFile.Targets[0].Dependencies[0].Id); Assert.Equal(actionList[0].PackageIdentity.Version, lockFile.Targets[0].Dependencies[0].ResolvedVersion); }
public async Task PackagePreFetcher_PackageDoesNotExistAnywhere() { using (var sourceDir = TestDirectory.Create()) using (var packagesFolderDir = TestDirectory.Create()) using (var globalPackagesFolder = TestDirectory.Create()) { // Arrange var actions = new List <NuGetProjectAction>(); var packagesFolder = new FolderNuGetProject(packagesFolderDir); var testSettings = NullSettings.Instance; var logger = new TestLogger(); var target = new PackageIdentity("packageA", NuGetVersion.Parse("1.0.0")); var source = Repository.Factory.GetVisualStudio(new Configuration.PackageSource(sourceDir.Path)); actions.Add(NuGetProjectAction.CreateInstallProjectAction(target, source, packagesFolder)); // Act using (var cacheContext = new SourceCacheContext()) { var result = await PackagePreFetcher.GetPackagesAsync( actions, packagesFolder, new PackageDownloadContext(cacheContext), globalPackagesFolder, logger, CancellationToken.None); Exception exception = null; try { using (await result[target].GetResultAsync()) { } Assert.True(false); } catch (Exception ex) { exception = ex; } // Assert Assert.StartsWith("Package 'packageA.1.0.0' is not found on source", exception.Message); } } }
public async Task PackagePreFetcher_PackageAlreadyExistsReinstall() { using (var sourceDir = TestDirectory.Create()) using (var packagesFolderDir = TestDirectory.Create()) using (var globalPackagesFolder = TestDirectory.Create()) { // Arrange var actions = new List <NuGetProjectAction>(); var packagesFolder = new FolderNuGetProject(packagesFolderDir); var testSettings = NullSettings.Instance; var logger = new TestLogger(); var target = new PackageIdentity("packageA", NuGetVersion.Parse("1.0.0")); var source = Repository.Factory.GetVisualStudio(new Configuration.PackageSource(sourceDir.Path)); // Add package AddToPackagesFolder(target, packagesFolderDir); actions.Add(NuGetProjectAction.CreateUninstallProjectAction(target, packagesFolder)); actions.Add(NuGetProjectAction.CreateInstallProjectAction(target, source, packagesFolder)); AddToSource(target, sourceDir); // Act using (var cacheContext = new SourceCacheContext()) { var result = await PackagePreFetcher.GetPackagesAsync( actions, packagesFolder, new PackageDownloadContext(cacheContext), globalPackagesFolder, logger, CancellationToken.None); using (var downloadResult = await result[target].GetResultAsync()) { // Assert Assert.Equal(1, result.Count); Assert.False(result[target].InPackagesFolder); Assert.Equal(source.PackageSource, result[target].Source); Assert.Equal(target, result[target].Package); Assert.True(result[target].IsComplete); Assert.Equal(target, downloadResult.PackageReader.GetIdentity()); Assert.NotNull(downloadResult.PackageStream); Assert.Equal(DownloadResourceResultStatus.Available, downloadResult.Status); } } } }
public async Task EnsurePackageCompatibility_WithValidProjectActions_Succeeds() { // Arrange using (var userPackageFolder = TestDirectory.Create()) { var tc = new TestContext(userPackageFolder); await SimpleTestPackageUtility.CreateFolderFeedV3Async( userPackageFolder, PackageSaveMode.Defaultv3, new[] { new SimpleTestPackageContext(tc.PackageIdentityA) { PackageTypes = { PackageType.DotnetCliTool } }, new SimpleTestPackageContext(tc.PackageIdentityB) // Not inspected, because this package is // being uninstalled, not installed. { PackageTypes = { tc.InvalidPackageType } }, new SimpleTestPackageContext(tc.PackageIdentityC) { PackageTypes = { PackageType.Dependency } }, }); // Act & Assert tc.Target.EnsurePackageCompatibility( tc.ProjectKProject, tc.NuGetPathContext.Object, new NuGetProjectAction[] { NuGetProjectAction.CreateInstallProjectAction(tc.PackageIdentityA, tc.SourceRepository, tc.ProjectKProject), NuGetProjectAction.CreateUninstallProjectAction(tc.PackageIdentityB, tc.ProjectKProject), NuGetProjectAction.CreateInstallProjectAction(tc.PackageIdentityC, tc.SourceRepository, tc.ProjectKProject) }, tc.GetRestoreResult(new[] { tc.PackageIdentityA, tc.PackageIdentityB, tc.PackageIdentityC })); } }
public void ApplyChanges_SortPackages_LastPackage() { // Arrange var lockFile = new PackagesLockFile { Targets = new List <PackagesLockFileTarget> { new PackagesLockFileTarget { Dependencies = new List <LockFileDependency> { new LockFileDependency { Id = "packageB", ResolvedVersion = NuGetVersion.Parse("1.0.0") }, new LockFileDependency { Id = "packageD", ResolvedVersion = NuGetVersion.Parse("1.0.0") } } } } }; var actionList = new List <NuGetProjectAction> { NuGetProjectAction.CreateInstallProjectAction(new PackageIdentity("packageE", NuGetVersion.Parse("1.0.0")), null, null) }; var contentHashUtility = new Mock <IPackagesConfigContentHashProvider>(); // Act PackagesConfigLockFileUtility.ApplyChanges(lockFile, actionList, contentHashUtility.Object, CancellationToken.None); // Assert Assert.Equal(3, lockFile.Targets[0].Dependencies.Count); Assert.Equal("packageB", lockFile.Targets[0].Dependencies[0].Id); Assert.Equal("packageD", lockFile.Targets[0].Dependencies[1].Id); Assert.Equal("packageE", lockFile.Targets[0].Dependencies[2].Id); }
public void OnAfterExecuteActions_PackageInstallAction_PackageInstalledEventFired() { CreateNuGetProject(); var packageIdentity = new PackageIdentity("Test", NuGetVersion.Parse("1.2")); var actions = new List <NuGetProjectAction> (); var action = NuGetProjectAction.CreateInstallProjectAction(packageIdentity, null, project); actions.Add(action); PackageManagementEventArgs eventArgs = null; project.PackageManagementEvents.PackageInstalled += (sender, e) => { eventArgs = e; }; project.OnAfterExecuteActions(actions); Assert.AreEqual("Test", eventArgs.Id); Assert.AreEqual("1.2", eventArgs.Version.ToString()); Assert.AreEqual(packageIdentity, eventArgs.Package); }
public async Task PackagePreFetcher_PackageAlreadyExists_NonNormalizedVersionInput() { using (var sourceDir = TestFileSystemUtility.CreateRandomTestFolder()) using (var packagesFolderDir = TestFileSystemUtility.CreateRandomTestFolder()) { // Arrange var actions = new List <NuGetProjectAction>(); var packagesFolder = new FolderNuGetProject(packagesFolderDir); var testSettings = new Configuration.NullSettings(); var logger = new TestLogger(); var target = new PackageIdentity("packageA", NuGetVersion.Parse("1.0.0")); var targetNonNormalized = new PackageIdentity("packageA", NuGetVersion.Parse("1.0")); var source = Repository.Factory.GetVisualStudio(new Configuration.PackageSource(sourceDir.Path)); // Add package AddToPackagesFolder(target, packagesFolderDir); actions.Add(NuGetProjectAction.CreateInstallProjectAction(targetNonNormalized, source)); AddToSource(target, sourceDir); // Act var result = await PackagePreFetcher.GetPackagesAsync( actions, packagesFolder, testSettings, logger, CancellationToken.None); var downloadResult = await result[target].GetResultAsync(); // Assert Assert.Equal(1, result.Count); Assert.True(result[target].InPackagesFolder); Assert.Null(result[target].Source); Assert.Equal(target, result[target].Package); Assert.True(result[target].IsComplete); Assert.NotNull(downloadResult.PackageStream); Assert.Equal(DownloadResourceResultStatus.Available, downloadResult.Status); } }
private static IEnumerable <NuGetProjectAction> GetProjectActions( PackageIdentity packageIdentity, IReadOnlyCollection <PackageIdentity> packagesToInstall, IReadOnlyCollection <SourcePackageDependencyInfo> availablePackageDependencies, NugetFolderProject nuGetProject) { var nuGetProjectActions = new List <NuGetProjectAction>(); foreach (var packageToInstall in packagesToInstall) { // Find the package match based on identity var sourceDepInfo = availablePackageDependencies.SingleOrDefault(p => PackageIdentity.Comparer.Equals(p, packageToInstall)); if (sourceDepInfo == null) { // This really should never happen since dependencies have been resolved. throw new InvalidOperationException($"Package '{packageIdentity}' is not found"); } nuGetProjectActions.Add(NuGetProjectAction.CreateInstallProjectAction(sourceDepInfo, sourceDepInfo.Source, nuGetProject)); } return(nuGetProjectActions); }
public async ValueTask InstallPackagesAsync( string projectId, IReadOnlyList <PackageIdentity> packageIdentities, CancellationToken cancellationToken) { Assumes.NotNullOrEmpty(projectId); Assumes.NotNullOrEmpty(packageIdentities); cancellationToken.ThrowIfCancellationRequested(); NuGetProject?project = await SolutionUtility.GetNuGetProjectAsync( _state.SolutionManager, projectId, cancellationToken); Assumes.NotNull(project); SourceRepository?sourceRepository = await GetSourceRepositoryAsync(cancellationToken); IEnumerable <NuGetProjectAction>?actions = packageIdentities .Select(packageIdentity => NuGetProjectAction.CreateInstallProjectAction(packageIdentity, sourceRepository, project)); NuGetPackageManager packageManager = await _state.GetPackageManagerAsync(cancellationToken); Assumes.NotNull(packageManager); INuGetProjectContext projectContext = await ServiceLocator.GetComponentModelServiceAsync <INuGetProjectContext>(); Assumes.NotNull(projectContext); await packageManager.ExecuteBuildIntegratedProjectActionsAsync( project as BuildIntegratedNuGetProject, actions, projectContext, cancellationToken); }
public static async Task <IEnumerable <NuGetProjectAction> > GetInstallProjectActionsAsync( this NuGetPackageManager packageManager, NugetFolderProject nuGetProject, PackageIdentity packageIdentity, ResolutionContext resolutionContext, INuGetProjectContext nuGetProjectContext, IEnumerable <SourceRepository> primarySourceRepositories, IEnumerable <SourceRepository> secondarySourceRepositories, CancellationToken token) { if (nuGetProject == null) { throw new ArgumentNullException(nameof(nuGetProject)); } if (packageIdentity == null) { throw new ArgumentNullException(nameof(packageIdentity)); } if (resolutionContext == null) { throw new ArgumentNullException(nameof(resolutionContext)); } if (nuGetProjectContext == null) { throw new ArgumentNullException(nameof(nuGetProjectContext)); } if (primarySourceRepositories == null) { throw new ArgumentNullException(nameof(primarySourceRepositories)); } if (!primarySourceRepositories.Any()) { throw new ArgumentException(nameof(primarySourceRepositories)); } if (secondarySourceRepositories == null) { throw new ArgumentNullException(nameof(secondarySourceRepositories)); } if (packageIdentity.Version == null) { throw new ArgumentNullException(nameof(packageIdentity)); } var localSources = new HashSet <SourceRepository>(new SourceRepositoryComparer()); localSources.Add(packageManager.PackagesFolderSourceRepository); localSources.AddRange(packageManager.GlobalPackageFolderRepositories); if (resolutionContext.DependencyBehavior == DependencyBehavior.Ignore) { var logger = new ProjectContextLogger(nuGetProjectContext); // First, check only local sources. var sourceRepository = await GetSourceRepositoryAsync(packageIdentity, localSources, resolutionContext.SourceCacheContext, logger, token); if (sourceRepository == null) { // Else, check provided sources. We use only primary sources when we don't care about dependencies. sourceRepository = await GetSourceRepositoryAsync(packageIdentity, primarySourceRepositories, resolutionContext.SourceCacheContext, logger, token); } // If still not found, we just throw an exception. if (sourceRepository == null) { throw new InvalidOperationException($"Unable to find version '{packageIdentity.Version}' of package '{packageIdentity.Id}'."); } return(new[] { NuGetProjectAction.CreateInstallProjectAction(packageIdentity, sourceRepository, nuGetProject) }); } var primarySources = new HashSet <SourceRepository>(new SourceRepositoryComparer()); primarySources.AddRange(localSources); primarySources.AddRange(primarySourceRepositories); var allSources = new HashSet <SourceRepository>(new SourceRepositoryComparer()); allSources.AddRange(primarySources); allSources.AddRange(secondarySourceRepositories); // Get the available package dependencies. var packageDependencies = await GetAvailablePackageDependencies( packageManager, nuGetProject, packageIdentity, resolutionContext, nuGetProjectContext, primarySources, allSources, token); if (!packageDependencies.Any()) { throw new InvalidOperationException($"Unable to gather dependency information for package '{packageIdentity}'"); } // Prune the results down to only what we would allow to be installed. packageDependencies = PruneAvailablePackageDependencies(packageIdentity, resolutionContext, packageDependencies); // Get the actual packages to install. var packagesToInstall = GetPackagesToInstall( packageIdentity, resolutionContext, nuGetProjectContext, packageDependencies, allSources, token); if (packagesToInstall == null || !packagesToInstall.Any()) { throw new InvalidOperationException($"Unable to resolve dependencies for package '{packageIdentity}' with DependencyBehavior '{resolutionContext.DependencyBehavior}'"); } // Create the install actions. return(GetProjectActions( packageIdentity, packagesToInstall, packageDependencies, nuGetProject)); }
/// <summary> /// Install a NuGet package. Returns all newly installed packages. /// </summary> public async Task <IReadOnlyCollection <InteractivePackage> > InstallPackageAsync( InteractivePackage package, SourceRepository sourceRepository, CancellationToken cancellationToken) { if (package == null) { throw new ArgumentNullException(nameof(package)); } if (!package.Identity.HasVersion) { throw new ArgumentException("PackageIdentity.Version must be set"); } // TODO: File upstream issue about exception if primary source repo is offline. // Shouldn't secondary source repos kick in? Our current work around is to // pass the source repo from search to install, but that's not perfect. sourceRepository = sourceRepository ?? SourceRepositories [0]; project.ResetInstallationContext(); // Just need to apply one fixup here if (PackageIdComparer.Equals(package.Identity.Id, FixedXamarinFormsPackageIdentity.Id) && package.Identity.Version != FixedXamarinFormsPackageIdentity.Version) { Log.Warning( TAG, $"Replacing requested Xamarin.Forms version {package.Identity.Version} with " + $"required version {FixedXamarinFormsPackageIdentity.Version}."); package = package.WithVersion( FixedXamarinFormsPackageIdentity.Version, overwriteRange: true); } if (PackageIdComparer.Equals(package.Identity.Id, IntegrationPackageId)) { Log.Warning(TAG, $"Refusing to add integration NuGet package {IntegrationPackageId}."); return(Array.Empty <InteractivePackage> ()); } var resolutionContext = new ResolutionContext( DependencyBehavior.Lowest, // IDEs only use Highest if upgrading includePrelease: true, includeUnlisted: true, versionConstraints: VersionConstraints.None); // Although there is a single repo associated with the package being installed, // dependency resolution will also look into the secondary sources. In some cases, // this can greatly slow down installation. For the primary case of searching for // packages in nuget.org, prevent the package manager from using secondary sources // for resolution. // // It is important to pass an empty enumerable, because if we pass null, the package // manager will determine secondary sources based on the NuGet configuration. var secondarySources = sourceRepository == SourceRepositories [0] ? Enumerable.Empty <SourceRepository> () : SourceRepositories.Where(r => r != sourceRepository).ToArray(); // There does not appear to be a way to hook into or override functionality of the // NuGetPackageManager or PackageResolver classes. In order to mess with package // resolution, we need to either write a lot of code, proxy the sources, or intercede // via preview installation actions. // // Here we do the latter, though it is not the best general-purpose approach. It works // fine for replacing one single package that we know a LOT about. If that package's // dependencies continually changed, we'd be better off with another approach. var previewInstallActions = await packageManager.PreviewInstallPackageAsync( project, package.Identity, resolutionContext, projectContext, sourceRepository, secondarySources, cancellationToken); var installActions = new List <NuGetProjectAction> (); foreach (var action in previewInstallActions) { // If the installed package has a dependency on Xamarin.Forms, make sure the version // that gets installed is our preferred version. Force it to install from the primary // source repository, because we can't assume that version is available everywhere. // // TODO: Consider adding a search or something to see if we can use the specified source // instead. Could be handy if nuget.org is down or the user is offline and using // a local repo. if (action.PackageIdentity.Id == FixedXamarinFormsPackageIdentity.Id) { installActions.Add(NuGetProjectAction.CreateInstallProjectAction( FixedXamarinFormsPackageIdentity, SourceRepositories [0], action.Project)); } else { installActions.Add(action); } } // We follow the modern behavior of .NET Core and do not actually install packages anywhere. // Instead, we ultimately reference them out of the user's global package cache (by default, // ~/.nuget/packages). Our NuGetProject implementation simply collects package assembly // references (and potentially other necessary files) and populates them back into the // InteractiveInstallationContext. using (var sourceCacheContext = new SourceCacheContext()) await packageManager.ExecuteNuGetProjectActionsAsync( project, installActions, projectContext, sourceCacheContext, cancellationToken); // Identify which packages were not already noted as installed, or have been upgraded now var newlyInstalledPackages = new List <InteractivePackage> (); foreach (var newPackage in project.InstallationContext.InstalledPackages) { InteractivePackage finalNewPackage; var foundInstalledMatch = installedPackages.TryGetValue( newPackage, out finalNewPackage); if (!foundInstalledMatch || newPackage.Identity.Version > finalNewPackage.Identity.Version) { // Make sure we have a reference to a matching explicit InteractivePackage if it // exists, so that we can persist the original SupportedVersionRange if (!foundInstalledMatch) { finalNewPackage = PackageIdComparer.Equals(package, newPackage) ? package : newPackage; } finalNewPackage = newPackage .WithIsExplicit(finalNewPackage.IsExplicit) .WithSupportedVersionRange(finalNewPackage.SupportedVersionRange); newlyInstalledPackages.Add(finalNewPackage); installedPackages = installedPackages .Remove(finalNewPackage) .Add(finalNewPackage); UpdateInstalledPackages(); } } return(newlyInstalledPackages); }
public async Task PackagePreFetcher_UpdateMultiplePackages() { using (var sourceDir = TestFileSystemUtility.CreateRandomTestFolder()) using (var packagesFolderDir = TestFileSystemUtility.CreateRandomTestFolder()) { // Arrange var actions = new List <NuGetProjectAction>(); var packagesFolder = new FolderNuGetProject(packagesFolderDir); var testSettings = new Configuration.NullSettings(); var logger = new TestLogger(); var targetA1 = new PackageIdentity("packageA", NuGetVersion.Parse("1.0.0")); var targetA2 = new PackageIdentity("packageA", NuGetVersion.Parse("2.0.0")); var targetB1 = new PackageIdentity("packageB", NuGetVersion.Parse("1.0.0")); var targetB2 = new PackageIdentity("packageB", NuGetVersion.Parse("2.0.0")); var targetC2 = new PackageIdentity("packageC", NuGetVersion.Parse("2.0.0")); var source = Repository.Factory.GetVisualStudio(new Configuration.PackageSource(sourceDir.Path)); // Add packages AddToPackagesFolder(targetA1, packagesFolderDir); AddToPackagesFolder(targetB1, packagesFolderDir); AddToPackagesFolder(targetA2, packagesFolderDir); // Update A and B, install C, A already exists actions.Add(NuGetProjectAction.CreateUninstallProjectAction(targetA1)); actions.Add(NuGetProjectAction.CreateUninstallProjectAction(targetB1)); actions.Add(NuGetProjectAction.CreateInstallProjectAction(targetC2, source)); actions.Add(NuGetProjectAction.CreateInstallProjectAction(targetB2, source)); actions.Add(NuGetProjectAction.CreateInstallProjectAction(targetA2, source)); AddToSource(targetA2, sourceDir); AddToSource(targetB2, sourceDir); AddToSource(targetC2, sourceDir); // Act var result = await PackagePreFetcher.GetPackagesAsync( actions, packagesFolder, testSettings, logger, CancellationToken.None); var resultA2 = await result[targetA2].GetResultAsync(); var resultB2 = await result[targetB2].GetResultAsync(); var resultC2 = await result[targetC2].GetResultAsync(); // Assert Assert.Equal(3, result.Count); Assert.True(result[targetA2].InPackagesFolder); Assert.Null(result[targetA2].Source); Assert.Equal(targetA2, result[targetA2].Package); Assert.True(result[targetA2].IsComplete); Assert.Equal(targetA2, resultA2.PackageReader.GetIdentity()); Assert.NotNull(resultA2.PackageStream); Assert.Equal(DownloadResourceResultStatus.Available, resultA2.Status); Assert.False(result[targetB2].InPackagesFolder); Assert.Equal(source.PackageSource, result[targetB2].Source); Assert.Equal(targetB2, result[targetB2].Package); Assert.True(result[targetB2].IsComplete); Assert.Equal(targetB2, resultB2.PackageReader.GetIdentity()); Assert.NotNull(resultB2.PackageStream); Assert.Equal(DownloadResourceResultStatus.Available, resultB2.Status); Assert.False(result[targetC2].InPackagesFolder); Assert.Equal(source.PackageSource, result[targetC2].Source); Assert.Equal(targetC2, result[targetC2].Package); Assert.True(result[targetC2].IsComplete); Assert.Equal(targetC2, resultC2.PackageReader.GetIdentity()); Assert.NotNull(resultC2.PackageStream); Assert.Equal(DownloadResourceResultStatus.Available, resultC2.Status); } }
internal static async Task <string> DoUpgradeAsync( INuGetUIContext context, INuGetUI uiService, NuGetProject nuGetProject, IEnumerable <NuGetProjectUpgradeDependencyItem> upgradeDependencyItems, IEnumerable <PackageIdentity> notFoundPackages, IProgress <ProgressDialogData> progress, CancellationToken token) { var startTime = DateTimeOffset.Now; var packagesCount = 0; var status = NuGetOperationStatus.Succeeded; using (var telemetry = new TelemetryActivity(Guid.Empty)) { try { // 0. Fail if any package was not found if (notFoundPackages.Any()) { status = NuGetOperationStatus.Failed; var notFoundPackageIds = string.Join(",", notFoundPackages.Select(t => t.Id)); uiService.ProjectContext.Log(MessageLevel.Error, string.Format(CultureInfo.CurrentCulture, Resources.Migrator_PackageNotFound, notFoundPackageIds)); return(null); } // 1. Backup files (csproj and packages.config) that will change var solutionManager = context.SolutionManager; var msBuildNuGetProject = (MSBuildNuGetProject)nuGetProject; var msBuildNuGetProjectSystem = msBuildNuGetProject.ProjectSystem; var backupPath = string.Empty; try { backupPath = CreateBackup(msBuildNuGetProject, solutionManager.SolutionDirectory); } catch (Exception ex) { status = NuGetOperationStatus.Failed; // log error message uiService.ShowError(ex); uiService.ProjectContext.Log(MessageLevel.Info, string.Format(CultureInfo.CurrentCulture, Resources.Upgrader_BackupFailed)); return(null); } // 2. Uninstall all packages currently in packages.config var progressData = new ProgressDialogData(Resources.NuGetUpgrade_WaitMessage, Resources.NuGetUpgrade_Progress_Uninstalling); progress.Report(progressData); // Don't uninstall packages we couldn't find - that will just fail var actions = upgradeDependencyItems.Select(d => d.Package) .Where(p => !notFoundPackages.Contains(p)) .Select(t => NuGetProjectAction.CreateUninstallProjectAction(t, nuGetProject)); try { await context.PackageManager.ExecuteNuGetProjectActionsAsync(nuGetProject, actions, uiService.ProjectContext, NullSourceCacheContext.Instance, CancellationToken.None); } catch (Exception ex) { status = NuGetOperationStatus.Failed; // log error message uiService.ShowError(ex); uiService.ProjectContext.Log(MessageLevel.Info, string.Format(CultureInfo.CurrentCulture, Resources.Upgrade_UninstallFailed)); return(null); } // Reload the project, and get a reference to the reloaded project var uniqueName = msBuildNuGetProjectSystem.ProjectUniqueName; await msBuildNuGetProject.SaveAsync(token); nuGetProject = await solutionManager.GetNuGetProjectAsync(uniqueName); nuGetProject = await solutionManager.UpgradeProjectToPackageReferenceAsync(nuGetProject); // Ensure we use the updated project for installing, and don't display preview or license acceptance windows. context.Projects = new[] { nuGetProject }; var nuGetUI = (NuGetUI)uiService; nuGetUI.Projects = new[] { nuGetProject }; nuGetUI.DisplayPreviewWindow = false; // 4. Install the requested packages var ideExecutionContext = uiService.ProjectContext.ExecutionContext as IDEExecutionContext; if (ideExecutionContext != null) { await ideExecutionContext.SaveExpandedNodeStates(solutionManager); } progressData = new ProgressDialogData(Resources.NuGetUpgrade_WaitMessage, Resources.NuGetUpgrade_Progress_Installing); progress.Report(progressData); var activeSources = new List <SourceRepository>(); PackageSourceMoniker .PopulateList(context.SourceProvider) .ForEach(s => activeSources.AddRange(s.SourceRepositories)); var packagesToInstall = GetPackagesToInstall(upgradeDependencyItems).ToList(); packagesCount = packagesToInstall.Count; // create low level NuGet actions based on number of packages being installed var lowLevelActions = new List <NuGetProjectAction>(); foreach (var packageIdentity in packagesToInstall) { lowLevelActions.Add(NuGetProjectAction.CreateInstallProjectAction(packageIdentity, activeSources.FirstOrDefault(), nuGetProject)); } try { var buildIntegratedProject = nuGetProject as BuildIntegratedNuGetProject; await context.PackageManager.ExecuteBuildIntegratedProjectActionsAsync( buildIntegratedProject, lowLevelActions, uiService.ProjectContext, token); if (ideExecutionContext != null) { await ideExecutionContext.CollapseAllNodes(solutionManager); } return(backupPath); } catch (Exception ex) { status = NuGetOperationStatus.Failed; uiService.ShowError(ex); uiService.ProjectContext.Log(MessageLevel.Info, string.Format(CultureInfo.CurrentCulture, Resources.Upgrade_InstallFailed, backupPath)); uiService.ProjectContext.Log(MessageLevel.Info, string.Format(CultureInfo.CurrentCulture, Resources.Upgrade_RevertSteps, "https://aka.ms/nugetupgraderevertv1")); return(null); } } catch (Exception ex) { status = NuGetOperationStatus.Failed; uiService.ShowError(ex); return(null); } finally { telemetry.TelemetryEvent = VSTelemetryServiceUtility.GetUpgradeTelemetryEvent( uiService.Projects, status, packagesCount); } } }
public static async Task <IEnumerable <NuGetProjectAction> > GetInstallProjectActionsAsync( this NuGetPackageManager packageManager, NugetFolderProject nuGetProject, PackageIdentity packageIdentity, ResolutionContext resolutionContext, INuGetProjectContext nuGetProjectContext, IEnumerable <SourceRepository> primarySourceRepositories, IEnumerable <SourceRepository> secondarySourceRepositories, CancellationToken token) { if (nuGetProject == null) { throw new ArgumentNullException(nameof(nuGetProject)); } if (packageIdentity == null) { throw new ArgumentNullException(nameof(packageIdentity)); } if (resolutionContext == null) { throw new ArgumentNullException(nameof(resolutionContext)); } if (nuGetProjectContext == null) { throw new ArgumentNullException(nameof(nuGetProjectContext)); } if (primarySourceRepositories == null) { throw new ArgumentNullException(nameof(primarySourceRepositories)); } if (!primarySourceRepositories.Any()) { throw new ArgumentException(nameof(primarySourceRepositories)); } if (secondarySourceRepositories == null) { throw new ArgumentNullException(nameof(secondarySourceRepositories)); } if (packageIdentity.Version == null) { throw new ArgumentNullException(nameof(packageIdentity)); } var localSources = new HashSet <SourceRepository>(new SourceRepositoryComparer()); localSources.Add(packageManager.PackagesFolderSourceRepository); localSources.AddRange(packageManager.GlobalPackageFolderRepositories); if (resolutionContext.DependencyBehavior == DependencyBehavior.Ignore) { var logger = new ProjectContextLogger(nuGetProjectContext); // First, check only local sources. var sourceRepository = await GetSourceRepositoryAsync(packageIdentity, localSources, resolutionContext.SourceCacheContext, logger, token); if (sourceRepository == null) { // Else, check provided sources. We use only primary sources when we don't care about dependencies. sourceRepository = await GetSourceRepositoryAsync(packageIdentity, primarySourceRepositories, resolutionContext.SourceCacheContext, logger, token); } // If still not found, we just throw an exception. if (sourceRepository == null) { throw new InvalidOperationException($"Unable to find version '{packageIdentity.Version}' of package '{packageIdentity.Id}'."); } return(new[] { NuGetProjectAction.CreateInstallProjectAction(packageIdentity, sourceRepository, nuGetProject) }); } var primarySources = new HashSet <SourceRepository>(new SourceRepositoryComparer()); var allSources = new HashSet <SourceRepository>(new SourceRepositoryComparer()); Tuple <IReadOnlyCollection <PackageIdentity>, IReadOnlyCollection <SourcePackageDependencyInfo> > packageAndDependencies = null; var allDependenciesResolved = false; // If target package is already installed, there's a slight chance that all packages are already installed. if (await PackageExistsInSourceRepository( packageIdentity, packageManager.PackagesFolderSourceRepository, resolutionContext.SourceCacheContext, new ProjectContextLogger(nuGetProjectContext), token)) { primarySources.Add(packageManager.PackagesFolderSourceRepository); allSources.Add(packageManager.PackagesFolderSourceRepository); try { // Try get all dependencies from local sources only. packageAndDependencies = await GetPackageAndDependenciesToInstall( packageManager, nuGetProject, packageIdentity, resolutionContext, nuGetProjectContext, primarySources, allSources, token); allDependenciesResolved = true; } catch (NuGetResolverConstraintException) { // We didn't manage to find all dependencies in the local packages folder. allDependenciesResolved = false; } } // If we didn't manage to resolve all dependencies from the local sources, check in all sources. if (!allDependenciesResolved) { primarySources.AddRange(localSources); primarySources.AddRange(primarySourceRepositories); allSources.AddRange(primarySources); allSources.AddRange(secondarySourceRepositories); packageAndDependencies = await GetPackageAndDependenciesToInstall( packageManager, nuGetProject, packageIdentity, resolutionContext, nuGetProjectContext, primarySources, allSources, token); } // Create the install actions. return(GetProjectActions( packageIdentity, packageAndDependencies.Item1, packageAndDependencies.Item2, nuGetProject)); }