Исходная проблема
При создании наших проектов я хочу, чтобы во всех хранилищах этого хранилища (библиотека, приложение или тестовое приложение) был встроен меркурийный идентификатор каждого репозитория.
Я нахожу, что гораздо проще отлаживать приложение, выполняемое клиентами, на 8 часовых поясов, если вы точно знаете, что нужно для создания конкретной версии приложения, которое они используют. Таким образом, каждый проект (приложение или библиотека) в наших системах реализует способ получения связанной информации о пересмотре.
Мне также очень полезно узнать, было ли скомпилировано приложение с чистыми (немодифицированными) наборами изменений из репозитория. "Hg id" полезно добавляет + к идентификатору набора изменений, когда в репозитории имеются незафиксированные изменения, поэтому это позволяет нам легко увидеть, работают ли люди с чистой или модифицированной версией кода.
Мое текущее решение подробно описано ниже и отвечает основным требованиям, но с ним есть ряд проблем.
Текущее решение
В настоящий момент для каждого решения Visual Studio я добавляю следующие команды командной строки "Pre-build event":
cd $(ProjectDir)
HgID
Я также добавляю файл HgID.bat в каталог проекта:
@echo off
type HgId.pre > HgId.cs
For /F "delims=" %%a in ('hg id') Do <nul >>HgID.cs set /p = @"%%a"
echo ; >> HgId.cs
echo } >> HgId.cs
echo } >> HgId.cs
вместе с файлом HgId.pre, который определяется как:
namespace My.Namespace {
/// <summary> Auto generated Mercurial ID class. </summary>
internal class HgID {
/// <summary> Mercurial version ID [+ is modified] [Named branch]</summary>
public const string Version =
Когда я создаю свое приложение, событие pre-build запускается во всех библиотеках, создавая новый файл HgId.cs(который не хранится под контролем ревизии) и заставляет библиотеку перекомпилировать с помощью нового ' hg id 'в' Version '.
Проблемы с текущим решением
Основная проблема заключается в том, что, поскольку HgId.cs воссоздается при каждой предварительной сборке, поэтому каждый раз, когда нам нужно что-то скомпилировать, все проекты в текущем решении перекомпилируются. Поскольку мы хотим легко отлаживать наши библиотеки, мы обычно храним много библиотек, на которые ссылается наше основное приложение. Это может привести к увеличению времени сборки, которое значительно больше, чем хотелось бы.
В идеале я хотел бы, чтобы библиотеки компилировались только в том случае, если содержимое файла HgId.cs действительно изменилось, в отличие от повторного создания с точно таким же содержимым.
Вторая проблема с этим методом заключается в зависимости от конкретного поведения оболочки Windows. Мне пришлось несколько раз модифицировать командный файл, поскольку оригинал работал под XP, но не Vista, следующая версия работала под Vista, но не XP, и, наконец, мне удалось заставить ее работать с обоими. Будет ли он работать с Windows 7, но все равно угадывает, и со временем я вижу, что более вероятно, что подрядчики ожидают, что смогут создавать наши приложения в своем ядре Windows 7.
Наконец, у меня есть эстетическая проблема с этим решением, пакетные файлы и связанные файлы шаблонов, похоже, неправильный способ сделать это.
Мои актуальные вопросы
Как бы вы решили/как вы решаете проблему, которую я пытаюсь решить?
Какие варианты лучше, чем то, что я сейчас делаю?
Отклоненные решения этих задач
Прежде чем я применил текущее решение, я посмотрел на расширение Mercuryial Keyword, поскольку это казалось очевидным решением. Тем не менее, чем больше я смотрел на него и читал мнения людей, тем больше я пришел к выводу, что это не совсем то, что нужно делать.
Я также помню проблемы, связанные с заменой ключевых слов в проектах в предыдущих компаниях (просто мысль о необходимости использования Source Safe снова наполняет меня чувством ужаса * 8).
Кроме того, я особо не хочу включать расширения Mercurial, чтобы завершить сборку. Я хочу, чтобы решение было само собой разумеющимся, так что приложение не просто случайно скомпилировано без встроенной информации о версии только потому, что расширение не включено или не было установлено правильное вспомогательное программное обеспечение.
Я также подумал о написании этого на более понятном языке сценариев, где я только напишу файл HgId.cs, если бы контент действительно изменился, но все варианты, о которых я мог думать, потребуют от моих сотрудников, подрядчиков и возможно, заказчикам необходимо установить программное обеспечение, которое им может и не понадобиться (например, cygwin).
Любые другие варианты, о которых люди могут подумать, будут оценены.
Update
Частичное решение
Поиграв с ним некоторое время, мне удалось получить файл HgId.bat, чтобы перезаписать файл HgId.cs, если он изменился:
@echo off
type HgId.pre > HgId.cst
For /F "delims=" %%a in ('hg id') Do <nul >>HgId.cst set /p = @"%%a"
echo ; >> HgId.cst
echo } >> HgId.cst
echo } >> HgId.cst
fc HgId.cs HgId.cst >NUL
if %errorlevel%==0 goto :ok
copy HgId.cst HgId.cs
:ok
del HgId.cst
Проблемы с этим решением
Несмотря на то, что HgId.cs больше не воссоздается каждый раз, Visual Studio все еще настаивает на компиляции всего раз. Я пробовал искать решения и проверял "Только создавать проекты запуска и зависимости от Run" в "Инструменты | Параметры | Проекты и решения" | Сборка и запуск, но это не имеет никакого значения.
Вторая проблема также остается, и теперь у меня нет возможности проверить, будет ли она работать с Vista, поскольку этот подрядчик больше не работает с нами.
- Если кто-нибудь может протестировать этот командный файл в окне Windows 7 и/или Vista, я был бы признателен, если бы он услышал, как это произошло.
Наконец, моя эстетическая проблема с этим решением еще сильнее, чем раньше, поскольку пакетный файл более сложный, и теперь есть больше ошибок.
Если вы можете думать о каких-либо лучших решениях, я бы хотел услышать о них.