#!/usr/bin/env python # -*- coding: utf-8 -*- # Copyright (C) 2006-2007 José Matos # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. # ChangeLog: # # * Sat Apr 28 2007 José Matos 1.2 # - Based on feedback from https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=215927 # - Create R libdir in %install section # - no need to remove the R.css with -r, after all it is a single file # - add a safeguard for post and postun sections. # # * Wed Mar 08 2006 José Matos 1.1 # - Check for fortran files and add gcc-gfortran as required if needed # - Add DESCRIPTION to %doc # # * Fri Mar 03 2006 José Matos 1.0 # - Initial script release import sys import tarfile import re import time def usage(): print """[Usage] cran2rpmspec tar_package tar_package - name of the R package (tar.gz) to build the spec file. """ sys.exit() token = re.compile(r"^\S+:") def get_description(fp): # dictionary that holds all the parsed data from the DESCRIPTION file r_info = {} cat = "" for line in fp.readlines(): if token.match(line): cat = line.split()[0][:-1] r_info[cat] = " ".join(line.split()[1:]) else: r_info[cat] += '\n' + line[:-1] # If package does to declare a URL give it the canonical location if 'URL' not in r_info: r_info["URL"] = "http://cran.r-project.org/contrib/main/Descriptions/%s.html" % r_info['Package'] # Deal with Version and Release Version tags r_info["Real_Version"] = r_info["Version"] r_info["Version"] = r_info["Version"].split('-')[0] if r_info["Real_Version"] != r_info["Version"]: idx = r_info["Real_Version"].find('-') + 1 r_info['packrel'] = r_info["Real_Version"][idx:] r_info["Real_Version"] = '%{packname}_%{version}-%{packrel}' else: r_info["Real_Version"] = '%{packname}_%{version}' # If the license is verbose output it as comments if '\n' in r_info['License']: real_license = '\n#' + r_info['License'].replace('\n','\n#') r_info['License'] = 'Distributable' + real_license # Time and packager for changelog of the spec file r_info['Time'] = time.strftime("%a %b %d %Y") r_info['Packager'] = 'Joe Doe ' # Remove final dot from title r_info['Title'] = r_info['Title'].rstrip(' .') # Requires depends = [] if 'Depends' in r_info: depends += r_info['Depends'].strip().split(',') suggests = depends[:] if 'Suggests' in r_info: suggests += r_info['Suggests'].strip().split(',') r_dep = False for i, line in enumerate(suggests): line = line.replace('(', '') line = line.replace(')', '') suggests[i] = line.strip() if not suggests[i]: continue if 'R' in suggests[i].split(): r_dep = True continue suggests[i] = 'R-' + suggests[i] if not r_dep: suggests += ['R'] r_dep = False for i, line in enumerate(depends): line = line.replace('(', '') line = line.replace(')', '') depends[i] = line.strip() if not suggests[i]: continue if 'R' in depends[i].split(): r_dep = True continue depends[i] = 'R-' + depends[i] if not r_dep: depends += ['R', 'tetex-latex'] else: depends += ['tetex-latex'] if 'SystemRequirements' in r_info: depends += r_info['SystemRequirements'].strip().split(',') suggests += r_info['SystemRequirements'].strip().split(',') # BuildRequires r_info['Suggests'] = ", ".join(suggests) r_info['Depends'] = ", ".join(depends) # Description # strip whitespaces from lines tmp = r_info['Description'].split('\n') for i,line in enumerate(tmp): tmp[i] = line.strip() r_info['Description'] = "\n".join(tmp) return r_info def get_info(name): doc = [] basedir = "" src = False fortran = False # Are there any fortran files? tar = tarfile.open(name, "r") for tarinfo in tar: fp = tarinfo.name.split('/') basedir = fp[0] if len(fp) == 2: if fp[1]: doc.append(fp[1]) if len(fp) > 2: if fp[1] == 'src': src = True if fp[-1][-2:] in (".f", ".F") or fp[-1][-4:] in ('.f90', '.f95'): fortran = True if 'DESCRIPTION' in doc: rinfo = get_description(tar.extractfile('%s/DESCRIPTION' % basedir)) else: rinfo = {} rinfo['doc'] = " ".join(doc) # if there is not any source code to compile the debug packages are useless if not src: rinfo['debug'] = '%define debug_package %{nil}' else: rinfo['debug'] = '' if fortran: rinfo['Depends'] += ', gcc-gfortran' tar.close() return rinfo def write_spec(rinfo): if 'packrel' in rinfo: print "%%define packrel %s" % rinfo['packrel'] print """%%define packname %(Package)s Summary: R module, %(Title)s Name: R-%%{packname} Version: %(Version)s Release: 1%%{?dist} License: %(License)s Group: Applications/Engineering Source0: ftp://cran.r-project.org/pub/R/contrib/main/%(Real_Version)s.tar.gz URL: %(URL)s BuildRoot: %%{_tmppath}/%%{name}-%%{version}-%%{release}-root-%%(%%{__id_u} -n) Requires: %(Suggests)s BuildRequires: %(Depends)s %(debug)s %%description %(Description)s %%prep %%setup -q -n %%{packname} %%build %%install %%{__rm} -rf %%{buildroot} mkdir -p %{buildroot}%{_libdir}/R/library cd ..; R CMD INSTALL %%{packname} -l %%{buildroot}%%{_libdir}/R/library %%{__rm} -f %%{buildroot}%%{_libdir}/R/library/R.css %%check cd ..;%%{_bindir}/R CMD check %%{packname} %%clean %%{__rm} -rf %%{buildroot} %%post %%{__cat} %%{_libdir}/R/library/*/CONTENTS > %%{_libdir}/R/doc/html/search/index.txt || : %%postun %%{__cat} %%{_libdir}/R/library/*/CONTENTS > %%{_libdir}/R/doc/html/search/index.txt || : %%files %%defattr(-, root, root, -) %%{_libdir}/R/library/%%{packname} %%doc DESCRIPTION %%changelog * %(Time)s %(Packager)s %(Version)s-1 - Initial package creation """ % rinfo if __name__ == "__main__": if len(sys.argv) < 2: usage() rinfo = get_info(sys.argv[1]) write_spec(rinfo)