Can't handle referenced build properties for AssemblyName
Current Behavior
We use the following definition in all our project files:
<RootNamespace>CycloneDxDotnet.Repro.WebApi</RootNamespace>
<AssemblyName>$(RootNamespace)</AssemblyName>
If you now reference multiple such projects in a main project, cyclonedx-dotnet throws an error:
Unhandled exception: System.ArgumentException: An item with the same key has already been added. Key: $(RootNamespace)
at System.Collections.Generic.Dictionary`2.TryInsert(TKey key, TValue value, InsertionBehavior behavior)
at System.Collections.Generic.Dictionary`2.Add(TKey key, TValue value)
at System.Linq.Enumerable.ToDictionary[TSource,TKey,TElement](IEnumerable`1 source, Func`2 keySelector, Func`2 elementSelector, IEqualityComparer`1 comparer)
at System.Linq.Enumerable.ToDictionary[TSource,TKey,TElement](IEnumerable`1 source, Func`2 keySelector, Func`2 elementSelector)
at CycloneDX.Services.ProjectFileService.RecursivelyGetProjectReferencesAsync(String projectFilePath) in /home/runner/work/cyclonedx-dotnet/cyclonedx-dotnet/CycloneDX/Services/ProjectFileService.cs:line 368
at CycloneDX.Services.ProjectFileService.RecursivelyGetProjectDotnetDependencysAsync(String projectFilePath, String baseIntermediateOutputPath, Boolean excludeTestProjects, String framework, String runtime) in /home/runner/work/cyclonedx-dotnet/cyclonedx-dotnet/CycloneDX/Services/ProjectFileService.cs:line 248
at CycloneDX.Runner.HandleCommandAsync(RunOptions options) in /home/runner/work/cyclonedx-dotnet/cyclonedx-dotnet/CycloneDX/Runner.cs:line 182
at CycloneDX.Program.<>c__DisplayClass0_0.<<Main>b__2>d.MoveNext() in /home/runner/work/cyclonedx-dotnet/cyclonedx-dotnet/CycloneDX/Program.cs:line 137
--- End of stack trace from previous location ---
at System.CommandLine.Invocation.AnonymousCommandHandler.InvokeAsync(InvocationContext context)
at System.CommandLine.Invocation.AnonymousCommandHandler.SyncUsingAsync(InvocationContext context)
at System.CommandLine.Invocation.AnonymousCommandHandler.Invoke(InvocationContext context)
at System.CommandLine.Invocation.InvocationPipeline.<>c__DisplayClass4_0.<<BuildInvocationChain>b__0>d.MoveNext()
--- End of stack trace from previous location ---
at System.CommandLine.Builder.CommandLineBuilderExtensions.<>c__DisplayClass17_0.<<UseParseErrorReporting>b__0>d.MoveNext()
--- End of stack trace from previous location ---
at System.CommandLine.Builder.CommandLineBuilderExtensions.<>c__DisplayClass12_0.<<UseHelp>b__0>d.MoveNext()
--- End of stack trace from previous location ---
at System.CommandLine.Builder.CommandLineBuilderExtensions.<>c__DisplayClass22_0.<<UseVersionOption>b__0>d.MoveNext()
--- End of stack trace from previous location ---
at System.CommandLine.Builder.CommandLineBuilderExtensions.<>c__DisplayClass19_0.<<UseTypoCorrections>b__0>d.MoveNext()
--- End of stack trace from previous location ---
at System.CommandLine.Builder.CommandLineBuilderExtensions.<>c.<<UseSuggestDirective>b__18_0>d.MoveNext()
--- End of stack trace from previous location ---
at System.CommandLine.Builder.CommandLineBuilderExtensions.<>c__DisplayClass16_0.<<UseParseDirective>b__0>d.MoveNext()
--- End of stack trace from previous location ---
at System.CommandLine.Builder.CommandLineBuilderExtensions.<>c.<<RegisterWithDotnetSuggest>b__5_0>d.MoveNext()
--- End of stack trace from previous location ---
at System.CommandLine.Builder.CommandLineBuilderExtensions.<>c__DisplayClass8_0.<<UseExceptionHandler>b__0>d.MoveNext()
Workaround
To work around this issue, you could set AssemblyName explicitly.
Reversing the reference of the build property is not a good solution because it can make problems in other tools (e.g. ReSharper):
<RootNamespace>$(AssemblyName)</RootNamespace>
<AssemblyName>CycloneDxDotnet.Repro.WebApi</AssemblyName>
Reproduction
For reproduction use the added solution folder and execute:
dotnet CycloneDX .\WebApi\WebApi.csproj -o . -f WebApi.sbom.json --json --recursive
Expected Behavior
Resolve referenced build properties for AssemblyName or detect such use cases and return a descriptive error message that cyclonedx-dotnet can't handle it.
Environment
dotnet cyclonedx --version
4.1.0+3ad0483c8724b6ddd0c20506b034dde5f8555b44
dotnet --info
.NET SDK:
Version: 8.0.404
Commit: 7b190310f2
Workload version: 8.0.400-manifests.c6df56b6
MSBuild version: 17.11.9+a69bbaaf5
Runtime Environment:
OS Name: Windows
OS Version: 10.0.19045
OS Platform: Windows
RID: win-x64
Base Path: C:\Program Files\dotnet\sdk\8.0.404\
.NET workloads installed:
Configured to use loose manifests when installing new manifests.
[aspire]
Installation Source: VS 17.11.35431.28
Manifest Version: 8.2.2/8.0.100
Manifest Path: C:\Program Files\dotnet\sdk-manifests\8.0.100\microsoft.net.sdk.aspire\8.2.2\WorkloadManifest.json
Install Type: FileBased
Host:
Version: 8.0.11
Architecture: x64
Commit: 9cb3b725e3
.NET SDKs installed:
8.0.404 [C:\Program Files\dotnet\sdk]
.NET runtimes installed:
Microsoft.AspNetCore.App 8.0.11 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.NETCore.App 3.1.22 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 3.1.23 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 5.0.14 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 6.0.12 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 6.0.13 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 6.0.15 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 6.0.36 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 8.0.11 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.WindowsDesktop.App 3.1.22 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
Microsoft.WindowsDesktop.App 3.1.23 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
Microsoft.WindowsDesktop.App 5.0.14 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
Microsoft.WindowsDesktop.App 6.0.13 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
Microsoft.WindowsDesktop.App 6.0.15 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
Microsoft.WindowsDesktop.App 6.0.36 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
Microsoft.WindowsDesktop.App 8.0.11 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
Other architectures found:
x86 [C:\Program Files (x86)\dotnet]
registered at [HKLM\SOFTWARE\dotnet\Setup\InstalledVersions\x86\InstallLocation]
Environment variables:
Not set
global.json file:
Not found
A workaround could also be to disable recursive. If not needed, I recommend to not use it as it can also cause inaccurate scan results.
The problem is likely here: https://github.com/CycloneDX/cyclonedx-dotnet/blob/790c3a79777f412e930a2ed68c2bde4f9ba98f79/CycloneDX/Services/ProjectFileService.cs#L99C1-L100C132.
It could become difficult to resolve those variables at design time, however for simpler cases, like $(RootNamespace), we could add handling.