Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 49 additions & 0 deletions src/MSBuildProjectCreator.UnitTests/ItemTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using Microsoft.Build.Evaluation;
using Shouldly;
using System.Collections.Generic;
using System.Linq;
using Xunit;

namespace Microsoft.Build.Utilities.ProjectCreation.UnitTests
Expand Down Expand Up @@ -292,6 +293,54 @@ public void RemoveItem()
StringCompareShould.IgnoreLineEndings);
}

[Fact]
public void TryGetItemsCustomSelector()
{
ProjectCreator.Create(projectFileOptions: NewProjectFileOptions.None)
.ItemInclude("MyItem", "3F114C1509CF4D499A44F986BEBD5707")
.ItemInclude("MyItem", "8A9654A639F5429AB1C7A8F2AE9639D8")
.TryGetItems("MyItem", i => i.EvaluatedInclude, out IReadOnlyCollection<string> items);

items.ShouldBe(new List<string>
{
"3F114C1509CF4D499A44F986BEBD5707",
"8A9654A639F5429AB1C7A8F2AE9639D8"
});
}

[Fact]
public void TryGetItemsDictionary()
{
ProjectCreator.Create(projectFileOptions: NewProjectFileOptions.None)
.ItemInclude("MyItem", "A9AA54F5E51E4C0A966A5F5CDBD5EC9D", metadata: new Dictionary<string, string> { ["MyMetadata"] = "A3A33B3B55A841D883A05F6CA920AC1F" })
.ItemInclude("MyItem", "910E2DA9075043AA850D923E8E3EE398", metadata: new Dictionary<string, string> { ["MyMetadata"] = "EF8E0862B0A946D98DA7082E70AEC3E9" })
.TryGetItems("MyItem", "MyMetadata", out IReadOnlyDictionary<string, string> items);

items.ShouldBe(new Dictionary<string, string>
{
["A9AA54F5E51E4C0A966A5F5CDBD5EC9D"] = "A3A33B3B55A841D883A05F6CA920AC1F",
["910E2DA9075043AA850D923E8E3EE398"] = "EF8E0862B0A946D98DA7082E70AEC3E9"
});
}

[Fact]
public void TryGetItemsProjectItems()
{
ProjectCreator.Create(projectFileOptions: NewProjectFileOptions.None)
.ItemInclude("MyItem", "B39E047FC97A48E3964EEA70C46F4E35")
.ItemInclude("MyItem", "E0FA8DA2551F4EE18D2102149D3049D4")
.TryGetItems("MyItem", out IReadOnlyCollection<ProjectItem> items);

items
.Select(i => i.EvaluatedInclude)
.ToList()
.ShouldBe(new List<string>
{
"B39E047FC97A48E3964EEA70C46F4E35",
"E0FA8DA2551F4EE18D2102149D3049D4"
});
}

[Fact]
public void UpdateItem()
{
Expand Down
13 changes: 13 additions & 0 deletions src/MSBuildProjectCreator.UnitTests/PropertyTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -93,5 +93,18 @@ public void PropertySimple()
</Project>",
StringCompareShould.IgnoreLineEndings);
}

[Fact]
public void TryGetPropertyValueSimple()
{
ProjectCreator.Create(projectFileOptions: NewProjectFileOptions.None)
.Property("E7A39154F5AB476A928067251F88FFCE", "E8F579A7E3374F389120CF6D888E74B9")
.Property("FAB58E5B32D14990ACE2490D7593FDF6", "60F55FB14D2E44B2BA4EC91488D9FF8F")
.TryGetPropertyValue("E7A39154F5AB476A928067251F88FFCE", out string property1)
.TryGetPropertyValue("FAB58E5B32D14990ACE2490D7593FDF6", out string property2);

property1.ShouldBe("E8F579A7E3374F389120CF6D888E74B9");
property2.ShouldBe("60F55FB14D2E44B2BA4EC91488D9FF8F");
}
}
}
22 changes: 18 additions & 4 deletions src/MSBuildProjectCreator/ProjectCreator.Build.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
//
// Licensed under the MIT license.

using Microsoft.Build.Execution;

namespace Microsoft.Build.Utilities.ProjectCreation
{
public partial class ProjectCreator
Expand All @@ -14,7 +16,10 @@ public partial class ProjectCreator
/// <returns>The current <see cref="ProjectCreator"/>.</returns>
public ProjectCreator TryBuild(string target, out bool result)
{
result = Project.Build(target);
lock (BuildManager.DefaultBuildManager)
{
result = Project.Build(target);
}

return this;
}
Expand All @@ -30,7 +35,10 @@ public ProjectCreator TryBuild(string target, out bool result, out BuildOutput b
{
buildOutput = BuildOutput.Create();

result = Project.Build(target, buildOutput.AsEnumerable());
lock (BuildManager.DefaultBuildManager)
{
result = Project.Build(target, buildOutput.AsEnumerable());
}

return this;
}
Expand All @@ -42,7 +50,10 @@ public ProjectCreator TryBuild(string target, out bool result, out BuildOutput b
/// <returns>The current <see cref="ProjectCreator"/>.</returns>
public ProjectCreator TryBuild(out bool result)
{
result = Project.Build();
lock (BuildManager.DefaultBuildManager)
{
result = Project.Build();
}

return this;
}
Expand All @@ -57,7 +68,10 @@ public ProjectCreator TryBuild(out bool result, out BuildOutput buildOutput)
{
buildOutput = BuildOutput.Create();

result = Project.Build(buildOutput.AsEnumerable());
lock (BuildManager.DefaultBuildManager)
{
result = Project.Build(buildOutput.AsEnumerable());
}

return this;
}
Expand Down
53 changes: 53 additions & 0 deletions src/MSBuildProjectCreator/ProjectCreator.Items.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

using Microsoft.Build.Construction;
using Microsoft.Build.Evaluation;
using System;
using System.Collections.Generic;
using System.Linq;

Expand Down Expand Up @@ -314,6 +315,58 @@ public ProjectCreator ItemUpdate(
condition: condition);
}

/// <summary>
/// Gets a list of items in the project.
/// </summary>
/// <param name="itemType">The item type.</param>
/// <param name="items">A <see cref="IReadOnlyCollection{ProjectItem}"/> containing the items.</param>
/// <returns>The current <see cref="ProjectCreator"/>.</returns>
public ProjectCreator TryGetItems(string itemType, out IReadOnlyCollection<ProjectItem> items)
{
items = Project.GetItems(itemType).ToList();

return this;
}

/// <summary>
/// Gets a list of items in the project.
/// </summary>
/// <typeparam name="T">The type of the object that the selector will return.</typeparam>
/// <param name="itemType">The item type.</param>
/// <param name="selector">A <see cref="Func{ProjectItem, T}"/> that gets the desired return object.</param>
/// <param name="items">A <see cref="IReadOnlyCollection{T}"/> containing the items.</param>
/// <returns>The current <see cref="ProjectCreator"/>.</returns>
public ProjectCreator TryGetItems<T>(string itemType, Func<ProjectItem, T> selector, out IReadOnlyCollection<T> items)
{
if (selector == null)
{
throw new ArgumentNullException(nameof(selector));
}

items = Project.GetItems(itemType).Select(selector).ToList();

return this;
}

/// <summary>
/// Gets a list of items in the project.
/// </summary>
/// <param name="itemType">The item type.</param>
/// <param name="metadataName">The name of a metadata item to get.</param>
/// <param name="items">A <see cref="IReadOnlyDictionary{String,String}"/> containing the ItemSpec and metadata value.</param>
/// <returns>The current <see cref="ProjectCreator"/>.</returns>
public ProjectCreator TryGetItems(string itemType, string metadataName, out IReadOnlyDictionary<string, string> items)
{
if (String.IsNullOrWhiteSpace(metadataName))
{
throw new ArgumentNullException(nameof(metadataName));
}

items = Project.GetItems(itemType).ToDictionary(i => i.EvaluatedInclude, i => i.GetMetadataValue(metadataName));

return this;
}

/// <summary>
/// Adds an item to the current item group.
/// </summary>
Expand Down
13 changes: 13 additions & 0 deletions src/MSBuildProjectCreator/ProjectCreator.Properties.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,19 @@ public ProjectCreator Property(string name, string unevaluatedValue, string cond
return Property(LastPropertyGroup, name, unevaluatedValue, condition, setIfEmpty);
}

/// <summary>
/// Attempts to get the specified evaluated property value.
/// </summary>
/// <param name="name">The name of the property.</param>
/// <param name="value">The evaluated value of the property</param>
/// <returns>The unescaped value of the property if it exists, otherwise an empty string.</returns>
public ProjectCreator TryGetPropertyValue(string name, out string value)
{
value = Project.GetPropertyValue(name);

return this;
}

/// <summary>
/// Adds a property element to the current &lt;PropertyGroup /&gt;. A property group is automatically added if necessary. if <paramref name="unevaluatedValue"/> is <code>null</code>, the property is not added.
/// </summary>
Expand Down