0

I'm building a NuGet package with a folder hierarchy that looks like this:

ProjectDir
    Infrastructure
        class1.cs
        class2.cs
    Task
        class3.cs
        class3.cs
    StuffToInclude
        SampleCode
            sampleclass1.cs.pp
            sampleclass2.cs.pp
        Images
            image1.gif
            image2.gif
        Doc
            text1.txt
            text2.txt
    Project.nuspec

Note the nuspec file is generated simply with the "nuget spec" command, and then the following file section is added:

<files>
    <file src="StuffToInclude\**\*.*" target="content" />
</files>

What I would expect (and want) is a content folder in the package that looks like this:

content
    SampleCode
        sampleclass1.cs.pp
        sampleclass2.cs.pp
    Images
        image1.gif
        image2.gif
    Doc
        text1.txt
        text2.txt

What I get however is a slightly larger content folder that includes a second copy of the "StuffToInclude" folder, looking like this:

content
    StuffToInclude
        Images
            image1.gif
            image2.gif
        Doc
            text1.txt
            text2.txt
    SampleCode
        sampleclass1.cs.pp
        sampleclass2.cs.pp
    Images
        image1.gif
        image2.gif
    Doc
        text1.txt
        text2.txt

Notice that the undesired StuffToInclude folder does not have the SampleCode subfolder in it -- somehow the nuget packer figured out that ".pp" files should not be placed in the content unless explicitly asked for. But all those other files (in all the other folders) are unnecessarily duplicated and it is not desirable to have them there - because when the package is consumed, that folder is also duplicated in the target project.

I thought perhaps something like this in the nuspec would help:

<files>
    <file src="StuffToInclude\**\*.*" target="content" exclude="StuffToInclude\**\*.*"/>
</files>

but all variants I have tried for the "exclude" attribute don't seem to help.

How do I exclude the "StuffToInclude" file from being included in the content folder?

Many thanks.

Pod Mo
  • 248
  • 2
  • 8
Stephan G
  • 3,289
  • 4
  • 30
  • 49
  • I followed your steps and got what you want. So I think maybe you make some mistake during packing, could you share the more content of the .nuspec?(Deleting the personal data like id,author...) And do you use the command `nuget spec` and `nuget pack xx.xxspec`? If not, please share the real command you use. – LoLance Jul 11 '19 at 02:22

1 Answers1

1

How to stop NuGet packaging from including unwanted files

I assume the command you use when creating the package is something like nuget pack xx.csproj.

If so, what's the special reason you created a package based on project file after creating the .nuspec file?

According to this document, we can use nuget pack command based on the specified .nuspec or project file.

So usually, if we create a package based on .csproj, there's no need to create a .nuspec file. Also, if we want to create a package based on .nuspec, I suggest use command nuget pack xx.nuspec instead of nuget pack xx.csproj.

Cause of the issue:

I've done some tests and found when we put Project.nuspec file in project dir, and use a command like nuget pack xx.csproj,then the nuget.exe will read data from both xx.nuspec and xx.csproj, that's why you have a second copy.

1# Structure for nuget pack xx.csproj if no xx.nuspec in same directory:

content
    StuffToInclude
        Images
            image1.gif
            image2.gif
        Doc
            text1.txt
            text2.txt

2# Structure for nuget pack xx.nuspec:

content
    SampleCode
        sampleclass1.cs.pp
        sampleclass2.cs.pp
    Images
        image1.gif
        image2.gif
    Doc
        text1.txt
        text2.txt

And when you use nuget pack command based on project file(.csproj) where exists a ProjectName.nuspec, it reads data from both .csproj and .nuspec. so it results in the second copy like what you got.

To resolve it:

  1. Keep the xx.nuspec file and use command like nuget pack xx.nuspec.(suggested)

  2. Delete the xx.nuspec file(Or delete the <Files> section) and use command like nuget pack xx.csproj, to include those xx.cs.pp files into content folder, you may need to set their build action to content.

  3. Keep both the xx.nuspec file and the xx.csproj file (see below) and everything you want in the xx.nuspec file, but to avoid the unwanted second copies of things, make sure that every single item you don't want copied twice is set to a Build Action of None.

Stephan G
  • 3,289
  • 4
  • 30
  • 49
LoLance
  • 25,666
  • 1
  • 39
  • 73
  • Thanks Lance. I've played with both of your ideas for resolution, and neither is ideal. I specifically created the NuSpec file so that I could list framework dependencies, files, etc. However when it was generated it has the nifty ability to refer to variable parameters (like title of $id$, and so forth) that come from MSBuild, but only if the pack is against the project file, not the nuspec file. So it seems like there was a great deal of thought that went into making that whole process very convenient, but there does seem to be a hole left because of this issue. Any other insights? – Stephan G Jul 11 '19 at 21:26
  • Further trials on your resolution #2.... seems like the only way to do this is to pollute the directory hierarchy of the source project with the actual content you want copied into the target consuming project through NuGet. So I think I have confirmed that it is theoretically possible, but definitely kind of ugly and difficult to maintain. – Stephan G Jul 11 '19 at 21:40
  • 1
    Lance - Your work triggered my ability to solve this -- I edited your solution to include a new #3 resolution as follows: "Keep both the xx.nuspec file and the xx.csproj file (see below) and everything you want in the xx.nuspec file, but to avoid the unwanted second copies of things, make sure that every single item you don't want copied twice is set to a Build Action of None." My thanks to you. – Stephan G Jul 11 '19 at 21:57