From 569e086caef59c27b49c48b331b52fde977a2a02 Mon Sep 17 00:00:00 2001 From: Siegfried Pammer Date: Mon, 11 Aug 2014 21:16:35 +0200 Subject: [PATCH 1/5] partial fix for #526: InsertWithCursor broken in Create Enum refactoring --- .../Project/Src/Refactoring/EditorScript.cs | 35 +++++++++---------- .../Src/Refactoring/InsertionCursorLayer.cs | 35 ++++++++++--------- 2 files changed, 35 insertions(+), 35 deletions(-) diff --git a/src/AddIns/BackendBindings/CSharpBinding/Project/Src/Refactoring/EditorScript.cs b/src/AddIns/BackendBindings/CSharpBinding/Project/Src/Refactoring/EditorScript.cs index cb33ec2b33..450088e1af 100644 --- a/src/AddIns/BackendBindings/CSharpBinding/Project/Src/Refactoring/EditorScript.cs +++ b/src/AddIns/BackendBindings/CSharpBinding/Project/Src/Refactoring/EditorScript.cs @@ -18,6 +18,7 @@ using System; using System.Collections.Generic; +using System.Diagnostics; using System.Linq; using System.Threading.Tasks; using System.Windows.Threading; @@ -132,21 +133,21 @@ namespace CSharpBinding.Refactoring switch (defaultPosition) { case InsertPosition.Start: - layer.CurrentInsertionPoint = 0; + layer.CurrentInsertionPointIndex = 0; break; case InsertPosition.End: - layer.CurrentInsertionPoint = insertionPoints.Count - 1; + layer.CurrentInsertionPointIndex = insertionPoints.Count - 1; break; case InsertPosition.Before: for (int i = 0; i < insertionPoints.Count; i++) { if (insertionPoints[i].Location < loc) - layer.CurrentInsertionPoint = i; + layer.CurrentInsertionPointIndex = i; } break; case InsertPosition.After: for (int i = 0; i < insertionPoints.Count; i++) { if (insertionPoints[i].Location > loc) { - layer.CurrentInsertionPoint = i; + layer.CurrentInsertionPointIndex = i; break; } } @@ -174,11 +175,20 @@ namespace CSharpBinding.Refactoring } int offset = currentScript.GetCurrentOffset(args.InsertionPoint.Location); - int indentLevel = currentScript.GetIndentLevelAt(offset); + int indentLevel = currentScript.GetIndentLevelAt(Math.Max(0, offset - 1)); foreach (var node in nodes.Reverse()) { var output = currentScript.OutputNode(indentLevel, node); - int delta = args.InsertionPoint.Insert(target, output.Text); + var text = output.Text; + var insertionPoint = args.InsertionPoint; + if (node is EnumMemberDeclaration) { + insertionPoint.LineAfter = NewLineInsertion.Eol; + insertionPoint.LineBefore = NewLineInsertion.None; + if (args.InsertionPoint != layer.InsertionPoints.Last()) { + text += ","; + } + } + int delta = insertionPoint.Insert(target, text); output.RegisterTrackedSegments(currentScript, delta + offset); } currentScript.FormatText(nodes); @@ -239,19 +249,6 @@ namespace CSharpBinding.Refactoring var layer = new InsertionCursorLayer(area, operation, insertionPoints); area.Dispatcher.BeginInvoke(DispatcherPriority.Background, (Action)area.TextView.InvalidateVisual); - if (declaringType.Kind == TypeKind.Enum) { - foreach (var node in nodes.Reverse()) { - int indentLevel = GetIndentLevelAt(area.Document.GetOffset(declaringType.BodyRegion.Begin)); - var output = OutputNode(indentLevel, node); - var point = insertionPoints[0]; - var offset = area.Document.GetOffset(point.Location); - var text = output.Text + ","; - var delta = point.Insert(area.Document, text); - output.RegisterTrackedSegments(script, delta + offset); - } - tcs.SetResult(script); - return tcs.Task; - } InsertWithCursorOnLayer(script, layer, tcs, nodes, area.Document); return tcs.Task; } diff --git a/src/AddIns/BackendBindings/CSharpBinding/Project/Src/Refactoring/InsertionCursorLayer.cs b/src/AddIns/BackendBindings/CSharpBinding/Project/Src/Refactoring/InsertionCursorLayer.cs index 5da8782c9a..19ae16a1c6 100644 --- a/src/AddIns/BackendBindings/CSharpBinding/Project/Src/Refactoring/InsertionCursorLayer.cs +++ b/src/AddIns/BackendBindings/CSharpBinding/Project/Src/Refactoring/InsertionCursorLayer.cs @@ -24,6 +24,7 @@ using System.Windows.Controls; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; + using ICSharpCode.AvalonEdit; using ICSharpCode.AvalonEdit.Editing; using ICSharpCode.AvalonEdit.Rendering; @@ -31,6 +32,7 @@ using ICSharpCode.AvalonEdit.Utils; using ICSharpCode.NRefactory; using ICSharpCode.SharpDevelop; using ICSharpCode.SharpDevelop.Editor; + namespace CSharpBinding.Refactoring { class InsertionCursorLayer : Canvas, IDisposable @@ -41,9 +43,10 @@ namespace CSharpBinding.Refactoring readonly TextArea editor; - public int CurrentInsertionPoint { - get; - set; + public int CurrentInsertionPointIndex { get; set; } + + public InsertionPoint[] InsertionPoints { + get { return insertionPoints; } } int insertionPointNextToMouse = -1; @@ -73,8 +76,8 @@ namespace CSharpBinding.Refactoring protected override void OnRender(DrawingContext drawingContext) { - DrawLineForInsertionPoint(CurrentInsertionPoint, markerPen, drawingContext); - if (insertionPointNextToMouse > -1 && insertionPointNextToMouse != CurrentInsertionPoint) + DrawLineForInsertionPoint(CurrentInsertionPointIndex, markerPen, drawingContext); + if (insertionPointNextToMouse > -1 && insertionPointNextToMouse != CurrentInsertionPointIndex) DrawLineForInsertionPoint(insertionPointNextToMouse, tempMarkerPen, drawingContext); SetGroupBoxPosition(); // HACK: why OnRender() override? we could just use Line objects instead @@ -128,7 +131,7 @@ namespace CSharpBinding.Refactoring else { insertionPointNextToMouse = FindNextInsertionPoint(e.GetPosition(this)); if (insertionPointNextToMouse >= 0) - CurrentInsertionPoint = insertionPointNextToMouse; + CurrentInsertionPointIndex = insertionPointNextToMouse; InvalidateVisual(); } e.Handled = true; @@ -181,9 +184,9 @@ namespace CSharpBinding.Refactoring { return (sender, e) => { if (up) - layer.CurrentInsertionPoint = Math.Max(0, layer.CurrentInsertionPoint - 1); + layer.CurrentInsertionPointIndex = Math.Max(0, layer.CurrentInsertionPointIndex - 1); else - layer.CurrentInsertionPoint = Math.Min(layer.insertionPoints.Length - 1, layer.CurrentInsertionPoint + 1); + layer.CurrentInsertionPointIndex = Math.Min(layer.insertionPoints.Length - 1, layer.CurrentInsertionPointIndex + 1); layer.InvalidateVisual(); layer.ScrollToInsertionPoint(); }; @@ -192,9 +195,9 @@ namespace CSharpBinding.Refactoring ExecutedRoutedEventHandler MoveMarkerPage(bool up) { return (sender, e) => { - TextLocation current = layer.insertionPoints[layer.CurrentInsertionPoint].Location; + TextLocation current = layer.insertionPoints[layer.CurrentInsertionPointIndex].Location; double currentVPos = layer.editor.TextView.GetVisualTopByDocumentLine(current.Line); - int newIndex = layer.CurrentInsertionPoint; + int newIndex = layer.CurrentInsertionPointIndex; double newVPos; do { if (up) { @@ -214,7 +217,7 @@ namespace CSharpBinding.Refactoring newVPos = layer.editor.TextView.GetVisualTopByDocumentLine(layer.insertionPoints[newIndex].Location.Line); } while (Math.Abs(currentVPos - newVPos) < layer.editor.ActualHeight); - layer.CurrentInsertionPoint = newIndex; + layer.CurrentInsertionPointIndex = newIndex; layer.InvalidateVisual(); layer.ScrollToInsertionPoint(); }; @@ -224,9 +227,9 @@ namespace CSharpBinding.Refactoring { return (sender, e) => { if (up) - layer.CurrentInsertionPoint = 0; + layer.CurrentInsertionPointIndex = 0; else - layer.CurrentInsertionPoint = layer.insertionPoints.Length - 1; + layer.CurrentInsertionPointIndex = layer.insertionPoints.Length - 1; layer.InvalidateVisual(); layer.ScrollToInsertionPoint(); }; @@ -247,14 +250,14 @@ namespace CSharpBinding.Refactoring internal void ScrollToInsertionPoint() { - var location = insertionPoints[CurrentInsertionPoint].Location; + var location = insertionPoints[CurrentInsertionPointIndex].Location; editor.GetService().ScrollTo(location.Line, location.Column); SetGroupBoxPosition(); } void SetGroupBoxPosition() { - var boxPosition = GetLinePosition(CurrentInsertionPoint) + new Vector(editor.TextView.ActualWidth * 0.6 - 5, -groupBox.ActualHeight / 2.0); + var boxPosition = GetLinePosition(CurrentInsertionPointIndex) + new Vector(editor.TextView.ActualWidth * 0.6 - 5, -groupBox.ActualHeight / 2.0); Canvas.SetTop(groupBox, boxPosition.Y); Canvas.SetLeft(groupBox, boxPosition.X); } @@ -267,7 +270,7 @@ namespace CSharpBinding.Refactoring void FireExited(bool success) { if (Exited != null) { - Exited(this, new InsertionCursorEventArgs(insertionPoints[CurrentInsertionPoint], success)); + Exited(this, new InsertionCursorEventArgs(insertionPoints[CurrentInsertionPointIndex], success)); } } From 96fdb81cfb573245e07ea669dc7557ea76966741 Mon Sep 17 00:00:00 2001 From: Siegfried Pammer Date: Tue, 12 Aug 2014 22:43:17 +0200 Subject: [PATCH 2/5] fix #526: InsertWithCursor broken in Create Enum refactoring - Enum member is added properly --- .../Project/Src/Refactoring/EditorScript.cs | 22 ++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/src/AddIns/BackendBindings/CSharpBinding/Project/Src/Refactoring/EditorScript.cs b/src/AddIns/BackendBindings/CSharpBinding/Project/Src/Refactoring/EditorScript.cs index 450088e1af..02f9e05f70 100644 --- a/src/AddIns/BackendBindings/CSharpBinding/Project/Src/Refactoring/EditorScript.cs +++ b/src/AddIns/BackendBindings/CSharpBinding/Project/Src/Refactoring/EditorScript.cs @@ -173,19 +173,31 @@ namespace CSharpBinding.Refactoring args.InsertionPoint.LineBefore == NewLineInsertion.None && nodes.Count > 1) { args.InsertionPoint.LineAfter = NewLineInsertion.BlankLine; } + + var insertionPoint = args.InsertionPoint; + if (nodes.All(n => n is EnumMemberDeclaration)) { + insertionPoint.LineAfter = NewLineInsertion.Eol; + insertionPoint.LineBefore = NewLineInsertion.None; + } - int offset = currentScript.GetCurrentOffset(args.InsertionPoint.Location); + int offset = currentScript.GetCurrentOffset(insertionPoint.Location); int indentLevel = currentScript.GetIndentLevelAt(Math.Max(0, offset - 1)); foreach (var node in nodes.Reverse()) { var output = currentScript.OutputNode(indentLevel, node); var text = output.Text; - var insertionPoint = args.InsertionPoint; if (node is EnumMemberDeclaration) { - insertionPoint.LineAfter = NewLineInsertion.Eol; - insertionPoint.LineBefore = NewLineInsertion.None; - if (args.InsertionPoint != layer.InsertionPoints.Last()) { + if (insertionPoint != layer.InsertionPoints.Last()) { text += ","; + } else { + var parentEnum = currentScript.context.RootNode.GetNodeAt(insertionPoint.Location, n => (n is TypeDeclaration) && ((TypeDeclaration)n).ClassType == ClassType.Enum) as TypeDeclaration; + if (parentEnum != null) { + var lastMember = parentEnum.Members.LastOrDefault(); + if (lastMember != null) { + var segment = currentScript.GetSegment(lastMember); + currentScript.InsertText(segment.EndOffset, ","); + } + } } } int delta = insertionPoint.Insert(target, text); From 9424de8c9b72b780a20c2660477748e84263bcee Mon Sep 17 00:00:00 2001 From: Matt Ward Date: Wed, 13 Aug 2014 21:51:55 +0100 Subject: [PATCH 3/5] Fix PackageManagement.sln. Allow NuGet addin to be compiled and unit tests to be run separately. --- src/AddIns/Misc/PackageManagement/PackageManagement.sln | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/AddIns/Misc/PackageManagement/PackageManagement.sln b/src/AddIns/Misc/PackageManagement/PackageManagement.sln index 578325f1a9..4f16e63711 100644 --- a/src/AddIns/Misc/PackageManagement/PackageManagement.sln +++ b/src/AddIns/Misc/PackageManagement/PackageManagement.sln @@ -1,7 +1,7 @@  Microsoft Visual Studio Solution File, Format Version 11.00 # Visual Studio 2010 -# SharpDevelop 4.3 +# SharpDevelop 4.4 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PackageManagement", "Project\PackageManagement.csproj", "{AE4AB0FA-6087-4480-AF37-0FA1452B3DA1}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PackageManagement.Tests", "Test\PackageManagement.Tests.csproj", "{56E98A01-8398-4A08-9578-C7337711A52B}" @@ -85,7 +85,7 @@ Global {6C55B776-26D4-4DB3-A6AB-87E783B2F3D1}.Debug|Any CPU.Build.0 = Debug|Any CPU {6C55B776-26D4-4DB3-A6AB-87E783B2F3D1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {6C55B776-26D4-4DB3-A6AB-87E783B2F3D1}.Debug|Any CPU.Build.0 = Debug|Any CPU - {6C55B776-26D4-4DB3-A6AB-87E783B2F3D1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {6C55B776-26D4-4DB3-A6AB-87E783B2F3D1}.Debug|Any CPU.ActiveCfg = Debug|WithNRefactory {6C55B776-26D4-4DB3-A6AB-87E783B2F3D1}.Release|Any CPU.Build.0 = Release|Any CPU {6C55B776-26D4-4DB3-A6AB-87E783B2F3D1}.Release|Any CPU.ActiveCfg = Release|Any CPU {6C55B776-26D4-4DB3-A6AB-87E783B2F3D1}.Release|Any CPU.Build.0 = Release|Any CPU From 5a8f57f425e79e8ae57a9e026e3be80eef339210 Mon Sep 17 00:00:00 2001 From: Matt Ward Date: Wed, 13 Aug 2014 22:00:34 +0100 Subject: [PATCH 4/5] Support version constraints in packages.config file. NuGet allows you to define a range of package versions that are allowed in your project. http://docs.nuget.org/docs/reference/versioning This is done by editing the packages.config file and adding an allowedVersions attribute for the installed package. For example, the following restricts jQuery to be any version from 1.4 up to but not including version 1.8. The NuGet addin now supports this information when updating the package from the PowerShell console when using the Update-Package cmdlet when no version is specified. With the above example when updating jQuery the NuGet addin will now update to jQuery 1.7.2 and not the latest 2.1.1 version. Previously it would update to the latest version of the NuGet package. Note that if you search for another NuGet package and install a later version that is outside the allowed range it will still install. This is the same behaviour as Visual Studio. The allowedVersions attribute is to prevent you from accidentally updating the version but you can explicitly pick a later NuGet package and update to it with the Manage Packages dialog. --- .../Design/FakePackageManagementProject.cs | 9 +++++ .../Project/Src/IPackageManagementProject.cs | 2 + .../Project/Src/PackageManagementProject.cs | 10 +++++ .../Project/Src/ProcessPackageAction.cs | 9 +++-- .../Test/PackageManagement.Tests.csproj | 1 + ...PackageRepositoryWithConstraintProvider.cs | 39 +++++++++++++++++++ .../Test/Src/PackageManagementProjectTests.cs | 22 +++++++++++ .../Test/Src/UpdatePackageActionTests.cs | 23 +++++++++++ 8 files changed, 112 insertions(+), 3 deletions(-) create mode 100644 src/AddIns/Misc/PackageManagement/Test/Src/Helpers/FakePackageRepositoryWithConstraintProvider.cs diff --git a/src/AddIns/Misc/PackageManagement/Project/Src/Design/FakePackageManagementProject.cs b/src/AddIns/Misc/PackageManagement/Project/Src/Design/FakePackageManagementProject.cs index 489755c5c6..973b15ab92 100644 --- a/src/AddIns/Misc/PackageManagement/Project/Src/Design/FakePackageManagementProject.cs +++ b/src/AddIns/Misc/PackageManagement/Project/Src/Design/FakePackageManagementProject.cs @@ -39,6 +39,8 @@ namespace ICSharpCode.PackageManagement.Design FakeUninstallPackageAction = new FakeUninstallPackageAction(this); this.Name = name; + + ConstraintProvider = NullConstraintProvider.Instance; } private FakeInstallPackageAction FakeInstallPackageAction; @@ -232,6 +234,11 @@ namespace ICSharpCode.PackageManagement.Design FakeSourceRepository.AddFakePackage(packageId); } + public FakePackage AddFakePackageToSourceRepository(string packageId, string version) + { + return FakeSourceRepository.AddFakePackageWithVersion(packageId, version); + } + public void UpdatePackages(UpdatePackagesAction action) { } @@ -274,5 +281,7 @@ namespace ICSharpCode.PackageManagement.Design { throw new NotImplementedException(); } + + public IPackageConstraintProvider ConstraintProvider { get; set; } } } diff --git a/src/AddIns/Misc/PackageManagement/Project/Src/IPackageManagementProject.cs b/src/AddIns/Misc/PackageManagement/Project/Src/IPackageManagementProject.cs index d84c17d928..629e24c367 100644 --- a/src/AddIns/Misc/PackageManagement/Project/Src/IPackageManagementProject.cs +++ b/src/AddIns/Misc/PackageManagement/Project/Src/IPackageManagementProject.cs @@ -38,6 +38,8 @@ namespace ICSharpCode.PackageManagement Project ConvertToDTEProject(); + IPackageConstraintProvider ConstraintProvider { get; } + bool IsPackageInstalled(IPackage package); bool IsPackageInstalled(string packageId); bool HasOlderPackageInstalled(IPackage package); diff --git a/src/AddIns/Misc/PackageManagement/Project/Src/PackageManagementProject.cs b/src/AddIns/Misc/PackageManagement/Project/Src/PackageManagementProject.cs index 3d17b9a309..2b206d57bd 100644 --- a/src/AddIns/Misc/PackageManagement/Project/Src/PackageManagementProject.cs +++ b/src/AddIns/Misc/PackageManagement/Project/Src/PackageManagementProject.cs @@ -178,5 +178,15 @@ namespace ICSharpCode.PackageManagement { packageManager.UpdatePackageReference(package, settings); } + + public IPackageConstraintProvider ConstraintProvider { + get { + var constraintProvider = projectManager.LocalRepository as IPackageConstraintProvider; + if (constraintProvider != null) { + return constraintProvider; + } + return NullConstraintProvider.Instance; + } + } } } diff --git a/src/AddIns/Misc/PackageManagement/Project/Src/ProcessPackageAction.cs b/src/AddIns/Misc/PackageManagement/Project/Src/ProcessPackageAction.cs index 740b745ee1..07add3da31 100644 --- a/src/AddIns/Misc/PackageManagement/Project/Src/ProcessPackageAction.cs +++ b/src/AddIns/Misc/PackageManagement/Project/Src/ProcessPackageAction.cs @@ -134,9 +134,12 @@ namespace ICSharpCode.PackageManagement void FindPackage() { - Package = Project - .SourceRepository - .FindPackage(PackageId, PackageVersion, AllowPrereleaseVersions, allowUnlisted: false); + Package = Project.SourceRepository.FindPackage( + PackageId, + PackageVersion, + Project.ConstraintProvider, + AllowPrereleaseVersions, + allowUnlisted: false); } void ThrowPackageNotFoundError(string packageId) diff --git a/src/AddIns/Misc/PackageManagement/Test/PackageManagement.Tests.csproj b/src/AddIns/Misc/PackageManagement/Test/PackageManagement.Tests.csproj index 0a2c80e407..580664fc67 100644 --- a/src/AddIns/Misc/PackageManagement/Test/PackageManagement.Tests.csproj +++ b/src/AddIns/Misc/PackageManagement/Test/PackageManagement.Tests.csproj @@ -111,6 +111,7 @@ + diff --git a/src/AddIns/Misc/PackageManagement/Test/Src/Helpers/FakePackageRepositoryWithConstraintProvider.cs b/src/AddIns/Misc/PackageManagement/Test/Src/Helpers/FakePackageRepositoryWithConstraintProvider.cs new file mode 100644 index 0000000000..f83fd2881e --- /dev/null +++ b/src/AddIns/Misc/PackageManagement/Test/Src/Helpers/FakePackageRepositoryWithConstraintProvider.cs @@ -0,0 +1,39 @@ +// Copyright (c) 2014 AlphaSierraPapa for the SharpDevelop Team +// +// Permission is hereby granted, free of charge, to any person obtaining a copy of this +// software and associated documentation files (the "Software"), to deal in the Software +// without restriction, including without limitation the rights to use, copy, modify, merge, +// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons +// to whom the Software is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all copies or +// substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE +// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. + +using System; +using ICSharpCode.PackageManagement.Design; +using NuGet; + +namespace PackageManagement.Tests.Helpers +{ + public class FakePackageRepositoryWithConstraintProvider : FakePackageRepository, IPackageConstraintProvider + { + DefaultConstraintProvider constraintProvider = new DefaultConstraintProvider(); + + public IVersionSpec GetConstraint(string packageId) + { + return constraintProvider.GetConstraint(packageId); + } + + public void AddConstraint(string packageId, IVersionSpec versionSpec) + { + constraintProvider.AddConstraint (packageId, versionSpec); + } + } +} diff --git a/src/AddIns/Misc/PackageManagement/Test/Src/PackageManagementProjectTests.cs b/src/AddIns/Misc/PackageManagement/Test/Src/PackageManagementProjectTests.cs index c721492fd3..3c1c06b677 100644 --- a/src/AddIns/Misc/PackageManagement/Test/Src/PackageManagementProjectTests.cs +++ b/src/AddIns/Misc/PackageManagement/Test/Src/PackageManagementProjectTests.cs @@ -759,5 +759,27 @@ namespace PackageManagement.Tests Assert.AreEqual(package, fakePackageManager.PackagePassedToUpdatePackageReference); Assert.AreEqual(updatePackagesAction, fakePackageManager.SettingsPassedToUpdatePackageReference); } + + [Test] + public void ConstraintProvider_LocalRepositoryDoesNotImplementIConstraintProvider_ReturnsNullConstraintProviderInstance () + { + CreateProject (); + + IPackageConstraintProvider provider = project.ConstraintProvider; + + Assert.AreEqual (NullConstraintProvider.Instance, provider); + } + + [Test] + public void ConstraintProvider_LocalRepositoryImplementsIConstraintProvider_ReturnsLocalRepository () + { + CreateProject (); + var localRepository = new FakePackageRepositoryWithConstraintProvider (); + fakeProjectManager.FakeLocalRepository = localRepository; + + IPackageConstraintProvider provider = project.ConstraintProvider; + + Assert.AreEqual (localRepository, provider); + } } } diff --git a/src/AddIns/Misc/PackageManagement/Test/Src/UpdatePackageActionTests.cs b/src/AddIns/Misc/PackageManagement/Test/Src/UpdatePackageActionTests.cs index 2258dd1699..a4c5f15634 100644 --- a/src/AddIns/Misc/PackageManagement/Test/Src/UpdatePackageActionTests.cs +++ b/src/AddIns/Misc/PackageManagement/Test/Src/UpdatePackageActionTests.cs @@ -355,5 +355,28 @@ namespace PackageManagement.Tests Assert.AreEqual(expectedPackage, actualPackage); } + + [Test] + public void Execute_PackageHasConstraint_LatestPackageIsNotUpdatedButPackageWithHighestVersionThatMatchesConstraint () + { + CreateSolution (); + var constraintProvider = new DefaultConstraintProvider (); + var versionSpec = new VersionSpec (); + versionSpec.MinVersion = new SemanticVersion ("1.0"); + versionSpec.IsMinInclusive = true; + versionSpec.IsMaxInclusive = true; + versionSpec.MaxVersion = new SemanticVersion ("2.0"); + constraintProvider.AddConstraint ("MyPackage", versionSpec); + fakeProject.ConstraintProvider = constraintProvider; + fakeProject.AddFakePackageToSourceRepository ("MyPackage", "1.0"); + FakePackage packageVersion2 = fakeProject.AddFakePackageToSourceRepository ("MyPackage", "2.0"); + fakeProject.AddFakePackageToSourceRepository ("MyPackage", "3.0"); + fakeProject.FakePackages.Add (new FakePackage ("MyPackage", "1.0")); + action.PackageId = "MyPackage"; + + action.Execute (); + + Assert.AreEqual (packageVersion2, fakeProject.PackagePassedToUpdatePackage); + } } } From 2baac1b1c5c77435c38808e2eb8ba4868f25def2 Mon Sep 17 00:00:00 2001 From: Matt Ward Date: Wed, 13 Aug 2014 22:47:15 +0100 Subject: [PATCH 5/5] Use version constraints for updates shown in Manage Packages dialog. A version constraint defined in the packages.config file, as shown below, is now used when checking for package updates from a package source. Previously always the latest version of the NuGet package would be displayed as an update in the Manage Packages dialog. After updating to jQuery 1.7.2 then no further updates will be shown in the Manage Packages dialog. Currently this only works if a project is selected when the Manage Packages dialog is opened. --- .../Cmdlets/Project/Src/GetPackageCmdlet.cs | 2 +- .../Src/PackageManagementSelectedProjects.cs | 8 ++++ .../Project/Src/UpdatedPackages.cs | 21 +++++++--- .../Project/Src/UpdatedPackagesViewModel.cs | 2 +- .../Test/Src/UpdatedPackagesTests.cs | 41 ++++++++++++++++++- .../Test/Src/UpdatedPackagesViewModelTests.cs | 27 ++++++++++++ 6 files changed, 93 insertions(+), 8 deletions(-) diff --git a/src/AddIns/Misc/PackageManagement/Cmdlets/Project/Src/GetPackageCmdlet.cs b/src/AddIns/Misc/PackageManagement/Cmdlets/Project/Src/GetPackageCmdlet.cs index 74c4cfadf9..fdaac36cbb 100644 --- a/src/AddIns/Misc/PackageManagement/Cmdlets/Project/Src/GetPackageCmdlet.cs +++ b/src/AddIns/Misc/PackageManagement/Cmdlets/Project/Src/GetPackageCmdlet.cs @@ -200,7 +200,7 @@ namespace ICSharpCode.PackageManagement.Cmdlets if (project != null) { return new UpdatedPackages(project, repository); } - return new UpdatedPackages(GetPackagesInstalledIntoAnyProject(), repository); + return new UpdatedPackages(GetPackagesInstalledIntoAnyProject(), repository, NullConstraintProvider.Instance); } IQueryable GetPackagesInstalledIntoAnyProject() diff --git a/src/AddIns/Misc/PackageManagement/Project/Src/PackageManagementSelectedProjects.cs b/src/AddIns/Misc/PackageManagement/Project/Src/PackageManagementSelectedProjects.cs index f5cf048d2c..3e04227eec 100644 --- a/src/AddIns/Misc/PackageManagement/Project/Src/PackageManagementSelectedProjects.cs +++ b/src/AddIns/Misc/PackageManagement/Project/Src/PackageManagementSelectedProjects.cs @@ -157,5 +157,13 @@ namespace ICSharpCode.PackageManagement } return null; } + + public IPackageConstraintProvider GetConstraintProvider(IPackageRepository repository) + { + if (HasSingleProjectSelected()) { + return GetSingleProjectSelected(repository).ConstraintProvider; + } + return NullConstraintProvider.Instance; + } } } diff --git a/src/AddIns/Misc/PackageManagement/Project/Src/UpdatedPackages.cs b/src/AddIns/Misc/PackageManagement/Project/Src/UpdatedPackages.cs index 073b0cd7a4..730c64bcb5 100644 --- a/src/AddIns/Misc/PackageManagement/Project/Src/UpdatedPackages.cs +++ b/src/AddIns/Misc/PackageManagement/Project/Src/UpdatedPackages.cs @@ -29,22 +29,26 @@ namespace ICSharpCode.PackageManagement { IPackageRepository sourceRepository; IQueryable installedPackages; + IPackageConstraintProvider constraintProvider; public UpdatedPackages( IPackageManagementProject project, IPackageRepository aggregateRepository) : this( project.GetPackages(), - aggregateRepository) + aggregateRepository, + project.ConstraintProvider) { } public UpdatedPackages( IQueryable installedPackages, - IPackageRepository aggregrateRepository) + IPackageRepository aggregrateRepository, + IPackageConstraintProvider constraintProvider) { this.installedPackages = installedPackages; this.sourceRepository = aggregrateRepository; + this.constraintProvider = constraintProvider; } public string SearchTerms { get; set; } @@ -54,7 +58,7 @@ namespace ICSharpCode.PackageManagement IQueryable localPackages = installedPackages; localPackages = FilterPackages(localPackages); IEnumerable distinctLocalPackages = DistinctPackages(localPackages); - return GetUpdatedPackages(sourceRepository, distinctLocalPackages, includePrerelease); + return GetUpdatedPackages(distinctLocalPackages, includePrerelease); } IQueryable GetInstalledPackages() @@ -81,11 +85,18 @@ namespace ICSharpCode.PackageManagement } IEnumerable GetUpdatedPackages( - IPackageRepository sourceRepository, IEnumerable localPackages, bool includePrelease) { - return sourceRepository.GetUpdates(localPackages, includePrelease, false); + IEnumerable constraints = localPackages + .Select(package => constraintProvider.GetConstraint(package.Id)); + + return sourceRepository.GetUpdates( + localPackages, + includePrelease, + false, + null, + constraints); } } } diff --git a/src/AddIns/Misc/PackageManagement/Project/Src/UpdatedPackagesViewModel.cs b/src/AddIns/Misc/PackageManagement/Project/Src/UpdatedPackagesViewModel.cs index 933a33997b..e14001ae20 100644 --- a/src/AddIns/Misc/PackageManagement/Project/Src/UpdatedPackagesViewModel.cs +++ b/src/AddIns/Misc/PackageManagement/Project/Src/UpdatedPackagesViewModel.cs @@ -78,7 +78,7 @@ namespace ICSharpCode.PackageManagement try { IPackageRepository repository = RegisteredPackageRepositories.ActiveRepository; IQueryable installedPackages = GetInstalledPackages(repository); - updatedPackages = new UpdatedPackages(installedPackages, repository); + updatedPackages = new UpdatedPackages(installedPackages, repository, selectedProjects.GetConstraintProvider(repository)); } catch (Exception ex) { errorMessage = ex.Message; } diff --git a/src/AddIns/Misc/PackageManagement/Test/Src/UpdatedPackagesTests.cs b/src/AddIns/Misc/PackageManagement/Test/Src/UpdatedPackagesTests.cs index 41cde30364..34979f6dd2 100644 --- a/src/AddIns/Misc/PackageManagement/Test/Src/UpdatedPackagesTests.cs +++ b/src/AddIns/Misc/PackageManagement/Test/Src/UpdatedPackagesTests.cs @@ -20,7 +20,9 @@ using System; using System.Collections.Generic; using System.Linq; using System.Runtime.Versioning; + using ICSharpCode.PackageManagement; +using ICSharpCode.PackageManagement.Design; using NuGet; using NUnit.Framework; using PackageManagement.Tests.Helpers; @@ -37,6 +39,7 @@ namespace PackageManagement.Tests List sourceRepositoryPackages; List packagesUsedWhenCheckingForUpdates; bool includePreleaseUsedWhenCheckingForUpdates; + FakePackageManagementProject project; [SetUp] public void Init() @@ -66,7 +69,17 @@ namespace PackageManagement.Tests }) .Return(sourceRepositoryPackages.AsQueryable()); - updatedPackages = new UpdatedPackages(installedPackages.AsQueryable(), sourceRepository); + updatedPackages = new UpdatedPackages(installedPackages.AsQueryable(), sourceRepository, NullConstraintProvider.Instance); + } + + void CreateProject() + { + project = new FakePackageManagementProject(); + } + + void CreateUpdatedPackages(IPackageRepository repository) + { + updatedPackages = new UpdatedPackages(project, repository); } IPackage AddPackageToSourceRepository(string id, string version) @@ -166,5 +179,31 @@ namespace PackageManagement.Tests Assert.IsFalse(includePreleaseUsedWhenCheckingForUpdates); } + + [Test] + public void GetUpdatedPackages_OnePackageReferencedWithConstraintAndUpdatesAvailable_LatestVersionReturnedBasedOnConstraint() + { + CreateProject(); + project.FakePackages.Add(new FakePackage("Test", "1.0")); + var sourceRepository = new FakePackageRepository(); + FakePackage packageVersion2 = sourceRepository.AddFakePackageWithVersion("Test", "2.0"); + FakePackage [] expectedPackages = new [] { + packageVersion2 + }; + sourceRepository.AddFakePackageWithVersion("Test", "3.0"); + var versionSpec = new VersionSpec(); + versionSpec.MinVersion = new SemanticVersion("1.0"); + versionSpec.IsMinInclusive = true; + versionSpec.MaxVersion = new SemanticVersion("2.0"); + versionSpec.IsMaxInclusive = true; + var constraintProvider = new DefaultConstraintProvider(); + constraintProvider.AddConstraint("Test", versionSpec); + project.ConstraintProvider = constraintProvider; + CreateUpdatedPackages(sourceRepository); + + IEnumerable packages = updatedPackages.GetUpdatedPackages(); + + PackageCollectionAssert.AreEqual(expectedPackages, packages); + } } } diff --git a/src/AddIns/Misc/PackageManagement/Test/Src/UpdatedPackagesViewModelTests.cs b/src/AddIns/Misc/PackageManagement/Test/Src/UpdatedPackagesViewModelTests.cs index 01a9c34832..0bec90135f 100644 --- a/src/AddIns/Misc/PackageManagement/Test/Src/UpdatedPackagesViewModelTests.cs +++ b/src/AddIns/Misc/PackageManagement/Test/Src/UpdatedPackagesViewModelTests.cs @@ -787,5 +787,32 @@ namespace PackageManagement.Tests operationAwareRepository.AssertOperationWasStartedAndDisposed(RepositoryOperationNames.Update, null); } + + [Test] + public void ReadPackages_TwoPackagesInSourceRepositoryAndTwoNewerPackageVersionAvailableAndProjectHasConstraint_NewerPackageVersionThatMeetsConstraintIsDisplayed() + { + CreateViewModel(); + var versionSpec = new VersionSpec(); + versionSpec.MinVersion = new SemanticVersion("1.0"); + versionSpec.IsMinInclusive = true; + versionSpec.MaxVersion = new SemanticVersion("2.0"); + versionSpec.IsMaxInclusive = true; + var constraintProvider = new DefaultConstraintProvider(); + constraintProvider.AddConstraint("Test", versionSpec); + solution.FakeProjectToReturnFromGetProject.ConstraintProvider = constraintProvider; + AddPackageToLocalRepository("Test", "1.0.0.0"); + AddPackageToActiveRepository("Test", "1.0.0.0"); + FakePackage expectedPackage = AddPackageToActiveRepository("Test", "2.0.0.0"); + AddPackageToActiveRepository("Test", "3.0.0.0"); + + viewModel.ReadPackages(); + CompleteReadPackagesTask(); + + var expectedPackages = new FakePackage[] { + expectedPackage + }; + + PackageCollectionAssert.AreEqual(expectedPackages, viewModel.PackageViewModels); + } } }