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

CS0229: Ambiguity between 'ThisAssembly.Info.Description' and 'ThisAssembly.Info.Description' when using Unclassified.NetRevisionTask #349

Closed
MagicAndre1981 opened this issue Jul 16, 2024 · 17 comments
Labels
enhancement New feature or request good first issue Good for newcomers help wanted Extra attention is needed

Comments

@MagicAndre1981
Copy link

Describe the Bug

some entries are generated twice, causing error CS0229: Ambiguity between 'ThisAssembly.Info.Description' and 'ThisAssembly.Info.Description'

Steps to Reproduce

add this config data from Unclassified.NetRevisionTask to Directory.Build.props :

<PropertyGroup>
		<NrtRevisionFormat>{semvertag}</NrtRevisionFormat>
		<NrtResolveSimpleAttributes>true</NrtResolveSimpleAttributes>
		<NrtResolveInformationalAttribute>true</NrtResolveInformationalAttribute>
		<NrtResolveCopyright>false</NrtResolveCopyright>
		<NrtTagMatch>v[0-9]*</NrtTagMatch>
		<NrtRemoveTagV>true</NrtRemoveTagV>
		<NrtRequiredVcs>svn</NrtRequiredVcs>
		<NrtShowRevision>true</NrtShowRevision>
	</PropertyGroup>

	<ItemGroup>
		<PackageReference Include="Unclassified.NetRevisionTask" Version="0.4.3">
			<PrivateAssets>all</PrivateAssets>
			<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
		</PackageReference>
	</ItemGroup>

and

[assembly: AssemblyVersion("0.0.0.0")]
[assembly: AssemblyInformationalVersion("1.2.{revnum}.0")]

to AssemblyInfo.cs to let Unclassified.NetRevisionTask generate the 3rd number based on the commit number from subversion (Yes, I still use subversion).

Expected Behavior

only 1 entry in generated code

Version Info

    <PackageReference Include="ThisAssembly" Version="1.4.3">
      <PrivateAssets>all</PrivateAssets>
      <IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
    </PackageReference>

Additional Info

image

image

Here you can see the doubled entries.

I want to replace my older runtime code

copyrightAttribute = assembly
				.GetCustomAttributes<AssemblyCopyrightAttribute>(false)
				.FirstOrDefault();

to get Copyright and others with your generated code and here I noticed this conflict.

Unclassified.NetRevisionTask merges all finished calculations into a file called NrtAssemblyInfo.cs.

So is it possible to detect this package and only use the data from the NrtAssemblyInfo.cs?

@MagicAndre1981 MagicAndre1981 added the bug Something isn't working label Jul 16, 2024
@MagicAndre1981
Copy link
Author

Is there a chance to fix this issue? @kzu

@kzu
Copy link
Member

kzu commented Jul 21, 2024

I'm not familiar with what Unclassified.NetRevisionTask does on how it works. If it's important to support that for you, I'd be glad to review and merge a PR for it.

@kzu kzu added enhancement New feature or request help wanted Extra attention is needed good first issue Good for newcomers and removed bug Something isn't working labels Jul 21, 2024
@MagicAndre1981
Copy link
Author

MagicAndre1981 commented Jul 21, 2024

I'm not familiar with what Unclassified.NetRevisionTask does on how it works.

as said, it hookes into Build process (<Target Name="NrtPatchAssemblyInfo" BeforeTargets="GenerateAdditionalSources">), reads the AssemblyInfo data from the normal AssemblyInfo.cs + the dummy data and creates a new AssemblyInfo.cs where the dummy data ([assembly: AssemblyInformationalVersion("1.1.{revnum}.0")]) get replaced with actual data from git or Subversion (revision), it next removed the original AssemblyInfo.cs from file list of files that should be compiled ( <Compile Remove="$(NrtSourceAssemblyInfo)" />) and adds the patched file (<Compile Include="$(NrtPatchedAssemblyInfo)" />).

Now I have 2 AssemblyInfo.cs in my project and your source generator picks data from both which causes my "Ambiguity between" error.

So maybe you can check the filenames when you read the AssemblyInfo data and if the name is NrtAssemblyInfo.cs only use the data from this file and ignore the normal AssemblyInfo.cs.

I tried source generators when they were added in .net 5 (?) and gave it up as it was horrible to debug them and so I can't really help here.

@MagicAndre1981
Copy link
Author

I've replaced the nuget references with the csproj of your generator and tried to configure the debug options of the source generator and I get a VS error:

Microsoft.VisualStudio.ProjectSystem.Query.QueryExecutionException: Value cannot be null.
Parameter name: value ---> System.ArgumentNullException: Value cannot be null.
Parameter name: value
   at System.String.EndsWith(String value, StringComparison comparisonType)
   at Roslyn.ComponentDebugger.ProjectUtilities.<GetComponentReferencingProjectsAsync>d__0.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Roslyn.ComponentDebugger.TargetProjectEnumProvider.<GetProviderAsync>d__3.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.VisualStudio.ProjectSystem.PropertyPages.PageDynamicEnumProperty.<GetAdmissibleEnumValueAsync>d__5.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.VisualStudio.ProjectSystem.PropertyPages.PageEnumPropertyBase.<GetValueAsIEnumValueAsync>d__4.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.VisualStudio.ProjectSystem.VS.Query.UIPropertyValueDataProducer.<CreateUIPropertyValueValueAsync>d__1.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.VisualStudio.ProjectSystem.VS.Query.UIPropertyValueDataProducer.<CreateUIPropertyValueValueAsync>d__0.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at Microsoft.VisualStudio.ProjectSystem.VS.Query.UIPropertyValueDataProducer.<CreateUIPropertyValueValuesAsync>d__2.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.VisualStudio.ProjectSystem.VS.Query.QueryDataFromProviderStateProducerBase`1.<SendRequestAsync>d__0.MoveNext()
   --- End of inner exception stack trace ---
   at Microsoft.VisualStudio.ProjectSystem.Query.Execution.QuerySubscription`1.<RunQueryOnceAsync>d__11.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.VisualStudio.ProjectSystem.Query.Execution.QuerySubscription`1.<>c__DisplayClass10_0.<<Start>b__0>d.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.VisualStudio.ProjectSystem.VS.Implementation.PropertyPages.Designer.LaunchProfileSubscription.<CreateAsync>d__42.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.VisualStudio.ProjectSystem.VS.Implementation.PropertyPages.Designer.LaunchProfilesWindow.<>c__DisplayClass0_0.<<-ctor>b__0>d.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.VisualStudio.ProjectSystem.VS.Implementation.PropertyPages.Designer.AsyncLoadContent.<>c__DisplayClass0_0.<<Initialize>b__0>d.MoveNext()

So same terrible experience again...

I need to get some sleep now as it is alreay 1am here in Germany.

@MagicAndre1981
Copy link
Author

How can I debug the generator? I followed this document but get the mentioned error. I have .NET Compiler Platform SDK installed under Vs 2022 17.10.4

@MagicAndre1981
Copy link
Author

added the generator as csproj to a demo doesn't add the 2 required data

OutputItemType="Analyzer"
ReferenceOutputAssembly="false"

to the ProjectReference entry and now I can select the debug target to the demo.

@MagicAndre1981
Copy link
Author

with attributeNode.GetLocation() in static KeyValuePair<string, string>? GetAttributes(GeneratorSyntaxContext ctx, CancellationToken token) I can see the code location and here I only see entries from NrtAssemblyInfo.cs, in GenerateSource() I see the list of attributes (attributes.ToList()) and here they are only added once with the correct data and now I'm confused

@MagicAndre1981
Copy link
Author

now the main application with the nuget reference starts fine inside debugger all code calls fetch the correct data.

So this looks like a VS bug

@MagicAndre1981
Copy link
Author

I've updated from 1.5.0-rc.1 to 1.5.0-rc.2 and the issue was gone, now it is back after several opening/closings of the solution. So something has changed.

@MagicAndre1981
Copy link
Author

I've updated from 1.5.0-rc.1 to 1.5.0-rc.2 and the issue was gone

ok, the update changed the nuget files in obj folder with the restore data. When I always clean those data, open the solution, let VS write the nuget data again I don't suffer the issue.

@kzu
Copy link
Member

kzu commented Jul 24, 2024

You can switch to the ThisAssembly.Constants instead and only lift the values you are interested in accessing via code. Or alternatively ThisAssembly.Project to lift project properties.

@kzu
Copy link
Member

kzu commented Jul 24, 2024

I'd say the issue is when the patch target runs. It seems to be running inconsistently between full build and design-time builds. To force it to run always BEFORE generators see any code, add the following:

<Target Name="EnsureNrtPatchAssemblyInfo" 
              BeforeTargets="GenerateMSBuildEditorConfigFileShouldRun" 
              DependsOnTargets="NrtPatchAssemblyInfo" />

@MagicAndre1981
Copy link
Author

where should I add this to? I've added this to the Unclassified.NetRevisionTask.targets, made a 0.4.4-beta1 nuget and updated my solution to this version, but the same happens again. If the nuget temp data are not available I don't get the issue, but after close and reopening of the solution I get the error again.

@MagicAndre1981
Copy link
Author

the only difference is now that the correct data are on top and the dummy data are added under it (difference to what I saw before as shown in the picture)

@MagicAndre1981
Copy link
Author

the order changes each time now. I also compared the generated nuget/msbuild files after 1st and 2nd load and they don't change.

I'm now out of ideas.

@kzu
Copy link
Member

kzu commented Aug 2, 2024

Report the bug to Unclassified? You add the target to your project file, or a Directory.Build.targets. Or switch to ThisAssembly.Constants instead to avoid collisions. I'm closing this since this isn't planned on my end.

@kzu kzu closed this as not planned Won't fix, can't repro, duplicate, stale Aug 2, 2024
@MagicAndre1981
Copy link
Author

MagicAndre1981 commented Aug 5, 2024

I think this is a VS issue. The generated exe has the correct assembly data and I can call them correctly at runtime.

The ThisAssembly.AssemblyInfo.g.cs inside the obj generated\ThisAssembly.AssemblyInfo\ThisAssembly.AssemblyInfoGenerator folder has the correct data but when I select Go to Definition and select Open containing folder I see empty file in C:\Users\André\AppData\Local\Temp\VSGeneratedDocuments\8b3f3a52-2fd0-c00f-3c33-22a20ae13471 So VS has issues with the data in memory and mixes them.

@devlooped devlooped locked and limited conversation to collaborators Sep 5, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
enhancement New feature or request good first issue Good for newcomers help wanted Extra attention is needed
Projects
None yet
Development

No branches or pull requests

2 participants