From c0ff79e49ed3e442cb97c180631090314a1496aa Mon Sep 17 00:00:00 2001 From: Matt Ward Date: Sat, 27 Jun 2015 12:47:01 +0100 Subject: [PATCH] Uninstall-Package can now remove solution level NuGet packages. Previously if a solution level NuGet package, such as Fake, was installed then running the Uninstall-Package cmdlet would not find the Fake NuGet package and report an error. Now if the NuGet package is not found in the project's package repository then the solution's package repository is checked. --- .../Design/FakePackageManagementProject.cs | 17 +++++ .../Project/Src/Design/FakePackageManager.cs | 2 + .../Project/Src/IPackageManagementProject.cs | 2 + .../Project/Src/PackageManagementProject.cs | 25 +++++++ .../Project/Src/ProcessPackageAction.cs | 16 ++--- .../Project/Src/SharpDevelopPackageManager.cs | 8 ++- .../Project/Src/UninstallPackageAction.cs | 5 ++ .../Test/Src/PackageManagementProjectTests.cs | 68 +++++++++++++++++++ .../Src/SharpDevelopPackageManagerTests.cs | 22 +++++- .../Test/Src/UninstallPackageActionTests.cs | 26 +++---- 10 files changed, 166 insertions(+), 25 deletions(-) diff --git a/src/AddIns/Misc/PackageManagement/Project/Src/Design/FakePackageManagementProject.cs b/src/AddIns/Misc/PackageManagement/Project/Src/Design/FakePackageManagementProject.cs index 07521f68f7..a8a2f27d96 100644 --- a/src/AddIns/Misc/PackageManagement/Project/Src/Design/FakePackageManagementProject.cs +++ b/src/AddIns/Misc/PackageManagement/Project/Src/Design/FakePackageManagementProject.cs @@ -299,5 +299,22 @@ namespace ICSharpCode.PackageManagement.Design public IPackageConstraintProvider ConstraintProvider { get; set; } public FrameworkName TargetFramework { get; set; } + + public FakePackageRepository FakeLocalRepository = new FakePackageRepository(); + + public IPackage FindPackage(string packageId, SemanticVersion version) + { + return FakeLocalRepository.FindPackage(packageId, version); + } + + public void AddFakePackageToLocalRepository(string packageId) + { + FakeLocalRepository.AddFakePackage(packageId); + } + + public FakePackage AddFakePackageToLocalRepository(string packageId, string version) + { + return FakeLocalRepository.AddFakePackageWithVersion(packageId, version); + } } } diff --git a/src/AddIns/Misc/PackageManagement/Project/Src/Design/FakePackageManager.cs b/src/AddIns/Misc/PackageManagement/Project/Src/Design/FakePackageManager.cs index 7f6417b4f7..09f8d3c199 100644 --- a/src/AddIns/Misc/PackageManagement/Project/Src/Design/FakePackageManager.cs +++ b/src/AddIns/Misc/PackageManagement/Project/Src/Design/FakePackageManager.cs @@ -60,11 +60,13 @@ namespace ICSharpCode.PackageManagement.Design public ISharpDevelopProjectManager ProjectManager { get; set; } public FakePackageRepository FakeSourceRepository = new FakePackageRepository(); + public FakePackageRepository FakeLocalRepository = new FakePackageRepository(); public FakePackageManager() { ProjectManager = FakeProjectManager; SourceRepository = FakeSourceRepository; + LocalRepository = FakeLocalRepository; } public bool ForceRemovePassedToUninstallPackage; diff --git a/src/AddIns/Misc/PackageManagement/Project/Src/IPackageManagementProject.cs b/src/AddIns/Misc/PackageManagement/Project/Src/IPackageManagementProject.cs index 82b782409f..e248733459 100644 --- a/src/AddIns/Misc/PackageManagement/Project/Src/IPackageManagementProject.cs +++ b/src/AddIns/Misc/PackageManagement/Project/Src/IPackageManagementProject.cs @@ -65,5 +65,7 @@ namespace ICSharpCode.PackageManagement UpdatePackagesAction CreateUpdatePackagesAction(); void RunPackageOperations(IEnumerable expectedOperations); + + IPackage FindPackage(string packageId, SemanticVersion version); } } diff --git a/src/AddIns/Misc/PackageManagement/Project/Src/PackageManagementProject.cs b/src/AddIns/Misc/PackageManagement/Project/Src/PackageManagementProject.cs index 3892191f4d..4e0d9a97ca 100644 --- a/src/AddIns/Misc/PackageManagement/Project/Src/PackageManagementProject.cs +++ b/src/AddIns/Misc/PackageManagement/Project/Src/PackageManagementProject.cs @@ -195,5 +195,30 @@ namespace ICSharpCode.PackageManagement return NullConstraintProvider.Instance; } } + + public IPackage FindPackage(string packageId, SemanticVersion version) + { + IPackage package = projectManager.LocalRepository.FindPackage(packageId, version); + + if (package != null) { + return package; + } + + if (version != null) { + return packageManager.LocalRepository.FindPackage(packageId, version); + } + + List packages = packageManager.LocalRepository.FindPackagesById(packageId).ToList(); + if (packages.Count > 1) { + throw CreateAmbiguousPackageException(packageId); + } + return packages.FirstOrDefault(); + } + + InvalidOperationException CreateAmbiguousPackageException(string packageId) + { + string message = String.Format("Multiple versions of '{0}' found. Please specify the version.", packageId); + return new InvalidOperationException(message); + } } } diff --git a/src/AddIns/Misc/PackageManagement/Project/Src/ProcessPackageAction.cs b/src/AddIns/Misc/PackageManagement/Project/Src/ProcessPackageAction.cs index 95d779dcde..a537364473 100644 --- a/src/AddIns/Misc/PackageManagement/Project/Src/ProcessPackageAction.cs +++ b/src/AddIns/Misc/PackageManagement/Project/Src/ProcessPackageAction.cs @@ -125,21 +125,21 @@ namespace ICSharpCode.PackageManagement void GetPackageIfMissing() { if (Package == null) { - FindPackage(); + Package = FindPackage(); } if (Package == null) { ThrowPackageNotFoundError(PackageId); } } - void FindPackage() + protected virtual IPackage FindPackage() { - Package = Project.SourceRepository.FindPackage( - PackageId, - PackageVersion, - Project.ConstraintProvider, - AllowPrereleaseVersions, - allowUnlisted: false); + return Project.SourceRepository.FindPackage( + PackageId, + PackageVersion, + Project.ConstraintProvider, + AllowPrereleaseVersions, + allowUnlisted: false); } void ThrowPackageNotFoundError(string packageId) diff --git a/src/AddIns/Misc/PackageManagement/Project/Src/SharpDevelopPackageManager.cs b/src/AddIns/Misc/PackageManagement/Project/Src/SharpDevelopPackageManager.cs index 1265c21821..f03bf3c536 100644 --- a/src/AddIns/Misc/PackageManagement/Project/Src/SharpDevelopPackageManager.cs +++ b/src/AddIns/Misc/PackageManagement/Project/Src/SharpDevelopPackageManager.cs @@ -108,8 +108,12 @@ namespace ICSharpCode.PackageManagement public override void UninstallPackage(IPackage package, bool forceRemove, bool removeDependencies) { - ProjectManager.RemovePackageReference(package.Id, forceRemove, removeDependencies); - if (!IsPackageReferencedByOtherProjects(package)) { + if (package.IsProjectPackage()) { + ProjectManager.RemovePackageReference(package.Id, forceRemove, removeDependencies); + if (!IsPackageReferencedByOtherProjects(package)) { + base.UninstallPackage(package, forceRemove, removeDependencies); + } + } else { base.UninstallPackage(package, forceRemove, removeDependencies); } } diff --git a/src/AddIns/Misc/PackageManagement/Project/Src/UninstallPackageAction.cs b/src/AddIns/Misc/PackageManagement/Project/Src/UninstallPackageAction.cs index eef9994228..e267539b10 100644 --- a/src/AddIns/Misc/PackageManagement/Project/Src/UninstallPackageAction.cs +++ b/src/AddIns/Misc/PackageManagement/Project/Src/UninstallPackageAction.cs @@ -52,5 +52,10 @@ namespace ICSharpCode.PackageManagement var files = new PackageFiles(Package); return files.HasUninstallPackageScript(); } + + protected override IPackage FindPackage() + { + return Project.FindPackage(PackageId, PackageVersion); + } } } diff --git a/src/AddIns/Misc/PackageManagement/Test/Src/PackageManagementProjectTests.cs b/src/AddIns/Misc/PackageManagement/Test/Src/PackageManagementProjectTests.cs index d2929838d8..d1de9b67d1 100644 --- a/src/AddIns/Misc/PackageManagement/Test/Src/PackageManagementProjectTests.cs +++ b/src/AddIns/Misc/PackageManagement/Test/Src/PackageManagementProjectTests.cs @@ -805,5 +805,73 @@ namespace PackageManagement.Tests Assert.AreEqual(expectedName, targetFramework); } + + [Test] + public void FindPackage_PackageExistsInProjectLocalRepository_PackageReturned() + { + CreateProject(); + FakePackage package = fakeProjectManager.FakeLocalRepository.AddFakePackageWithVersion("Test", "1.0"); + + IPackage packageFound = project.FindPackage("Test", new SemanticVersion("1.0")); + + Assert.AreEqual(package, packageFound); + } + + [Test] + public void FindPackage_PackageWithDifferentVersionExistsInProjectLocalRepository_PackageNotFound() + { + CreateProject(); + fakeProjectManager.FakeLocalRepository.AddFakePackageWithVersion("Test", "1.0"); + + IPackage packageFound = project.FindPackage("Test", new SemanticVersion("2.1")); + + Assert.IsNull(packageFound); + } + + [Test] + public void FindPackage_PackageWithSameVersionExistsInSolutionPackageRepository_PackageReturned() + { + CreateProject(); + FakePackage package = fakePackageManager.FakeLocalRepository.AddFakePackageWithVersion("Test", "1.0"); + + IPackage packageFound = project.FindPackage("Test", new SemanticVersion("1.0")); + + Assert.AreEqual(package, packageFound); + } + + [Test] + public void FindPackage_PackageWithDifferentVersionExistsInSolutionPackageRepository_PackageNotFound() + { + CreateProject(); + fakePackageManager.FakeLocalRepository.AddFakePackageWithVersion("Test", "1.0"); + + IPackage packageFound = project.FindPackage("Test", new SemanticVersion("2.1")); + + Assert.IsNull(packageFound); + } + + [Test] + public void FindPackage_PackageWithoutVersionWhichExistsInSolutionPackageRepository_PackageReturned() + { + CreateProject(); + FakePackage package = fakePackageManager.FakeLocalRepository.AddFakePackageWithVersion("Test", "1.0"); + + IPackage packageFound = project.FindPackage("Test", null); + + Assert.AreEqual(package, packageFound); + } + + [Test] + public void FindPackage_PackageWithoutVersionWhenPackageExistsWithMultipleVersionsInSolutionPackageRepository_InvalidOperationExceptionThrown() + { + CreateProject(); + fakePackageManager.FakeLocalRepository.AddFakePackageWithVersion("Test", "1.0"); + fakePackageManager.FakeLocalRepository.AddFakePackageWithVersion("Test", "1.1"); + + InvalidOperationException ex = + Assert.Throws(() => project.FindPackage("Test", null)); + + Assert.AreEqual("Multiple versions of 'Test' found. Please specify the version.", ex.Message); + } } } diff --git a/src/AddIns/Misc/PackageManagement/Test/Src/SharpDevelopPackageManagerTests.cs b/src/AddIns/Misc/PackageManagement/Test/Src/SharpDevelopPackageManagerTests.cs index 0a0ce3c82b..a242b56709 100644 --- a/src/AddIns/Misc/PackageManagement/Test/Src/SharpDevelopPackageManagerTests.cs +++ b/src/AddIns/Misc/PackageManagement/Test/Src/SharpDevelopPackageManagerTests.cs @@ -98,7 +98,9 @@ namespace PackageManagement.Tests FakePackage CreateFakePackage(string id = "Test", string version = "1.0.0.0") { - return new FakePackage(id, version); + var package = new FakePackage(id, version); + package.FrameworkAssembliesList.Add(new FrameworkAssemblyReference("System.Xml")); + return package; } FakePackage InstallPackage() @@ -632,7 +634,7 @@ namespace PackageManagement.Tests CreatePackageManager(); CreateTestableProjectManager(); - var package = new FakePackage("MyPackageId", "1.4.5.2"); + FakePackage package = CreateFakePackage("MyPackageId", "1.4.5.2"); testableProjectManager.FakeLocalRepository.FakePackages.Add(package); fakeSolutionSharedRepository.FakePackages.Add(package); @@ -1116,5 +1118,21 @@ namespace PackageManagement.Tests Assert.IsTrue(fakeSolutionSharedRepository.FakePackages.Contains(installedPackage)); } + + [Test] + public void UninstallPackage_SolutionLevelPackage_PackageIsRemovedFromSharedSolutionRepositoryAndProjectManagerNotUsed() + { + CreatePackageManager(); + CreateTestableProjectManager(); + var package = new FakePackage("MyPackage", "1.0"); + fakeSolutionSharedRepository.FakePackages.Add(package); + + packageManager.UninstallPackage(package); + + bool containsPackage = fakeSolutionSharedRepository.FakePackages.Contains(package); + + Assert.IsFalse(containsPackage); + Assert.IsNull(testableProjectManager.PackagePassedToRemovePackageReference); + } } } diff --git a/src/AddIns/Misc/PackageManagement/Test/Src/UninstallPackageActionTests.cs b/src/AddIns/Misc/PackageManagement/Test/Src/UninstallPackageActionTests.cs index 6f89618202..f6999acc6e 100644 --- a/src/AddIns/Misc/PackageManagement/Test/Src/UninstallPackageActionTests.cs +++ b/src/AddIns/Misc/PackageManagement/Test/Src/UninstallPackageActionTests.cs @@ -42,14 +42,14 @@ namespace PackageManagement.Tests uninstallPackageHelper = new UninstallPackageHelper(action); } - FakePackage AddOnePackageToProjectSourceRepository(string packageId) + FakePackage AddOnePackageToProjectLocalRepository(string packageId) { - return fakeProject.FakeSourceRepository.AddFakePackage(packageId); + return fakeProject.FakeLocalRepository.AddFakePackage(packageId); } - FakePackage AddOnePackageToProjectSourceRepository(string packageId, string version) + FakePackage AddOnePackageToProjectLocalRepository(string packageId, string version) { - return fakeProject.FakeSourceRepository.AddFakePackageWithVersion(packageId, version); + return fakeProject.FakeLocalRepository.AddFakePackageWithVersion(packageId, version); } void AddFileToPackageBeingUninstalled(string fileName) @@ -90,7 +90,7 @@ namespace PackageManagement.Tests public void Execute_PackageObjectPassedAndForceRemoveIsFalse_PackageIsNotForcefullyRemoved() { CreateAction(); - fakeProject.AddFakePackageToSourceRepository("PackageId"); + fakeProject.AddFakePackageToLocalRepository("PackageId"); uninstallPackageHelper.ForceRemove = false; uninstallPackageHelper.UninstallPackageById("PackageId"); @@ -103,7 +103,7 @@ namespace PackageManagement.Tests public void Execute_PackageObjectPassedAndForceRemoveIsTrue_PackageIsForcefullyRemoved() { CreateAction(); - fakeProject.AddFakePackageToSourceRepository("PackageId"); + fakeProject.AddFakePackageToLocalRepository("PackageId"); uninstallPackageHelper.ForceRemove = true; uninstallPackageHelper.UninstallPackageById("PackageId"); @@ -116,7 +116,7 @@ namespace PackageManagement.Tests public void Execute_PackageObjectPassedAndRemoveDependenciesIsFalse_PackageDependenciesAreNotRemoved() { CreateAction(); - fakeProject.AddFakePackageToSourceRepository("PackageId"); + fakeProject.AddFakePackageToLocalRepository("PackageId"); uninstallPackageHelper.RemoveDependencies = false; uninstallPackageHelper.UninstallPackageById("PackageId"); @@ -129,7 +129,7 @@ namespace PackageManagement.Tests public void Execute_PackageObjectPassedAndRemoveDependenciesIsTrue_PackageDependenciesAreRemoved() { CreateAction(); - fakeProject.AddFakePackageToSourceRepository("PackageId"); + fakeProject.AddFakePackageToLocalRepository("PackageId"); uninstallPackageHelper.RemoveDependencies = true; uninstallPackageHelper.UninstallPackageById("PackageId"); @@ -142,7 +142,7 @@ namespace PackageManagement.Tests public void Execute_PackageIdSpecifiedAndForceRemoveIsTrue_PackageIsForcefullyRemoved() { CreateAction(); - fakeProject.AddFakePackageToSourceRepository("PackageId"); + fakeProject.AddFakePackageToLocalRepository("PackageId"); uninstallPackageHelper.ForceRemove = true; uninstallPackageHelper.UninstallPackageById("PackageId"); @@ -155,7 +155,7 @@ namespace PackageManagement.Tests public void Execute_PackageIdSpecifiedAndRemoveDependenciesIsTrue_PackageDependenciesAreRemoved() { CreateAction(); - fakeProject.AddFakePackageToSourceRepository("PackageId"); + fakeProject.AddFakePackageToLocalRepository("PackageId"); uninstallPackageHelper.RemoveDependencies = true; uninstallPackageHelper.UninstallPackageById("PackageId"); @@ -169,9 +169,9 @@ namespace PackageManagement.Tests { CreateAction(); - FakePackage recentPackage = AddOnePackageToProjectSourceRepository("PackageId", "1.2.0.0"); - FakePackage oldPackage = AddOnePackageToProjectSourceRepository("PackageId", "1.0.0.0"); - FakePackage package = AddOnePackageToProjectSourceRepository("PackageId", "1.1.0"); + FakePackage recentPackage = AddOnePackageToProjectLocalRepository("PackageId", "1.2.0.0"); + FakePackage oldPackage = AddOnePackageToProjectLocalRepository("PackageId", "1.0.0.0"); + FakePackage package = AddOnePackageToProjectLocalRepository("PackageId", "1.1.0"); uninstallPackageHelper.Version = package.Version; uninstallPackageHelper.UninstallPackageById("PackageId");