18

我有一个 RPM Spec 文件,使用 rpmbuild 在 rhel7 上构建,我想在其中使用脚本定义版本。

我在这里读到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

这些工作得很好,所以我不知道是什么导致它失败。当我在规范文件的定义标签中调用相同的东西时,有什么想法可能导致它失败?

更新

我尝试用实际值替换文件名,所以它看起来像这样

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

好的,所以我似乎已经隔离了它必须是什么,好奇,看起来它可能是rpmbuild 不喜欢-n的语法。s| | \1 |p我制作了一个更简单的原始版本。一探究竟:

#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!

最终更新

使用 rpm 进行了休战,我将使用以下命令:

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

它与我的第一个命令执行相同的操作,并在 specfile 中正确设置版本号。如果有人对为什么第一个命令不会运行有任何猜测,我会很高兴阅读它。和平!

4

2 回答 2

4

您必须有一个调用 rpmbuild 命令的 shell 脚本。您可以使用该脚本来计算版本(或者就此而言,您尝试在 rpm 规范文件中使用的任何命令)。

更改您的原始代码,

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

至,

%define version _VERSION_
Version: %{version}

并将VERSION sed到调用 rpmbuild 的 shell 脚本中的计算值(在调用 rpmbuild 之前)。在将实际规范内容转储到某个文件后,将生成的文件传递给同一 shell 脚本中的 rpmbuild。

以下是步骤的摘要:

假设您有一个调用 rpmbuild 的 builder.sh shell 脚本,请执行以下步骤:

  1. 更新您的规范文件以具有VERSION占位符字符串/宏,如上所示
  2. 将当前 rpm 规范文件移动到 my_package_template.spec
  3. 在 builder.sh 中,运行命令以获取您的版本并将版本保存到变量中
  4. 在 my_package_template.spec 文件上使用 sed 命令将VERSION替换为此计算版本,并将 sed 输出保存到 my_package.spec
  5. 将 my_package.spec 传递给 rpmbuild 命令。

重复步骤 1、3 和 4 以替换 spec 文件中任何其他 shell 命令的使用。

于 2015-11-22T08:09:20.910 回答
1

我会做一个包装脚本。这使您可以决定它是常规版本还是开发版本等。然后您可以使用--define选项传递变量-有关更多选项,请参见此问题

要回应@Herrgott 的评论“如果你%define在规范中尝试重新定义--define它不会覆盖它”(评论中不能有换行符) - 你可以设置一个“ _override”变量与--define.

%if 0%{?val_override:1}
%define val %{val_override}
%else
%define val whatever
%endif
于 2015-11-22T13:46:14.417 回答