Определить версию со сценарием в файле спецификации RPM

У меня есть файл спецификации RPM, основанный на rhel7 с rpmbuild, где я хотел бы определить версию с помощью скрипта.

Я прочитал здесь http://www.techrepublic.com/article/rpmproc-spec-file/, что я могу это сделать:

%define version 1.2

Version: %{version}

И здесь файл спецификации RPM - Можно ли динамически заполнить переменную файла спецификации, которую я могу определить с помощью скрипта:

%define whoami %(cmd)

Итак, я попытался сделать это в своем файле спецификации:

%define version %(echo "$(sed -n 's|^[ ]*appVersion = "\(.*\)"|\1|p' /fullfilepath/values.txt | sed 's/^\(.*\)-.*$/\1/')")

Version: %{version}  **Line 23**

Но я получаю

error: line 23: Empty tag: Version:

Вещи, которые я тестировал до сих пор:

%define version %(echo "12") --basic script works ok, version becomes 12

//As a command straight in terminal
$ echo "$(sed -n 's|^[ ]*appVersion = "\(.*\)"|\1|p' /fullfilepath/values.txt | sed 's/^\(.*\)-.*$/\1/')"
//returns 1.2

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

Обновить

Я попытался заменить имя файла на фактическое значение, чтобы оно выглядело так

echo "$(sed -n 's|^[ ]*appVersion = "\(.*\)"|\1|p' <<< "appVersion = \"1.2-SNAPSHOT\"" | sed 's/^\(.*\)-.*$/\1/')"

Это работает при вызове в терминале, но как

%(echo "$(sed -n 's|^[ ]*appVersion = "\(.*\)"|\1|p' <<< "appVersion = \"1.2-SNAPSHOT\"" | sed 's/^\(.*\)-.*$/\1/')") 

но я все еще получаю

Empty tag: Version: Error

Обновление 2

Я протестировал другую, более сложную команду, чем echo "12":

%define version %(echo "$(git log -1 | grep commit | awk -F"commit " '{print $2}' | cut -c1-8)")

Это тоже нормально работает! Делает версию из 7 первых цифр хэша фиксации.

Обновление 3

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

%define version %(echo "$( sed 's/.*= //' <<< "appVersion = 1.2" )")

Если эта команда работает, но не моя первая, то в моей первой команде должно быть что-то, что работает только при вызове непосредственно в терминале, а не в% (cmd). Приближаемся!

Обновление 4

Итак, я, кажется, выделил, что это должно быть, любопытно, похоже, это может быть синтаксис -n или s| | \1 |p, который не нравится rpmbuild. Я сделал более простую версию своего оригинала. Проверить это:

#Error, doesn`t set version to 1.2
%define version %(echo "$( sed -n 's|^.*-\(-*\)|\1|p' <<< "foo-1.2" )") 

#Works ok! sets version to 1.2
%define version %(echo "$( sed 's/.*= //' <<< "appVersion = 1.2" )") 

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

Обновление 5

Я обнаружил, что здесь возникает серьезная проблема при работе с любым скриптом внутри% () с файлом спецификации и rpmbuild. Я попытался использовать awk, чтобы посмотреть, что произойдет, и он тоже сломается! Это гораздо глубже, чем я думал изначально, вроде раскрытия заговора:

#In terminal it prints 1.2-SNAPSHOT, but in Spec it's an error 
%define version %(echo "$(awk '/appVersion /{ print $3 }' <<< "appVersion = \"1.2-SNAPSHOT\"" | tr -d \")")

sh: -c: line 0: unexpected EOF while looking for matching `)'
sh: -c: line 1: syntax error: unexpected end of file
error: line 23: Empty tag: Version:

Обновление 6

Хорошие новости и плохие новости для всех, я обнаружил, что rpm, похоже, выполняет часть своей работы в фоновом режиме и не показывает, что делает, я наконец нашел команду, которая дает разные значения при вызове через rpm:

%define version %(echo "$(awk '/midonetVersion /{ print $3 }' <<< "midonetVersion = \"5.1-SNAPSHOT\"")")
#In terminal it echos "5.1-SNAPSHOT" (literally wrapped in "" )
#When in spec it set version to 5.1-SNAPSHOT , rpmbuild is removing the ""

Итак, теперь я внес изменения и назвал это:

#echos "5.1 in terminal and sets version to 5.1 in spec
%define version %(echo "$(awk '/appVersion /{ print $3 }' <<< "appVersion = \"1.2-SNAPSHOT\"")"| cut -d'-' -f1)

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

Последнее обновление

Было заключено перемирие с rpm, вместо этого я воспользуюсь этой командой:

%define version %(echo "$(awk '/ appVersion =/{ print $3 }' /filepath/values.txt" | sed 's/\"//g' | cut -d'-' -f1)

Он делает то же самое, что и моя первая команда, и работает внутри specfile, правильно устанавливая номер версии. Если кто-то догадывается, почему первая команда не запускается, я буду рад ее прочитать. Мир!


person Jimmie    schedule 18.11.2015    source источник
comment
Возможно, из-за проблемы с правами доступа /fullfilepath/values.txt. Попробуйте заменить это фактическим (или упрощенным) значением.   -  person Thirupathi Thangavel    schedule 18.11.2015


Ответы (2)


У вас должен быть сценарий оболочки, вызывающий команду rpmbuild. Вы можете использовать этот сценарий для вычисления версии (или, если на то пошло, любой команды, которую вы пытаетесь использовать в файле спецификации rpm).

Измените исходный код,

%define version %(echo "$(sed -n 's|^[ ]*appVersion = "\(.*\)"|\1|p' /fullfilepath/values.txt | sed 's/^\(.*\)-.*$/\1/')")
Version: %{version}

to,

%define version _VERSION_
Version: %{version}

и sed VERSION к его вычисленному значению в сценарии оболочки, который вызывает rpmbuild (перед вызовом rpmbuild). После того, как фактическое содержимое спецификации будет сброшено в какой-либо файл, передайте этот сгенерированный файл в rpmbuild в том же сценарии оболочки.

Вот краткое изложение шагов:

Предполагая, что у вас есть сценарий оболочки builder.sh, который вызывает rpmbuild, выполните следующие действия:

  1. Обновите файл спецификации, чтобы в нем была строка / макрос-заполнитель VERSION, как показано выше.
  2. Переместить текущий файл спецификации rpm в my_package_template.spec
  3. в builder.sh запустите команду (ы), чтобы получить версию и сохранить ее в переменной
  4. Используйте команду sed в файле my_package_template.spec, чтобы заменить VERSION этой вычисленной версией, и сохраните вывод sed в my_package.spec
  5. Передайте my_package.spec команде rpmbuild.

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

person Prasanna    schedule 22.11.2015
comment
rpmbuild позволяет устанавливать переменные из командной строки, и это намного проще, чем требовать sed и временные файлы. - person Aaron D. Marasco; 22.11.2015

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

Чтобы ответить на комментарий @Herrgott, если вы %define его в спецификации и попытаетесь переопределить с помощью --define, он не переопределит это (не может быть новой строки в комментариях) - вы можете установить _override переменную с тем же именем с помощью --define.

%if 0%{?val_override:1}
%define val %{val_override}
%else
%define val whatever
%endif
person Aaron D. Marasco    schedule 22.11.2015
comment
если вы %define это в спецификации и попытаетесь переопределить с помощью --define, это не переопределит - person Herrgott; 07.10.2020
comment
@Herrgott ответил в основном ответе; не может делать новые строки в комментариях. - person Aaron D. Marasco; 07.10.2020