diff options
Diffstat (limited to 'scripts')
-rw-r--r-- | scripts/lib/devtool/__init__.py | 21 | ||||
-rw-r--r-- | scripts/lib/devtool/standard.py | 269 | ||||
-rw-r--r-- | scripts/lib/devtool/upgrade.py | 51 | ||||
-rw-r--r-- | scripts/lib/recipetool/append.py | 4 |
4 files changed, 220 insertions, 125 deletions
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 | ||
1244 | def _remove_file_entries(srcuri, filelist): | 1270 | def _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 | ||
1297 | def _export_patches(srctree, rd, start_rev, destdir, changed_revs=None): | 1323 | def _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 | ||
93 | def _write_append(rc, srctreebase, srctree, same_dir, no_same_dir, rev, copied, workspace, d): | 93 | def _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 | ||
293 | def _add_license_diff_to_recipe(path, diff): | 302 | def _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() |