Skip to content
Closed
Show file tree
Hide file tree
Changes from 3 commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
cf264e2
Initial plan
Copilot Dec 5, 2025
3c0d56a
WIP: Investigation of chained item function comparison issue
Copilot Dec 5, 2025
e991105
Fix chained item function empty string comparison in conditions
Copilot Dec 5, 2025
49a6fd4
Fix unhandled exception in /getItem and /getTargetResult for items wi…
Copilot Jan 5, 2026
9ba8f3e
Log SDK environment variable messages only when values differ (#12918)
Copilot Jan 5, 2026
5fccf5a
Localized file check-in by OneLocBuild Task: Build definition ID 9434…
dotnet-bot Jan 5, 2026
fb77584
Localized file check-in by OneLocBuild Task: Build definition ID 9434…
YuliiaKovalova Jan 5, 2026
2392c79
Fix terminal logger quiet mode to show project context for warnings/e…
Copilot Jan 6, 2026
3d8dd2e
Replace OpenTelemetry with Microsoft.VisualStudio.Telemetry for VS (#…
YuliiaKovalova Jan 7, 2026
b8e744f
Localized file check-in by OneLocBuild Task: Build definition ID 9434…
dotnet-bot Jan 7, 2026
bddfab6
[main] Source code updates from dotnet/dotnet (#12979)
dotnet-maestro[bot] Jan 7, 2026
a8434cb
eliminate test data serialization warnings (#12983)
JanProvaznik Jan 7, 2026
0a54973
Add the feature flag that allows users to opt out automatic UTF8 cons…
GangWang01 Jan 7, 2026
dc7f357
Polyfill clean up and source package organization (#12977)
DustinCampbell Jan 7, 2026
9da1bd7
Localized file check-in by OneLocBuild Task: Build definition ID 9434…
dotnet-bot Jan 8, 2026
09c7666
Add documentation for enabling binlog collection via env var (#12805)
YuliiaKovalova Jan 9, 2026
3f8a08b
Support multiple binary logs from command line arguments (#12706)
Copilot Jan 9, 2026
3b83621
Add VcxprojReader.exe to ngenApplications (#12986)
YuliiaKovalova Jan 9, 2026
b8cacb7
Add HostServices support in Out-of-Process Task Host (#12753)
YuliiaKovalova Jan 9, 2026
f469379
[main] Update dependencies from dotnet/roslyn (#13002)
dotnet-maestro[bot] Jan 12, 2026
7c44a50
[main] Update dependencies from dotnet/arcade (#13000)
dotnet-maestro[bot] Jan 12, 2026
7cf4f24
Localized file check-in by OneLocBuild Task: Build definition ID 9434…
dotnet-bot Jan 12, 2026
6ef3f7b
Add telemetry tracking for task factory names and runtime usage (#12989)
Copilot Jan 12, 2026
712f8ef
[main] Source code updates from dotnet/dotnet (#12987)
dotnet-maestro[bot] Jan 12, 2026
6883d6d
Localized file check-in by OneLocBuild Task: Build definition ID 9434…
dotnet-bot Jan 12, 2026
bd54b25
Snap for VS 18.3 and update branding to VS 18.4 (#13005)
Copilot Jan 12, 2026
21efb94
[main] Source code updates from dotnet/dotnet (#13012)
dotnet-maestro[bot] Jan 13, 2026
39e218c
Add telemetry to categorize build failure reasons (#13007)
Copilot Jan 13, 2026
5284a3f
Update MicrosoftBuildVersion in analyzer template (#13011)
github-actions[bot] Jan 13, 2026
75edd3c
Update OptProf drop metadata configuration (#13020)
YuliiaKovalova Jan 14, 2026
d7c46da
Fix MSB1025 error when using DistributedFileLogger (-dfl flag) (#13036)
Copilot Jan 15, 2026
633ca60
CmdLine parsing was extracted from XMake and the implementation is vi…
MichalPavlik Jan 16, 2026
5025a99
Make task environment path absolutization not throw. (#13035)
AR-May Jan 16, 2026
58c73e6
Fix flaky test TestTerminalLoggerTogetherWithOtherLoggers (#13044)
Copilot Jan 16, 2026
4618ab5
Enlighten more tasks that require no change (#13045)
AR-May Jan 16, 2026
b703e1a
[main] Update dependencies from dotnet/roslyn (#13050)
dotnet-maestro[bot] Jan 19, 2026
c81b56d
[main] Update dependencies from dotnet/arcade (#13048)
dotnet-maestro[bot] Jan 19, 2026
825180b
Add support for MSBUILD_LOGGING_ARGS (#12993)
YuliiaKovalova Jan 19, 2026
d6f451b
Fix MSBuildEventSource (#13030)
dfederm Jan 19, 2026
c1ccadd
Localized file check-in by OneLocBuild Task: Build definition ID 9434…
dotnet-bot Jan 19, 2026
a949b5a
Merge branch 'main' into copilot/fix-item-function-comparison
JanProvaznik Jan 19, 2026
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
30 changes: 30 additions & 0 deletions src/Build.UnitTests/Evaluation/Expander_Tests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5268,5 +5268,35 @@ public void PropertyFunctionRegisterBuildCheck()
logger.AllBuildEvents.Count.ShouldBe(1);
}
}

/// <summary>
/// Test for issue where chained item functions with empty results incorrectly evaluate as non-empty in conditions
/// </summary>
[Fact]
public void ChainedItemFunctionEmptyResultInCondition()
{
string content = @"
<Project>
<Target Name='Test'>
<ItemGroup>
<TestItem Include='Test1' Foo='Bar' />
<TestItem Include='Test2' />
</ItemGroup>

<!-- This should be empty because Test1 has Foo='Bar', not 'Baz' -->
<PropertyGroup Condition=""'@(TestItem->WithMetadataValue('Identity', 'Test1')->WithMetadataValue('Foo', 'Baz'))' == ''"">
<EmptyResult>TRUE</EmptyResult>
</PropertyGroup>

<Message Text='EmptyResult=$(EmptyResult)' Importance='high' />
</Target>
</Project>
";

MockLogger log = Helpers.BuildProjectWithNewOMExpectSuccess(content);

// The chained WithMetadataValue should return empty, so the condition should be true and EmptyResult should be set
log.AssertLogContains("EmptyResult=TRUE");
}
}
}
20 changes: 12 additions & 8 deletions src/Build/Evaluation/Expander.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2021,21 +2021,25 @@ internal static List<KeyValuePair<string, S>> Transform<S>(
break;
}

// If we have another transform, swap the source and transform lists.
if (i < captures.Count - 1)
{
(transformedItems, sourceItems) = (sourceItems, transformedItems);
transformedItems.Clear();
}
}

// Check for break on non-empty only after ALL transforms are complete
if ((options & ExpanderOptions.BreakOnNotEmpty) != 0)
{
foreach (KeyValuePair<string, S> itemTuple in transformedItems)
{
if (!string.IsNullOrEmpty(itemTuple.Key) && (options & ExpanderOptions.BreakOnNotEmpty) != 0)
if (!string.IsNullOrEmpty(itemTuple.Key))
{
brokeEarly = true;
return transformedItems; // break out early
}
}

// If we have another transform, swap the source and transform lists.
if (i < captures.Count - 1)
{
(transformedItems, sourceItems) = (sourceItems, transformedItems);
transformedItems.Clear();
}
}

brokeEarly = false;
Expand Down