diff options
Diffstat (limited to 'meta')
-rw-r--r-- | meta/lib/oe/buildhistory_analysis.py | 92 |
1 files changed, 76 insertions, 16 deletions
diff --git a/meta/lib/oe/buildhistory_analysis.py b/meta/lib/oe/buildhistory_analysis.py index 449446f33b..3a5b7b6b44 100644 --- a/meta/lib/oe/buildhistory_analysis.py +++ b/meta/lib/oe/buildhistory_analysis.py | |||
@@ -13,7 +13,10 @@ import os.path | |||
13 | import difflib | 13 | import difflib |
14 | import git | 14 | import git |
15 | import re | 15 | import re |
16 | import hashlib | ||
17 | import collections | ||
16 | import bb.utils | 18 | import bb.utils |
19 | import bb.tinfoil | ||
17 | 20 | ||
18 | 21 | ||
19 | # How to display fields | 22 | # How to display fields |
@@ -410,7 +413,7 @@ def compare_dict_blobs(path, ablob, bblob, report_all, report_ver): | |||
410 | return changes | 413 | return changes |
411 | 414 | ||
412 | 415 | ||
413 | def compare_siglists(a_blob, b_blob): | 416 | def compare_siglists(a_blob, b_blob, taskdiff=False): |
414 | # FIXME collapse down a recipe's tasks? | 417 | # FIXME collapse down a recipe's tasks? |
415 | alines = a_blob.data_stream.read().decode('utf-8').splitlines() | 418 | alines = a_blob.data_stream.read().decode('utf-8').splitlines() |
416 | blines = b_blob.data_stream.read().decode('utf-8').splitlines() | 419 | blines = b_blob.data_stream.read().decode('utf-8').splitlines() |
@@ -429,26 +432,83 @@ def compare_siglists(a_blob, b_blob): | |||
429 | adict = readsigs(alines) | 432 | adict = readsigs(alines) |
430 | bdict = readsigs(blines) | 433 | bdict = readsigs(blines) |
431 | out = [] | 434 | out = [] |
435 | |||
432 | changecount = 0 | 436 | changecount = 0 |
433 | addcount = 0 | 437 | addcount = 0 |
434 | removecount = 0 | 438 | removecount = 0 |
435 | for key in keys: | 439 | if taskdiff: |
436 | siga = adict.get(key, None) | 440 | with bb.tinfoil.Tinfoil() as tinfoil: |
437 | sigb = bdict.get(key, None) | 441 | tinfoil.prepare(config_only=True) |
438 | if siga is not None and sigb is not None and siga != sigb: | 442 | |
439 | out.append('%s changed from %s to %s' % (key, siga, sigb)) | 443 | changes = collections.OrderedDict() |
440 | changecount += 1 | 444 | |
441 | elif siga is None: | 445 | def compare_hashfiles(pn, taskname, hash1, hash2): |
442 | out.append('%s was added' % key) | 446 | hashes = [hash1, hash2] |
443 | addcount += 1 | 447 | hashfiles = bb.siggen.find_siginfo(pn, taskname, hashes, tinfoil.config_data) |
444 | elif sigb is None: | 448 | |
445 | removecount += 1 | 449 | if not taskname: |
446 | out.append('%s was removed' % key) | 450 | (pn, taskname) = pn.rsplit('.', 1) |
451 | pn = pnmap.get(pn, pn) | ||
452 | desc = '%s.%s' % (pn, taskname) | ||
453 | |||
454 | if len(hashfiles) == 0: | ||
455 | out.append("Unable to find matching sigdata for %s with hashes %s or %s" % (desc, hash1, hash2)) | ||
456 | elif not hash1 in hashfiles: | ||
457 | out.append("Unable to find matching sigdata for %s with hash %s" % (desc, hash1)) | ||
458 | elif not hash2 in hashfiles: | ||
459 | out.append("Unable to find matching sigdata for %s with hash %s" % (desc, hash2)) | ||
460 | else: | ||
461 | out2 = bb.siggen.compare_sigfiles(hashfiles[hash1], hashfiles[hash2], recursecb, collapsed=True) | ||
462 | for line in out2: | ||
463 | m = hashlib.sha256() | ||
464 | m.update(line.encode('utf-8')) | ||
465 | entry = changes.get(m.hexdigest(), (line, [])) | ||
466 | if desc not in entry[1]: | ||
467 | changes[m.hexdigest()] = (line, entry[1] + [desc]) | ||
468 | |||
469 | # Define recursion callback | ||
470 | def recursecb(key, hash1, hash2): | ||
471 | compare_hashfiles(key, None, hash1, hash2) | ||
472 | return [] | ||
473 | |||
474 | for key in keys: | ||
475 | siga = adict.get(key, None) | ||
476 | sigb = bdict.get(key, None) | ||
477 | if siga is not None and sigb is not None and siga != sigb: | ||
478 | changecount += 1 | ||
479 | (pn, taskname) = key.rsplit('.', 1) | ||
480 | compare_hashfiles(pn, taskname, siga, sigb) | ||
481 | elif siga is None: | ||
482 | addcount += 1 | ||
483 | elif sigb is None: | ||
484 | removecount += 1 | ||
485 | for key, item in changes.items(): | ||
486 | line, tasks = item | ||
487 | if len(tasks) == 1: | ||
488 | desc = tasks[0] | ||
489 | elif len(tasks) == 2: | ||
490 | desc = '%s and %s' % (tasks[0], tasks[1]) | ||
491 | else: | ||
492 | desc = '%s and %d others' % (tasks[-1], len(tasks)-1) | ||
493 | out.append('%s: %s' % (desc, line)) | ||
494 | else: | ||
495 | for key in keys: | ||
496 | siga = adict.get(key, None) | ||
497 | sigb = bdict.get(key, None) | ||
498 | if siga is not None and sigb is not None and siga != sigb: | ||
499 | out.append('%s changed from %s to %s' % (key, siga, sigb)) | ||
500 | changecount += 1 | ||
501 | elif siga is None: | ||
502 | out.append('%s was added' % key) | ||
503 | addcount += 1 | ||
504 | elif sigb is None: | ||
505 | out.append('%s was removed' % key) | ||
506 | removecount += 1 | ||
447 | out.append('Summary: %d tasks added, %d tasks removed, %d tasks modified (%.1f%%)' % (addcount, removecount, changecount, (changecount / float(len(bdict)) * 100))) | 507 | out.append('Summary: %d tasks added, %d tasks removed, %d tasks modified (%.1f%%)' % (addcount, removecount, changecount, (changecount / float(len(bdict)) * 100))) |
448 | return '\n'.join(out) | 508 | return '\n'.join(out) |
449 | 509 | ||
450 | 510 | ||
451 | def process_changes(repopath, revision1, revision2='HEAD', report_all=False, report_ver=False, sigs=False): | 511 | def process_changes(repopath, revision1, revision2='HEAD', report_all=False, report_ver=False, sigs=False, sigsdiff=False): |
452 | repo = git.Repo(repopath) | 512 | repo = git.Repo(repopath) |
453 | assert repo.bare == False | 513 | assert repo.bare == False |
454 | commit = repo.commit(revision1) | 514 | commit = repo.commit(revision1) |
@@ -456,10 +516,10 @@ def process_changes(repopath, revision1, revision2='HEAD', report_all=False, rep | |||
456 | 516 | ||
457 | changes = [] | 517 | changes = [] |
458 | 518 | ||
459 | if sigs: | 519 | if sigs or sigsdiff: |
460 | for d in diff.iter_change_type('M'): | 520 | for d in diff.iter_change_type('M'): |
461 | if d.a_blob.path == 'siglist.txt': | 521 | if d.a_blob.path == 'siglist.txt': |
462 | changes.append(compare_siglists(d.a_blob, d.b_blob)) | 522 | changes.append(compare_siglists(d.a_blob, d.b_blob, taskdiff=sigsdiff)) |
463 | return changes | 523 | return changes |
464 | 524 | ||
465 | for d in diff.iter_change_type('M'): | 525 | for d in diff.iter_change_type('M'): |