Open ds27680 opened 2 years ago
@ds27680 Have you taken a look at https://github.com/Humanizr/Humanizer/tree/main/NuSpecs ?
It seems this repo organization might solve how to ship localized packages without relying on contentFiles; unless you want to ship some contentFiles functionality for your package consumers.
Team Triage: Pulling into this sprint to analyze in more detail whether there's truly a bug here with .NET Framework projects, or whether the package can be authored differently.
NuGet Product Used
NuGet.exe, Visual Studio Package Management UI
Product Version
NuGet: 5.4.0.6315, VisualStudio: 2022
Worked before?
Not really
Impact
It's more difficult to complete my work
Repro Steps & Context
For the purpose of better managing translations, we are looking into moving resource files out of one of our projects to a repository where translators have access.
We would like to have the resource files only within that repository.
Currently, the resources are typically split within a project following this type of pattern:
One basically has folders ResourcesA, ResourcesB a.s.o. containing Resources.resx and their localizations.
The idea would be then, to generate NuGet packages from the separate repository, containing the resources as contentFiles, remove the resource files from our projects in the original repository, and simply reference the NuGet packages created from the repository the packages were moved to.
The original project containing the resources is a .Net Framework .csproj (currently targeting 4.8) using PackageReferences.
Generating NuGet packages is done using a Nuspec in the lines of:
Removing the *.resx files from the original project and referencing the NuGet package created using the above Nuspec leads to a build error:
Severity Code Description Project File Line Suppression State Error Two output file names resolved to the same output path: "obj\Debug\SomeClassLibrary.Resources.resources" SomeClassLibrary C:\Program Files\Microsoft Visual Studio\2022\Enterprise\MSBuild\Current\Bin\amd64\Microsoft.Common.CurrentVersion.targets 3262
Indeed, looking at the MSBuild output one has:
1>Task "AssignTargetPath" (TaskId:13) 1> Task Parameter:RootFolder=C:\Temp\NugetContentSample\TestContentPackage-WithPackageResourcesRemoved\SomeClassLibrary (TaskId:13) 1> Task Parameter: 1> Files= 1> C:\Users\mssdu.nuget\packages\someclasslibrary.resources\1.0.0\contentFiles\any\any\ResourcesA\Resources.es.resx 1> NuGetItemType=EmbeddedResource 1> NuGetPackageId=SomeClassLibrary.Resources 1> NuGetPackageVersion=1.0.0 1> C:\Users\mssdu.nuget\packages\someclasslibrary.resources\1.0.0\contentFiles\any\any\ResourcesA\Resources.resx 1> NuGetItemType=EmbeddedResource 1> NuGetPackageId=SomeClassLibrary.Resources 1> NuGetPackageVersion=1.0.0 1> C:\Users\mssdu.nuget\packages\someclasslibrary.resources\1.0.0\contentFiles\any\any\ResourcesB\Resources.es.resx 1> NuGetItemType=EmbeddedResource 1> NuGetPackageId=SomeClassLibrary.Resources 1> NuGetPackageVersion=1.0.0 1> C:\Users\mssdu.nuget\packages\someclasslibrary.resources\1.0.0\contentFiles\any\any\ResourcesB\Resources.resx 1> NuGetItemType=EmbeddedResource 1> NuGetPackageId=SomeClassLibrary.Resources 1> NuGetPackageVersion=1.0.0 (TaskId:13) 1> Output Item(s): 1> _Temporary= 1> C:\Users\mssdu.nuget\packages\someclasslibrary.resources\1.0.0\contentFiles\any\any\ResourcesA\Resources.es.resx 1> NuGetItemType=EmbeddedResource 1> NuGetPackageId=SomeClassLibrary.Resources 1> NuGetPackageVersion=1.0.0 1> OriginalItemSpec=C:\Users\mssdu.nuget\packages\someclasslibrary.resources\1.0.0\contentFiles\any\any\ResourcesA\Resources.es.resx 1> TargetPath=Resources.es.resx 1> C:\Users\mssdu.nuget\packages\someclasslibrary.resources\1.0.0\contentFiles\any\any\ResourcesA\Resources.resx 1> NuGetItemType=EmbeddedResource 1> NuGetPackageId=SomeClassLibrary.Resources 1> NuGetPackageVersion=1.0.0 1> OriginalItemSpec=C:\Users\mssdu.nuget\packages\someclasslibrary.resources\1.0.0\contentFiles\any\any\ResourcesA\Resources.resx 1> TargetPath=Resources.resx 1> C:\Users\mssdu.nuget\packages\someclasslibrary.resources\1.0.0\contentFiles\any\any\ResourcesB\Resources.es.resx 1> NuGetItemType=EmbeddedResource 1> NuGetPackageId=SomeClassLibrary.Resources 1> NuGetPackageVersion=1.0.0 1> OriginalItemSpec=C:\Users\mssdu.nuget\packages\someclasslibrary.resources\1.0.0\contentFiles\any\any\ResourcesB\Resources.es.resx 1> TargetPath=Resources.es.resx 1> C:\Users\mssdu.nuget\packages\someclasslibrary.resources\1.0.0\contentFiles\any\any\ResourcesB\Resources.resx 1> NuGetItemType=EmbeddedResource 1> NuGetPackageId=SomeClassLibrary.Resources 1> NuGetPackageVersion=1.0.0 1> OriginalItemSpec=C:\Users\mssdu.nuget\packages\someclasslibrary.resources\1.0.0\contentFiles\any\any\ResourcesB\Resources.resx 1> TargetPath=Resources.resx (TaskId:13)
So, it seems that the TargetPath gets flattened out, although this is not requested in the nuspec. Searched and found also this: #7255.
However:
The logs indicate that an attempt is being made to honor the contentFiles properly, and I did not find any indication in the documentation that the functionality does not work in .Net framework project with PackageReferences.
The NuGet package works as expected in a .Net Core project.
Even if I only have just the resources in ResourceA in the NuGet package I still get a build error (so the flattening of the folder structure is not the issue here), I have the impression it is more a conflict between the embedded resources from the NuGet and the default assembly manifest resources getting basically the same *.resource output names
I attached an archive to this report. Please see:
NugetContentSample-21.07.2022.zip
The archive contains:
Where:
NuGetContent: Contains the files and the Nuspec for generating the resources NuGet package. One can generate/re-generate the package by opening a cmd prompt in the folder and issuing: > nuget pack SomeClassLibrary.nuspec -OutputDirectory ../NuGetPackages
NuGetPackages: Contains the generated NuGet package. The projects contained in TestContentPackage-WithPackageResourcesRemoved and TestContentPackage-.NetCore configure this directory as the only Nuget package source avaiable for simplicity.
Screenshots: Contains some of the screenshots in the report.
TestContentPackage-Start: Contains the original "sample" .Net Framework project with the resource files in. Builds and works as expected. It contains a console project and a library (which contains the resources). The console can be executed with "en-US" or "es" as parameter and gets and prints out two resource strings one from the ResourcesA and one from ResourcesB, to illustrate that all works "as expected"
TestContentPackage-WithPackageResourcesRemoved: Contains a copy of the "sample" .Net Framework project where the resx files were removed from the library and the library references the resources NuGet package. It does not build, gives error message described above. Console app is also present and is identical to the one in TestContentPackage-Start.
TestContentPackage-.NetCore: A .Net Core project that similarly to the TestContentPackage-WithPackageResourcesRemoved contains a library where the resx files were removed and the library references the resources NuGet package. It builds and works as expected. It contains a console project that works in the same way as the one in "TestContentPackage-Start".
I know I could maybe "fix" my problem by using a .targets file that does copy the *.resx files to the projects before build, but I would rather avoid doing this.
Currently I'm still hoping that I am doing something something wrong...
Verbose Logs
No response