Opened 10 years ago

Closed 8 years ago

#76 closed enhancement (fixed)

spec: Pull sources directly from SVN/GIT

Reported by: dmik Owned by:
Priority: major Milestone:
Component: spec files Version:
Severity: high Keywords:
Cc:

Description

Currently, for many packages the logic of obtaining the sources to build the package is like this:

  1. Take the original vendor source archive.
  2. Generate an OS/2 diff from SVN/GIT between the corresponding vendor branch and the corresponding revision of the trunk.
  3. Apply the diff to the source tree from 1.
  4. Pack the archive from 1. and the diff from 2. in the source RPM.

This approach has several problems:

  1. You need to find and download the right source archive and generate the right diff each time you want to make a new RPM package. This is kind of double work since both the source and the diff are already in the repo, matched and merged.
  2. The information about the exact SVN/GIT commit the sources are taken from is lost. This makes it hard to tell which state of the source tree the given RPM release represents. It's therefore easy to mess things up when there are too many packages to maintain.

I have a better solution which I already tested on a small which package. In short, the logic looks like this:

  1. Add two variables to .spec: svn_url and svn_rev which point to the correct SVN branch and revision of the source tree to build (including all necessary OS/2 patches etc).
  2. In the %prep section, check for the presence of the ZIP with the given revision in SRCS and if not there, check it out right from SVN, then pack and put to SRCS.
  3. Proceed further as usual.

For GIT, use a similar logic but with the appropriate variables git_url and git_commit and respective commands.

This way, no duplication takes place, no manual work is needed and it's always clear which revision the given RPM represents. This simplifies package managing a lot.

The .spec code for this is very simple, these are the corresponding parts from http://trac.netlabs.org/rpm/browser/spec/trunk/SPECS/which.spec?rev=429 which may be used as a template:

%define svn_url     http://svn.netlabs.org/repos/ports/which/trunk
%define svn_rev     733

Source: %{name}-%{version}-r%{svn_rev}.zip
%prep
%if %(sh -c 'if test -f "%{_sourcedir}/%{name}-%{version}-r%{svn_rev}.zip" ; then echo 1 ; else echo 0 ; fi')
%setup -q
%else
%setup -n "%{name}-%{version}" -Tc
svn export -r %{svn_rev} %{svn_url} . --force
rm -f "%{_sourcedir}/%{name}-%{version}-r%{svn_rev}.zip"
(cd .. && zip -SrX9 "%{_sourcedir}/%{name}-%{version}-r%{svn_rev}.zip" "%{name}-%{version}")
%endif

I suggest to use this approach for all programs for which we maintain a SVN or a GIT repo (i.e. everything from http://trac.netlabs.org/ports/, for instance).

Change History (6)

comment:1 Changed 9 years ago by dmik

In r471, I improved the snippet a bit. The new one allows to specify an absolute file path to the working copy instead of the repository's URL. The new snippet is like this:

%define svn_url     http://svn.netlabs.org/repos/ports/libtool/trunk
%define svn_rev     891

Source: %{name}-%{version}%{?svn_rev:-r%{svn_rev}}.zip

BuildRequires: gcc make subversion zip
%prep
%if %{?svn_rev:%(sh -c 'if test -f "%{_sourcedir}/%{name}-%{version}-r%{svn_rev}.zip" ; then echo 1 ; else echo 0 ; fi')}%{!?svn_rev):0}
%setup -q
%else
%setup -n "%{name}-%{version}" -Tc
svn export %{?svn_rev:-r %{svn_rev}} %{svn_url} . --force
rm -f "%{_sourcedir}/%{name}-%{version}%{?svn_rev:-r%{svn_rev}}.zip"
(cd .. && zip -SrX9 "%{_sourcedir}/%{name}-%{version}%{?svn_rev:-r%{svn_rev}}.zip" "%{name}-%{version}")
%endif

In order to use the working copy instead of the URL one does something like that:

%define svn_url     D:/Coding/ports/libtool/trunk
#%define svn_rev     891

Note that svn_rev is commented out — this causes the local changes to be picked up. If svn_rev is not commented out, the specified revision w/o any local modifications will be used (i.e. the same way as when giving an URL; the only difference is that no network connection is required given that the specified revision is already contained in the working copy).

comment:2 Changed 9 years ago by dmik

I only used the above snippet in libtool.spec so far; I'm not going to batch update the rest of .spec files using this technique: this is to be done as needed. New .spec files should always use the recent snippet.

comment:4 Changed 9 years ago by Silvan Scherrer

Component: rpmspec files
Severity: high

comment:5 Changed 8 years ago by Silvan Scherrer

Shouldn't we close this ticket, as the documentation is at the wiki now?

comment:6 Changed 8 years ago by dmik

Resolution: fixed
Status: newclosed

Yes, we've been already doing it in all .spec files on a general basis and it's well documented. The issue may be closed.

Note: See TracTickets for help on using tickets.