summaryrefslogtreecommitdiffstats
path: root/meta/lib
diff options
context:
space:
mode:
authorPaul Eggleton <paul.eggleton@linux.intel.com>2015-10-11 15:41:20 +0100
committerRichard Purdie <richard.purdie@linuxfoundation.org>2015-12-01 21:32:03 +0000
commita360fa7d519320faf53065ba9584a426fd275c1a (patch)
treeb0c2809259ff8b05d220ed8ea3d6dfad760bf64f /meta/lib
parentf79cc4d9c37cc8b08b51491f335119b8caf84671 (diff)
downloadpoky-a360fa7d519320faf53065ba9584a426fd275c1a.tar.gz
lib/oe/patch: improve extraction of patch header
For patches that we have to extract the header information by hand (i.e. will not apply with "git am"), make the following improvements: * If we can't extract author/date/subject, then try to do so from the commit that added the patch in git (assuming the metadata is tracked by git) * Take only first Signed-off-by line instead of last * Accept any case for "Signed-off-by" in case author has typed it by hand * Improve conditional - we can skip the other cases if one matches Implements [YOCTO #7624]. (From OE-Core rev: 13ec296b5c35aefa2c44f64f8bd1ef54c4a0a731) Signed-off-by: Paul Eggleton <paul.eggleton@linux.intel.com> Signed-off-by: Ross Burton <ross.burton@intel.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Diffstat (limited to 'meta/lib')
-rw-r--r--meta/lib/oe/patch.py58
1 files changed, 43 insertions, 15 deletions
diff --git a/meta/lib/oe/patch.py b/meta/lib/oe/patch.py
index 2bf501e9e6..2255ce437b 100644
--- a/meta/lib/oe/patch.py
+++ b/meta/lib/oe/patch.py
@@ -282,33 +282,32 @@ class GitApplyTree(PatchTree):
282 return lines 282 return lines
283 283
284 @staticmethod 284 @staticmethod
285 def prepareCommit(patchfile): 285 def decodeAuthor(line):
286 """ 286 from email.header import decode_header
287 Prepare a git commit command line based on the header from a patch file 287 authorval = line.split(':', 1)[1].strip().replace('"', '')
288 (typically this is useful for patches that cannot be applied with "git am" due to formatting) 288 return decode_header(authorval)[0][0]
289 """ 289
290 import tempfile 290 @staticmethod
291 def interpretPatchHeader(headerlines):
291 import re 292 import re
292 author_re = re.compile('[\S ]+ <\S+@\S+\.\S+>') 293 author_re = re.compile('[\S ]+ <\S+@\S+\.\S+>')
293 # Process patch header and extract useful information
294 lines = GitApplyTree.extractPatchHeader(patchfile)
295 outlines = [] 294 outlines = []
296 author = None 295 author = None
297 date = None 296 date = None
298 for line in lines: 297 subject = None
298 for line in headerlines:
299 if line.startswith('Subject: '): 299 if line.startswith('Subject: '):
300 subject = line.split(':', 1)[1] 300 subject = line.split(':', 1)[1]
301 # Remove any [PATCH][oe-core] etc. 301 # Remove any [PATCH][oe-core] etc.
302 subject = re.sub(r'\[.+?\]\s*', '', subject) 302 subject = re.sub(r'\[.+?\]\s*', '', subject)
303 outlines.insert(0, '%s\n\n' % subject.strip())
304 continue 303 continue
305 if line.startswith('From: ') or line.startswith('Author: '): 304 elif line.startswith('From: ') or line.startswith('Author: '):
306 authorval = line.split(':', 1)[1].strip().replace('"', '') 305 authorval = GitApplyTree.decodeAuthor(line)
307 # git is fussy about author formatting i.e. it must be Name <email@domain> 306 # git is fussy about author formatting i.e. it must be Name <email@domain>
308 if author_re.match(authorval): 307 if author_re.match(authorval):
309 author = authorval 308 author = authorval
310 continue 309 continue
311 if line.startswith('Date: '): 310 elif line.startswith('Date: '):
312 if date is None: 311 if date is None:
313 dateval = line.split(':', 1)[1].strip() 312 dateval = line.split(':', 1)[1].strip()
314 # Very crude check for date format, since git will blow up if it's not in the right 313 # Very crude check for date format, since git will blow up if it's not in the right
@@ -316,12 +315,41 @@ class GitApplyTree(PatchTree):
316 if len(dateval) > 12: 315 if len(dateval) > 12:
317 date = dateval 316 date = dateval
318 continue 317 continue
319 if line.startswith('Signed-off-by: '): 318 elif not author and line.lower().startswith('signed-off-by: '):
320 authorval = line.split(':', 1)[1].strip().replace('"', '') 319 authorval = GitApplyTree.decodeAuthor(line)
321 # git is fussy about author formatting i.e. it must be Name <email@domain> 320 # git is fussy about author formatting i.e. it must be Name <email@domain>
322 if author_re.match(authorval): 321 if author_re.match(authorval):
323 author = authorval 322 author = authorval
324 outlines.append(line) 323 outlines.append(line)
324 return outlines, author, date, subject
325
326 @staticmethod
327 def prepareCommit(patchfile):
328 """
329 Prepare a git commit command line based on the header from a patch file
330 (typically this is useful for patches that cannot be applied with "git am" due to formatting)
331 """
332 import tempfile
333 # Process patch header and extract useful information
334 lines = GitApplyTree.extractPatchHeader(patchfile)
335 outlines, author, date, subject = GitApplyTree.interpretPatchHeader(lines)
336 if not author or not subject:
337 try:
338 shellcmd = ["git", "log", "--format=email", "--diff-filter=A", "--", patchfile]
339 out = runcmd(["sh", "-c", " ".join(shellcmd)], os.path.dirname(patchfile))
340 except CmdError:
341 out = None
342 if out:
343 _, newauthor, newdate, newsubject = GitApplyTree.interpretPatchHeader(out.splitlines())
344 if not author or not date:
345 # These really need to go together
346 author = newauthor
347 date = newdate
348 if not subject:
349 subject = newsubject
350 if subject:
351 outlines.insert(0, '%s\n\n' % subject.strip())
352
325 # Write out commit message to a file 353 # Write out commit message to a file
326 with tempfile.NamedTemporaryFile('w', delete=False) as tf: 354 with tempfile.NamedTemporaryFile('w', delete=False) as tf:
327 tmpfile = tf.name 355 tmpfile = tf.name