diff --git a/src/AddIns/Misc/PackageManagement/Project/PackageManagement.csproj b/src/AddIns/Misc/PackageManagement/Project/PackageManagement.csproj
index cee6ae3b57..1f8d7e8de0 100644
--- a/src/AddIns/Misc/PackageManagement/Project/PackageManagement.csproj
+++ b/src/AddIns/Misc/PackageManagement/Project/PackageManagement.csproj
@@ -78,6 +78,7 @@
+
@@ -147,6 +148,7 @@
+
@@ -218,6 +220,7 @@
+
diff --git a/src/AddIns/Misc/PackageManagement/Project/Src/Design/FakePackageManagementProjectService.cs b/src/AddIns/Misc/PackageManagement/Project/Src/Design/FakePackageManagementProjectService.cs
index 2c8390a1ab..af3a2d168d 100644
--- a/src/AddIns/Misc/PackageManagement/Project/Src/Design/FakePackageManagementProjectService.cs
+++ b/src/AddIns/Misc/PackageManagement/Project/Src/Design/FakePackageManagementProjectService.cs
@@ -114,5 +114,11 @@ namespace ICSharpCode.PackageManagement.Design
}
return String.Empty;
}
+
+ public FakeProjectBuilder FakeProjectBuilder = new FakeProjectBuilder();
+
+ public IProjectBuilder ProjectBuilder {
+ get { return FakeProjectBuilder; }
+ }
}
}
diff --git a/src/AddIns/Misc/PackageManagement/Project/Src/Design/FakeProjectBuilder.cs b/src/AddIns/Misc/PackageManagement/Project/Src/Design/FakeProjectBuilder.cs
new file mode 100644
index 0000000000..d343f06786
--- /dev/null
+++ b/src/AddIns/Misc/PackageManagement/Project/Src/Design/FakeProjectBuilder.cs
@@ -0,0 +1,25 @@
+// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
+// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
+
+using System;
+using ICSharpCode.SharpDevelop.Project;
+
+namespace ICSharpCode.PackageManagement.Design
+{
+ public class FakeProjectBuilder : IProjectBuilder
+ {
+ public FakeProjectBuilder()
+ {
+ BuildResults = new BuildResults();
+ }
+
+ public IProject ProjectPassedToBuild;
+
+ public BuildResults BuildResults { get; set; }
+
+ public void Build(IProject project)
+ {
+ ProjectPassedToBuild = project;
+ }
+ }
+}
diff --git a/src/AddIns/Misc/PackageManagement/Project/Src/EnvDTE/Solution.cs b/src/AddIns/Misc/PackageManagement/Project/Src/EnvDTE/Solution.cs
index e1d26cca24..81ad82c752 100644
--- a/src/AddIns/Misc/PackageManagement/Project/Src/EnvDTE/Solution.cs
+++ b/src/AddIns/Misc/PackageManagement/Project/Src/EnvDTE/Solution.cs
@@ -19,6 +19,7 @@ namespace ICSharpCode.PackageManagement.EnvDTE
this.solution = projectService.OpenSolution;
this.Projects = new Projects(projectService);
this.Globals = new SolutionGlobals(this);
+ this.SolutionBuild = new SolutionBuild(this, projectService.ProjectBuilder);
CreateProperties();
}
@@ -63,10 +64,7 @@ namespace ICSharpCode.PackageManagement.EnvDTE
return null;
}
- public global::EnvDTE.SolutionBuild SolutionBuild {
- get { return new SolutionBuild(this); }
- }
-
+ public global::EnvDTE.SolutionBuild SolutionBuild { get; private set; }
public global::EnvDTE.Properties Properties { get; private set; }
internal Project GetStartupProject()
diff --git a/src/AddIns/Misc/PackageManagement/Project/Src/EnvDTE/SolutionBuild.cs b/src/AddIns/Misc/PackageManagement/Project/Src/EnvDTE/SolutionBuild.cs
index 67d82fc0b2..5d47d72a70 100644
--- a/src/AddIns/Misc/PackageManagement/Project/Src/EnvDTE/SolutionBuild.cs
+++ b/src/AddIns/Misc/PackageManagement/Project/Src/EnvDTE/SolutionBuild.cs
@@ -2,6 +2,7 @@
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
using System;
+using ICSharpCode.SharpDevelop.Project;
using ICSharpCode.SharpDevelop.Project.Commands;
namespace ICSharpCode.PackageManagement.EnvDTE
@@ -9,14 +10,17 @@ namespace ICSharpCode.PackageManagement.EnvDTE
public class SolutionBuild : MarshalByRefObject, global::EnvDTE.SolutionBuild
{
Solution solution;
+ IProjectBuilder projectBuilder;
+ int lastBuildInfo;
public SolutionBuild()
{
}
- public SolutionBuild(Solution solution)
+ public SolutionBuild(Solution solution, IProjectBuilder projectBuilder)
{
this.solution = solution;
+ this.projectBuilder = projectBuilder;
}
public global::EnvDTE.SolutionConfiguration ActiveConfiguration {
@@ -27,11 +31,23 @@ namespace ICSharpCode.PackageManagement.EnvDTE
/// Returns the number of projects that failed to build.
///
public int LastBuildInfo {
- get { return 0; }
+ get { return lastBuildInfo; }
}
public void BuildProject(string solutionConfiguration, string projectUniqueName, bool waitForBuildToFinish)
{
+ Project project = solution.Projects.Item(projectUniqueName) as Project;
+ projectBuilder.Build(project.MSBuildProject);
+ UpdateLastBuildInfo(projectBuilder.BuildResults);
+ }
+
+ void UpdateLastBuildInfo(BuildResults buildResults)
+ {
+ if (buildResults.ErrorCount > 0) {
+ lastBuildInfo = 1;
+ } else {
+ lastBuildInfo = 0;
+ }
}
public object StartupProjects {
diff --git a/src/AddIns/Misc/PackageManagement/Project/Src/IPackageManagementProjectService.cs b/src/AddIns/Misc/PackageManagement/Project/Src/IPackageManagementProjectService.cs
index f6b5267be1..45da1d59bd 100644
--- a/src/AddIns/Misc/PackageManagement/Project/Src/IPackageManagementProjectService.cs
+++ b/src/AddIns/Misc/PackageManagement/Project/Src/IPackageManagementProjectService.cs
@@ -12,6 +12,7 @@ namespace ICSharpCode.PackageManagement
{
IProject CurrentProject { get; }
Solution OpenSolution { get; }
+ IProjectBuilder ProjectBuilder { get; }
event ProjectEventHandler ProjectAdded;
event SolutionFolderEventHandler SolutionFolderRemoved;
diff --git a/src/AddIns/Misc/PackageManagement/Project/Src/IProjectBuilder.cs b/src/AddIns/Misc/PackageManagement/Project/Src/IProjectBuilder.cs
new file mode 100644
index 0000000000..6fca66a6d2
--- /dev/null
+++ b/src/AddIns/Misc/PackageManagement/Project/Src/IProjectBuilder.cs
@@ -0,0 +1,18 @@
+// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
+// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
+
+using System;
+using ICSharpCode.SharpDevelop.Project;
+
+namespace ICSharpCode.PackageManagement
+{
+ public interface IProjectBuilder
+ {
+ BuildResults BuildResults { get; }
+
+ ///
+ /// Builds the project and waits for the build to complete.
+ ///
+ void Build(IProject project);
+ }
+}
diff --git a/src/AddIns/Misc/PackageManagement/Project/Src/PackageManagementProjectService.cs b/src/AddIns/Misc/PackageManagement/Project/Src/PackageManagementProjectService.cs
index b0acff35dd..baf44547c4 100644
--- a/src/AddIns/Misc/PackageManagement/Project/Src/PackageManagementProjectService.cs
+++ b/src/AddIns/Misc/PackageManagement/Project/Src/PackageManagementProjectService.cs
@@ -15,6 +15,11 @@ namespace ICSharpCode.PackageManagement
{
public class PackageManagementProjectService : IPackageManagementProjectService
{
+ public PackageManagementProjectService()
+ {
+ ProjectBuilder = new ProjectBuilder();
+ }
+
public IProject CurrentProject {
get { return ProjectService.CurrentProject; }
}
@@ -23,6 +28,8 @@ namespace ICSharpCode.PackageManagement
get { return ProjectService.OpenSolution; }
}
+ public IProjectBuilder ProjectBuilder { get; private set; }
+
public void RefreshProjectBrowser()
{
if (WorkbenchSingleton.InvokeRequired) {
diff --git a/src/AddIns/Misc/PackageManagement/Project/Src/ProjectBuilder.cs b/src/AddIns/Misc/PackageManagement/Project/Src/ProjectBuilder.cs
new file mode 100644
index 0000000000..2f9559af87
--- /dev/null
+++ b/src/AddIns/Misc/PackageManagement/Project/Src/ProjectBuilder.cs
@@ -0,0 +1,50 @@
+// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
+// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
+
+using System;
+using System.Linq;
+using System.Threading;
+using ICSharpCode.SharpDevelop.Gui;
+using ICSharpCode.SharpDevelop.Project;
+using ICSharpCode.SharpDevelop.Project.Commands;
+
+namespace ICSharpCode.PackageManagement
+{
+ public class ProjectBuilder : IProjectBuilder
+ {
+ ManualResetEvent buildCompleteEvent = new ManualResetEvent(false);
+ TimeSpan DefaultBuildTimeout = new TimeSpan(0, 5, 0);
+
+ public ProjectBuilder()
+ {
+ }
+
+ public BuildResults BuildResults { get; private set; }
+
+ public void Build(IProject project)
+ {
+ var build = new BuildProject(project);
+ build.BuildComplete += BuildComplete;
+ buildCompleteEvent.Reset();
+ WorkbenchSingleton.SafeThreadAsyncCall(() => build.Run());
+ if (buildCompleteEvent.WaitOne(DefaultBuildTimeout)) {
+ BuildResults = build.LastBuildResults;
+ } else {
+ BuildResults = GetBuildTimeoutResult();
+ }
+ build.BuildComplete -= BuildComplete;
+ }
+
+ BuildResults GetBuildTimeoutResult()
+ {
+ var results = new BuildResults { Result = BuildResultCode.Error };
+ results.Add(new BuildError(String.Empty, "Timed out waiting for build to complete."));
+ return results;
+ }
+
+ void BuildComplete(object sender, EventArgs e)
+ {
+ buildCompleteEvent.Set();
+ }
+ }
+}
diff --git a/src/AddIns/Misc/PackageManagement/Test/Src/EnvDTE/SolutionBuildTests.cs b/src/AddIns/Misc/PackageManagement/Test/Src/EnvDTE/SolutionBuildTests.cs
index 813fde117a..622d4099c2 100644
--- a/src/AddIns/Misc/PackageManagement/Test/Src/EnvDTE/SolutionBuildTests.cs
+++ b/src/AddIns/Misc/PackageManagement/Test/Src/EnvDTE/SolutionBuildTests.cs
@@ -2,6 +2,8 @@
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
using System;
+using ICSharpCode.PackageManagement;
+using ICSharpCode.PackageManagement.Design;
using ICSharpCode.PackageManagement.EnvDTE;
using NUnit.Framework;
using PackageManagement.Tests.Helpers;
@@ -14,11 +16,13 @@ namespace PackageManagement.Tests.EnvDTE
SolutionHelper solutionHelper;
Solution solution;
SolutionBuild solutionBuild;
+ FakeProjectBuilder projectBuilder;
void CreateSolutionBuild()
{
solutionHelper = new SolutionHelper();
solution = solutionHelper.Solution;
+ projectBuilder = solutionHelper.FakeProjectService.FakeProjectBuilder;
solutionBuild = (SolutionBuild)solution.SolutionBuild;
}
@@ -39,6 +43,29 @@ namespace PackageManagement.Tests.EnvDTE
solutionHelper.SetActiveConfiguration(name);
}
+ void BuildProjectResultHasBuildError()
+ {
+ var error = new ICSharpCode.SharpDevelop.Project.BuildError();
+ projectBuilder.BuildResults.Add(error);
+ }
+
+ void BuildProjectFails()
+ {
+ CreateSolutionBuild(@"d:\projects\MyProject\MySolution.sln");
+ string projectFileName = @"d:\projects\MyProject\MyProject.csproj";
+ solutionHelper.AddProjectToSolutionWithFileName("MyProject", projectFileName);
+ BuildProjectResultHasBuildError();
+ solutionBuild.BuildProject("Debug", "MyProject.csproj", true);
+ }
+
+ void BuildProjectSucceeds()
+ {
+ CreateSolutionBuild(@"d:\projects\MyProject\MySolution.sln");
+ string projectFileName = @"d:\projects\MyProject\MyProject.csproj";
+ solutionHelper.AddProjectToSolutionWithFileName("MyProject", projectFileName);
+ solutionBuild.BuildProject("Debug", "MyProject.csproj", true);
+ }
+
[Test]
public void StartupProjects_SolutionHasNoProjects_ReturnsEmptyArray()
{
@@ -73,5 +100,72 @@ namespace PackageManagement.Tests.EnvDTE
Assert.AreEqual("Debug", name);
}
+
+ [Test]
+ public void BuildProject_OneProjectInSolutionAndUniqueNameMatchesProject_ProjectPassedToProjectBuilder()
+ {
+ CreateSolutionBuild(@"d:\projects\MyProject\MySolution.sln");
+ string projectFileName = @"d:\projects\MyProject\MyProject.csproj";
+ TestableProject expectedProject = solutionHelper.AddProjectToSolutionWithFileName("MyProject", projectFileName);
+
+ solutionBuild.BuildProject("Debug", "MyProject.csproj", true);
+
+ Assert.AreEqual(expectedProject, projectBuilder.ProjectPassedToBuild);
+ }
+
+ [Test]
+ public void BuildProject_ProjectIsSecondProjectInSolution_CorrectProjectPassedToProjectBuilder()
+ {
+ CreateSolutionBuild(@"d:\projects\MyProject\MySolution.sln");
+ solutionHelper.AddProjectToSolution("FirstProject");
+ string projectFileName = @"d:\projects\MyProject\MyProject.csproj";
+ TestableProject expectedProject = solutionHelper.AddProjectToSolutionWithFileName("MyProject", projectFileName);
+
+ solutionBuild.BuildProject("Debug", "MyProject.csproj", true);
+
+ Assert.AreEqual(expectedProject, projectBuilder.ProjectPassedToBuild);
+ }
+
+ [Test]
+ public void BuildProject_OneProjectInSubFolderInsideSolutionFolderAndUniqueNameMatchesProject_ProjectPassedToProjectBuilder()
+ {
+ CreateSolutionBuild(@"d:\projects\MyProject\MySolution.sln");
+ string projectFileName = @"d:\projects\MyProject\SubFolder\MyProject.csproj";
+ TestableProject expectedProject = solutionHelper.AddProjectToSolutionWithFileName("MyProject", projectFileName);
+
+ solutionBuild.BuildProject("Debug", @"SubFolder\MyProject.csproj", true);
+
+ Assert.AreEqual(expectedProject, projectBuilder.ProjectPassedToBuild);
+ }
+
+ [Test]
+ public void LastBuildInfo_BuildProjectFails_LastBuildInfoIsOne()
+ {
+ BuildProjectFails();
+
+ int result = solutionBuild.LastBuildInfo;
+
+ Assert.AreEqual(1, result);
+ }
+
+ [Test]
+ public void LastBuildInfo_BuildProjectFails_SolutionBuildLastBuildInfoUnchangedWhenAccessedViaSolution()
+ {
+ BuildProjectFails();
+
+ int result = solution.SolutionBuild.LastBuildInfo;
+
+ Assert.AreEqual(1, result);
+ }
+
+ [Test]
+ public void LastBuildInfo_BuildProjectSucceeds_LastBuildInfoIsZero()
+ {
+ BuildProjectSucceeds();
+
+ int result = solution.SolutionBuild.LastBuildInfo;
+
+ Assert.AreEqual(0, result);
+ }
}
}