diff options
Diffstat (limited to 'scripts/lib/devtool/standard.py')
-rw-r--r-- | scripts/lib/devtool/standard.py | 288 |
1 files changed, 108 insertions, 180 deletions
diff --git a/scripts/lib/devtool/standard.py b/scripts/lib/devtool/standard.py index bd009f44b1..1fd5947c41 100644 --- a/scripts/lib/devtool/standard.py +++ b/scripts/lib/devtool/standard.py | |||
@@ -18,11 +18,13 @@ import argparse_oe | |||
18 | import scriptutils | 18 | import scriptutils |
19 | import errno | 19 | import errno |
20 | import glob | 20 | import glob |
21 | import filecmp | ||
22 | from collections import OrderedDict | 21 | from collections import OrderedDict |
22 | |||
23 | from devtool import exec_build_env_command, setup_tinfoil, check_workspace_recipe, use_external_build, setup_git_repo, recipe_to_append, get_bbclassextend_targets, update_unlockedsigs, check_prerelease_version, check_git_repo_dirty, check_git_repo_op, DevtoolError | 23 | from devtool import exec_build_env_command, setup_tinfoil, check_workspace_recipe, use_external_build, setup_git_repo, recipe_to_append, get_bbclassextend_targets, update_unlockedsigs, check_prerelease_version, check_git_repo_dirty, check_git_repo_op, DevtoolError |
24 | from devtool import parse_recipe | 24 | from devtool import parse_recipe |
25 | 25 | ||
26 | import bb.utils | ||
27 | |||
26 | logger = logging.getLogger('devtool') | 28 | logger = logging.getLogger('devtool') |
27 | 29 | ||
28 | override_branch_prefix = 'devtool-override-' | 30 | override_branch_prefix = 'devtool-override-' |
@@ -30,7 +32,8 @@ override_branch_prefix = 'devtool-override-' | |||
30 | 32 | ||
31 | def add(args, config, basepath, workspace): | 33 | def add(args, config, basepath, workspace): |
32 | """Entry point for the devtool 'add' subcommand""" | 34 | """Entry point for the devtool 'add' subcommand""" |
33 | import bb | 35 | import bb.data |
36 | import bb.process | ||
34 | import oe.recipeutils | 37 | import oe.recipeutils |
35 | 38 | ||
36 | if not args.recipename and not args.srctree and not args.fetch and not args.fetchuri: | 39 | if not args.recipename and not args.srctree and not args.fetch and not args.fetchuri: |
@@ -206,7 +209,7 @@ def add(args, config, basepath, workspace): | |||
206 | for fn in os.listdir(tempdir): | 209 | for fn in os.listdir(tempdir): |
207 | shutil.move(os.path.join(tempdir, fn), recipedir) | 210 | shutil.move(os.path.join(tempdir, fn), recipedir) |
208 | else: | 211 | else: |
209 | raise DevtoolError('Command \'%s\' did not create any recipe file:\n%s' % (e.command, e.stdout)) | 212 | raise DevtoolError(f'Failed to create a recipe file for source {source}') |
210 | attic_recipe = os.path.join(config.workspace_path, 'attic', recipename, os.path.basename(recipefile)) | 213 | attic_recipe = os.path.join(config.workspace_path, 'attic', recipename, os.path.basename(recipefile)) |
211 | if os.path.exists(attic_recipe): | 214 | if os.path.exists(attic_recipe): |
212 | logger.warning('A modified recipe from a previous invocation exists in %s - you may wish to move this over the top of the new recipe if you had changes in it that you want to continue with' % attic_recipe) | 215 | logger.warning('A modified recipe from a previous invocation exists in %s - you may wish to move this over the top of the new recipe if you had changes in it that you want to continue with' % attic_recipe) |
@@ -305,6 +308,7 @@ def add(args, config, basepath, workspace): | |||
305 | 308 | ||
306 | def _check_compatible_recipe(pn, d): | 309 | def _check_compatible_recipe(pn, d): |
307 | """Check if the recipe is supported by devtool""" | 310 | """Check if the recipe is supported by devtool""" |
311 | import bb.data | ||
308 | if pn == 'perf': | 312 | if pn == 'perf': |
309 | raise DevtoolError("The perf recipe does not actually check out " | 313 | raise DevtoolError("The perf recipe does not actually check out " |
310 | "source and thus cannot be supported by this tool", | 314 | "source and thus cannot be supported by this tool", |
@@ -374,7 +378,7 @@ def _copy_file(src, dst, dry_run_outdir=None, base_outdir=None): | |||
374 | 378 | ||
375 | def _git_ls_tree(repodir, treeish='HEAD', recursive=False): | 379 | def _git_ls_tree(repodir, treeish='HEAD', recursive=False): |
376 | """List contents of a git treeish""" | 380 | """List contents of a git treeish""" |
377 | import bb | 381 | import bb.process |
378 | cmd = ['git', 'ls-tree', '-z', treeish] | 382 | cmd = ['git', 'ls-tree', '-z', treeish] |
379 | if recursive: | 383 | if recursive: |
380 | cmd.append('-r') | 384 | cmd.append('-r') |
@@ -387,6 +391,19 @@ def _git_ls_tree(repodir, treeish='HEAD', recursive=False): | |||
387 | ret[split[3]] = split[0:3] | 391 | ret[split[3]] = split[0:3] |
388 | return ret | 392 | return ret |
389 | 393 | ||
394 | def _git_modified(repodir): | ||
395 | """List the difference between HEAD and the index""" | ||
396 | import bb.process | ||
397 | cmd = ['git', 'status', '--porcelain'] | ||
398 | out, _ = bb.process.run(cmd, cwd=repodir) | ||
399 | ret = [] | ||
400 | if out: | ||
401 | for line in out.split("\n"): | ||
402 | if line and not line.startswith('??'): | ||
403 | ret.append(line[3:]) | ||
404 | return ret | ||
405 | |||
406 | |||
390 | def _git_exclude_path(srctree, path): | 407 | def _git_exclude_path(srctree, path): |
391 | """Return pathspec (list of paths) that excludes certain path""" | 408 | """Return pathspec (list of paths) that excludes certain path""" |
392 | # NOTE: "Filtering out" files/paths in this way is not entirely reliable - | 409 | # NOTE: "Filtering out" files/paths in this way is not entirely reliable - |
@@ -414,8 +431,6 @@ def _ls_tree(directory): | |||
414 | 431 | ||
415 | def extract(args, config, basepath, workspace): | 432 | def extract(args, config, basepath, workspace): |
416 | """Entry point for the devtool 'extract' subcommand""" | 433 | """Entry point for the devtool 'extract' subcommand""" |
417 | import bb | ||
418 | |||
419 | tinfoil = setup_tinfoil(basepath=basepath, tracking=True) | 434 | tinfoil = setup_tinfoil(basepath=basepath, tracking=True) |
420 | if not tinfoil: | 435 | if not tinfoil: |
421 | # Error already shown | 436 | # Error already shown |
@@ -438,8 +453,6 @@ def extract(args, config, basepath, workspace): | |||
438 | 453 | ||
439 | def sync(args, config, basepath, workspace): | 454 | def sync(args, config, basepath, workspace): |
440 | """Entry point for the devtool 'sync' subcommand""" | 455 | """Entry point for the devtool 'sync' subcommand""" |
441 | import bb | ||
442 | |||
443 | tinfoil = setup_tinfoil(basepath=basepath, tracking=True) | 456 | tinfoil = setup_tinfoil(basepath=basepath, tracking=True) |
444 | if not tinfoil: | 457 | if not tinfoil: |
445 | # Error already shown | 458 | # Error already shown |
@@ -460,37 +473,11 @@ def sync(args, config, basepath, workspace): | |||
460 | finally: | 473 | finally: |
461 | tinfoil.shutdown() | 474 | tinfoil.shutdown() |
462 | 475 | ||
463 | def symlink_oelocal_files_srctree(rd, srctree): | ||
464 | import oe.patch | ||
465 | if os.path.abspath(rd.getVar('S')) == os.path.abspath(rd.getVar('WORKDIR')): | ||
466 | # If recipe extracts to ${WORKDIR}, symlink the files into the srctree | ||
467 | # (otherwise the recipe won't build as expected) | ||
468 | local_files_dir = os.path.join(srctree, 'oe-local-files') | ||
469 | addfiles = [] | ||
470 | for root, _, files in os.walk(local_files_dir): | ||
471 | relpth = os.path.relpath(root, local_files_dir) | ||
472 | if relpth != '.': | ||
473 | bb.utils.mkdirhier(os.path.join(srctree, relpth)) | ||
474 | for fn in files: | ||
475 | if fn == '.gitignore': | ||
476 | continue | ||
477 | destpth = os.path.join(srctree, relpth, fn) | ||
478 | if os.path.exists(destpth): | ||
479 | os.unlink(destpth) | ||
480 | if relpth != '.': | ||
481 | back_relpth = os.path.relpath(local_files_dir, root) | ||
482 | os.symlink('%s/oe-local-files/%s/%s' % (back_relpth, relpth, fn), destpth) | ||
483 | else: | ||
484 | os.symlink('oe-local-files/%s' % fn, destpth) | ||
485 | addfiles.append(os.path.join(relpth, fn)) | ||
486 | if addfiles: | ||
487 | oe.patch.GitApplyTree.commitIgnored("Add local file symlinks", dir=srctree, files=addfiles, d=rd) | ||
488 | |||
489 | def _extract_source(srctree, keep_temp, devbranch, sync, config, basepath, workspace, fixed_setup, d, tinfoil, no_overrides=False): | 476 | def _extract_source(srctree, keep_temp, devbranch, sync, config, basepath, workspace, fixed_setup, d, tinfoil, no_overrides=False): |
490 | """Extract sources of a recipe""" | 477 | """Extract sources of a recipe""" |
491 | import oe.recipeutils | ||
492 | import oe.patch | ||
493 | import oe.path | 478 | import oe.path |
479 | import bb.data | ||
480 | import bb.process | ||
494 | 481 | ||
495 | pn = d.getVar('PN') | 482 | pn = d.getVar('PN') |
496 | 483 | ||
@@ -555,6 +542,7 @@ def _extract_source(srctree, keep_temp, devbranch, sync, config, basepath, works | |||
555 | tempbasedir = d.getVar('WORKDIR') | 542 | tempbasedir = d.getVar('WORKDIR') |
556 | bb.utils.mkdirhier(tempbasedir) | 543 | bb.utils.mkdirhier(tempbasedir) |
557 | tempdir = tempfile.mkdtemp(prefix='devtooltmp-', dir=tempbasedir) | 544 | tempdir = tempfile.mkdtemp(prefix='devtooltmp-', dir=tempbasedir) |
545 | appendbackup = None | ||
558 | try: | 546 | try: |
559 | tinfoil.logger.setLevel(logging.WARNING) | 547 | tinfoil.logger.setLevel(logging.WARNING) |
560 | 548 | ||
@@ -565,7 +553,6 @@ def _extract_source(srctree, keep_temp, devbranch, sync, config, basepath, works | |||
565 | appendbackup = os.path.join(tempdir, os.path.basename(appendfile) + '.bak') | 553 | appendbackup = os.path.join(tempdir, os.path.basename(appendfile) + '.bak') |
566 | shutil.copyfile(appendfile, appendbackup) | 554 | shutil.copyfile(appendfile, appendbackup) |
567 | else: | 555 | else: |
568 | appendbackup = None | ||
569 | bb.utils.mkdirhier(os.path.dirname(appendfile)) | 556 | bb.utils.mkdirhier(os.path.dirname(appendfile)) |
570 | logger.debug('writing append file %s' % appendfile) | 557 | logger.debug('writing append file %s' % appendfile) |
571 | with open(appendfile, 'a') as f: | 558 | with open(appendfile, 'a') as f: |
@@ -638,7 +625,7 @@ def _extract_source(srctree, keep_temp, devbranch, sync, config, basepath, works | |||
638 | srcsubdir = f.read() | 625 | srcsubdir = f.read() |
639 | except FileNotFoundError as e: | 626 | except FileNotFoundError as e: |
640 | raise DevtoolError('Something went wrong with source extraction - the devtool-source class was not active or did not function correctly:\n%s' % str(e)) | 627 | raise DevtoolError('Something went wrong with source extraction - the devtool-source class was not active or did not function correctly:\n%s' % str(e)) |
641 | srcsubdir_rel = os.path.relpath(srcsubdir, os.path.join(tempdir, 'workdir')) | 628 | srcsubdir_rel = os.path.relpath(srcsubdir, os.path.join(tempdir, 'workdir', os.path.relpath(d.getVar('UNPACKDIR'), d.getVar('WORKDIR')))) |
642 | 629 | ||
643 | # Check if work-shared is empty, if yes | 630 | # Check if work-shared is empty, if yes |
644 | # find source and copy to work-shared | 631 | # find source and copy to work-shared |
@@ -657,9 +644,6 @@ def _extract_source(srctree, keep_temp, devbranch, sync, config, basepath, works | |||
657 | elif not os.path.exists(workshareddir): | 644 | elif not os.path.exists(workshareddir): |
658 | oe.path.copyhardlinktree(srcsubdir, workshareddir) | 645 | oe.path.copyhardlinktree(srcsubdir, workshareddir) |
659 | 646 | ||
660 | tempdir_localdir = os.path.join(tempdir, 'oe-local-files') | ||
661 | srctree_localdir = os.path.join(srctree, 'oe-local-files') | ||
662 | |||
663 | if sync: | 647 | if sync: |
664 | try: | 648 | try: |
665 | logger.info('Backing up current %s branch as branch: %s.bak' % (devbranch, devbranch)) | 649 | logger.info('Backing up current %s branch as branch: %s.bak' % (devbranch, devbranch)) |
@@ -674,29 +658,8 @@ def _extract_source(srctree, keep_temp, devbranch, sync, config, basepath, works | |||
674 | except bb.process.ExecutionError as e: | 658 | except bb.process.ExecutionError as e: |
675 | raise DevtoolError("Error when syncing source files to local checkout: %s" % str(e)) | 659 | raise DevtoolError("Error when syncing source files to local checkout: %s" % str(e)) |
676 | 660 | ||
677 | # Move the oe-local-files directory to srctree. | ||
678 | # As oe-local-files is not part of the constructed git tree, | ||
679 | # removing it directly during the synchronization might surprise | ||
680 | # the user. Instead, we move it to oe-local-files.bak and remind | ||
681 | # the user in the log message. | ||
682 | if os.path.exists(srctree_localdir + '.bak'): | ||
683 | shutil.rmtree(srctree_localdir + '.bak') | ||
684 | |||
685 | if os.path.exists(srctree_localdir): | ||
686 | logger.info('Backing up current local file directory %s' % srctree_localdir) | ||
687 | shutil.move(srctree_localdir, srctree_localdir + '.bak') | ||
688 | |||
689 | if os.path.exists(tempdir_localdir): | ||
690 | logger.info('Syncing local source files to srctree...') | ||
691 | shutil.copytree(tempdir_localdir, srctree_localdir) | ||
692 | else: | 661 | else: |
693 | # Move oe-local-files directory to srctree | ||
694 | if os.path.exists(tempdir_localdir): | ||
695 | logger.info('Adding local source files to srctree...') | ||
696 | shutil.move(tempdir_localdir, srcsubdir) | ||
697 | |||
698 | shutil.move(srcsubdir, srctree) | 662 | shutil.move(srcsubdir, srctree) |
699 | symlink_oelocal_files_srctree(d, srctree) | ||
700 | 663 | ||
701 | if is_kernel_yocto: | 664 | if is_kernel_yocto: |
702 | logger.info('Copying kernel config to srctree') | 665 | logger.info('Copying kernel config to srctree') |
@@ -715,8 +678,6 @@ def _extract_source(srctree, keep_temp, devbranch, sync, config, basepath, works | |||
715 | 678 | ||
716 | def _add_md5(config, recipename, filename): | 679 | def _add_md5(config, recipename, filename): |
717 | """Record checksum of a file (or recursively for a directory) to the md5-file of the workspace""" | 680 | """Record checksum of a file (or recursively for a directory) to the md5-file of the workspace""" |
718 | import bb.utils | ||
719 | |||
720 | def addfile(fn): | 681 | def addfile(fn): |
721 | md5 = bb.utils.md5_file(fn) | 682 | md5 = bb.utils.md5_file(fn) |
722 | with open(os.path.join(config.workspace_path, '.devtool_md5'), 'a+') as f: | 683 | with open(os.path.join(config.workspace_path, '.devtool_md5'), 'a+') as f: |
@@ -735,7 +696,6 @@ def _add_md5(config, recipename, filename): | |||
735 | def _check_preserve(config, recipename): | 696 | def _check_preserve(config, recipename): |
736 | """Check if a file was manually changed and needs to be saved in 'attic' | 697 | """Check if a file was manually changed and needs to be saved in 'attic' |
737 | directory""" | 698 | directory""" |
738 | import bb.utils | ||
739 | origfile = os.path.join(config.workspace_path, '.devtool_md5') | 699 | origfile = os.path.join(config.workspace_path, '.devtool_md5') |
740 | newfile = os.path.join(config.workspace_path, '.devtool_md5_new') | 700 | newfile = os.path.join(config.workspace_path, '.devtool_md5_new') |
741 | preservepath = os.path.join(config.workspace_path, 'attic', recipename) | 701 | preservepath = os.path.join(config.workspace_path, 'attic', recipename) |
@@ -766,36 +726,36 @@ def _check_preserve(config, recipename): | |||
766 | 726 | ||
767 | def get_staging_kver(srcdir): | 727 | def get_staging_kver(srcdir): |
768 | # Kernel version from work-shared | 728 | # Kernel version from work-shared |
769 | kerver = [] | 729 | import itertools |
770 | staging_kerVer="" | 730 | try: |
771 | if os.path.exists(srcdir) and os.listdir(srcdir): | ||
772 | with open(os.path.join(srcdir, "Makefile")) as f: | 731 | with open(os.path.join(srcdir, "Makefile")) as f: |
773 | version = [next(f) for x in range(5)][1:4] | 732 | # Take VERSION, PATCHLEVEL, SUBLEVEL from lines 1, 2, 3 |
774 | for word in version: | 733 | return ".".join(line.rstrip().split('= ')[1] for line in itertools.islice(f, 1, 4)) |
775 | kerver.append(word.split('= ')[1].split('\n')[0]) | 734 | except FileNotFoundError: |
776 | staging_kerVer = ".".join(kerver) | 735 | return "" |
777 | return staging_kerVer | ||
778 | 736 | ||
779 | def get_staging_kbranch(srcdir): | 737 | def get_staging_kbranch(srcdir): |
738 | import bb.process | ||
780 | staging_kbranch = "" | 739 | staging_kbranch = "" |
781 | if os.path.exists(srcdir) and os.listdir(srcdir): | 740 | if os.path.exists(srcdir) and os.listdir(srcdir): |
782 | (branch, _) = bb.process.run('git branch | grep \\* | cut -d \' \' -f2', cwd=srcdir) | 741 | (branch, _) = bb.process.run('git branch | grep \\* | cut -d \' \' -f2', cwd=srcdir) |
783 | staging_kbranch = "".join(branch.split('\n')[0]) | 742 | staging_kbranch = "".join(branch.split('\n')[0]) |
784 | return staging_kbranch | 743 | return staging_kbranch |
785 | 744 | ||
786 | def get_real_srctree(srctree, s, workdir): | 745 | def get_real_srctree(srctree, s, unpackdir): |
787 | # Check that recipe isn't using a shared workdir | 746 | # Check that recipe isn't using a shared workdir |
788 | s = os.path.abspath(s) | 747 | s = os.path.abspath(s) |
789 | workdir = os.path.abspath(workdir) | 748 | unpackdir = os.path.abspath(unpackdir) |
790 | if s.startswith(workdir) and s != workdir and os.path.dirname(s) != workdir: | 749 | if s.startswith(unpackdir) and s != unpackdir and os.path.dirname(s) != unpackdir: |
791 | # Handle if S is set to a subdirectory of the source | 750 | # Handle if S is set to a subdirectory of the source |
792 | srcsubdir = os.path.relpath(s, workdir).split(os.sep, 1)[1] | 751 | srcsubdir = os.path.relpath(s, unpackdir).split(os.sep, 1)[1] |
793 | srctree = os.path.join(srctree, srcsubdir) | 752 | srctree = os.path.join(srctree, srcsubdir) |
794 | return srctree | 753 | return srctree |
795 | 754 | ||
796 | def modify(args, config, basepath, workspace): | 755 | def modify(args, config, basepath, workspace): |
797 | """Entry point for the devtool 'modify' subcommand""" | 756 | """Entry point for the devtool 'modify' subcommand""" |
798 | import bb | 757 | import bb.data |
758 | import bb.process | ||
799 | import oe.recipeutils | 759 | import oe.recipeutils |
800 | import oe.patch | 760 | import oe.patch |
801 | import oe.path | 761 | import oe.path |
@@ -851,35 +811,21 @@ def modify(args, config, basepath, workspace): | |||
851 | staging_kbranch = get_staging_kbranch(srcdir) | 811 | staging_kbranch = get_staging_kbranch(srcdir) |
852 | if (os.path.exists(srcdir) and os.listdir(srcdir)) and (kernelVersion in staging_kerVer and staging_kbranch == kbranch): | 812 | if (os.path.exists(srcdir) and os.listdir(srcdir)) and (kernelVersion in staging_kerVer and staging_kbranch == kbranch): |
853 | oe.path.copyhardlinktree(srcdir, srctree) | 813 | oe.path.copyhardlinktree(srcdir, srctree) |
854 | workdir = rd.getVar('WORKDIR') | 814 | unpackdir = rd.getVar('UNPACKDIR') |
855 | srcsubdir = rd.getVar('S') | 815 | srcsubdir = rd.getVar('S') |
856 | localfilesdir = os.path.join(srctree, 'oe-local-files') | ||
857 | # Move local source files into separate subdir | ||
858 | recipe_patches = [os.path.basename(patch) for patch in oe.recipeutils.get_recipe_patches(rd)] | ||
859 | local_files = oe.recipeutils.get_recipe_local_files(rd) | ||
860 | 816 | ||
861 | for key in local_files.copy(): | 817 | # Add locally copied files to gitignore as we add back to the metadata directly |
862 | if key.endswith('scc'): | 818 | local_files = oe.recipeutils.get_recipe_local_files(rd) |
863 | sccfile = open(local_files[key], 'r') | ||
864 | for l in sccfile: | ||
865 | line = l.split() | ||
866 | if line and line[0] in ('kconf', 'patch'): | ||
867 | cfg = os.path.join(os.path.dirname(local_files[key]), line[-1]) | ||
868 | if not cfg in local_files.values(): | ||
869 | local_files[line[-1]] = cfg | ||
870 | shutil.copy2(cfg, workdir) | ||
871 | sccfile.close() | ||
872 | |||
873 | # Ignore local files with subdir={BP} | ||
874 | srcabspath = os.path.abspath(srcsubdir) | 819 | srcabspath = os.path.abspath(srcsubdir) |
875 | local_files = [fname for fname in local_files if os.path.exists(os.path.join(workdir, fname)) and (srcabspath == workdir or not os.path.join(workdir, fname).startswith(srcabspath + os.sep))] | 820 | local_files = [fname for fname in local_files if |
821 | os.path.exists(os.path.join(unpackdir, fname)) and | ||
822 | srcabspath == unpackdir] | ||
876 | if local_files: | 823 | if local_files: |
877 | for fname in local_files: | 824 | with open(os.path.join(srctree, '.gitignore'), 'a+') as f: |
878 | _move_file(os.path.join(workdir, fname), os.path.join(srctree, 'oe-local-files', fname)) | 825 | f.write('# Ignore local files, by default. Remove following lines' |
879 | with open(os.path.join(srctree, 'oe-local-files', '.gitignore'), 'w') as f: | 826 | 'if you want to commit the directory to Git\n') |
880 | f.write('# Ignore local files, by default. Remove this file if you want to commit the directory to Git\n*\n') | 827 | for fname in local_files: |
881 | 828 | f.write('%s\n' % fname) | |
882 | symlink_oelocal_files_srctree(rd, srctree) | ||
883 | 829 | ||
884 | task = 'do_configure' | 830 | task = 'do_configure' |
885 | res = tinfoil.build_targets(pn, task, handle_events=True) | 831 | res = tinfoil.build_targets(pn, task, handle_events=True) |
@@ -904,7 +850,10 @@ def modify(args, config, basepath, workspace): | |||
904 | (stdout, _) = bb.process.run('git rev-list --reverse %s..HEAD' % initial_revs["."], cwd=srctree) | 850 | (stdout, _) = bb.process.run('git rev-list --reverse %s..HEAD' % initial_revs["."], cwd=srctree) |
905 | commits["."] = stdout.split() | 851 | commits["."] = stdout.split() |
906 | check_commits = True | 852 | check_commits = True |
907 | (stdout, _) = bb.process.run('git submodule --quiet foreach --recursive \'echo `git rev-parse devtool-base` $PWD\'', cwd=srctree) | 853 | try: |
854 | (stdout, _) = bb.process.run('git submodule --quiet foreach --recursive \'echo `git rev-parse devtool-base` $PWD\'', cwd=srctree) | ||
855 | except bb.process.ExecutionError: | ||
856 | stdout = "" | ||
908 | for line in stdout.splitlines(): | 857 | for line in stdout.splitlines(): |
909 | (rev, submodule_path) = line.split() | 858 | (rev, submodule_path) = line.split() |
910 | submodule = os.path.relpath(submodule_path, srctree) | 859 | submodule = os.path.relpath(submodule_path, srctree) |
@@ -958,7 +907,7 @@ def modify(args, config, basepath, workspace): | |||
958 | 907 | ||
959 | # Need to grab this here in case the source is within a subdirectory | 908 | # Need to grab this here in case the source is within a subdirectory |
960 | srctreebase = srctree | 909 | srctreebase = srctree |
961 | srctree = get_real_srctree(srctree, rd.getVar('S'), rd.getVar('WORKDIR')) | 910 | srctree = get_real_srctree(srctree, rd.getVar('S'), rd.getVar('UNPACKDIR')) |
962 | 911 | ||
963 | bb.utils.mkdirhier(os.path.dirname(appendfile)) | 912 | bb.utils.mkdirhier(os.path.dirname(appendfile)) |
964 | with open(appendfile, 'w') as f: | 913 | with open(appendfile, 'w') as f: |
@@ -998,13 +947,6 @@ def modify(args, config, basepath, workspace): | |||
998 | f.write('EXTERNALSRC_BUILD:pn-%s = "%s"\n' % (pn, srctree)) | 947 | f.write('EXTERNALSRC_BUILD:pn-%s = "%s"\n' % (pn, srctree)) |
999 | 948 | ||
1000 | if bb.data.inherits_class('kernel', rd): | 949 | if bb.data.inherits_class('kernel', rd): |
1001 | f.write('SRCTREECOVEREDTASKS = "do_validate_branches do_kernel_checkout ' | ||
1002 | 'do_fetch do_unpack do_kernel_configcheck"\n') | ||
1003 | f.write('\ndo_patch[noexec] = "1"\n') | ||
1004 | f.write('\ndo_configure:append() {\n' | ||
1005 | ' cp ${B}/.config ${S}/.config.baseline\n' | ||
1006 | ' ln -sfT ${B}/.config ${S}/.config.new\n' | ||
1007 | '}\n') | ||
1008 | f.write('\ndo_kernel_configme:prepend() {\n' | 950 | f.write('\ndo_kernel_configme:prepend() {\n' |
1009 | ' if [ -e ${S}/.config ]; then\n' | 951 | ' if [ -e ${S}/.config ]; then\n' |
1010 | ' mv ${S}/.config ${S}/.config.old\n' | 952 | ' mv ${S}/.config ${S}/.config.old\n' |
@@ -1028,6 +970,8 @@ def modify(args, config, basepath, workspace): | |||
1028 | if branch == args.branch: | 970 | if branch == args.branch: |
1029 | continue | 971 | continue |
1030 | f.write('# patches_%s: %s\n' % (branch, ','.join(branch_patches[branch]))) | 972 | f.write('# patches_%s: %s\n' % (branch, ','.join(branch_patches[branch]))) |
973 | if args.debug_build: | ||
974 | f.write('\nDEBUG_BUILD = "1"\n') | ||
1031 | 975 | ||
1032 | update_unlockedsigs(basepath, workspace, args.fixed_setup, [pn]) | 976 | update_unlockedsigs(basepath, workspace, args.fixed_setup, [pn]) |
1033 | 977 | ||
@@ -1072,6 +1016,7 @@ def rename(args, config, basepath, workspace): | |||
1072 | origfnver = '' | 1016 | origfnver = '' |
1073 | 1017 | ||
1074 | recipefilemd5 = None | 1018 | recipefilemd5 = None |
1019 | newrecipefilemd5 = None | ||
1075 | tinfoil = setup_tinfoil(basepath=basepath, tracking=True) | 1020 | tinfoil = setup_tinfoil(basepath=basepath, tracking=True) |
1076 | try: | 1021 | try: |
1077 | rd = parse_recipe(config, tinfoil, args.recipename, True) | 1022 | rd = parse_recipe(config, tinfoil, args.recipename, True) |
@@ -1149,6 +1094,7 @@ def rename(args, config, basepath, workspace): | |||
1149 | 1094 | ||
1150 | # Rename source tree if it's the default path | 1095 | # Rename source tree if it's the default path |
1151 | appendmd5 = None | 1096 | appendmd5 = None |
1097 | newappendmd5 = None | ||
1152 | if not args.no_srctree: | 1098 | if not args.no_srctree: |
1153 | srctree = workspace[args.recipename]['srctree'] | 1099 | srctree = workspace[args.recipename]['srctree'] |
1154 | if os.path.abspath(srctree) == os.path.join(config.workspace_path, 'sources', args.recipename): | 1100 | if os.path.abspath(srctree) == os.path.join(config.workspace_path, 'sources', args.recipename): |
@@ -1237,7 +1183,7 @@ def _get_patchset_revs(srctree, recipe_path, initial_rev=None, force_patch_refre | |||
1237 | """Get initial and update rev of a recipe. These are the start point of the | 1183 | """Get initial and update rev of a recipe. These are the start point of the |
1238 | whole patchset and start point for the patches to be re-generated/updated. | 1184 | whole patchset and start point for the patches to be re-generated/updated. |
1239 | """ | 1185 | """ |
1240 | import bb | 1186 | import bb.process |
1241 | 1187 | ||
1242 | # Get current branch | 1188 | # Get current branch |
1243 | stdout, _ = bb.process.run('git rev-parse --abbrev-ref HEAD', | 1189 | stdout, _ = bb.process.run('git rev-parse --abbrev-ref HEAD', |
@@ -1363,6 +1309,7 @@ def _export_patches(srctree, rd, start_revs, destdir, changed_revs=None): | |||
1363 | """ | 1309 | """ |
1364 | import oe.recipeutils | 1310 | import oe.recipeutils |
1365 | from oe.patch import GitApplyTree | 1311 | from oe.patch import GitApplyTree |
1312 | import bb.process | ||
1366 | updated = OrderedDict() | 1313 | updated = OrderedDict() |
1367 | added = OrderedDict() | 1314 | added = OrderedDict() |
1368 | seqpatch_re = re.compile('^([0-9]{4}-)?(.+)') | 1315 | seqpatch_re = re.compile('^([0-9]{4}-)?(.+)') |
@@ -1384,6 +1331,7 @@ def _export_patches(srctree, rd, start_revs, destdir, changed_revs=None): | |||
1384 | # values, but they ought to be anyway... | 1331 | # values, but they ought to be anyway... |
1385 | new_basename = seqpatch_re.match(new_patch).group(2) | 1332 | new_basename = seqpatch_re.match(new_patch).group(2) |
1386 | match_name = None | 1333 | match_name = None |
1334 | old_patch = None | ||
1387 | for old_patch in existing_patches: | 1335 | for old_patch in existing_patches: |
1388 | old_basename = seqpatch_re.match(old_patch).group(2) | 1336 | old_basename = seqpatch_re.match(old_patch).group(2) |
1389 | old_basename_splitext = os.path.splitext(old_basename) | 1337 | old_basename_splitext = os.path.splitext(old_basename) |
@@ -1432,6 +1380,7 @@ def _export_patches(srctree, rd, start_revs, destdir, changed_revs=None): | |||
1432 | 1380 | ||
1433 | def _create_kconfig_diff(srctree, rd, outfile): | 1381 | def _create_kconfig_diff(srctree, rd, outfile): |
1434 | """Create a kconfig fragment""" | 1382 | """Create a kconfig fragment""" |
1383 | import bb.process | ||
1435 | # Only update config fragment if both config files exist | 1384 | # Only update config fragment if both config files exist |
1436 | orig_config = os.path.join(srctree, '.config.baseline') | 1385 | orig_config = os.path.join(srctree, '.config.baseline') |
1437 | new_config = os.path.join(srctree, '.config.new') | 1386 | new_config = os.path.join(srctree, '.config.new') |
@@ -1469,12 +1418,15 @@ def _export_local_files(srctree, rd, destdir, srctreebase): | |||
1469 | - for removed dict, the absolute path to the existing file in recipe space | 1418 | - for removed dict, the absolute path to the existing file in recipe space |
1470 | """ | 1419 | """ |
1471 | import oe.recipeutils | 1420 | import oe.recipeutils |
1421 | import bb.data | ||
1422 | import bb.process | ||
1472 | 1423 | ||
1473 | # Find out local files (SRC_URI files that exist in the "recipe space"). | 1424 | # Find out local files (SRC_URI files that exist in the "recipe space"). |
1474 | # Local files that reside in srctree are not included in patch generation. | 1425 | # Local files that reside in srctree are not included in patch generation. |
1475 | # Instead they are directly copied over the original source files (in | 1426 | # Instead they are directly copied over the original source files (in |
1476 | # recipe space). | 1427 | # recipe space). |
1477 | existing_files = oe.recipeutils.get_recipe_local_files(rd) | 1428 | existing_files = oe.recipeutils.get_recipe_local_files(rd) |
1429 | |||
1478 | new_set = None | 1430 | new_set = None |
1479 | updated = OrderedDict() | 1431 | updated = OrderedDict() |
1480 | added = OrderedDict() | 1432 | added = OrderedDict() |
@@ -1491,24 +1443,28 @@ def _export_local_files(srctree, rd, destdir, srctreebase): | |||
1491 | if branchname.startswith(override_branch_prefix): | 1443 | if branchname.startswith(override_branch_prefix): |
1492 | return (updated, added, removed) | 1444 | return (updated, added, removed) |
1493 | 1445 | ||
1494 | local_files_dir = os.path.join(srctreebase, 'oe-local-files') | 1446 | files = _git_modified(srctree) |
1495 | git_files = _git_ls_tree(srctree) | 1447 | #if not files: |
1496 | if 'oe-local-files' in git_files: | 1448 | # files = _ls_tree(srctree) |
1497 | # If tracked by Git, take the files from srctree HEAD. First get | 1449 | for f in files: |
1498 | # the tree object of the directory | 1450 | fullfile = os.path.join(srctree, f) |
1499 | tmp_index = os.path.join(srctree, '.git', 'index.tmp.devtool') | 1451 | if os.path.exists(os.path.join(fullfile, ".git")): |
1500 | tree = git_files['oe-local-files'][2] | 1452 | # submodules handled elsewhere |
1501 | bb.process.run(['git', 'checkout', tree, '--', '.'], cwd=srctree, | 1453 | continue |
1502 | env=dict(os.environ, GIT_WORK_TREE=destdir, | 1454 | if f not in existing_files: |
1503 | GIT_INDEX_FILE=tmp_index)) | 1455 | added[f] = {} |
1504 | new_set = list(_git_ls_tree(srctree, tree, True).keys()) | 1456 | if os.path.isdir(os.path.join(srctree, f)): |
1505 | elif os.path.isdir(local_files_dir): | 1457 | shutil.copytree(fullfile, os.path.join(destdir, f)) |
1506 | # If not tracked by Git, just copy from working copy | 1458 | else: |
1507 | new_set = _ls_tree(local_files_dir) | 1459 | shutil.copy2(fullfile, os.path.join(destdir, f)) |
1508 | bb.process.run(['cp', '-ax', | 1460 | elif not os.path.exists(fullfile): |
1509 | os.path.join(local_files_dir, '.'), destdir]) | 1461 | removed[f] = existing_files[f] |
1510 | else: | 1462 | elif f in existing_files: |
1511 | new_set = [] | 1463 | updated[f] = {'path' : existing_files[f]} |
1464 | if os.path.isdir(os.path.join(srctree, f)): | ||
1465 | shutil.copytree(fullfile, os.path.join(destdir, f)) | ||
1466 | else: | ||
1467 | shutil.copy2(fullfile, os.path.join(destdir, f)) | ||
1512 | 1468 | ||
1513 | # Special handling for kernel config | 1469 | # Special handling for kernel config |
1514 | if bb.data.inherits_class('kernel-yocto', rd): | 1470 | if bb.data.inherits_class('kernel-yocto', rd): |
@@ -1516,17 +1472,14 @@ def _export_local_files(srctree, rd, destdir, srctreebase): | |||
1516 | fragment_path = os.path.join(destdir, fragment_fn) | 1472 | fragment_path = os.path.join(destdir, fragment_fn) |
1517 | if _create_kconfig_diff(srctree, rd, fragment_path): | 1473 | if _create_kconfig_diff(srctree, rd, fragment_path): |
1518 | if os.path.exists(fragment_path): | 1474 | if os.path.exists(fragment_path): |
1519 | if fragment_fn not in new_set: | 1475 | if fragment_fn in removed: |
1520 | new_set.append(fragment_fn) | 1476 | del removed[fragment_fn] |
1521 | # Copy fragment to local-files | 1477 | if fragment_fn not in updated and fragment_fn not in added: |
1522 | if os.path.isdir(local_files_dir): | 1478 | added[fragment_fn] = {} |
1523 | shutil.copy2(fragment_path, local_files_dir) | ||
1524 | else: | 1479 | else: |
1525 | if fragment_fn in new_set: | 1480 | if fragment_fn in updated: |
1526 | new_set.remove(fragment_fn) | 1481 | removed[fragment_fn] = updated[fragment_fn] |
1527 | # Remove fragment from local-files | 1482 | del updated[fragment_fn] |
1528 | if os.path.exists(os.path.join(local_files_dir, fragment_fn)): | ||
1529 | os.unlink(os.path.join(local_files_dir, fragment_fn)) | ||
1530 | 1483 | ||
1531 | # Special handling for cml1, ccmake, etc bbclasses that generated | 1484 | # Special handling for cml1, ccmake, etc bbclasses that generated |
1532 | # configuration fragment files that are consumed as source files | 1485 | # configuration fragment files that are consumed as source files |
@@ -1534,42 +1487,13 @@ def _export_local_files(srctree, rd, destdir, srctreebase): | |||
1534 | if bb.data.inherits_class(frag_class, rd): | 1487 | if bb.data.inherits_class(frag_class, rd): |
1535 | srcpath = os.path.join(rd.getVar('WORKDIR'), frag_name) | 1488 | srcpath = os.path.join(rd.getVar('WORKDIR'), frag_name) |
1536 | if os.path.exists(srcpath): | 1489 | if os.path.exists(srcpath): |
1537 | if frag_name not in new_set: | 1490 | if frag_name in removed: |
1538 | new_set.append(frag_name) | 1491 | del removed[frag_name] |
1492 | if frag_name not in updated: | ||
1493 | added[frag_name] = {} | ||
1539 | # copy fragment into destdir | 1494 | # copy fragment into destdir |
1540 | shutil.copy2(srcpath, destdir) | 1495 | shutil.copy2(srcpath, destdir) |
1541 | # copy fragment into local files if exists | 1496 | |
1542 | if os.path.isdir(local_files_dir): | ||
1543 | shutil.copy2(srcpath, local_files_dir) | ||
1544 | |||
1545 | if new_set is not None: | ||
1546 | for fname in new_set: | ||
1547 | if fname in existing_files: | ||
1548 | origpath = existing_files.pop(fname) | ||
1549 | workpath = os.path.join(local_files_dir, fname) | ||
1550 | if not filecmp.cmp(origpath, workpath): | ||
1551 | updated[fname] = {'path' : origpath} | ||
1552 | elif fname != '.gitignore': | ||
1553 | added[fname] = {} | ||
1554 | |||
1555 | workdir = rd.getVar('WORKDIR') | ||
1556 | s = rd.getVar('S') | ||
1557 | if not s.endswith(os.sep): | ||
1558 | s += os.sep | ||
1559 | |||
1560 | if workdir != s: | ||
1561 | # Handle files where subdir= was specified | ||
1562 | for fname in list(existing_files.keys()): | ||
1563 | # FIXME handle both subdir starting with BP and not? | ||
1564 | fworkpath = os.path.join(workdir, fname) | ||
1565 | if fworkpath.startswith(s): | ||
1566 | fpath = os.path.join(srctree, os.path.relpath(fworkpath, s)) | ||
1567 | if os.path.exists(fpath): | ||
1568 | origpath = existing_files.pop(fname) | ||
1569 | if not filecmp.cmp(origpath, fpath): | ||
1570 | updated[fpath] = {'path' : origpath} | ||
1571 | |||
1572 | removed = existing_files | ||
1573 | return (updated, added, removed) | 1497 | return (updated, added, removed) |
1574 | 1498 | ||
1575 | 1499 | ||
@@ -1587,7 +1511,7 @@ def _determine_files_dir(rd): | |||
1587 | 1511 | ||
1588 | def _update_recipe_srcrev(recipename, workspace, srctree, rd, appendlayerdir, wildcard_version, no_remove, no_report_remove, dry_run_outdir=None): | 1512 | def _update_recipe_srcrev(recipename, workspace, srctree, rd, appendlayerdir, wildcard_version, no_remove, no_report_remove, dry_run_outdir=None): |
1589 | """Implement the 'srcrev' mode of update-recipe""" | 1513 | """Implement the 'srcrev' mode of update-recipe""" |
1590 | import bb | 1514 | import bb.process |
1591 | import oe.recipeutils | 1515 | import oe.recipeutils |
1592 | 1516 | ||
1593 | dry_run_suffix = ' (dry-run)' if dry_run_outdir else '' | 1517 | dry_run_suffix = ' (dry-run)' if dry_run_outdir else '' |
@@ -1625,6 +1549,7 @@ def _update_recipe_srcrev(recipename, workspace, srctree, rd, appendlayerdir, wi | |||
1625 | local_files_dir = tempfile.mkdtemp(dir=tempdir) | 1549 | local_files_dir = tempfile.mkdtemp(dir=tempdir) |
1626 | srctreebase = workspace[recipename]['srctreebase'] | 1550 | srctreebase = workspace[recipename]['srctreebase'] |
1627 | upd_f, new_f, del_f = _export_local_files(srctree, rd, local_files_dir, srctreebase) | 1551 | upd_f, new_f, del_f = _export_local_files(srctree, rd, local_files_dir, srctreebase) |
1552 | removedentries = {} | ||
1628 | if not no_remove: | 1553 | if not no_remove: |
1629 | # Find list of existing patches in recipe file | 1554 | # Find list of existing patches in recipe file |
1630 | patches_dir = tempfile.mkdtemp(dir=tempdir) | 1555 | patches_dir = tempfile.mkdtemp(dir=tempdir) |
@@ -1688,7 +1613,6 @@ def _update_recipe_srcrev(recipename, workspace, srctree, rd, appendlayerdir, wi | |||
1688 | 1613 | ||
1689 | def _update_recipe_patch(recipename, workspace, srctree, rd, appendlayerdir, wildcard_version, no_remove, no_report_remove, initial_rev, dry_run_outdir=None, force_patch_refresh=False): | 1614 | def _update_recipe_patch(recipename, workspace, srctree, rd, appendlayerdir, wildcard_version, no_remove, no_report_remove, initial_rev, dry_run_outdir=None, force_patch_refresh=False): |
1690 | """Implement the 'patch' mode of update-recipe""" | 1615 | """Implement the 'patch' mode of update-recipe""" |
1691 | import bb | ||
1692 | import oe.recipeutils | 1616 | import oe.recipeutils |
1693 | 1617 | ||
1694 | recipefile = rd.getVar('FILE') | 1618 | recipefile = rd.getVar('FILE') |
@@ -1802,6 +1726,7 @@ def _update_recipe_patch(recipename, workspace, srctree, rd, appendlayerdir, wil | |||
1802 | for basepath, param in upd_p.items(): | 1726 | for basepath, param in upd_p.items(): |
1803 | path = param['path'] | 1727 | path = param['path'] |
1804 | patchdir = param.get('patchdir', ".") | 1728 | patchdir = param.get('patchdir', ".") |
1729 | patchdir_param = {} | ||
1805 | if patchdir != "." : | 1730 | if patchdir != "." : |
1806 | patchdir_param = dict(patchdir_params) | 1731 | patchdir_param = dict(patchdir_params) |
1807 | if patchdir_param: | 1732 | if patchdir_param: |
@@ -1867,6 +1792,7 @@ def _update_recipe_patch(recipename, workspace, srctree, rd, appendlayerdir, wil | |||
1867 | 1792 | ||
1868 | def _guess_recipe_update_mode(srctree, rdata): | 1793 | def _guess_recipe_update_mode(srctree, rdata): |
1869 | """Guess the recipe update mode to use""" | 1794 | """Guess the recipe update mode to use""" |
1795 | import bb.process | ||
1870 | src_uri = (rdata.getVar('SRC_URI') or '').split() | 1796 | src_uri = (rdata.getVar('SRC_URI') or '').split() |
1871 | git_uris = [uri for uri in src_uri if uri.startswith('git://')] | 1797 | git_uris = [uri for uri in src_uri if uri.startswith('git://')] |
1872 | if not git_uris: | 1798 | if not git_uris: |
@@ -1888,6 +1814,8 @@ def _guess_recipe_update_mode(srctree, rdata): | |||
1888 | return 'patch' | 1814 | return 'patch' |
1889 | 1815 | ||
1890 | def _update_recipe(recipename, workspace, rd, mode, appendlayerdir, wildcard_version, no_remove, initial_rev, no_report_remove=False, dry_run_outdir=None, no_overrides=False, force_patch_refresh=False): | 1816 | def _update_recipe(recipename, workspace, rd, mode, appendlayerdir, wildcard_version, no_remove, initial_rev, no_report_remove=False, dry_run_outdir=None, no_overrides=False, force_patch_refresh=False): |
1817 | import bb.data | ||
1818 | import bb.process | ||
1891 | srctree = workspace[recipename]['srctree'] | 1819 | srctree = workspace[recipename]['srctree'] |
1892 | if mode == 'auto': | 1820 | if mode == 'auto': |
1893 | mode = _guess_recipe_update_mode(srctree, rd) | 1821 | mode = _guess_recipe_update_mode(srctree, rd) |
@@ -2010,6 +1938,7 @@ def status(args, config, basepath, workspace): | |||
2010 | 1938 | ||
2011 | def _reset(recipes, no_clean, remove_work, config, basepath, workspace): | 1939 | def _reset(recipes, no_clean, remove_work, config, basepath, workspace): |
2012 | """Reset one or more recipes""" | 1940 | """Reset one or more recipes""" |
1941 | import bb.process | ||
2013 | import oe.path | 1942 | import oe.path |
2014 | 1943 | ||
2015 | def clean_preferred_provider(pn, layerconf_path): | 1944 | def clean_preferred_provider(pn, layerconf_path): |
@@ -2022,7 +1951,7 @@ def _reset(recipes, no_clean, remove_work, config, basepath, workspace): | |||
2022 | lines = f.readlines() | 1951 | lines = f.readlines() |
2023 | with open(new_layerconf_file, 'a') as nf: | 1952 | with open(new_layerconf_file, 'a') as nf: |
2024 | for line in lines: | 1953 | for line in lines: |
2025 | pprovider_exp = r'^PREFERRED_PROVIDER_.*? = "' + pn + r'"$' | 1954 | pprovider_exp = r'^PREFERRED_PROVIDER_.*? = "' + re.escape(pn) + r'"$' |
2026 | if not re.match(pprovider_exp, line): | 1955 | if not re.match(pprovider_exp, line): |
2027 | nf.write(line) | 1956 | nf.write(line) |
2028 | else: | 1957 | else: |
@@ -2113,8 +2042,6 @@ def _reset(recipes, no_clean, remove_work, config, basepath, workspace): | |||
2113 | 2042 | ||
2114 | def reset(args, config, basepath, workspace): | 2043 | def reset(args, config, basepath, workspace): |
2115 | """Entry point for the devtool 'reset' subcommand""" | 2044 | """Entry point for the devtool 'reset' subcommand""" |
2116 | import bb | ||
2117 | import shutil | ||
2118 | 2045 | ||
2119 | recipes = "" | 2046 | recipes = "" |
2120 | 2047 | ||
@@ -2393,6 +2320,7 @@ def register_commands(subparsers, context): | |||
2393 | parser_modify.add_argument('--branch', '-b', default="devtool", help='Name for development branch to checkout (when not using -n/--no-extract) (default "%(default)s")') | 2320 | parser_modify.add_argument('--branch', '-b', default="devtool", help='Name for development branch to checkout (when not using -n/--no-extract) (default "%(default)s")') |
2394 | parser_modify.add_argument('--no-overrides', '-O', action="store_true", help='Do not create branches for other override configurations') | 2321 | parser_modify.add_argument('--no-overrides', '-O', action="store_true", help='Do not create branches for other override configurations') |
2395 | parser_modify.add_argument('--keep-temp', help='Keep temporary directory (for debugging)', action="store_true") | 2322 | parser_modify.add_argument('--keep-temp', help='Keep temporary directory (for debugging)', action="store_true") |
2323 | parser_modify.add_argument('--debug-build', action="store_true", help='Add DEBUG_BUILD = "1" to the modified recipe') | ||
2396 | parser_modify.set_defaults(func=modify, fixed_setup=context.fixed_setup) | 2324 | parser_modify.set_defaults(func=modify, fixed_setup=context.fixed_setup) |
2397 | 2325 | ||
2398 | parser_extract = subparsers.add_parser('extract', help='Extract the source for an existing recipe', | 2326 | parser_extract = subparsers.add_parser('extract', help='Extract the source for an existing recipe', |