Skip to content
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

[Bug]: Inconsistent behavior when using Choose element for conditional package references in MSBuild #10149

Open
myth384 opened this issue May 17, 2024 · 2 comments
Labels
Area: Language Issues impacting the MSBuild programming language. backlog Documentation Priority:2 Work that is important, but not critical for the release triaged

Comments

@myth384
Copy link

myth384 commented May 17, 2024

Issue Description

There is an observed inconsistency in MSBuild when attempting to conditionally include NuGet package references using the Choose element with the When condition. Specifically, using Choose for this purpose does not work as expected, whereas using the Condition attribute directly on ItemGroup functions correctly.

Steps to Reproduce

  1. Create a new .NET project.

  2. Create a Directory.Build.props file in the root directory.

  3. Add the following content to the Directory.Build.props file using the Choose element:

<Project>
  <Choose>
    <When Condition="'$(IsTestProject)' == 'true'">
      <ItemGroup>
        <PackageReference Include="xunit" Version="2.4.1" />
      </ItemGroup>
    </When>
  </Choose>
</Project>
  1. Mark the project as a test project by setting the IsTestProject property to true in its .csproj file:
<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <IsTestProject>true</IsTestProject>
  </PropertyGroup>
</Project>
  1. Run dotnet restore and observe that the xunit package is not included.

  2. Modify the Directory.Build.props to use the Condition attribute directly on ItemGroup:

<Project>
  <ItemGroup Condition="'$(IsTestProject)' == 'true'">
    <PackageReference Include="xunit" Version="2.4.1" />
  </ItemGroup>
</Project>
  1. Run dotnet restore again and observe that the xunit package is now included.

Expected Behavior

Both the Choose element with When conditions and the Condition attribute on ItemGroup should enable or disable the inclusion of NuGet package references based on the specified condition.

Actual Behavior

  • Using the Choose element with When condition does not reliably include the specified NuGet package reference when the condition evaluates to true.
  • Using the Condition attribute directly on ItemGroup successfully includes the specified NuGet package reference when the condition evaluates to true.

Analysis

No response

Versions & Configurations

17.9.8.16306

@myth384 myth384 added the bug label May 17, 2024
@rainersigwald
Copy link
Member

What's happening here is that the Choose condition evaluation happens only in the properties evaluation pass (pass 1), at which time the condition isn't true--Directory.Build.props is imported before the body of the project, so IsTestProject hasn't been set yet when the condition evaluates.

ItemGroup evaluation happens later (in pass 3), after all properties (from all imports) have been set, so your step-6 condition evaluates to the value you expect.

I was a bit surprised by this Choose condition timing, and it doesn't seem to be well documented outside this comment which doesn't help anyone:

/// <remarks>
/// We enter here in both the property and item passes, since Chooses can contain both.
/// However, we only evaluate the When conditions on the first pass, so we only pulse
/// those states on that pass. On the other pass, it's as if they're not there.
/// </remarks>
private void EvaluateChooseElement(ProjectChooseElement chooseElement)

@rainersigwald rainersigwald added Area: Language Issues impacting the MSBuild programming language. Documentation and removed bug labels May 17, 2024
@AR-May AR-May added triaged backlog Priority:2 Work that is important, but not critical for the release labels May 21, 2024
@myth384
Copy link
Author

myth384 commented May 22, 2024

Hi @rainersigwald,
If I understand correctly, the observed behaviour is by design. Which would be quite logical if project related files are interpreted in multiple passes and the Choose block is only evaluated once. The current behaviour is therefore quite obscure, and I would rather avoid its usage altogether.
Would it be an option to modify the behaviour of the Choose block so it is evaluated in each pass?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Area: Language Issues impacting the MSBuild programming language. backlog Documentation Priority:2 Work that is important, but not critical for the release triaged
Projects
None yet
Development

No branches or pull requests

3 participants