NuGet v4 contentFiles не копируется на выход - PullRequest
1 голос
/ 08 ноября 2019

У меня проблемы с копированием файлов NuGet на выход с использованием интерфейса командной строки NuGet v4.

Моя структура каталогов выглядит следующим образом:

repo
repo\CodeAnalyzer.nuspec
repo\CodeAnalyzer.props
repo\contentFiles\any\any\StyleCop.ruleset

Вот мой файл CodeAnalyzer.props:

<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <PropertyGroup>
    <PackageName>CodeAnalyzer</PackageName>
    <PackageVersion>0.1.0</PackageVersion>
  </PropertyGroup>
  <PropertyGroup>
      <CodeAnalysisRuleSet>StyleCop.ruleset</CodeAnalysisRuleSet>
  </PropertyGroup>
</Project>

И файл CodeAnalyzer.nuspec:

<?xml version="1.0"?>
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
  <metadata>
    <id>CodeAnalyzer</id>
    <description>Provides standard code analyzer tooling and customisation.</description>
    <authors>Me</authors>
    <version>0.1.0</version>
    <dependencies>
      <dependency id="StyleCop.Analyzers" version="1.1.118" />
    </dependencies>
    <contentFiles>
      <files include="any/any/*" buildAction="Content" copyToOutput="true" flatten="false" />
    </contentFiles>
  </metadata>
  <files>
    <file src="contentFiles\any\any\StyleCop.ruleset" target="contentFiles" />
    <file src="CodeAnalyzer.props" target="build" />
  </files>
</package>

В CLI я упаковываю с использованием:

.\nuget.exe pack .\CodeAnalyzer.nuspec

В результате .nupkgесть каталог contentFiles с файлом StyleCop.ruleset, так что это работает.

Если я затем установлю пакет в проект, он обнаружит штрафную зависимость StyleCop.Analyzers и найдетФайл StyleCop.ruleset, так что файл .props в порядке.

Но файл StyleCop.ruleset нигде не размещен.

Чувствую, что я много пытался изменить buildActions на None/ Content, copyToOutput в true / false, различные пути для элемента contentFiles.file и элемента file.file.

Редактировать: проект-потребитель использует PackageReferences для пакетов NuGet, а не packages.config.

Ответы [ 2 ]

1 голос
/ 13 ноября 2019

contentFiles с PackageReference работает принципиально иначе, чем content с packages.config. С packages.config вы должны использовать инструменты (Visual Studio) для установки пакетов, и во время установки NuGet скопирует content в каталог проекта и любые другие необходимые ему изменения (например, указав Системе проекта изменить csproj). ). С packages.config восстановление концептуально отличается от установки, и все, что нужно сделать для восстановления, - это разархивировать пакет в ожидаемом месте, чтобы lib/<tfm>/*.dll сборки были доступны во время компиляции.

С PackageReference возможноотредактируйте csproj без инструментов, не зная, что это произошло. Это означает, что, когда NuGet выполняет восстановление, он не имеет понятия, выполняется ли это в первый раз, когда конкретный пакет был восстановлен для проекта, или только в первый раз на этом компьютере (фактически NuGet даже не проверяет существующее состояниепроект на машине, поэтому в настоящее время он не знает, был ли пакет ранее восстановлен в проекте на текущем компьютере). Хотя вы все еще можете использовать инструменты (Visual Studio или dotnet add package), это не более чем удобный способ редактирования csproj. Это долгий способ сказать, что концепция install vs restore больше не существует с PackageReference. Теперь есть только восстановление.

Поскольку концепция установки с PackageReference больше не существует, возникает большой вопрос о том, как делать файлы содержимого, если бы NuGet скопировал файлы в каталог потребляющего проекта. Если NuGet копирует файл при каждом восстановлении, это означает, что если разработчики проекта изменят файл, они потеряют свои изменения при следующем восстановлении NuGet. Если NuGet не перезаписывает файлы, то когда проект изменяет версию пакета, новый контент из нового пакета не будет обновлен.

Итак, способ, которым работает contentFiles, заключается в том, что NuGet сообщает сборкесистема о файлах, и они используются в качестве ссылок из папки глобальных пакетов. Во время сборки для TFM .NET Framework или во время публикации для .NET Core TFM файлы копируются в выходной каталог. Но они никогда не копируются в каталог проекта. При использовании Visual Studio они должны отображаться в обозревателе решений, но если щелкнуть файл, чтобы открыть его, он откроется в режиме только для чтения, поскольку было бы плохо вносить изменения, относящиеся к проекту, в папку глобальных пакетов, которая используетсяпо всем проектам на компьютере. Таким образом, концептуально это похоже на копирование файла в каждой сборке, и для того, чтобы отговорить разработчиков потребляющего проекта от внесения изменений, оно не беспокоит копирование файлов в каталог. Это также означает, что проверять управление исходным кодом меньше.

Поскольку файл содержимого, который вы используете, является активом времени сборки, а не средой выполнения, я полагаю, что contentFiles не является подходящим местом для размещенияфайл вашего набора правил. Я бы просто поместил его в каталог build/ рядом с вашим файлом props. Поскольку в вашем файле props не указан путь к файлу набора правил, я полагаю, что он говорит MSBuild искать в каталоге файла props, так что он просто будет работать. В худшем случае вы измените его на $(MSBuildThisFileDirectory)StyleCop.ruleset. Предполагается, что вы согласны с тем, что проекты-потребители не могут изменять файл набора правил. Если вы хотите, чтобы они могли изменять файл, то NuGet не является подходящим механизмом доставки, и я предлагаю вам взглянуть на шаблонов новых элементов dotnet .

1 голос
/ 11 ноября 2019

У меня была эта проблема, когда я изменил кучу изменений и ничего не получалось. И, наконец, решено с помощью PackageReferences

. В проектах package.config используется content/ В проектах PackageReference используется contentFiles/

Подробнее об неизменяемом контенте можно узнать здесь:

ContentFilesExample

nuget-contentFiles-demystified

  1. Существующий проект со ссылками на Nuget через packages.config
  2. Установленный пакет NuGetс файлами содержимого
  3. Сборка проекта
  4. Нет файлов содержимого в выходном каталоге

  5. Преобразование packages.config в PackageReferences
  6. Проект сборки
  7. Файлы содержимого были скопированы в выходной каталог

IDE - Visual Studio 2017. Проект - это проект приложения, который означает, что он имеет старый формат csproj.

Обновленный ответ

Атрибут GeneratePathProperty был добавлен к PackageReference

<PackageReference Include="EO.Pdf" GeneratePathProperty="true">
    <Version>19.0.83</Version>
</PackageReference>

Проверьте свои \ obj \ .csproj.nuget.g.props, чтобы убедиться, что переменные сгенерированы

Переменныеимеют префикс Pkg. Похоже, они автоматически генерируются для всех пакетов nuget с папкой инструментов.

...