Проблемы с NuGet с пакетами .config, ссылки на проекты и пакет пакетов решений

Мы начинаем использовать NuGet, и у нас возникают некоторые проблемы:

Сначала некоторые факты NuGet:

(Просто чтобы убедиться, что мы поняли, как работает NuGet)

  • Пакет package.config(расположенный в корне проекта) создается и обновляется при добавлении, обновлении или удалении пакетов. Внутри этого файла свойство версии пакета отражает полную версию, которая используется, поэтому в этом смысле это также состояние. Можно добавить свойство allowedVersions в спецификацию пакета, что является ограничением на версии, которые могут быть обновлены. Чтобы сделать восстановление пакета, этот файл должен находиться под контролем источника.

  • Папка пакетов находится в корневом каталоге решений и содержит загруженную версию зависимых пакетов в подпапке, названной так, чтобы соответствовать именам пакетов (включая версию), чтобы можно было использовать несколько версий одного и того же пакета различными проектами в многопроектном решении. Рекомендуется не контролировать исходный код, поскольку они являются двоичными файлами, и тот факт, что восстановление пакета может воссоздать их при необходимости. Когда пакет обновляется, новая папка, соответствующая обновлению, создается вместе с пакетом.

  • В файлах проекта содержатся ссылки на пакеты в папке пакетов, чтобы сборщики работали, а для визуальной студии также можно было предоставить автозаполнение, intellisense и многое другое. Когда пакет обновляется, ссылки в файле проекта обновляются в соответствии с новым расположением пакета в папке пакетов.

Вопросы:

  • Так как записи пакетов пакета package.config содержат полную информацию о версии, нам постоянно нужно обновлять репозиторий исходного кода с изменениями. Или мы могли бы игнорировать изменения в большинстве случаев, но когда изменилась только версия, мы (в большинстве случаев) могли бы их игнорировать. Это кажется очень ненужным, так как восстановление NuGet должно быть в состоянии узнать, какие версии разрешены (через allowedVersions).

  • Свойство allowedVersions должно быть добавлено вручную, что легко забывается. Мы используем семантическое управление версиями, поэтому для нас при установке, то есть версии Foo-1.1.0, допускается allowVersions = "[1,2)".

  • При добавлении разрешенногоVersion тогда восстановление пакета NuGet, похоже, не может найти -перехват сборок (может быть, ошибка?).

  • Почему пакеты обрабатываются NuGet на уровне решения? Если вы работаете в решении mix-and-match, которое содержит проект-A (repo-1) и project-B (repo-2), то упаковка уровня решения не будет работать хорошо. То есть, если вы сохраните файл решения в отдельном месте, все может работать afaik. Но если вы затем настроили другое решение, содержащее project-A (repo-1) и project-C (repo-3), то проекту-A вдруг понадобится восстановление пакета, и, что еще хуже, ссылки на проект будут изменено в соответствии с последним изменением. Возвращаясь к первому решению, тогда будут ссылки, которые не сработают. Проверка в них, безусловно, заставит их работать не на других.

  • При обновлении пакета ссылки на файл проекта обновляются (для соответствия новым именам имен с версией в них) и отображаются как незафиксированные изменения. Выполнение этого изменения, по-видимому, является нормой, но, на наш взгляд, это не обязательно.

Заметки об ExcludeVersion (что может быть предложено как решение указанной проблемы:

  • Вы можете предоставить эту опцию только при ручном выполнении команд NuGet, afaik. При установке/обновлении пакетов через меню NuGet в Visual Studio этот параметр не может быть использован. Использование любого из автоматизированных инструментов означает, что впоследствии имя папки и ссылку на проект должны быть исправлены вручную.

  • Мы знаем, что ExcludeVersion не является настройкой по умолчанию, вероятно, из-за поддержки случаев, когда кто-то работает в многопроектном решении, где разные проекты зависят от разных версий одного и того же пакета.

Возможные решения?

(Но, что может потребовать существенных изменений в экосистеме NuGet?)

A - packages.config

Я хочу, чтобы каждый элемент пакета в файле package.config мог отбросить разрешенныеVersions и вместо этого изменить версию как спецификатор диапазона. Элемент package также должен предоставить возможность отдельно определить источник, из которого можно получить обновления. Наконец, если установленный пакет следует за Semantic Versioning, то свойство version должно автоматически устанавливать диапазон версии в соответствии с установленной версией.

Пример package.config:

`<?xml version="1.0" encoding="utf-8"?>
<packages>
  <package id="Foo" version="[1,2] source="Development Feed">
</packages>`

Это:

  • Исправить проблему с чрезмерными фиксациями файла package.config, поскольку свойство version больше не постоянно обновляется.

  • Не нужно забывать устанавливать диапазон для проектов с семантической версией.

  • Убедитесь, что пакеты выбраны из нужного канала, и это время не пропало даром, ища его в неправильных источниках.

B - папка Пакеты и имена установленных пакетов в

Я хочу, чтобы папка пакетов располагалась в каждом корневом каталоге проекта и что имена подпапок были ограничены только именем пакета, исключая версию. Это:

  • Исправить проблему с чрезмерной фиксацией файлов проекта, так как ссылки проекта в файле проекта теперь указывают на одну и ту же папку пакета после обновления.

  • Позволяет проектам использовать разные версии одного и того же пакета, так как они действительно независимы друг от друга.


Мы будем очень рады услышать о решениях перечисленных проблем.

Ответы

Ответ 1

Как было предложено в NuGet Enterprise - лучшие практики для разных уровней зрелости пакетов, я думаю, что вы делаете вещи более сложными, чем необходимо:)

  • Почему бы вам не захотеть захватить версию пакета, с которым был скомпилирован код? Это важная информация для надежной диагностики и повторяемости сборки. Учитывая, что вы, вероятно, скопируете изменения кода обратно в элемент управления версиями, очень важны данные о том, какие пакеты были использованы для создания этого источника.
  • "при установке, т.е. версии Foo-1.1.0, allowVersions =" ​​[1,2) "следует подразумевать" Я не думаю, что allowVersions действительно может подразумеваться, потому что не все пакеты NuGet придерживаются SemVer (см. фиаско с log4net 1.2.11). Настройка grep для allowedVersions как часть либо CI-сборки, либо pre-commit/pre-push Dev-проверки должна поймать это. Он не должен часто меняться, и полезно следить за ним (если другие команды и пакеты правильно используют SemVer:)).
  • Чтобы найти пакеты Prerelease, вам понадобятся флаги Prerelease или -IncludePrerelease для установки nuget.
  • "Если вы работаете в решении mix-and-match, которое содержит проект-A (repo-1) и project-B (repo-2)" - почему вы упорядочили свой код следующим образом? Код для одного решения должен жить в одном и том же репо. Нарушение кода решения через репозитории определенно будет болезненным!
  • Вы можете указать nuget использовать имена папок без версий для установки пакетов (-ExcludeVersion).

Я бы настоятельно рекомендовал интегрировать Visual Studio NuGet в пользу использования командной строки nuget.exe и вместо этого создавать скрипты. Это относится, в частности, к № 5, но к взаимодействию с NuGet в целом. Интеграция с Visual Studio хороша при работе исключительно с сторонними публичными пакетами из фида nuget.org, но недостаточно гибка для моей работы при работе с внутренними фидами и пакетами NuGet.