Настройка общей папки пакетов nuget для всех решений, когда некоторые проекты включены в несколько решений


Я использую NuGet для извлечения пакетов из внешних и внутренних источников пакетов, что очень удобно. Но я понял, что пакеты по умолчанию хранятся в каждом решении, что очень расстраивает, когда некоторые проекты со ссылками NuGet включены в несколько решений. Затем ссылки изменяются на другую папку пакета решений, которая может быть фактически недоступна другому разработчику или машине сборки.

Я видел, что есть способы укажите общее расположение пакета (возможно, на корневом уровне проекта, мы используем систему управления версиями TFS) с выпуском 2.1 NuGet, см. заметки . Я использую NuGet v2. 7

но я попытался добавить nuget.конфигурационные файлы, не видя никакого эффекта от этого. Пакеты хранятся в папке решения. Я что-нибудь пропустил? Кажется, что существуют различные структуры узла xml для добавления в nuget.конфигурационный файл, в зависимости от того, кто отвечает, что вопрос: Шварци предлагает на другой поток Stackoverflow:

<settings>
  <repositoryPath>....[relative or absolute path]</repositoryPath>
</settings>

в примечаниях к выпуску NuGet 2.1 (см. ссылку выше) предлагается следующий формат:

<configuration>
  <config>
    <add key="repositoryPath" value="....[relative or absolute path]" />
  </config>
</configuration>

Я не знаю, какой из этих, или любой, или оба будут работать в конце концов. Я пробовал оба на уровне решения. Может из NuGet.файл конфигурации должен быть размещен на корневом уровне проекта TFS, или он должен быть в каталоге решения? Кажется, что NuGet читает и применяет настройки из этих файлов в определенном порядке, почему это имело бы смысл добавить их в несколько уровней, где нугет.файл конфигурации на уровне решения будет переопределять один на корневом уровне проекта TFS. Можно ли это прояснить?

мне нужно удалить все установленные пакеты, прежде чем эти ссылки будут работать? Я бы хотел, чтобы кто-то мог предоставить пошаговую инструкцию для перехода от использования nuget для конкретного решения к общей папке пакета, где проекты, принадлежащие нескольким решениям, могут найти свои необходимые пакеты nuget.

13 117

13 ответов:

у меня аналогичная ситуация с внешними и внутренними источниками пакетов с проектами, на которые ссылаются более чем в одном решении. Я только что получил эту работу с одной из наших баз кода сегодня, и, похоже, она работает с рабочими станциями разработчиков и нашим сервером сборки. Ниже процесс имеет этот сценарий в виду (хотя это не должно быть трудно адаптироваться, чтобы иметь общую папку пакетов еще где).

  • кода
    • Проект A
    • B
  • Проект C
  • решения
    • Решение 1
    • решение 2
    • решение 3
    • пакеты (это общий для всех решений)

обновленный ответ от NuGet 3.5.0.1484 с обновлением Visual Studio 2015 3

теперь этот процесс немного проще, чем когда я изначально занимался этим и думал, что пришло время обновить это. В общем, процесс такой же, только с меньшим количеством шагов. Результатом является процесс, который решает или обеспечивает следующее:

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

есть некоторые потенциальные недостатки, чтобы быть в курсе (я еще не испытал их, YMMV). Смотрите Бенол это ответ и комментарии ниже.

Добавить NuGet.Конфигурации

вы хотите создать NuGet.Конфигурационный файл в корне папки \Solutions\. Убедитесь, что это кодированный файл UTF-8, который вы создаете, если вы не знаете, как это сделать, используйте Visual Studio Меню Файл- > Создать - >файл, а затем выберите шаблон XML-файла. Добавить в NuGet.Сконфигурируйте следующее:

<?xml version="1.0" encoding="utf-8"?>
<configuration>  
  <config>
    <add key="repositoryPath" value="$\..\Packages" />
  </config>
</configuration>

для параметра repositoryPath можно указать абсолютный путь или относительный путь (рекомендуется) с помощью $ token. Токен $ основан на том, где находится NuGet.Конфигурация находится (токен $ фактически относится к на один уровень ниже расположение NuGet.Конфигурация.) Итак, если у меня есть \Solutions\NuGet.Config и я хочу \Solutions\Packages мне нужно будет указать $\..\Пакеты как значение.

Далее, вы хотите добавить папку решения к вам решение называется что-то вроде "NuGet" (щелкните правой кнопкой мыши на вашем решении, добавить->Новая папка решения). Папки решения-это виртуальные папки, которые существуют только в решении Visual Studio и не создают фактическую папку на диске (и вы можете ссылаться на файлы из любого места). Щелкните правой кнопкой мыши на папке решения" NuGet", а затем добавьте - >существующий элемент и выберите \\NuGet Для Решения.Конфиг.

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

путем размещения NuGet.Конфигурационный файл в \Solutions\ выше любого .sln файлы, мы используем тот факт, что NuGet будет рекурсивно перемещаться по структуре папок вверх от "текущего рабочего каталога" ищет NuGet.Конфигурационный файл для использования. "Текущий рабочий каталог" означает здесь несколько разных вещей, одна из которых-путь выполнения NuGet.exe и другое расположение .sln файл.

переключение через папку пакетов

во-первых, я настоятельно рекомендую вам пройти через каждую из ваших папок решений и удалить все существующие папки \Packages\ (сначала вам нужно закрыть Visual Studio). Это делает его проще чтобы увидеть, где NuGet помещает вашу недавно настроенную папку \Packages\ и гарантирует, что любые ссылки на неправильную папку \Packages\ не будут выполнены, а затем могут быть исправлены.

откройте свое решение в Visual Studio и начните перестраивать все. Игнорируйте все ошибки сборки, которые вы получите, это ожидается на данный момент. Однако это должно запустить функцию восстановления пакета NuGet в начале процесса сборки. Убедитесь, что ваша папка \Solutions\Packages\ создана в том месте, где вы находитесь хотеть. Если это не так, проверьте свою конфигурацию.

теперь, для каждого проекта в решении вы хотите:

  1. Правой Кнопкой Мыши на проекте и выберите выгрузить проект
  2. щелкните правой кнопкой мыши на проекте и выберите Редактировать-xxx. csproj
  3. найдите все ссылки на \packages\ и обновите их до нового местоположения.
    • большинство из них будут ссылки, но не все из них. Например, WebGrease и Microsoft.Bcl.Сборка будет иметь отдельные настройки пути, которые необходимо будет обновить.
  4. сохранить .csproj файл и щелкните правой кнопкой мыши на проекте и выберите перезагрузить проект

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

по состоянию на NuGet 2.7.1 (2.7.40906.75) с VStudio 2012

во-первых, нужно иметь в виду, что nuget.config не контролирует все параметры пути в системе пакетов nuget. Это было особенно запутанным, чтобы выяснить. В частности, проблема заключается в том, что msbuild и Visual Studio (вызывающие msbuild) не используют путь в nuget.config, но скорее переопределяют его в nuget.целевой файл.

Подготовка Окружающей Среды

во-первых, я хотел бы пройти через ваши папка решения и удалить все \packages\ папки, которые существуют. Это поможет убедиться, что все пакеты явно устанавливаются в правильную папку и помогают обнаружить любые неверные ссылки на пути во всех ваших решениях. Затем я бы удостоверился, что у вас установлено последнее расширение NuGet Visual Studio. Я также хотел бы убедиться, что у вас есть последний nuget.exe устанавливается в каждое решение. Откройте командную строку и перейдите на каждые $(SolutionDir)\ .NuGet\ folder и выполните следующие действия команда:

nuget update -self

установка общего пути к папке пакета для NuGet

открыть каждый\ $(SolutionDir).nuget\NuGet.Сконфигурируйте и добавьте в раздел следующее:

<config>
    <add key="repositorypath" value="$\..\..\..\Packages" />
</config>

Примечание: вы можете использовать абсолютный путь или относительный путь. Имейте в виду, если вы используете относительный путь с $, что по отношению к на один уровень ниже расположение NuGet.Config (считаю, что это a жук.)

установка общего пути к папке пакета для MSBuild и Visual Studio

открыть каждый\ $(SolutionDir).nuget\NuGet.цели и измените следующий раздел (обратите внимание, что для не-Windows есть еще один раздел ниже):

<PropertyGroup Condition=" '$(OS)' == 'Windows_NT'">
    <!-- Windows specific commands -->
    <NuGetToolsPath>$([System.IO.Path]::Combine($(SolutionDir), ".nuget"))</NuGetToolsPath>
    <PackagesConfig>$([System.IO.Path]::Combine($(ProjectDir), "packages.config"))</PackagesConfig>
    <PackagesDir>$([System.IO.Path]::Combine($(SolutionDir), "packages"))</PackagesDir>
</PropertyGroup>

обновить PackagesDir, чтобы быть

<PackagesDir>$([System.IO.Path]::GetFullPath("$(SolutionDir)\..\Packages"))</PackagesDir>

Примечание: GetFullPath разрешит наш относительный путь в абсолютный путь.

восстановление всех пакетов nuget в общую папку

открыть командную строку и перейти каждые $(SolutionDir)\ .NuGet и выполните следующую команду:

nuget restore ..\YourSolution.sln

на этом этапе у вас должна быть одна папка \packages\ в вашем общем расположении и ни в одной из ваших папок решения. Если нет, то проверьте свои пути.

исправление ссылок на проект

открыть каждый .csproj файл в текстовом редакторе и найти любые ссылки на \packages и обновить их до правильного пути. Большинство из них будут ссылки, но не все из них. Например, WebGrease и Microsoft.Bcl.Сборка будет иметь отдельные настройки пути, которые необходимо будет обновить.

построить решение

откройте решение в Visual Studio и начать строить. Если он жалуется на отсутствующие пакеты, которые необходимо восстановить, не предполагайте, что пакет отсутствует и должен быть восстановлен (ошибка может вводить в заблуждение). Это может быть плохой путь в одном из ваших .csproj файл файлы. Убедитесь, что, прежде чем восстанавливать пакет.

есть ошибка сборки о недостающих пакетах?

если вы уже проверили, что пути в вашем .файлы csproj верны, то у вас есть два варианта, чтобы попробовать. Если это результат обновления код из системы управления исходным кодом, то вы можете попробовать проверить чистую копию, а затем здание. Это сработало для одного из наших разработчиков, и я думаю, что в нем был артефакт .СУО файл или что-то подобное. Этот другой вариант-вручную принудительно восстановить пакет с помощью командной строки .папка nuget рассматриваемого решения:

nuget restore ..\YourSolution.sln

вместо установки общего расположения пакета для всех проектов, также можно изменить HintPath в проекте следующим образом:

<HintPath>$(SolutionDir)\packages\EntityFramework.6.1.0\lib\net40\EntityFramework.dll</HintPath>

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

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

мой опыт пытается это с последней версией NuGet (2.7) и VS2012:

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

в моем случае я хотел поместить все пакеты в .packages, так что мой NuGet.Конфиг выглядел как ниже.

 <?xml version="1.0" encoding="utf-8"?>
 <configuration>
   <config>
     <add key="repositorypath" value=".packages" />
   </config>
 </configuration>

обратите внимание, что есть несколько "странных" вещей, которые могут произойти, но я думаю, что они терпимы:

  • если вы "обновить" пакет из одного решения, он будет быстро удалить старую версию из папки пакетов (он не может знать, есть ли у вас другое решение, которое указывает там). Это меня не сильно беспокоит, так как другое решение будет просто восстанавливаться, когда это необходимо.
  • если вы попытаетесь добавить пакет из правой кнопки мыши на решении, если пакет уже присутствует в другом решении, он увидит, что он есть, и покажет вам "зеленую галочку" вместо кнопки "Установить". Я обычно устанавливаю из правой кнопки мыши на проекте, так что это меня совсем не беспокоит.

отказ от ответственности: я только что попробовал это сегодня, у меня нет никакого долгосрочного опыта, чтобы поддержать его!

у меня есть версия NuGet 2.8.50926 с VS 2013. Вам не нужно использовать несколько nuget.конфигурационные файлы, или использовать сложные структуры каталогов. Просто измените файл по умолчанию находится здесь:

%APPDATA%\Roaming\NuGet\NuGet.Config

вот содержание моего файла:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <config>
    <add key="repositoryPath" value="C:\Projects\nugetpackages" />
  </config>
  <activePackageSource>
    <add key="nuget.org" value="https://www.nuget.org/api/v2/" />
  </activePackageSource>
</configuration>

Так что все пакеты идут в "C:\Projects\nugetpackages" папка, независимо от того, где находится решение.

во всех ваших решениях просто удалите существующие папки "пакеты". Затем создайте свое решение, и NuGet будет автоматически восстановите отсутствующие пакеты в новом централизованном каталоге, который вы указали.

уже нет необходимости изменять nuget.цели. Он был исправлен в nuget 2.8 (http://nuget.codeplex.com/workitem/2921). вам нужно только установить repositorypath.

Я придумал пакет NuGet, который прозрачно преобразует все ссылки NuGet в проекте в относительный формат $(Solutions dir). Он делает это с помощью преобразования XSLT во время сборки, поэтому вам не нужно взламывать файл проекта вручную. Вы можете обновить свои пакеты свободно, это ничего не сломает.

https://www.nuget.org/packages/NugetRelativeRefs

или если вы используете Visual Studio 2015 Update 3, Вы можете просто перенести ссылки на пакеты project.json форма, как описано здесь: https://oren.коды/2016/02/08/project-json-all-the-things

обновление моего опыта работы с nuget 2.8.3. Это было относительно просто. Все делали было включено восстановление пакета от щелчка правой кнопкой мыши решение. Отредактированный NuGet.Конфигурации и добавил Эти строки :

  <config>
    <add key="repositorypath" value="..\Core\Packages" />
  </config>

затем перестроил решение, он загрузил все пакеты в нужную папку и автоматически обновил ссылки. Я сделал то же самое для всех моих других проектов, где были загружены только инкрементные пакеты и ссылки на существующие пакеты. Отсюда общий репозиторий для всех проектов, как было установлено.

вот пошаговая процедура для включения восстановления пакета.

http://blogs.4ward.it/enable-nuget-package-restore-in-visual-studio-and-tfs-2012-rc-to-building-windows-8-metro-apps/

из Visual Studio 2013 Update 4 и Nugget Package Manager version > 2.8.5...

создать nuget.конфигурационный файл в корне репозитория.

файл содержимое:

<configuration>
  <config>
    <add key="repositoryPath" value="packages" />
  </config>
  <packageSources>
    <add key="nuget.org" value="https://www.nuget.org/api/v2/" />
  </packageSources>
</configuration>

это приведет к тому, что все пакеты перейдут в папку packages на уровне вашего nuget.конфигурационный файл.

теперь вы можете пойти для каждого .sln NuGet консоль с командой 'update-package-reinstall'

Если у вас есть как несколько репозиториев на одном уровне и что делать поделитесь одной и той же папкой пакета через них попробуйте использовать способ перехода на одну папку вверх.

 <add key="repositoryPath" value="..\packages" />

но таким образом вы вызываете, что NuGet packages reference csproj указывает одну папку за пределами вашего пути репозитория.

просто hardlink / пакеты в нужное общее место. Тогда ваш проект не будет нарушен для других пользователей, которые не имеют специального расположения пакетов.

Откройте командную строку в качестве администратора и используйте

mklink /prefix link_path Target_file/folder_path

для любого значимого решения вышеуказанные ответы будут короткими. Довольно просто, сложная структура рабочего пространства TFS с различными относительными путями, ветвлением, общими проектами и т. д. сделать единый центральный репозиторий невозможным.

использование ($Solutions dir) - это шаг в правильном направлении, но ручное кодирование файла csproj с помощью ($Solutions dir) станет довольно утомительным в базе кода с сотнями пакетов, которые регулярно обновляются (каждый раз, когда происходит обновление, HintPath получает перезаписывается новым относительным путем). Что произойдет, если вам нужно запустить Update-Package-Reinstall.

есть отличное решение под названием NugetReferenceHintPathRewrite. Он автоматизирует инъекцию ($Solutions Dir) в HintPaths непосредственно перед сборкой (без фактического изменения файла csproj). Я предполагаю, что он может быть легко включен в автоматизированные системы сборки

краткое резюме для тех, кто на VS 2013 professional С NuGet версия: 2.8.60318.667

Это то, как вы бы направить пакеты к пути относительно.папка nuget:

<configuration>
  <config>
    <add key="repositoryPath" value="../Dependencies" />
  </config>
</configuration>

например, если решение (.sln file) находится в C:\Projects\MySolution, когда вы включаете восстановление пакета NuGet, то .папку создал NuGet-это вот так: C:\Projects\MySolution.NuGet и пакеты будут загружены в каталог вот так: C:\Projects\MySolution\Dependencies

Примечание: по какой-то (неизвестной) причине каждый раз, когда я обновляю "repositoryPath", я должен закрыть и снова открыть решение, чтобы изменения вступили в силу

для тех, кто использует пакет в качестве менеджера пакетов, есть опция автоматической символической ссылки для вашего файла зависимостей:

storage: symlink

кстати: пакет использует nuget

Ссылка:https://fsprojects.github.io/Paket/dependencies-file.html

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

Это инструкции по состоянию на NuGet 2.1: http://docs.nuget.org/docs/release-notes/nuget-2.1

нет необходимости редактировать файлы уровня решения.

работает с Visual Studio 2013 и тремя проектами совместного использования решений.

Не забудьте обновить NuGet уровня решения (каждый nuget.exe в .папки из NuGet).