Как включить номер редакции Subversion в проект Delphi

Я хотел бы иметь номер редакции исходного кода для исходного кода Delphi и exe-версии. Каков наилучший способ сделать это автоматически?

Я хотел бы отобразить номер редакции на экране «О программе» и в информации о версии проекта.

В настоящее время я использую Delphi IDE (2006/2007) и Tortoise SVN.

12.12.2008 20:23:20
5 ОТВЕТОВ
РЕШЕНИЕ

Я согласен с комментариями о том, что $ Revision $ не является подходящим инструментом для работы. Использование инструмента для извлечения номера ревизии из вывода svn info - действительно правильная вещь.

Однако следует отметить еще две вещи:

  1. Информация svn вернет правильную информацию только в том случае, если обновление svn было выполнено в каталоге с извлеченными источниками. Если вы используете пользовательские этапы сборки, вам, вероятно, следует добавить и команду для этого.

  2. svn info предоставляет вам также информацию о пути к хранилищу. Это единственный способ различать источники в транке и где-то еще, как в тегах . Если вы хотите, чтобы в поле «О программе» содержалась строка для правильной идентификации источников, использованных для сборки приложения, убедитесь, что путь к репозиторию также доступен.

Редактировать:

Это командный скрипт, который следует скопировать в каталог верхнего уровня проекта. Он обновит источники из репозитория, получит номер ревизии SVN из информационного вызова svn и сравнит его с константой SVN_REVISION из файла src \ SvnRev.inc . Если файл отсутствует, он создаст его, если ревизия отличается, он перезапишет его. Если svn недоступен, он запишет номер ревизии 0 в файл.

Полученный файл src \ SvnRev.inc можно просто включить в исходный файл. Аналогичный файл может быть создан для включения в ресурс версии.

@echo off

setlocal
rem determine project top level directory from command file name
set PRJDIR=%~dp0
cd %PRJDIR%

set SVNREVFILE=src\SvnRev.inc

rem execute "svn info", extract "Revision: 1234" line, and take SVN rev from there
svn update
for /F " usebackq tokens=1,2 delims=: " %%i in (`svn info`) do set key=%%i&set value=%%j&call :read-svn-rev
@echo SVN revision "%SVNREV%"

rem extract "const SVN_REVISION = 1234;" line, and take header SVN rev from there
for /F " usebackq tokens=2,4 " %%i in (%SVNREVFILE%) do set name=%%i&set value=%%j&call :read-file-rev
@echo Include file revision "%FILEREV%"

rem check for valid SVN rev
if "%SVNREV%" EQU "" goto :no-svn-ref
rem do not write file if SVN ref is equal
if "%FILEREV%" EQU "%SVNREV%" goto :EOF

@echo Writing svn revision %SVNREV% to %SVNREVFILE%
@echo const SVN_REVISION = %SVNREV% ; > %SVNREVFILE%
goto :EOF

:no-svn-ref
if not exist %SVNREVFILE% goto :no-header-file
rem do not write file if SVN ref is already unset
if "%FILEREV%" EQU "0" goto :EOF
@echo Writing svn revision 0 to %SVNREVFILE%
goto :write-no-version

:no-header-file
@echo Creating %SVNREVFILE% with svn revision 0
:write-no-version
@echo const SVN_REVISION = 0 ; > %SVNREVFILE%
goto :EOF

endlocal
goto :EOF

:read-svn-rev
if "%key%" EQU "Revision" set SVNREV=%value%&
goto :EOF

:read-file-rev
if "%name%" EQU "SVN_REVISION" set FILEREV=%value%&
goto :EOF
9
13.12.2008 14:31:15
Я обнаружил, что это не работает должным образом. Я думаю, что причина, вероятно, в том, что моя рабочая копия всегда содержит мою полную структуру проекта, включая теги и ветви. Поэтому скрипт будет принимать номер ревизии последнего изменения глобально, а не только папку, в которой оно выполнено. SubWCRev.exe, с другой стороны, безупречно работает с моим сценарием использования.
Timo Kosig 9.03.2010 10:03:18
@ Тимо: Это, безусловно, работает должным образом, даже если он может не делать то, что вы ожидаете. Этот скрипт возвращает глобальную ревизию, которую запрашивает OP. Я никогда не заявлял об этом, чтобы вернуть последнюю версию коммита, которая, конечно, отличается. Спасибо за отрицательное голосование.
mghie 9.03.2010 10:34:54
@mghie: Перечитав твой ответ, признаюсь, да, ты прав. Вы никогда не утверждали, что он вернет последнюю версию коммита в текущей рабочей копии. Поэтому я снял свой голос против. Это все еще не правильное решение для меня, но я уверен, что другие нашли этот ответ полезным.
Timo Kosig 12.03.2010 08:54:31
@mghie: Я пытался убрать свой отрицательный голос, но он говорит: «Голосуйте слишком старым, чтобы его можно было изменить, если этот ответ не отредактирован». Простите за это.
Timo Kosig 12.03.2010 08:58:18
@ Тимо: Если SubWCRev работает для вас, это здорово. Однако я не понимаю, почему скрипт не работает для вас. Если rev 42 был последним коммитом, который изменил вашу ветку, то совершенно неважно, какая ревизия у вашей рабочей копии, при условии, что она не меньше 42 - код, созданный на этой ветке, будет точно таким же для любой более поздней ревизии. Вот почему ревизия коммита бессмысленна, путь к хранилищу, используемый с определенной ревизией, важен. Вы требуете, чтобы ваш номер сборки был последней ревизией коммита , и я не знаю, почему вас это волнует.
mghie 12.03.2010 09:44:34

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

1
12.12.2008 20:27:10

Существует программа под названием SubWCRev.exe, которая поставляется с TortoiseSVN, которая сделает замену токена для вас. Таким образом, где-то в вашем источнике вы вставляете токен и передаете имена входных и выходных файлов в SubWCRev.exe, и он заменяет токен различной информацией SVN, например, номером редакции. Обратите внимание, что это отдельная программа, которую вы можете использовать со своим скриптом сборки, вам не нужно использовать TortoiseSVN с ним.

13
9.03.2010 14:39:02
Вот как я это использую. Ранее мы использовали скрипт выше, но сегодня мы создавали тег выпуска, и скрипт включал неправильный номер версии в сборку по причинам, описанным выше. Виноват. Мы перешли на использование SubWCRev.exe сейчас.
Timo Kosig 9.03.2010 10:04:43

Если вы используете ключевые слова svn: и включаете $Revision$в свой файл, он будет обновляться каждый раз, когда этот файл фиксируется.

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

1
12.12.2008 20:29:53
Звучит отлично, за исключением того, что я хотел бы получить «глобальную ревизию», которая обсуждается в документации.
Harriv 12.12.2008 20:52:21
Это не будет работать, если не существует какого-либо автоматического способа изменить этот файл, иначе он не будет зафиксирован, и номер редакции не изменится. И даже в этом случае, в лучшем случае, это взлом, потому что вы получаете много ненужных изменений SVN и загрязнение различий.
mghie 12.12.2008 22:24:02

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

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

Для версий до MSBuild Delphi создайте группу проектов, а затем сделайте сценарий первым проектом в группе. «Build all» или «Compile all» запустит скрипт перед компиляцией основного проекта.

Вы также можете иметь код в initializationразделе каждого модуля, который добавляет его ревизию (полученную в ответе Ieure) в глобальный список. Затем выберите наибольшее число в списке во время выполнения. Это может дать вам номер, отображаемый в поле «about», но вы не можете использовать его в информации о версии вашей программы.

5
12.12.2008 21:25:18