summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOlav Vitters <olav@vitters.nl>2013-09-17 21:08:19 +0200
committerOlav Vitters <olav@vitters.nl>2013-09-17 21:08:19 +0200
commit8306ced1a8df6fb53c356d639b52ecc59bc0bfe6 (patch)
tree0def80ac23b0f02bc73ce182d07236b49643537b
parent802d02e02abbc1299d8eef07b9c0dd9a7cb3272b (diff)
downloadmgagnome-8306ced1a8df6fb53c356d639b52ecc59bc0bfe6.tar
mgagnome-8306ced1a8df6fb53c356d639b52ecc59bc0bfe6.tar.gz
mgagnome-8306ced1a8df6fb53c356d639b52ecc59bc0bfe6.tar.bz2
mgagnome-8306ced1a8df6fb53c356d639b52ecc59bc0bfe6.tar.xz
mgagnome-8306ced1a8df6fb53c356d639b52ecc59bc0bfe6.zip
automatically drop a merged patch
-rwxr-xr-xmgagnome146
1 files changed, 95 insertions, 51 deletions
diff --git a/mgagnome b/mgagnome
index 18c9ee1..d2797cb 100755
--- a/mgagnome
+++ b/mgagnome
@@ -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