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

NuGetizer v0.9.1 packing reference assembly instead of real assembly #263

Closed
RichardD2 opened this issue Nov 28, 2022 · 8 comments · Fixed by #282
Closed

NuGetizer v0.9.1 packing reference assembly instead of real assembly #263

RichardD2 opened this issue Nov 28, 2022 · 8 comments · Fixed by #282
Labels
bug Something isn't working

Comments

@RichardD2
Copy link

Describe the Bug

I have a .NET Framework 4.8 project using NuGetizer 0.9.1 which is set up to generate a package on the release build.

Since upgrading to VS2022 v17.4, the generated package contains the reference assembly version of System.Buffers, despite the project having an explicit reference to that package.

Steps to Reproduce

Create a new console application. Add references to System.Memory, System.Buffers, and NuGetizer. Set the package ID and the "generate package on build" flag.

<Project Sdk="Microsoft.NET.Sdk">
    <PropertyGroup>
        <OutputType>Exe</OutputType>
        <TargetFramework>net48</TargetFramework>
        <GeneratePackageOnBuild>True</GeneratePackageOnBuild>
        <PackageId>TestNuGetizer</PackageId>
    </PropertyGroup>

    <ItemGroup>
        <PackageReference Include="System.Buffers" Version="4.5.1" PrivateAssets="all" />
        <PackageReference Include="System.Memory" Version="4.5.5" PrivateAssets="all" />
        <PackageReference Include="NuGetizer" Version="0.9.1">
            <PrivateAssets>all</PrivateAssets>
            <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
        </PackageReference>
    </ItemGroup>
</Project>

Build the project.

Open the generated nupkg file in NuGet Package Explorer.

Extract lib/net48/System.Buffers.dll from the file.

Observe that the file is the reference assembly, not the real assembly. Specifically, the reference assembly is 15Kb whereas the real assembly is 21Kb. If you open the file with a decompiler, you will see there are no bodies defined for any methods or properties.

Expected Behavior

The generated nupkg file should contain the real assembly.

Version Info

NuGetizer v0.9.1 (latest stable)
VS2022 v17.4.1

Additional Info

The same project generated the correct package in VS v17.3.x

@RichardD2 RichardD2 added the bug Something isn't working label Nov 28, 2022
@kzu
Copy link
Member

kzu commented Feb 4, 2023

Does this work as expected if you use the built-in SDK Pack instead?

@RichardD2
Copy link
Author

Using dotnet pack at the command-line produces the same output - the reference version of System.Buffers is included rather than the real version.

Removing NuGetizer from the project results in a package that doesn't contain any of the referenced assemblies. That would be fine for a package that was going to be referenced from another project; but I'm using this to build a Squirrel.Windows package for distribution, which needs to contain all of the assemblies.

As a workaround, I had to create an explicit nuspec file to include all of the files from the output directory, and an explicit post-build step to build the package before "releasifying" it.

<?xml version="1.0" encoding="utf-8"?>
<package xmlns="http://schemas.microsoft.com/packaging/2012/06/nuspec.xsd">
  <metadata>
    <id>My-Package-Id</id>
    <version>0.0.0.0</version>
    <authors>...</authors>
    <requireLicenseAcceptance>false</requireLicenseAcceptance>
    <icon>MyIcon.png</icon>
    <projectUrl>...</projectUrl>
    <description>...</description>
    <copyright>...</copyright>
    <language>en-GB</language>
    <tags>Library</tags>
    <dependencies>
      <group targetFramework=".NETFramework4.7.2" />
    </dependencies>
    <frameworkAssemblies>
      <frameworkAssembly assemblyName="Microsoft.CSharp" targetFramework=".NETFramework4.7.2" />
      <frameworkAssembly assemblyName="PresentationCore" targetFramework=".NETFramework4.7.2" />
      <frameworkAssembly assemblyName="PresentationFramework.Aero" targetFramework=".NETFramework4.7.2" />
      <frameworkAssembly assemblyName="PresentationFramework" targetFramework=".NETFramework4.7.2" />
      <frameworkAssembly assemblyName="ReachFramework" targetFramework=".NETFramework4.7.2" />
      <frameworkAssembly assemblyName="System.ComponentModel.DataAnnotations" targetFramework=".NETFramework4.7.2" />
      <frameworkAssembly assemblyName="System.Configuration" targetFramework=".NETFramework4.7.2" />
      <frameworkAssembly assemblyName="System.Data.OracleClient" targetFramework=".NETFramework4.7.2" />
      <frameworkAssembly assemblyName="System.Design" targetFramework=".NETFramework4.7.2" />
      <frameworkAssembly assemblyName="System.Drawing.Primitives" targetFramework=".NETFramework4.7.2" />
      <frameworkAssembly assemblyName="System.IO" targetFramework=".NETFramework4.7.2" />
      <frameworkAssembly assemblyName="System.Net" targetFramework=".NETFramework4.7.2" />
      <frameworkAssembly assemblyName="System.Net.Http" targetFramework=".NETFramework4.7.2" />
      <frameworkAssembly assemblyName="System.Printing" targetFramework=".NETFramework4.7.2" />
      <frameworkAssembly assemblyName="System.Runtime" targetFramework=".NETFramework4.7.2" />
      <frameworkAssembly assemblyName="System.Runtime.InteropServices.RuntimeInformation" targetFramework=".NETFramework4.7.2" />
      <frameworkAssembly assemblyName="System.Security.Cryptography.Algorithms" targetFramework=".NETFramework4.7.2" />
      <frameworkAssembly assemblyName="System.Security.Cryptography.Encoding" targetFramework=".NETFramework4.7.2" />
      <frameworkAssembly assemblyName="System.Security.Cryptography.Primitives" targetFramework=".NETFramework4.7.2" />
      <frameworkAssembly assemblyName="System.Security.Cryptography.X509Certificates" targetFramework=".NETFramework4.7.2" />
      <frameworkAssembly assemblyName="System.Security" targetFramework=".NETFramework4.7.2" />
      <frameworkAssembly assemblyName="System.ServiceProcess" targetFramework=".NETFramework4.7.2" />
      <frameworkAssembly assemblyName="System.Transactions" targetFramework=".NETFramework4.7.2" />
      <frameworkAssembly assemblyName="System.Xaml" targetFramework=".NETFramework4.7.2" />
      <frameworkAssembly assemblyName="WindowsBase" targetFramework=".NETFramework4.7.2" />
    </frameworkAssemblies>
  </metadata>
  <files>
    <file src="*.*" target="lib\net472\" exclude="*.nupkg;*.vshost.*;*.xml;*.dll.config"/>
    <file src="..\..\..\..\..\MyIcon.png" target="MyIcon.png" />
  </files>
</package>
<Target Name="SquirrelReleasify" AfterTargets="PostBuildEvent" Condition="'$(Configuration)' == 'Release'">
    <GetAssemblyIdentity AssemblyFiles="$(TargetPath)">
        <Output TaskParameter="Assemblies" ItemName="myAssemblyInfo" />
    </GetAssemblyIdentity>

    <PropertyGroup>
        <NuGetPackageRoot Condition=" '$(NuGetPackageRoot)' == '' ">$(USERPROFILE)\.nuget\packages\</NuGetPackageRoot>
    </PropertyGroup>

    <ItemGroup>
        <SquirrelExe Include="$(NuGetPackageRoot)\Squirrel.Windows\2.0.1\tools\squirrel.exe" />
    </ItemGroup>

    <PropertyGroup>
        <ReleaseDir>$(ProjectDir)Releases</ReleaseDir>
        <SquirrelParams>--no-msi --framework-version=net472 -n "/a /f ""$(ProjectDir)MyCert.pfx"" /p MyCertPassword /fd sha256 /tr http://timestamp.digicert.com /td sha256"</SquirrelParams>
        <SemVerNumber>$([System.Version]::Parse(%(myAssemblyInfo.Version)).ToString(3))</SemVerNumber>
        <SourcePackage>$(ProjectDir)bin\$(Configuration)\My-Package-Id.$(SemVerNumber).nupkg</SourcePackage>
    </PropertyGroup>

    <Error Condition="!Exists(%(SquirrelExe.FullPath))" Text="You are trying to use the Squirrel.Windows package, but it is not installed. Please install Squirrel.Windows from the Package Manager. [%(SquirrelExe.FullPath)]" />

    <Exec Command="nuget pack My-Package-Id.nuspec -Version %(myAssemblyInfo.Version) -Properties Configuration=$(Configuration) -OutputDirectory $(ProjectDir)bin\$(Configuration)\ -BasePath $(OutDir)" />

    <Error Condition="!Exists($(SourcePackage))" Text="The source package $(SourcePackage) does not exist." />

    <Exec Command="&quot;%(SquirrelExe.FullPath)&quot; --releasify &quot;$(SourcePackage)&quot; --releaseDir=&quot;$(ReleaseDir)&quot; $(SquirrelParams)" />
</Target>

@kzu
Copy link
Member

kzu commented Feb 6, 2023

Oh no, that's the worst, nuspec should die for good ;).

NuGetizer provides advanced extensibility via MSBuild so you never need to do that, however challenging your scenario might seem. Check the advanced scenarios in the readme. In particular, pulling arbitrary files from package references should totally solve your issue (while I investigate how to properly solve it).

See https://github.com/devlooped/nugetizer/#packing-arbitrary-files-from-referenced-packages

A combination of Pack=false on the reference plus explicit packing if the files your want, should fix it.

@RichardD2
Copy link
Author

This seems to produce the correct output:

<ItemGroup>
    <PackageReference Include="System.Buffers" Version="4.5.1" GeneratePathProperty="true" Pack="false" />
    <PackageReference Include="System.Memory" Version="4.5.5" PrivateAssets="all" />
    <PackageReference Include="NuGetizer" Version="0.9.1">
        <PrivateAssets>all</PrivateAssets>
        <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
    </PackageReference>
</ItemGroup>

<ItemGroup>
    <PackageFile Include="lib/net461/System.Buffers.dll" PackagePath="lib/net48/System.Buffers.dll" PackageReference="System.Buffers" />
</ItemGroup>

image

image

However, VS2022 now shows lib/net461/System.Buffers.dll as a missing file/folder:

image

Have I missed something?

@kzu
Copy link
Member

kzu commented Feb 10, 2023

Just add Visible=false to the item (that's just how VS/MSBuild works by default):

<PackageFile Include="lib/net461/System.Buffers.dll" 
             PackagePath="lib/net48/System.Buffers.dll" 
             PackageReference="System.Buffers" 
             Visible="false" />

@kzu
Copy link
Member

kzu commented Feb 10, 2023

BTW, you can simplify nugetizer reference to just <PackageReference Include="NuGetizer" Version="0.9.1" />. It will never pack itself as a dependency.

@kzu
Copy link
Member

kzu commented Feb 10, 2023

Looking at the underlying root cause, something seems to be specific to System.Buffers, because System.Memory is packed as expected:

(using msbuildlog.com)

image

@kzu
Copy link
Member

kzu commented Feb 10, 2023

Found the root cause! dotnet/msbuild#3069

kzu added a commit that referenced this issue Feb 10, 2023
We were previously using a combination of @(ReferencePath) and @(_ReferenceRelatedPaths) to determine the candidate libs to pack as private, but this was incorrect since we would still sometimes pack ref assemblies.

Turns out that this is an issue that surfaced elsewhere (see NuGet/Home#9310 (comment)) which resulted in a new output group being available from the common MSBuild targets (see dotnet/msbuild#3069) that we can use instead to do this properly.

Closes #263
kzu added a commit that referenced this issue Feb 10, 2023
We were previously using a combination of @(ReferencePath) and @(_ReferenceRelatedPaths) to determine the candidate libs to pack as private, but this was incorrect since we would still sometimes pack ref assemblies.

Turns out that this is an issue that surfaced elsewhere (see NuGet/Home#9310 (comment)) which resulted in a new output group being available from the common MSBuild targets (see dotnet/msbuild#3069) that we can use instead to do this properly.

Closes #263
kzu added a commit that referenced this issue Feb 10, 2023
We were previously using a combination of @(ReferencePath) and @(_ReferenceRelatedPaths) to determine the candidate libs to pack as private, but this was incorrect since we would still sometimes pack ref assemblies.

Turns out that this is an issue that surfaced elsewhere (see NuGet/Home#9310 (comment)) which resulted in a new output group being available from the common MSBuild targets (see dotnet/msbuild#3069) that we can use instead to do this properly.

Closes #263
kzu added a commit that referenced this issue Feb 10, 2023
We were previously using a combination of @(ReferencePath) and @(_ReferenceRelatedPaths) to determine the candidate libs to pack as private, but this was incorrect since we would still sometimes pack ref assemblies.

Turns out that this is an issue that surfaced elsewhere (see NuGet/Home#9310 (comment)) which resulted in a new output group being available from the common MSBuild targets (see dotnet/msbuild#3069) that we can use instead to do this properly.

Closes #263
@kzu kzu closed this as completed in #282 Feb 10, 2023
kzu added a commit that referenced this issue Feb 10, 2023
We were previously using a combination of @(ReferencePath) and @(_ReferenceRelatedPaths) to determine the candidate libs to pack as private, but this was incorrect since we would still sometimes pack ref assemblies.

Turns out that this is an issue that surfaced elsewhere (see NuGet/Home#9310 (comment)) which resulted in a new output group being available from the common MSBuild targets (see dotnet/msbuild#3069) that we can use instead to do this properly.

Closes #263
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants