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

contentFiles under "any" folder doesn't work with PackageReference-style with classic csproj #3042

Open
jainaashish opened this issue Dec 12, 2017 · 10 comments
Assignees
Labels
Feature-NuGet NuGet integration including pushing it properties, project and package references, and Pack support. Legacy Issues against the legacy project system. Triage-Investigate Reviewed and investigation needed by dev team
Milestone

Comments

@jainaashish
Copy link
Contributor

jainaashish commented Dec 12, 2017

Copied from NuGet/Home#6287

Details about Problem

Using VS UI/nuget.exe pack

NuGet version in VS: 4.5.0

VS version: 15.5.0

OS version: win10 v1709 (16299.98)

Detailed repro steps so we can see the same problem

  1. See the repro below. Basically try using contentFiles to control attributes like copyToOutput and have the target folder use "any" rather than a specific value
  2. Pack the nuspec and install the nupkg into a .NET Framework project using PackageReference style.
  3. Alternatively, use a CPS-style csproj with TargetFramwork=net471 (or similar)

Expected:
All the files listed appear in the output directory after building.

Actual:
Only the file in contentFiles\cs\net45 appears in the output directory after building.

Note that the bug does not repro when using a .NET Core project.
Note also that the bug is only for target locations such as:
contentFiles\cs\any
contentFiles\any\any

Things work correctly for targets such as:
contentFiles\cs\net45

Apologies if this is a dup, but I couldn't find this specific issue in a quick search.

Sample Project

repro.zip

@Pilchie Pilchie added Bug Legacy Issues against the legacy project system. Feature-NuGet NuGet integration including pushing it properties, project and package references, and Pack support. labels Dec 13, 2017
@Pilchie
Copy link
Member

Pilchie commented Dec 13, 2017

@jainaashish Can you help us understand how many such packages there are?

@jainaashish
Copy link
Contributor Author

I'm not sure of the numbers, but I would imagine it as a common scenario for ContentFiles since most cases, users aren't sure of {tfm} so they just keep it as any which is also mentioned in our docs.

But I can try running a script to get this number for you.

@Pilchie Pilchie added this to the 15.6 milestone Dec 13, 2017
@Pilchie Pilchie modified the milestones: 15.6, 15.7 Dec 22, 2017
@dadhi
Copy link

dadhi commented Dec 24, 2017

Observed the same issue in well known IOC Performance benchark maintained by @danielpalme.
I am trying to add DryIocZero 3 preview which contains .cs and .tt content files.
Working fine when adding to .Net Core project.

@Pilchie Pilchie modified the milestones: 15.7, 15.8 Apr 4, 2018
@Pilchie Pilchie modified the milestones: 15.8, 16.0 Jul 3, 2018
@tmeschter
Copy link
Contributor

@jainaashish I'm not sure this is a dotnet/project-system issue.

When using an SDK-based project targeting netcoreapp2.1 the .nuget.g.props file ends up with the following after a restore:

<ItemGroup Condition=" '$(Language)' == 'C#' AND '$(ExcludeRestorePackageImports)' != 'true' ">
  <None Include="$(NuGetPackageRoot)test\1.0.0\contentFiles\cs\any\Test.conf" Condition="Exists('$(NuGetPackageRoot)test\1.0.0\contentFiles\cs\any\Test.conf')">
    <NuGetPackageId>Test</NuGetPackageId>
    <NuGetPackageVersion>1.0.0</NuGetPackageVersion>
    <NuGetItemType>None</NuGetItemType>
    <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
    <TargetPath>Test.conf</TargetPath>
    <Private>True</Private>
    <Link>Test.conf</Link>
  </None>
  <None Include="$(NuGetPackageRoot)test\1.0.0\contentFiles\cs\any\Test.txt" Condition="Exists('$(NuGetPackageRoot)test\1.0.0\contentFiles\cs\any\Test.txt')">
    <NuGetPackageId>Test</NuGetPackageId>
    <NuGetPackageVersion>1.0.0</NuGetPackageVersion>
    <NuGetItemType>None</NuGetItemType>
    <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
    <TargetPath>Test.txt</TargetPath>
    <Private>True</Private>
    <Link>Test.txt</Link>
  </None>
  <None Include="$(NuGetPackageRoot)test\1.0.0\contentFiles\cs\any\Test2.cs" Condition="Exists('$(NuGetPackageRoot)test\1.0.0\contentFiles\cs\any\Test2.cs')">
    <NuGetPackageId>Test</NuGetPackageId>
    <NuGetPackageVersion>1.0.0</NuGetPackageVersion>
    <NuGetItemType>None</NuGetItemType>
    <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
    <TargetPath>Test2.cs</TargetPath>
    <Private>True</Private>
    <Link>Test2.cs</Link>
  </None>
</ItemGroup>

This seems reasonable, and those files are copied to the output as expected.

However, when using a csproj-based project targeting 4.6.1 none of these items appear in the .nuget.g.props. However, the "contentFiles\cs\net45\Test.cs" file does end up being copied to the output directory--I assume this is being done by the tasks/targets in NuGet/NuGet.BuildTasks.

It gets more confusing. If I update the SDK-based project to target net461 instead of netcoreapp2.1 and restore, then only the item under "contentFiles\cs\net45\Test.cs" file appears in the .nuget.g.props, and only that one is copied to the output:

<ItemGroup Condition=" '$(Language)' == 'C#' AND '$(ExcludeRestorePackageImports)' != 'true' ">
  <None Include="$(NuGetPackageRoot)test\1.0.0\contentFiles\cs\net45\Test.cs" Condition="Exists('$(NuGetPackageRoot)test\1.0.0\contentFiles\cs\net45\Test.cs')">
    <NuGetPackageId>Test</NuGetPackageId>
    <NuGetPackageVersion>1.0.0</NuGetPackageVersion>
    <NuGetItemType>None</NuGetItemType>
    <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
    <TargetPath>Test.cs</TargetPath>
    <Private>True</Private>
    <Link>Test.cs</Link>
  </None>
</ItemGroup>

So when targeting the same framework (4.6.1), the SDK and csproj behavior lines up (though clearly through different mechanisms).

A couple of questions:

  1. Should the .nuget.g.props file have the same contents, or is it intentionally different in csproj- vs SDK-based projects?
  2. Why wouldn't any apply when an SDK-based project targets net461?

@nkolev92
Copy link
Contributor

nkolev92 commented Oct 5, 2018

@tmeschter
That has to do with the weird implementations of any in NuGet.
In the build folder, it'll be different, any will apply to net461.

The root of all that evil is somewhere here.
https://github.com/NuGet/NuGet.Client/blob/dev/src/NuGet.Core/NuGet.Packaging/ContentModel/ManagedCodeConventions.cs

I have created an on NuGet's side to follow up on this.

NuGet/Home#7367

@jainaashish
Copy link
Contributor Author

@nkolev92 this issue isn't about build folder, instead about ContentFiles which is consistent for desktop framework or sdk. We shouldn't try to mix 2 different things.

And to answer @tmeschter questions:

  1. It's intentionally skipped in csproj with PackageReference since NuGet/NuGet.BuildTasks handles it, otherwise there will be duplicate files added into project. And this is done through skipContentFileWrite

  2. I'd imagine any should apply for sdk-based projects targeting net461 as well. Reason it didn't work in your case is because package has both any and net45 content files so it just picked net45 files for desktop framework. If you create a package with just any content files or try consuming https://www.nuget.org/packages/DryIocZero/4.0.0-preview-04, you will see it works with sdk-style projects (either targeting netstandard or net46) but doesn't work with csproj with PackageReference

@dadhi
Copy link

dadhi commented Oct 6, 2018

Btw, regarding the simplest workaround until this issue is fixed..

In DryIocZero 4 final version I've ended up with readme file popping up on package install, with instruction to copy .tt files manually from package to your project :/

@jjmew jjmew modified the milestones: 16.0, 16.X Feb 13, 2019
@tmeschter
Copy link
Contributor

Tom's triage notes: likely a straight-forward fix in NuGet/NuGet.BuildTasks. However, I don't have a good sense for how important it is to fix.

@tmeschter
Copy link
Contributor

@jainaashish Could you take a look at the PR I've created to fix this and let me know if the behavior seems correct?

@davkean davkean added this to the 16.6 milestone Feb 10, 2020
@davkean davkean added the Triage-Investigate Reviewed and investigation needed by dev team label Feb 10, 2020
@davkean
Copy link
Member

davkean commented Feb 10, 2020

@tmeschter Can you determine what should happen with this bug?

@jjmew jjmew modified the milestones: 16.6, 16.7 Mar 25, 2020
@tmeschter tmeschter modified the milestones: 16.7, 16.8 Jun 23, 2020
@drewnoakes drewnoakes modified the milestones: 16.8, 17.x Nov 29, 2021
@drewnoakes drewnoakes removed the Bug label Oct 16, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Feature-NuGet NuGet integration including pushing it properties, project and package references, and Pack support. Legacy Issues against the legacy project system. Triage-Investigate Reviewed and investigation needed by dev team
Projects
None yet
Development

No branches or pull requests

8 participants