From 7b30112606252ef9d69c3061344f7a3e946ae390 Mon Sep 17 00:00:00 2001 From: Olav Vitters Date: Wed, 2 Jul 2014 21:11:23 +0200 Subject: add clean-spec subcommand and minor bugfix --- mgagnome | 94 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 92 insertions(+), 2 deletions(-) (limited to 'mgagnome') diff --git a/mgagnome b/mgagnome index 26ff3fe..9702dc8 100755 --- a/mgagnome +++ b/mgagnome @@ -331,10 +331,17 @@ def is_valid_hash(path, algo, hexdigest): return local_hash.hexdigest() == hexdigest +re_clean_1 = re.compile(r'\[[^]()]+\]$') +def clean_pkgconfig_prov(prov): + prov = re_clean_1.sub('', prov) + return prov + class SpecFile(object): re_update_version = re.compile(r'^(?P
Version:\s*)(?P.+)(?P\s*)$', re.MULTILINE + re.IGNORECASE)
     re_update_release = re.compile(r'^(?P
Release:\s*)(?P%mkrel \d+)(?P\s*)$', re.MULTILINE + re.IGNORECASE)
     re_update_patch = re.compile(r'^(?P
Patch)(?P[0-9]*)(?P:\s*)(?P.+)(?P\s*)\n', re.MULTILINE + re.IGNORECASE)
+    re_update_br = re.compile(r'^(?P
BuildRequires:\s*)(?P
.+?)(?P\s*\n)', re.MULTILINE + re.IGNORECASE) + re_update_br_unsplit = re.compile(r'^(?P
BuildRequires:\s*)(?P[^\n,]+,[^\n]+)(?P\s*\n)', re.MULTILINE + re.IGNORECASE)
 
     def __init__(self, path, module=None):
         self.path = path
@@ -365,6 +372,28 @@ class SpecFile(object):
     def sources(self):
         return self._sources_and_patches(flag=1)
 
+    @property
+    def buildrequires(self):
+        ts = rpm.ts()
+        spec = ts.parseSpec(self.path)
+
+        requires = spec.sourceHeader[rpm.RPMTAG_REQUIRES]
+        require_flags = spec.sourceHeader[rpm.RPMTAG_REQUIREFLAGS]
+        require_ver = spec.sourceHeader[rpm.RPMTAG_REQUIREVERSION]
+
+        br = {}
+        for req, flag, ver in itertools.izip_longest(requires, require_flags, require_ver):
+            # bitmask other than 15 means the require is (probably?) a require for a trigger or script
+            if flag & 15 <> flag: continue
+
+            ver_cmp = ""
+            if (flag & rpm.RPMSENSE_LESS): ver_cmp += '<'
+            if (flag & rpm.RPMSENSE_GREATER): ver_cmp += '>'
+            if (flag & rpm.RPMSENSE_EQUAL): ver_cmp += '='
+
+            br[req] = (ver_cmp, ver)
+        return br
+
     @property
     def uses_apply_patches(self):
         return subprocess.call(['grep', '-q', '^%apply_patches', '--', self.path]) == 0
@@ -476,6 +505,34 @@ class SpecFile(object):
 
             return True
 
+    def update_br(self, changes, force=False):
+        """Update buildrequirement"""
+
+        # XXX - doesn't handle buildrequires with version numbers :-(
+
+        with open(self.path, "rw") as f:
+            data = f.read()
+            data_before=data
+
+            # Change any "," in buildrequires into multiple lines
+            data, nr = self.re_update_br_unsplit.subn(lambda mo: ''.join((''.join((mo.group('pre'), part, mo.group('post'))) for part in re.split(r',\s*', mo.group('unsplit')))), data)
+
+            # Now update buildrequires if any
+            data, nr = self.re_update_br.subn(lambda mo: ''.join((mo.group('pre'), changes[mo.group('br')], mo.group('post'))) if mo.group('br') in changes else mo.group(0), data)
+
+            # XXX - very hacky because of multiple changes, could miss out on a change
+            if data_before == data:
+                print >>sys.stderr, "ERROR: Could not update buildrequires!"
+                return False
+
+            # Overwrite file with new version number
+            import difflib
+            sys.stdout.writelines(difflib.unified_diff(data_before.splitlines(True), data.splitlines(True)))
+            #write_file(self.path, data)
+
+        self._changes.append('SILENT Updated buildrequirements')
+
+
     MAX_JUDGEMENT=5
 
     def update(self, version, force=False, max_judgement=MAX_JUDGEMENT):
@@ -1043,6 +1100,29 @@ def cmd_check_prep(options, parser):
     s = SpecFile(os.path.join(cwd, "SPECS", "%s.spec" % options.package), module=options.package)
     s.check_and_update_patches()
 
+def cmd_clean_spec(options, parser):
+    # Directories packages are located in
+    root = os.path.expanduser(Downstream.PKGROOT)
+    cwd = os.path.join(root, options.package)
+
+    s = SpecFile(os.path.join(cwd, "SPECS", "%s.spec" % options.package), module=options.package)
+
+    # Convert -devel requires into pkgconfig requires
+    br = s.buildrequires
+    br_old = [r for r in br.keys() if r.endswith('-devel')]
+    changes = {}
+    for req in br_old:
+         #urpmq --whatprovides 'pkgconfig(polkit-agent-1)' --provides
+        provides = subprocess.check_output(["urpmq", "--whatprovides", req, "--provides"]).splitlines()
+        provides_alt = [clean_pkgconfig_prov(prov) for prov in provides if prov.startswith('pkgconfig(')]
+        print req, "=>", provides_alt
+        if len(provides_alt) == 1:
+            changes[req] = provides_alt[0]
+
+    if changes:
+        s.update_br(changes)
+
+
 def cmd_package_new_version(options, parser):
     # Determine the package name
     if options.upstream:
@@ -1174,10 +1254,12 @@ def cmd_parse_ftp_release_list(options, parser):
         if options.mail: _send_reply_mail(stdout, msg, options.mail, error=True)
         sys.exit(1)
 
-    if options.wait:
+    if options.wait or options.fork:
         # maildrop aborts and will try to deliver after 5min
         # fork to avoid this
         if os.fork() != 0: sys.exit(0)
+
+    if options.wait:
         # wait SLEEP_INITIAL after the message was sent
         secs = SLEEP_INITIAL
         t = email.utils.parsedate_tz(msg['Date'])
@@ -1225,6 +1307,12 @@ def main():
         func=cmd_check_prep
     )
 
+    subparser = subparsers.add_parser('clean-spec', help='clean specfile')
+    subparser.add_argument("package", help="Package name")
+    subparser.set_defaults(
+        func=cmd_clean_spec
+    )
+
     subparser = subparsers.add_parser('check-version', help='check if spec version and downstream version match')
     subparser.set_defaults(
         func=cmd_check_version
@@ -1243,6 +1331,8 @@ def main():
 
     subparser = subparsers.add_parser('gnome-release-email', help='submit packages based on GNOME ftp-release-list email')
     subparser.add_argument("-m", "--mail", help="Email address to send the progress to")
+    subparser.add_argument(      "--fork", action="store_true",
+                                 help="Fork as quickly as possible")
     subparser.add_argument("-w", "--wait", action="store_true",
                                  help="Wait before trying to retrieve the new version")
     subparser.add_argument("-s", "--submit", action="store_true", dest="submit",
@@ -1250,7 +1340,7 @@ def main():
     subparser.add_argument("-f", "--force", action="store_true",
                                  help="Force submission")
     subparser.set_defaults(
-        func=cmd_parse_ftp_release_list, force=False, wait=False
+        func=cmd_parse_ftp_release_list, force=False, wait=False, fork=False
     )
 
     subparser = subparsers.add_parser('group-owner', help='list packages by group')
-- 
cgit v1.2.1