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

Fix logging source-gens duplication on WPF #5024

Draft
wants to merge 8 commits into
base: main
Choose a base branch
from

Conversation

xakep139
Copy link
Member

@xakep139 xakep139 commented Mar 12, 2024

This is a naive fix for the #4969

We can also consider fixing RemoveDuplicateAnalyzers Target since it basically adds back the analyzer:
https://github.com/dotnet/ResXResourceManager/blob/c7f0d75c55917c5de01f807394c37dd2af11251b/src/Directory.Build.targets#L28

Microsoft Reviewers: Open in CodeFlow

@tarekgh
Copy link
Member

tarekgh commented Mar 12, 2024

Reading the comment #4969 (comment) it suggests the issue is not specific to extension telemetry library and it suggest the fix should be somewhere else maybe in SDK targets? I am not sure.

@RussKie
Copy link
Member

RussKie commented Mar 12, 2024

@tarekgh is there someone else you could suggest to rope in for a review of this?

@tarekgh
Copy link
Member

tarekgh commented Mar 12, 2024

@joperezr can advise about that. I have no idea why the analyzer get injected twice in the WPF scenario (if I am understanding the issue correctly).

@xakep139
Copy link
Member Author

xakep139 commented Mar 13, 2024

Reading the comment #4969 (comment) it suggests the issue is not specific to extension telemetry library and it suggest the fix should be somewhere else maybe in SDK targets? I am not sure.

In fact, it is specific for Microsoft.Extensions.Telemetry.Abstractions package. I left that comment to highlight that the root cause isn't related to Microsoft.Extensions.Resilience package - as the author wrote there. The latter references former, that's why it fails to compile even if you reference only resilience bits.

@xakep139
Copy link
Member Author

@joperezr can advise about that. I have no idea why the analyzer get injected twice in the WPF scenario (if I am understanding the issue correctly).

Correct, the issue doesn't happen on console projects, nor does it happen for WinForms.

@RussKie
Copy link
Member

RussKie commented Mar 13, 2024

If it's WPF specific, perhaps we should get WPF folks roped in? E.g., ping @dotnet/dotnet-wpf alias.

@xakep139
Copy link
Member Author

@dotnet/dotnet-wpf folks, can you please suggest a good way of disabling an analyzer/source-generator (or confirm that the approach in this PR is acceptable) for WPF apps?

@ZzZombo
Copy link

ZzZombo commented Mar 15, 2024

Is there anything interim for us to implement on our end in order to progress while you figure this out? Thanks in advance.

@RussKie
Copy link
Member

RussKie commented Mar 18, 2024

Is there anything interim for us to implement on our end in order to progress while you figure this out? Thanks in advance.

Copy the new target into your project, and it should remove the analyzers from the intermediate project.

@RussKie RussKie marked this pull request as draft March 19, 2024 00:32
@RussKie
Copy link
Member

RussKie commented Mar 19, 2024

Setting to draft for now until we agree this is the best way to proceed.

@ZzZombo
Copy link

ZzZombo commented Mar 20, 2024

I can confirm the change works! Thanks!

…dTransitive/net6.0/Microsoft.Extensions.Telemetry.Abstractions.targets
Copy link

@gdamiaN538 gdamiaN538 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Directory.Build.targets

Copy link

@gdamiaN538 gdamiaN538 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Directory.Build.targets

@RussKie
Copy link
Member

RussKie commented May 17, 2024

I propose the following change instead:

--- a/src/Libraries/Microsoft.Extensions.Telemetry.Abstractions/buildTransitive/net8.0/Microsoft.Extensions.Telemetry.Abstractions.targets
+++ b/src/Libraries/Microsoft.Extensions.Telemetry.Abstractions/buildTransitive/net8.0/Microsoft.Extensions.Telemetry.Abstractions.targets
@@ -2,10 +2,10 @@
   <!-- This package should replace the Microsoft.Extensions.Logging.Abstractions source generator. -->
   <Target Name="_Microsoft_Extensions_Logging_AbstractionsRemoveAnalyzers" 
           Condition="'$(DisableMicrosoftExtensionsLoggingSourceGenerator)' == 'true'"
-          AfterTargets="ResolveReferences">
+          BeforeTargets="CoreCompile">
     <ItemGroup>
-      <_Microsoft_Extensions_Logging_AbstractionsAnalyzer Include="@(Analyzer)" Condition="'%(Analyzer.AssemblyName)' == 'Microsoft.Extensions.Logging.Generators' Or
-                                                                                           '%(Analyzer.NuGetPackageId)' == 'Microsoft.Extensions.Logging.Abstractions'" />
+      <_Microsoft_Extensions_Logging_AbstractionsAnalyzer Include="@(Analyzer)" Condition="'%(Analyzer.Filename)' == 'Microsoft.Extensions.Logging.Generators' Or
+                                                                                           '%(Analyzer.Filename)' == 'Microsoft.Extensions.Logging.Abstractions'" />
     </ItemGroup>
 
     <!-- Remove Microsoft.Extensions.Logging.Abstractions Analyzer -->

@xakep139
Copy link
Member Author

@RussKie, thanks! I applied your change, please review

@RussKie RussKie requested a review from joperezr May 20, 2024 00:30
Condition="'$(DisableMicrosoftExtensionsLoggingSourceGenerator)' == 'true'"
AfterTargets="ResolveReferences">
BeforeTargets="CoreCompile">
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I haven't followed all of the thread here, but can you explain why this needs to happen before corecompile as opposed to after RAR? Are we expecting any other target to add the analyzer that is not RAR? For things like this, having a comment explaining why we want to run at a specific time is helpful.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can check Igor's message: #4969 (comment)
TL;DR: this works universally for both regular projects (e.g. console, web API) and WPF apps.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So, instead of having two targets, now we have just one.
We can't rely on ResolveReferences because for WPF there's an additional stage that doesn't take into account changes made with the current approach

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In that case, can we add a comment above explaining this? While we don't have a comment there today explaining why it was after ResolveReferences, that one feels obvious as it is the one that typically add's stuff the Analyzer item. On the other hand, it is not immediately obvious why we'd put it in the before CoreCompile, and especially now that we know there is an edge case we are covering for with WPF, so I'd probably write down a comment explaining that just doing it after RAR is not enough, and share this scenario.

Also, not sure if you tested, but it would be great to validate that this also works for design time builds. (Design time builds don't run all the exact same targets that are run during a regular build, so if you don't hook properly you could end up breaking intellisense. ResolveReferences is one of the ones that does run in both regular builds and design time builds)

Copy link
Member

@RussKie RussKie May 21, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ResolveReferences target doesn't exist in the WPF's temp project, which causes the original issue:
image

Intead the temp project has RemoveDuplicateAnalyzers target, which is run before CoreCompile target:
image

A WPF fix would be to run our target after RemoveDuplicateAnalyzers target, however, since that target is Windows Desktop specific, a more generic fix is to run our target before CoreCompile.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@joperezr I validated that it works both in compile and design time. Both WPF and WinForms apps are working just fine.
The new WinUI doesn't work though, so I guess I will have to update the targets again.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The new WinUI doesn't work though, so I guess I will have to update the targets again.

@xakep139 could you share more information? E.g., a binlog.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So, for WinUI applications the CoreCompile target happens after the XamlPreCompile target which causes the error:
image

I would recommend to stick with the initial solution and have the "standard" BeforeTargets="ResolveReferences" for non-WPF projects, and a separate RemoveDuplicateAnalyzers target for WPF ones.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please review the changes, folks

<ItemGroup>
<_Microsoft_Extensions_Logging_AbstractionsAnalyzer Include="@(Analyzer)" Condition="'%(Analyzer.AssemblyName)' == 'Microsoft.Extensions.Logging.Generators' Or
'%(Analyzer.NuGetPackageId)' == 'Microsoft.Extensions.Logging.Abstractions'" />
<_Microsoft_Extensions_Logging_AbstractionsAnalyzer Include="@(Analyzer)" Condition="'%(Analyzer.Filename)' == 'Microsoft.Extensions.Logging.Generators' Or
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure I'm following this. The analyzer will always be called Microsoft.Extensions.Logging.Generators, right? When will it be called Microsoft.Extensions.Logging.Abstractions?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch. @RussKie, should we remove the second part of the condition?

Copy link
Member

@RussKie RussKie May 21, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tbh, I don't understand why the original condition was written the way it was - that's a question to @joperezr.

I used %(Analyzer.Filename) because it is a) more obvious and b) this is what I saw inspecting binlogs.

If there's no real reason/need for this condition - I'd remove it.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I decided to get back to the original approach, as it makes sense to check the NuGet package ID. But please let me know if you have any doubts

Copy link
Member

@RussKie RussKie left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

:shipit:

</ItemGroup>

<!-- Remove Microsoft.Extensions.Logging.Abstractions Analyzer -->
<ItemGroup>
<Analyzer Remove="@(_Microsoft_Extensions_Logging_AbstractionsAnalyzer)" />
</ItemGroup>
</Target>

<!-- We have a separate target for WPF projects because there's "GenerateTemporaryTargetAssembly" target for those -->
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The comment is a good idea, but I feel like it could be expanded a little to make the reason clearer.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

The logging source generator emits CS0757 errors when referencing Microsoft.Extensions.Resilience
6 participants