Define Version with script in RPM spec file

11,699

Solution 1

You must be having a shell script that invokes rpmbuild command. You can use that script to compute version (or for that matter, any command that you are trying to use in rpm spec file).

Change your original code,

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

to,

%define version _VERSION_
Version: %{version}

and sed VERSION to its computed value in the shell script that calls rpmbuild (before invoking rpmbuild). After the actual spec contents are dumped to some file, pass on that generated file to rpmbuild in the same shell script.

Here is a summary of the steps:

Assuming you have a builder.sh shell script that calls rpmbuild, follow below steps:

  1. Update your spec file to have VERSION placeholder string/macro as show above
  2. Move current rpm spec file to my_package_template.spec
  3. in builder.sh, run command(s) to get your version and save the version to a variable
  4. Use sed command on my_package_template.spec file to replace VERSION by this computed version, and save the sed output to my_package.spec
  5. Pass my_package.spec to rpmbuild command.

Repeat steps 1, 3 and 4 for replacing usage of any other shell commands inside your spec file.

Solution 2

I would do a wrapper script. That allows you to decide things like if it is a regular release or a development one, etc. Then you can pass the variables with the --define option - see this question for more options.

To respond to @Herrgott's comment "if you %define it in spec and try to redefine with --define it won't override that" (can't have newlines in comments) - you can set an "_override" variable of the same name with --define.

%if 0%{?val_override:1}
%define val %{val_override}
%else
%define val whatever
%endif
Share:
11,699

Related videos on Youtube

Jimmie
Author by

Jimmie

Amateur programmer and software developer

Updated on August 10, 2022

Comments

  • Jimmie
    Jimmie over 1 year

    I have an RPM Spec file, building on rhel7 with rpmbuild, where I would like to define the Version with a script.

    I read here http://www.techrepublic.com/article/rpmproc-spec-file/ , That I can do this:

    %define version 1.2
    
    Version: %{version}
    

    And here RPM spec file - Is it possible to dynamically populate a spec file variable , That I can define with a script:

    %define whoami %(cmd)
    

    So I tried to do this in my Spec File:

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

    But I get a

    error: line 23: Empty tag: Version:
    

    Things I have tested so far:

    %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
    

    These work well, So I have no idea what it could be thats causing it to fail. Any ideas what could be casuing it to fail when I call the same thing in define tag in spec file?

    Update

    I tried replacing the file name with the actual value so it looks like this

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

    That works when called in terminal but as a

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

    but I still get the

    Empty tag: Version: Error
    

    Update 2

    I tested a different more complex command then echo "12":

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

    This works ok too! Makes the version the 7 first digits of the commit hash.

    Update 3

    The mystery continues, I did a test to check if its the sed command thats the cause but the following command gives me 1.2 as the version

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

    If this command works but not my first one, then its got to be with something in my first command that only works when called directly in terminal and not in %(cmd). Getting closer!

    Update 4

    Ok so I seem to have isolated what it must be, curious, looks like it could be the -n or the s| | \1 |p syntax that rpmbuild doesn't like. I made a more simpler version of my original. Check it out:

    #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" )") 
    

    Unfortunately though I don't think I can do anymore to isolate and figure out what the issue is. Theres nothing wrong with using a sed in the style of the second command but its still very interesting as to why the first command doesn't work.

    Update 5

    I have discovered that there is some deep issue here when working with any script inside %() with a spec file and rpmbuild. I tried using awk just to see what would happen and it too breaks! This goes way deeper then I initially thought, like discovering a conspiracy:

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

    Update 6

    Good news and bad news for everyone, I found that rpm seems to be doing some of its own work in the backround and not showing what its doing, I finally found a command that gives different values when called through 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 ""
    

    So now I made an adjustment and called this:

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

    So from looking at this, I think there maybe is a similar kind of behind the scenes parsing of the result of my first sed command from rpm. We will have our way rpm!

    Final Update

    A truce was made with rpm, I am going to use this command instead:

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

    It does the same thing as my first command and works inside specfile setting the version number correctly. If anyone has any guess as to why the first command wouldn't run I would be thrilled to read it. Peace!

  • Aaron D. Marasco
    Aaron D. Marasco over 8 years
    rpmbuild allows setting variables from the command line, and that's a lot easier than requiring sed and temporary files.