diff options
Diffstat (limited to 'scripts')
| -rw-r--r-- | scripts/lib/devtool/standard.py | 194 |
1 files changed, 59 insertions, 135 deletions
diff --git a/scripts/lib/devtool/standard.py b/scripts/lib/devtool/standard.py index 05161942b7..1d0fe13788 100644 --- a/scripts/lib/devtool/standard.py +++ b/scripts/lib/devtool/standard.py | |||
| @@ -387,6 +387,19 @@ def _git_ls_tree(repodir, treeish='HEAD', recursive=False): | |||
| 387 | ret[split[3]] = split[0:3] | 387 | ret[split[3]] = split[0:3] |
| 388 | return ret | 388 | return ret |
| 389 | 389 | ||
| 390 | def _git_modified(repodir): | ||
| 391 | """List the difference between HEAD and the index""" | ||
| 392 | import bb | ||
| 393 | cmd = ['git', 'status', '--porcelain'] | ||
| 394 | out, _ = bb.process.run(cmd, cwd=repodir) | ||
| 395 | ret = [] | ||
| 396 | if out: | ||
| 397 | for line in out.split("\n"): | ||
| 398 | if line and not line.startswith('??'): | ||
| 399 | ret.append(line[3:]) | ||
| 400 | return ret | ||
| 401 | |||
| 402 | |||
| 390 | def _git_exclude_path(srctree, path): | 403 | def _git_exclude_path(srctree, path): |
| 391 | """Return pathspec (list of paths) that excludes certain path""" | 404 | """Return pathspec (list of paths) that excludes certain path""" |
| 392 | # NOTE: "Filtering out" files/paths in this way is not entirely reliable - | 405 | # NOTE: "Filtering out" files/paths in this way is not entirely reliable - |
| @@ -460,32 +473,6 @@ def sync(args, config, basepath, workspace): | |||
| 460 | finally: | 473 | finally: |
| 461 | tinfoil.shutdown() | 474 | tinfoil.shutdown() |
| 462 | 475 | ||
| 463 | def symlink_oelocal_files_srctree(rd, srctree): | ||
| 464 | import oe.patch | ||
| 465 | if os.path.abspath(rd.getVar('S')) == os.path.abspath(rd.getVar('WORKDIR')): | ||
| 466 | # If recipe extracts to ${WORKDIR}, symlink the files into the srctree | ||
| 467 | # (otherwise the recipe won't build as expected) | ||
| 468 | local_files_dir = os.path.join(srctree, 'oe-local-files') | ||
| 469 | addfiles = [] | ||
| 470 | for root, _, files in os.walk(local_files_dir): | ||
| 471 | relpth = os.path.relpath(root, local_files_dir) | ||
| 472 | if relpth != '.': | ||
| 473 | bb.utils.mkdirhier(os.path.join(srctree, relpth)) | ||
| 474 | for fn in files: | ||
| 475 | if fn == '.gitignore': | ||
| 476 | continue | ||
| 477 | destpth = os.path.join(srctree, relpth, fn) | ||
| 478 | if os.path.exists(destpth): | ||
| 479 | os.unlink(destpth) | ||
| 480 | if relpth != '.': | ||
| 481 | back_relpth = os.path.relpath(local_files_dir, root) | ||
| 482 | os.symlink('%s/oe-local-files/%s/%s' % (back_relpth, relpth, fn), destpth) | ||
| 483 | else: | ||
| 484 | os.symlink('oe-local-files/%s' % fn, destpth) | ||
| 485 | addfiles.append(os.path.join(relpth, fn)) | ||
| 486 | if addfiles: | ||
| 487 | oe.patch.GitApplyTree.commitIgnored("Add local file symlinks", dir=srctree, files=addfiles, d=rd) | ||
| 488 | |||
| 489 | def _extract_source(srctree, keep_temp, devbranch, sync, config, basepath, workspace, fixed_setup, d, tinfoil, no_overrides=False): | 476 | def _extract_source(srctree, keep_temp, devbranch, sync, config, basepath, workspace, fixed_setup, d, tinfoil, no_overrides=False): |
| 490 | """Extract sources of a recipe""" | 477 | """Extract sources of a recipe""" |
| 491 | import oe.recipeutils | 478 | import oe.recipeutils |
| @@ -657,9 +644,6 @@ def _extract_source(srctree, keep_temp, devbranch, sync, config, basepath, works | |||
| 657 | elif not os.path.exists(workshareddir): | 644 | elif not os.path.exists(workshareddir): |
| 658 | oe.path.copyhardlinktree(srcsubdir, workshareddir) | 645 | oe.path.copyhardlinktree(srcsubdir, workshareddir) |
| 659 | 646 | ||
| 660 | tempdir_localdir = os.path.join(tempdir, 'oe-local-files') | ||
| 661 | srctree_localdir = os.path.join(srctree, 'oe-local-files') | ||
| 662 | |||
| 663 | if sync: | 647 | if sync: |
| 664 | try: | 648 | try: |
| 665 | logger.info('Backing up current %s branch as branch: %s.bak' % (devbranch, devbranch)) | 649 | logger.info('Backing up current %s branch as branch: %s.bak' % (devbranch, devbranch)) |
| @@ -674,29 +658,8 @@ def _extract_source(srctree, keep_temp, devbranch, sync, config, basepath, works | |||
| 674 | except bb.process.ExecutionError as e: | 658 | except bb.process.ExecutionError as e: |
| 675 | raise DevtoolError("Error when syncing source files to local checkout: %s" % str(e)) | 659 | raise DevtoolError("Error when syncing source files to local checkout: %s" % str(e)) |
| 676 | 660 | ||
| 677 | # Move the oe-local-files directory to srctree. | ||
| 678 | # As oe-local-files is not part of the constructed git tree, | ||
| 679 | # removing it directly during the synchronization might surprise | ||
| 680 | # the user. Instead, we move it to oe-local-files.bak and remind | ||
| 681 | # the user in the log message. | ||
| 682 | if os.path.exists(srctree_localdir + '.bak'): | ||
| 683 | shutil.rmtree(srctree_localdir + '.bak') | ||
| 684 | |||
| 685 | if os.path.exists(srctree_localdir): | ||
| 686 | logger.info('Backing up current local file directory %s' % srctree_localdir) | ||
| 687 | shutil.move(srctree_localdir, srctree_localdir + '.bak') | ||
| 688 | |||
| 689 | if os.path.exists(tempdir_localdir): | ||
| 690 | logger.info('Syncing local source files to srctree...') | ||
| 691 | shutil.copytree(tempdir_localdir, srctree_localdir) | ||
| 692 | else: | 661 | else: |
| 693 | # Move oe-local-files directory to srctree | ||
| 694 | if os.path.exists(tempdir_localdir): | ||
| 695 | logger.info('Adding local source files to srctree...') | ||
| 696 | shutil.move(tempdir_localdir, srcsubdir) | ||
| 697 | |||
| 698 | shutil.move(srcsubdir, srctree) | 662 | shutil.move(srcsubdir, srctree) |
| 699 | symlink_oelocal_files_srctree(d, srctree) | ||
| 700 | 663 | ||
| 701 | if is_kernel_yocto: | 664 | if is_kernel_yocto: |
| 702 | logger.info('Copying kernel config to srctree') | 665 | logger.info('Copying kernel config to srctree') |
| @@ -852,34 +815,22 @@ def modify(args, config, basepath, workspace): | |||
| 852 | if (os.path.exists(srcdir) and os.listdir(srcdir)) and (kernelVersion in staging_kerVer and staging_kbranch == kbranch): | 815 | if (os.path.exists(srcdir) and os.listdir(srcdir)) and (kernelVersion in staging_kerVer and staging_kbranch == kbranch): |
| 853 | oe.path.copyhardlinktree(srcdir, srctree) | 816 | oe.path.copyhardlinktree(srcdir, srctree) |
| 854 | workdir = rd.getVar('WORKDIR') | 817 | workdir = rd.getVar('WORKDIR') |
| 818 | unpackdir = rd.getVar('UNPACKDIR') | ||
| 855 | srcsubdir = rd.getVar('S') | 819 | srcsubdir = rd.getVar('S') |
| 856 | localfilesdir = os.path.join(srctree, 'oe-local-files') | 820 | localfilesdir = os.path.join(srctree, 'oe-local-files') |
| 857 | # Move local source files into separate subdir | ||
| 858 | recipe_patches = [os.path.basename(patch) for patch in oe.recipeutils.get_recipe_patches(rd)] | ||
| 859 | local_files = oe.recipeutils.get_recipe_local_files(rd) | ||
| 860 | 821 | ||
| 861 | for key in local_files.copy(): | 822 | # Add locally copied files to gitignore as we add back to the metadata directly |
| 862 | if key.endswith('scc'): | 823 | local_files = oe.recipeutils.get_recipe_local_files(rd) |
| 863 | sccfile = open(local_files[key], 'r') | ||
| 864 | for l in sccfile: | ||
| 865 | line = l.split() | ||
| 866 | if line and line[0] in ('kconf', 'patch'): | ||
| 867 | cfg = os.path.join(os.path.dirname(local_files[key]), line[-1]) | ||
| 868 | if not cfg in local_files.values(): | ||
| 869 | local_files[line[-1]] = cfg | ||
| 870 | shutil.copy2(cfg, workdir) | ||
| 871 | sccfile.close() | ||
| 872 | |||
| 873 | # Ignore local files with subdir={BP} | ||
| 874 | srcabspath = os.path.abspath(srcsubdir) | 824 | srcabspath = os.path.abspath(srcsubdir) |
| 875 | local_files = [fname for fname in local_files if os.path.exists(os.path.join(workdir, fname)) and (srcabspath == workdir or not os.path.join(workdir, fname).startswith(srcabspath + os.sep))] | 825 | local_files = [fname for fname in local_files if |
| 826 | os.path.exists(os.path.join(unpackdir, fname)) and | ||
| 827 | srcabspath == unpackdir] | ||
| 876 | if local_files: | 828 | if local_files: |
| 877 | for fname in local_files: | 829 | with open(os.path.join(srctree, '.gitignore'), 'a+') as f: |
| 878 | _move_file(os.path.join(workdir, fname), os.path.join(srctree, 'oe-local-files', fname)) | 830 | f.write('# Ignore local files, by default. Remove following lines' |
| 879 | with open(os.path.join(srctree, 'oe-local-files', '.gitignore'), 'w') as f: | 831 | 'if you want to commit the directory to Git\n') |
| 880 | f.write('# Ignore local files, by default. Remove this file if you want to commit the directory to Git\n*\n') | 832 | for fname in local_files: |
| 881 | 833 | f.write('%s\n' % fname) | |
| 882 | symlink_oelocal_files_srctree(rd, srctree) | ||
| 883 | 834 | ||
| 884 | task = 'do_configure' | 835 | task = 'do_configure' |
| 885 | res = tinfoil.build_targets(pn, task, handle_events=True) | 836 | res = tinfoil.build_targets(pn, task, handle_events=True) |
| @@ -1478,6 +1429,7 @@ def _export_local_files(srctree, rd, destdir, srctreebase): | |||
| 1478 | # Instead they are directly copied over the original source files (in | 1429 | # Instead they are directly copied over the original source files (in |
| 1479 | # recipe space). | 1430 | # recipe space). |
| 1480 | existing_files = oe.recipeutils.get_recipe_local_files(rd) | 1431 | existing_files = oe.recipeutils.get_recipe_local_files(rd) |
| 1432 | |||
| 1481 | new_set = None | 1433 | new_set = None |
| 1482 | updated = OrderedDict() | 1434 | updated = OrderedDict() |
| 1483 | added = OrderedDict() | 1435 | added = OrderedDict() |
| @@ -1494,24 +1446,28 @@ def _export_local_files(srctree, rd, destdir, srctreebase): | |||
| 1494 | if branchname.startswith(override_branch_prefix): | 1446 | if branchname.startswith(override_branch_prefix): |
| 1495 | return (updated, added, removed) | 1447 | return (updated, added, removed) |
| 1496 | 1448 | ||
| 1497 | local_files_dir = os.path.join(srctreebase, 'oe-local-files') | 1449 | files = _git_modified(srctree) |
| 1498 | git_files = _git_ls_tree(srctree) | 1450 | #if not files: |
| 1499 | if 'oe-local-files' in git_files: | 1451 | # files = _ls_tree(srctree) |
| 1500 | # If tracked by Git, take the files from srctree HEAD. First get | 1452 | for f in files: |
| 1501 | # the tree object of the directory | 1453 | fullfile = os.path.join(srctree, f) |
| 1502 | tmp_index = os.path.join(srctree, '.git', 'index.tmp.devtool') | 1454 | if os.path.exists(os.path.join(fullfile, ".git")): |
| 1503 | tree = git_files['oe-local-files'][2] | 1455 | # submodules handled elsewhere |
| 1504 | bb.process.run(['git', 'checkout', tree, '--', '.'], cwd=srctree, | 1456 | continue |
| 1505 | env=dict(os.environ, GIT_WORK_TREE=destdir, | 1457 | if f not in existing_files: |
| 1506 | GIT_INDEX_FILE=tmp_index)) | 1458 | added[f] = {} |
| 1507 | new_set = list(_git_ls_tree(srctree, tree, True).keys()) | 1459 | if os.path.isdir(os.path.join(srctree, f)): |
| 1508 | elif os.path.isdir(local_files_dir): | 1460 | shutil.copytree(fullfile, os.path.join(destdir, f)) |
| 1509 | # If not tracked by Git, just copy from working copy | 1461 | else: |
| 1510 | new_set = _ls_tree(local_files_dir) | 1462 | shutil.copy2(fullfile, os.path.join(destdir, f)) |
| 1511 | bb.process.run(['cp', '-ax', | 1463 | elif not os.path.exists(fullfile): |
| 1512 | os.path.join(local_files_dir, '.'), destdir]) | 1464 | removed[f] = existing_files[f] |
| 1513 | else: | 1465 | elif f in existing_files: |
| 1514 | new_set = [] | 1466 | updated[f] = {'path' : existing_files[f]} |
| 1467 | if os.path.isdir(os.path.join(srctree, f)): | ||
| 1468 | shutil.copytree(fullfile, os.path.join(destdir, f)) | ||
| 1469 | else: | ||
| 1470 | shutil.copy2(fullfile, os.path.join(destdir, f)) | ||
| 1515 | 1471 | ||
| 1516 | # Special handling for kernel config | 1472 | # Special handling for kernel config |
| 1517 | if bb.data.inherits_class('kernel-yocto', rd): | 1473 | if bb.data.inherits_class('kernel-yocto', rd): |
| @@ -1519,17 +1475,14 @@ def _export_local_files(srctree, rd, destdir, srctreebase): | |||
| 1519 | fragment_path = os.path.join(destdir, fragment_fn) | 1475 | fragment_path = os.path.join(destdir, fragment_fn) |
| 1520 | if _create_kconfig_diff(srctree, rd, fragment_path): | 1476 | if _create_kconfig_diff(srctree, rd, fragment_path): |
| 1521 | if os.path.exists(fragment_path): | 1477 | if os.path.exists(fragment_path): |
| 1522 | if fragment_fn not in new_set: | 1478 | if fragment_fn in removed: |
| 1523 | new_set.append(fragment_fn) | 1479 | del removed[fragment_fn] |
| 1524 | # Copy fragment to local-files | 1480 | if fragment_fn not in updated and fragment_fn not in added: |
| 1525 | if os.path.isdir(local_files_dir): | 1481 | added[fragment_fn] = {} |
| 1526 | shutil.copy2(fragment_path, local_files_dir) | ||
| 1527 | else: | 1482 | else: |
| 1528 | if fragment_fn in new_set: | 1483 | if fragment_fn in updated: |
| 1529 | new_set.remove(fragment_fn) | 1484 | revoved[fragment_fn] = updated[fragment_fn] |
| 1530 | # Remove fragment from local-files | 1485 | del updated[fragment_fn] |
| 1531 | if os.path.exists(os.path.join(local_files_dir, fragment_fn)): | ||
| 1532 | os.unlink(os.path.join(local_files_dir, fragment_fn)) | ||
| 1533 | 1486 | ||
| 1534 | # Special handling for cml1, ccmake, etc bbclasses that generated | 1487 | # Special handling for cml1, ccmake, etc bbclasses that generated |
| 1535 | # configuration fragment files that are consumed as source files | 1488 | # configuration fragment files that are consumed as source files |
| @@ -1537,42 +1490,13 @@ def _export_local_files(srctree, rd, destdir, srctreebase): | |||
| 1537 | if bb.data.inherits_class(frag_class, rd): | 1490 | if bb.data.inherits_class(frag_class, rd): |
| 1538 | srcpath = os.path.join(rd.getVar('WORKDIR'), frag_name) | 1491 | srcpath = os.path.join(rd.getVar('WORKDIR'), frag_name) |
| 1539 | if os.path.exists(srcpath): | 1492 | if os.path.exists(srcpath): |
| 1540 | if frag_name not in new_set: | 1493 | if frag_name in removed: |
| 1541 | new_set.append(frag_name) | 1494 | del removed[frag_name] |
| 1495 | if frag_name not in updated: | ||
| 1496 | added[frag_name] = {} | ||
| 1542 | # copy fragment into destdir | 1497 | # copy fragment into destdir |
| 1543 | shutil.copy2(srcpath, destdir) | 1498 | shutil.copy2(srcpath, destdir) |
| 1544 | # copy fragment into local files if exists | 1499 | |
| 1545 | if os.path.isdir(local_files_dir): | ||
| 1546 | shutil.copy2(srcpath, local_files_dir) | ||
| 1547 | |||
| 1548 | if new_set is not None: | ||
| 1549 | for fname in new_set: | ||
| 1550 | if fname in existing_files: | ||
| 1551 | origpath = existing_files.pop(fname) | ||
| 1552 | workpath = os.path.join(local_files_dir, fname) | ||
| 1553 | if not filecmp.cmp(origpath, workpath): | ||
| 1554 | updated[fname] = {'path' : origpath} | ||
| 1555 | elif fname != '.gitignore': | ||
| 1556 | added[fname] = {} | ||
| 1557 | |||
| 1558 | workdir = rd.getVar('WORKDIR') | ||
| 1559 | s = rd.getVar('S') | ||
| 1560 | if not s.endswith(os.sep): | ||
| 1561 | s += os.sep | ||
| 1562 | |||
| 1563 | if workdir != s: | ||
| 1564 | # Handle files where subdir= was specified | ||
| 1565 | for fname in list(existing_files.keys()): | ||
| 1566 | # FIXME handle both subdir starting with BP and not? | ||
| 1567 | fworkpath = os.path.join(workdir, fname) | ||
| 1568 | if fworkpath.startswith(s): | ||
| 1569 | fpath = os.path.join(srctree, os.path.relpath(fworkpath, s)) | ||
| 1570 | if os.path.exists(fpath): | ||
| 1571 | origpath = existing_files.pop(fname) | ||
| 1572 | if not filecmp.cmp(origpath, fpath): | ||
| 1573 | updated[fpath] = {'path' : origpath} | ||
| 1574 | |||
| 1575 | removed = existing_files | ||
| 1576 | return (updated, added, removed) | 1500 | return (updated, added, removed) |
| 1577 | 1501 | ||
| 1578 | 1502 | ||
