Browse Source
The Fody NuGet package has an install PowerShell script that directly updates the MSBuild project from the Microsoft.Build.Evaluation.ProjectCollection.GlobalProjectCollection to set a FodyPath property that defines where the Fody.targets file should find the main Fody assembly. Extended the support added for the Microsoft.Bcl.Build NuGet package so project properties added by directly updating the MSBuild project from the GlobalProjectCollection are added/updated in the actual project file. No support for updating properties that exist multiple times inside a project (e.g. OutputPath).pull/79/head
6 changed files with 423 additions and 0 deletions
@ -0,0 +1,55 @@
@@ -0,0 +1,55 @@
|
||||
// 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.Collections.Generic; |
||||
using System.Linq; |
||||
|
||||
namespace ICSharpCode.PackageManagement.Scripting |
||||
{ |
||||
public class MSBuildProjectPropertiesMergeResult |
||||
{ |
||||
List<string> propertiesAdded = new List<string>(); |
||||
List<string> propertiesUpdated = new List<string>(); |
||||
|
||||
public IEnumerable<string> PropertiesAdded { |
||||
get { return propertiesAdded; } |
||||
} |
||||
|
||||
public IEnumerable<string> PropertiesUpdated { |
||||
get { return propertiesUpdated; } |
||||
} |
||||
|
||||
public override string ToString() |
||||
{ |
||||
return String.Format( |
||||
"Properties added: {0}\r\nProperties updated: {1}", |
||||
PropertiesToString(propertiesAdded), |
||||
PropertiesToString(propertiesUpdated)); |
||||
} |
||||
|
||||
static string PropertiesToString(IEnumerable<string> properties) |
||||
{ |
||||
if (!properties.Any()) { |
||||
return String.Empty; |
||||
} |
||||
|
||||
return String.Join(",\r\n", properties.Select(property => property)); |
||||
} |
||||
|
||||
public void AddPropertyAdded(string propertyName) |
||||
{ |
||||
propertiesAdded.Add(propertyName); |
||||
} |
||||
|
||||
public void AddPropertyUpdated(string propertyName) |
||||
{ |
||||
propertiesUpdated.Add(propertyName); |
||||
} |
||||
|
||||
public bool AnyPropertiesChanged() |
||||
{ |
||||
return propertiesUpdated.Any() || propertiesAdded.Any(); |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,93 @@
@@ -0,0 +1,93 @@
|
||||
// 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.Collections.Generic; |
||||
using System.Linq; |
||||
|
||||
using ICSharpCode.SharpDevelop.Project; |
||||
using Microsoft.Build.Construction; |
||||
using Microsoft.Build.Evaluation; |
||||
|
||||
namespace ICSharpCode.PackageManagement.Scripting |
||||
{ |
||||
public class MSBuildProjectPropertiesMerger |
||||
{ |
||||
IPackageManagementProjectService projectService; |
||||
Project msbuildProject; |
||||
MSBuildBasedProject sharpDevelopProject; |
||||
MSBuildProjectPropertiesMergeResult result = new MSBuildProjectPropertiesMergeResult(); |
||||
|
||||
public MSBuildProjectPropertiesMerger(Project msbuildProject, MSBuildBasedProject sharpDevelopProject) |
||||
: this(msbuildProject, sharpDevelopProject, new PackageManagementProjectService()) |
||||
{ |
||||
} |
||||
|
||||
public MSBuildProjectPropertiesMerger( |
||||
Project msbuildProject, |
||||
MSBuildBasedProject sharpDevelopProject, |
||||
IPackageManagementProjectService projectService) |
||||
{ |
||||
this.msbuildProject = msbuildProject; |
||||
this.sharpDevelopProject = sharpDevelopProject; |
||||
this.projectService = projectService; |
||||
} |
||||
|
||||
public MSBuildProjectPropertiesMergeResult Result { |
||||
get { return result; } |
||||
} |
||||
|
||||
public void Merge() |
||||
{ |
||||
foreach (ProjectPropertyElement property in msbuildProject.Xml.Properties) { |
||||
UpdateProperty(property); |
||||
} |
||||
|
||||
projectService.Save(sharpDevelopProject); |
||||
} |
||||
|
||||
void UpdateProperty(ProjectPropertyElement msbuildProjectProperty) |
||||
{ |
||||
List<ProjectPropertyElement> sharpDevelopProjectProperties = FindSharpDevelopProjectProperties(msbuildProjectProperty); |
||||
if (sharpDevelopProjectProperties.Count > 1) { |
||||
// Ignore. Currently do not handle properties defined inside
|
||||
// property groups with conditions (e.g. OutputPath)
|
||||
} else if (!sharpDevelopProjectProperties.Any()) { |
||||
AddPropertyToSharpDevelopProject(msbuildProjectProperty); |
||||
} else if (HasMSBuildProjectPropertyBeenUpdated(msbuildProjectProperty, sharpDevelopProjectProperties.First())) { |
||||
UpdatePropertyInSharpDevelopProject(msbuildProjectProperty); |
||||
} |
||||
} |
||||
|
||||
List<ProjectPropertyElement> FindSharpDevelopProjectProperties(ProjectPropertyElement msbuildProjectProperty) |
||||
{ |
||||
return sharpDevelopProject |
||||
.MSBuildProjectFile |
||||
.Properties |
||||
.Where(property => String.Equals(property.Name, msbuildProjectProperty.Name, StringComparison.OrdinalIgnoreCase)) |
||||
.ToList(); |
||||
} |
||||
|
||||
void AddPropertyToSharpDevelopProject(ProjectPropertyElement msbuildProjectProperty) |
||||
{ |
||||
SetPropertyInSharpDevelopProject(msbuildProjectProperty); |
||||
result.AddPropertyAdded(msbuildProjectProperty.Name); |
||||
} |
||||
|
||||
void SetPropertyInSharpDevelopProject(ProjectPropertyElement msbuildProjectProperty) |
||||
{ |
||||
sharpDevelopProject.SetProperty(msbuildProjectProperty.Name, msbuildProjectProperty.Value); |
||||
} |
||||
|
||||
bool HasMSBuildProjectPropertyBeenUpdated(ProjectPropertyElement msbuildProjectProperty, ProjectPropertyElement sharpDevelopProjectProperty) |
||||
{ |
||||
return msbuildProjectProperty.Value != sharpDevelopProjectProperty.Value; |
||||
} |
||||
|
||||
void UpdatePropertyInSharpDevelopProject(ProjectPropertyElement msbuildProjectProperty) |
||||
{ |
||||
SetPropertyInSharpDevelopProject(msbuildProjectProperty); |
||||
result.AddPropertyUpdated(msbuildProjectProperty.Name); |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,248 @@
@@ -0,0 +1,248 @@
|
||||
// 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 ICSharpCode.PackageManagement; |
||||
using ICSharpCode.PackageManagement.Scripting; |
||||
using Microsoft.Build.Construction; |
||||
using Microsoft.Build.Evaluation; |
||||
using NUnit.Framework; |
||||
using PackageManagement.Tests.Helpers; |
||||
using Rhino.Mocks; |
||||
|
||||
namespace PackageManagement.Tests.Scripting |
||||
{ |
||||
[TestFixture] |
||||
public class MSBuildProjectPropertiesMergerTests |
||||
{ |
||||
MSBuildProjectPropertiesMerger propertiesMerger; |
||||
IPackageManagementProjectService projectService; |
||||
TestableProject sharpDevelopProject; |
||||
Project msbuildProject; |
||||
|
||||
[SetUp] |
||||
public void Init() |
||||
{ |
||||
CreateMSBuildProject(); |
||||
CreateSharpDevelopProject(); |
||||
CreateProjectPropertiesMerger(); |
||||
} |
||||
|
||||
void CreateMSBuildProject() |
||||
{ |
||||
msbuildProject = new Project(); |
||||
} |
||||
|
||||
void CreateSharpDevelopProject() |
||||
{ |
||||
sharpDevelopProject = ProjectHelper.CreateTestProject(); |
||||
} |
||||
|
||||
void CreateProjectPropertiesMerger() |
||||
{ |
||||
projectService = MockRepository.GenerateStub<IPackageManagementProjectService>(); |
||||
propertiesMerger = new MSBuildProjectPropertiesMerger(msbuildProject, sharpDevelopProject, projectService); |
||||
} |
||||
|
||||
void Merge() |
||||
{ |
||||
propertiesMerger.Merge(); |
||||
} |
||||
|
||||
void AddPropertyToSharpDevelopProject(string name, string value) |
||||
{ |
||||
sharpDevelopProject.SetProperty(name, value); |
||||
} |
||||
|
||||
void AddPropertyToSharpDevelopProjectWithCondition(string name, string value, string condition) |
||||
{ |
||||
AddPropertyWithCondition(sharpDevelopProject.MSBuildProjectFile, name, value, condition); |
||||
} |
||||
|
||||
void AddPropertyWithCondition(ProjectRootElement projectRoot, string name, string value, string condition) |
||||
{ |
||||
ProjectPropertyGroupElement groupProperty = projectRoot.CreatePropertyGroupElement(); |
||||
groupProperty.Condition = condition; |
||||
projectRoot.AppendChild(groupProperty); |
||||
|
||||
ProjectPropertyElement property = projectRoot.CreatePropertyElement(name); |
||||
groupProperty.AppendChild(property); |
||||
property.Value = value; |
||||
property.Condition = condition; |
||||
} |
||||
|
||||
void AddPropertyToMSBuildProject(string name, string value) |
||||
{ |
||||
msbuildProject.SetProperty(name, value); |
||||
} |
||||
|
||||
void AddPropertyToMSBuildProjectWithCondition(string name, string value, string condition) |
||||
{ |
||||
AddPropertyWithCondition(msbuildProject.Xml, name, value, condition); |
||||
} |
||||
|
||||
void AssertSharpDevelopProjectContainsProperty(string propertyName, string expectedValue) |
||||
{ |
||||
string actualValue = sharpDevelopProject.GetEvaluatedProperty(propertyName); |
||||
|
||||
Assert.AreEqual(expectedValue, actualValue); |
||||
} |
||||
|
||||
[Test] |
||||
public void Merge_MSBuildProjectHasNewPropertyAdded_PropertyAddedToSharpDevelopProject() |
||||
{ |
||||
AddPropertyToMSBuildProject("Test", "test-value"); |
||||
|
||||
Merge(); |
||||
|
||||
AssertSharpDevelopProjectContainsProperty("Test", "test-value"); |
||||
} |
||||
|
||||
[Test] |
||||
public void Merge_MSBuildProjectHasNewPropertyAdded_SharpDevelopProjectIsSaved() |
||||
{ |
||||
AddPropertyToMSBuildProject("Test", "test-value"); |
||||
|
||||
Merge(); |
||||
|
||||
projectService.AssertWasCalled(service => service.Save(sharpDevelopProject)); |
||||
} |
||||
|
||||
[Test] |
||||
public void Merge_MSBuildProjectHasTwoNewPropertiesAdded_BothPropertiesAddedToSharpDevelopProject() |
||||
{ |
||||
AddPropertyToMSBuildProject("Test1", "test-value1"); |
||||
AddPropertyToMSBuildProject("Test2", "test-value2"); |
||||
|
||||
Merge(); |
||||
|
||||
AssertSharpDevelopProjectContainsProperty("Test1", "test-value1"); |
||||
AssertSharpDevelopProjectContainsProperty("Test2", "test-value2"); |
||||
} |
||||
|
||||
[Test] |
||||
public void Merge_MSBuildProjectHasTwoNewPropertiesAdded_MergeResultHasBothPropertiesAdded() |
||||
{ |
||||
AddPropertyToMSBuildProject("Test1", "test-value2"); |
||||
AddPropertyToMSBuildProject("Test2", "test-value2"); |
||||
|
||||
Merge(); |
||||
|
||||
var expected = new string[] { "Test1", "Test2" }; |
||||
string expectedToString = "Properties added: Test1,\r\nTest2\r\nProperties updated: "; |
||||
CollectionAssert.AreEqual(expected, propertiesMerger.Result.PropertiesAdded); |
||||
Assert.AreEqual(expectedToString, propertiesMerger.Result.ToString()); |
||||
} |
||||
|
||||
[Test] |
||||
public void Merge_MSBuildProjectPropertyUpdated_SharpDevelopProjectPropertyIsUpdated() |
||||
{ |
||||
AddPropertyToSharpDevelopProject("Test", "old-value"); |
||||
AddPropertyToMSBuildProject("Test", "new-value"); |
||||
|
||||
Merge(); |
||||
|
||||
AssertSharpDevelopProjectContainsProperty("Test", "new-value"); |
||||
} |
||||
|
||||
[Test] |
||||
public void Merge_TwoMSBuildProjectsPropertiesUpdated_BothPropertiesUpdatedInSharpDevelopProject() |
||||
{ |
||||
AddPropertyToSharpDevelopProject("Test1", "old-value"); |
||||
AddPropertyToSharpDevelopProject("Test2", "old-value"); |
||||
AddPropertyToMSBuildProject("Test1", "new-value1"); |
||||
AddPropertyToMSBuildProject("Test2", "new-value2"); |
||||
|
||||
Merge(); |
||||
|
||||
AssertSharpDevelopProjectContainsProperty("Test1", "new-value1"); |
||||
AssertSharpDevelopProjectContainsProperty("Test2", "new-value2"); |
||||
} |
||||
|
||||
[Test] |
||||
public void Merge_TwoMSBuildProjectsPropertiesUpdated_MergeResultShowsUpdatedProperty() |
||||
{ |
||||
AddPropertyToSharpDevelopProject("Test1", "old-value"); |
||||
AddPropertyToSharpDevelopProject("Test2", "old-value"); |
||||
AddPropertyToMSBuildProject("Test1", "new-value"); |
||||
AddPropertyToMSBuildProject("Test2", "new-value"); |
||||
|
||||
Merge(); |
||||
|
||||
var expected = new string[] { "Test1", "Test2" }; |
||||
string expectedToString = "Properties added: \r\nProperties updated: Test1,\r\nTest2"; |
||||
CollectionAssert.AreEqual(expected, propertiesMerger.Result.PropertiesUpdated); |
||||
Assert.AreEqual(expectedToString, propertiesMerger.Result.ToString()); |
||||
} |
||||
|
||||
[Test] |
||||
public void Merge_TwoMSBuildProjectsNotChanged_MergeResultShowNoUpdatedProperties() |
||||
{ |
||||
AddPropertyToSharpDevelopProject("Test1", "old-value"); |
||||
AddPropertyToSharpDevelopProject("Test2", "old-value"); |
||||
AddPropertyToMSBuildProject("Test1", "old-value"); |
||||
AddPropertyToMSBuildProject("Test2", "old-value"); |
||||
|
||||
Merge(); |
||||
|
||||
var expected = new string[0]; |
||||
CollectionAssert.AreEqual(expected, propertiesMerger.Result.PropertiesUpdated); |
||||
CollectionAssert.AreEqual(expected, propertiesMerger.Result.PropertiesAdded); |
||||
Assert.IsFalse(propertiesMerger.Result.AnyPropertiesChanged()); |
||||
} |
||||
|
||||
[Test] |
||||
public void SetProperty_UseDifferentCaseForMSBuildPropertyName_WhatHappens() |
||||
{ |
||||
AddPropertyToMSBuildProject("test", "value"); |
||||
|
||||
string propertyValue = msbuildProject.GetPropertyValue("TEST"); |
||||
|
||||
Assert.AreEqual("value", propertyValue); |
||||
} |
||||
|
||||
[Test] |
||||
public void Merge_MSBuildProjectPropertyUpdatedButDifferentCaseUsedForName_SharpDevelopProjectPropertyIsStillUpdated() |
||||
{ |
||||
AddPropertyToSharpDevelopProject("TEST", "old-value"); |
||||
AddPropertyToMSBuildProject("Test", "new-value"); |
||||
|
||||
Merge(); |
||||
|
||||
AssertSharpDevelopProjectContainsProperty("TEST", "new-value"); |
||||
} |
||||
|
||||
[Test] |
||||
public void Merge_MSBuildProjectPropertyUpdatedButDifferentCaseUsedForName_MergeResultShowsPropertyHasBeenUpdated() |
||||
{ |
||||
AddPropertyToSharpDevelopProject("TEST", "old-value"); |
||||
AddPropertyToMSBuildProject("Test", "new-value"); |
||||
|
||||
Merge(); |
||||
|
||||
var expected = new string[] { "Test" }; |
||||
CollectionAssert.AreEqual(expected, propertiesMerger.Result.PropertiesUpdated); |
||||
Assert.AreEqual(0, propertiesMerger.Result.PropertiesAdded.Count()); |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Ignore any properties that are duplicated in the project file, such as
|
||||
/// OutputPath which exists twice due to Debug and Release configurations.
|
||||
/// </summary>
|
||||
[Test] |
||||
public void Merge_OutputPathPropertyInDebugAndReleaseConfigurations_SharpDevelopProjectPropertiesNotChanged() |
||||
{ |
||||
string debugConfiguration = "'$(Configuration)' == 'Debug'"; |
||||
string releaseConfiguration = "'$(Configuration)' == 'Release'"; |
||||
AddPropertyToSharpDevelopProjectWithCondition("OutputPath", @"bin\Release", releaseConfiguration); |
||||
AddPropertyToSharpDevelopProjectWithCondition("OutputPath", @"bin\Debug", debugConfiguration); |
||||
AddPropertyToMSBuildProjectWithCondition("OutputPath", @"bin\Release", releaseConfiguration); |
||||
AddPropertyToMSBuildProjectWithCondition("OutputPath", @"bin\Debug", debugConfiguration); |
||||
|
||||
Merge(); |
||||
|
||||
Assert.IsFalse(propertiesMerger.Result.AnyPropertiesChanged()); |
||||
} |
||||
} |
||||
} |
Loading…
Reference in new issue