diff options
author | Matt Ward <matt.ward@xamarin.com> | 2015-07-03 18:12:35 +0300 |
---|---|---|
committer | Matt Ward <matt.ward@xamarin.com> | 2015-07-03 18:58:45 +0300 |
commit | 1486b7fc4886056e888469403a6497cfb05b2a4c (patch) | |
tree | a5d4c92a941790ddccd7b255b13878c986c78769 /main/src/addins/MonoDevelop.PackageManagement | |
parent | f2bc648b62b29f88c51fa74ef41fd3d40c4361e9 (diff) |
[NuGet] Fix package compatibility check when multiple solutions open.
Previously if multiple solutions were open in the workspace then
changing the project's target framework would not work in a solution
after one of the solutions are closed. All the event handlers were
removed for all projects. Also when the target framework was changed
in the project file outside of the IDE the package compatibility check
would not be run. This was because event handlers for the solution's
SolutionItemAdded event were removed.
Diffstat (limited to 'main/src/addins/MonoDevelop.PackageManagement')
6 files changed, 163 insertions, 37 deletions
diff --git a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.Tests/MonoDevelop.PackageManagement.Tests.Helpers/FakePackageManagementProjectService.cs b/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.Tests/MonoDevelop.PackageManagement.Tests.Helpers/FakePackageManagementProjectService.cs index a562f08514..c6af0cadd1 100644 --- a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.Tests/MonoDevelop.PackageManagement.Tests.Helpers/FakePackageManagementProjectService.cs +++ b/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.Tests/MonoDevelop.PackageManagement.Tests.Helpers/FakePackageManagementProjectService.cs @@ -75,15 +75,25 @@ namespace MonoDevelop.PackageManagement.Tests.Helpers public void RaiseSolutionLoadedEvent ()
{
+ RaiseSolutionLoadedEvent (new FakeSolution ());
+ }
+
+ public void RaiseSolutionLoadedEvent (ISolution solution)
+ {
if (SolutionLoaded != null) {
- SolutionLoaded (this, new EventArgs ());
+ SolutionLoaded (this, new SolutionEventArgs (solution));
}
}
public void RaiseSolutionUnloadedEvent ()
{
+ RaiseSolutionUnloadedEvent (new FakeSolution ());
+ }
+
+ public void RaiseSolutionUnloadedEvent (ISolution solution)
+ {
if (SolutionUnloaded != null) {
- SolutionUnloaded (this, new EventArgs ());
+ SolutionUnloaded (this, new SolutionEventArgs (solution));
}
}
diff --git a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.Tests/MonoDevelop.PackageManagement.Tests/ProjectTargetFrameworkMonitorTests.cs b/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.Tests/MonoDevelop.PackageManagement.Tests/ProjectTargetFrameworkMonitorTests.cs index 9d4ffd32ae..2286de495b 100644 --- a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.Tests/MonoDevelop.PackageManagement.Tests/ProjectTargetFrameworkMonitorTests.cs +++ b/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.Tests/MonoDevelop.PackageManagement.Tests/ProjectTargetFrameworkMonitorTests.cs @@ -39,6 +39,7 @@ namespace MonoDevelop.PackageManagement.Tests FakePackageManagementProjectService projectService;
List<ProjectTargetFrameworkChangedEventArgs> eventArgs;
FakeSolution solution;
+ int solutionCount;
const string targetFrameworkPropertyName = "TargetFramework";
void CreateProjectTargetFrameworkMonitor ()
@@ -50,12 +51,14 @@ namespace MonoDevelop.PackageManagement.Tests FakeDotNetProject LoadSolutionWithOneProject ()
{
- solution = new FakeSolution ();
+ solutionCount++;
+ string fileName = String.Format (@"d:\projects\MySolution\MySolution{0}.sln", solutionCount);
+ solution = new FakeSolution (fileName);
projectService.OpenSolution = solution;
var project = new FakeDotNetProject ();
projectService.OpenProjects.Add (project);
solution.Projects.Add (project);
- projectService.RaiseSolutionLoadedEvent ();
+ projectService.RaiseSolutionLoadedEvent (solution);
return project;
}
@@ -69,7 +72,12 @@ namespace MonoDevelop.PackageManagement.Tests void UnloadSolution ()
{
- projectService.RaiseSolutionUnloadedEvent ();
+ UnloadSolution (solution);
+ }
+
+ void UnloadSolution (FakeSolution solutionToUnload)
+ {
+ projectService.RaiseSolutionUnloadedEvent (solutionToUnload);
}
FakeDotNetProject AddNewProjectToSolution ()
@@ -250,6 +258,58 @@ namespace MonoDevelop.PackageManagement.Tests Assert.DoesNotThrow (UnloadSolution);
}
+
+ [Test]
+ public void ProjectModified_TwoSolutionsLoadedProjectTargetFrameworkChangedInFirstAndSecondSolution_EventFiresForBothProjects ()
+ {
+ CreateProjectTargetFrameworkMonitor ();
+ FakeDotNetProject firstProject = LoadSolutionWithOneProject ();
+ projectService.OpenProjects.Clear ();
+ FakeDotNetProject secondProject = LoadSolutionWithOneProject ();
+ CaptureProjectTargetFrameworkChangedEvents ();
+
+ firstProject.RaiseModifiedEvent (firstProject, targetFrameworkPropertyName);
+ secondProject.RaiseModifiedEvent (secondProject, targetFrameworkPropertyName);
+
+ Assert.AreEqual (2, eventArgs.Count);
+ Assert.AreEqual (firstProject, eventArgs [0].Project);
+ Assert.AreEqual (secondProject, eventArgs [1].Project);
+ }
+
+ [Test]
+ public void ProjectModified_TwoSolutionsLoadedSecondSolutionUnloadedProjectTargetFrameworkChangedInFirstAndSecondSolution_EventFiresForProjectInOpenSolutionOnly ()
+ {
+ CreateProjectTargetFrameworkMonitor ();
+ FakeDotNetProject firstProject = LoadSolutionWithOneProject ();
+ projectService.OpenProjects.Clear ();
+ FakeDotNetProject secondProject = LoadSolutionWithOneProject ();
+ CaptureProjectTargetFrameworkChangedEvents ();
+ UnloadSolution ();
+
+ firstProject.RaiseModifiedEvent (firstProject, targetFrameworkPropertyName);
+ secondProject.RaiseModifiedEvent (secondProject, targetFrameworkPropertyName);
+
+ Assert.AreEqual (1, eventArgs.Count);
+ Assert.AreEqual (firstProject, eventArgs [0].Project);
+ }
+
+ [Test]
+ public void ProjectModified_TwoSolutionsLoadedFirstSolutionUnloadedProjectTargetFrameworkChangedInFirstAndSecondSolution_EventFiresForProjectInOpenSolutionOnly ()
+ {
+ CreateProjectTargetFrameworkMonitor ();
+ FakeDotNetProject firstProject = LoadSolutionWithOneProject ();
+ FakeSolution firstSolution = new FakeSolution (solution.FileName);
+ projectService.OpenProjects.Clear ();
+ FakeDotNetProject secondProject = LoadSolutionWithOneProject ();
+ CaptureProjectTargetFrameworkChangedEvents ();
+ UnloadSolution (firstSolution);
+
+ firstProject.RaiseModifiedEvent (firstProject, targetFrameworkPropertyName);
+ secondProject.RaiseModifiedEvent (secondProject, targetFrameworkPropertyName);
+
+ Assert.AreEqual (1, eventArgs.Count);
+ Assert.AreEqual (secondProject, eventArgs [0].Project);
+ }
}
}
diff --git a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.csproj b/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.csproj index 7ca4e806da..dba06a7ba1 100644 --- a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.csproj +++ b/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.csproj @@ -373,6 +373,7 @@ <Compile Include="MonoDevelop.PackageManagement\NullOpenPackageReadMeMonitor.cs" /> <Compile Include="MonoDevelop.PackageManagement\DotNetProjectReferenceEventArgs.cs" /> <Compile Include="MonoDevelop.PackageManagement\LocalCopyReferenceMaintainer.cs" /> + <Compile Include="MonoDevelop.PackageManagement\SolutionEventArgs.cs" /> </ItemGroup> <ItemGroup> <EmbeddedResource Include="MonoDevelop.PackageManagement.addin.xml" /> diff --git a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement/PackageManagementProjectService.cs b/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement/PackageManagementProjectService.cs index 9a1aa7aebb..f00e30270e 100644 --- a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement/PackageManagementProjectService.cs +++ b/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement/PackageManagementProjectService.cs @@ -28,7 +28,6 @@ using System;
using System.Collections.Generic;
-using System.Linq;
using MonoDevelop.Ide;
using MonoDevelop.PackageManagement;
using MonoDevelop.Projects;
@@ -40,32 +39,35 @@ namespace ICSharpCode.PackageManagement public PackageManagementProjectService ()
{
IdeApp.Workspace.SolutionLoaded += (sender, e) => OnSolutionLoaded (e.Solution);
- IdeApp.Workspace.SolutionUnloaded += (sender, e) => OnSolutionUnloaded ();
+ IdeApp.Workspace.SolutionUnloaded += (sender, e) => OnSolutionUnloaded (e.Solution);
}
public event EventHandler SolutionLoaded;
- ISolution openSolution;
void OnSolutionLoaded (Solution solution)
{
+ solution.SolutionItemAdded += SolutionItemAdded;
+
OpenSolution = new SolutionProxy (solution);
EventHandler handler = SolutionLoaded;
if (handler != null) {
- handler (this, new EventArgs ());
+ handler (this, new MonoDevelop.PackageManagement.SolutionEventArgs (OpenSolution));
}
}
public event EventHandler SolutionUnloaded;
- void OnSolutionUnloaded ()
+ void OnSolutionUnloaded (Solution solution)
{
+ solution.SolutionItemAdded -= SolutionItemAdded;
OpenSolution = null;
var handler = SolutionUnloaded;
if (handler != null) {
- handler (this, new EventArgs ());
+ var proxy = new SolutionProxy (solution);
+ handler (this, new MonoDevelop.PackageManagement.SolutionEventArgs (proxy));
}
}
@@ -82,21 +84,7 @@ namespace ICSharpCode.PackageManagement }
}
- public ISolution OpenSolution {
- get { return openSolution; }
-
- private set {
- if (openSolution != null) {
- openSolution.Solution.SolutionItemAdded -= SolutionItemAdded;
- }
-
- openSolution = value;
-
- if (openSolution != null) {
- openSolution.Solution.SolutionItemAdded += SolutionItemAdded;
- }
- }
- }
+ public ISolution OpenSolution { get; private set; }
public IEnumerable<IDotNetProject> GetOpenProjects ()
{
diff --git a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement/ProjectTargetFrameworkMonitor.cs b/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement/ProjectTargetFrameworkMonitor.cs index c9985ec485..0f68a7f6b6 100644 --- a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement/ProjectTargetFrameworkMonitor.cs +++ b/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement/ProjectTargetFrameworkMonitor.cs @@ -28,15 +28,13 @@ using System; using System.Collections.Generic;
using ICSharpCode.PackageManagement;
using System.Linq;
-using MonoDevelop.Projects;
namespace MonoDevelop.PackageManagement
{
public class ProjectTargetFrameworkMonitor
{
IPackageManagementProjectService projectService;
- ISolution solution;
- List<IDotNetProject> projects = new List<IDotNetProject> ();
+ List<MonitoredSolution> monitoredSolutions = new List<MonitoredSolution> ();
public ProjectTargetFrameworkMonitor (IPackageManagementProjectService projectService)
{
@@ -59,33 +57,54 @@ namespace MonoDevelop.PackageManagement void SolutionUnloaded (object sender, EventArgs e)
{
- if (solution == null)
+ MonitoredSolution monitoredSolution = FindMonitoredSolution ((SolutionEventArgs)e);
+ if (monitoredSolution == null)
return;
- foreach (IDotNetProject project in projects) {
+ foreach (IDotNetProject project in monitoredSolution.Projects) {
project.Modified -= ProjectModified;
}
- projects.Clear ();
+ monitoredSolution.Projects.Clear ();
+
+ monitoredSolution.Solution.ProjectAdded -= ProjectAdded;
+ monitoredSolutions.Remove (monitoredSolution);
+ }
+
+ MonitoredSolution FindMonitoredSolution (SolutionEventArgs eventArgs)
+ {
+ return FindMonitoredSolution (eventArgs.Solution);
+ }
- solution.ProjectAdded -= ProjectAdded;
- solution = null;
+ MonitoredSolution FindMonitoredSolution (ISolution solutionToMatch)
+ {
+ if (monitoredSolutions.Count == 1)
+ return monitoredSolutions [0];
+
+ return monitoredSolutions.FirstOrDefault (monitoredSolution => monitoredSolution.Solution.FileName == solutionToMatch.FileName);
}
void SolutionLoaded (object sender, EventArgs e)
{
- solution = projectService.OpenSolution;
+ var solutionEventArgs = (SolutionEventArgs)e;
+ ISolution solution = solutionEventArgs.Solution;
solution.ProjectAdded += ProjectAdded;
- projects = projectService.GetOpenProjects ().ToList ();
+ List<IDotNetProject> projects = solution.GetAllProjects ().ToList ();
foreach (IDotNetProject project in projects) {
project.Modified += ProjectModified;
}
+
+ monitoredSolutions.Add (new MonitoredSolution {
+ Solution = solution,
+ Projects = projects
+ });
}
void ProjectAdded (object sender, DotNetProjectEventArgs e)
{
+ MonitoredSolution monitoredSolution = FindMonitoredSolution ((ISolution)sender);
e.Project.Modified += ProjectModified;
- projects.Add (e.Project);
+ monitoredSolution.Projects.Add (e.Project);
}
void ProjectModified (object sender, ProjectModifiedEventArgs e)
@@ -109,6 +128,13 @@ namespace MonoDevelop.PackageManagement }
return false;
}
+
+ class MonitoredSolution
+ {
+ public ISolution Solution { get; set; }
+ public EventHandler<DotNetProjectEventArgs> ProjectAddedHandler { get; set; }
+ public List<IDotNetProject> Projects { get; set; }
+ }
}
}
diff --git a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement/SolutionEventArgs.cs b/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement/SolutionEventArgs.cs new file mode 100644 index 0000000000..5cca680748 --- /dev/null +++ b/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement/SolutionEventArgs.cs @@ -0,0 +1,41 @@ +//
+// SolutionEventArgs.cs
+//
+// Author:
+// Matt Ward <matt.ward@xamarin.com>
+//
+// Copyright (c) 2015 Xamarin Inc. (http://xamarin.com)
+//
+// 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;
+
+namespace MonoDevelop.PackageManagement
+{
+ public class SolutionEventArgs : EventArgs
+ {
+ public SolutionEventArgs (ISolution solution)
+ {
+ Solution = solution;
+ }
+
+ public ISolution Solution { get; private set; }
+ }
+}
+
|