diff options
-rw-r--r-- | scripts/lib/devtool/standard.py | 119 |
1 files changed, 72 insertions, 47 deletions
diff --git a/scripts/lib/devtool/standard.py b/scripts/lib/devtool/standard.py index 01d7b8cf81..b8435ae701 100644 --- a/scripts/lib/devtool/standard.py +++ b/scripts/lib/devtool/standard.py | |||
@@ -25,6 +25,7 @@ import logging | |||
25 | import argparse | 25 | import argparse |
26 | import scriptutils | 26 | import scriptutils |
27 | import errno | 27 | import errno |
28 | from collections import OrderedDict | ||
28 | from devtool import exec_build_env_command, setup_tinfoil, check_workspace_recipe, use_external_build, setup_git_repo, DevtoolError | 29 | from devtool import exec_build_env_command, setup_tinfoil, check_workspace_recipe, use_external_build, setup_git_repo, DevtoolError |
29 | from devtool import parse_recipe | 30 | from devtool import parse_recipe |
30 | 31 | ||
@@ -590,11 +591,55 @@ def _remove_patch_files(args, patches, destpath): | |||
590 | if ose.errno != errno.ENOTEMPTY: | 591 | if ose.errno != errno.ENOTEMPTY: |
591 | raise | 592 | raise |
592 | 593 | ||
594 | |||
595 | def _export_patches(srctree, rd, start_rev, destdir): | ||
596 | """Export patches from srctree to given location. | ||
597 | Returns three-tuple of dicts: | ||
598 | 1. updated - patches that already exist in SRCURI | ||
599 | 2. added - new patches that don't exist in SRCURI | ||
600 | 3 removed - patches that exist in SRCURI but not in exported patches | ||
601 | In each dict the key is the 'basepath' of the URI and value is the | ||
602 | absolute path to the existing file in recipe space (if any). | ||
603 | """ | ||
604 | import oe.recipeutils | ||
605 | from oe.patch import GitApplyTree | ||
606 | updated = OrderedDict() | ||
607 | added = OrderedDict() | ||
608 | seqpatch_re = re.compile('^([0-9]{4}-)?(.+)') | ||
609 | |||
610 | existing_patches = dict((os.path.basename(path), path) for path in | ||
611 | oe.recipeutils.get_recipe_patches(rd)) | ||
612 | |||
613 | # Generate patches from Git | ||
614 | GitApplyTree.extractPatches(srctree, start_rev, destdir) | ||
615 | |||
616 | new_patches = sorted(os.listdir(destdir)) | ||
617 | for new_patch in new_patches: | ||
618 | # Strip numbering from patch names. If it's a git sequence named patch, | ||
619 | # the numbers might not match up since we are starting from a different | ||
620 | # revision This does assume that people are using unique shortlog | ||
621 | # values, but they ought to be anyway... | ||
622 | new_basename = seqpatch_re.match(new_patch).group(2) | ||
623 | found = False | ||
624 | for old_patch in existing_patches: | ||
625 | old_basename = seqpatch_re.match(old_patch).group(2) | ||
626 | if new_basename == old_basename: | ||
627 | updated[new_patch] = existing_patches.pop(old_patch) | ||
628 | found = True | ||
629 | # Rename patch files | ||
630 | if new_patch != old_patch: | ||
631 | os.rename(os.path.join(destdir, new_patch), | ||
632 | os.path.join(destdir, old_patch)) | ||
633 | break | ||
634 | if not found: | ||
635 | added[new_patch] = None | ||
636 | return (updated, added, existing_patches) | ||
637 | |||
638 | |||
593 | def _update_recipe_srcrev(args, srctree, rd, config_data): | 639 | def _update_recipe_srcrev(args, srctree, rd, config_data): |
594 | """Implement the 'srcrev' mode of update-recipe""" | 640 | """Implement the 'srcrev' mode of update-recipe""" |
595 | import bb | 641 | import bb |
596 | import oe.recipeutils | 642 | import oe.recipeutils |
597 | from oe.patch import GitApplyTree | ||
598 | 643 | ||
599 | recipefile = rd.getVar('FILE', True) | 644 | recipefile = rd.getVar('FILE', True) |
600 | logger.info('Updating SRCREV in recipe %s' % os.path.basename(recipefile)) | 645 | logger.info('Updating SRCREV in recipe %s' % os.path.basename(recipefile)) |
@@ -621,12 +666,10 @@ def _update_recipe_srcrev(args, srctree, rd, config_data): | |||
621 | old_srcrev = (rd.getVar('SRCREV', False) or '') | 666 | old_srcrev = (rd.getVar('SRCREV', False) or '') |
622 | tempdir = tempfile.mkdtemp(prefix='devtool') | 667 | tempdir = tempfile.mkdtemp(prefix='devtool') |
623 | try: | 668 | try: |
624 | GitApplyTree.extractPatches(srctree, old_srcrev, tempdir) | 669 | upd_p, new_p, del_p = _export_patches(srctree, rd, old_srcrev, |
625 | newpatches = os.listdir(tempdir) | 670 | tempdir) |
626 | for patch in existing_patches: | 671 | # Remove "overlapping" patches |
627 | patchfile = os.path.basename(patch) | 672 | removepatches = upd_p.values() |
628 | if patchfile in newpatches: | ||
629 | removepatches.append(patch) | ||
630 | finally: | 673 | finally: |
631 | shutil.rmtree(tempdir) | 674 | shutil.rmtree(tempdir) |
632 | 675 | ||
@@ -654,7 +697,6 @@ def _update_recipe_patch(args, config, srctree, rd, config_data): | |||
654 | """Implement the 'patch' mode of update-recipe""" | 697 | """Implement the 'patch' mode of update-recipe""" |
655 | import bb | 698 | import bb |
656 | import oe.recipeutils | 699 | import oe.recipeutils |
657 | from oe.patch import GitApplyTree | ||
658 | 700 | ||
659 | recipefile = rd.getVar('FILE', True) | 701 | recipefile = rd.getVar('FILE', True) |
660 | append = os.path.join(config.workspace_path, 'appends', '%s.bbappend' % | 702 | append = os.path.join(config.workspace_path, 'appends', '%s.bbappend' % |
@@ -677,40 +719,27 @@ def _update_recipe_patch(args, config, srctree, rd, config_data): | |||
677 | # Get all patches from source tree and check if any should be removed | 719 | # Get all patches from source tree and check if any should be removed |
678 | tempdir = tempfile.mkdtemp(prefix='devtool') | 720 | tempdir = tempfile.mkdtemp(prefix='devtool') |
679 | try: | 721 | try: |
680 | GitApplyTree.extractPatches(srctree, initial_rev, tempdir) | 722 | # Get all patches from source tree and check if any should be removed |
681 | # Strip numbering from patch names. If it's a git sequence named | 723 | upd_p, new_p, del_p = _export_patches(srctree, rd, initial_rev, |
682 | # patch, the numbers might not match up since we are starting from | 724 | tempdir) |
683 | # a different revision This does assume that people are using | 725 | # Remove deleted patches |
684 | # unique shortlog values, but they ought to be anyway... | 726 | removepatches = del_p.values() |
685 | newpatches = [seqpatch_re.match(fname).group(2) for fname in | ||
686 | os.listdir(tempdir)] | ||
687 | for patch in existing_patches: | ||
688 | basename = seqpatch_re.match( | ||
689 | os.path.basename(patch)).group(2) | ||
690 | if basename not in newpatches: | ||
691 | removepatches.append(patch) | ||
692 | finally: | 727 | finally: |
693 | shutil.rmtree(tempdir) | 728 | shutil.rmtree(tempdir) |
694 | 729 | ||
695 | # Get updated patches from source tree | 730 | # Get updated patches from source tree |
696 | tempdir = tempfile.mkdtemp(prefix='devtool') | 731 | tempdir = tempfile.mkdtemp(prefix='devtool') |
697 | try: | 732 | try: |
698 | GitApplyTree.extractPatches(srctree, update_rev, tempdir) | 733 | upd_p, new_p, del_p = _export_patches(srctree, rd, update_rev, |
734 | tempdir) | ||
699 | 735 | ||
700 | # Match up and replace existing patches with corresponding new patches | 736 | # Match up and replace existing patches with corresponding new patches |
701 | updatepatches = False | 737 | updatepatches = False |
702 | updaterecipe = False | 738 | updaterecipe = False |
703 | destpath = None | 739 | destpath = None |
704 | newpatches = sorted(os.listdir(tempdir)) | ||
705 | if args.append: | 740 | if args.append: |
706 | patchfiles = {} | 741 | patchfiles = dict((os.path.join(tempdir, key), val) for |
707 | for patch in existing_patches: | 742 | key, val in upd_p.items() + new_p.items()) |
708 | patchfile = os.path.basename(patch) | ||
709 | if patchfile in newpatches: | ||
710 | patchfiles[os.path.join(tempdir, patchfile)] = patchfile | ||
711 | newpatches.remove(patchfile) | ||
712 | for patchfile in newpatches: | ||
713 | patchfiles[os.path.join(tempdir, patchfile)] = None | ||
714 | 743 | ||
715 | if patchfiles or removepatches: | 744 | if patchfiles or removepatches: |
716 | removevalues = None | 745 | removevalues = None |
@@ -728,25 +757,21 @@ def _update_recipe_patch(args, config, srctree, rd, config_data): | |||
728 | else: | 757 | else: |
729 | logger.info('No patches needed updating') | 758 | logger.info('No patches needed updating') |
730 | else: | 759 | else: |
731 | for patch in existing_patches: | 760 | for basepath, path in upd_p.iteritems(): |
732 | patchfile = os.path.basename(patch) | 761 | logger.info('Updating patch %s' % basepath) |
733 | if patchfile in newpatches: | 762 | shutil.move(os.path.join(tempdir, basepath), path) |
734 | logger.info('Updating patch %s' % patchfile) | 763 | updatepatches = True |
735 | shutil.move(os.path.join(tempdir, patchfile), patch) | ||
736 | newpatches.remove(patchfile) | ||
737 | updatepatches = True | ||
738 | srcuri = (rd.getVar('SRC_URI', False) or '').split() | 764 | srcuri = (rd.getVar('SRC_URI', False) or '').split() |
739 | if newpatches: | 765 | patchdir = os.path.join(os.path.dirname(recipefile), |
740 | # Add any patches left over | 766 | rd.getVar('BPN', True)) |
741 | patchdir = os.path.join(os.path.dirname(recipefile), | 767 | bb.utils.mkdirhier(patchdir) |
742 | rd.getVar('BPN', True)) | 768 | for basepath, path in new_p.iteritems(): |
769 | logger.info('Adding new patch %s' % basepath) | ||
743 | bb.utils.mkdirhier(patchdir) | 770 | bb.utils.mkdirhier(patchdir) |
744 | for patchfile in newpatches: | 771 | shutil.move(os.path.join(tempdir, basepath), |
745 | logger.info('Adding new patch %s' % patchfile) | 772 | os.path.join(patchdir, basepath)) |
746 | shutil.move(os.path.join(tempdir, patchfile), | 773 | srcuri.append('file://%s' % basepath) |
747 | os.path.join(patchdir, patchfile)) | 774 | updaterecipe = True |
748 | srcuri.append('file://%s' % patchfile) | ||
749 | updaterecipe = True | ||
750 | if removepatches: | 775 | if removepatches: |
751 | removedentries, _ = _remove_patch_entries(srcuri, removepatches) | 776 | removedentries, _ = _remove_patch_entries(srcuri, removepatches) |
752 | if removedentries: | 777 | if removedentries: |