Howto patch a rubygem based package?

Posted on Jul 23, 2015

After I was asked again today how to properly patch a rubygems package, here is a quick how to.

First things first we branch the package.

darix@tengu ~/osc/tmp % osc bco devel:languages:ruby:extensions/rubygem-net-ssh-session
A    home:darix:branches:devel:languages:ruby:extensions
A    home:darix:branches:devel:languages:ruby:extensions/rubygem-net-ssh-session
A    home:darix:branches:devel:languages:ruby:extensions/rubygem-net-ssh-session/net-ssh-session-0.1.6.gem
A    home:darix:branches:devel:languages:ruby:extensions/rubygem-net-ssh-session/rubygem-net-ssh-session.changes
A    home:darix:branches:devel:languages:ruby:extensions/rubygem-net-ssh-session/rubygem-net-ssh-session.spec
At revision 9edd872bc9121e1c68a71d057dfa607f.
Note: You can use "osc delete" or "osc submitpac" when done.

darix@tengu ~/osc/tmp % cd home:darix:branches:devel:languages:ruby:extensions/rubygem-net-ssh-session

So far nothing unexpected a gem file and spec+changes.

darix@tengu rubygem-net-ssh-session % l
total 28
drwxr-xr-x 3 darix users   122 Jul 23 12:21 ./
drwxr-xr-x 4 darix users    47 Jul 23 12:21 ../
-rw-r--r-- 1 darix users 13824 Jul 23 09:54 net-ssh-session-0.1.6.gem
drwxr-xr-x 2 darix users  4096 Jul 23 12:21 .osc/
-rw-r--r-- 1 darix users   143 Jul 23 10:09 rubygem-net-ssh-session.changes
-rw-r--r-- 1 darix users  1472 Jul 23 09:54 rubygem-net-ssh-session.spec

I prefer quilt for my patch handling but quilt setup doesn’t know how to handle our spec files yet. So some manual work required. This btw is also the reason why I include the series file in the source package.

darix@tengu rubygem-net-ssh-session % gem unpack *gem
Unpacked gem: 'net-ssh-session-0.1.6'
darix@tengu rubygem-net-ssh-session % l
total 32
drwxr-xr-x 4 darix users   150 Jul 23 15:43 ./
drwxr-xr-x 4 darix users    47 Jul 23 12:21 ../
drwxr-xr-x 4 darix users  4096 Jul 23 15:43 net-ssh-session-0.1.6/
-rw-r--r-- 1 darix users 13824 Jul 23 09:54 net-ssh-session-0.1.6.gem
drwxr-xr-x 2 darix users  4096 Jul 23 12:21 .osc/
-rw-r--r-- 1 darix users   143 Jul 23 10:09 rubygem-net-ssh-session.changes
-rw-r--r-- 1 darix users  1472 Jul 23 09:54 rubygem-net-ssh-session.spec
darix@tengu rubygem-net-ssh-session % cd net-ssh-session-0.1.6 
darix@tengu rubygem-net-ssh-session/net-ssh-session-0.1.6 % ln -s .. patches

Quilt base set up is done and we can start patching. We start a new patch and try to find the files that need patching.

darix@tengu rubygem-net-ssh-session/net-ssh-session-0.1.6 % quilt new net-ssh-session-0.1.6_use_global_timeout.patch
Patch patches/net-ssh-session-0.1.6_use_global_timeout.patch is now on top
darix@tengu rubygem-net-ssh-session/net-ssh-session-0.1.6 % grep -r Timeout lib
lib/net/ssh/session.rb:          raise ArgumentError, "Timeout value should be numeric"
lib/net/ssh/session.rb:          Timeout.timeout(timeout) { block.call(self) }
lib/net/ssh/session_helpers.rb:        Timeout.timeout(time) do
darix@tengu rubygem-net-ssh-session/net-ssh-session-0.1.6 % quilt add lib/net/ssh/session.rb lib/net/ssh/session_helpers.rb
File lib/net/ssh/session.rb added to patch patches/net-ssh-session-0.1.6_use_global_timeout.patch
File lib/net/ssh/session_helpers.rb added to patch patches/net-ssh-session-0.1.6_use_global_timeout.patch
darix@tengu rubygem-net-ssh-session/net-ssh-session-0.1.6 % vim lib/net/ssh/session.rb lib/net/ssh/session_helpers.rb
# patch patch patch 
darix@tengu rubygem-net-ssh-session/net-ssh-session-0.1.6 % quilt refresh                                            
Refreshed patch patches/net-ssh-session-0.1.6_use_global_timeout.patch

Patch done! In this case it was really only 2 one line changes. Let us see what we got now.

darix@tengu rubygem-net-ssh-session/net-ssh-session-0.1.6 % ..
darix@tengu rubygem-net-ssh-session % l
total 44
drwxr-xr-x 4 darix users  4096 Jul 23 15:44 ./
drwxr-xr-x 4 darix users    47 Jul 23 12:21 ../
drwxr-xr-x 5 darix users  4096 Jul 23 15:44 net-ssh-session-0.1.6/
-rw-r--r-- 1 darix users 13824 Jul 23 09:54 net-ssh-session-0.1.6.gem
-rw-r--r-- 1 darix users  1154 Jul 23 15:44 net-ssh-session-0.1.6_use_global_timeout.patch
drwxr-xr-x 2 darix users  4096 Jul 23 12:21 .osc/
-rw-r--r-- 1 darix users   143 Jul 23 10:09 rubygem-net-ssh-session.changes
-rw-r--r-- 1 darix users  1472 Jul 23 09:54 rubygem-net-ssh-session.spec
-rw-r--r-- 1 darix users    47 Jul 23 15:43 series

Now we need to hook it up into our gem packaging magic. We need a gem2rpm.yml. I use a local copy here, but it ships also as documentation in the gem2rpm package.

darix@tengu rubygem-net-ssh-session % cp ~/gem2rpm.yml .
darix@tengu rubygem-net-ssh-session % vim gem2rpm.yml 

We append the following 2 lines to the example file:

:sources:
- series
:patches:
  net-ssh-session-0.1.6_use_global_timeout.patch: -p1
darix@tengu rubygem-net-ssh-session % l
total 60
drwxr-xr-x 4 darix users  4096 Jul 23 15:45 ./
drwxr-xr-x 4 darix users    47 Jul 23 12:21 ../
-rw-r--r-- 1 darix users  1717 Jul 23 15:45 gem2rpm.yml
drwxr-xr-x 5 darix users  4096 Jul 23 15:44 net-ssh-session-0.1.6/
-rw-r--r-- 1 darix users 13824 Jul 23 09:54 net-ssh-session-0.1.6.gem
-rw-r--r-- 1 darix users  1154 Jul 23 15:44 net-ssh-session-0.1.6_use_global_timeout.patch
drwxr-xr-x 2 darix users  4096 Jul 23 12:21 .osc/
-rw-r--r-- 1 darix users   143 Jul 23 10:09 rubygem-net-ssh-session.changes
-rw-r--r-- 1 darix users  1472 Jul 23 09:54 rubygem-net-ssh-session.spec
-rw-r--r-- 1 darix users    47 Jul 23 15:43 series
darix@tengu rubygem-net-ssh-session % g2r

g2r is a small shell function which calls gem2rpm with the –config parameter if a gem2rpm.yml exists. All left is some little osc house keeping.

darix@tengu rubygem-net-ssh-session % osc addremove
A    gem2rpm.yml
A    series
A    net-ssh-session-0.1.6_use_global_timeout.patch
darix@tengu rubygem-net-ssh-session % osc vc
darix@tengu rubygem-net-ssh-session % osc st
A    gem2rpm.yml
A    net-ssh-session-0.1.6_use_global_timeout.patch
M    rubygem-net-ssh-session.changes
M    rubygem-net-ssh-session.spec
A    series
darix@tengu rubygem-net-ssh-session % osc ci
Sending    rubygem-net-ssh-session.changes
Sending    rubygem-net-ssh-session.spec
Sending    gem2rpm.yml
Sending    series
Sending    net-ssh-session-0.1.6_use_global_timeout.patch
Transmitting file data .....
Committed revision 2.
darix@tengu rubygem-net-ssh-session %

Patch uploaded and we can submit it back into the project we branched from.