Синхронизация всех проектов Visual Studio с библиотекой

сценарий

У меня есть библиотека, которая содержит проекты A, B и C.

у меня есть два решения. Решение 1 включает в себя копию проекта A, а решение 2 включает в себя копии проектов A и B.


когда я создаю Решение 1, вот что должно произойти:

alt текст http://img689.imageshack.us/img689/9341/onbuildsolution1.jpg


когда я создаю решение 2, вот что должно произойти:

alt текст http://img32.imageshack.us/img32/7821/onbuildsolution2.jpg


как я могу это сделать?

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

Если я создам свое собственное решение, у меня есть некоторые мысли о том, как это может работать, но я был бы признателен за любой вклад, который вы можете есть:

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

    c:Program FilesLibrary SyncronizerLibSync.exe /solution:Solution 1
    
  • XML-файл, используемый для регистрации активных решений, содержащих библиотечные проекты. Возможный формат:

    <solutions>
      <solution>
        <name>Solution1</name>
        <path>c:...ProjectsSolution 1</path>
      </solution>
      <solution>
        <name>Solution2</name>
        <path>c:...ProjectsSolution 2</path>
      </solution>
      <!-- more solutions -->
    </solutions>
    
  • программа будет делать следующее:

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

этой звуки относительно простой в концепции, но это может иметь серьезные нежелательные последствия я не думаю. Надеюсь, кто-то предупредит меня, если это делает :)


Update - какова моя мотивация для копирования папок проекта?

в word-управление версиями.

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

моим обходным путем для этого было добавление тегов в ревизии в репозитории моей библиотеки, которые говорят такие вещи, как" Решение 1 - версия 2.5.3", но это довольно неуклюже. И все становится очень неудобно, если я работаю над" три версии назад " решения 1 и текущей версией решения 2. Теперь решение 2 будет указывать на старую версию проектов библиотеки, что делает потенциально невозможным работать и тестировать, пока я не закончу работу над старой версией решения 1.

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

Я должен отметить здесь, что я использую Tortoise HG (Mercurial) для контроля версий.

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


обновление 2

прежде всего, просто Примечание. Я использую Mercurial (TortoiseHG) для управления версиями, а не SVN. Я мог бы измениться, если это абсолютно необходимо, но я действительно предпочитаю Mercurial.

основываясь на ответах до сих пор, я решил покончить с " двунаправленным копированием" идея, и вернуться к ссылкам на мои библиотечные проекты. Вот новая схема:

alt текст http://img30.imageshack.us/img30/7445/referencedprojects.jpg

Я продолжаю иметь те же цели, однако:

  1. последняя версия каждого решения использует последний код библиотеки
  2. одно решение/приложение в репозиторий
  3. каждый репозиторий содержит все исходный код, включая библиотеки проекты
  4. все максимально автоматизировано, чтобы минимизировать риск ошибок

цель #1 выполняется автоматически путем ссылки на проекты библиотеки вместо использования копий, а цель #2-это просто вопрос того, как я настраиваю свои репозитории, но цели #3 и #4 остаются неуловимыми.

С Mercurial, есть функция subrepositories похоже, что он справится с моей ситуацией, но, как указано в документации, это все еще считается экспериментальным и рискованным.

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

Я приветствую ваши мысли о любом из этого.

5 ответов


это звучит точно так же, как то, что поддержка суб-репозиторий в mercurial для. Если проект а и Проект Б и т. д. являются отдельными репозиториями, которые вы можете сделать их вложенными репозиториями в решениях 1 и 2. The .hgsub файлы в 1 и 2 версионны сами по себе и указывают на определенные ревизии в A, B и C, поэтому вы всегда можете создавать с одной и той же версией в каждом решении, но не нужно держать их в шаге блокировки. Перемещение изменений из решений в библиотеки становится легко, и при желании, branchable.

Не позволяйте упоминанию" бета в 1.3 " на этой странице wiki обмануть вас. Mercurial теперь до 1.4.2, а subrepos остаются такими, какие они есть.


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

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

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


способ решения аналогичной проблемы-это то, что вы описываете в обновлении 2, но там, где вы предлагаете "резервные копии", мы используем клоны, и они являются неотъемлемой частью нашего рабочего процесса.

мое решение.

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

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

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

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

почему я делаю это таким образом?

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

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

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

это рабочий процесс, который никогда не был бы возможен с традиционным VCS как SourceSafe, но прекрасно работает с DVCS как Hg.

конкретные решения этих неуловимых целей.

чтобы попытаться ответить на ваши цели недостижимыми

.3. Каждый репозиторий содержит весь исходный код, включая проекты библиотек

клонирование библиотек в каталогах близко к вашей программе, вы получаете набор репозиториев, которые можно собрать вместе и, возможно, в конечном итоге преобразует красиво в суб-РЕПО от "приложение" супер-РЕПО.

.4. Все максимально автоматизировано, чтобы минимизировать риск ошибок

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

например, данные приложения " _projects.летучая мышь" может содержать:

@echo off
@shift
set APPDIR=%CD%
cd ..\Library1
%0 %1 %2 %3 %4 %5 %6 %7 %8 %9

cd ..\Library2
%0 %1 %2 %3 %4 %5 %6 %7 %8 %9

cd ..\Library3
%0 %1 %2 %3 %4 %5 %6 %7 %8 %9

cd %APPDIR%
%0 %1 %2 %3 %4 %5 %6 %7 %8 %9

pause

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

@echo off
call _projects hg incoming

и проверьте, что будет нажато с " _ _ исходящим.летучая мышь":

@echo off
call _projects hg outgoing

или фактически выполните эти операции с помощью " _ _ push.летучая мышь":

@echo off
call _projects hg push

и "__тянуть.летучая мышь":

@echo off
call _projects hg pull

в то время как "__update.bat " обновляет все до последней версии (в той же ветви вам все равно нужно явно обновить вне текущей ветви):

@echo off
call _projects hg update

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

@echo off
call _projects hg id

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

обратите внимание на подчеркивания в именах файлов как раз там, чтобы подтолкнуть их к верхней части списков каталогов, чтобы сделать их легче найти. *8')

варианты будущего.

в конце концов, я хотел бы полностью автоматизировать этот рабочий процесс с помощью вложенных репозиториев (поэтому состояние всего приложения и всех его библиотек записываются в одном приложении changeset), но, хотя он становится довольно стабильным в Mercurial, интеграция TortoiseHG, похоже, не является приоритетом. Я не мог заставить инструмент фиксации THG сделать что-нибудь полезное в последний раз, когда я его пробовал (около 0.8.3). Я действительно должен повторить тест с 0.9.3, но я не помню, чтобы видел какие-либо заметки о суб-РЕПО в списках изменений, поэтому это не стоит того, если люди не скажут мне, что поддержка суб-РЕПО THG была молча добавлена.

как есть, пакетные файлы работают довольно хорошо. Следующая вещь на моем todo список-это "__клон.bat", который должен сделать клонирование приложения и все его библиотеки намного проще, но у меня не было времени, чтобы это работало.

если кто-то хочет пойти, хотя, я хотел бы увидеть ответ в этой теме. *8')

береги себя, Надеюсь, это поможет,

Марк..........


Я не уверен, что понимаю цель вашей "библиотеке"?

Почему эти два решения фактически не ссылаются на один и тот же проект, а не на копию?

Если цель состоит в том, чтобы иметь возможность работать на разных ветвях "библиотеки", то то, что вы описываете, - это то, что обрабатывается программным обеспечением управления исходным кодом, таким как SVN.

У вас будет "ствол" (ваша библиотека), а затем две ветви, созданные из ствола. На соответствующих вехах вы бы слейте ветку обратно в ствол и слейте ствол вниз в другие ветви.


Извините, я не прочитал весь текст на этой странице. Но! Короткий ответ: Visual Studio делает всю необходимую автоматизацию, которую вы хотите.

мы имеем подобную структуру. Решение 1, Решение 2 и общая библиотека с несколькими проектами в ней. Наша структура папок под SVN следующая:

\myRepository
            \Solution1
            \Solution2
            \CommonLibrary\
                          \Project1
                          \Project2
                          \Project3

Как видите,копирование здесь. Оба решения просто сохраняют ссылку на ..\CommonLibrary\ProjectX.

после выполнения команды SVN-Update для репозитория Visual Studio спрашивает меня: "ProjectX был изменен. Хочешь перезарядить? Я нажимаю " да " и продолжаю кодирование.

PS: также посмотрите на это программное обеспечение http://svnnotifier.tigris.org/ он может обновлять любое количество локальных копий репозитория автоматически (по таймеру) или щелчком мыши.