diff options
author | Olav Vitters <olav@vitters.nl> | 2013-09-17 21:08:19 +0200 |
---|---|---|
committer | Olav Vitters <olav@vitters.nl> | 2013-09-17 21:08:19 +0200 |
commit | 8306ced1a8df6fb53c356d639b52ecc59bc0bfe6 (patch) | |
tree | 0def80ac23b0f02bc73ce182d07236b49643537b | |
parent | 802d02e02abbc1299d8eef07b9c0dd9a7cb3272b (diff) | |
download | mgagnome-8306ced1a8df6fb53c356d639b52ecc59bc0bfe6.tar mgagnome-8306ced1a8df6fb53c356d639b52ecc59bc0bfe6.tar.gz mgagnome-8306ced1a8df6fb53c356d639b52ecc59bc0bfe6.tar.bz2 mgagnome-8306ced1a8df6fb53c356d639b52ecc59bc0bfe6.tar.xz mgagnome-8306ced1a8df6fb53c356d639b52ecc59bc0bfe6.zip |
automatically drop a merged patch
-rwxr-xr-x | mgagnome | 146 |
1 files changed, 95 insertions, 51 deletions
@@ -288,6 +288,7 @@ def is_valid_hash(path, algo, hexdigest): class SpecFile(object): re_update_version = re.compile(r'^(?P<pre>Version:\s*)(?P<version>.+)(?P<post>\s*)$', re.MULTILINE + re.IGNORECASE) re_update_release = re.compile(r'^(?P<pre>Release:\s*)(?P<release>%mkrel \d+)(?P<post>\s*)$', re.MULTILINE + re.IGNORECASE) + re_update_patch = re.compile(r'^(?P<pre>Patch)(?P<nr>[0-9]*)(?P<pre2>:\s*)(?P<patch>.+)(?P<post>\s*)\n', re.MULTILINE + re.IGNORECASE) def __init__(self, path, module=None): self.path = path @@ -298,24 +299,49 @@ class SpecFile(object): @property def version(self): return subprocess.check_output(["rpm", "--specfile", self.path, "--queryformat", "%{VERSION}\n"]).splitlines()[0] + def _sources_and_patches(self, flag=None): ts = rpm.ts() spec = ts.parseSpec(self.path) srclist = spec.sources if isinstance(spec.sources, (list, tuple)) \ else spec.sources() - return dict((os.path.basename(name), [name, no]) for name, no, flags in srclist if flag is None or flags == flag) + return dict((os.path.basename(name), [name, 0 if no == 2147483647 and flags == 2 else no]) for name, no, flags in srclist if flag is None or flags == flag) @property def patches(self): return self._sources_and_patches(flag=2) @property + def sources(self): + return self._sources_and_patches(flag=1) + + @property def uses_apply_patches(self): return subprocess.call(['grep', '-q', '^%apply_patches', '--', self.path]) == 0 - @property - def sources(self): - return self._sources_and_patches(flag=1) + def _revert_changes(self): + """Revert uncommited changes made to spec file""" + self.changes = [] + subprocess.check_call(["svn", "revert", "-R", os.path.join(self.path, '..')]) + + def remove_patch(self, nr): + print >>sys.stderr, "DEBUG: removing patch %s" % nr + nrs = [str(nr)] + if nr == 0: nrs.append('') + with open(self.path, "rw") as f: + data = f.read() + + data, nr = self.re_update_patch.subn(lambda mo: '' if mo.group('nr') in nrs else mo.group(0), data, 1) + if nr != 1: + print >>sys.stderr, "ERROR: Could not remove patch nr %s!" % nr + return False + + # Overwrite file with new version number + write_file(self.path, data) + + self.changes.append('dropped merged patch %s' % nr) + + return True def check_and_update_patches(self): """Check if patches still apply @@ -328,51 +354,69 @@ class SpecFile(object): patches = initial_patches uses_apply_patches = self.uses_apply_patches if patches else False - try: - # Check patches still apply - subprocess.check_call(['bm', '-p', '--nodeps'], cwd=self.cwd) - except subprocess.CalledProcessError: - logfile = os.path.join(os.path.dirname(self.path), 'log.%s' % os.path.splitext(os.path.basename(self.path))[0]) - - failed_patch = None - cmd = None - cmd_output = [] - # Determine the last command that failed - if os.path.exists(logfile): - with open(logfile, "r") as f: - for line in line_input(f): - if line.startswith('+ '): - cmd = line[2:] - cmd_output = [] - else: - cmd_output.append(line) - - cmd_parsed = shlex.split(cmd) if cmd else [] - - if uses_apply_patches and patches and cmd_parsed: - if os.path.basename(cmd_parsed[0]) == 'patch' and os.path.exists(cmd_parsed[-1]): - failed_patch = os.path.basename(cmd_parsed[-1]) - - # XXX -- check if patch has been merged - # XXX -- if patch was merged, drop it from spec file and rety - - if cmd and len(cmd_output) > LOGLINES: - print >>sys.stdout, '+ %s' % cmd - print >>sys.stdout, "\n".join(cmd_output) - elif os.path.exists(logfile): - subprocess.call(['tail', '-n', str(LOGLINES), logfile]) - - if failed_patch: - print >>sys.stderr, "ERROR: Problem applying patch: %s" % failed_patch - elif cmd: - print >>sys.stderr, "ERROR: Problem in %%setup phase command: %s" % cmd - elif patches: - print >>sys.stderr, "ERROR: Problem applying patches and/or %setup phase" - else: - print >>sys.stderr, "ERROR: Problem in %setup phase" - return False + while True: + try: + # Check patches still apply + subprocess.check_call(['bm', '-p', '--nodeps'], cwd=self.cwd) + except subprocess.CalledProcessError: + logfile = os.path.join(os.path.dirname(self.path), 'log.%s' % os.path.splitext(os.path.basename(self.path))[0]) + + failed_patch = None + cmd = None + cmd_output = [] + # Determine the last command that failed + if os.path.exists(logfile): + with open(logfile, "r") as f: + for line in line_input(f): + if line.startswith('+ '): + cmd = line[2:] + cmd_output = [] + else: + cmd_output.append(line) + + cmd_parsed = shlex.split(cmd) if cmd else [] + + if uses_apply_patches and patches and cmd_parsed: + if os.path.basename(cmd_parsed[0]) == 'patch' and os.path.exists(cmd_parsed[-1]): + failed_patch = os.path.basename(cmd_parsed[-1]) + + # Patch is merged if there is at least one 'ignored' line and no 'FAILED' line anywhere + has_ignored = False + has_failed = False + for line in cmd_output: + if 'FAILED' in line: + has_failed = True + break + elif 'ignored' in line: + has_ignored = True + + if has_ignored and not has_failed: + # If patch was merged, drop it from spec file and rety + print >>sys.stdout, "INFO: Patch has been merged: %s" % failed_patch + if failed_patch in patches: + if self.remove_patch(patches[failed_patch][1]): + # try again + patches = self.patches + continue + sys.exit(1) + + if cmd and len(cmd_output) > LOGLINES: + print >>sys.stdout, '+ %s' % cmd + print >>sys.stdout, "\n".join(cmd_output) + elif os.path.exists(logfile): + subprocess.call(['tail', '-n', str(LOGLINES), logfile]) + + if failed_patch: + print >>sys.stderr, "ERROR: Problem applying patch: %s" % failed_patch + elif cmd: + print >>sys.stderr, "ERROR: Problem in %%setup phase command: %s" % cmd + elif patches: + print >>sys.stderr, "ERROR: Problem applying patches and/or %setup phase" + else: + print >>sys.stderr, "ERROR: Problem in %setup phase" + return False - return True + return True def update(self, version, force=False): """Update specfile (increase version)""" @@ -399,7 +443,7 @@ class SpecFile(object): # Forcing package submission: revert changes try: print >>sys.stderr, "WARNING: Force used; reverting svn changes" - subprocess.check_call(["svn", "revert", "-R", os.path.join(self.path, '..')]) + self._revert_changes() except subprocess.CalledProcessError: return False @@ -448,11 +492,11 @@ class SpecFile(object): except subprocess.CalledProcessError, e: # mgarepo sync returns 1 if the tarball cannot be downloaded if e.returncode != 1: - subprocess.check_call(["svn", "revert", "-R", os.path.join(self.path, '..')]) + self._revert_changes() return False else: # failed to download tarball - subprocess.check_call(["svn", "revert", "-R", os.path.join(self.path, '..')]) + self._revert_changes() return False |