summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul Eggleton <paul.eggleton@linux.intel.com>2015-05-18 16:15:08 +0100
committerRichard Purdie <richard.purdie@linuxfoundation.org>2015-05-20 21:41:04 +0100
commit7539c1f8892e5f7467e3fe8cf8cf7a5a23033e4d (patch)
tree02fa87af1b254a594c339871d54eaf665417e82f
parentfbfc06a969200e582a059c9943e6fd17aca70e30 (diff)
downloadpoky-7539c1f8892e5f7467e3fe8cf8cf7a5a23033e4d.tar.gz
devtool: update-recipe: add option to write changes to bbappend
Quite often what you want to do having made customisations to a piece of software is to apply those customisations in your own layer rather than in the original recipe. Thus, add a -a/--append option to the update-recipe subcommand which allows you to specify the layer to write a bbappend into. The bbappend will be created at the appropriate path within the specified layer directory (which may or may not be in your bblayers.conf) or if one already exists it will be updated appropriately. (This re-uses code written for recipetool appendfile.) Implements [YOCTO #7587]. (From OE-Core rev: 87d487ea4fdfb6cd30e3b3fad47732db12e86f23) Signed-off-by: Paul Eggleton <paul.eggleton@linux.intel.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
-rw-r--r--meta/lib/oeqa/selftest/devtool.py171
-rw-r--r--scripts/lib/devtool/standard.py148
2 files changed, 278 insertions, 41 deletions
diff --git a/meta/lib/oeqa/selftest/devtool.py b/meta/lib/oeqa/selftest/devtool.py
index ad10af5826..4e22e1dfe4 100644
--- a/meta/lib/oeqa/selftest/devtool.py
+++ b/meta/lib/oeqa/selftest/devtool.py
@@ -524,6 +524,177 @@ class DevtoolTests(DevtoolBase):
524 break 524 break
525 self.assertTrue(matched, 'Unexpected diff remove line: %s' % line) 525 self.assertTrue(matched, 'Unexpected diff remove line: %s' % line)
526 526
527 def test_devtool_update_recipe_append(self):
528 # Check preconditions
529 workspacedir = os.path.join(self.builddir, 'workspace')
530 self.assertTrue(not os.path.exists(workspacedir), 'This test cannot be run with a workspace directory under the build directory')
531 testrecipe = 'mdadm'
532 recipefile = get_bb_var('FILE', testrecipe)
533 src_uri = get_bb_var('SRC_URI', testrecipe)
534 self.assertNotIn('git://', src_uri, 'This test expects the %s recipe to NOT be a git recipe' % testrecipe)
535 result = runCmd('git status . --porcelain', cwd=os.path.dirname(recipefile))
536 self.assertEqual(result.output.strip(), "", '%s recipe is not clean' % testrecipe)
537 # First, modify a recipe
538 tempdir = tempfile.mkdtemp(prefix='devtoolqa')
539 tempsrcdir = os.path.join(tempdir, 'source')
540 templayerdir = os.path.join(tempdir, 'layer')
541 self.track_for_cleanup(tempdir)
542 self.track_for_cleanup(workspacedir)
543 self.add_command_to_tearDown('bitbake-layers remove-layer */workspace')
544 # (don't bother with cleaning the recipe on teardown, we won't be building it)
545 result = runCmd('devtool modify %s -x %s' % (testrecipe, tempsrcdir))
546 # Check git repo
547 self.assertTrue(os.path.isdir(os.path.join(tempsrcdir, '.git')), 'git repository for external source tree not found')
548 result = runCmd('git status --porcelain', cwd=tempsrcdir)
549 self.assertEqual(result.output.strip(), "", 'Created git repo is not clean')
550 result = runCmd('git symbolic-ref HEAD', cwd=tempsrcdir)
551 self.assertEqual(result.output.strip(), "refs/heads/devtool", 'Wrong branch in git repo')
552 # Add a commit
553 result = runCmd("sed 's!\\(#define VERSION\\W*\"[^\"]*\\)\"!\\1-custom\"!' -i ReadMe.c", cwd=tempsrcdir)
554 result = runCmd('git commit -a -m "Add our custom version"', cwd=tempsrcdir)
555 self.add_command_to_tearDown('cd %s; rm -f %s/*.patch; git checkout .' % (os.path.dirname(recipefile), testrecipe))
556 # Create a temporary layer and add it to bblayers.conf
557 self._create_temp_layer(templayerdir, True, 'selftestupdaterecipe')
558 # Create the bbappend
559 result = runCmd('devtool update-recipe %s -a %s' % (testrecipe, templayerdir))
560 self.assertNotIn('WARNING:', result.output)
561 # Check recipe is still clean
562 result = runCmd('git status . --porcelain', cwd=os.path.dirname(recipefile))
563 self.assertEqual(result.output.strip(), "", '%s recipe is not clean' % testrecipe)
564 # Check bbappend was created
565 splitpath = os.path.dirname(recipefile).split(os.sep)
566 appenddir = os.path.join(templayerdir, splitpath[-2], splitpath[-1])
567 bbappendfile = self._check_bbappend(testrecipe, recipefile, appenddir)
568 patchfile = os.path.join(appenddir, testrecipe, '0001-Add-our-custom-version.patch')
569 self.assertTrue(os.path.exists(patchfile), 'Patch file not created')
570
571 # Check bbappend contents
572 expectedlines = ['FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:"\n',
573 '\n',
574 'SRC_URI += "file://0001-Add-our-custom-version.patch"\n',
575 '\n']
576 with open(bbappendfile, 'r') as f:
577 self.assertEqual(expectedlines, f.readlines())
578
579 # Check we can run it again and bbappend isn't modified
580 result = runCmd('devtool update-recipe %s -a %s' % (testrecipe, templayerdir))
581 with open(bbappendfile, 'r') as f:
582 self.assertEqual(expectedlines, f.readlines())
583 # Drop new commit and check patch gets deleted
584 result = runCmd('git reset HEAD^', cwd=tempsrcdir)
585 result = runCmd('devtool update-recipe %s -a %s' % (testrecipe, templayerdir))
586 self.assertFalse(os.path.exists(patchfile), 'Patch file not deleted')
587 expectedlines2 = ['FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:"\n',
588 '\n']
589 with open(bbappendfile, 'r') as f:
590 self.assertEqual(expectedlines2, f.readlines())
591 # Put commit back and check we can run it if layer isn't in bblayers.conf
592 os.remove(bbappendfile)
593 result = runCmd('git commit -a -m "Add our custom version"', cwd=tempsrcdir)
594 result = runCmd('bitbake-layers remove-layer %s' % templayerdir, cwd=self.builddir)
595 result = runCmd('devtool update-recipe %s -a %s' % (testrecipe, templayerdir))
596 self.assertIn('WARNING: Specified layer is not currently enabled in bblayers.conf', result.output)
597 self.assertTrue(os.path.exists(patchfile), 'Patch file not created (with disabled layer)')
598 with open(bbappendfile, 'r') as f:
599 self.assertEqual(expectedlines, f.readlines())
600 # Deleting isn't expected to work under these circumstances
601
602 def test_devtool_update_recipe_append_git(self):
603 # Check preconditions
604 workspacedir = os.path.join(self.builddir, 'workspace')
605 self.assertTrue(not os.path.exists(workspacedir), 'This test cannot be run with a workspace directory under the build directory')
606 testrecipe = 'mtd-utils'
607 recipefile = get_bb_var('FILE', testrecipe)
608 src_uri = get_bb_var('SRC_URI', testrecipe)
609 self.assertIn('git://', src_uri, 'This test expects the %s recipe to be a git recipe' % testrecipe)
610 for entry in src_uri.split():
611 if entry.startswith('git://'):
612 git_uri = entry
613 break
614 result = runCmd('git status . --porcelain', cwd=os.path.dirname(recipefile))
615 self.assertEqual(result.output.strip(), "", '%s recipe is not clean' % testrecipe)
616 # First, modify a recipe
617 tempdir = tempfile.mkdtemp(prefix='devtoolqa')
618 tempsrcdir = os.path.join(tempdir, 'source')
619 templayerdir = os.path.join(tempdir, 'layer')
620 self.track_for_cleanup(tempdir)
621 self.track_for_cleanup(workspacedir)
622 self.add_command_to_tearDown('bitbake-layers remove-layer */workspace')
623 # (don't bother with cleaning the recipe on teardown, we won't be building it)
624 result = runCmd('devtool modify %s -x %s' % (testrecipe, tempsrcdir))
625 # Check git repo
626 self.assertTrue(os.path.isdir(os.path.join(tempsrcdir, '.git')), 'git repository for external source tree not found')
627 result = runCmd('git status --porcelain', cwd=tempsrcdir)
628 self.assertEqual(result.output.strip(), "", 'Created git repo is not clean')
629 result = runCmd('git symbolic-ref HEAD', cwd=tempsrcdir)
630 self.assertEqual(result.output.strip(), "refs/heads/devtool", 'Wrong branch in git repo')
631 # Add a commit
632 result = runCmd('echo "# Additional line" >> Makefile', cwd=tempsrcdir)
633 result = runCmd('git commit -a -m "Change the Makefile"', cwd=tempsrcdir)
634 self.add_command_to_tearDown('cd %s; rm -f %s/*.patch; git checkout .' % (os.path.dirname(recipefile), testrecipe))
635 # Create a temporary layer
636 os.makedirs(os.path.join(templayerdir, 'conf'))
637 with open(os.path.join(templayerdir, 'conf', 'layer.conf'), 'w') as f:
638 f.write('BBPATH .= ":${LAYERDIR}"\n')
639 f.write('BBFILES += "${LAYERDIR}/recipes-*/*/*.bbappend"\n')
640 f.write('BBFILE_COLLECTIONS += "oeselftesttemplayer"\n')
641 f.write('BBFILE_PATTERN_oeselftesttemplayer = "^${LAYERDIR}/"\n')
642 f.write('BBFILE_PRIORITY_oeselftesttemplayer = "999"\n')
643 f.write('BBFILE_PATTERN_IGNORE_EMPTY_oeselftesttemplayer = "1"\n')
644 self.add_command_to_tearDown('bitbake-layers remove-layer %s || true' % templayerdir)
645 result = runCmd('bitbake-layers add-layer %s' % templayerdir, cwd=self.builddir)
646 # Create the bbappend
647 result = runCmd('devtool update-recipe %s -a %s' % (testrecipe, templayerdir))
648 self.assertNotIn('WARNING:', result.output)
649 # Check recipe is still clean
650 result = runCmd('git status . --porcelain', cwd=os.path.dirname(recipefile))
651 self.assertEqual(result.output.strip(), "", '%s recipe is not clean' % testrecipe)
652 # Check bbappend was created
653 splitpath = os.path.dirname(recipefile).split(os.sep)
654 appenddir = os.path.join(templayerdir, splitpath[-2], splitpath[-1])
655 bbappendfile = self._check_bbappend(testrecipe, recipefile, appenddir)
656 self.assertFalse(os.path.exists(os.path.join(appenddir, testrecipe)), 'Patch directory should not be created')
657
658 # Check bbappend contents
659 result = runCmd('git rev-parse HEAD', cwd=tempsrcdir)
660 expectedlines = ['SRCREV = "%s"\n' % result.output,
661 '\n',
662 'SRC_URI = "%s"\n' % git_uri,
663 '\n']
664 with open(bbappendfile, 'r') as f:
665 self.assertEqual(expectedlines, f.readlines())
666
667 # Check we can run it again and bbappend isn't modified
668 result = runCmd('devtool update-recipe %s -a %s' % (testrecipe, templayerdir))
669 with open(bbappendfile, 'r') as f:
670 self.assertEqual(expectedlines, f.readlines())
671 # Drop new commit and check SRCREV changes
672 result = runCmd('git reset HEAD^', cwd=tempsrcdir)
673 result = runCmd('devtool update-recipe %s -a %s' % (testrecipe, templayerdir))
674 self.assertFalse(os.path.exists(os.path.join(appenddir, testrecipe)), 'Patch directory should not be created')
675 result = runCmd('git rev-parse HEAD', cwd=tempsrcdir)
676 expectedlines = ['SRCREV = "%s"\n' % result.output,
677 '\n',
678 'SRC_URI = "%s"\n' % git_uri,
679 '\n']
680 with open(bbappendfile, 'r') as f:
681 self.assertEqual(expectedlines, f.readlines())
682 # Put commit back and check we can run it if layer isn't in bblayers.conf
683 os.remove(bbappendfile)
684 result = runCmd('git commit -a -m "Change the Makefile"', cwd=tempsrcdir)
685 result = runCmd('bitbake-layers remove-layer %s' % templayerdir, cwd=self.builddir)
686 result = runCmd('devtool update-recipe %s -a %s' % (testrecipe, templayerdir))
687 self.assertIn('WARNING: Specified layer is not currently enabled in bblayers.conf', result.output)
688 self.assertFalse(os.path.exists(os.path.join(appenddir, testrecipe)), 'Patch directory should not be created')
689 result = runCmd('git rev-parse HEAD', cwd=tempsrcdir)
690 expectedlines = ['SRCREV = "%s"\n' % result.output,
691 '\n',
692 'SRC_URI = "%s"\n' % git_uri,
693 '\n']
694 with open(bbappendfile, 'r') as f:
695 self.assertEqual(expectedlines, f.readlines())
696 # Deleting isn't expected to work under these circumstances
697
527 def test_devtool_extract(self): 698 def test_devtool_extract(self):
528 # Check preconditions 699 # Check preconditions
529 workspacedir = os.path.join(self.builddir, 'workspace') 700 workspacedir = os.path.join(self.builddir, 'workspace')
diff --git a/scripts/lib/devtool/standard.py b/scripts/lib/devtool/standard.py
index 122121aedb..c5b32d81db 100644
--- a/scripts/lib/devtool/standard.py
+++ b/scripts/lib/devtool/standard.py
@@ -24,6 +24,7 @@ import tempfile
24import logging 24import logging
25import argparse 25import argparse
26import scriptutils 26import scriptutils
27import errno
27from devtool import exec_build_env_command, setup_tinfoil 28from devtool import exec_build_env_command, setup_tinfoil
28 29
29logger = logging.getLogger('devtool') 30logger = logging.getLogger('devtool')
@@ -510,6 +511,14 @@ def update_recipe(args, config, basepath, workspace):
510 logger.error("no recipe named %s in your workspace" % args.recipename) 511 logger.error("no recipe named %s in your workspace" % args.recipename)
511 return -1 512 return -1
512 513
514 if args.append:
515 if not os.path.exists(args.append):
516 logger.error('bbappend destination layer directory "%s" does not exist' % args.append)
517 return 2
518 if not os.path.exists(os.path.join(args.append, 'conf', 'layer.conf')):
519 logger.error('conf/layer.conf not found in bbappend destination layer "%s"' % args.append)
520 return 2
521
513 tinfoil = setup_tinfoil() 522 tinfoil = setup_tinfoil()
514 import bb 523 import bb
515 from oe.patch import GitApplyTree 524 from oe.patch import GitApplyTree
@@ -535,22 +544,19 @@ def update_recipe(args, config, basepath, workspace):
535 else: 544 else:
536 mode = args.mode 545 mode = args.mode
537 546
538 def remove_patches(srcuri, patchlist): 547 def remove_patch_entries(srcuri, patchlist):
539 """Remove patches""" 548 """Remove patch entries from SRC_URI"""
540 updated = False 549 remaining = patchlist[:]
550 entries = []
541 for patch in patchlist: 551 for patch in patchlist:
542 patchfile = os.path.basename(patch) 552 patchfile = os.path.basename(patch)
543 for i in xrange(len(srcuri)): 553 for i in xrange(len(srcuri)):
544 if srcuri[i].startswith('file://') and os.path.basename(srcuri[i]).split(';')[0] == patchfile: 554 if srcuri[i].startswith('file://') and os.path.basename(srcuri[i].split(';')[0]) == patchfile:
545 logger.info('Removing patch %s' % patchfile) 555 entries.append(srcuri[i])
556 remaining.remove(patch)
546 srcuri.pop(i) 557 srcuri.pop(i)
547 # FIXME "git rm" here would be nice if the file in question is tracked
548 # FIXME there's a chance that this file is referred to by another recipe, in which case deleting wouldn't be the right thing to do
549 if patch.startswith(os.path.dirname(recipefile)):
550 os.remove(patch)
551 updated = True
552 break 558 break
553 return updated 559 return entries, remaining
554 560
555 srctree = workspace[args.recipename] 561 srctree = workspace[args.recipename]
556 562
@@ -565,8 +571,11 @@ def update_recipe(args, config, basepath, workspace):
565 logger.error('Invalid hash returned by git: %s' % stdout) 571 logger.error('Invalid hash returned by git: %s' % stdout)
566 return 1 572 return 1
567 573
574 removepatches = []
575 destpath = None
568 if mode == 'srcrev': 576 if mode == 'srcrev':
569 logger.info('Updating SRCREV in recipe %s' % os.path.basename(recipefile)) 577 logger.info('Updating SRCREV in recipe %s' % os.path.basename(recipefile))
578 removevalues = None
570 patchfields = {} 579 patchfields = {}
571 patchfields['SRCREV'] = srcrev 580 patchfields['SRCREV'] = srcrev
572 if not args.no_remove: 581 if not args.no_remove:
@@ -575,7 +584,6 @@ def update_recipe(args, config, basepath, workspace):
575 584
576 old_srcrev = (rd.getVar('SRCREV', False) or '') 585 old_srcrev = (rd.getVar('SRCREV', False) or '')
577 tempdir = tempfile.mkdtemp(prefix='devtool') 586 tempdir = tempfile.mkdtemp(prefix='devtool')
578 removepatches = []
579 try: 587 try:
580 GitApplyTree.extractPatches(srctree, old_srcrev, tempdir) 588 GitApplyTree.extractPatches(srctree, old_srcrev, tempdir)
581 newpatches = os.listdir(tempdir) 589 newpatches = os.listdir(tempdir)
@@ -587,10 +595,14 @@ def update_recipe(args, config, basepath, workspace):
587 shutil.rmtree(tempdir) 595 shutil.rmtree(tempdir)
588 if removepatches: 596 if removepatches:
589 srcuri = (rd.getVar('SRC_URI', False) or '').split() 597 srcuri = (rd.getVar('SRC_URI', False) or '').split()
590 if remove_patches(srcuri, removepatches): 598 removedentries, _ = remove_patch_entries(srcuri, removepatches)
599 if removedentries:
591 patchfields['SRC_URI'] = ' '.join(srcuri) 600 patchfields['SRC_URI'] = ' '.join(srcuri)
592 601
593 oe.recipeutils.patch_recipe(tinfoil.config_data, recipefile, patchfields) 602 if args.append:
603 (appendfile, destpath) = oe.recipeutils.bbappend_recipe(rd, args.append, None, wildcardver=args.wildcard_version, extralines=patchfields)
604 else:
605 oe.recipeutils.patch_recipe(tinfoil.config_data, recipefile, patchfields)
594 606
595 if not 'git://' in orig_src_uri: 607 if not 'git://' in orig_src_uri:
596 logger.info('You will need to update SRC_URI within the recipe to point to a git repository where you have pushed your changes') 608 logger.info('You will need to update SRC_URI within the recipe to point to a git repository where you have pushed your changes')
@@ -628,6 +640,7 @@ def update_recipe(args, config, basepath, workspace):
628 existing_patches = oe.recipeutils.get_recipe_patches(rd) 640 existing_patches = oe.recipeutils.get_recipe_patches(rd)
629 641
630 removepatches = [] 642 removepatches = []
643 seqpatch_re = re.compile('^[0-9]{4}-')
631 if not args.no_remove: 644 if not args.no_remove:
632 # Get all patches from source tree and check if any should be removed 645 # Get all patches from source tree and check if any should be removed
633 tempdir = tempfile.mkdtemp(prefix='devtool') 646 tempdir = tempfile.mkdtemp(prefix='devtool')
@@ -635,8 +648,18 @@ def update_recipe(args, config, basepath, workspace):
635 GitApplyTree.extractPatches(srctree, initial_rev, tempdir) 648 GitApplyTree.extractPatches(srctree, initial_rev, tempdir)
636 newpatches = os.listdir(tempdir) 649 newpatches = os.listdir(tempdir)
637 for patch in existing_patches: 650 for patch in existing_patches:
651 # If it's a git sequence named patch, the numbers might not match up
652 # since we are starting from a different revision
653 # This does assume that people are using unique shortlog values, but
654 # they ought to be anyway...
638 patchfile = os.path.basename(patch) 655 patchfile = os.path.basename(patch)
639 if patchfile not in newpatches: 656 if seqpatch_re.search(patchfile):
657 for newpatch in newpatches:
658 if seqpatch_re.search(newpatch) and patchfile[5:] == newpatch[5:]:
659 break
660 else:
661 removepatches.append(patch)
662 elif patchfile not in newpatches:
640 removepatches.append(patch) 663 removepatches.append(patch)
641 finally: 664 finally:
642 shutil.rmtree(tempdir) 665 shutil.rmtree(tempdir)
@@ -650,33 +673,56 @@ def update_recipe(args, config, basepath, workspace):
650 updatepatches = False 673 updatepatches = False
651 updaterecipe = False 674 updaterecipe = False
652 newpatches = os.listdir(tempdir) 675 newpatches = os.listdir(tempdir)
653 for patch in existing_patches: 676 if args.append:
654 patchfile = os.path.basename(patch) 677 patchfiles = {}
655 if patchfile in newpatches: 678 for patch in existing_patches:
656 logger.info('Updating patch %s' % patchfile) 679 patchfile = os.path.basename(patch)
657 shutil.move(os.path.join(tempdir, patchfile), patch) 680 if patchfile in newpatches:
658 newpatches.remove(patchfile) 681 patchfiles[os.path.join(tempdir, patchfile)] = patchfile
659 updatepatches = True 682 newpatches.remove(patchfile)
660 srcuri = (rd.getVar('SRC_URI', False) or '').split()
661 if newpatches:
662 # Add any patches left over
663 patchdir = os.path.join(os.path.dirname(recipefile), rd.getVar('BPN', True))
664 bb.utils.mkdirhier(patchdir)
665 for patchfile in newpatches: 683 for patchfile in newpatches:
666 logger.info('Adding new patch %s' % patchfile) 684 patchfiles[os.path.join(tempdir, patchfile)] = None
667 shutil.move(os.path.join(tempdir, patchfile), os.path.join(patchdir, patchfile)) 685
668 srcuri.append('file://%s' % patchfile) 686 if patchfiles or removepatches:
669 updaterecipe = True 687 removevalues = None
670 if removepatches: 688 if removepatches:
671 if remove_patches(srcuri, removepatches): 689 srcuri = (rd.getVar('SRC_URI', False) or '').split()
672 updaterecipe = True 690 removedentries, remaining = remove_patch_entries(srcuri, removepatches)
673 if updaterecipe: 691 if removedentries or remaining:
674 logger.info('Updating recipe %s' % os.path.basename(recipefile)) 692 removevalues = {'SRC_URI': removedentries + ['file://' + os.path.basename(item) for item in remaining]}
675 oe.recipeutils.patch_recipe(tinfoil.config_data, 693 (appendfile, destpath) = oe.recipeutils.bbappend_recipe(rd, args.append, patchfiles, removevalues=removevalues)
676 recipefile, {'SRC_URI': ' '.join(srcuri)}) 694 else:
677 elif not updatepatches: 695 logger.info('No patches needed updating')
678 # Neither patches nor recipe were updated 696 else:
679 logger.info('No patches need updating') 697 for patch in existing_patches:
698 patchfile = os.path.basename(patch)
699 if patchfile in newpatches:
700 logger.info('Updating patch %s' % patchfile)
701 shutil.move(os.path.join(tempdir, patchfile), patch)
702 newpatches.remove(patchfile)
703 updatepatches = True
704 srcuri = (rd.getVar('SRC_URI', False) or '').split()
705 if newpatches:
706 # Add any patches left over
707 patchdir = os.path.join(os.path.dirname(recipefile), rd.getVar('BPN', True))
708 bb.utils.mkdirhier(patchdir)
709 for patchfile in newpatches:
710 logger.info('Adding new patch %s' % patchfile)
711 shutil.move(os.path.join(tempdir, patchfile), os.path.join(patchdir, patchfile))
712 srcuri.append('file://%s' % patchfile)
713 updaterecipe = True
714 if removepatches:
715 removedentries, _ = remove_patch_entries(srcuri, removepatches)
716 if removedentries:
717 updaterecipe = True
718 if updaterecipe:
719 logger.info('Updating recipe %s' % os.path.basename(recipefile))
720 oe.recipeutils.patch_recipe(tinfoil.config_data,
721 recipefile, {'SRC_URI': ' '.join(srcuri)})
722 elif not updatepatches:
723 # Neither patches nor recipe were updated
724 logger.info('No patches need updating')
725
680 finally: 726 finally:
681 shutil.rmtree(tempdir) 727 shutil.rmtree(tempdir)
682 728
@@ -684,6 +730,24 @@ def update_recipe(args, config, basepath, workspace):
684 logger.error('update_recipe: invalid mode %s' % mode) 730 logger.error('update_recipe: invalid mode %s' % mode)
685 return 1 731 return 1
686 732
733 if removepatches:
734 for patchfile in removepatches:
735 if args.append:
736 if not destpath:
737 raise Exception('destpath should be set here')
738 patchfile = os.path.join(destpath, os.path.basename(patchfile))
739
740 if os.path.exists(patchfile):
741 logger.info('Removing patch %s' % patchfile)
742 # FIXME "git rm" here would be nice if the file in question is tracked
743 # FIXME there's a chance that this file is referred to by another recipe, in which case deleting wouldn't be the right thing to do
744 os.remove(patchfile)
745 # Remove directory if empty
746 try:
747 os.rmdir(os.path.dirname(patchfile))
748 except OSError as ose:
749 if ose.errno != errno.ENOTEMPTY:
750 raise
687 return 0 751 return 0
688 752
689 753
@@ -797,6 +861,8 @@ def register_commands(subparsers, context):
797 parser_update_recipe.add_argument('recipename', help='Name of recipe to update') 861 parser_update_recipe.add_argument('recipename', help='Name of recipe to update')
798 parser_update_recipe.add_argument('--mode', '-m', choices=['patch', 'srcrev', 'auto'], default='auto', help='Update mode (where %(metavar)s is %(choices)s; default is %(default)s)', metavar='MODE') 862 parser_update_recipe.add_argument('--mode', '-m', choices=['patch', 'srcrev', 'auto'], default='auto', help='Update mode (where %(metavar)s is %(choices)s; default is %(default)s)', metavar='MODE')
799 parser_update_recipe.add_argument('--initial-rev', help='Starting revision for patches') 863 parser_update_recipe.add_argument('--initial-rev', help='Starting revision for patches')
864 parser_update_recipe.add_argument('--append', '-a', help='Write changes to a bbappend in the specified layer instead of the recipe', metavar='LAYERDIR')
865 parser_update_recipe.add_argument('--wildcard-version', '-w', help='In conjunction with -a/--append, use a wildcard to make the bbappend apply to any recipe version', action='store_true')
800 parser_update_recipe.add_argument('--no-remove', '-n', action="store_true", help='Don\'t remove patches, only add or update') 866 parser_update_recipe.add_argument('--no-remove', '-n', action="store_true", help='Don\'t remove patches, only add or update')
801 parser_update_recipe.set_defaults(func=update_recipe) 867 parser_update_recipe.set_defaults(func=update_recipe)
802 868