Альтернативный идентификатор инструмента в свойстве SVN
Мы уже использовали инструмент "Ident" в CVS через ключевые слова RCS, чтобы получить некоторую информацию, такую как "ID" и "DATE" из наших исходных кодов. Мы могли бы просто сделать это, вставив ключевые слова $Id$ и $Date$ в текстовый файл, и было приятно, когда мы компилировали программу и могли получить ту же информацию из двоичного файла с помощью инструмента Ident:
$ ident a.out
Теперь мы используем SVN. Это все еще может быть просто сделано через свойства SVN с лучшими функциями. Единственная проблема заключается в том, что мы получаем эту информацию только в текстовых файлах, но нам также нужно каким-то образом получать их из двоичного скомпилированного файла, как Ident выше.
Любая идея, как мы можем получить их из двоичного файла?
1 ответ
Subversion, когда заданы ключевые слова, создаст идентичную строку типа идентификатора. Ключевое слово не установлено в бинарных программах, потому что это повредит бинарным программам. Вместо этого вы создаете строковую переменную с информацией о версии, например, в источнике:
VERSION_STRING = "$Id$";
Когда Subversion сделает заказ, он расширит это до:
VERSION_STRING = "$Id: foo.blah 12338 2014/06/12 02:11:38 bsmith $";
Поскольку это переменная, она будет сохранена в двоичном коде, а ident
Программа должна быть в состоянии найти его.
Убедитесь, что свойство Subversion svn: Keywords установлено в этом исходном файле. В противном случае Subversion не расширит ключевое слово.
И не то, почему вы не должны использовать расширение ключевых слов...
Расширение ключевых слов было концепцией, которая началась с более примитивных систем контроля версий. Это был способ отслеживать изменения, потому что концепция working directory
не существовало В конце концов, ключевые слова оказались чем-то большим, чем боль. Интересно, что первой системой контроля версий, которая отказалась от автоматических ключевых слов, была CVS, основанная на RCS. CVS была первой системой контроля версий, которая создала рабочий каталог, а не отдельные файлы, версии которых были по одному.
Программа - это не один или два файла, это могут быть десятки, а может быть, и сотни. Если у меня есть один файл, где я положил $Id$
ключевое слово, показанная информация о версии - это просто информация о версии этого файла. Если я не изменю этот файл, информация о версии будет идентичной в каждом выпуске. Одним из способов было поместить ключевое слово в каждый файл:
$ ident /bin/ksh | wc -l
58
Есть 57 отдельных ключевых слов в моем /bin/ksh
файл. Теперь все, что мне нужно сделать, это посмотреть на каждый из этих отдельных идентификаторов и определить, какая версия Kornshell у меня есть.
Или я мог бы сделать это:
$ ksh --version
version sh (AT&T Research) 93u 2011-02-08
Ах, теперь я знаю, какую версию моего кода нужно оформить. Это, вероятно, помечены с 93u 2011-02-08
(Ну, не совсем, поскольку CVS и RCS не допускали теги с пробелами или начинающиеся с цифр. Но я легко смог бы преобразовать это в определенный тег CVS/RCS). С CVS я мог взглянуть на информацию журнала и посмотреть, какие изменения произошли тоже. Исправлена ли определенная ошибка? Была ли добавлена определенная функция? Кто сделал это изменение кода?
Чтобы создать эту информацию, система сборки использовала некоторый метод для изменения исходного файла с этой информацией, когда она была извлечена. Вам даже не нужно совершать это изменение. На самом деле, лучше не делать этого. Мой источник выглядит так:
VERSION = "$Id: %VERSION% $";
и система сборки заменяет %VERSION%
с тем, что я хочу %VERSION%
быть. Даже не скомпилированный код, такой как PHP или JavaScript, может извлечь из этого пользу. Объедините это с CI-системой, такой как Jenkins, которая может запускать модульные тесты, и упаковывать программное обеспечение при каждом изменении кода, и у вас есть возможность автоматически включить это в ваш реальный выпуск.
Мы магазин Java, поэтому мы встраиваем эту информацию следующим образом:
<copy file="${version.file}"
tofile="${actual.version.file}">
<filterset>
<filter token="VERSION" value="${env.JENKINS_JOB} Build #${env.BUILD_NUMBER}"/>
</filterset>
</copy>
И Дженкинс заменит эту строку именем работы Дженкинса и номером сборки. Поскольку мы выпускаем наше программное обеспечение на основе заданий Jenkins и номера сборки, мы можем отслеживать наши изменения таким образом.
Представьте, что это изменение привело к скомпилированной строке, например:
$Id: Project-trunk Build #343 $
ident
Команда может выбрать это. Эта сборка связана с определенным набором ревизий Subversion (и, возможно, даже с тегом Subversion), и с помощью Subversion я могу видеть, какие изменения были внесены, и если я интегрировал это в систему отслеживания проблем. На самом деле, почему вы это делаете, почему бы не настроить его так, чтобы команда SCCS `what тоже могла его забрать:
$Id: @(#) Project-trunk Build #343 < $
what command picks up the
@(#)string and prints out the entire string until it runs into a NULL character, a _NL_ character, or the
< `.
$ what program.exe
/opt/bin/program.ext
Project-trunk Build #343
$ ident program.exe
/opt/bin/program.exe
$Id: @(#) Project-trunk Build #343 < $