NuGet / Home

Repo for NuGet Client issues
Other
1.49k stars 250 forks source link

ContentFiles build action is not applied on linux #6159

Open livarcocc opened 6 years ago

livarcocc commented 6 years ago

From @Petermarcu on October 6, 2017 21:49

@AnisAli commented on Mon Sep 11 2017

invalid csproj.nuget.g.props file generated by dotnet restore on Linux

I do have binary zip file and want to pack that zip file in nupkg as content therefore I am adding my binary file as content in csproj file

basicmodule.csproj

 <ItemGroup>
    <Content Include="package.zip">
     <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
     <Pack>True</Pack>
      <BuildAction>Content</BuildAction>
      <PackagePath>contentFiles\any\any\MyPackage\package.zip</PackagePath>
    </Content>
 </ItemGroup>

after packing basicmodule.csproj getting nuget package "basicmodule.1.0.1.nupkg and used this nuget package in another project called advancemodule.csproj

basicmodule.1.0.1 nuspec file after packing basicmodule.csproj

<?xml version="1.0" encoding="utf-8"?>
<package xmlns="http://schemas.microsoft.com/packaging/2013/05/nuspec.xsd">
  <metadata>
    <id>BasicModule</id>
    <version>1.0.1</version>
    <authors>BasicModule</authors>
    <owners>BasicModule</owners>
    <requireLicenseAcceptance>false</requireLicenseAcceptance>
    <description>The BasicModule is a simple example</description>
    <dependencies>
      <group targetFramework=".NETStandard2.0">
        <dependency id="Contracts" version="1.0.1.2" exclude="Build,Analyzers" />
      </group>
    </dependencies>
    <contentFiles>
      <files include="any/any/MyPackage/package.zip" buildAction="Content" />
    </contentFiles>
  </metadata>
</package>

When I run dotnet restore on advancemodule.csproj in the Linux enviornment, dotnet restore generates the basicmodule.1.0.1.csproj.nuget.g.props file with incorrect XML tag, instead of content tag for package.zip it generates compile tag

basicmodule.1.0.1.csproj.nuget.g.props generated inside obj folder after dotnet restore

<?xml version="1.0" encoding="utf-8" standalone="no"?>
<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <PropertyGroup Condition=" '$(ExcludeRestorePackageImports)' != 'true' ">
    <RestoreSuccess Condition=" '$(RestoreSuccess)' == '' ">True</RestoreSuccess>
    <RestoreTool Condition=" '$(RestoreTool)' == '' ">NuGet</RestoreTool>
    <ProjectAssetsFile Condition=" '$(ProjectAssetsFile)' == '' ">/build/src/BasicModule/obj/project.assets.json</ProjectAssetsFile>
    <NuGetPackageRoot Condition=" '$(NuGetPackageRoot)' == '' ">/root/.nuget/packages/</NuGetPackageRoot>
    <NuGetPackageFolders Condition=" '$(NuGetPackageFolders)' == '' ">/root/.nuget/packages/;/usr/share/dotnet/sdk/NuGetFallbackFolder</NuGetPackageFolders>
    <NuGetProjectStyle Condition=" '$(NuGetProjectStyle)' == '' ">PackageReference</NuGetProjectStyle>
    <NuGetToolVersion Condition=" '$(NuGetToolVersion)' == '' ">4.3.0</NuGetToolVersion>
  </PropertyGroup>
  <PropertyGroup>
    <MSBuildAllProjects>$(MSBuildAllProjects);$(MSBuildThisFileFullPath)</MSBuildAllProjects>
  </PropertyGroup>
  <ItemGroup Condition=" '$(ExcludeRestorePackageImports)' != 'true' ">

 <Compile 
Include="$(NuGetPackageRoot)basicmodule/1.0.1/contentfiles/any/any/MyPackage/package.zip" Condition="Exists('$(NuGetPackageRoot)basic$
      <NuGetPackageId>BasicModule</NuGetPackageId>
      <NuGetPackageVersion>1.0.1</NuGetPackageVersion>
      **<NuGetItemType>Compile</NuGetItemType>**
      <Private>False</Private>
      <Link>MyPackage/package.zip</Link>
    </Compile>

  </ItemGroup>
  <ImportGroup Condition=" '$(ExcludeRestorePackageImports)' != 'true' ">
    <Import Project="$(NuGetPackageRoot)xunit.runner.visualstudio/2.2.0/build/netcoreapp1.0/xunit.runner.visualstudio.props" Condition="Exists('$(NuGetPackageRoot)xunit.runner.visualstudio/$
    <Import Project="/usr/share/dotnet/sdk/NuGetFallbackFolder/microsoft.netcore.app/2.0.0/build/netcoreapp2.0/Microsoft.NETCore.App.props" Condition="Exists('/usr/share/dotnet/sdk/NuGetFal$
    <Import Project="$(NuGetPackageRoot)microsoft.net.test.sdk/15.3.0-preview-20170628-02/build/netcoreapp1.0/Microsoft.Net.Test.Sdk.props" Condition="Exists('$(NuGetPackageRoot)microsoft.n$
  </ImportGroup>
</Project>

Because of tag for contentfile in basicmodule.1.0.1.csproj.nuget.g.props getting error during dotnet build

CSC : error CS2015: '/root/localnuget/basicmodule/1.0.1/contentFiles/any/any/MyPackage/package.zip' is a binary file instead of a text file [/build/src/AdvanceModule/AdvanceModule.csproj]

Expected Behavior should be same as Windows

Copied from original issue: dotnet/cli#7784

livarcocc commented 6 years ago

From @Petermarcu on October 6, 2017 21:50

Moved this here for now. Not sure if NuGet is a better place or not...

emgarten commented 6 years ago

The contentFiles of the nuspec looks correct as well as the path. It seems it is not getting applied to the file during restore based on the output.

sandyarmstrong commented 6 years ago

I'm seeing this behavior with VSMac as well. I have a simple nuspec that has only contentFiles, and buildAction="None". The files are all in contentFiles\any\any\**.

The *.csproj.nuget.g.props file has <NuGetItemType>Compile</NuGetItemType> for all files, so my build also fails with CS2015, as these are not source code files.

I'm installing into a default Mono console project that I have converted to be SDK style. The csproj is literally just:

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <TargetFramework>net461</TargetFramework>
    <OutputType>Exe</OutputType>
  </PropertyGroup>
  <ItemGroup>
    <PackageReference Include="mynuget" Version="0.0.0" />
  </ItemGroup>
</Project>

VSmac 7.3 build 764 (which uses NuGet 4.3.1.4445).

sandyarmstrong commented 6 years ago

https://github.com/NuGet/Home/issues/5024 seems related.

sandyarmstrong commented 6 years ago

Okay, I'm starting to understand this a little better.

I was trying to use both the local layout of having my files in contentFiles\any\any and the contentFiles element in my metadata. It appears that when doing the former, the latter is totally ignored. So all my files were packed, but with the default buildAction (Compile).

But I cannot figure out how to properly use contentFiles without this layout. I tried removing the contentFiles folder, and instead just having everything in any, and then bringing them in like so:

<contentFiles>
  <files
    include="any\**"
    buildAction="None"
    copyToOutput="true" />
</contentFiles>

But then the packed layout doesn't have contentFiles at all (it just has a top-level any folder), and my files get totally ignored. They don't show up in *.csproj.nuget.g.props and they don't get copied to the build output directory.

EDIT: Sorry for the noise on this issue. Although I suppose it could be that other people are simply running into the same confusions I had. As far as I can tell, you need to have a contentFiles directory adjacent to your .nuspec when you run nuget pack. You can set the build action on the files by adding a contentFiles attribute, but the trick is to realize that the path in the include attribute is relative to contentFiles. So the sample contentFiles element I have above works fine as long as you understand that any is contentFiles\any, and contentFiles is next to the .nuspec. I'm sure I'm missing even more here, but at least it's working for me now.

grantbowering commented 6 years ago

I'm actually experiencing this same issue on Windows 10 in Visual Studio 2017, with packages that were generated via CI in a Linux environment. I don't experience the issue if I reference the same package built on my local Windows machine, and upon further inspection, the critical difference between the resulting packages appears to be the pathing in their respective .nuspec files.

On the right is the nuspec generated locally, and the left is generated on our linux CI: image

This occurs as a result of this item group in the .csproj files: image

Observations:

emgarten commented 6 years ago

@grantbowering this is an issue with consuming correctly authored packages. Your issue looks like a problem with pack, would you please open a new issue for it?

AnisAli commented 6 years ago

@emgarten @grantbowering

I found the actual problem which caused this issue. The path of the content file in the csproj files is in windows format (backward slash). By making it in Unix format (forward slash) fix this problem. BEFORE <PackagePath>contentFiles\any\any\MyPackage\package.zip</PackagePath>

AFTER <PackagePath>contentFiles/any/any/MyPackage/package.zip</PackagePath>

This change fixes both the issue which I was facing and @grantbowering is facing.