diff options
Diffstat (limited to 'scripts/lib/devtool/standard.py')
-rw-r--r-- | scripts/lib/devtool/standard.py | 111 |
1 files changed, 110 insertions, 1 deletions
diff --git a/scripts/lib/devtool/standard.py b/scripts/lib/devtool/standard.py index 5a5995f664..9c09533b54 100644 --- a/scripts/lib/devtool/standard.py +++ b/scripts/lib/devtool/standard.py | |||
@@ -1,6 +1,6 @@ | |||
1 | # Development tool - standard commands plugin | 1 | # Development tool - standard commands plugin |
2 | # | 2 | # |
3 | # Copyright (C) 2014-2015 Intel Corporation | 3 | # Copyright (C) 2014-2016 Intel Corporation |
4 | # | 4 | # |
5 | # This program is free software; you can redistribute it and/or modify | 5 | # This program is free software; you can redistribute it and/or modify |
6 | # it under the terms of the GNU General Public License version 2 as | 6 | # it under the terms of the GNU General Public License version 2 as |
@@ -1394,6 +1394,106 @@ def reset(args, config, basepath, workspace): | |||
1394 | return 0 | 1394 | return 0 |
1395 | 1395 | ||
1396 | 1396 | ||
1397 | def _get_layer(layername, d): | ||
1398 | """Determine the base layer path for the specified layer name/path""" | ||
1399 | layerdirs = d.getVar('BBLAYERS', True).split() | ||
1400 | layers = {os.path.basename(p): p for p in layerdirs} | ||
1401 | # Provide some shortcuts | ||
1402 | if layername.lower() in ['oe-core', 'openembedded-core']: | ||
1403 | layerdir = layers.get('meta', None) | ||
1404 | else: | ||
1405 | layerdir = layers.get(layername, None) | ||
1406 | if layerdir: | ||
1407 | layerdir = os.path.abspath(layerdir) | ||
1408 | return layerdir or layername | ||
1409 | |||
1410 | def finish(args, config, basepath, workspace): | ||
1411 | """Entry point for the devtool 'finish' subcommand""" | ||
1412 | import bb | ||
1413 | import oe.recipeutils | ||
1414 | |||
1415 | check_workspace_recipe(workspace, args.recipename) | ||
1416 | |||
1417 | tinfoil = setup_tinfoil(basepath=basepath, tracking=True) | ||
1418 | try: | ||
1419 | rd = parse_recipe(config, tinfoil, args.recipename, True) | ||
1420 | if not rd: | ||
1421 | return 1 | ||
1422 | |||
1423 | destlayerdir = _get_layer(args.destination, tinfoil.config_data) | ||
1424 | origlayerdir = oe.recipeutils.find_layerdir(rd.getVar('FILE', True)) | ||
1425 | |||
1426 | if not os.path.isdir(destlayerdir): | ||
1427 | raise DevtoolError('Unable to find layer or directory matching "%s"' % args.destination) | ||
1428 | |||
1429 | if os.path.abspath(destlayerdir) == config.workspace_path: | ||
1430 | raise DevtoolError('"%s" specifies the workspace layer - that is not a valid destination' % args.destination) | ||
1431 | |||
1432 | # If it's an upgrade, grab the original path | ||
1433 | origpath = None | ||
1434 | origfilelist = None | ||
1435 | append = workspace[args.recipename]['bbappend'] | ||
1436 | with open(append, 'r') as f: | ||
1437 | for line in f: | ||
1438 | if line.startswith('# original_path:'): | ||
1439 | origpath = line.split(':')[1].strip() | ||
1440 | elif line.startswith('# original_files:'): | ||
1441 | origfilelist = line.split(':')[1].split() | ||
1442 | |||
1443 | if origlayerdir == config.workspace_path: | ||
1444 | # Recipe file itself is in workspace, update it there first | ||
1445 | appendlayerdir = None | ||
1446 | origrelpath = None | ||
1447 | if origpath: | ||
1448 | origlayerpath = oe.recipeutils.find_layerdir(origpath) | ||
1449 | if origlayerpath: | ||
1450 | origrelpath = os.path.relpath(origpath, origlayerpath) | ||
1451 | destpath = oe.recipeutils.get_bbfile_path(rd, destlayerdir, origrelpath) | ||
1452 | if not destpath: | ||
1453 | raise DevtoolError("Unable to determine destination layer path - check that %s specifies an actual layer and %s/conf/layer.conf specifies BBFILES. You may also need to specify a more complete path." % (args.destination, destlayerdir)) | ||
1454 | elif destlayerdir == origlayerdir: | ||
1455 | # Same layer, update the original recipe | ||
1456 | appendlayerdir = None | ||
1457 | destpath = None | ||
1458 | else: | ||
1459 | # Create/update a bbappend in the specified layer | ||
1460 | appendlayerdir = destlayerdir | ||
1461 | destpath = None | ||
1462 | |||
1463 | # Remove any old files in the case of an upgrade | ||
1464 | if origpath and origfilelist and oe.recipeutils.find_layerdir(origpath) == oe.recipeutils.find_layerdir(destlayerdir): | ||
1465 | for fn in origfilelist: | ||
1466 | fnp = os.path.join(origpath, fn) | ||
1467 | try: | ||
1468 | os.remove(fnp) | ||
1469 | except FileNotFoundError: | ||
1470 | pass | ||
1471 | |||
1472 | # Actually update the recipe / bbappend | ||
1473 | _update_recipe(args.recipename, workspace, rd, args.mode, appendlayerdir, wildcard_version=True, no_remove=False, initial_rev=args.initial_rev) | ||
1474 | |||
1475 | if origlayerdir == config.workspace_path and destpath: | ||
1476 | # Recipe file itself is in the workspace - need to move it and any | ||
1477 | # associated files to the specified layer | ||
1478 | logger.info('Moving recipe file to %s' % destpath) | ||
1479 | recipedir = os.path.dirname(rd.getVar('FILE', True)) | ||
1480 | for root, _, files in os.walk(recipedir): | ||
1481 | for fn in files: | ||
1482 | srcpath = os.path.join(root, fn) | ||
1483 | relpth = os.path.relpath(os.path.dirname(srcpath), recipedir) | ||
1484 | destdir = os.path.abspath(os.path.join(destpath, relpth)) | ||
1485 | bb.utils.mkdirhier(destdir) | ||
1486 | shutil.move(srcpath, os.path.join(destdir, fn)) | ||
1487 | |||
1488 | finally: | ||
1489 | tinfoil.shutdown() | ||
1490 | |||
1491 | # Everything else has succeeded, we can now reset | ||
1492 | _reset([args.recipename], no_clean=False, config=config, basepath=basepath, workspace=workspace) | ||
1493 | |||
1494 | return 0 | ||
1495 | |||
1496 | |||
1397 | def get_default_srctree(config, recipename=''): | 1497 | def get_default_srctree(config, recipename=''): |
1398 | """Get the default srctree path""" | 1498 | """Get the default srctree path""" |
1399 | srctreeparent = config.get('General', 'default_source_parent_dir', config.workspace_path) | 1499 | srctreeparent = config.get('General', 'default_source_parent_dir', config.workspace_path) |
@@ -1481,3 +1581,12 @@ def register_commands(subparsers, context): | |||
1481 | parser_reset.add_argument('--all', '-a', action="store_true", help='Reset all recipes (clear workspace)') | 1581 | parser_reset.add_argument('--all', '-a', action="store_true", help='Reset all recipes (clear workspace)') |
1482 | parser_reset.add_argument('--no-clean', '-n', action="store_true", help='Don\'t clean the sysroot to remove recipe output') | 1582 | parser_reset.add_argument('--no-clean', '-n', action="store_true", help='Don\'t clean the sysroot to remove recipe output') |
1483 | parser_reset.set_defaults(func=reset) | 1583 | parser_reset.set_defaults(func=reset) |
1584 | |||
1585 | parser_finish = subparsers.add_parser('finish', help='Finish working on a recipe in your workspace', | ||
1586 | description='Pushes any committed changes to the specified recipe to the specified layer and removes it from your workspace. Roughly equivalent to an update-recipe followed by reset, except the update-recipe step will do the "right thing" depending on the recipe and the destination layer specified.', | ||
1587 | group='working', order=-100) | ||
1588 | parser_finish.add_argument('recipename', help='Recipe to finish') | ||
1589 | parser_finish.add_argument('destination', help='Layer/path to put recipe into. Can be the name of a layer configured in your bblayers.conf, the path to the base of a layer, or a partial path inside a layer. %(prog)s will attempt to complete the path based on the layer\'s structure.') | ||
1590 | parser_finish.add_argument('--mode', '-m', choices=['patch', 'srcrev', 'auto'], default='auto', help='Update mode (where %(metavar)s is %(choices)s; default is %(default)s)', metavar='MODE') | ||
1591 | parser_finish.add_argument('--initial-rev', help='Override starting revision for patches') | ||
1592 | parser_finish.set_defaults(func=finish) | ||