public override async Task <bool> UninstallPackageAsync(PackageIdentity packageIdentity, INuGetProjectContext nuGetProjectContext, CancellationToken token) { if (packageIdentity == null) { throw new ArgumentNullException(nameof(packageIdentity)); } if (nuGetProjectContext == null) { throw new ArgumentNullException(nameof(nuGetProjectContext)); } // Step-1: Check if the package already exists after setting the nuGetProjectContext ProjectSystem.NuGetProjectContext = nuGetProjectContext; var packageReference = (await GetInstalledPackagesAsync(token)) .FirstOrDefault(p => p.PackageIdentity.Equals(packageIdentity)); if (packageReference == null) { nuGetProjectContext.Log(MessageLevel.Warning, Strings.PackageDoesNotExistInProject, packageIdentity, ProjectSystem.ProjectName); return(false); } var packageTargetFramework = packageReference.TargetFramework ?? ProjectSystem.TargetFramework; var packageEventArgs = new PackageEventArgs(FolderNuGetProject, packageIdentity, FolderNuGetProject.GetInstalledPath(packageIdentity)); if (PackageUninstalling != null) { PackageUninstalling(this, packageEventArgs); } PackageEventsProvider.Instance.NotifyUninstalling(packageEventArgs); using (var packageStream = File.OpenRead(FolderNuGetProject.GetInstalledPackageFilePath(packageIdentity))) { var zipArchive = new ZipArchive(packageStream); var packageReader = new PackageArchiveReader(zipArchive); // Step-2: Execute powershell script - uninstall.ps1 var toolItemGroups = packageReader.GetToolItems(); var compatibleToolItemsGroup = MSBuildNuGetProjectSystemUtility .GetMostCompatibleGroup(packageTargetFramework, toolItemGroups); compatibleToolItemsGroup = MSBuildNuGetProjectSystemUtility.Normalize(compatibleToolItemsGroup); if (MSBuildNuGetProjectSystemUtility.IsValid(compatibleToolItemsGroup)) { var uninstallPS1RelativePath = compatibleToolItemsGroup.Items.FirstOrDefault( p => p.EndsWith(Path.DirectorySeparatorChar + PowerShellScripts.Uninstall, StringComparison.OrdinalIgnoreCase)); if (!string.IsNullOrEmpty(uninstallPS1RelativePath)) { var packageInstallPath = FolderNuGetProject.GetInstalledPath( packageIdentity); await ProjectServices.ScriptService.ExecutePackageScriptAsync( packageIdentity, packageInstallPath, uninstallPS1RelativePath, nuGetProjectContext, throwOnFailure : false, token : token); } } // Step-3: Obtain the various item groups // Get the package target framework instead of using project targetframework var referenceItemGroups = packageReader.GetReferenceItems(); var contentFileGroups = packageReader.GetContentItems(); var buildFileGroups = packageReader.GetBuildItems(); // Step-4: Get the most compatible items groups for all items groups var compatibleReferenceItemsGroup = MSBuildNuGetProjectSystemUtility.GetMostCompatibleGroup(packageTargetFramework, referenceItemGroups); var compatibleContentFilesGroup = MSBuildNuGetProjectSystemUtility.GetMostCompatibleGroup(packageTargetFramework, contentFileGroups); var compatibleBuildFilesGroup = MSBuildNuGetProjectSystemUtility.GetMostCompatibleGroup(packageTargetFramework, buildFileGroups); compatibleReferenceItemsGroup = MSBuildNuGetProjectSystemUtility.Normalize(compatibleReferenceItemsGroup); compatibleContentFilesGroup = MSBuildNuGetProjectSystemUtility.Normalize(compatibleContentFilesGroup); compatibleBuildFilesGroup = MSBuildNuGetProjectSystemUtility.Normalize(compatibleBuildFilesGroup); // Step-5: Remove package reference from packages.config await PackagesConfigNuGetProject.UninstallPackageAsync(packageIdentity, nuGetProjectContext, token); // Step-6: Remove packages.config from MSBuildNuGetProject if there are no packages // OR Add it again (to ensure that Source Control works), when there are some packages if (!(await PackagesConfigNuGetProject.GetInstalledPackagesAsync(token)).Any()) { ProjectSystem.RemoveFile(Path.GetFileName(PackagesConfigNuGetProject.FullPath)); } else { ProjectSystem.AddExistingFile(Path.GetFileName(PackagesConfigNuGetProject.FullPath)); } // Step-7: Uninstall package from the msbuild project // Step-7.1: Remove references if (MSBuildNuGetProjectSystemUtility.IsValid(compatibleReferenceItemsGroup)) { foreach (var item in compatibleReferenceItemsGroup.Items) { if (IsAssemblyReference(item)) { await ProjectSystem.RemoveReferenceAsync(Path.GetFileName(item)); } } } // Step-7.2: Framework references are never removed. This is a no-op // Step-7.3: Remove content files if (MSBuildNuGetProjectSystemUtility.IsValid(compatibleContentFilesGroup)) { var packagesPaths = (await GetInstalledPackagesAsync(token)) .Select(pr => FolderNuGetProject.GetInstalledPackageFilePath(pr.PackageIdentity)); await MSBuildNuGetProjectSystemUtility.DeleteFilesAsync( ProjectSystem, zipArchive, packagesPaths, compatibleContentFilesGroup, FileTransformers, token); } // Step-7.4: Remove build imports if (MSBuildNuGetProjectSystemUtility.IsValid(compatibleBuildFilesGroup)) { foreach (var buildImportFile in compatibleBuildFilesGroup.Items) { var fullImportFilePath = Path.Combine(FolderNuGetProject.GetInstalledPath(packageIdentity), buildImportFile); ProjectSystem.RemoveImport(fullImportFilePath); } } // Step-7.5: Remove binding redirects. This is a no-op // Binding redirects will be removed when all packages have finished // uninstalling for performance reasons // Step-8: Raise PackageReferenceRemoved event if (PackageReferenceRemoved != null) { PackageReferenceRemoved(this, packageEventArgs); } PackageEventsProvider.Instance.NotifyReferenceRemoved(packageEventArgs); } // Step-9: Uninstall package from the folderNuGetProject await FolderNuGetProject.UninstallPackageAsync(packageIdentity, nuGetProjectContext, token); // Step-10: Raise PackageUninstalled event if (PackageUninstalled != null) { PackageUninstalled(this, packageEventArgs); } PackageEventsProvider.Instance.NotifyUninstalled(packageEventArgs); return(true); }
public async override Task <bool> UninstallPackageAsync(PackageIdentity packageIdentity, INuGetProjectContext nuGetProjectContext, CancellationToken token) { if (packageIdentity == null) { throw new ArgumentNullException("packageIdentity"); } if (nuGetProjectContext == null) { throw new ArgumentNullException("nuGetProjectContext"); } // Step-1: Check if the package already exists after setting the nuGetProjectContext MSBuildNuGetProjectSystem.SetNuGetProjectContext(nuGetProjectContext); var packageReference = (await GetInstalledPackagesAsync(token)).Where( p => p.PackageIdentity.Equals(packageIdentity)).FirstOrDefault(); if (packageReference == null) { nuGetProjectContext.Log(MessageLevel.Warning, Strings.PackageDoesNotExistInProject, packageIdentity, MSBuildNuGetProjectSystem.ProjectName); return(false); } var packageTargetFramework = packageReference.TargetFramework ?? NuGetFramework.UnsupportedFramework; var packageEventArgs = new PackageEventArgs(FolderNuGetProject, packageIdentity, FolderNuGetProject.GetInstalledPath(packageIdentity)); using (var packageStream = File.OpenRead(FolderNuGetProject.GetInstalledPackageFilePath(packageIdentity))) { // Step-2: Create PackageReader using the PackageStream and obtain the various item groups // Get the package target framework instead of using project targetframework var zipArchive = new ZipArchive(packageStream); var packageReader = new PackageReader(zipArchive); IEnumerable <FrameworkSpecificGroup> referenceItemGroups = packageReader.GetReferenceItems(); IEnumerable <FrameworkSpecificGroup> frameworkReferenceGroups = packageReader.GetFrameworkItems(); IEnumerable <FrameworkSpecificGroup> contentFileGroups = packageReader.GetContentItems(); IEnumerable <FrameworkSpecificGroup> buildFileGroups = packageReader.GetBuildItems(); // Step-3: Get the most compatible items groups for all items groups FrameworkSpecificGroup compatibleReferenceItemsGroup = MSBuildNuGetProjectSystemUtility.GetMostCompatibleGroup(packageTargetFramework, referenceItemGroups); FrameworkSpecificGroup compatibleFrameworkReferencesGroup = MSBuildNuGetProjectSystemUtility.GetMostCompatibleGroup(packageTargetFramework, frameworkReferenceGroups); FrameworkSpecificGroup compatibleContentFilesGroup = MSBuildNuGetProjectSystemUtility.GetMostCompatibleGroup(packageTargetFramework, contentFileGroups); FrameworkSpecificGroup compatibleBuildFilesGroup = MSBuildNuGetProjectSystemUtility.GetMostCompatibleGroup(packageTargetFramework, buildFileGroups); // TODO: Need to handle References element?? // Step-4: Raise PackageUninstalling event if (PackageUninstalling != null) { PackageUninstalling(this, packageEventArgs); } PackageEventsProvider.Instance.NotifyUninstalling(packageEventArgs); // Step-5: Uninstall package from packages.config await PackagesConfigNuGetProject.UninstallPackageAsync(packageIdentity, nuGetProjectContext, token); // Step-6: Remove packages.config from MSBuildNuGetProject if there are no packages // OR Add it again (to ensure that Source Control works), when there are some packages if (!(await PackagesConfigNuGetProject.GetInstalledPackagesAsync(token)).Any()) { MSBuildNuGetProjectSystem.RemoveFile(Path.GetFileName(PackagesConfigNuGetProject.FullPath)); } else { MSBuildNuGetProjectSystem.AddExistingFile(Path.GetFileName(PackagesConfigNuGetProject.FullPath)); } // Step-7: Uninstall package from the msbuild project // Step-7.1: Remove references if (MSBuildNuGetProjectSystemUtility.IsValid(compatibleReferenceItemsGroup)) { foreach (var item in compatibleReferenceItemsGroup.Items) { if (IsAssemblyReference(item)) { MSBuildNuGetProjectSystem.RemoveReference(Path.GetFileName(item)); } } } // Step-7.2: Framework references are never removed. This is a no-op // Step-7.3: Remove content files if (MSBuildNuGetProjectSystemUtility.IsValid(compatibleContentFilesGroup)) { MSBuildNuGetProjectSystemUtility.DeleteFiles(MSBuildNuGetProjectSystem, zipArchive, (await GetInstalledPackagesAsync(token)).Select(pr => FolderNuGetProject.GetInstalledPackageFilePath(pr.PackageIdentity)), compatibleContentFilesGroup, FileTransformers); } // Step-7.4: Remove build imports if (MSBuildNuGetProjectSystemUtility.IsValid(compatibleBuildFilesGroup)) { foreach (var buildImportFile in compatibleBuildFilesGroup.Items) { string fullImportFilePath = Path.Combine(FolderNuGetProject.GetInstalledPath(packageIdentity), buildImportFile); MSBuildNuGetProjectSystem.RemoveImport(fullImportFilePath); } } // Step-7.5: Remove binding redirects. This is a no-op // Step-8: Raise PackageReferenceRemoved event if (PackageReferenceRemoved != null) { PackageReferenceRemoved(this, packageEventArgs); } PackageEventsProvider.Instance.NotifyReferenceRemoved(packageEventArgs); // Step-9: Execute powershell script - uninstall.ps1 IEnumerable <FrameworkSpecificGroup> toolItemGroups = packageReader.GetToolItems(); FrameworkSpecificGroup compatibleToolItemsGroup = MSBuildNuGetProjectSystemUtility.GetMostCompatibleGroup(MSBuildNuGetProjectSystem.TargetFramework, toolItemGroups); if (MSBuildNuGetProjectSystemUtility.IsValid(compatibleToolItemsGroup)) { string uninstallPS1RelativePath = compatibleToolItemsGroup.Items.Where(p => p.EndsWith(Path.DirectorySeparatorChar + PowerShellScripts.Uninstall)).FirstOrDefault(); if (!String.IsNullOrEmpty(uninstallPS1RelativePath)) { string packageInstallPath = FolderNuGetProject.GetInstalledPath(packageIdentity); await MSBuildNuGetProjectSystem.ExecuteScriptAsync(packageInstallPath, uninstallPS1RelativePath, zipArchive, this); } } } // Step-10: Uninstall package from the folderNuGetProject await FolderNuGetProject.UninstallPackageAsync(packageIdentity, nuGetProjectContext, token); // Step-11: Raise PackageUninstalled event if (PackageUninstalled != null) { PackageUninstalled(this, packageEventArgs); } PackageEventsProvider.Instance.NotifyUninstalled(packageEventArgs); return(true); }