dotnet / project-system

The .NET Project System for Visual Studio
MIT License
967 stars 386 forks source link

Fast up-to-date check doesn't trigger build when app.config modified #5918

Closed anlau closed 4 years ago

anlau commented 4 years ago

Visual Studio Version:

Version 16.4.5

Summary:

We recently migrated a .NET Framework WPF application to SDK-style projects and I encountered the following behavior.

Steps to Reproduce:

  1. Create a new WPF project: dotnet new wpf (dotnet -v is 3.1.101)

  2. Modify created csproj to target net452 (does not seem to matter, as long it is .NET Framework)

  3. Add an app.config file with minimal content (like an appSettings section with one entry)

  4. Build twice, the second time should output "1 up-to-date"

  5. Modify added app.config (ex. change existing entry key or value)

  6. Build

Expected Behavior:

Fast up-to-date check triggers a build.

Actual Behavior:

...
1>FastUpToDate: Project is up to date. (MyWpfProject)
1>FastUpToDate: Up to date check completed in 2,9 ms (MyWpfProject)
========== Build: 0 succeeded, 0 failed, 1 up-to-date, 0 skipped ==========

User Impact:

Not much; something which can be surprising or maybe annoying for developers (the build have to be forced by modifying something else).


When looking at the "Up to date checks" output, it seems an intermediate file is used as the source for the generated .exe.config:

1>FastUpToDate: Checking copied output (UpToDateCheckBuilt with Original property) file 'C:\Users\Antoine\Desktop\MyWpfProject\obj\Debug\net452\MyWpfProject.exe.withSupportedRuntime.config': (MyWpfProject)
1>FastUpToDate:     Source 2020-02-25 23:28:32: 'C:\Users\Antoine\Desktop\MyWpfProject\obj\Debug\net452\MyWpfProject.exe.withSupportedRuntime.config'. (MyWpfProject)
1>FastUpToDate:     Destination 2020-02-25 23:28:32: 'C:\Users\Antoine\Desktop\MyWpfProject\bin\Debug\net452\MyWpfProject.exe.config'. (MyWpfProject)

If <GenerateSupportedRuntime>false</GenerateSupportedRuntime> is added to the csproj, everything works as expected (source is now C:\Users\Antoine\Desktop\MyWpfProject\App.config).

Adding the following UpToDateCheckBuilt to the csproj seems to work too.

<ItemGroup>
  <UpToDateCheckBuilt Include="$(OutDir)\$(TargetFileName).config" Original="App.config" />
</ItemGroup>

Thanks!

drewnoakes commented 4 years ago

Triage note: Investigate whether the fix in 16.5 (#5851) addresses this.

ocallesp commented 4 years ago

@drewnoakes this issue still repro. It seems that the bug is because FUTD is using the incorrect source file to compare with the destination file. The current implementation is using the intermediate file as the source file instead of App.config. The data is given by state.CopiedOutputFiles. I started checking BuildUpToDateCheck.State

ocallesp commented 4 years ago

@drewnoakes

The target GenerateSupportedRuntime adds the items AppConfigWithTargetPath.

Why the target GenerateSupportedRuntime needs to remove this item ? <AppConfigWithTargetPath Remove="@(AppConfigWithTargetPath)" />

It seems that design-time builds is not updating the intermediate file whenever App.config changes. This should happen before the target CollectUpToDateCheckBuiltDesignTime.

https://github.com/dotnet/sdk/blob/8244c653ebeb83cf570c307b4b8bad5cd1ed1fe0/src/Tasks/Microsoft.NET.Build.Tasks/targets/Microsoft.NET.GenerateSupportedRuntime.targets#L21-L61

drewnoakes commented 4 years ago

This seems like a question for the SDK folks @dsplaisted @nguerrera

ocallesp commented 4 years ago

@drewnoakes this change fixes this issue https://github.com/ocallesp/project-system/commit/d5c54fffe9c25294cde4e0eea689a40e4378912e