Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Fix NuGet/Home#1547

1. Change the order of uninstall to run the uninstall.ps1 script first (to match NuGet 2)
2. Check that the folder exists before trying to delete it
3. Remove duplicate call to Remove file from the project
  • Loading branch information
Yishai Galatzer committed Oct 14, 2015
1 parent 30bde3e commit 7a74868
Show file tree
Hide file tree
Showing 3 changed files with 82 additions and 70 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@

using System.Collections.Generic;
using System.IO;
using System.IO.Compression;
using System.Threading.Tasks;
using NuGet.Frameworks;
using NuGet.Packaging.Core;
Expand Down
105 changes: 46 additions & 59 deletions src/NuGet.Core/NuGet.ProjectManagement/Projects/MSBuildNuGetProject.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,33 +17,6 @@

namespace NuGet.ProjectManagement
{
internal class PackageItemComparer : IComparer<string>
{
public int Compare(string x, string y)
{
// BUG 636: We sort files so that they are added in the correct order
// e.g aspx before aspx.cs

if (x.Equals(y, StringComparison.OrdinalIgnoreCase))
{
return 0;
}

// Add files that are prefixes of other files first
if (x.StartsWith(y, StringComparison.OrdinalIgnoreCase))
{
return -1;
}

if (y.StartsWith(x, StringComparison.OrdinalIgnoreCase))
{
return 1;
}

return string.Compare(y, x, StringComparison.OrdinalIgnoreCase);
}
}

/// <summary>
/// This class represents a NuGetProject based on a .NET project. This also contains an instance of a
/// FolderNuGetProject
Expand Down Expand Up @@ -92,7 +65,9 @@ public class MSBuildNuGetProject : NuGetProject
{ new FileTransformExtensions(".install.xdt", ".uninstall.xdt"), new XdtTransformer() }
};

public MSBuildNuGetProject(IMSBuildNuGetProjectSystem msbuildNuGetProjectSystem, string folderNuGetProjectPath, string packagesConfigFolderPath)
public MSBuildNuGetProject(IMSBuildNuGetProjectSystem msbuildNuGetProjectSystem,
string folderNuGetProjectPath,
string packagesConfigFolderPath)
{
if (msbuildNuGetProjectSystem == null)
{
Expand Down Expand Up @@ -303,10 +278,12 @@ public override async Task<bool> InstallPackageAsync(
{
var referenceItemFullPath = Path.Combine(packageInstallPath, referenceItem);
var referenceName = Path.GetFileName(referenceItem);

if (MSBuildNuGetProjectSystem.ReferenceExists(referenceName))
{
MSBuildNuGetProjectSystem.RemoveReference(referenceName);
}

MSBuildNuGetProjectSystem.AddReference(referenceItemFullPath);
}
}
Expand Down Expand Up @@ -403,36 +380,57 @@ public override async Task<bool> UninstallPackageAsync(PackageIdentity packageId
}

var packageTargetFramework = packageReference.TargetFramework ?? MSBuildNuGetProjectSystem.TargetFramework;
var packageEventArgs = new PackageEventArgs(FolderNuGetProject, packageIdentity, FolderNuGetProject.GetInstalledPath(packageIdentity));
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)))
{
// 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);

// Step-2: Execute powershell script - uninstall.ps1
var toolItemGroups = packageReader.GetToolItems();
var compatibleToolItemsGroup = MSBuildNuGetProjectSystemUtility
.GetMostCompatibleGroup(packageTargetFramework, toolItemGroups);

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 MSBuildNuGetProjectSystem.ExecuteScriptAsync(packageIdentity, packageInstallPath, uninstallPS1RelativePath, this, throwOnFailure: false);
}
}

// 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-3: Get the most compatible items groups for all items groups
// 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);

// 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
// 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
Expand Down Expand Up @@ -485,38 +483,27 @@ public override async Task<bool> UninstallPackageAsync(PackageIdentity packageId
}

// 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: Execute powershell script - uninstall.ps1
var toolItemGroups = packageReader.GetToolItems();
var compatibleToolItemsGroup = MSBuildNuGetProjectSystemUtility.GetMostCompatibleGroup(packageTargetFramework,
toolItemGroups);
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 MSBuildNuGetProjectSystem.ExecuteScriptAsync(packageIdentity, packageInstallPath, uninstallPS1RelativePath, this, throwOnFailure: false);
}
}
PackageEventsProvider.Instance.NotifyReferenceRemoved(packageEventArgs);
}

// Step-10: Uninstall package from the folderNuGetProject
// Step-9: Uninstall package from the folderNuGetProject
await FolderNuGetProject.UninstallPackageAsync(packageIdentity, nuGetProjectContext, token);

// Step-11: Raise PackageUninstalled event
// Step-10: Raise PackageUninstalled event
if (PackageUninstalled != null)
{
PackageUninstalled(this, packageEventArgs);
}

PackageEventsProvider.Instance.NotifyUninstalled(packageEventArgs);

return true;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -145,13 +145,13 @@ internal static void DeleteFiles(IMSBuildNuGetProjectSystem projectSystem,
FrameworkSpecificGroup frameworkSpecificGroup,
IDictionary<FileTransformExtensions, IPackageFileTransformer> fileTransformers)
{
var packageTargetFramework = frameworkSpecificGroup.TargetFramework;
IPackageFileTransformer transformer;

try
{
projectSystem.BeginProcessing();

var packageTargetFramework = frameworkSpecificGroup.TargetFramework;

IPackageFileTransformer transformer;

var directoryLookup = frameworkSpecificGroup.Items.ToLookup(
p => Path.GetDirectoryName(ResolveTargetPath(projectSystem,
Expand Down Expand Up @@ -347,7 +347,6 @@ private static void DeleteDirectory(IMSBuildNuGetProjectSystem projectSystem, st
projectSystem.NuGetProjectContext.Log(MessageLevel.Warning, Strings.Warning_DirectoryNotEmpty, path);
return;
}

projectSystem.RegisterProcessedFiles(new[] { path });

projectSystem.DeleteDirectory(path, recursive: false);
Expand All @@ -360,7 +359,10 @@ private static void DeleteDirectory(IMSBuildNuGetProjectSystem projectSystem, st
return;
}

try
// For potential project systems that do not remove items from disk, we delete the folder directly
// There is no actual scenario where we know this is broken without the code below, but since the
// code was always there, we are leaving it behind for now.
if (!Directory.Exists(fullPath))
{
Directory.Delete(fullPath, recursive: false);

Expand All @@ -370,14 +372,11 @@ private static void DeleteDirectory(IMSBuildNuGetProjectSystem projectSystem, st
{
Thread.Sleep(100);
}

projectSystem.RegisterProcessedFiles(new[] { path });
projectSystem.RemoveFile(path);

projectSystem.NuGetProjectContext.Log(MessageLevel.Debug, Strings.Debug_RemovedFolder, fullPath);
}
catch (DirectoryNotFoundException)
{
}
}

private static void PerformSafeAction(Action action, INuGetProjectContext nuGetProjectContext)
Expand Down Expand Up @@ -532,5 +531,32 @@ internal static void AddFile(IMSBuildNuGetProjectSystem msBuildNuGetProjectSyste
msBuildNuGetProjectSystem.AddFile(path, memoryStream);
}
}

private class PackageItemComparer : IComparer<string>
{
public int Compare(string x, string y)
{
// BUG 636: We sort files so that they are added in the correct order
// e.g aspx before aspx.cs

if (x.Equals(y, StringComparison.OrdinalIgnoreCase))
{
return 0;
}

// Add files that are prefixes of other files first
if (x.StartsWith(y, StringComparison.OrdinalIgnoreCase))
{
return -1;
}

if (y.StartsWith(x, StringComparison.OrdinalIgnoreCase))
{
return 1;
}

return string.Compare(y, x, StringComparison.OrdinalIgnoreCase);
}
}
}
}
}

0 comments on commit 7a74868

Please sign in to comment.