-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Expose Properties and Items data enumeration #10771
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
17 commits
Select commit
Hold shift + click to select a range
913b00e
Expose Properties and Items data enumeration
JanKrivanek 7a96d24
Merge branch 'main' into proto/expose-eventargs-enumeration
YuliiaKovalova 137ec1f
Add stronger type guarantee
JanKrivanek b4926c9
Merge branch 'main' into proto/expose-eventargs-enumeration
JanKrivanek 5d83e49
Add stronger typing for enumerating items
JanKrivanek d25b4e0
Remove extra newlines
JanKrivanek 7139ad0
Do not wrap the underlying item objects
JanKrivanek 080bf5a
Fix styling
JanKrivanek 9b7c565
Add unit tests
JanKrivanek a5e4303
Add explicit types for the API
JanKrivanek 4d6cd7d
Remove breaking API change to ITaskItem
JanKrivanek fbead3b
Add comments
JanKrivanek db8f24f
Allow for item types without common base
JanKrivanek d3a1200
Reflect PR suggestions
JanKrivanek 438125d
Add unit test
JanKrivanek 758d261
Remove redundant nullability
JanKrivanek 7e8b35b
Move the extensions codefile
JanKrivanek File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,143 @@ | ||
| // Licensed to the .NET Foundation under one or more agreements. | ||
| // The .NET Foundation licenses this file to you under the MIT license. | ||
|
|
||
| using System; | ||
| using System.Collections; | ||
| using System.Collections.Generic; | ||
| using System.Linq; | ||
| using Microsoft.Build.Execution; | ||
| using Microsoft.Build.Framework; | ||
| using Microsoft.Build.Logging; | ||
| using Microsoft.Build.Shared; | ||
| using Shouldly; | ||
| using Xunit; | ||
|
|
||
| namespace Microsoft.Build.UnitTests | ||
| { | ||
| public class BuildEventArgsDataEnumeration | ||
| { | ||
| [Fact] | ||
| public void SamplePropertiesEnumeration() | ||
| { | ||
| var projectFile = @"C:\foo\bar.proj"; | ||
| var args = new ProjectEvaluationFinishedEventArgs( | ||
| ResourceUtilities.GetResourceString("EvaluationFinished"), | ||
| projectFile) | ||
| { | ||
| BuildEventContext = BuildEventContext.Invalid, | ||
| ProjectFile = @"C:\foo\bar.proj", | ||
| GlobalProperties = new Dictionary<string, string>() { { "GlobalKey", "GlobalValue" } }, | ||
| Properties = new List<object>() | ||
| { | ||
| new DictionaryEntry("Key", "Value"), | ||
| ProjectPropertyInstance.Create("prop", "val"), | ||
| new KeyValuePair<string, string>("foo","bar") | ||
| }, | ||
| Items = null | ||
| }; | ||
|
|
||
| List<PropertyData> results = args.EnumerateProperties().ToList(); | ||
| results.Count.ShouldBe(3); | ||
| results[0].ShouldBe(new("Key", "Value")); | ||
| results[1].ShouldBe(new("prop", "val")); | ||
| results[2].ShouldBe(new("foo", "bar")); | ||
| } | ||
|
|
||
| [Fact] | ||
| public void SampleItemsEnumeration() | ||
| { | ||
| string projectFile = @"C:\foo\bar.proj"; | ||
| ProjectEvaluationFinishedEventArgs args = new ProjectEvaluationFinishedEventArgs( | ||
| ResourceUtilities.GetResourceString("EvaluationFinished"), | ||
| projectFile) | ||
| { | ||
| BuildEventContext = BuildEventContext.Invalid, | ||
| ProjectFile = @"C:\foo\bar.proj", | ||
| GlobalProperties = new Dictionary<string, string>() { { "GlobalKey", "GlobalValue" } }, | ||
| Properties = null, | ||
| Items = new List<DictionaryEntry>() | ||
| { | ||
| new DictionaryEntry("Key", new MyTaskItem() { ItemSpec = "TestItemSpec" }), | ||
| new DictionaryEntry("Key2", | ||
| new TaskItemData("spec", | ||
| new Dictionary<string, string>() { { "metadat1", "val1" }, { "metadat2", "val2" } })), | ||
| } | ||
| }; | ||
|
|
||
| List<ItemData> results = args.EnumerateItems().ToList(); | ||
|
|
||
| results.Count.ShouldBe(2); | ||
| results[0].Type.ShouldBe("Key"); | ||
| results[0].EvaluatedInclude.ShouldBe("TestItemSpec"); | ||
| results[0].EnumerateMetadata().ShouldBeEmpty(); | ||
|
|
||
| results[1].Type.ShouldBe("Key2"); | ||
| results[1].EvaluatedInclude.ShouldBe("spec"); | ||
| List<KeyValuePair<string, string>> metadata = results[1].EnumerateMetadata().ToList(); | ||
| metadata.Count.ShouldBe(2); | ||
| metadata[0].Key.ShouldBe("metadat1"); | ||
| metadata[0].Value.ShouldBe("val1"); | ||
| metadata[1].Key.ShouldBe("metadat2"); | ||
| metadata[1].Value.ShouldBe("val2"); | ||
| } | ||
|
|
||
| [Fact] | ||
| public void SampleFilteredItemsEnumeration() | ||
| { | ||
| string projectFile = @"C:\foo\bar.proj"; | ||
| ProjectEvaluationFinishedEventArgs args = new ProjectEvaluationFinishedEventArgs( | ||
| ResourceUtilities.GetResourceString("EvaluationFinished"), | ||
| projectFile) | ||
| { | ||
| BuildEventContext = BuildEventContext.Invalid, | ||
| ProjectFile = @"C:\foo\bar.proj", | ||
| GlobalProperties = new Dictionary<string, string>() { { "GlobalKey", "GlobalValue" } }, | ||
| Properties = null, | ||
| Items = new List<DictionaryEntry>() | ||
| { | ||
| new DictionaryEntry("Key", new MyTaskItem() { ItemSpec = "TestItemSpec" }), | ||
| new DictionaryEntry("Key2", | ||
| new TaskItemData("spec", | ||
| new Dictionary<string, string>() { { "metadat1", "val1" }, { "metadat2", "val2" } })), | ||
| new DictionaryEntry("Key2", new MyTaskItem() { ItemSpec = "TestItemSpec3" }), | ||
| new DictionaryEntry("Key", | ||
| new TaskItemData("spec4", | ||
| new Dictionary<string, string>() { { "metadat41", "val41" }, { "metadat42", "val42" } })), | ||
| } | ||
| }; | ||
|
|
||
| List<ItemData> results = args.EnumerateItemsOfType("Key").ToList(); | ||
|
|
||
| results.Count.ShouldBe(2); | ||
| results[0].Type.ShouldBe("Key"); | ||
| results[0].EvaluatedInclude.ShouldBe("TestItemSpec"); | ||
| results[0].EnumerateMetadata().ShouldBeEmpty(); | ||
|
|
||
| results[1].Type.ShouldBe("Key"); | ||
| results[1].EvaluatedInclude.ShouldBe("spec4"); | ||
| List<KeyValuePair<string, string>> metadata = results[1].EnumerateMetadata().ToList(); | ||
| metadata.Count.ShouldBe(2); | ||
| metadata[0].Key.ShouldBe("metadat41"); | ||
| metadata[0].Value.ShouldBe("val41"); | ||
| metadata[1].Key.ShouldBe("metadat42"); | ||
| metadata[1].Value.ShouldBe("val42"); | ||
|
|
||
| results = args.EnumerateItemsOfType("Key2").ToList(); | ||
|
|
||
| results.Count.ShouldBe(2); | ||
|
|
||
| results[0].Type.ShouldBe("Key2"); | ||
| results[0].EvaluatedInclude.ShouldBe("spec"); | ||
| metadata = results[0].EnumerateMetadata().ToList(); | ||
| metadata.Count.ShouldBe(2); | ||
| metadata[0].Key.ShouldBe("metadat1"); | ||
| metadata[0].Value.ShouldBe("val1"); | ||
| metadata[1].Key.ShouldBe("metadat2"); | ||
| metadata[1].Value.ShouldBe("val2"); | ||
|
|
||
| results[1].Type.ShouldBe("Key2"); | ||
| results[1].EvaluatedInclude.ShouldBe("TestItemSpec3"); | ||
| results[1].EnumerateMetadata().ShouldBeEmpty(); | ||
| } | ||
| } | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,73 @@ | ||
| // Licensed to the .NET Foundation under one or more agreements. | ||
| // The .NET Foundation licenses this file to you under the MIT license. | ||
|
|
||
| using System.Collections; | ||
| using System.Collections.Generic; | ||
| using Microsoft.Build.Framework; | ||
|
|
||
| namespace Microsoft.Build.Logging; | ||
|
|
||
| /// <summary> | ||
| /// Helper extension methods for working with data passed via | ||
| /// <see cref="ProjectEvaluationFinishedEventArgs"/> and <see cref="ProjectStartedEventArgs"/> | ||
| /// </summary> | ||
| public static class BuildEventArgsExtensions | ||
| { | ||
| /// <summary> | ||
| /// Lazy enumerates and strong types properties from Properties property. | ||
| /// </summary> | ||
| public static IEnumerable<PropertyData> EnumerateProperties( | ||
| this ProjectEvaluationFinishedEventArgs eventArgs) | ||
| => EnumerateProperties(eventArgs.Properties); | ||
|
|
||
| /// <summary> | ||
| /// Lazy enumerates and strong types properties from Properties property. | ||
| /// </summary> | ||
| public static IEnumerable<PropertyData> EnumerateProperties( | ||
| this ProjectStartedEventArgs eventArgs) | ||
| => EnumerateProperties(eventArgs.Properties); | ||
|
|
||
| /// <summary> | ||
| /// Lazy enumerates and partially strong types items from Items property. | ||
| /// The actual item value is proxied via accessor methods - to be able to provide defined interface | ||
| /// </summary> | ||
| /// <returns></returns> | ||
| public static IEnumerable<ItemData> EnumerateItems( | ||
| this ProjectEvaluationFinishedEventArgs eventArgs) | ||
| => EnumerateItems(eventArgs.Items); | ||
|
|
||
| /// <summary> | ||
| /// Lazy enumerates and partially strong types items from Items property. Only items with matching type will be returned (case-insensitive, MSBuild valid names only). | ||
| /// The actual item value is proxied via accessor methods - to be able to provide defined interface | ||
| /// </summary> | ||
| /// <returns></returns> | ||
| public static IEnumerable<ItemData> EnumerateItemsOfType( | ||
| this ProjectEvaluationFinishedEventArgs eventArgs, string typeName) | ||
| => EnumerateItemsOfType(eventArgs.Items, typeName); | ||
|
|
||
| /// <summary> | ||
| /// Lazy enumerates and strong types items from Items property. | ||
| /// The actual item value is proxied via accessor methods - to be able to provide defined interface | ||
| /// </summary> | ||
| public static IEnumerable<ItemData> EnumerateItems( | ||
| this ProjectStartedEventArgs eventArgs) | ||
| => EnumerateItems(eventArgs.Items); | ||
|
|
||
| /// <summary> | ||
| /// Lazy enumerates and partially strong types items from Items property. Only items with matching type will be returned (case-insensitive, MSBuild valid names only). | ||
| /// The actual item value is proxied via accessor methods - to be able to provide defined interface | ||
| /// </summary> | ||
| /// <returns></returns> | ||
| public static IEnumerable<ItemData> EnumerateItemsOfType( | ||
| this ProjectStartedEventArgs eventArgs, string typeName) | ||
| => EnumerateItemsOfType(eventArgs.Items, typeName); | ||
|
|
||
| private static IEnumerable<PropertyData> EnumerateProperties(IEnumerable? properties) | ||
| => Internal.Utilities.EnumerateProperties(properties); | ||
|
|
||
| private static IEnumerable<ItemData> EnumerateItems(IEnumerable? items) | ||
| => Internal.Utilities.EnumerateItems(items); | ||
|
|
||
| private static IEnumerable<ItemData> EnumerateItemsOfType(IEnumerable? items, string typeName) | ||
| => Internal.Utilities.EnumerateItemsOfType(items, typeName); | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.