summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOlav Vitters <olav@vitters.nl>2014-07-10 02:57:47 +0200
committerOlav Vitters <olav@vitters.nl>2014-07-10 02:57:47 +0200
commit15a5fa8bb2d0b5697a06dc8e80f353f26b654cd6 (patch)
treeb02beed919fbc1d2cfb7e423526f623972a85ef6
parente9e9f7323a65a704ebb62b849c8716876b0b98a8 (diff)
downloadmgagnome-15a5fa8bb2d0b5697a06dc8e80f353f26b654cd6.tar
mgagnome-15a5fa8bb2d0b5697a06dc8e80f353f26b654cd6.tar.gz
mgagnome-15a5fa8bb2d0b5697a06dc8e80f353f26b654cd6.tar.bz2
mgagnome-15a5fa8bb2d0b5697a06dc8e80f353f26b654cd6.tar.xz
mgagnome-15a5fa8bb2d0b5697a06dc8e80f353f26b654cd6.zip
add ability to convert patches into %autopatch
-rwxr-xr-xmgagnome90
1 files changed, 79 insertions, 11 deletions
diff --git a/mgagnome b/mgagnome
index 1b8ebd9..032715f 100755
--- a/mgagnome
+++ b/mgagnome
@@ -362,9 +362,12 @@ class SpecFile(object):
@property
def version(self):
- return subprocess.check_output(["rpm", "--specfile", self.path, "--queryformat", "%{VERSION}\n"]).splitlines()[0]
+ return subprocess.check_output(["rpm", "--define", "_topdir %s" % os.path.join(self.cwd, ".."), "--specfile", self.path, "--queryformat", "%{VERSION}\n"]).splitlines()[0]
def _sources_and_patches(self, flag=None):
+ os.chdir(self.cwd)
+ rpm.delMacro("_topdir" )
+ rpm.addMacro("_topdir", os.path.join(self.cwd, '..'))
ts = rpm.ts()
spec = ts.parseSpec(self.path)
srclist = spec.sources if isinstance(spec.sources, (list, tuple)) \
@@ -452,11 +455,7 @@ class SpecFile(object):
data = data.lstrip()
self._changes.append('SILENT remove variable definition(s) %s' % ", ".join(converted_defines))
- # Make use of %apply_patches
- patches = self.patches
- if patches and not self.uses_apply_patches:
- print "WARNING: Patches, no %%apply_patches for %s" % self.module
- print self.module, patches
+ made_changes, data = self._clean_spec_patches(f, made_changes, data)
# Overwrite file with new version number
if made_changes:
@@ -464,8 +463,78 @@ class SpecFile(object):
return made_changes
+ def _clean_spec_patches(self, f, made_changes, data):
+ re_patch_header = re.compile('^\Patch(?P<nr>[0-9]*):[ \t]*(?P<filename>[^\n]+)\n', re.MULTILINE + re.IGNORECASE)
+ re_patch_any = re.compile(r'^[ \t]*\%patch(?P<nr>[0-9]*)', re.MULTILINE)
+ re_patch_valid = re.compile(r'^[ \t+]*\%patch(?P<nr>[0-9]*)(?:[ \t]+-p(?P<strip>[0-9]+))?(?:[ \t]+-b[ \t]+\S+)$\n?', re.MULTILINE)
+ re_prep_patches = re.compile(r'^\%setup[^\n]+$(?:' + re_patch_valid.pattern + r'|^#[^%\n]+\n|\s)+\n\%build', re.MULTILINE)
+
+ give_patchnr = lambda mo: (mo.group('nr') if len(mo.group('nr')) == 1 else mo.group('nr').lstrip('0')) if mo.group('nr') else "0"
+
+ # Make use of %apply_patches
+ patches = self.patches
+ if not patches:
+ return made_changes, data
+
+ if self.uses_apply_patches:
+ return made_changes, data
+
+# print "WARNING: Patches, no %%apply_patches for %s" % self.module
+# print self.module, patches
+# print re_patch_header.findall(data)
+# print re_patch_valid.findall(data)
+
+ mo2 = re_prep_patches.search(data)
+ patch_nrs_header = set([give_patchnr(mo) for mo in re_patch_header.finditer(data)])
+ patch_nrs_any = set([give_patchnr(mo) for mo in re_patch_any.finditer(data)])
+ patch_nrs_valid = set([give_patchnr(mo) for mo in re_patch_valid.finditer(mo2.group(0))]) if mo2 else set()
+
+ if not patch_nrs_header:
+ # XXX -- werird, self.patches should've returned 0 already
+ return made_changes, data
+
+ if not (patch_nrs_header == patch_nrs_any == patch_nrs_valid):
+ print >>sys.stderr, "NOTICE: Unable to automatically convert patches into %autopatch"
+ return made_changes, data
+
+ patch_flags = set([mo.group('strip') for mo in re_patch_valid.finditer(mo2.group(0))])
+
+ if len(patch_flags) != 1:
+ print >>sys.stderr, "NOTICE: Unable to automatically convert patches into as different -p / strip levels used"
+ return made_changes, data
+
+ # Whoot, we can convert!!
+ change_to = "%%autopatch -p%s\n" % list(patch_flags)[0]
+ prep, n1 = re_patch_valid.subn(change_to.replace('\\', '\\\\'), mo2.group(0), count=1)
+ prep, n2 = re_patch_valid.subn('', prep)
+ if len(patch_nrs_valid) <> n1 + n2:
+ print >>sys.stderr, "WARNING: Couldn't replace patches?!? Likely error in program logic"
+ return made_changes, data
+
+ # First check if patches currently apply
+ if not self.check_and_update_patches(check_only=True):
+ return made_changes, data
+
+ try:
+ change_to = data.replace(mo2.group(0), prep, 1)
+ write_file(self.path, change_to)
+
+ # Validate patches still apply
+ if self.check_and_update_patches(check_only=True):
+ pass
+ data = change_to
+ self._changes.append('SILENT use autopatch')
+ made_changes = True
+ finally:
+ if not made_changes:
+ write_file(self.path, data)
+
+ return made_changes, data
+
@property
def buildrequires(self):
+ rpm.delMacro("_topdir" )
+ rpm.addMacro("_topdir", os.path.join(self.cwd, '..'))
ts = rpm.ts()
spec = ts.parseSpec(self.path)
@@ -518,7 +587,7 @@ class SpecFile(object):
subprocess.check_call(['mgarepo', 'sync'], cwd=self.cwd)
return True
- def check_and_update_patches(self):
+ def check_and_update_patches(self, check_only=False):
"""Check if patches still apply
Remove any merged patches"""
@@ -534,13 +603,14 @@ class SpecFile(object):
# 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])
+ logfile = os.path.join(self.cwd, '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):
+ print logfile
with open(logfile, "r") as f:
for line in line_input(f):
if line.startswith('+ '):
@@ -551,7 +621,7 @@ class SpecFile(object):
cmd_parsed = shlex.split(cmd) if cmd else []
- if uses_apply_patches and patches and cmd_parsed:
+ if not check_only and 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])
@@ -604,8 +674,6 @@ class SpecFile(object):
# XXX - doesn't handle buildrequires with version numbers :-(
made_changes = False
- re_patch = re.compile(r'^\%patch(?P<nr>[0-9]*)(?:[ \t]+-p(P<strip>[0-9]+))?(?:[ \t]+-b[ \t]+\S+)?\n', re.MULTILINE)
-
with open(self.path, "rw") as f:
data = f.read()
data_before=data