summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJulien Stephan <jstephan@baylibre.com>2023-11-22 12:08:16 +0100
committerRichard Purdie <richard.purdie@linuxfoundation.org>2023-12-01 11:48:25 +0000
commit89f16624842a91e063dc9e6b98787d44c55e4900 (patch)
treec22ebb7b7f5ff89d3ed8431e8dcace59678b9ed3
parent17427db136491f13b0c9f187906ce9e3f6c85b29 (diff)
downloadpoky-89f16624842a91e063dc9e6b98787d44c55e4900.tar.gz
devtool: add support for git submodules
Adding the support of submodules required a lot of changes on the internal data structures: * initial_rev/startcommit used as a starting point for looking at new / updated commits was replaced by a dictionary where the keys are the submodule name ("." for main repo) and the values are the initial_rev/startcommit * the extractPatches function now extracts patch for the main repo and for all submodules and stores them in a hierarchical way describing the submodule path * store initial_rev/commit also for all submodules inside the recipe bbappend file * _export_patches now returns dictionaries that contains the 'patchdir' parameter (if any). This parameter is used to add the correct 'patchdir=' parameter on the recipe Also, recipe can extract a secondary git tree inside the workdir. By default, at the end of the do_patch function, there is a hook in devtool that commits everything that was modified to have a clean repository. It uses the command: "git add .; git commit ..." The issue here is that, it adds the secondary git tree as a submodule but in a wrong way. Doing "git add <git dir>" declares a submodule but do not adds a url associated to it, and all following "git submodule foreach" commands will fail. So detect that a git tree was extracted inside S and correctly add it using "git submodule add <url> <path>", so that it will be considered as a regular git submodule (From OE-Core rev: 900129cbdf25297a42ab5dbd02d1adbea405c935) Signed-off-by: Julien Stephan <jstephan@baylibre.com> Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
-rw-r--r--meta/lib/oe/patch.py64
-rw-r--r--meta/lib/oe/recipeutils.py27
-rw-r--r--scripts/lib/devtool/__init__.py21
-rw-r--r--scripts/lib/devtool/standard.py269
-rw-r--r--scripts/lib/devtool/upgrade.py51
-rw-r--r--scripts/lib/recipetool/append.py4
6 files changed, 270 insertions, 166 deletions
diff --git a/meta/lib/oe/patch.py b/meta/lib/oe/patch.py
index 9b480b2b28..e4bb5a7839 100644
--- a/meta/lib/oe/patch.py
+++ b/meta/lib/oe/patch.py
@@ -461,41 +461,43 @@ class GitApplyTree(PatchTree):
461 return (tmpfile, cmd) 461 return (tmpfile, cmd)
462 462
463 @staticmethod 463 @staticmethod
464 def extractPatches(tree, startcommit, outdir, paths=None): 464 def extractPatches(tree, startcommits, outdir, paths=None):
465 import tempfile 465 import tempfile
466 import shutil 466 import shutil
467 tempdir = tempfile.mkdtemp(prefix='oepatch') 467 tempdir = tempfile.mkdtemp(prefix='oepatch')
468 try: 468 try:
469 shellcmd = ["git", "format-patch", "--no-signature", "--no-numbered", startcommit, "-o", tempdir] 469 for name, rev in startcommits.items():
470 if paths: 470 shellcmd = ["git", "format-patch", "--no-signature", "--no-numbered", rev, "-o", tempdir]
471 shellcmd.append('--') 471 if paths:
472 shellcmd.extend(paths) 472 shellcmd.append('--')
473 out = runcmd(["sh", "-c", " ".join(shellcmd)], tree) 473 shellcmd.extend(paths)
474 if out: 474 out = runcmd(["sh", "-c", " ".join(shellcmd)], os.path.join(tree, name))
475 for srcfile in out.split(): 475 if out:
476 for encoding in ['utf-8', 'latin-1']: 476 for srcfile in out.split():
477 patchlines = [] 477 for encoding in ['utf-8', 'latin-1']:
478 outfile = None 478 patchlines = []
479 try: 479 outfile = None
480 with open(srcfile, 'r', encoding=encoding) as f: 480 try:
481 for line in f: 481 with open(srcfile, 'r', encoding=encoding) as f:
482 if line.startswith(GitApplyTree.patch_line_prefix): 482 for line in f:
483 outfile = line.split()[-1].strip() 483 if line.startswith(GitApplyTree.patch_line_prefix):
484 continue 484 outfile = line.split()[-1].strip()
485 if line.startswith(GitApplyTree.ignore_commit_prefix): 485 continue
486 continue 486 if line.startswith(GitApplyTree.ignore_commit_prefix):
487 patchlines.append(line) 487 continue
488 except UnicodeDecodeError: 488 patchlines.append(line)
489 continue 489 except UnicodeDecodeError:
490 break 490 continue
491 else: 491 break
492 raise PatchError('Unable to find a character encoding to decode %s' % srcfile) 492 else:
493 493 raise PatchError('Unable to find a character encoding to decode %s' % srcfile)
494 if not outfile: 494
495 outfile = os.path.basename(srcfile) 495 if not outfile:
496 with open(os.path.join(outdir, outfile), 'w') as of: 496 outfile = os.path.basename(srcfile)
497 for line in patchlines: 497 bb.utils.mkdirhier(os.path.join(outdir, name))
498 of.write(line) 498 with open(os.path.join(outdir, name, outfile), 'w') as of:
499 for line in patchlines:
500 of.write(line)
499 finally: 501 finally:
500 shutil.rmtree(tempdir) 502 shutil.rmtree(tempdir)
501 503
diff --git a/meta/lib/oe/recipeutils.py b/meta/lib/oe/recipeutils.py
index 695e981623..25b159bc1b 100644
--- a/meta/lib/oe/recipeutils.py
+++ b/meta/lib/oe/recipeutils.py
@@ -672,11 +672,11 @@ def bbappend_recipe(rd, destlayerdir, srcfiles, install=None, wildcardver=False,
672 destlayerdir: base directory of the layer to place the bbappend in 672 destlayerdir: base directory of the layer to place the bbappend in
673 (subdirectory path from there will be determined automatically) 673 (subdirectory path from there will be determined automatically)
674 srcfiles: dict of source files to add to SRC_URI, where the value 674 srcfiles: dict of source files to add to SRC_URI, where the value
675 is the full path to the file to be added, and the value is the 675 is the full path to the file to be added, and the value is a
676 original filename as it would appear in SRC_URI or None if it 676 dict with 'path' key containing the original filename as it
677 isn't already present. You may pass None for this parameter if 677 would appear in SRC_URI or None if it isn't already present.
678 you simply want to specify your own content via the extralines 678 You may pass None for this parameter if you simply want to specify
679 parameter. 679 your own content via the extralines parameter.
680 install: dict mapping entries in srcfiles to a tuple of two elements: 680 install: dict mapping entries in srcfiles to a tuple of two elements:
681 install path (*without* ${D} prefix) and permission value (as a 681 install path (*without* ${D} prefix) and permission value (as a
682 string, e.g. '0644'). 682 string, e.g. '0644').
@@ -763,10 +763,9 @@ def bbappend_recipe(rd, destlayerdir, srcfiles, install=None, wildcardver=False,
763 copyfiles = {} 763 copyfiles = {}
764 if srcfiles: 764 if srcfiles:
765 instfunclines = [] 765 instfunclines = []
766 for i, (newfile, origsrcfile) in enumerate(srcfiles.items()): 766 for i, (newfile, param) in enumerate(srcfiles.items()):
767 srcfile = origsrcfile
768 srcurientry = None 767 srcurientry = None
769 if not srcfile: 768 if not 'path' in param or not param['path']:
770 srcfile = os.path.basename(newfile) 769 srcfile = os.path.basename(newfile)
771 srcurientry = 'file://%s' % srcfile 770 srcurientry = 'file://%s' % srcfile
772 if params and params[i]: 771 if params and params[i]:
@@ -778,7 +777,10 @@ def bbappend_recipe(rd, destlayerdir, srcfiles, install=None, wildcardver=False,
778 appendline('SRC_URI:append%s' % appendoverride, '=', ' ' + srcurientry) 777 appendline('SRC_URI:append%s' % appendoverride, '=', ' ' + srcurientry)
779 else: 778 else:
780 appendline('SRC_URI', '+=', srcurientry) 779 appendline('SRC_URI', '+=', srcurientry)
781 copyfiles[newfile] = srcfile 780 param['path'] = srcfile
781 else:
782 srcfile = param['path']
783 copyfiles[newfile] = param
782 if install: 784 if install:
783 institem = install.pop(newfile, None) 785 institem = install.pop(newfile, None)
784 if institem: 786 if institem:
@@ -901,7 +903,12 @@ def bbappend_recipe(rd, destlayerdir, srcfiles, install=None, wildcardver=False,
901 outdir = redirect_output 903 outdir = redirect_output
902 else: 904 else:
903 outdir = appenddir 905 outdir = appenddir
904 for newfile, srcfile in copyfiles.items(): 906 for newfile, param in copyfiles.items():
907 srcfile = param['path']
908 patchdir = param.get('patchdir', ".")
909
910 if patchdir != ".":
911 newfile = os.path.join(os.path.split(newfile)[0], patchdir, os.path.split(newfile)[1])
905 filedest = os.path.join(outdir, destsubdir, os.path.basename(srcfile)) 912 filedest = os.path.join(outdir, destsubdir, os.path.basename(srcfile))
906 if os.path.abspath(newfile) != os.path.abspath(filedest): 913 if os.path.abspath(newfile) != os.path.abspath(filedest):
907 if newfile.startswith(tempfile.gettempdir()): 914 if newfile.startswith(tempfile.gettempdir()):
diff --git a/scripts/lib/devtool/__init__.py b/scripts/lib/devtool/__init__.py
index e9e88a5533..b4f998a5bc 100644
--- a/scripts/lib/devtool/__init__.py
+++ b/scripts/lib/devtool/__init__.py
@@ -233,6 +233,27 @@ def setup_git_repo(repodir, version, devbranch, basetag='devtool-base', d=None):
233 bb.process.run('git checkout -b %s' % devbranch, cwd=repodir) 233 bb.process.run('git checkout -b %s' % devbranch, cwd=repodir)
234 bb.process.run('git tag -f %s' % basetag, cwd=repodir) 234 bb.process.run('git tag -f %s' % basetag, cwd=repodir)
235 235
236 # if recipe unpacks another git repo inside S, we need to declare it as a regular git submodule now,
237 # so we will be able to tag branches on it and extract patches when doing finish/update on the recipe
238 stdout, _ = bb.process.run("git status --porcelain", cwd=repodir)
239 found = False
240 for line in stdout.splitlines():
241 if line.endswith("/"):
242 new_dir = line.split()[1]
243 for root, dirs, files in os.walk(os.path.join(repodir, new_dir)):
244 if ".git" in dirs + files:
245 (stdout, _) = bb.process.run('git remote', cwd=root)
246 remote = stdout.splitlines()[0]
247 (stdout, _) = bb.process.run('git remote get-url %s' % remote, cwd=root)
248 remote_url = stdout.splitlines()[0]
249 logger.error(os.path.relpath(os.path.join(root, ".."), root))
250 bb.process.run('git submodule add %s %s' % (remote_url, os.path.relpath(root, os.path.join(root, ".."))), cwd=os.path.join(root, ".."))
251 found = True
252 if found:
253 useroptions = []
254 oe.patch.GitApplyTree.gitCommandUserOptions(useroptions, d=d)
255 bb.process.run('git %s commit -m "Adding additionnal submodule from SRC_URI\n\n%s"' % (' '.join(useroptions), oe.patch.GitApplyTree.ignore_commit_prefix), cwd=os.path.join(root, ".."))
256 found = False
236 if os.path.exists(os.path.join(repodir, '.gitmodules')): 257 if os.path.exists(os.path.join(repodir, '.gitmodules')):
237 bb.process.run('git submodule foreach --recursive "git tag -f %s"' % basetag, cwd=repodir) 258 bb.process.run('git submodule foreach --recursive "git tag -f %s"' % basetag, cwd=repodir)
238 259
diff --git a/scripts/lib/devtool/standard.py b/scripts/lib/devtool/standard.py
index 55fa38ccfb..ad6e346279 100644
--- a/scripts/lib/devtool/standard.py
+++ b/scripts/lib/devtool/standard.py
@@ -234,10 +234,14 @@ def add(args, config, basepath, workspace):
234 if args.fetchuri and not args.no_git: 234 if args.fetchuri and not args.no_git:
235 setup_git_repo(srctree, args.version, 'devtool', d=tinfoil.config_data) 235 setup_git_repo(srctree, args.version, 'devtool', d=tinfoil.config_data)
236 236
237 initial_rev = None 237 initial_rev = {}
238 if os.path.exists(os.path.join(srctree, '.git')): 238 if os.path.exists(os.path.join(srctree, '.git')):
239 (stdout, _) = bb.process.run('git rev-parse HEAD', cwd=srctree) 239 (stdout, _) = bb.process.run('git rev-parse HEAD', cwd=srctree)
240 initial_rev = stdout.rstrip() 240 initial_rev["."] = stdout.rstrip()
241 (stdout, _) = bb.process.run('git submodule --quiet foreach --recursive \'echo `git rev-parse HEAD` $PWD\'', cwd=srctree)
242 for line in stdout.splitlines():
243 (rev, submodule) = line.split()
244 initial_rev[os.path.relpath(submodule, srctree)] = rev
241 245
242 if args.src_subdir: 246 if args.src_subdir:
243 srctree = os.path.join(srctree, args.src_subdir) 247 srctree = os.path.join(srctree, args.src_subdir)
@@ -251,7 +255,8 @@ def add(args, config, basepath, workspace):
251 if b_is_s: 255 if b_is_s:
252 f.write('EXTERNALSRC_BUILD = "%s"\n' % srctree) 256 f.write('EXTERNALSRC_BUILD = "%s"\n' % srctree)
253 if initial_rev: 257 if initial_rev:
254 f.write('\n# initial_rev: %s\n' % initial_rev) 258 for key, value in initial_rev.items():
259 f.write('\n# initial_rev %s: %s\n' % (key, value))
255 260
256 if args.binary: 261 if args.binary:
257 f.write('do_install:append() {\n') 262 f.write('do_install:append() {\n')
@@ -823,8 +828,8 @@ def modify(args, config, basepath, workspace):
823 828
824 _check_compatible_recipe(pn, rd) 829 _check_compatible_recipe(pn, rd)
825 830
826 initial_rev = None 831 initial_revs = {}
827 commits = [] 832 commits = {}
828 check_commits = False 833 check_commits = False
829 834
830 if bb.data.inherits_class('kernel-yocto', rd): 835 if bb.data.inherits_class('kernel-yocto', rd):
@@ -880,15 +885,23 @@ def modify(args, config, basepath, workspace):
880 args.no_extract = True 885 args.no_extract = True
881 886
882 if not args.no_extract: 887 if not args.no_extract:
883 initial_rev, _ = _extract_source(srctree, args.keep_temp, args.branch, False, config, basepath, workspace, args.fixed_setup, rd, tinfoil, no_overrides=args.no_overrides) 888 initial_revs["."], _ = _extract_source(srctree, args.keep_temp, args.branch, False, config, basepath, workspace, args.fixed_setup, rd, tinfoil, no_overrides=args.no_overrides)
884 if not initial_rev: 889 if not initial_revs["."]:
885 return 1 890 return 1
886 logger.info('Source tree extracted to %s' % srctree) 891 logger.info('Source tree extracted to %s' % srctree)
892
887 if os.path.exists(os.path.join(srctree, '.git')): 893 if os.path.exists(os.path.join(srctree, '.git')):
888 # Get list of commits since this revision 894 # Get list of commits since this revision
889 (stdout, _) = bb.process.run('git rev-list --reverse %s..HEAD' % initial_rev, cwd=srctree) 895 (stdout, _) = bb.process.run('git rev-list --reverse %s..HEAD' % initial_revs["."], cwd=srctree)
890 commits = stdout.split() 896 commits["."] = stdout.split()
891 check_commits = True 897 check_commits = True
898 (stdout, _) = bb.process.run('git submodule --quiet foreach --recursive \'echo `git rev-parse devtool-base` $PWD\'', cwd=srctree)
899 for line in stdout.splitlines():
900 (rev, submodule_path) = line.split()
901 submodule = os.path.relpath(submodule_path, srctree)
902 initial_revs[submodule] = rev
903 (stdout, _) = bb.process.run('git rev-list --reverse devtool-base..HEAD', cwd=submodule_path)
904 commits[submodule] = stdout.split()
892 else: 905 else:
893 if os.path.exists(os.path.join(srctree, '.git')): 906 if os.path.exists(os.path.join(srctree, '.git')):
894 # Check if it's a tree previously extracted by us. This is done 907 # Check if it's a tree previously extracted by us. This is done
@@ -905,11 +918,11 @@ def modify(args, config, basepath, workspace):
905 for line in stdout.splitlines(): 918 for line in stdout.splitlines():
906 if line.startswith('*'): 919 if line.startswith('*'):
907 (stdout, _) = bb.process.run('git rev-parse devtool-base', cwd=srctree) 920 (stdout, _) = bb.process.run('git rev-parse devtool-base', cwd=srctree)
908 initial_rev = stdout.rstrip() 921 initial_revs["."] = stdout.rstrip()
909 if not initial_rev: 922 if not initial_revs["."]:
910 # Otherwise, just grab the head revision 923 # Otherwise, just grab the head revision
911 (stdout, _) = bb.process.run('git rev-parse HEAD', cwd=srctree) 924 (stdout, _) = bb.process.run('git rev-parse HEAD', cwd=srctree)
912 initial_rev = stdout.rstrip() 925 initial_revs["."] = stdout.rstrip()
913 926
914 branch_patches = {} 927 branch_patches = {}
915 if check_commits: 928 if check_commits:
@@ -976,10 +989,11 @@ def modify(args, config, basepath, workspace):
976 ' ln -sfT ${KCONFIG_CONFIG_ROOTDIR}/.config ${S}/.config.new\n' 989 ' ln -sfT ${KCONFIG_CONFIG_ROOTDIR}/.config ${S}/.config.new\n'
977 ' fi\n' 990 ' fi\n'
978 '}\n') 991 '}\n')
979 if initial_rev: 992 if initial_revs:
980 f.write('\n# initial_rev: %s\n' % initial_rev) 993 for name, rev in initial_revs.items():
981 for commit in commits: 994 f.write('\n# initial_rev %s: %s\n' % (name, rev))
982 f.write('# commit: %s\n' % commit) 995 for commit in commits[name]:
996 f.write('# commit %s: %s\n' % (name, commit))
983 if branch_patches: 997 if branch_patches:
984 for branch in branch_patches: 998 for branch in branch_patches:
985 if branch == args.branch: 999 if branch == args.branch:
@@ -1202,44 +1216,56 @@ def _get_patchset_revs(srctree, recipe_path, initial_rev=None, force_patch_refre
1202 branchname = stdout.rstrip() 1216 branchname = stdout.rstrip()
1203 1217
1204 # Parse initial rev from recipe if not specified 1218 # Parse initial rev from recipe if not specified
1205 commits = [] 1219 commits = {}
1206 patches = [] 1220 patches = []
1221 initial_revs = {}
1207 with open(recipe_path, 'r') as f: 1222 with open(recipe_path, 'r') as f:
1208 for line in f: 1223 for line in f:
1209 if line.startswith('# initial_rev:'): 1224 pattern = r'^#\s.*\s(.*):\s([0-9a-fA-F]+)$'
1210 if not initial_rev: 1225 match = re.search(pattern, line)
1211 initial_rev = line.split(':')[-1].strip() 1226 if match:
1212 elif line.startswith('# commit:') and not force_patch_refresh: 1227 name = match.group(1)
1213 commits.append(line.split(':')[-1].strip()) 1228 rev = match.group(2)
1214 elif line.startswith('# patches_%s:' % branchname): 1229 if line.startswith('# initial_rev'):
1215 patches = line.split(':')[-1].strip().split(',') 1230 if not (name == "." and initial_rev):
1216 1231 initial_revs[name] = rev
1217 update_rev = initial_rev 1232 elif line.startswith('# commit') and not force_patch_refresh:
1218 changed_revs = None 1233 if name not in commits:
1219 if initial_rev: 1234 commits[name] = [rev]
1235 else:
1236 commits[name].append(rev)
1237 elif line.startswith('# patches_%s:' % branchname):
1238 patches = line.split(':')[-1].strip().split(',')
1239
1240 update_revs = dict(initial_revs)
1241 changed_revs = {}
1242 for name, rev in initial_revs.items():
1220 # Find first actually changed revision 1243 # Find first actually changed revision
1221 stdout, _ = bb.process.run('git rev-list --reverse %s..HEAD' % 1244 stdout, _ = bb.process.run('git rev-list --reverse %s..HEAD' %
1222 initial_rev, cwd=srctree) 1245 rev, cwd=os.path.join(srctree, name))
1223 newcommits = stdout.split() 1246 newcommits = stdout.split()
1224 for i in range(min(len(commits), len(newcommits))): 1247 if name in commits:
1225 if newcommits[i] == commits[i]: 1248 for i in range(min(len(commits[name]), len(newcommits))):
1226 update_rev = commits[i] 1249 if newcommits[i] == commits[name][i]:
1250 update_revs[name] = commits[name][i]
1227 1251
1228 try: 1252 try:
1229 stdout, _ = bb.process.run('git cherry devtool-patched', 1253 stdout, _ = bb.process.run('git cherry devtool-patched',
1230 cwd=srctree) 1254 cwd=os.path.join(srctree, name))
1231 except bb.process.ExecutionError as err: 1255 except bb.process.ExecutionError as err:
1232 stdout = None 1256 stdout = None
1233 1257
1234 if stdout is not None and not force_patch_refresh: 1258 if stdout is not None and not force_patch_refresh:
1235 changed_revs = []
1236 for line in stdout.splitlines(): 1259 for line in stdout.splitlines():
1237 if line.startswith('+ '): 1260 if line.startswith('+ '):
1238 rev = line.split()[1] 1261 rev = line.split()[1]
1239 if rev in newcommits: 1262 if rev in newcommits:
1240 changed_revs.append(rev) 1263 if name not in changed_revs:
1264 changed_revs[name] = [rev]
1265 else:
1266 changed_revs[name].append(rev)
1241 1267
1242 return initial_rev, update_rev, changed_revs, patches 1268 return initial_revs, update_revs, changed_revs, patches
1243 1269
1244def _remove_file_entries(srcuri, filelist): 1270def _remove_file_entries(srcuri, filelist):
1245 """Remove file:// entries from SRC_URI""" 1271 """Remove file:// entries from SRC_URI"""
@@ -1294,14 +1320,17 @@ def _remove_source_files(append, files, destpath, no_report_remove=False, dry_ru
1294 raise 1320 raise
1295 1321
1296 1322
1297def _export_patches(srctree, rd, start_rev, destdir, changed_revs=None): 1323def _export_patches(srctree, rd, start_revs, destdir, changed_revs=None):
1298 """Export patches from srctree to given location. 1324 """Export patches from srctree to given location.
1299 Returns three-tuple of dicts: 1325 Returns three-tuple of dicts:
1300 1. updated - patches that already exist in SRCURI 1326 1. updated - patches that already exist in SRCURI
1301 2. added - new patches that don't exist in SRCURI 1327 2. added - new patches that don't exist in SRCURI
1302 3 removed - patches that exist in SRCURI but not in exported patches 1328 3 removed - patches that exist in SRCURI but not in exported patches
1303 In each dict the key is the 'basepath' of the URI and value is the 1329 In each dict the key is the 'basepath' of the URI and value is:
1304 absolute path to the existing file in recipe space (if any). 1330 - for updated and added dicts, a dict with 2 optionnal keys:
1331 - 'path': the absolute path to the existing file in recipe space (if any)
1332 - 'patchdir': the directory in wich the patch should be applied (if any)
1333 - for removed dict, the absolute path to the existing file in recipe space
1305 """ 1334 """
1306 import oe.recipeutils 1335 import oe.recipeutils
1307 from oe.patch import GitApplyTree 1336 from oe.patch import GitApplyTree
@@ -1315,54 +1344,60 @@ def _export_patches(srctree, rd, start_rev, destdir, changed_revs=None):
1315 1344
1316 # Generate patches from Git, exclude local files directory 1345 # Generate patches from Git, exclude local files directory
1317 patch_pathspec = _git_exclude_path(srctree, 'oe-local-files') 1346 patch_pathspec = _git_exclude_path(srctree, 'oe-local-files')
1318 GitApplyTree.extractPatches(srctree, start_rev, destdir, patch_pathspec) 1347 GitApplyTree.extractPatches(srctree, start_revs, destdir, patch_pathspec)
1319 1348 for dirpath, dirnames, filenames in os.walk(destdir):
1320 new_patches = sorted(os.listdir(destdir)) 1349 new_patches = filenames
1321 for new_patch in new_patches: 1350 reldirpath = os.path.relpath(dirpath, destdir)
1322 # Strip numbering from patch names. If it's a git sequence named patch, 1351 for new_patch in new_patches:
1323 # the numbers might not match up since we are starting from a different 1352 # Strip numbering from patch names. If it's a git sequence named patch,
1324 # revision This does assume that people are using unique shortlog 1353 # the numbers might not match up since we are starting from a different
1325 # values, but they ought to be anyway... 1354 # revision This does assume that people are using unique shortlog
1326 new_basename = seqpatch_re.match(new_patch).group(2) 1355 # values, but they ought to be anyway...
1327 match_name = None 1356 new_basename = seqpatch_re.match(new_patch).group(2)
1328 for old_patch in existing_patches: 1357 match_name = None
1329 old_basename = seqpatch_re.match(old_patch).group(2) 1358 for old_patch in existing_patches:
1330 old_basename_splitext = os.path.splitext(old_basename) 1359 old_basename = seqpatch_re.match(old_patch).group(2)
1331 if old_basename.endswith(('.gz', '.bz2', '.Z')) and old_basename_splitext[0] == new_basename: 1360 old_basename_splitext = os.path.splitext(old_basename)
1332 old_patch_noext = os.path.splitext(old_patch)[0] 1361 if old_basename.endswith(('.gz', '.bz2', '.Z')) and old_basename_splitext[0] == new_basename:
1333 match_name = old_patch_noext 1362 old_patch_noext = os.path.splitext(old_patch)[0]
1334 break 1363 match_name = old_patch_noext
1335 elif new_basename == old_basename: 1364 break
1336 match_name = old_patch 1365 elif new_basename == old_basename:
1337 break 1366 match_name = old_patch
1338 if match_name: 1367 break
1339 # Rename patch files 1368 if match_name:
1340 if new_patch != match_name: 1369 # Rename patch files
1341 bb.utils.rename(os.path.join(destdir, new_patch), 1370 if new_patch != match_name:
1342 os.path.join(destdir, match_name)) 1371 bb.utils.rename(os.path.join(destdir, new_patch),
1343 # Need to pop it off the list now before checking changed_revs 1372 os.path.join(destdir, match_name))
1344 oldpath = existing_patches.pop(old_patch) 1373 # Need to pop it off the list now before checking changed_revs
1345 if changed_revs is not None: 1374 oldpath = existing_patches.pop(old_patch)
1346 # Avoid updating patches that have not actually changed 1375 if changed_revs is not None and dirpath in changed_revs:
1347 with open(os.path.join(destdir, match_name), 'r') as f: 1376 # Avoid updating patches that have not actually changed
1348 firstlineitems = f.readline().split() 1377 with open(os.path.join(dirpath, match_name), 'r') as f:
1349 # Looking for "From <hash>" line 1378 firstlineitems = f.readline().split()
1350 if len(firstlineitems) > 1 and len(firstlineitems[1]) == 40: 1379 # Looking for "From <hash>" line
1351 if not firstlineitems[1] in changed_revs: 1380 if len(firstlineitems) > 1 and len(firstlineitems[1]) == 40:
1352 continue 1381 if not firstlineitems[1] in changed_revs[dirpath]:
1353 # Recompress if necessary 1382 continue
1354 if oldpath.endswith(('.gz', '.Z')): 1383 # Recompress if necessary
1355 bb.process.run(['gzip', match_name], cwd=destdir) 1384 if oldpath.endswith(('.gz', '.Z')):
1356 if oldpath.endswith('.gz'): 1385 bb.process.run(['gzip', match_name], cwd=destdir)
1357 match_name += '.gz' 1386 if oldpath.endswith('.gz'):
1358 else: 1387 match_name += '.gz'
1359 match_name += '.Z' 1388 else:
1360 elif oldpath.endswith('.bz2'): 1389 match_name += '.Z'
1361 bb.process.run(['bzip2', match_name], cwd=destdir) 1390 elif oldpath.endswith('.bz2'):
1362 match_name += '.bz2' 1391 bb.process.run(['bzip2', match_name], cwd=destdir)
1363 updated[match_name] = oldpath 1392 match_name += '.bz2'
1364 else: 1393 updated[match_name] = {'path' : oldpath}
1365 added[new_patch] = None 1394 if reldirpath != ".":
1395 updated[match_name]['patchdir'] = reldirpath
1396 else:
1397 added[new_patch] = {}
1398 if reldirpath != ".":
1399 added[new_patch]['patchdir'] = reldirpath
1400
1366 return (updated, added, existing_patches) 1401 return (updated, added, existing_patches)
1367 1402
1368 1403
@@ -1534,6 +1569,7 @@ def _update_recipe_srcrev(recipename, workspace, srctree, rd, appendlayerdir, wi
1534 old_srcrev = rd.getVar('SRCREV') or '' 1569 old_srcrev = rd.getVar('SRCREV') or ''
1535 if old_srcrev == "INVALID": 1570 if old_srcrev == "INVALID":
1536 raise DevtoolError('Update mode srcrev is only valid for recipe fetched from an SCM repository') 1571 raise DevtoolError('Update mode srcrev is only valid for recipe fetched from an SCM repository')
1572 old_srcrev = {'.': old_srcrev}
1537 1573
1538 # Get HEAD revision 1574 # Get HEAD revision
1539 try: 1575 try:
@@ -1566,7 +1602,7 @@ def _update_recipe_srcrev(recipename, workspace, srctree, rd, appendlayerdir, wi
1566 logger.debug('Patches: update %s, new %s, delete %s' % (dict(upd_p), dict(new_p), dict(del_p))) 1602 logger.debug('Patches: update %s, new %s, delete %s' % (dict(upd_p), dict(new_p), dict(del_p)))
1567 1603
1568 # Remove deleted local files and "overlapping" patches 1604 # Remove deleted local files and "overlapping" patches
1569 remove_files = list(del_f.values()) + list(upd_p.values()) + list(del_p.values()) 1605 remove_files = list(del_f.values()) + [value["path"] for value in upd_p.values() if "path" in value] + [value["path"] for value in del_p.values() if "path" in value]
1570 if remove_files: 1606 if remove_files:
1571 removedentries = _remove_file_entries(srcuri, remove_files)[0] 1607 removedentries = _remove_file_entries(srcuri, remove_files)[0]
1572 update_srcuri = True 1608 update_srcuri = True
@@ -1635,15 +1671,15 @@ def _update_recipe_patch(recipename, workspace, srctree, rd, appendlayerdir, wil
1635 else: 1671 else:
1636 patchdir_params = {'patchdir': relpatchdir} 1672 patchdir_params = {'patchdir': relpatchdir}
1637 1673
1638 def srcuri_entry(basepath): 1674 def srcuri_entry(basepath, patchdir_params):
1639 if patchdir_params: 1675 if patchdir_params:
1640 paramstr = ';' + ';'.join('%s=%s' % (k,v) for k,v in patchdir_params.items()) 1676 paramstr = ';' + ';'.join('%s=%s' % (k,v) for k,v in patchdir_params.items())
1641 else: 1677 else:
1642 paramstr = '' 1678 paramstr = ''
1643 return 'file://%s%s' % (basepath, paramstr) 1679 return 'file://%s%s' % (basepath, paramstr)
1644 1680
1645 initial_rev, update_rev, changed_revs, filter_patches = _get_patchset_revs(srctree, append, initial_rev, force_patch_refresh) 1681 initial_revs, update_revs, changed_revs, filter_patches = _get_patchset_revs(srctree, append, initial_rev, force_patch_refresh)
1646 if not initial_rev: 1682 if not initial_revs:
1647 raise DevtoolError('Unable to find initial revision - please specify ' 1683 raise DevtoolError('Unable to find initial revision - please specify '
1648 'it with --initial-rev') 1684 'it with --initial-rev')
1649 1685
@@ -1661,11 +1697,11 @@ def _update_recipe_patch(recipename, workspace, srctree, rd, appendlayerdir, wil
1661 1697
1662 # Get updated patches from source tree 1698 # Get updated patches from source tree
1663 patches_dir = tempfile.mkdtemp(dir=tempdir) 1699 patches_dir = tempfile.mkdtemp(dir=tempdir)
1664 upd_p, new_p, _ = _export_patches(srctree, rd, update_rev, 1700 upd_p, new_p, _ = _export_patches(srctree, rd, update_revs,
1665 patches_dir, changed_revs) 1701 patches_dir, changed_revs)
1666 # Get all patches from source tree and check if any should be removed 1702 # Get all patches from source tree and check if any should be removed
1667 all_patches_dir = tempfile.mkdtemp(dir=tempdir) 1703 all_patches_dir = tempfile.mkdtemp(dir=tempdir)
1668 _, _, del_p = _export_patches(srctree, rd, initial_rev, 1704 _, _, del_p = _export_patches(srctree, rd, initial_revs,
1669 all_patches_dir) 1705 all_patches_dir)
1670 logger.debug('Pre-filtering: update: %s, new: %s' % (dict(upd_p), dict(new_p))) 1706 logger.debug('Pre-filtering: update: %s, new: %s' % (dict(upd_p), dict(new_p)))
1671 if filter_patches: 1707 if filter_patches:
@@ -1680,18 +1716,31 @@ def _update_recipe_patch(recipename, workspace, srctree, rd, appendlayerdir, wil
1680 updaterecipe = False 1716 updaterecipe = False
1681 destpath = None 1717 destpath = None
1682 srcuri = (rd.getVar('SRC_URI', False) or '').split() 1718 srcuri = (rd.getVar('SRC_URI', False) or '').split()
1719
1683 if appendlayerdir: 1720 if appendlayerdir:
1684 files = OrderedDict((os.path.join(local_files_dir, key), val) for 1721 files = OrderedDict((os.path.join(local_files_dir, key), val) for
1685 key, val in list(upd_f.items()) + list(new_f.items())) 1722 key, val in list(upd_f.items()) + list(new_f.items()))
1686 files.update(OrderedDict((os.path.join(patches_dir, key), val) for 1723 files.update(OrderedDict((os.path.join(patches_dir, key), val) for
1687 key, val in list(upd_p.items()) + list(new_p.items()))) 1724 key, val in list(upd_p.items()) + list(new_p.items())))
1725
1726 params = []
1727 for file, param in files.items():
1728 patchdir_param = dict(patchdir_params)
1729 patchdir = param.get('patchdir', ".")
1730 if patchdir != "." :
1731 if patchdir_param:
1732 patchdir_param['patchdir'] += patchdir
1733 else:
1734 patchdir_param['patchdir'] = patchdir
1735 params.append(patchdir_param)
1736
1688 if files or remove_files: 1737 if files or remove_files:
1689 removevalues = None 1738 removevalues = None
1690 if remove_files: 1739 if remove_files:
1691 removedentries, remaining = _remove_file_entries( 1740 removedentries, remaining = _remove_file_entries(
1692 srcuri, remove_files) 1741 srcuri, remove_files)
1693 if removedentries or remaining: 1742 if removedentries or remaining:
1694 remaining = [srcuri_entry(os.path.basename(item)) for 1743 remaining = [srcuri_entry(os.path.basename(item), patchdir_params) for
1695 item in remaining] 1744 item in remaining]
1696 removevalues = {'SRC_URI': removedentries + remaining} 1745 removevalues = {'SRC_URI': removedentries + remaining}
1697 appendfile, destpath = oe.recipeutils.bbappend_recipe( 1746 appendfile, destpath = oe.recipeutils.bbappend_recipe(
@@ -1699,7 +1748,7 @@ def _update_recipe_patch(recipename, workspace, srctree, rd, appendlayerdir, wil
1699 wildcardver=wildcard_version, 1748 wildcardver=wildcard_version,
1700 removevalues=removevalues, 1749 removevalues=removevalues,
1701 redirect_output=dry_run_outdir, 1750 redirect_output=dry_run_outdir,
1702 params=[patchdir_params] * len(files)) 1751 params=params)
1703 else: 1752 else:
1704 logger.info('No patches or local source files needed updating') 1753 logger.info('No patches or local source files needed updating')
1705 else: 1754 else:
@@ -1716,14 +1765,22 @@ def _update_recipe_patch(recipename, workspace, srctree, rd, appendlayerdir, wil
1716 _move_file(os.path.join(local_files_dir, basepath), path, 1765 _move_file(os.path.join(local_files_dir, basepath), path,
1717 dry_run_outdir=dry_run_outdir, base_outdir=recipedir) 1766 dry_run_outdir=dry_run_outdir, base_outdir=recipedir)
1718 updatefiles = True 1767 updatefiles = True
1719 for basepath, path in upd_p.items(): 1768 for basepath, param in upd_p.items():
1720 patchfn = os.path.join(patches_dir, basepath) 1769 path = param['path']
1770 patchdir = param.get('patchdir', ".")
1771 if patchdir != "." :
1772 patchdir_param = dict(patchdir_params)
1773 if patchdir_param:
1774 patchdir_param['patchdir'] += patchdir
1775 else:
1776 patchdir_param['patchdir'] = patchdir
1777 patchfn = os.path.join(patches_dir, patchdir, basepath)
1721 if os.path.dirname(path) + '/' == dl_dir: 1778 if os.path.dirname(path) + '/' == dl_dir:
1722 # This is a a downloaded patch file - we now need to 1779 # This is a a downloaded patch file - we now need to
1723 # replace the entry in SRC_URI with our local version 1780 # replace the entry in SRC_URI with our local version
1724 logger.info('Replacing remote patch %s with updated local version' % basepath) 1781 logger.info('Replacing remote patch %s with updated local version' % basepath)
1725 path = os.path.join(files_dir, basepath) 1782 path = os.path.join(files_dir, basepath)
1726 _replace_srcuri_entry(srcuri, basepath, srcuri_entry(basepath)) 1783 _replace_srcuri_entry(srcuri, basepath, srcuri_entry(basepath, patchdir_param))
1727 updaterecipe = True 1784 updaterecipe = True
1728 else: 1785 else:
1729 logger.info('Updating patch %s%s' % (basepath, dry_run_suffix)) 1786 logger.info('Updating patch %s%s' % (basepath, dry_run_suffix))
@@ -1737,15 +1794,23 @@ def _update_recipe_patch(recipename, workspace, srctree, rd, appendlayerdir, wil
1737 os.path.join(files_dir, basepath), 1794 os.path.join(files_dir, basepath),
1738 dry_run_outdir=dry_run_outdir, 1795 dry_run_outdir=dry_run_outdir,
1739 base_outdir=recipedir) 1796 base_outdir=recipedir)
1740 srcuri.append(srcuri_entry(basepath)) 1797 srcuri.append(srcuri_entry(basepath, patchdir_params))
1741 updaterecipe = True 1798 updaterecipe = True
1742 for basepath, path in new_p.items(): 1799 for basepath, param in new_p.items():
1800 patchdir = param.get('patchdir', ".")
1743 logger.info('Adding new patch %s%s' % (basepath, dry_run_suffix)) 1801 logger.info('Adding new patch %s%s' % (basepath, dry_run_suffix))
1744 _move_file(os.path.join(patches_dir, basepath), 1802 _move_file(os.path.join(patches_dir, patchdir, basepath),
1745 os.path.join(files_dir, basepath), 1803 os.path.join(files_dir, basepath),
1746 dry_run_outdir=dry_run_outdir, 1804 dry_run_outdir=dry_run_outdir,
1747 base_outdir=recipedir) 1805 base_outdir=recipedir)
1748 srcuri.append(srcuri_entry(basepath)) 1806 params = dict(patchdir_params)
1807 if patchdir != "." :
1808 if params:
1809 params['patchdir'] += patchdir
1810 else:
1811 params['patchdir'] = patchdir
1812
1813 srcuri.append(srcuri_entry(basepath, params))
1749 updaterecipe = True 1814 updaterecipe = True
1750 # Update recipe, if needed 1815 # Update recipe, if needed
1751 if _remove_file_entries(srcuri, remove_files)[0]: 1816 if _remove_file_entries(srcuri, remove_files)[0]:
diff --git a/scripts/lib/devtool/upgrade.py b/scripts/lib/devtool/upgrade.py
index 9cd50be3a2..10827a762b 100644
--- a/scripts/lib/devtool/upgrade.py
+++ b/scripts/lib/devtool/upgrade.py
@@ -90,7 +90,7 @@ def _rename_recipe_files(oldrecipe, bpn, oldpv, newpv, path):
90 _rename_recipe_dirs(oldpv, newpv, path) 90 _rename_recipe_dirs(oldpv, newpv, path)
91 return _rename_recipe_file(oldrecipe, bpn, oldpv, newpv, path) 91 return _rename_recipe_file(oldrecipe, bpn, oldpv, newpv, path)
92 92
93def _write_append(rc, srctreebase, srctree, same_dir, no_same_dir, rev, copied, workspace, d): 93def _write_append(rc, srctreebase, srctree, same_dir, no_same_dir, revs, copied, workspace, d):
94 """Writes an append file""" 94 """Writes an append file"""
95 if not os.path.exists(rc): 95 if not os.path.exists(rc):
96 raise DevtoolError("bbappend not created because %s does not exist" % rc) 96 raise DevtoolError("bbappend not created because %s does not exist" % rc)
@@ -119,8 +119,9 @@ def _write_append(rc, srctreebase, srctree, same_dir, no_same_dir, rev, copied,
119 if b_is_s: 119 if b_is_s:
120 f.write('EXTERNALSRC_BUILD:pn-%s = "%s"\n' % (pn, srctree)) 120 f.write('EXTERNALSRC_BUILD:pn-%s = "%s"\n' % (pn, srctree))
121 f.write('\n') 121 f.write('\n')
122 if rev: 122 if revs:
123 f.write('# initial_rev: %s\n' % rev) 123 for name, rev in revs.items():
124 f.write('# initial_rev %s: %s\n' % (name, rev))
124 if copied: 125 if copied:
125 f.write('# original_path: %s\n' % os.path.dirname(d.getVar('FILE'))) 126 f.write('# original_path: %s\n' % os.path.dirname(d.getVar('FILE')))
126 f.write('# original_files: %s\n' % ' '.join(copied)) 127 f.write('# original_files: %s\n' % ' '.join(copied))
@@ -182,10 +183,15 @@ def _extract_new_source(newpv, srctree, no_patch, srcrev, srcbranch, branch, kee
182 uri, rev = _get_uri(crd) 183 uri, rev = _get_uri(crd)
183 if srcrev: 184 if srcrev:
184 rev = srcrev 185 rev = srcrev
186 paths = [srctree]
185 if uri.startswith('git://') or uri.startswith('gitsm://'): 187 if uri.startswith('git://') or uri.startswith('gitsm://'):
186 __run('git fetch') 188 __run('git fetch')
187 __run('git checkout %s' % rev) 189 __run('git checkout %s' % rev)
188 __run('git tag -f devtool-base-new') 190 __run('git tag -f devtool-base-new')
191 __run('git submodule update --recursive')
192 __run('git submodule foreach \'git tag -f devtool-base-new\'')
193 (stdout, _) = __run('git submodule --quiet foreach \'echo $sm_path\'')
194 paths += [os.path.join(srctree, p) for p in stdout.splitlines()]
189 md5 = None 195 md5 = None
190 sha256 = None 196 sha256 = None
191 _, _, _, _, _, params = bb.fetch2.decodeurl(uri) 197 _, _, _, _, _, params = bb.fetch2.decodeurl(uri)
@@ -256,29 +262,32 @@ def _extract_new_source(newpv, srctree, no_patch, srcrev, srcbranch, branch, kee
256 __run('git %s commit -q -m "Commit of upstream changes at version %s" --allow-empty' % (' '.join(useroptions), newpv)) 262 __run('git %s commit -q -m "Commit of upstream changes at version %s" --allow-empty' % (' '.join(useroptions), newpv))
257 __run('git tag -f devtool-base-%s' % newpv) 263 __run('git tag -f devtool-base-%s' % newpv)
258 264
259 (stdout, _) = __run('git rev-parse HEAD') 265 revs = {}
260 rev = stdout.rstrip() 266 for path in paths:
267 (stdout, _) = _run('git rev-parse HEAD', cwd=path)
268 revs[os.path.relpath(path,srctree)] = stdout.rstrip()
261 269
262 if no_patch: 270 if no_patch:
263 patches = oe.recipeutils.get_recipe_patches(crd) 271 patches = oe.recipeutils.get_recipe_patches(crd)
264 if patches: 272 if patches:
265 logger.warning('By user choice, the following patches will NOT be applied to the new source tree:\n %s' % '\n '.join([os.path.basename(patch) for patch in patches])) 273 logger.warning('By user choice, the following patches will NOT be applied to the new source tree:\n %s' % '\n '.join([os.path.basename(patch) for patch in patches]))
266 else: 274 else:
267 __run('git checkout devtool-patched -b %s' % branch) 275 for path in paths:
268 (stdout, _) = __run('git branch --list devtool-override-*') 276 _run('git checkout devtool-patched -b %s' % branch, cwd=path)
269 branches_to_rebase = [branch] + stdout.split() 277 (stdout, _) = _run('git branch --list devtool-override-*', cwd=path)
270 for b in branches_to_rebase: 278 branches_to_rebase = [branch] + stdout.split()
271 logger.info("Rebasing {} onto {}".format(b, rev)) 279 for b in branches_to_rebase:
272 __run('git checkout %s' % b) 280 logger.info("Rebasing {} onto {}".format(b, revs[os.path.relpath(path,srctree)]))
273 try: 281 _run('git checkout %s' % b, cwd=path)
274 __run('git rebase %s' % rev) 282 try:
275 except bb.process.ExecutionError as e: 283 _run('git rebase %s' % revs[os.path.relpath(path, srctree)], cwd=path)
276 if 'conflict' in e.stdout: 284 except bb.process.ExecutionError as e:
277 logger.warning('Command \'%s\' failed:\n%s\n\nYou will need to resolve conflicts in order to complete the upgrade.' % (e.command, e.stdout.rstrip())) 285 if 'conflict' in e.stdout:
278 __run('git rebase --abort') 286 logger.warning('Command \'%s\' failed:\n%s\n\nYou will need to resolve conflicts in order to complete the upgrade.' % (e.command, e.stdout.rstrip()))
279 else: 287 _run('git rebase --abort', cwd=path)
280 logger.warning('Command \'%s\' failed:\n%s' % (e.command, e.stdout)) 288 else:
281 __run('git checkout %s' % branch) 289 logger.warning('Command \'%s\' failed:\n%s' % (e.command, e.stdout))
290 _run('git checkout %s' % branch, cwd=path)
282 291
283 if tmpsrctree: 292 if tmpsrctree:
284 if keep_temp: 293 if keep_temp:
@@ -288,7 +297,7 @@ def _extract_new_source(newpv, srctree, no_patch, srcrev, srcbranch, branch, kee
288 if tmpdir != tmpsrctree: 297 if tmpdir != tmpsrctree:
289 shutil.rmtree(tmpdir) 298 shutil.rmtree(tmpdir)
290 299
291 return (rev, md5, sha256, srcbranch, srcsubdir_rel) 300 return (revs, md5, sha256, srcbranch, srcsubdir_rel)
292 301
293def _add_license_diff_to_recipe(path, diff): 302def _add_license_diff_to_recipe(path, diff):
294 notice_text = """# FIXME: the LIC_FILES_CHKSUM values have been updated by 'devtool upgrade'. 303 notice_text = """# FIXME: the LIC_FILES_CHKSUM values have been updated by 'devtool upgrade'.
diff --git a/scripts/lib/recipetool/append.py b/scripts/lib/recipetool/append.py
index 9dbb1cc4b5..4b6a7112c2 100644
--- a/scripts/lib/recipetool/append.py
+++ b/scripts/lib/recipetool/append.py
@@ -299,7 +299,7 @@ def appendfile(args):
299 if st.st_mode & stat.S_IXUSR: 299 if st.st_mode & stat.S_IXUSR:
300 perms = '0755' 300 perms = '0755'
301 install = {args.newfile: (args.targetpath, perms)} 301 install = {args.newfile: (args.targetpath, perms)}
302 oe.recipeutils.bbappend_recipe(rd, args.destlayer, {args.newfile: sourcepath}, install, wildcardver=args.wildcard_version, machine=args.machine) 302 oe.recipeutils.bbappend_recipe(rd, args.destlayer, {args.newfile: {'path' : sourcepath}}, install, wildcardver=args.wildcard_version, machine=args.machine)
303 tinfoil.modified_files() 303 tinfoil.modified_files()
304 return 0 304 return 0
305 else: 305 else:
@@ -353,7 +353,7 @@ def appendsrc(args, files, rd, extralines=None):
353 logger.warning('{0!r} is already in SRC_URI, not adding'.format(source_uri)) 353 logger.warning('{0!r} is already in SRC_URI, not adding'.format(source_uri))
354 else: 354 else:
355 extralines.append('SRC_URI += {0}'.format(source_uri)) 355 extralines.append('SRC_URI += {0}'.format(source_uri))
356 copyfiles[newfile] = srcfile 356 copyfiles[newfile] = {'path' : srcfile}
357 357
358 oe.recipeutils.bbappend_recipe(rd, args.destlayer, copyfiles, None, wildcardver=args.wildcard_version, machine=args.machine, extralines=extralines) 358 oe.recipeutils.bbappend_recipe(rd, args.destlayer, copyfiles, None, wildcardver=args.wildcard_version, machine=args.machine, extralines=extralines)
359 tinfoil.modified_files() 359 tinfoil.modified_files()