Сегодня я хочу рассказать о том, как можно централизованно управлять настройками ReSharper на уровне команды разработчиков. Под настройками я понимаю настройки форматтера, Live Templates и настройки ReSharper. Они могут быть экспортированы и упакованы в так называемые Declarative Extensions.

На данный момент все плагины для ReSharper представляют собой стандартные NuGet пакеты. Это позволяет распространять их через официальный NuGet feed от JetBrains или публиковать их в частном закрытом NuGet сервере внутри компании.

Экспорт настроек


Для экспорта настроек и Live Templates перейдём в меню RESHARPER->Manage Options.

Manage Options

В данном диалоге нужно выбрать уровень (Layer) настроек, который мы хотим экспортировать.

Нажмём кнопку «Import/Export settings».

export settings and templates

В окне «Export To File» отметим узлы «Code Style» и «LiveTemplates». Затем нужно указать директорию и имя DotSettings файла, в который будут записаны экспортируемые настройки.

Подготовка NuGet пакета


Как только настройки экспортированы, можно приступать к созданию NuGet пакета. Необходимо описать .nuspec файл. Для ReSharper 8.2 он будет выглядеть следующим образом:

<?xml version="1.0"?>
<package>
  <metadata>
    <id>YourCompany.Settings</id>
    <version>1.0.0</version>
    <title>TeamSettings</title>
    <authors>Your name</authors>
    <owners>Your Company</owners>
    <projectUrl>http://your-company.com</projectUrl>
    <requireLicenseAcceptance>false</requireLicenseAcceptance>
    <description>
      Team settings and live templates for ReSharper
    </description>
    <copyright>Copyright © Your Company</copyright>
    <dependencies>
      <dependency id="ReSharper" version="8.2" />
    </dependencies>
    <releaseNotes>
    </releaseNotes>
    <tags>settings</tags>
  </metadata>
  <files>
    <file src="..\Settings\" target="ReSharper\v8.2\settings\" />
  </files>
</package>


В случае с ReSharper 9.1 .nuspec файл будет немного отличаться. Узел Dependencies должен указывать версию «Wave», а не ReSharper:

<dependencies>
      <dependency id="Wave" version="[2.0]" />
</dependencies>


Так же нужно будет изменить target:

<files>
    <file src="..\Settings\" 
    target="DotFiles\Extensions\YourCompany.Settings\settings\" />
  </files>


Где «YourCompany.Settings» это идентификатор NuGet пакета.

Теперь можно собрать пакет, выполнив команду:

nuget.exe pack nuspec-file-name.nuspec


Если мы выполнили предыдущие шаги без ошибок, то рядом с nuspec файлом будет создан пакет «YourCompany.Settings.1.0.0.nupkg».

Публикация NuGet пакета


Как упоминалось выше, ReSharper может использовать следующие источники NuGet пакетов:
  • Официальный feed от JetBrains
  • Любой сторонний NuGet сервер (например ProGet)
  • Артефакты TeamCity
  • Локальная или сетевая папка

Публикация пакета на NuGet сервере практически ничем не отличается от публикации на nuget.org.

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

Использование кастомного NuGet feed


После того, как пакет с расширением опубликован, нам нужно зарегистрировать новый источник расширений. Для этого перейдём в RESHARPER -> Options...-> Environment -> Extension Manager.

Options-Environment dialog

Нажмём «добавить» (Add), укажем имя в поле «Name» и путь до Артефактов, NuGet сервера или директории в поле «Source».

add custom gallery

Установка расширения


Для установки расширения необходимо перейти в меню RESHARPER -> Extension Manager.

В поиске нужно найти наш пакет и нажать Install.

install custom plugin

Проверим, что ReSharper обнаружил новые настройки. Откроем диалог Manage Options и убедимся, что новый слой настроек отображается на экране.

new settings layer

Теперь каждый член команды может использовать актуальную версию настроек. В случае изменения или обновления настроек достаточно лишь опубликовать новую версию плагина, и ReSharper автоматически найдёт обновление и проинформирует разработчика.
Как ваша команда работает с настройками?

Проголосовало 9 человек. Воздержалось 3 человека.

Только зарегистрированные пользователи могут участвовать в опросе. Войдите, пожалуйста.

Комментарии (11)


  1. Scratch
    13.07.2015 10:16
    +1

    Вот это спасибо, давно о чем-то таком думал. А то у одних так, у других сяк


  1. lair
    13.07.2015 10:31
    +2

    В чем преимущество по сравнению с тем, чтобы просто положить настройки в VCS? (благо, R# умеет это делать на нескольких уровнях)


    1. return_true Автор
      13.07.2015 10:40
      +1

      Не очень понял вопрос. Если он про коммит настроек в репозиторий с проектом, то у нас в команде 50+ репозиториев, часть в Git, часть в SVN. Проще держать настройки в одном месте, чем копировать обновления в каждый проект.

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


      1. lair
        13.07.2015 11:35
        +2

        Вы правы, если множество репозиториев, а настройки нужны общие — тогда пакет выгоднее. Просто я чаще сталкиваюсь с ситуацией «одна команда — одни настройки — один репозиторий», и тут коммитить настройки в репозиторий выгоднее.


        1. return_true Автор
          13.07.2015 11:58
          +3

          1. mihasic
            13.07.2015 17:48

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


            1. return_true Автор
              13.07.2015 17:56

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

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

              В нашем случае в настройках хранятся в том числе и кастомные инспекции для соблюдения naming convention, которые применимы ко всем проектам.


  1. YuZZ
    13.07.2015 15:30

    Попробовал, extension встал, но файл настроек в слоях не появился. Скорее всего ошибка у меня в files — есть описание где-то какой именно путь должен быть у target?


    1. return_true Автор
      13.07.2015 15:39

      Какая версия R# у вас?


    1. return_true Автор
      13.07.2015 15:47

      Есть официальный DevGuide.

      Для R# 9.1 target должен быть «DotFiles\Extensions\YourCompany.Settings\settings\» В id пакета нужна точка (".")
      Для R# 8.2 target=«ReSharper\v8.2\settings\»

      Проверьте .nupkg файл, убедитесь, что .DotSettings запакован в него.


      1. YuZZ
        13.07.2015 16:45
        +1

        R#9.1 Заработало, спасибо. В src я сначала файл указывал, заменил на папку — все стало ок