Подтвердить что ты не робот

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

Сценарий

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

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


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

alt text http://img689.imageshack.us/img689/9341/onbuildsolution1.jpg


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

alt text http://img32.imageshack.us/img32/7821/onbuildsolution2.jpg


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

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

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

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

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

    <solutions>
      <solution>
        <name>Solution1</name>
        <path>c:\...\Projects\Solution 1</path>
      </solution>
      <solution>
        <name>Solution2</name>
        <path>c:\...\Projects\Solution 2</path>
      </solution>
      <!-- more solutions -->
    </solutions>
    
  • Программа выполнит следующие действия:

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

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


Обновление. Какова моя мотивация для копирования папок проекта?

Одним словом - контроль версий.

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

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

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

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

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


Обновление 2

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

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

alt text http://img30.imageshack.us/img30/7445/referencedprojects.jpg

Я продолжаю иметь те же самые цели:

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

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

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

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

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

4b9b3361

Ответ 1

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

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

Ответ 2

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

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

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

Ответ 3

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

Мое решение.

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

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

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

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

Почему я так делаю?

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

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

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

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

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

Чтобы попытаться ответить на ваши неуловимые цели

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

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

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

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

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

@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.bat:

@echo off
call _projects hg incoming

и проверьте, что было бы нажато с помощью "__outgoing.bat":

@echo off
call _projects hg outgoing

Или на самом деле выполняйте эти операции с помощью "__push.bat":

@echo off
call _projects hg push

и "__pull.bat":

@echo off
call _projects hg pull

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

@echo off
call _projects hg update

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

@echo off
call _projects hg id

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

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

Параметры будущего.

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

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

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

Позаботьтесь, надеюсь, что это поможет,

Mark..........

Ответ 4

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

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

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

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

Ответ 5

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

Мы имеем аналогичную структуру. Solution1, Solution2 и общая библиотека с несколькими проектами в ней. Структура нашей папки в SVN следующая:

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

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

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

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