33
Vote

File Properties are not preserved for content files

description

Scenario: In my project I have a file with a Build Action that I would like to be preserved when I install the package. No file related properties appear to be preserved when installing a package.

Repro:
  1. Add a file to the content folder of the project of a package
  2. Specify a build action and/or other advanced properties that are written to the project file.
  3. Create the package
  4. Install the package into an application
Expected: File properties are preserved
Actual: No file properties are preserved

We should provide helpers for this as part of our helper library: http://nuget.codeplex.com/workitem/310

(Other keywords: Content Item, Content Properties)

comments

Haacked wrote Dec 21, 2010 at 10:31 PM

We don't want to add VS specific attributes to NuSpec. Let's provide easy to use PS helper methods for doing this properly.

Haacked wrote Mar 22, 2011 at 11:59 PM

Perhaps this should be rolled into http://nuget.codeplex.com/workitem/310 (NuGet PS Helper Library)

Haacked wrote Apr 18, 2011 at 10:16 PM

Moving to 1.4.

mistachkin wrote Mar 12, 2012 at 6:57 AM

I've hit this issue as well. Marking content files to be copied to the output directory is a very basic operation (and is not necessarily even VS specific) and should be supported using an attribute on the <file> element in the nuspec file. Also, having looked at the NuGet source code, it seems like implementing this should not be too large a task. Fundamentally, when adding the ProjectItem (using the VS specific interface?), all you have to do is set the CopyToOutputDirectory property to the value 0, 1, or 2 via the Properties collection on the ProjectItem.

karldodd wrote Aug 20, 2013 at 4:41 AM

I hit this issue also. The IMPACT of this issue should not be 'low'. And it will be a very easy fix.

I agree with mistachkin that CopyToOutputDirectory property should be added. For non-VS environments they could choose to ignore this property.

dotnetjunky wrote Aug 20, 2013 at 7:19 PM

Here's the rough design from Anthony Johnston:

Overview

I was trying to get VS to run CustomTools on install of a particular file type using NuGet
But it seem to me that this could be abstracted further to, "when this type of file is installed into a project do something to it"

The Flow

ProjectManager has a new dependency (with an overload to supply a default)
     public ProjectManager(
        IPackageRepository sourceRepository, 
        IPackagePathResolver pathResolver, 
        IProjectSystem project, 
        IPackageRepository localRepository,
        ProjectFileProcessingBuilder fileProcessingBuilder)
    {
    }
The builder is used to create a ProjectFileProcessingExecutor specifically for the package, which contains a list of processors to match and run against the files.
(see ProjectManager.cs line 248)

The ProjectFileProcessingExecutor is passed into IProjectSystem.AddFiles and run after each file is added
(see ProjectSystemExtensions.cs line 69)

The idea is that the builder would contain a number of Processors for conventions such as "Always set X to Y when a file is of type .ZZZ"
and that processors can be additionally to run against files according to the nuspec

How far I got

The services are all in place and tested
Most new stuff is in a folders called ProjectFileProcessing in Core and VisualStudio and some in Core.Authoring

What I haven't done is sorted out how a file is matched on add, I had seen some stuff on this using PathResolver, but hadn't got to writing tests and checking this out
I suspect when I get IProjectFileProcessingProjectItem.Path I am looking at the wrong one, so that would be what I'd look into next.

Also, the processors added by means other than the nuspec, ie the "Conventional Processors" I haven't touched on. But what would be good here is if you could set them up at both the "Global" level in the nuget config and at "Package" level in the nuspec - but you can decide that

NuSpec and FileProperties

Additional to the nuspec XSD, where you could supply a number of properties to set on install of a file

e.g.
<package>
<metadata>
...
</metadata>
<files>
    <file src=""my.txt"" target=""content"">
      <properties>
        <property name=""propName1"" value=""propValue"" />
        <property name=""propName2"" value=""propValue"" />
      </properties>
    </file>
</files>
</package>
The changes to the XSD are all in place, with ManifestVersionUtility.FilePropertiesVersion (7) setup and tested

Important Interfaces & Classes

IProjectFileProcessingProject
Abstraction of a VsProject for file processing

IProjectFileProcessingProjectItem
Abstraction of a VsProjectItem for file processing

IProjectFileProcessor
This interface describes a processor, allows for many processors that do different things to be called by a single service

ProjectFileProcessingExecutor
Executes the list of IProjectFileProcessors against an item

ProjectFileProcessingBuilder
Creates an executor (above) and allows for pre-configured processors as well a those added by the nuspec