Blob Blame History Raw
#!/usr/bin/python
# -*- coding: utf-8 -*-
#
# apply-languages.py -- generate language subpackages from LANGUAGES comment
#                       in RPM spec files
# Copyright © 2012 Red Hat, Inc.
#
# 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, see <http://www.gnu.org/licenses/>.
#
# Author: Nils Philippsen <nils@redhat.com>

import os
import sys
import tempfile
import atexit
import re
from stat import S_IMODE

def usage():
    print >>sys.stderr, "Usage: %s <packagename>.spec" % (sys.argv[0],)
    sys.exit(1)

def cleantmpfile():
    global newfspath

    try:
        os.unlink(newsfpath)
    except OSError:
        pass

if len(sys.argv) != 2:
    usage()

sfpath = sys.argv[1]
if not os.access(sfpath, os.R_OK | os.W_OK):
    print >>sys.stderr, "Not readable/writable:", sfpath
    sys.exit(2)

sfdir = os.path.dirname(sfpath)
sfbase = os.path.basename(sfpath)

(fd, newsfpath) = tempfile.mkstemp(prefix=sfbase + ".", dir=sfdir)
atexit.register(cleantmpfile)
newsf = os.fdopen(fd, "w")

sf = open(sfpath)
sfcontent = sf.read()
sf.close()

sfmode = S_IMODE(os.stat(sfpath).st_mode)

languages_re = re.compile(
        r"^#\s*LANGUAGES:\s*(?P<languages>[^\n\r]+)\s*$", re.MULTILINE)
langsplit_re = re.compile(r"\s+")
begin_langpkgs_re = re.compile(
        r"^#\s*BEGIN:\s*LANGUAGE\s+SUB\s+PACKAGES\s*$", re.MULTILINE)
end_langpkgs_re = re.compile(
        r"^#\s*END:\s*LANGUAGE\s+SUB\s+PACKAGES\s*$", re.MULTILINE)
begin_langfiles_re = re.compile(
        r"^#\s*BEGIN:\s*LANGUAGE\s+FILE\s+LISTS\s*$", re.MULTILINE)
end_langfiles_re = re.compile(
        r"^#\s*END:\s*LANGUAGE\s+FILE\s+LISTS\s*$", re.MULTILINE)

name_re = re.compile(r"^name:\s*(?P<name>[^\n\r]+)\s*$",
        re.MULTILINE | re.IGNORECASE)
license_re = re.compile(r"^license:\s*(?P<license>[^\n\r]+)\s*$",
        re.MULTILINE | re.IGNORECASE)
group_re = re.compile(r"^group:\s*(?P<group>[^\n\r]+)\s*$",
        re.MULTILINE | re.IGNORECASE)

missing = False
for what, what_re in (("name tag", name_re), ("license tag", license_re),
        ("group tag", group_re), ("LANGUAGES comment", languages_re),
        ("BEGIN: LANGUAGE SUB PACKAGES comment", begin_langpkgs_re),
        ("END: LANGUAGE SUB PACKAGES comment", end_langpkgs_re),
        ("BEGIN: LANGUAGE FILE LISTS comment", begin_langfiles_re),
        ("END: LANGUAGE FILE LISTS comment", end_langfiles_re),
        ):
    found = what_re.search(sfcontent)
    if found is None:
        print >>sys.stderr, "%s not found" % (what,)
        missing = True
if missing:
    sys.exit(2)

langspecs = langsplit_re.split(
        languages_re.search(sfcontent).group('languages'))
#languages = []
#for ls in langspecs:
#    langcode, langname = ls.split(",")
#    languages.append((langcode, langname))
languages = [(x.split(",")[0], x.split(",")[1].replace('_', ' '))
        for x in langspecs]
name = name_re.search(sfcontent).group('name')
license = license_re.search(sfcontent).group('license')
group = group_re.search(sfcontent).group('group')

numlang = len(languages)
replacing = None

sflines = sfcontent.split("\n")
if sflines[-1] == "":
    del sflines[-1]

for line in sflines:
    if not replacing:
        print >>newsf, line
        if begin_langpkgs_re.match(line):
            replacing = 'langpkgs'
        elif begin_langfiles_re.match(line):
            replacing = 'langfiles'
    elif replacing == 'langpkgs':
        if end_langpkgs_re.match(line):
            replacing = None
            for no, lang in enumerate(languages):
                langcode, langname = lang
                print >>newsf, """%%package %(langcode)s
Summary: %(langname)s (%(langcode)s) language support for %(name)s
Group: %(group)s
Requires: %%{name} = %%{?epoch:%%{epoch}:}%%{version}-%%{release}

%%description %(langcode)s
%(langname)s language support for %(name)s.""" % locals()
                if no < numlang:
                    print >>newsf
            print >>newsf, line
    elif replacing == 'langfiles':
        if end_langfiles_re.match(line):
            replacing = None
            for lang in languages:
                langcode, langname = lang
                print >>newsf, "%%files %(langcode)s -f files.list.%(langcode)s" % locals()
            print >>newsf, line

newsf.close()

os.rename(newsfpath, sfpath)
os.chmod(sfpath, sfmode)