diff options
-rw-r--r-- | meta/classes/devtool-source.bbclass | 56 | ||||
-rw-r--r-- | scripts/lib/devtool/standard.py | 176 | ||||
-rw-r--r-- | scripts/lib/devtool/upgrade.py | 3 |
3 files changed, 209 insertions, 26 deletions
diff --git a/meta/classes/devtool-source.bbclass b/meta/classes/devtool-source.bbclass index 8f5bc86b2e..56882a41d8 100644 --- a/meta/classes/devtool-source.bbclass +++ b/meta/classes/devtool-source.bbclass | |||
@@ -152,9 +152,65 @@ python devtool_pre_patch() { | |||
152 | } | 152 | } |
153 | 153 | ||
154 | python devtool_post_patch() { | 154 | python devtool_post_patch() { |
155 | import shutil | ||
155 | tempdir = d.getVar('DEVTOOL_TEMPDIR') | 156 | tempdir = d.getVar('DEVTOOL_TEMPDIR') |
156 | with open(os.path.join(tempdir, 'srcsubdir'), 'r') as f: | 157 | with open(os.path.join(tempdir, 'srcsubdir'), 'r') as f: |
157 | srcsubdir = f.read() | 158 | srcsubdir = f.read() |
159 | with open(os.path.join(tempdir, 'initial_rev'), 'r') as f: | ||
160 | initial_rev = f.read() | ||
161 | |||
162 | def rm_patches(): | ||
163 | patches_dir = os.path.join(srcsubdir, 'patches') | ||
164 | if os.path.exists(patches_dir): | ||
165 | shutil.rmtree(patches_dir) | ||
166 | # Restore any "patches" directory that was actually part of the source tree | ||
167 | try: | ||
168 | bb.process.run('git checkout -- patches', cwd=srcsubdir) | ||
169 | except bb.process.ExecutionError: | ||
170 | pass | ||
171 | |||
172 | extra_overrides = d.getVar('DEVTOOL_EXTRA_OVERRIDES') | ||
173 | if extra_overrides: | ||
174 | extra_override_list = extra_overrides.split(':') | ||
175 | devbranch = d.getVar('DEVTOOL_DEVBRANCH') | ||
176 | default_overrides = d.getVar('OVERRIDES').split(':') | ||
177 | no_overrides = [] | ||
178 | # First, we may have some overrides that are referred to in the recipe set in | ||
179 | # our configuration, so we need to make a branch that excludes those | ||
180 | for override in default_overrides: | ||
181 | if override not in extra_override_list: | ||
182 | no_overrides.append(override) | ||
183 | if default_overrides != no_overrides: | ||
184 | # Some overrides are active in the current configuration, so | ||
185 | # we need to create a branch where none of the overrides are active | ||
186 | bb.process.run('git checkout %s -b devtool-no-overrides' % initial_rev, cwd=srcsubdir) | ||
187 | # Run do_patch function with the override applied | ||
188 | localdata = bb.data.createCopy(d) | ||
189 | localdata.setVar('OVERRIDES', ':'.join(no_overrides)) | ||
190 | bb.build.exec_func('do_patch', localdata) | ||
191 | rm_patches() | ||
192 | # Now we need to reconcile the dev branch with the no-overrides one | ||
193 | # (otherwise we'd likely be left with identical commits that have different hashes) | ||
194 | bb.process.run('git checkout %s' % devbranch, cwd=srcsubdir) | ||
195 | bb.process.run('git rebase devtool-no-overrides', cwd=srcsubdir) | ||
196 | else: | ||
197 | bb.process.run('git checkout %s -b devtool-no-overrides' % devbranch, cwd=srcsubdir) | ||
198 | |||
199 | for override in extra_override_list: | ||
200 | localdata = bb.data.createCopy(d) | ||
201 | if override in default_overrides: | ||
202 | bb.process.run('git branch devtool-override-%s %s' % (override, devbranch), cwd=srcsubdir) | ||
203 | else: | ||
204 | # Reset back to the initial commit on a new branch | ||
205 | bb.process.run('git checkout %s -b devtool-override-%s' % (initial_rev, override), cwd=srcsubdir) | ||
206 | # Run do_patch function with the override applied | ||
207 | localdata.appendVar('OVERRIDES', ':%s' % override) | ||
208 | bb.build.exec_func('do_patch', localdata) | ||
209 | rm_patches() | ||
210 | # Now we need to reconcile the new branch with the no-overrides one | ||
211 | # (otherwise we'd likely be left with identical commits that have different hashes) | ||
212 | bb.process.run('git rebase devtool-no-overrides', cwd=srcsubdir) | ||
213 | bb.process.run('git checkout %s' % devbranch, cwd=srcsubdir) | ||
158 | bb.process.run('git tag -f devtool-patched', cwd=srcsubdir) | 214 | bb.process.run('git tag -f devtool-patched', cwd=srcsubdir) |
159 | } | 215 | } |
160 | 216 | ||
diff --git a/scripts/lib/devtool/standard.py b/scripts/lib/devtool/standard.py index d55d504a14..26187a0c41 100644 --- a/scripts/lib/devtool/standard.py +++ b/scripts/lib/devtool/standard.py | |||
@@ -35,6 +35,8 @@ from devtool import parse_recipe | |||
35 | 35 | ||
36 | logger = logging.getLogger('devtool') | 36 | logger = logging.getLogger('devtool') |
37 | 37 | ||
38 | override_branch_prefix = 'devtool-override-' | ||
39 | |||
38 | 40 | ||
39 | def add(args, config, basepath, workspace): | 41 | def add(args, config, basepath, workspace): |
40 | """Entry point for the devtool 'add' subcommand""" | 42 | """Entry point for the devtool 'add' subcommand""" |
@@ -425,7 +427,7 @@ def extract(args, config, basepath, workspace): | |||
425 | """Entry point for the devtool 'extract' subcommand""" | 427 | """Entry point for the devtool 'extract' subcommand""" |
426 | import bb | 428 | import bb |
427 | 429 | ||
428 | tinfoil = setup_tinfoil(basepath=basepath) | 430 | tinfoil = setup_tinfoil(basepath=basepath, tracking=True) |
429 | if not tinfoil: | 431 | if not tinfoil: |
430 | # Error already shown | 432 | # Error already shown |
431 | return 1 | 433 | return 1 |
@@ -435,7 +437,7 @@ def extract(args, config, basepath, workspace): | |||
435 | return 1 | 437 | return 1 |
436 | 438 | ||
437 | srctree = os.path.abspath(args.srctree) | 439 | srctree = os.path.abspath(args.srctree) |
438 | initial_rev, _ = _extract_source(srctree, args.keep_temp, args.branch, False, config, basepath, workspace, args.fixed_setup, rd, tinfoil) | 440 | initial_rev, _ = _extract_source(srctree, args.keep_temp, args.branch, False, config, basepath, workspace, args.fixed_setup, rd, tinfoil, no_overrides=args.no_overrides) |
439 | logger.info('Source tree extracted to %s' % srctree) | 441 | logger.info('Source tree extracted to %s' % srctree) |
440 | 442 | ||
441 | if initial_rev: | 443 | if initial_rev: |
@@ -449,7 +451,7 @@ def sync(args, config, basepath, workspace): | |||
449 | """Entry point for the devtool 'sync' subcommand""" | 451 | """Entry point for the devtool 'sync' subcommand""" |
450 | import bb | 452 | import bb |
451 | 453 | ||
452 | tinfoil = setup_tinfoil(basepath=basepath) | 454 | tinfoil = setup_tinfoil(basepath=basepath, tracking=True) |
453 | if not tinfoil: | 455 | if not tinfoil: |
454 | # Error already shown | 456 | # Error already shown |
455 | return 1 | 457 | return 1 |
@@ -459,7 +461,7 @@ def sync(args, config, basepath, workspace): | |||
459 | return 1 | 461 | return 1 |
460 | 462 | ||
461 | srctree = os.path.abspath(args.srctree) | 463 | srctree = os.path.abspath(args.srctree) |
462 | initial_rev, _ = _extract_source(srctree, args.keep_temp, args.branch, True, config, basepath, workspace, args.fixed_setup, rd, tinfoil) | 464 | initial_rev, _ = _extract_source(srctree, args.keep_temp, args.branch, True, config, basepath, workspace, args.fixed_setup, rd, tinfoil, no_overrides=True) |
463 | logger.info('Source tree %s synchronized' % srctree) | 465 | logger.info('Source tree %s synchronized' % srctree) |
464 | 466 | ||
465 | if initial_rev: | 467 | if initial_rev: |
@@ -470,7 +472,7 @@ def sync(args, config, basepath, workspace): | |||
470 | tinfoil.shutdown() | 472 | tinfoil.shutdown() |
471 | 473 | ||
472 | 474 | ||
473 | def _extract_source(srctree, keep_temp, devbranch, sync, config, basepath, workspace, fixed_setup, d, tinfoil): | 475 | def _extract_source(srctree, keep_temp, devbranch, sync, config, basepath, workspace, fixed_setup, d, tinfoil, no_overrides=False): |
474 | """Extract sources of a recipe""" | 476 | """Extract sources of a recipe""" |
475 | import oe.recipeutils | 477 | import oe.recipeutils |
476 | import oe.patch | 478 | import oe.patch |
@@ -500,6 +502,16 @@ def _extract_source(srctree, keep_temp, devbranch, sync, config, basepath, works | |||
500 | bb.utils.mkdirhier(srctree) | 502 | bb.utils.mkdirhier(srctree) |
501 | os.rmdir(srctree) | 503 | os.rmdir(srctree) |
502 | 504 | ||
505 | extra_overrides = [] | ||
506 | if not no_overrides: | ||
507 | history = d.varhistory.variable('SRC_URI') | ||
508 | for event in history: | ||
509 | if not 'flag' in event: | ||
510 | if event['op'].startswith(('_append[', '_prepend[')): | ||
511 | extra_overrides.append(event['op'].split('[')[1].split(']')[0]) | ||
512 | if extra_overrides: | ||
513 | logger.info('SRC_URI contains some conditional appends/prepends - will create branches to represent these') | ||
514 | |||
503 | initial_rev = None | 515 | initial_rev = None |
504 | 516 | ||
505 | appendexisted = False | 517 | appendexisted = False |
@@ -542,6 +554,8 @@ def _extract_source(srctree, keep_temp, devbranch, sync, config, basepath, works | |||
542 | if not is_kernel_yocto: | 554 | if not is_kernel_yocto: |
543 | f.write('PATCHTOOL = "git"\n') | 555 | f.write('PATCHTOOL = "git"\n') |
544 | f.write('PATCH_COMMIT_FUNCTIONS = "1"\n') | 556 | f.write('PATCH_COMMIT_FUNCTIONS = "1"\n') |
557 | if extra_overrides: | ||
558 | f.write('DEVTOOL_EXTRA_OVERRIDES = "%s"\n' % ':'.join(extra_overrides)) | ||
545 | f.write('inherit devtool-source\n') | 559 | f.write('inherit devtool-source\n') |
546 | f.write('###--- _extract_source\n') | 560 | f.write('###--- _extract_source\n') |
547 | 561 | ||
@@ -702,12 +716,13 @@ def modify(args, config, basepath, workspace): | |||
702 | """Entry point for the devtool 'modify' subcommand""" | 716 | """Entry point for the devtool 'modify' subcommand""" |
703 | import bb | 717 | import bb |
704 | import oe.recipeutils | 718 | import oe.recipeutils |
719 | import oe.patch | ||
705 | 720 | ||
706 | if args.recipename in workspace: | 721 | if args.recipename in workspace: |
707 | raise DevtoolError("recipe %s is already in your workspace" % | 722 | raise DevtoolError("recipe %s is already in your workspace" % |
708 | args.recipename) | 723 | args.recipename) |
709 | 724 | ||
710 | tinfoil = setup_tinfoil(basepath=basepath) | 725 | tinfoil = setup_tinfoil(basepath=basepath, tracking=True) |
711 | try: | 726 | try: |
712 | rd = parse_recipe(config, tinfoil, args.recipename, True) | 727 | rd = parse_recipe(config, tinfoil, args.recipename, True) |
713 | if not rd: | 728 | if not rd: |
@@ -742,14 +757,16 @@ def modify(args, config, basepath, workspace): | |||
742 | 757 | ||
743 | initial_rev = None | 758 | initial_rev = None |
744 | commits = [] | 759 | commits = [] |
760 | check_commits = False | ||
745 | if not args.no_extract: | 761 | if not args.no_extract: |
746 | initial_rev, _ = _extract_source(srctree, args.keep_temp, args.branch, False, config, basepath, workspace, args.fixed_setup, rd, tinfoil) | 762 | initial_rev, _ = _extract_source(srctree, args.keep_temp, args.branch, False, config, basepath, workspace, args.fixed_setup, rd, tinfoil, no_overrides=args.no_overrides) |
747 | if not initial_rev: | 763 | if not initial_rev: |
748 | return 1 | 764 | return 1 |
749 | logger.info('Source tree extracted to %s' % srctree) | 765 | logger.info('Source tree extracted to %s' % srctree) |
750 | # Get list of commits since this revision | 766 | # Get list of commits since this revision |
751 | (stdout, _) = bb.process.run('git rev-list --reverse %s..HEAD' % initial_rev, cwd=srctree) | 767 | (stdout, _) = bb.process.run('git rev-list --reverse %s..HEAD' % initial_rev, cwd=srctree) |
752 | commits = stdout.split() | 768 | commits = stdout.split() |
769 | check_commits = True | ||
753 | else: | 770 | else: |
754 | if os.path.exists(os.path.join(srctree, '.git')): | 771 | if os.path.exists(os.path.join(srctree, '.git')): |
755 | # Check if it's a tree previously extracted by us | 772 | # Check if it's a tree previously extracted by us |
@@ -757,6 +774,8 @@ def modify(args, config, basepath, workspace): | |||
757 | (stdout, _) = bb.process.run('git branch --contains devtool-base', cwd=srctree) | 774 | (stdout, _) = bb.process.run('git branch --contains devtool-base', cwd=srctree) |
758 | except bb.process.ExecutionError: | 775 | except bb.process.ExecutionError: |
759 | stdout = '' | 776 | stdout = '' |
777 | if stdout: | ||
778 | check_commits = True | ||
760 | for line in stdout.splitlines(): | 779 | for line in stdout.splitlines(): |
761 | if line.startswith('*'): | 780 | if line.startswith('*'): |
762 | (stdout, _) = bb.process.run('git rev-parse devtool-base', cwd=srctree) | 781 | (stdout, _) = bb.process.run('git rev-parse devtool-base', cwd=srctree) |
@@ -766,6 +785,30 @@ def modify(args, config, basepath, workspace): | |||
766 | (stdout, _) = bb.process.run('git rev-parse HEAD', cwd=srctree) | 785 | (stdout, _) = bb.process.run('git rev-parse HEAD', cwd=srctree) |
767 | initial_rev = stdout.rstrip() | 786 | initial_rev = stdout.rstrip() |
768 | 787 | ||
788 | branch_patches = {} | ||
789 | if check_commits: | ||
790 | # Check if there are override branches | ||
791 | (stdout, _) = bb.process.run('git branch', cwd=srctree) | ||
792 | branches = [] | ||
793 | for line in stdout.rstrip().splitlines(): | ||
794 | branchname = line[2:].rstrip() | ||
795 | if branchname.startswith(override_branch_prefix): | ||
796 | branches.append(branchname) | ||
797 | if branches: | ||
798 | logger.warn('SRC_URI is conditionally overridden in this recipe, thus several %s* branches have been created, one for each override that makes changes to SRC_URI. It is recommended that you make changes to the %s branch first, then checkout and rebase each %s* branch and update any unique patches there (duplicates on those branches will be ignored by devtool finish/update-recipe)' % (override_branch_prefix, args.branch, override_branch_prefix)) | ||
799 | branches.insert(0, args.branch) | ||
800 | seen_patches = [] | ||
801 | for branch in branches: | ||
802 | branch_patches[branch] = [] | ||
803 | (stdout, _) = bb.process.run('git log devtool-base..%s' % branch, cwd=srctree) | ||
804 | for line in stdout.splitlines(): | ||
805 | line = line.strip() | ||
806 | if line.startswith(oe.patch.GitApplyTree.patch_line_prefix): | ||
807 | origpatch = line[len(oe.patch.GitApplyTree.patch_line_prefix):].split(':', 1)[-1].strip() | ||
808 | if not origpatch in seen_patches: | ||
809 | seen_patches.append(origpatch) | ||
810 | branch_patches[branch].append(origpatch) | ||
811 | |||
769 | # Need to grab this here in case the source is within a subdirectory | 812 | # Need to grab this here in case the source is within a subdirectory |
770 | srctreebase = srctree | 813 | srctreebase = srctree |
771 | 814 | ||
@@ -808,6 +851,11 @@ def modify(args, config, basepath, workspace): | |||
808 | f.write('\n# initial_rev: %s\n' % initial_rev) | 851 | f.write('\n# initial_rev: %s\n' % initial_rev) |
809 | for commit in commits: | 852 | for commit in commits: |
810 | f.write('# commit: %s\n' % commit) | 853 | f.write('# commit: %s\n' % commit) |
854 | if branch_patches: | ||
855 | for branch in branch_patches: | ||
856 | if branch == args.branch: | ||
857 | continue | ||
858 | f.write('# patches_%s: %s\n' % (branch, ','.join(branch_patches[branch]))) | ||
811 | 859 | ||
812 | update_unlockedsigs(basepath, workspace, args.fixed_setup, [pn]) | 860 | update_unlockedsigs(basepath, workspace, args.fixed_setup, [pn]) |
813 | 861 | ||
@@ -1019,8 +1067,14 @@ def _get_patchset_revs(srctree, recipe_path, initial_rev=None): | |||
1019 | """ | 1067 | """ |
1020 | import bb | 1068 | import bb |
1021 | 1069 | ||
1070 | # Get current branch | ||
1071 | stdout, _ = bb.process.run('git rev-parse --abbrev-ref HEAD', | ||
1072 | cwd=srctree) | ||
1073 | branchname = stdout.rstrip() | ||
1074 | |||
1022 | # Parse initial rev from recipe if not specified | 1075 | # Parse initial rev from recipe if not specified |
1023 | commits = [] | 1076 | commits = [] |
1077 | patches = [] | ||
1024 | with open(recipe_path, 'r') as f: | 1078 | with open(recipe_path, 'r') as f: |
1025 | for line in f: | 1079 | for line in f: |
1026 | if line.startswith('# initial_rev:'): | 1080 | if line.startswith('# initial_rev:'): |
@@ -1028,6 +1082,8 @@ def _get_patchset_revs(srctree, recipe_path, initial_rev=None): | |||
1028 | initial_rev = line.split(':')[-1].strip() | 1082 | initial_rev = line.split(':')[-1].strip() |
1029 | elif line.startswith('# commit:'): | 1083 | elif line.startswith('# commit:'): |
1030 | commits.append(line.split(':')[-1].strip()) | 1084 | commits.append(line.split(':')[-1].strip()) |
1085 | elif line.startswith('# patches_%s:' % branchname): | ||
1086 | patches = line.split(':')[-1].strip().split(',') | ||
1031 | 1087 | ||
1032 | update_rev = initial_rev | 1088 | update_rev = initial_rev |
1033 | changed_revs = None | 1089 | changed_revs = None |
@@ -1054,7 +1110,7 @@ def _get_patchset_revs(srctree, recipe_path, initial_rev=None): | |||
1054 | if rev in newcommits: | 1110 | if rev in newcommits: |
1055 | changed_revs.append(rev) | 1111 | changed_revs.append(rev) |
1056 | 1112 | ||
1057 | return initial_rev, update_rev, changed_revs | 1113 | return initial_rev, update_rev, changed_revs, patches |
1058 | 1114 | ||
1059 | def _remove_file_entries(srcuri, filelist): | 1115 | def _remove_file_entries(srcuri, filelist): |
1060 | """Remove file:// entries from SRC_URI""" | 1116 | """Remove file:// entries from SRC_URI""" |
@@ -1126,6 +1182,7 @@ def _export_patches(srctree, rd, start_rev, destdir, changed_revs=None): | |||
1126 | 1182 | ||
1127 | existing_patches = dict((os.path.basename(path), path) for path in | 1183 | existing_patches = dict((os.path.basename(path), path) for path in |
1128 | oe.recipeutils.get_recipe_patches(rd)) | 1184 | oe.recipeutils.get_recipe_patches(rd)) |
1185 | logger.debug('Existing patches: %s' % existing_patches) | ||
1129 | 1186 | ||
1130 | # Generate patches from Git, exclude local files directory | 1187 | # Generate patches from Git, exclude local files directory |
1131 | patch_pathspec = _git_exclude_path(srctree, 'oe-local-files') | 1188 | patch_pathspec = _git_exclude_path(srctree, 'oe-local-files') |
@@ -1414,7 +1471,7 @@ def _update_recipe_patch(recipename, workspace, srctree, rd, appendlayerdir, wil | |||
1414 | raise DevtoolError('unable to find workspace bbappend for recipe %s' % | 1471 | raise DevtoolError('unable to find workspace bbappend for recipe %s' % |
1415 | recipename) | 1472 | recipename) |
1416 | 1473 | ||
1417 | initial_rev, update_rev, changed_revs = _get_patchset_revs(srctree, append, initial_rev) | 1474 | initial_rev, update_rev, changed_revs, filter_patches = _get_patchset_revs(srctree, append, initial_rev) |
1418 | if not initial_rev: | 1475 | if not initial_rev: |
1419 | raise DevtoolError('Unable to find initial revision - please specify ' | 1476 | raise DevtoolError('Unable to find initial revision - please specify ' |
1420 | 'it with --initial-rev') | 1477 | 'it with --initial-rev') |
@@ -1429,22 +1486,32 @@ def _update_recipe_patch(recipename, workspace, srctree, rd, appendlayerdir, wil | |||
1429 | tempdir = tempfile.mkdtemp(prefix='devtool') | 1486 | tempdir = tempfile.mkdtemp(prefix='devtool') |
1430 | try: | 1487 | try: |
1431 | local_files_dir = tempfile.mkdtemp(dir=tempdir) | 1488 | local_files_dir = tempfile.mkdtemp(dir=tempdir) |
1432 | srctreebase = workspace[recipename]['srctreebase'] | 1489 | if filter_patches: |
1433 | upd_f, new_f, del_f = _export_local_files(srctree, rd, local_files_dir, srctreebase) | 1490 | upd_f = {} |
1491 | new_f = {} | ||
1492 | del_f = {} | ||
1493 | else: | ||
1494 | srctreebase = workspace[recipename]['srctreebase'] | ||
1495 | upd_f, new_f, del_f = _export_local_files(srctree, rd, local_files_dir, srctreebase) | ||
1434 | 1496 | ||
1435 | remove_files = [] | 1497 | remove_files = [] |
1436 | if not no_remove: | 1498 | if not no_remove: |
1437 | # Get all patches from source tree and check if any should be removed | 1499 | # Get all patches from source tree and check if any should be removed |
1438 | all_patches_dir = tempfile.mkdtemp(dir=tempdir) | 1500 | all_patches_dir = tempfile.mkdtemp(dir=tempdir) |
1439 | upd_p, new_p, del_p = _export_patches(srctree, rd, initial_rev, | 1501 | _, _, del_p = _export_patches(srctree, rd, initial_rev, |
1440 | all_patches_dir) | 1502 | all_patches_dir) |
1441 | # Remove deleted local files and patches | 1503 | # Remove deleted local files and patches |
1442 | remove_files = list(del_f.values()) + list(del_p.values()) | 1504 | remove_files = list(del_f.values()) + list(del_p.values()) |
1443 | 1505 | ||
1444 | # Get updated patches from source tree | 1506 | # Get updated patches from source tree |
1445 | patches_dir = tempfile.mkdtemp(dir=tempdir) | 1507 | patches_dir = tempfile.mkdtemp(dir=tempdir) |
1446 | upd_p, new_p, del_p = _export_patches(srctree, rd, update_rev, | 1508 | upd_p, new_p, _ = _export_patches(srctree, rd, update_rev, |
1447 | patches_dir, changed_revs) | 1509 | patches_dir, changed_revs) |
1510 | logger.debug('Pre-filtering: update: %s, new: %s' % (dict(upd_p), dict(new_p))) | ||
1511 | if filter_patches: | ||
1512 | new_p = {} | ||
1513 | upd_p = {k:v for k,v in upd_p.items() if k in filter_patches} | ||
1514 | remove_files = [f for f in remove_files if f in filter_patches] | ||
1448 | updatefiles = False | 1515 | updatefiles = False |
1449 | updaterecipe = False | 1516 | updaterecipe = False |
1450 | destpath = None | 1517 | destpath = None |
@@ -1556,18 +1623,73 @@ def _guess_recipe_update_mode(srctree, rdata): | |||
1556 | 1623 | ||
1557 | return 'patch' | 1624 | return 'patch' |
1558 | 1625 | ||
1559 | def _update_recipe(recipename, workspace, rd, mode, appendlayerdir, wildcard_version, no_remove, initial_rev, no_report_remove=False, dry_run_outdir=None): | 1626 | 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): |
1560 | srctree = workspace[recipename]['srctree'] | 1627 | srctree = workspace[recipename]['srctree'] |
1561 | if mode == 'auto': | 1628 | if mode == 'auto': |
1562 | mode = _guess_recipe_update_mode(srctree, rd) | 1629 | mode = _guess_recipe_update_mode(srctree, rd) |
1563 | 1630 | ||
1564 | if mode == 'srcrev': | 1631 | override_branches = [] |
1565 | updated, appendfile, removed = _update_recipe_srcrev(recipename, workspace, srctree, rd, appendlayerdir, wildcard_version, no_remove, no_report_remove, dry_run_outdir) | 1632 | mainbranch = None |
1566 | elif mode == 'patch': | 1633 | startbranch = None |
1567 | updated, appendfile, removed = _update_recipe_patch(recipename, workspace, srctree, rd, appendlayerdir, wildcard_version, no_remove, no_report_remove, initial_rev, dry_run_outdir) | 1634 | if not no_overrides: |
1568 | else: | 1635 | stdout, _ = bb.process.run('git branch', cwd=srctree) |
1569 | raise DevtoolError('update_recipe: invalid mode %s' % mode) | 1636 | other_branches = [] |
1570 | return updated, appendfile, removed | 1637 | for line in stdout.splitlines(): |
1638 | branchname = line[2:] | ||
1639 | if line.startswith('* '): | ||
1640 | startbranch = branchname | ||
1641 | if branchname.startswith(override_branch_prefix): | ||
1642 | override_branches.append(branchname) | ||
1643 | else: | ||
1644 | other_branches.append(branchname) | ||
1645 | |||
1646 | if override_branches: | ||
1647 | logger.debug('_update_recipe: override branches: %s' % override_branches) | ||
1648 | logger.debug('_update_recipe: other branches: %s' % other_branches) | ||
1649 | if startbranch.startswith(override_branch_prefix): | ||
1650 | if len(other_branches) == 1: | ||
1651 | mainbranch = other_branches[1] | ||
1652 | else: | ||
1653 | raise DevtoolError('Unable to determine main branch - please check out the main branch in source tree first') | ||
1654 | else: | ||
1655 | mainbranch = startbranch | ||
1656 | |||
1657 | checkedout = None | ||
1658 | anyupdated = False | ||
1659 | appendfile = None | ||
1660 | allremoved = [] | ||
1661 | if override_branches: | ||
1662 | logger.info('Handling main branch (%s)...' % mainbranch) | ||
1663 | if startbranch != mainbranch: | ||
1664 | bb.process.run('git checkout %s' % mainbranch, cwd=srctree) | ||
1665 | checkedout = mainbranch | ||
1666 | try: | ||
1667 | branchlist = [mainbranch] + override_branches | ||
1668 | for branch in branchlist: | ||
1669 | crd = bb.data.createCopy(rd) | ||
1670 | if branch != mainbranch: | ||
1671 | logger.info('Handling branch %s...' % branch) | ||
1672 | override = branch[len(override_branch_prefix):] | ||
1673 | crd.appendVar('OVERRIDES', ':%s' % override) | ||
1674 | bb.process.run('git checkout %s' % branch, cwd=srctree) | ||
1675 | checkedout = branch | ||
1676 | |||
1677 | if mode == 'srcrev': | ||
1678 | updated, appendf, removed = _update_recipe_srcrev(recipename, workspace, srctree, crd, appendlayerdir, wildcard_version, no_remove, no_report_remove, dry_run_outdir) | ||
1679 | elif mode == 'patch': | ||
1680 | updated, appendf, removed = _update_recipe_patch(recipename, workspace, srctree, crd, appendlayerdir, wildcard_version, no_remove, no_report_remove, initial_rev, dry_run_outdir) | ||
1681 | else: | ||
1682 | raise DevtoolError('update_recipe: invalid mode %s' % mode) | ||
1683 | if updated: | ||
1684 | anyupdated = True | ||
1685 | if appendf: | ||
1686 | appendfile = appendf | ||
1687 | allremoved.extend(removed) | ||
1688 | finally: | ||
1689 | if startbranch and checkedout != startbranch: | ||
1690 | bb.process.run('git checkout %s' % startbranch, cwd=srctree) | ||
1691 | |||
1692 | return anyupdated, appendfile, allremoved | ||
1571 | 1693 | ||
1572 | def update_recipe(args, config, basepath, workspace): | 1694 | def update_recipe(args, config, basepath, workspace): |
1573 | """Entry point for the devtool 'update-recipe' subcommand""" | 1695 | """Entry point for the devtool 'update-recipe' subcommand""" |
@@ -1593,7 +1715,7 @@ def update_recipe(args, config, basepath, workspace): | |||
1593 | if args.dry_run: | 1715 | if args.dry_run: |
1594 | dry_run_output = tempfile.TemporaryDirectory(prefix='devtool') | 1716 | dry_run_output = tempfile.TemporaryDirectory(prefix='devtool') |
1595 | dry_run_outdir = dry_run_output.name | 1717 | dry_run_outdir = dry_run_output.name |
1596 | updated, _, _ = _update_recipe(args.recipename, workspace, rd, args.mode, args.append, args.wildcard_version, args.no_remove, args.initial_rev, dry_run_outdir=dry_run_outdir) | 1718 | updated, _, _ = _update_recipe(args.recipename, workspace, rd, args.mode, args.append, args.wildcard_version, args.no_remove, args.initial_rev, dry_run_outdir=dry_run_outdir, no_overrides=args.no_overrides) |
1597 | 1719 | ||
1598 | if updated: | 1720 | if updated: |
1599 | rf = rd.getVar('FILE') | 1721 | rf = rd.getVar('FILE') |
@@ -1816,7 +1938,7 @@ def finish(args, config, basepath, workspace): | |||
1816 | if args.dry_run: | 1938 | if args.dry_run: |
1817 | dry_run_output = tempfile.TemporaryDirectory(prefix='devtool') | 1939 | dry_run_output = tempfile.TemporaryDirectory(prefix='devtool') |
1818 | dry_run_outdir = dry_run_output.name | 1940 | dry_run_outdir = dry_run_output.name |
1819 | updated, appendfile, removed = _update_recipe(args.recipename, workspace, rd, args.mode, appendlayerdir, wildcard_version=True, no_remove=False, no_report_remove=removing_original, initial_rev=args.initial_rev, dry_run_outdir=dry_run_outdir) | 1941 | updated, appendfile, removed = _update_recipe(args.recipename, workspace, rd, args.mode, appendlayerdir, wildcard_version=True, no_remove=False, no_report_remove=removing_original, initial_rev=args.initial_rev, dry_run_outdir=dry_run_outdir, no_overrides=args.no_overrides) |
1820 | removed = [os.path.relpath(pth, recipedir) for pth in removed] | 1942 | removed = [os.path.relpath(pth, recipedir) for pth in removed] |
1821 | 1943 | ||
1822 | # Remove any old files in the case of an upgrade | 1944 | # Remove any old files in the case of an upgrade |
@@ -1959,6 +2081,7 @@ def register_commands(subparsers, context): | |||
1959 | group.add_argument('--same-dir', '-s', help='Build in same directory as source', action="store_true") | 2081 | group.add_argument('--same-dir', '-s', help='Build in same directory as source', action="store_true") |
1960 | group.add_argument('--no-same-dir', help='Force build in a separate build directory', action="store_true") | 2082 | group.add_argument('--no-same-dir', help='Force build in a separate build directory', action="store_true") |
1961 | parser_modify.add_argument('--branch', '-b', default="devtool", help='Name for development branch to checkout (when not using -n/--no-extract) (default "%(default)s")') | 2083 | parser_modify.add_argument('--branch', '-b', default="devtool", help='Name for development branch to checkout (when not using -n/--no-extract) (default "%(default)s")') |
2084 | parser_modify.add_argument('--no-overrides', '-O', action="store_true", help='Do not create branches for other override configurations') | ||
1962 | parser_modify.add_argument('--keep-temp', help='Keep temporary directory (for debugging)', action="store_true") | 2085 | parser_modify.add_argument('--keep-temp', help='Keep temporary directory (for debugging)', action="store_true") |
1963 | parser_modify.set_defaults(func=modify, fixed_setup=context.fixed_setup) | 2086 | parser_modify.set_defaults(func=modify, fixed_setup=context.fixed_setup) |
1964 | 2087 | ||
@@ -1968,6 +2091,7 @@ def register_commands(subparsers, context): | |||
1968 | parser_extract.add_argument('recipename', help='Name of recipe to extract the source for') | 2091 | parser_extract.add_argument('recipename', help='Name of recipe to extract the source for') |
1969 | parser_extract.add_argument('srctree', help='Path to where to extract the source tree') | 2092 | parser_extract.add_argument('srctree', help='Path to where to extract the source tree') |
1970 | parser_extract.add_argument('--branch', '-b', default="devtool", help='Name for development branch to checkout (default "%(default)s")') | 2093 | parser_extract.add_argument('--branch', '-b', default="devtool", help='Name for development branch to checkout (default "%(default)s")') |
2094 | parser_extract.add_argument('--no-overrides', '-O', action="store_true", help='Do not create branches for other override configurations') | ||
1971 | parser_extract.add_argument('--keep-temp', action="store_true", help='Keep temporary directory (for debugging)') | 2095 | parser_extract.add_argument('--keep-temp', action="store_true", help='Keep temporary directory (for debugging)') |
1972 | parser_extract.set_defaults(func=extract, fixed_setup=context.fixed_setup) | 2096 | parser_extract.set_defaults(func=extract, fixed_setup=context.fixed_setup) |
1973 | 2097 | ||
@@ -1999,6 +2123,7 @@ def register_commands(subparsers, context): | |||
1999 | parser_update_recipe.add_argument('--append', '-a', help='Write changes to a bbappend in the specified layer instead of the recipe', metavar='LAYERDIR') | 2123 | parser_update_recipe.add_argument('--append', '-a', help='Write changes to a bbappend in the specified layer instead of the recipe', metavar='LAYERDIR') |
2000 | 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') | 2124 | 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') |
2001 | parser_update_recipe.add_argument('--no-remove', '-n', action="store_true", help='Don\'t remove patches, only add or update') | 2125 | parser_update_recipe.add_argument('--no-remove', '-n', action="store_true", help='Don\'t remove patches, only add or update') |
2126 | parser_update_recipe.add_argument('--no-overrides', '-O', action="store_true", help='Do not handle other override branches (if they exist)') | ||
2002 | parser_update_recipe.add_argument('--dry-run', '-N', action="store_true", help='Dry-run (just report changes instead of writing them)') | 2127 | parser_update_recipe.add_argument('--dry-run', '-N', action="store_true", help='Dry-run (just report changes instead of writing them)') |
2003 | parser_update_recipe.set_defaults(func=update_recipe) | 2128 | parser_update_recipe.set_defaults(func=update_recipe) |
2004 | 2129 | ||
@@ -2023,5 +2148,6 @@ def register_commands(subparsers, context): | |||
2023 | parser_finish.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') | 2148 | parser_finish.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') |
2024 | parser_finish.add_argument('--initial-rev', help='Override starting revision for patches') | 2149 | parser_finish.add_argument('--initial-rev', help='Override starting revision for patches') |
2025 | parser_finish.add_argument('--force', '-f', action="store_true", help='Force continuing even if there are uncommitted changes in the source tree repository') | 2150 | parser_finish.add_argument('--force', '-f', action="store_true", help='Force continuing even if there are uncommitted changes in the source tree repository') |
2151 | parser_finish.add_argument('--no-overrides', '-O', action="store_true", help='Do not handle other override branches (if they exist)') | ||
2026 | parser_finish.add_argument('--dry-run', '-N', action="store_true", help='Dry-run (just report changes instead of writing them)') | 2152 | parser_finish.add_argument('--dry-run', '-N', action="store_true", help='Dry-run (just report changes instead of writing them)') |
2027 | parser_finish.set_defaults(func=finish) | 2153 | parser_finish.set_defaults(func=finish) |
diff --git a/scripts/lib/devtool/upgrade.py b/scripts/lib/devtool/upgrade.py index 3cb523c2f4..f6141bfdc3 100644 --- a/scripts/lib/devtool/upgrade.py +++ b/scripts/lib/devtool/upgrade.py | |||
@@ -474,7 +474,7 @@ def upgrade(args, config, basepath, workspace): | |||
474 | rf = None | 474 | rf = None |
475 | try: | 475 | try: |
476 | logger.info('Extracting current version source...') | 476 | logger.info('Extracting current version source...') |
477 | rev1, srcsubdir1 = standard._extract_source(srctree, False, 'devtool-orig', False, config, basepath, workspace, args.fixed_setup, rd, tinfoil) | 477 | rev1, srcsubdir1 = standard._extract_source(srctree, False, 'devtool-orig', False, config, basepath, workspace, args.fixed_setup, rd, tinfoil, no_overrides=args.no_overrides) |
478 | logger.info('Extracting upgraded version source...') | 478 | logger.info('Extracting upgraded version source...') |
479 | rev2, md5, sha256, srcbranch, srcsubdir2 = _extract_new_source(args.version, srctree, args.no_patch, | 479 | rev2, md5, sha256, srcbranch, srcsubdir2 = _extract_new_source(args.version, srctree, args.no_patch, |
480 | args.srcrev, args.srcbranch, args.branch, args.keep_temp, | 480 | args.srcrev, args.srcbranch, args.branch, args.keep_temp, |
@@ -513,6 +513,7 @@ def register_commands(subparsers, context): | |||
513 | parser_upgrade.add_argument('--srcbranch', '-B', help='Branch in source repository containing the revision to use (if fetching from an SCM such as git)') | 513 | parser_upgrade.add_argument('--srcbranch', '-B', help='Branch in source repository containing the revision to use (if fetching from an SCM such as git)') |
514 | parser_upgrade.add_argument('--branch', '-b', default="devtool", help='Name for new development branch to checkout (default "%(default)s")') | 514 | parser_upgrade.add_argument('--branch', '-b', default="devtool", help='Name for new development branch to checkout (default "%(default)s")') |
515 | parser_upgrade.add_argument('--no-patch', action="store_true", help='Do not apply patches from the recipe to the new source code') | 515 | parser_upgrade.add_argument('--no-patch', action="store_true", help='Do not apply patches from the recipe to the new source code') |
516 | parser_upgrade.add_argument('--no-overrides', '-O', action="store_true", help='Do not create branches for other override configurations') | ||
516 | group = parser_upgrade.add_mutually_exclusive_group() | 517 | group = parser_upgrade.add_mutually_exclusive_group() |
517 | group.add_argument('--same-dir', '-s', help='Build in same directory as source', action="store_true") | 518 | group.add_argument('--same-dir', '-s', help='Build in same directory as source', action="store_true") |
518 | group.add_argument('--no-same-dir', help='Force build in a separate build directory', action="store_true") | 519 | group.add_argument('--no-same-dir', help='Force build in a separate build directory', action="store_true") |