# Development tool - standard commands plugin
#
# Copyright (C) 2014-2017 Intel Corporation
#
# SPDX-License-Identifier: GPL-2.0-only
#
"""Devtool standard plugins"""

import os
import sys
import re
import shutil
import subprocess
import tempfile
import logging
import argparse
import argparse_oe
import scriptutils
import errno
import glob
import filecmp
from collections import OrderedDict
from devtool import exec_build_env_command, setup_tinfoil, check_workspace_recipe, use_external_build, setup_git_repo, recipe_to_append, get_bbclassextend_targets, update_unlockedsigs, check_prerelease_version, check_git_repo_dirty, check_git_repo_op, DevtoolError
from devtool import parse_recipe

logger = logging.getLogger('devtool')

override_branch_prefix = 'devtool-override-'


def add(args, config, basepath, workspace):
    """Entry point for the devtool 'add' subcommand"""
    import bb
    import oe.recipeutils

    if not args.recipename and not args.srctree and not args.fetch and not args.fetchuri:
        raise argparse_oe.ArgumentUsageError('At least one of recipename, srctree, fetchuri or -f/--fetch must be specified', 'add')

    # These are positional arguments, but because we're nice, allow
    # specifying e.g. source tree without name, or fetch URI without name or
    # source tree (if we can detect that that is what the user meant)
    if scriptutils.is_src_url(args.recipename):
        if not args.fetchuri:
            if args.fetch:
                raise DevtoolError('URI specified as positional argument as well as -f/--fetch')
            args.fetchuri = args.recipename
            args.recipename = ''
    elif scriptutils.is_src_url(args.srctree):
        if not args.fetchuri:
            if args.fetch:
                raise DevtoolError('URI specified as positional argument as well as -f/--fetch')
            args.fetchuri = args.srctree
            args.srctree = ''
    elif args.recipename and not args.srctree:
        if os.sep in args.recipename:
            args.srctree = args.recipename
            args.recipename = None
        elif os.path.isdir(args.recipename):
            logger.warning('Ambiguous argument "%s" - assuming you mean it to be the recipe name' % args.recipename)

    if not args.fetchuri:
        if args.srcrev:
            raise DevtoolError('The -S/--srcrev option is only valid when fetching from an SCM repository')
        if args.srcbranch:
            raise DevtoolError('The -B/--srcbranch option is only valid when fetching from an SCM repository')

    if args.srctree and os.path.isfile(args.srctree):
        args.fetchuri = 'file://' + os.path.abspath(args.srctree)
        args.srctree = ''

    if args.fetch:
        if args.fetchuri:
            raise DevtoolError('URI specified as positional argument as well as -f/--fetch')
        else:
            logger.warning('-f/--fetch option is deprecated - you can now simply specify the URL to fetch as a positional argument instead')
            args.fetchuri = args.fetch

    if args.recipename:
        if args.recipename in workspace:
            raise DevtoolError("recipe %s is already in your workspace" %
                               args.recipename)
        reason = oe.recipeutils.validate_pn(args.recipename)
        if reason:
            raise DevtoolError(reason)

    if args.srctree:
        srctree = os.path.abspath(args.srctree)
        srctreeparent = None
        tmpsrcdir = None
    else:
        srctree = None
        srctreeparent = get_default_srctree(config)
        bb.utils.mkdirhier(srctreeparent)
        tmpsrcdir = tempfile.mkdtemp(prefix='devtoolsrc', dir=srctreeparent)

    if srctree and os.path.exists(srctree):
        if args.fetchuri:
            if not os.path.isdir(srctree):
                raise DevtoolError("Cannot fetch into source tree path %s as "
                                   "it exists and is not a directory" %
                                   srctree)
            elif os.listdir(srctree):
                raise DevtoolError("Cannot fetch into source tree path %s as "
                                   "it already exists and is non-empty" %
                                   srctree)
    elif not args.fetchuri:
        if args.srctree:
            raise DevtoolError("Specified source tree %s could not be found" %
                               args.srctree)
        elif srctree:
            raise DevtoolError("No source tree exists at default path %s - "
                               "either create and populate this directory, "
                               "or specify a path to a source tree, or a "
                               "URI to fetch source from" % srctree)
        else:
            raise DevtoolError("You must either specify a source tree "
                               "or a URI to fetch source from")

    if args.version:
        if '_' in args.version or ' ' in args.version:
            raise DevtoolError('Invalid version string "%s"' % args.version)

    if args.color == 'auto' and sys.stdout.isatty():
        color = 'always'
    else:
        color = args.color
    extracmdopts = ''
    if args.fetchuri:
        source = args.fetchuri
        if srctree:
            extracmdopts += ' -x %s' % srctree
        else:
            extracmdopts += ' -x %s' % tmpsrcdir
    else:
        source = srctree
    if args.recipename:
        extracmdopts += ' -N %s' % args.recipename
    if args.version:
        extracmdopts += ' -V %s' % args.version
    if args.binary:
        extracmdopts += ' -b'
    if args.also_native:
        extracmdopts += ' --also-native'
    if args.src_subdir:
        extracmdopts += ' --src-subdir "%s"' % args.src_subdir
    if args.autorev:
        extracmdopts += ' -a'
    if args.fetch_dev:
        extracmdopts += ' --fetch-dev'
    if args.mirrors:
        extracmdopts += ' --mirrors'
    if args.srcrev:
        extracmdopts += ' --srcrev %s' % args.srcrev
    if args.srcbranch:
        extracmdopts += ' --srcbranch %s' % args.srcbranch
    if args.provides:
        extracmdopts += ' --provides %s' % args.provides

    tempdir = tempfile.mkdtemp(prefix='devtool')
    try:
        try:
            stdout, _ = exec_build_env_command(config.init_path, basepath, 'recipetool --color=%s create --devtool -o %s \'%s\' %s' % (color, tempdir, source, extracmdopts), watch=True)
        except bb.process.ExecutionError as e:
            if e.exitcode == 15:
                raise DevtoolError('Could not auto-determine recipe name, please specify it on the command line')
            else:
                raise DevtoolError('Command \'%s\' failed' % e.command)

        recipes = glob.glob(os.path.join(tempdir, '*.bb'))
        if recipes:
            recipename = os.path.splitext(os.path.basename(recipes[0]))[0].split('_')[0]
            if recipename in workspace:
                raise DevtoolError('A recipe with the same name as the one being created (%s) already exists in your workspace' % recipename)
            recipedir = os.path.join(config.workspace_path, 'recipes', recipename)
            bb.utils.mkdirhier(recipedir)
            recipefile = os.path.join(recipedir, os.path.basename(recipes[0]))
            appendfile = recipe_to_append(recipefile, config)
            if os.path.exists(appendfile):
                # This shouldn't be possible, but just in case
                raise DevtoolError('A recipe with the same name as the one being created already exists in your workspace')
            if os.path.exists(recipefile):
                raise DevtoolError('A recipe file %s already exists in your workspace; this shouldn\'t be there - please delete it before continuing' % recipefile)
            if tmpsrcdir:
                srctree = os.path.join(srctreeparent, recipename)
                if os.path.exists(tmpsrcdir):
                    if os.path.exists(srctree):
                        if os.path.isdir(srctree):
                            try:
                                os.rmdir(srctree)
                            except OSError as e:
                                if e.errno == errno.ENOTEMPTY:
                                    raise DevtoolError('Source tree path %s already exists and is not empty' % srctree)
                                else:
                                    raise
                        else:
                            raise DevtoolError('Source tree path %s already exists and is not a directory' % srctree)
                    logger.info('Using default source tree path %s' % srctree)
                    shutil.move(tmpsrcdir, srctree)
                else:
                    raise DevtoolError('Couldn\'t find source tree created by recipetool')
            bb.utils.mkdirhier(recipedir)
            shutil.move(recipes[0], recipefile)
            # Move any additional files created by recipetool
            for fn in os.listdir(tempdir):
                shutil.move(os.path.join(tempdir, fn), recipedir)
        else:
            raise DevtoolError('Command \'%s\' did not create any recipe file:\n%s' % (e.command, e.stdout))
        attic_recipe = os.path.join(config.workspace_path, 'attic', recipename, os.path.basename(recipefile))
        if os.path.exists(attic_recipe):
            logger.warning('A modified recipe from a previous invocation exists in %s - you may wish to move this over the top of the new recipe if you had changes in it that you want to continue with' % attic_recipe)
    finally:
        if tmpsrcdir and os.path.exists(tmpsrcdir):
            shutil.rmtree(tmpsrcdir)
        shutil.rmtree(tempdir)

    for fn in os.listdir(recipedir):
        _add_md5(config, recipename, os.path.join(recipedir, fn))

    tinfoil = setup_tinfoil(config_only=True, basepath=basepath)
    try:
        try:
            rd = tinfoil.parse_recipe_file(recipefile, False)
        except Exception as e:
            logger.error(str(e))
            rd = None
        if not rd:
            # Parsing failed. We just created this recipe and we shouldn't
            # leave it in the workdir or it'll prevent bitbake from starting
            movefn = '%s.parsefailed' % recipefile
            logger.error('Parsing newly created recipe failed, moving recipe to %s for reference. If this looks to be caused by the recipe itself, please report this error.' % movefn)
            shutil.move(recipefile, movefn)
            return 1

        if args.fetchuri and not args.no_git:
            setup_git_repo(srctree, args.version, 'devtool', d=tinfoil.config_data)

        initial_rev = None
        if os.path.exists(os.path.join(srctree, '.git')):
            (stdout, _) = bb.process.run('git rev-parse HEAD', cwd=srctree)
            initial_rev = stdout.rstrip()

        if args.src_subdir:
            srctree = os.path.join(srctree, args.src_subdir)

        bb.utils.mkdirhier(os.path.dirname(appendfile))
        with open(appendfile, 'w') as f:
            f.write('inherit externalsrc\n')
            f.write('EXTERNALSRC = "%s"\n' % srctree)

            b_is_s = use_external_build(args.same_dir, args.no_same_dir, rd)
            if b_is_s:
                f.write('EXTERNALSRC_BUILD = "%s"\n' % srctree)
            if initial_rev:
                f.write('\n# initial_rev: %s\n' % initial_rev)

            if args.binary:
                f.write('do_install_append() {\n')
                f.write('    rm -rf ${D}/.git\n')
                f.write('    rm -f ${D}/singletask.lock\n')
                f.write('}\n')

            if bb.data.inherits_class('npm', rd):
                f.write('do_install_append() {\n')
                f.write('    # Remove files added to source dir by devtool/externalsrc\n')
                f.write('    rm -f ${NPM_INSTALLDIR}/singletask.lock\n')
                f.write('    rm -rf ${NPM_INSTALLDIR}/.git\n')
                f.write('    rm -rf ${NPM_INSTALLDIR}/oe-local-files\n')
                f.write('    for symlink in ${EXTERNALSRC_SYMLINKS} ; do\n')
                f.write('        rm -f ${NPM_INSTALLDIR}/${symlink%%:*}\n')
                f.write('    done\n')
                f.write('}\n')

        # Check if the new layer provides recipes whose priorities have been
        # overriden by PREFERRED_PROVIDER.
        recipe_name = rd.getVar('PN')
        provides = rd.getVar('PROVIDES')
        # Search every item defined in PROVIDES
        for recipe_provided in provides.split():
            preferred_provider = 'PREFERRED_PROVIDER_' + recipe_provided
            current_pprovider = rd.getVar(preferred_provider)
            if current_pprovider and current_pprovider != recipe_name:
                if args.fixed_setup:
                    #if we are inside the eSDK add the new PREFERRED_PROVIDER in the workspace layer.conf
                    layerconf_file = os.path.join(config.workspace_path, "conf", "layer.conf")
                    with open(layerconf_file, 'a') as f:
                        f.write('%s = "%s"\n' % (preferred_provider, recipe_name))
                else:
                    logger.warning('Set \'%s\' in order to use the recipe' % preferred_provider)
                break

        _add_md5(config, recipename, appendfile)

        check_prerelease_version(rd.getVar('PV'), 'devtool add')

        logger.info('Recipe %s has been automatically created; further editing may be required to make it fully functional' % recipefile)

    finally:
        tinfoil.shutdown()

    return 0


def _check_compatible_recipe(pn, d):
    """Check if the recipe is supported by devtool"""
    if pn == 'perf':
        raise DevtoolError("The perf recipe does not actually check out "
                           "source and thus cannot be supported by this tool",
                           4)

    if pn in ['kernel-devsrc', 'package-index'] or pn.startswith('gcc-source'):
        raise DevtoolError("The %s recipe is not supported by this tool" % pn, 4)

    if bb.data.inherits_class('image', d):
        raise DevtoolError("The %s recipe is an image, and therefore is not "
                           "supported by this tool" % pn, 4)

    if bb.data.inherits_class('populate_sdk', d):
        raise DevtoolError("The %s recipe is an SDK, and therefore is not "
                           "supported by this tool" % pn, 4)

    if bb.data.inherits_class('packagegroup', d):
        raise DevtoolError("The %s recipe is a packagegroup, and therefore is "
                           "not supported by this tool" % pn, 4)

    if bb.data.inherits_class('meta', d):
        raise DevtoolError("The %s recipe is a meta-recipe, and therefore is "
                           "not supported by this tool" % pn, 4)

    if bb.data.inherits_class('externalsrc', d) and d.getVar('EXTERNALSRC'):
        # Not an incompatibility error per se, so we don't pass the error code
        raise DevtoolError("externalsrc is currently enabled for the %s "
                           "recipe. This prevents the normal do_patch task "
                           "from working. You will need to disable this "
                           "first." % pn)

def _dry_run_copy(src, dst, dry_run_outdir, base_outdir):
    """Common function for copying a file to the dry run output directory"""
    relpath = os.path.relpath(dst, base_outdir)
    if relpath.startswith('..'):
        raise Exception('Incorrect base path %s for path %s' % (base_outdir, dst))
    dst = os.path.join(dry_run_outdir, relpath)
    dst_d = os.path.dirname(dst)
    if dst_d:
        bb.utils.mkdirhier(dst_d)
    # Don't overwrite existing files, otherwise in the case of an upgrade
    # the dry-run written out recipe will be overwritten with an unmodified
    # version
    if not os.path.exists(dst):
        shutil.copy(src, dst)

def _move_file(src, dst, dry_run_outdir=None, base_outdir=None):
    """Move a file. Creates all the directory components of destination path."""
    dry_run_suffix = ' (dry-run)' if dry_run_outdir else ''
    logger.debug('Moving %s to %s%s' % (src, dst, dry_run_suffix))
    if dry_run_outdir:
        # We want to copy here, not move
        _dry_run_copy(src, dst, dry_run_outdir, base_outdir)
    else:
        dst_d = os.path.dirname(dst)
        if dst_d:
            bb.utils.mkdirhier(dst_d)
        shutil.move(src, dst)

def _copy_file(src, dst, dry_run_outdir=None):
    """Copy a file. Creates all the directory components of destination path."""
    dry_run_suffix = ' (dry-run)' if dry_run_outdir else ''
    logger.debug('Copying %s to %s%s' % (src, dst, dry_run_suffix))
    if dry_run_outdir:
        _dry_run_copy(src, dst, dry_run_outdir, base_outdir)
    else:
        dst_d = os.path.dirname(dst)
        if dst_d:
            bb.utils.mkdirhier(dst_d)
        shutil.copy(src, dst)

def _git_ls_tree(repodir, treeish='HEAD', recursive=False):
    """List contents of a git treeish"""
    import bb
    cmd = ['git', 'ls-tree', '-z', treeish]
    if recursive:
        cmd.append('-r')
    out, _ = bb.process.run(cmd, cwd=repodir)
    ret = {}
    if out:
        for line in out.split('\0'):
            if line:
                split = line.split(None, 4)
                ret[split[3]] = split[0:3]
    return ret

def _git_exclude_path(srctree, path):
    """Return pathspec (list of paths) that excludes certain path"""
    # NOTE: "Filtering out" files/paths in this way is not entirely reliable -
    # we don't catch files that are deleted, for example. A more reliable way
    # to implement this would be to use "negative pathspecs" which were
    # introduced in Git v1.9.0. Revisit this when/if the required Git version
    # becomes greater than that.
    path = os.path.normpath(path)
    recurse = True if len(path.split(os.path.sep)) > 1 else False
    git_files = list(_git_ls_tree(srctree, 'HEAD', recurse).keys())
    if path in git_files:
        git_files.remove(path)
        return git_files
    else:
        return ['.']

def _ls_tree(directory):
    """Recursive listing of files in a directory"""
    ret = []
    for root, dirs, files in os.walk(directory):
        ret.extend([os.path.relpath(os.path.join(root, fname), directory) for
                    fname in files])
    return ret


def extract(args, config, basepath, workspace):
    """Entry point for the devtool 'extract' subcommand"""
    import bb

    tinfoil = setup_tinfoil(basepath=basepath, tracking=True)
    if not tinfoil:
        # Error already shown
        return 1
    try:
        rd = parse_recipe(config, tinfoil, args.recipename, True)
        if not rd:
            return 1

        srctree = os.path.abspath(args.srctree)
        initial_rev, _ = _extract_source(srctree, args.keep_temp, args.branch, False, config, basepath, workspace, args.fixed_setup, rd, tinfoil, no_overrides=args.no_overrides)
        logger.info('Source tree extracted to %s' % srctree)

        if initial_rev:
            return 0
        else:
            return 1
    finally:
        tinfoil.shutdown()

def sync(args, config, basepath, workspace):
    """Entry point for the devtool 'sync' subcommand"""
    import bb

    tinfoil = setup_tinfoil(basepath=basepath, tracking=True)
    if not tinfoil:
        # Error already shown
        return 1
    try:
        rd = parse_recipe(config, tinfoil, args.recipename, True)
        if not rd:
            return 1

        srctree = os.path.abspath(args.srctree)
        initial_rev, _ = _extract_source(srctree, args.keep_temp, args.branch, True, config, basepath, workspace, args.fixed_setup, rd, tinfoil, no_overrides=True)
        logger.info('Source tree %s synchronized' % srctree)

        if initial_rev:
            return 0
        else:
            return 1
    finally:
        tinfoil.shutdown()

def symlink_oelocal_files_srctree(rd,srctree):
    import oe.patch
    if os.path.abspath(rd.getVar('S')) == os.path.abspath(rd.getVar('WORKDIR')):
        # If recipe extracts to ${WORKDIR}, symlink the files into the srctree
        # (otherwise the recipe won't build as expected)
        local_files_dir = os.path.join(srctree, 'oe-local-files')
        addfiles = []
        for root, _, files in os.walk(local_files_dir):
            relpth = os.path.relpath(root, local_files_dir)
            if relpth != '.':
                bb.utils.mkdirhier(os.path.join(srctree, relpth))
            for fn in files:
                if fn == '.gitignore':
                    continue
                destpth = os.path.join(srctree, relpth, fn)
                if os.path.exists(destpth):
                    os.unlink(destpth)
                os.symlink('oe-local-files/%s' % fn, destpth)
                addfiles.append(os.path.join(relpth, fn))
        if addfiles:
            bb.process.run('git add %s' % ' '.join(addfiles), cwd=srctree)
            useroptions = []
            oe.patch.GitApplyTree.gitCommandUserOptions(useroptions, d=rd)
            bb.process.run('git %s commit -m "Committing local file symlinks\n\n%s"' % (' '.join(useroptions), oe.patch.GitApplyTree.ignore_commit_prefix), cwd=srctree)


def _extract_source(srctree, keep_temp, devbranch, sync, config, basepath, workspace, fixed_setup, d, tinfoil, no_overrides=False):
    """Extract sources of a recipe"""
    import oe.recipeutils
    import oe.patch
    import oe.path

    pn = d.getVar('PN')

    _check_compatible_recipe(pn, d)

    if sync:
        if not os.path.exists(srctree):
                raise DevtoolError("output path %s does not exist" % srctree)
    else:
        if os.path.exists(srctree):
            if not os.path.isdir(srctree):
                raise DevtoolError("output path %s exists and is not a directory" %
                                   srctree)
            elif os.listdir(srctree):
                raise DevtoolError("output path %s already exists and is "
                                   "non-empty" % srctree)

        if 'noexec' in (d.getVarFlags('do_unpack', False) or []):
            raise DevtoolError("The %s recipe has do_unpack disabled, unable to "
                               "extract source" % pn, 4)

    if not sync:
        # Prepare for shutil.move later on
        bb.utils.mkdirhier(srctree)
        os.rmdir(srctree)

    extra_overrides = []
    if not no_overrides:
        history = d.varhistory.variable('SRC_URI')
        for event in history:
            if not 'flag' in event:
                if event['op'].startswith(('_append[', '_prepend[')):
                    extra_overrides.append(event['op'].split('[')[1].split(']')[0])
        # We want to remove duplicate overrides. If a recipe had multiple
        # SRC_URI_override += values it would cause mulitple instances of
        # overrides. This doesn't play nicely with things like creating a
        # branch for every instance of DEVTOOL_EXTRA_OVERRIDES.
        extra_overrides = list(set(extra_overrides))
        if extra_overrides:
            logger.info('SRC_URI contains some conditional appends/prepends - will create branches to represent these')

    initial_rev = None

    appendexisted = False
    recipefile = d.getVar('FILE')
    appendfile = recipe_to_append(recipefile, config)
    is_kernel_yocto = bb.data.inherits_class('kernel-yocto', d)

    # We need to redirect WORKDIR, STAMPS_DIR etc. under a temporary
    # directory so that:
    # (a) we pick up all files that get unpacked to the WORKDIR, and
    # (b) we don't disturb the existing build
    # However, with recipe-specific sysroots the sysroots for the recipe
    # will be prepared under WORKDIR, and if we used the system temporary
    # directory (i.e. usually /tmp) as used by mkdtemp by default, then
    # our attempts to hardlink files into the recipe-specific sysroots
    # will fail on systems where /tmp is a different filesystem, and it
    # would have to fall back to copying the files which is a waste of
    # time. Put the temp directory under the WORKDIR to prevent that from
    # being a problem.
    tempbasedir = d.getVar('WORKDIR')
    bb.utils.mkdirhier(tempbasedir)
    tempdir = tempfile.mkdtemp(prefix='devtooltmp-', dir=tempbasedir)
    try:
        tinfoil.logger.setLevel(logging.WARNING)

        # FIXME this results in a cache reload under control of tinfoil, which is fine
        # except we don't get the knotty progress bar

        if os.path.exists(appendfile):
            appendbackup = os.path.join(tempdir, os.path.basename(appendfile) + '.bak')
            shutil.copyfile(appendfile, appendbackup)
        else:
            appendbackup = None
            bb.utils.mkdirhier(os.path.dirname(appendfile))
        logger.debug('writing append file %s' % appendfile)
        with open(appendfile, 'a') as f:
            f.write('###--- _extract_source\n')
            f.write('DEVTOOL_TEMPDIR = "%s"\n' % tempdir)
            f.write('DEVTOOL_DEVBRANCH = "%s"\n' % devbranch)
            if not is_kernel_yocto:
                f.write('PATCHTOOL = "git"\n')
                f.write('PATCH_COMMIT_FUNCTIONS = "1"\n')
            if extra_overrides:
                f.write('DEVTOOL_EXTRA_OVERRIDES = "%s"\n' % ':'.join(extra_overrides))
            f.write('inherit devtool-source\n')
            f.write('###--- _extract_source\n')

        update_unlockedsigs(basepath, workspace, fixed_setup, [pn])

        sstate_manifests = d.getVar('SSTATE_MANIFESTS')
        bb.utils.mkdirhier(sstate_manifests)
        preservestampfile = os.path.join(sstate_manifests, 'preserve-stamps')
        with open(preservestampfile, 'w') as f:
            f.write(d.getVar('STAMP'))
        try:
            if is_kernel_yocto:
                # We need to generate the kernel config
                task = 'do_configure'
            else:
                task = 'do_patch'

            # Run the fetch + unpack tasks
            res = tinfoil.build_targets(pn,
                                        task,
                                        handle_events=True)
        finally:
            if os.path.exists(preservestampfile):
                os.remove(preservestampfile)

        if not res:
            raise DevtoolError('Extracting source for %s failed' % pn)

        try:
            with open(os.path.join(tempdir, 'initial_rev'), 'r') as f:
                initial_rev = f.read()

            with open(os.path.join(tempdir, 'srcsubdir'), 'r') as f:
                srcsubdir = f.read()
        except FileNotFoundError as e:
            raise DevtoolError('Something went wrong with source extraction - the devtool-source class was not active or did not function correctly:\n%s' % str(e))
        srcsubdir_rel = os.path.relpath(srcsubdir, os.path.join(tempdir, 'workdir'))

        # Check if work-shared is empty, if yes
        # find source and copy to work-shared
        if is_kernel_yocto:
            workshareddir = d.getVar('STAGING_KERNEL_DIR')
            staging_kerVer = get_staging_kver(workshareddir)
            kernelVersion = d.getVar('LINUX_VERSION')

            # handle dangling symbolic link in work-shared:
            if os.path.islink(workshareddir):
                os.unlink(workshareddir)

            if os.path.exists(workshareddir) and (not os.listdir(workshareddir) or kernelVersion != staging_kerVer):
                shutil.rmtree(workshareddir)
                oe.path.copyhardlinktree(srcsubdir,workshareddir)
            elif not os.path.exists(workshareddir):
                oe.path.copyhardlinktree(srcsubdir,workshareddir)

        tempdir_localdir = os.path.join(tempdir, 'oe-local-files')
        srctree_localdir = os.path.join(srctree, 'oe-local-files')

        if sync:
            bb.process.run('git fetch file://' + srcsubdir + ' ' + devbranch + ':' + devbranch, cwd=srctree)

            # Move oe-local-files directory to srctree
            # As the oe-local-files is not part of the constructed git tree,
            # remove them directly during the synchrounizating might surprise
            # the users.  Instead, we move it to oe-local-files.bak and remind
            # user in the log message.
            if os.path.exists(srctree_localdir + '.bak'):
                shutil.rmtree(srctree_localdir, srctree_localdir + '.bak')

            if os.path.exists(srctree_localdir):
                logger.info('Backing up current local file directory %s' % srctree_localdir)
                shutil.move(srctree_localdir, srctree_localdir + '.bak')

            if os.path.exists(tempdir_localdir):
                logger.info('Syncing local source files to srctree...')
                shutil.copytree(tempdir_localdir, srctree_localdir)
        else:
            # Move oe-local-files directory to srctree
            if os.path.exists(tempdir_localdir):
                logger.info('Adding local source files to srctree...')
                shutil.move(tempdir_localdir, srcsubdir)

            shutil.move(srcsubdir, srctree)
            symlink_oelocal_files_srctree(d,srctree)

        if is_kernel_yocto:
            logger.info('Copying kernel config to srctree')
            shutil.copy2(os.path.join(tempdir, '.config'), srctree)

    finally:
        if appendbackup:
            shutil.copyfile(appendbackup, appendfile)
        elif os.path.exists(appendfile):
            os.remove(appendfile)
        if keep_temp:
            logger.info('Preserving temporary directory %s' % tempdir)
        else:
            shutil.rmtree(tempdir)
    return initial_rev, srcsubdir_rel

def _add_md5(config, recipename, filename):
    """Record checksum of a file (or recursively for a directory) to the md5-file of the workspace"""
    import bb.utils

    def addfile(fn):
        md5 = bb.utils.md5_file(fn)
        with open(os.path.join(config.workspace_path, '.devtool_md5'), 'a+') as f:
            md5_str = '%s|%s|%s\n' % (recipename, os.path.relpath(fn, config.workspace_path), md5)
            f.seek(0, os.SEEK_SET)
            if not md5_str in f.read():
                f.write(md5_str)

    if os.path.isdir(filename):
        for root, _, files in os.walk(filename):
            for f in files:
                addfile(os.path.join(root, f))
    else:
        addfile(filename)

def _check_preserve(config, recipename):
    """Check if a file was manually changed and needs to be saved in 'attic'
       directory"""
    import bb.utils
    origfile = os.path.join(config.workspace_path, '.devtool_md5')
    newfile = os.path.join(config.workspace_path, '.devtool_md5_new')
    preservepath = os.path.join(config.workspace_path, 'attic', recipename)
    with open(origfile, 'r') as f:
        with open(newfile, 'w') as tf:
            for line in f.readlines():
                splitline = line.rstrip().split('|')
                if splitline[0] == recipename:
                    removefile = os.path.join(config.workspace_path, splitline[1])
                    try:
                        md5 = bb.utils.md5_file(removefile)
                    except IOError as err:
                        if err.errno == 2:
                            # File no longer exists, skip it
                            continue
                        else:
                            raise
                    if splitline[2] != md5:
                        bb.utils.mkdirhier(preservepath)
                        preservefile = os.path.basename(removefile)
                        logger.warning('File %s modified since it was written, preserving in %s' % (preservefile, preservepath))
                        shutil.move(removefile, os.path.join(preservepath, preservefile))
                    else:
                        os.remove(removefile)
                else:
                    tf.write(line)
    os.rename(newfile, origfile)

def get_staging_kver(srcdir):
    # Kernel version from work-shared
    kerver = []
    staging_kerVer=""
    if os.path.exists(srcdir) and os.listdir(srcdir):
        with open(os.path.join(srcdir,"Makefile")) as f:
            version = [next(f) for x in range(5)][1:4]
            for word in version:
                kerver.append(word.split('= ')[1].split('\n')[0])
            staging_kerVer = ".".join(kerver)
    return staging_kerVer

def get_staging_kbranch(srcdir):
    staging_kbranch = ""
    if os.path.exists(srcdir) and os.listdir(srcdir):
        (branch, _) = bb.process.run('git branch | grep \* | cut -d \' \' -f2', cwd=srcdir)
        staging_kbranch = "".join(branch.split('\n')[0])
    return staging_kbranch

def modify(args, config, basepath, workspace):
    """Entry point for the devtool 'modify' subcommand"""
    import bb
    import oe.recipeutils
    import oe.patch
    import oe.path

    if args.recipename in workspace:
        raise DevtoolError("recipe %s is already in your workspace" %
                           args.recipename)

    tinfoil = setup_tinfoil(basepath=basepath, tracking=True)
    try:
        rd = parse_recipe(config, tinfoil, args.recipename, True)
        if not rd:
            return 1

        pn = rd.getVar('PN')
        if pn != args.recipename:
            logger.info('Mapping %s to %s' % (args.recipename, pn))
        if pn in workspace:
            raise DevtoolError("recipe %s is already in your workspace" %
                            pn)

        if args.srctree:
            srctree = os.path.abspath(args.srctree)
        else:
            srctree = get_default_srctree(config, pn)

        if args.no_extract and not os.path.isdir(srctree):
            raise DevtoolError("--no-extract specified and source path %s does "
                            "not exist or is not a directory" %
                            srctree)

        recipefile = rd.getVar('FILE')
        appendfile = recipe_to_append(recipefile, config, args.wildcard)
        if os.path.exists(appendfile):
            raise DevtoolError("Another variant of recipe %s is already in your "
                            "workspace (only one variant of a recipe can "
                            "currently be worked on at once)"
                            % pn)

        _check_compatible_recipe(pn, rd)

        initial_rev = None
        commits = []
        check_commits = False

        if bb.data.inherits_class('kernel-yocto', rd):
            # Current set kernel version
            kernelVersion = rd.getVar('LINUX_VERSION')
            srcdir = rd.getVar('STAGING_KERNEL_DIR')
            kbranch = rd.getVar('KBRANCH')

            staging_kerVer = get_staging_kver(srcdir)
            staging_kbranch = get_staging_kbranch(srcdir)
            if (os.path.exists(srcdir) and os.listdir(srcdir)) and (kernelVersion in staging_kerVer and staging_kbranch == kbranch):
                oe.path.copyhardlinktree(srcdir,srctree)
                workdir = rd.getVar('WORKDIR')
                srcsubdir = rd.getVar('S')
                localfilesdir = os.path.join(srctree,'oe-local-files')
                # Move local source files into separate subdir
                recipe_patches = [os.path.basename(patch) for patch in oe.recipeutils.get_recipe_patches(rd)]
                local_files = oe.recipeutils.get_recipe_local_files(rd)

                for key in local_files.copy():
                    if key.endswith('scc'):
                        sccfile = open(local_files[key], 'r')
                        for l in sccfile:
                            line = l.split()
                            if line and line[0] in ('kconf', 'patch'):
                                cfg = os.path.join(os.path.dirname(local_files[key]), line[-1])
                                if not cfg in local_files.values():
                                    local_files[line[-1]] = cfg
                                    shutil.copy2(cfg, workdir)
                        sccfile.close()

                # Ignore local files with subdir={BP}
                srcabspath = os.path.abspath(srcsubdir)
                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))]
                if local_files:
                    for fname in local_files:
                        _move_file(os.path.join(workdir, fname), os.path.join(srctree, 'oe-local-files', fname))
                    with open(os.path.join(srctree, 'oe-local-files', '.gitignore'), 'w') as f:
                        f.write('# Ignore local files, by default. Remove this file ''if you want to commit the directory to Git\n*\n')

                symlink_oelocal_files_srctree(rd,srctree)

                task = 'do_configure'
                res = tinfoil.build_targets(pn, task, handle_events=True)

                # Copy .config to workspace
                kconfpath = rd.getVar('B')
                logger.info('Copying kernel config to workspace')
                shutil.copy2(os.path.join(kconfpath, '.config'),srctree)

                # Set this to true, we still need to get initial_rev
                # by parsing the git repo
                args.no_extract = True

        if not args.no_extract:
            initial_rev, _ = _extract_source(srctree, args.keep_temp, args.branch, False, config, basepath, workspace, args.fixed_setup, rd, tinfoil, no_overrides=args.no_overrides)
            if not initial_rev:
                return 1
            logger.info('Source tree extracted to %s' % srctree)
            # Get list of commits since this revision
            (stdout, _) = bb.process.run('git rev-list --reverse %s..HEAD' % initial_rev, cwd=srctree)
            commits = stdout.split()
            check_commits = True
        else:
            if os.path.exists(os.path.join(srctree, '.git')):
                # Check if it's a tree previously extracted by us. This is done
                # by ensuring that devtool-base and args.branch (devtool) exist.
                # The check_commits logic will cause an exception if either one
                # of these doesn't exist
                try:
                    (stdout, _) = bb.process.run('git branch --contains devtool-base', cwd=srctree)
                    bb.process.run('git rev-parse %s' % args.branch, cwd=srctree)
                except bb.process.ExecutionError:
                    stdout = ''
                if stdout:
                    check_commits = True
                for line in stdout.splitlines():
                    if line.startswith('*'):
                        (stdout, _) = bb.process.run('git rev-parse devtool-base', cwd=srctree)
                        initial_rev = stdout.rstrip()
                if not initial_rev:
                    # Otherwise, just grab the head revision
                    (stdout, _) = bb.process.run('git rev-parse HEAD', cwd=srctree)
                    initial_rev = stdout.rstrip()

        branch_patches = {}
        if check_commits:
            # Check if there are override branches
            (stdout, _) = bb.process.run('git branch', cwd=srctree)
            branches = []
            for line in stdout.rstrip().splitlines():
                branchname = line[2:].rstrip()
                if branchname.startswith(override_branch_prefix):
                    branches.append(branchname)
            if branches:
                logger.warning('SRC_URI is conditionally overridden in this recipe, thus several %s* branches have been created, one for each override that makes changes to SRC_URI. It is recommended that you make changes to the %s branch first, then checkout and rebase each %s* branch and update any unique patches there (duplicates on those branches will be ignored by devtool finish/update-recipe)' % (override_branch_prefix, args.branch, override_branch_prefix))
            branches.insert(0, args.branch)
            seen_patches = []
            for branch in branches:
                branch_patches[branch] = []
                (stdout, _) = bb.process.run('git log devtool-base..%s' % branch, cwd=srctree)
                for line in stdout.splitlines():
                    line = line.strip()
                    if line.startswith(oe.patch.GitApplyTree.patch_line_prefix):
                        origpatch = line[len(oe.patch.GitApplyTree.patch_line_prefix):].split(':', 1)[-1].strip()
                        if not origpatch in seen_patches:
                            seen_patches.append(origpatch)
                            branch_patches[branch].append(origpatch)

        # Need to grab this here in case the source is within a subdirectory
        srctreebase = srctree

        # Check that recipe isn't using a shared workdir
        s = os.path.abspath(rd.getVar('S'))
        workdir = os.path.abspath(rd.getVar('WORKDIR'))
        if s.startswith(workdir) and s != workdir and os.path.dirname(s) != workdir:
            # Handle if S is set to a subdirectory of the source
            srcsubdir = os.path.relpath(s, workdir).split(os.sep, 1)[1]
            srctree = os.path.join(srctree, srcsubdir)

        bb.utils.mkdirhier(os.path.dirname(appendfile))
        with open(appendfile, 'w') as f:
            f.write('FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:"\n')
            # Local files can be modified/tracked in separate subdir under srctree
            # Mostly useful for packages with S != WORKDIR
            f.write('FILESPATH_prepend := "%s:"\n' %
                    os.path.join(srctreebase, 'oe-local-files'))
            f.write('# srctreebase: %s\n' % srctreebase)

            f.write('\ninherit externalsrc\n')
            f.write('# NOTE: We use pn- overrides here to avoid affecting multiple variants in the case where the recipe uses BBCLASSEXTEND\n')
            f.write('EXTERNALSRC_pn-%s = "%s"\n' % (pn, srctree))

            b_is_s = use_external_build(args.same_dir, args.no_same_dir, rd)
            if b_is_s:
                f.write('EXTERNALSRC_BUILD_pn-%s = "%s"\n' % (pn, srctree))

            if bb.data.inherits_class('kernel', rd):
                f.write('SRCTREECOVEREDTASKS = "do_validate_branches do_kernel_checkout '
                        'do_fetch do_unpack do_kernel_configme do_kernel_configcheck"\n')
                f.write('\ndo_patch[noexec] = "1"\n')
                f.write('\ndo_configure_append() {\n'
                        '    cp ${B}/.config ${S}/.config.baseline\n'
                        '    ln -sfT ${B}/.config ${S}/.config.new\n'
                        '}\n')
            if rd.getVarFlag('do_menuconfig','task'):
                f.write('\ndo_configure_append() {\n'
                '    cp ${B}/.config ${S}/.config.baseline\n'
                '    ln -sfT ${B}/.config ${S}/.config.new\n'
                '}\n')
            if initial_rev:
                f.write('\n# initial_rev: %s\n' % initial_rev)
                for commit in commits:
                    f.write('# commit: %s\n' % commit)
            if branch_patches:
                for branch in branch_patches:
                    if branch == args.branch:
                        continue
                    f.write('# patches_%s: %s\n' % (branch, ','.join(branch_patches[branch])))

        update_unlockedsigs(basepath, workspace, args.fixed_setup, [pn])

        _add_md5(config, pn, appendfile)

        logger.info('Recipe %s now set up to build from %s' % (pn, srctree))

    finally:
        tinfoil.shutdown()

    return 0


def rename(args, config, basepath, workspace):
    """Entry point for the devtool 'rename' subcommand"""
    import bb
    import oe.recipeutils

    check_workspace_recipe(workspace, args.recipename)

    if not (args.newname or args.version):
        raise DevtoolError('You must specify a new name, a version with -V/--version, or both')

    recipefile = workspace[args.recipename]['recipefile']
    if not recipefile:
        raise DevtoolError('devtool rename can only be used where the recipe file itself is in the workspace (e.g. after devtool add)')

    if args.newname and args.newname != args.recipename:
        reason = oe.recipeutils.validate_pn(args.newname)
        if reason:
            raise DevtoolError(reason)
        newname = args.newname
    else:
        newname = args.recipename

    append = workspace[args.recipename]['bbappend']
    appendfn = os.path.splitext(os.path.basename(append))[0]
    splitfn = appendfn.split('_')
    if len(splitfn) > 1:
        origfnver = appendfn.split('_')[1]
    else:
        origfnver = ''

    recipefilemd5 = None
    tinfoil = setup_tinfoil(basepath=basepath, tracking=True)
    try:
        rd = parse_recipe(config, tinfoil, args.recipename, True)
        if not rd:
            return 1

        bp = rd.getVar('BP')
        bpn = rd.getVar('BPN')
        if newname != args.recipename:
            localdata = rd.createCopy()
            localdata.setVar('PN', newname)
            newbpn = localdata.getVar('BPN')
        else:
            newbpn = bpn
        s = rd.getVar('S', False)
        src_uri = rd.getVar('SRC_URI', False)
        pv = rd.getVar('PV')

        # Correct variable values that refer to the upstream source - these
        # values must stay the same, so if the name/version are changing then
        # we need to fix them up
        new_s = s
        new_src_uri = src_uri
        if newbpn != bpn:
            # ${PN} here is technically almost always incorrect, but people do use it
            new_s = new_s.replace('${BPN}', bpn)
            new_s = new_s.replace('${PN}', bpn)
            new_s = new_s.replace('${BP}', '%s-${PV}' % bpn)
            new_src_uri = new_src_uri.replace('${BPN}', bpn)
            new_src_uri = new_src_uri.replace('${PN}', bpn)
            new_src_uri = new_src_uri.replace('${BP}', '%s-${PV}' % bpn)
        if args.version and origfnver == pv:
            new_s = new_s.replace('${PV}', pv)
            new_s = new_s.replace('${BP}', '${BPN}-%s' % pv)
            new_src_uri = new_src_uri.replace('${PV}', pv)
            new_src_uri = new_src_uri.replace('${BP}', '${BPN}-%s' % pv)
        patchfields = {}
        if new_s != s:
            patchfields['S'] = new_s
        if new_src_uri != src_uri:
            patchfields['SRC_URI'] = new_src_uri
        if patchfields:
            recipefilemd5 = bb.utils.md5_file(recipefile)
            oe.recipeutils.patch_recipe(rd, recipefile, patchfields)
            newrecipefilemd5 = bb.utils.md5_file(recipefile)
    finally:
        tinfoil.shutdown()

    if args.version:
        newver = args.version
    else:
        newver = origfnver

    if newver:
        newappend = '%s_%s.bbappend' % (newname, newver)
        newfile =  '%s_%s.bb' % (newname, newver)
    else:
        newappend = '%s.bbappend' % newname
        newfile = '%s.bb' % newname

    oldrecipedir = os.path.dirname(recipefile)
    newrecipedir = os.path.join(config.workspace_path, 'recipes', newname)
    if oldrecipedir != newrecipedir:
        bb.utils.mkdirhier(newrecipedir)

    newappend = os.path.join(os.path.dirname(append), newappend)
    newfile = os.path.join(newrecipedir, newfile)

    # Rename bbappend
    logger.info('Renaming %s to %s' % (append, newappend))
    os.rename(append, newappend)
    # Rename recipe file
    logger.info('Renaming %s to %s' % (recipefile, newfile))
    os.rename(recipefile, newfile)

    # Rename source tree if it's the default path
    appendmd5 = None
    if not args.no_srctree:
        srctree = workspace[args.recipename]['srctree']
        if os.path.abspath(srctree) == os.path.join(config.workspace_path, 'sources', args.recipename):
            newsrctree = os.path.join(config.workspace_path, 'sources', newname)
            logger.info('Renaming %s to %s' % (srctree, newsrctree))
            shutil.move(srctree, newsrctree)
            # Correct any references (basically EXTERNALSRC*) in the .bbappend
            appendmd5 = bb.utils.md5_file(newappend)
            appendlines = []
            with open(newappend, 'r') as f:
                for line in f:
                    appendlines.append(line)
            with open(newappend, 'w') as f:
                for line in appendlines:
                    if srctree in line:
                        line = line.replace(srctree, newsrctree)
                    f.write(line)
            newappendmd5 = bb.utils.md5_file(newappend)

    bpndir = None
    newbpndir = None
    if newbpn != bpn:
        bpndir = os.path.join(oldrecipedir, bpn)
        if os.path.exists(bpndir):
            newbpndir = os.path.join(newrecipedir, newbpn)
            logger.info('Renaming %s to %s' % (bpndir, newbpndir))
            shutil.move(bpndir, newbpndir)

    bpdir = None
    newbpdir = None
    if newver != origfnver or newbpn != bpn:
        bpdir = os.path.join(oldrecipedir, bp)
        if os.path.exists(bpdir):
            newbpdir = os.path.join(newrecipedir, '%s-%s' % (newbpn, newver))
            logger.info('Renaming %s to %s' % (bpdir, newbpdir))
            shutil.move(bpdir, newbpdir)

    if oldrecipedir != newrecipedir:
        # Move any stray files and delete the old recipe directory
        for entry in os.listdir(oldrecipedir):
            oldpath = os.path.join(oldrecipedir, entry)
            newpath = os.path.join(newrecipedir, entry)
            logger.info('Renaming %s to %s' % (oldpath, newpath))
            shutil.move(oldpath, newpath)
        os.rmdir(oldrecipedir)

    # Now take care of entries in .devtool_md5
    md5entries = []
    with open(os.path.join(config.workspace_path, '.devtool_md5'), 'r') as f:
        for line in f:
            md5entries.append(line)

    if bpndir and newbpndir:
        relbpndir = os.path.relpath(bpndir, config.workspace_path) + '/'
    else:
        relbpndir = None
    if bpdir and newbpdir:
        relbpdir = os.path.relpath(bpdir, config.workspace_path) + '/'
    else:
        relbpdir = None

    with open(os.path.join(config.workspace_path, '.devtool_md5'), 'w') as f:
        for entry in md5entries:
            splitentry = entry.rstrip().split('|')
            if len(splitentry) > 2:
                if splitentry[0] == args.recipename:
                    splitentry[0] = newname
                    if splitentry[1] == os.path.relpath(append, config.workspace_path):
                        splitentry[1] = os.path.relpath(newappend, config.workspace_path)
                        if appendmd5 and splitentry[2] == appendmd5:
                            splitentry[2] = newappendmd5
                    elif splitentry[1] == os.path.relpath(recipefile, config.workspace_path):
                        splitentry[1] = os.path.relpath(newfile, config.workspace_path)
                        if recipefilemd5 and splitentry[2] == recipefilemd5:
                            splitentry[2] = newrecipefilemd5
                    elif relbpndir and splitentry[1].startswith(relbpndir):
                        splitentry[1] = os.path.relpath(os.path.join(newbpndir, splitentry[1][len(relbpndir):]), config.workspace_path)
                    elif relbpdir and splitentry[1].startswith(relbpdir):
                        splitentry[1] = os.path.relpath(os.path.join(newbpdir, splitentry[1][len(relbpdir):]), config.workspace_path)
                    entry = '|'.join(splitentry) + '\n'
            f.write(entry)
    return 0


def _get_patchset_revs(srctree, recipe_path, initial_rev=None, force_patch_refresh=False):
    """Get initial and update rev of a recipe. These are the start point of the
    whole patchset and start point for the patches to be re-generated/updated.
    """
    import bb

    # Get current branch
    stdout, _ = bb.process.run('git rev-parse --abbrev-ref HEAD',
                               cwd=srctree)
    branchname = stdout.rstrip()

    # Parse initial rev from recipe if not specified
    commits = []
    patches = []
    with open(recipe_path, 'r') as f:
        for line in f:
            if line.startswith('# initial_rev:'):
                if not initial_rev:
                    initial_rev = line.split(':')[-1].strip()
            elif line.startswith('# commit:') and not force_patch_refresh:
                commits.append(line.split(':')[-1].strip())
            elif line.startswith('# patches_%s:' % branchname):
                patches = line.split(':')[-1].strip().split(',')

    update_rev = initial_rev
    changed_revs = None
    if initial_rev:
        # Find first actually changed revision
        stdout, _ = bb.process.run('git rev-list --reverse %s..HEAD' %
                                   initial_rev, cwd=srctree)
        newcommits = stdout.split()
        for i in range(min(len(commits), len(newcommits))):
            if newcommits[i] == commits[i]:
                update_rev = commits[i]

        try:
            stdout, _ = bb.process.run('git cherry devtool-patched',
                                        cwd=srctree)
        except bb.process.ExecutionError as err:
            stdout = None

        if stdout is not None and not force_patch_refresh:
            changed_revs = []
            for line in stdout.splitlines():
                if line.startswith('+ '):
                    rev = line.split()[1]
                    if rev in newcommits:
                        changed_revs.append(rev)

    return initial_rev, update_rev, changed_revs, patches

def _remove_file_entries(srcuri, filelist):
    """Remove file:// entries from SRC_URI"""
    remaining = filelist[:]
    entries = []
    for fname in filelist:
        basename = os.path.basename(fname)
        for i in range(len(srcuri)):
            if (srcuri[i].startswith('file://') and
                    os.path.basename(srcuri[i].split(';')[0]) == basename):
                entries.append(srcuri[i])
                remaining.remove(fname)
                srcuri.pop(i)
                break
    return entries, remaining

def _replace_srcuri_entry(srcuri, filename, newentry):
    """Replace entry corresponding to specified file with a new entry"""
    basename = os.path.basename(filename)
    for i in range(len(srcuri)):
        if os.path.basename(srcuri[i].split(';')[0]) == basename:
            srcuri.pop(i)
            srcuri.insert(i, newentry)
            break

def _remove_source_files(append, files, destpath, no_report_remove=False, dry_run=False):
    """Unlink existing patch files"""

    dry_run_suffix = ' (dry-run)' if dry_run else ''

    for path in files:
        if append:
            if not destpath:
                raise Exception('destpath should be set here')
            path = os.path.join(destpath, os.path.basename(path))

        if os.path.exists(path):
            if not no_report_remove:
                logger.info('Removing file %s%s' % (path, dry_run_suffix))
            if not dry_run:
                # FIXME "git rm" here would be nice if the file in question is
                #       tracked
                # FIXME there's a chance that this file is referred to by
                #       another recipe, in which case deleting wouldn't be the
                #       right thing to do
                os.remove(path)
                # Remove directory if empty
                try:
                    os.rmdir(os.path.dirname(path))
                except OSError as ose:
                    if ose.errno != errno.ENOTEMPTY:
                        raise


def _export_patches(srctree, rd, start_rev, destdir, changed_revs=None):
    """Export patches from srctree to given location.
       Returns three-tuple of dicts:
         1. updated - patches that already exist in SRCURI
         2. added - new patches that don't exist in SRCURI
         3  removed - patches that exist in SRCURI but not in exported patches
      In each dict the key is the 'basepath' of the URI and value is the
      absolute path to the existing file in recipe space (if any).
    """
    import oe.recipeutils
    from oe.patch import GitApplyTree
    updated = OrderedDict()
    added = OrderedDict()
    seqpatch_re = re.compile('^([0-9]{4}-)?(.+)')

    existing_patches = dict((os.path.basename(path), path) for path in
                            oe.recipeutils.get_recipe_patches(rd))
    logger.debug('Existing patches: %s' % existing_patches)

    # Generate patches from Git, exclude local files directory
    patch_pathspec = _git_exclude_path(srctree, 'oe-local-files')
    GitApplyTree.extractPatches(srctree, start_rev, destdir, patch_pathspec)

    new_patches = sorted(os.listdir(destdir))
    for new_patch in new_patches:
        # Strip numbering from patch names. If it's a git sequence named patch,
        # the numbers might not match up since we are starting from a different
        # revision This does assume that people are using unique shortlog
        # values, but they ought to be anyway...
        new_basename = seqpatch_re.match(new_patch).group(2)
        match_name = None
        for old_patch in existing_patches:
            old_basename = seqpatch_re.match(old_patch).group(2)
            old_basename_splitext = os.path.splitext(old_basename)
            if old_basename.endswith(('.gz', '.bz2', '.Z')) and old_basename_splitext[0] == new_basename:
                old_patch_noext = os.path.splitext(old_patch)[0]
                match_name = old_patch_noext
                break
            elif new_basename == old_basename:
                match_name = old_patch
                break
        if match_name:
            # Rename patch files
            if new_patch != match_name:
                os.rename(os.path.join(destdir, new_patch),
                          os.path.join(destdir, match_name))
            # Need to pop it off the list now before checking changed_revs
            oldpath = existing_patches.pop(old_patch)
            if changed_revs is not None:
                # Avoid updating patches that have not actually changed
                with open(os.path.join(destdir, match_name), 'r') as f:
                    firstlineitems = f.readline().split()
                    # Looking for "From <hash>" line
                    if len(firstlineitems) > 1 and len(firstlineitems[1]) == 40:
                        if not firstlineitems[1] in changed_revs:
                            continue
            # Recompress if necessary
            if oldpath.endswith(('.gz', '.Z')):
                bb.process.run(['gzip', match_name], cwd=destdir)
                if oldpath.endswith('.gz'):
                    match_name += '.gz'
                else:
                    match_name += '.Z'
            elif oldpath.endswith('.bz2'):
                bb.process.run(['bzip2', match_name], cwd=destdir)
                match_name += '.bz2'
            updated[match_name] = oldpath
        else:
            added[new_patch] = None
    return (updated, added, existing_patches)


def _create_kconfig_diff(srctree, rd, outfile):
    """Create a kconfig fragment"""
    # Only update config fragment if both config files exist
    orig_config = os.path.join(srctree, '.config.baseline')
    new_config = os.path.join(srctree, '.config.new')
    if os.path.exists(orig_config) and os.path.exists(new_config):
        cmd = ['diff', '--new-line-format=%L', '--old-line-format=',
               '--unchanged-line-format=', orig_config, new_config]
        pipe = subprocess.Popen(cmd, stdout=subprocess.PIPE,
                                stderr=subprocess.PIPE)
        stdout, stderr = pipe.communicate()
        if pipe.returncode == 1:
            logger.info("Updating config fragment %s" % outfile)
            with open(outfile, 'wb') as fobj:
                fobj.write(stdout)
        elif pipe.returncode == 0:
            logger.info("Would remove config fragment %s" % outfile)
            if os.path.exists(outfile):
                # Remove fragment file in case of empty diff
                logger.info("Removing config fragment %s" % outfile)
                os.unlink(outfile)
        else:
            raise bb.process.ExecutionError(cmd, pipe.returncode, stdout, stderr)
        return True
    return False


def _export_local_files(srctree, rd, destdir, srctreebase):
    """Copy local files from srctree to given location.
       Returns three-tuple of dicts:
         1. updated - files that already exist in SRCURI
         2. added - new files files that don't exist in SRCURI
         3  removed - files that exist in SRCURI but not in exported files
      In each dict the key is the 'basepath' of the URI and value is the
      absolute path to the existing file in recipe space (if any).
    """
    import oe.recipeutils

    # Find out local files (SRC_URI files that exist in the "recipe space").
    # Local files that reside in srctree are not included in patch generation.
    # Instead they are directly copied over the original source files (in
    # recipe space).
    existing_files = oe.recipeutils.get_recipe_local_files(rd)
    new_set = None
    updated = OrderedDict()
    added = OrderedDict()
    removed = OrderedDict()
    local_files_dir = os.path.join(srctreebase, 'oe-local-files')
    git_files = _git_ls_tree(srctree)
    if 'oe-local-files' in git_files:
        # If tracked by Git, take the files from srctree HEAD. First get
        # the tree object of the directory
        tmp_index = os.path.join(srctree, '.git', 'index.tmp.devtool')
        tree = git_files['oe-local-files'][2]
        bb.process.run(['git', 'checkout', tree, '--', '.'], cwd=srctree,
                        env=dict(os.environ, GIT_WORK_TREE=destdir,
                                 GIT_INDEX_FILE=tmp_index))
        new_set = list(_git_ls_tree(srctree, tree, True).keys())
    elif os.path.isdir(local_files_dir):
        # If not tracked by Git, just copy from working copy
        new_set = _ls_tree(local_files_dir)
        bb.process.run(['cp', '-ax',
                        os.path.join(local_files_dir, '.'), destdir])
    else:
        new_set = []

    # Special handling for kernel config
    if bb.data.inherits_class('kernel-yocto', rd):
        fragment_fn = 'devtool-fragment.cfg'
        fragment_path = os.path.join(destdir, fragment_fn)
        if _create_kconfig_diff(srctree, rd, fragment_path):
            if os.path.exists(fragment_path):
                if fragment_fn not in new_set:
                    new_set.append(fragment_fn)
                # Copy fragment to local-files
                if os.path.isdir(local_files_dir):
                    shutil.copy2(fragment_path, local_files_dir)
            else:
                if fragment_fn in new_set:
                    new_set.remove(fragment_fn)
                # Remove fragment from local-files
                if os.path.exists(os.path.join(local_files_dir, fragment_fn)):
                    os.unlink(os.path.join(local_files_dir, fragment_fn))

    # Special handling for cml1, ccmake, etc bbclasses that generated
    # configuration fragment files that are consumed as source files
    for frag_class, frag_name in [("cml1", "fragment.cfg"), ("ccmake", "site-file.cmake")]:
        if bb.data.inherits_class(frag_class, rd):
            srcpath = os.path.join(rd.getVar('WORKDIR'), frag_name)
            if os.path.exists(srcpath):
                if frag_name not in new_set:
                    new_set.append(frag_name)
                # copy fragment into destdir
                shutil.copy2(srcpath, destdir)
                # copy fragment into local files if exists
                if os.path.isdir(local_files_dir):
                    shutil.copy2(srcpath, local_files_dir)

    if new_set is not None:
        for fname in new_set:
            if fname in existing_files:
                origpath = existing_files.pop(fname)
                workpath = os.path.join(local_files_dir, fname)
                if not filecmp.cmp(origpath, workpath):
                    updated[fname] = origpath
            elif fname != '.gitignore':
                added[fname] = None

        workdir = rd.getVar('WORKDIR')
        s = rd.getVar('S')
        if not s.endswith(os.sep):
            s += os.sep

        if workdir != s:
            # Handle files where subdir= was specified
            for fname in list(existing_files.keys()):
                # FIXME handle both subdir starting with BP and not?
                fworkpath = os.path.join(workdir, fname)
                if fworkpath.startswith(s):
                    fpath = os.path.join(srctree, os.path.relpath(fworkpath, s))
                    if os.path.exists(fpath):
                        origpath = existing_files.pop(fname)
                        if not filecmp.cmp(origpath, fpath):
                            updated[fpath] = origpath

        removed = existing_files
    return (updated, added, removed)


def _determine_files_dir(rd):
    """Determine the appropriate files directory for a recipe"""
    recipedir = rd.getVar('FILE_DIRNAME')
    for entry in rd.getVar('FILESPATH').split(':'):
        relpth = os.path.relpath(entry, recipedir)
        if not os.sep in relpth:
            # One (or zero) levels below only, so we don't put anything in machine-specific directories
            if os.path.isdir(entry):
                return entry
    return os.path.join(recipedir, rd.getVar('BPN'))


def _update_recipe_srcrev(recipename, workspace, srctree, rd, appendlayerdir, wildcard_version, no_remove, no_report_remove, dry_run_outdir=None):
    """Implement the 'srcrev' mode of update-recipe"""
    import bb
    import oe.recipeutils

    dry_run_suffix = ' (dry-run)' if dry_run_outdir else ''

    recipefile = rd.getVar('FILE')
    recipedir = os.path.basename(recipefile)
    logger.info('Updating SRCREV in recipe %s%s' % (recipedir, dry_run_suffix))

    # Get HEAD revision
    try:
        stdout, _ = bb.process.run('git rev-parse HEAD', cwd=srctree)
    except bb.process.ExecutionError as err:
        raise DevtoolError('Failed to get HEAD revision in %s: %s' %
                           (srctree, err))
    srcrev = stdout.strip()
    if len(srcrev) != 40:
        raise DevtoolError('Invalid hash returned by git: %s' % stdout)

    destpath = None
    remove_files = []
    patchfields = {}
    patchfields['SRCREV'] = srcrev
    orig_src_uri = rd.getVar('SRC_URI', False) or ''
    srcuri = orig_src_uri.split()
    tempdir = tempfile.mkdtemp(prefix='devtool')
    update_srcuri = False
    appendfile = None
    try:
        local_files_dir = tempfile.mkdtemp(dir=tempdir)
        srctreebase = workspace[recipename]['srctreebase']
        upd_f, new_f, del_f = _export_local_files(srctree, rd, local_files_dir, srctreebase)
        if not no_remove:
            # Find list of existing patches in recipe file
            patches_dir = tempfile.mkdtemp(dir=tempdir)
            old_srcrev = rd.getVar('SRCREV') or ''
            upd_p, new_p, del_p = _export_patches(srctree, rd, old_srcrev,
                                                  patches_dir)
            logger.debug('Patches: update %s, new %s, delete %s' % (dict(upd_p), dict(new_p), dict(del_p)))

            # Remove deleted local files and "overlapping" patches
            remove_files = list(del_f.values()) + list(upd_p.values()) + list(del_p.values())
            if remove_files:
                removedentries = _remove_file_entries(srcuri, remove_files)[0]
                update_srcuri = True

        if appendlayerdir:
            files = dict((os.path.join(local_files_dir, key), val) for
                          key, val in list(upd_f.items()) + list(new_f.items()))
            removevalues = {}
            if update_srcuri:
                removevalues  = {'SRC_URI': removedentries}
                patchfields['SRC_URI'] = '\\\n    '.join(srcuri)
            if dry_run_outdir:
                logger.info('Creating bbappend (dry-run)')
            else:
                appendfile, destpath = oe.recipeutils.bbappend_recipe(
                        rd, appendlayerdir, files, wildcardver=wildcard_version,
                        extralines=patchfields, removevalues=removevalues,
                        redirect_output=dry_run_outdir)
        else:
            files_dir = _determine_files_dir(rd)
            for basepath, path in upd_f.items():
                logger.info('Updating file %s%s' % (basepath, dry_run_suffix))
                if os.path.isabs(basepath):
                    # Original file (probably with subdir pointing inside source tree)
                    # so we do not want to move it, just copy
                    _copy_file(basepath, path, dry_run_outdir=dry_run_outdir, base_outdir=recipedir)
                else:
                    _move_file(os.path.join(local_files_dir, basepath), path,
                               dry_run_outdir=dry_run_outdir, base_outdir=recipedir)
                update_srcuri= True
            for basepath, path in new_f.items():
                logger.info('Adding new file %s%s' % (basepath, dry_run_suffix))
                _move_file(os.path.join(local_files_dir, basepath),
                           os.path.join(files_dir, basepath),
                           dry_run_outdir=dry_run_outdir,
                           base_outdir=recipedir)
                srcuri.append('file://%s' % basepath)
                update_srcuri = True
            if update_srcuri:
                patchfields['SRC_URI'] = ' '.join(srcuri)
            ret = oe.recipeutils.patch_recipe(rd, recipefile, patchfields, redirect_output=dry_run_outdir)
    finally:
        shutil.rmtree(tempdir)
    if not 'git://' in orig_src_uri:
        logger.info('You will need to update SRC_URI within the recipe to '
                    'point to a git repository where you have pushed your '
                    'changes')

    _remove_source_files(appendlayerdir, remove_files, destpath, no_report_remove, dry_run=dry_run_outdir)
    return True, appendfile, remove_files

def _update_recipe_patch(recipename, workspace, srctree, rd, appendlayerdir, wildcard_version, no_remove, no_report_remove, initial_rev, dry_run_outdir=None, force_patch_refresh=False):
    """Implement the 'patch' mode of update-recipe"""
    import bb
    import oe.recipeutils

    recipefile = rd.getVar('FILE')
    recipedir = os.path.dirname(recipefile)
    append = workspace[recipename]['bbappend']
    if not os.path.exists(append):
        raise DevtoolError('unable to find workspace bbappend for recipe %s' %
                           recipename)

    initial_rev, update_rev, changed_revs, filter_patches = _get_patchset_revs(srctree, append, initial_rev, force_patch_refresh)
    if not initial_rev:
        raise DevtoolError('Unable to find initial revision - please specify '
                           'it with --initial-rev')

    appendfile = None
    dl_dir = rd.getVar('DL_DIR')
    if not dl_dir.endswith('/'):
        dl_dir += '/'

    dry_run_suffix = ' (dry-run)' if dry_run_outdir else ''

    tempdir = tempfile.mkdtemp(prefix='devtool')
    try:
        local_files_dir = tempfile.mkdtemp(dir=tempdir)
        if filter_patches:
            upd_f = {}
            new_f = {}
            del_f = {}
        else:
            srctreebase = workspace[recipename]['srctreebase']
            upd_f, new_f, del_f = _export_local_files(srctree, rd, local_files_dir, srctreebase)

        remove_files = []
        if not no_remove:
            # Get all patches from source tree and check if any should be removed
            all_patches_dir = tempfile.mkdtemp(dir=tempdir)
            _, _, del_p = _export_patches(srctree, rd, initial_rev,
                                          all_patches_dir)
            # Remove deleted local files and  patches
            remove_files = list(del_f.values()) + list(del_p.values())

        # Get updated patches from source tree
        patches_dir = tempfile.mkdtemp(dir=tempdir)
        upd_p, new_p, _ = _export_patches(srctree, rd, update_rev,
                                          patches_dir, changed_revs)
        logger.debug('Pre-filtering: update: %s, new: %s' % (dict(upd_p), dict(new_p)))
        if filter_patches:
            new_p = OrderedDict()
            upd_p = OrderedDict((k,v) for k,v in upd_p.items() if k in filter_patches)
            remove_files = [f for f in remove_files if f in filter_patches]
        updatefiles = False
        updaterecipe = False
        destpath = None
        srcuri = (rd.getVar('SRC_URI', False) or '').split()
        if appendlayerdir:
            files = OrderedDict((os.path.join(local_files_dir, key), val) for
                         key, val in list(upd_f.items()) + list(new_f.items()))
            files.update(OrderedDict((os.path.join(patches_dir, key), val) for
                              key, val in list(upd_p.items()) + list(new_p.items())))
            if files or remove_files:
                removevalues = None
                if remove_files:
                    removedentries, remaining = _remove_file_entries(
                                                    srcuri, remove_files)
                    if removedentries or remaining:
                        remaining = ['file://' + os.path.basename(item) for
                                     item in remaining]
                        removevalues = {'SRC_URI': removedentries + remaining}
                appendfile, destpath = oe.recipeutils.bbappend_recipe(
                                rd, appendlayerdir, files,
                                wildcardver=wildcard_version,
                                removevalues=removevalues,
                                redirect_output=dry_run_outdir)
            else:
                logger.info('No patches or local source files needed updating')
        else:
            # Update existing files
            files_dir = _determine_files_dir(rd)
            for basepath, path in upd_f.items():
                logger.info('Updating file %s' % basepath)
                if os.path.isabs(basepath):
                    # Original file (probably with subdir pointing inside source tree)
                    # so we do not want to move it, just copy
                    _copy_file(basepath, path,
                               dry_run_outdir=dry_run_outdir, base_outdir=recipedir)
                else:
                    _move_file(os.path.join(local_files_dir, basepath), path,
                               dry_run_outdir=dry_run_outdir, base_outdir=recipedir)
                updatefiles = True
            for basepath, path in upd_p.items():
                patchfn = os.path.join(patches_dir, basepath)
                if os.path.dirname(path) + '/' == dl_dir:
                    # This is a a downloaded patch file - we now need to
                    # replace the entry in SRC_URI with our local version
                    logger.info('Replacing remote patch %s with updated local version' % basepath)
                    path = os.path.join(files_dir, basepath)
                    _replace_srcuri_entry(srcuri, basepath, 'file://%s' % basepath)
                    updaterecipe = True
                else:
                    logger.info('Updating patch %s%s' % (basepath, dry_run_suffix))
                _move_file(patchfn, path,
                           dry_run_outdir=dry_run_outdir, base_outdir=recipedir)
                updatefiles = True
            # Add any new files
            for basepath, path in new_f.items():
                logger.info('Adding new file %s%s' % (basepath, dry_run_suffix))
                _move_file(os.path.join(local_files_dir, basepath),
                           os.path.join(files_dir, basepath),
                           dry_run_outdir=dry_run_outdir,
                           base_outdir=recipedir)
                srcuri.append('file://%s' % basepath)
                updaterecipe = True
            for basepath, path in new_p.items():
                logger.info('Adding new patch %s%s' % (basepath, dry_run_suffix))
                _move_file(os.path.join(patches_dir, basepath),
                           os.path.join(files_dir, basepath),
                           dry_run_outdir=dry_run_outdir,
                           base_outdir=recipedir)
                srcuri.append('file://%s' % basepath)
                updaterecipe = True
            # Update recipe, if needed
            if _remove_file_entries(srcuri, remove_files)[0]:
                updaterecipe = True
            if updaterecipe:
                if not dry_run_outdir:
                    logger.info('Updating recipe %s' % os.path.basename(recipefile))
                ret = oe.recipeutils.patch_recipe(rd, recipefile,
                                                  {'SRC_URI': ' '.join(srcuri)},
                                                  redirect_output=dry_run_outdir)
            elif not updatefiles:
                # Neither patches nor recipe were updated
                logger.info('No patches or files need updating')
                return False, None, []
    finally:
        shutil.rmtree(tempdir)

    _remove_source_files(appendlayerdir, remove_files, destpath, no_report_remove, dry_run=dry_run_outdir)
    return True, appendfile, remove_files

def _guess_recipe_update_mode(srctree, rdata):
    """Guess the recipe update mode to use"""
    src_uri = (rdata.getVar('SRC_URI', False) or '').split()
    git_uris = [uri for uri in src_uri if uri.startswith('git://')]
    if not git_uris:
        return 'patch'
    # Just use the first URI for now
    uri = git_uris[0]
    # Check remote branch
    params = bb.fetch.decodeurl(uri)[5]
    upstr_branch = params['branch'] if 'branch' in params else 'master'
    # Check if current branch HEAD is found in upstream branch
    stdout, _ = bb.process.run('git rev-parse HEAD', cwd=srctree)
    head_rev = stdout.rstrip()
    stdout, _ = bb.process.run('git branch -r --contains %s' % head_rev,
                               cwd=srctree)
    remote_brs = [branch.strip() for branch in stdout.splitlines()]
    if 'origin/' + upstr_branch in remote_brs:
        return 'srcrev'

    return 'patch'

def _update_recipe(recipename, workspace, rd, mode, appendlayerdir, wildcard_version, no_remove, initial_rev, no_report_remove=False, dry_run_outdir=None, no_overrides=False, force_patch_refresh=False):
    srctree = workspace[recipename]['srctree']
    if mode == 'auto':
        mode = _guess_recipe_update_mode(srctree, rd)

    override_branches = []
    mainbranch = None
    startbranch = None
    if not no_overrides:
        stdout, _ = bb.process.run('git branch', cwd=srctree)
        other_branches = []
        for line in stdout.splitlines():
            branchname = line[2:]
            if line.startswith('* '):
                startbranch = branchname
            if branchname.startswith(override_branch_prefix):
                override_branches.append(branchname)
            else:
                other_branches.append(branchname)

        if override_branches:
            logger.debug('_update_recipe: override branches: %s' % override_branches)
            logger.debug('_update_recipe: other branches: %s' % other_branches)
            if startbranch.startswith(override_branch_prefix):
                if len(other_branches) == 1:
                    mainbranch = other_branches[1]
                else:
                    raise DevtoolError('Unable to determine main branch - please check out the main branch in source tree first')
            else:
                mainbranch = startbranch

    checkedout = None
    anyupdated = False
    appendfile = None
    allremoved = []
    if override_branches:
        logger.info('Handling main branch (%s)...' % mainbranch)
        if startbranch != mainbranch:
            bb.process.run('git checkout %s' % mainbranch, cwd=srctree)
        checkedout = mainbranch
    try:
        branchlist = [mainbranch] + override_branches
        for branch in branchlist:
            crd = bb.data.createCopy(rd)
            if branch != mainbranch:
                logger.info('Handling branch %s...' % branch)
                override = branch[len(override_branch_prefix):]
                crd.appendVar('OVERRIDES', ':%s' % override)
                bb.process.run('git checkout %s' % branch, cwd=srctree)
                checkedout = branch

            if mode == 'srcrev':
                updated, appendf, removed = _update_recipe_srcrev(recipename, workspace, srctree, crd, appendlayerdir, wildcard_version, no_remove, no_report_remove, dry_run_outdir)
            elif mode == 'patch':
                updated, appendf, removed = _update_recipe_patch(recipename, workspace, srctree, crd, appendlayerdir, wildcard_version, no_remove, no_report_remove, initial_rev, dry_run_outdir, force_patch_refresh)
            else:
                raise DevtoolError('update_recipe: invalid mode %s' % mode)
            if updated:
                anyupdated = True
            if appendf:
                appendfile = appendf
            allremoved.extend(removed)
    finally:
        if startbranch and checkedout != startbranch:
            bb.process.run('git checkout %s' % startbranch, cwd=srctree)

    return anyupdated, appendfile, allremoved

def update_recipe(args, config, basepath, workspace):
    """Entry point for the devtool 'update-recipe' subcommand"""
    check_workspace_recipe(workspace, args.recipename)

    if args.append:
        if not os.path.exists(args.append):
            raise DevtoolError('bbappend destination layer directory "%s" '
                               'does not exist' % args.append)
        if not os.path.exists(os.path.join(args.append, 'conf', 'layer.conf')):
            raise DevtoolError('conf/layer.conf not found in bbappend '
                               'destination layer "%s"' % args.append)

    tinfoil = setup_tinfoil(basepath=basepath, tracking=True)
    try:

        rd = parse_recipe(config, tinfoil, args.recipename, True)
        if not rd:
            return 1

        dry_run_output = None
        dry_run_outdir = None
        if args.dry_run:
            dry_run_output = tempfile.TemporaryDirectory(prefix='devtool')
            dry_run_outdir = dry_run_output.name
        updated, _, _ = _update_recipe(args.recipename, workspace, rd, args.mode, args.append, args.wildcard_version, args.no_remove, args.initial_rev, dry_run_outdir=dry_run_outdir, no_overrides=args.no_overrides, force_patch_refresh=args.force_patch_refresh)

        if updated:
            rf = rd.getVar('FILE')
            if rf.startswith(config.workspace_path):
                logger.warning('Recipe file %s has been updated but is inside the workspace - you will need to move it (and any associated files next to it) out to the desired layer before using "devtool reset" in order to keep any changes' % rf)
    finally:
        tinfoil.shutdown()

    return 0


def status(args, config, basepath, workspace):
    """Entry point for the devtool 'status' subcommand"""
    if workspace:
        for recipe, value in sorted(workspace.items()):
            recipefile = value['recipefile']
            if recipefile:
                recipestr = ' (%s)' % recipefile
            else:
                recipestr = ''
            print("%s: %s%s" % (recipe, value['srctree'], recipestr))
    else:
        logger.info('No recipes currently in your workspace - you can use "devtool modify" to work on an existing recipe or "devtool add" to add a new one')
    return 0


def _reset(recipes, no_clean, config, basepath, workspace):
    """Reset one or more recipes"""
    import oe.path

    def clean_preferred_provider(pn, layerconf_path):
        """Remove PREFERRED_PROVIDER from layer.conf'"""
        import re
        layerconf_file = os.path.join(layerconf_path, 'conf', 'layer.conf')
        new_layerconf_file = os.path.join(layerconf_path, 'conf', '.layer.conf')
        pprovider_found = False
        with open(layerconf_file, 'r') as f:
            lines = f.readlines()
            with open(new_layerconf_file, 'a') as nf:
                for line in lines:
                    pprovider_exp = r'^PREFERRED_PROVIDER_.*? = "' + pn + r'"$'
                    if not re.match(pprovider_exp, line):
                        nf.write(line)
                    else:
                        pprovider_found = True
        if pprovider_found:
            shutil.move(new_layerconf_file, layerconf_file)
        else:
            os.remove(new_layerconf_file)

    if recipes and not no_clean:
        if len(recipes) == 1:
            logger.info('Cleaning sysroot for recipe %s...' % recipes[0])
        else:
            logger.info('Cleaning sysroot for recipes %s...' % ', '.join(recipes))
        # If the recipe file itself was created in the workspace, and
        # it uses BBCLASSEXTEND, then we need to also clean the other
        # variants
        targets = []
        for recipe in recipes:
            targets.append(recipe)
            recipefile = workspace[recipe]['recipefile']
            if recipefile and os.path.exists(recipefile):
                targets.extend(get_bbclassextend_targets(recipefile, recipe))
        try:
            exec_build_env_command(config.init_path, basepath, 'bitbake -c clean %s' % ' '.join(targets))
        except bb.process.ExecutionError as e:
            raise DevtoolError('Command \'%s\' failed, output:\n%s\nIf you '
                                'wish, you may specify -n/--no-clean to '
                                'skip running this command when resetting' %
                                (e.command, e.stdout))

    for pn in recipes:
        _check_preserve(config, pn)

        appendfile = workspace[pn]['bbappend']
        if os.path.exists(appendfile):
            # This shouldn't happen, but is possible if devtool errored out prior to
            # writing the md5 file. We need to delete this here or the recipe won't
            # actually be reset
            os.remove(appendfile)

        preservepath = os.path.join(config.workspace_path, 'attic', pn, pn)
        def preservedir(origdir):
            if os.path.exists(origdir):
                for root, dirs, files in os.walk(origdir):
                    for fn in files:
                        logger.warning('Preserving %s in %s' % (fn, preservepath))
                        _move_file(os.path.join(origdir, fn),
                                   os.path.join(preservepath, fn))
                    for dn in dirs:
                        preservedir(os.path.join(root, dn))
                os.rmdir(origdir)

        recipefile = workspace[pn]['recipefile']
        if recipefile and oe.path.is_path_parent(config.workspace_path, recipefile):
            # This should always be true if recipefile is set, but just in case
            preservedir(os.path.dirname(recipefile))
        # We don't automatically create this dir next to appends, but the user can
        preservedir(os.path.join(config.workspace_path, 'appends', pn))

        srctreebase = workspace[pn]['srctreebase']
        if os.path.isdir(srctreebase):
            if os.listdir(srctreebase):
                # We don't want to risk wiping out any work in progress
                logger.info('Leaving source tree %s as-is; if you no '
                            'longer need it then please delete it manually'
                            % srctreebase)
            else:
                # This is unlikely, but if it's empty we can just remove it
                os.rmdir(srctreebase)

        clean_preferred_provider(pn, config.workspace_path)

def reset(args, config, basepath, workspace):
    """Entry point for the devtool 'reset' subcommand"""
    import bb
    if args.recipename:
        if args.all:
            raise DevtoolError("Recipe cannot be specified if -a/--all is used")
        else:
            for recipe in args.recipename:
                check_workspace_recipe(workspace, recipe, checksrc=False)
    elif not args.all:
        raise DevtoolError("Recipe must be specified, or specify -a/--all to "
                           "reset all recipes")
    if args.all:
        recipes = list(workspace.keys())
    else:
        recipes = args.recipename

    _reset(recipes, args.no_clean, config, basepath, workspace)

    return 0


def _get_layer(layername, d):
    """Determine the base layer path for the specified layer name/path"""
    layerdirs = d.getVar('BBLAYERS').split()
    layers = {}    # {basename: layer_paths}
    for p in layerdirs:
        bn = os.path.basename(p)
        if bn not in layers:
            layers[bn] = [p]
        else:
            layers[bn].append(p)
    # Provide some shortcuts
    if layername.lower() in ['oe-core', 'openembedded-core']:
        layername = 'meta'
    layer_paths = layers.get(layername, None)
    if not layer_paths:
        return os.path.abspath(layername)
    elif len(layer_paths) == 1:
        return os.path.abspath(layer_paths[0])
    else:
        # multiple layers having the same base name
        logger.warning("Multiple layers have the same base name '%s', use the first one '%s'." % (layername, layer_paths[0]))
        logger.warning("Consider using path instead of base name to specify layer:\n\t\t%s" % '\n\t\t'.join(layer_paths))
        return os.path.abspath(layer_paths[0])


def finish(args, config, basepath, workspace):
    """Entry point for the devtool 'finish' subcommand"""
    import bb
    import oe.recipeutils

    check_workspace_recipe(workspace, args.recipename)

    dry_run_suffix = ' (dry-run)' if args.dry_run else ''

    # Grab the equivalent of COREBASE without having to initialise tinfoil
    corebasedir = os.path.abspath(os.path.join(os.path.dirname(__file__), '..', '..', '..'))

    srctree = workspace[args.recipename]['srctree']
    check_git_repo_op(srctree, [corebasedir])
    dirty = check_git_repo_dirty(srctree)
    if dirty:
        if args.force:
            logger.warning('Source tree is not clean, continuing as requested by -f/--force')
        else:
            raise DevtoolError('Source tree is not clean:\n\n%s\nEnsure you have committed your changes or use -f/--force if you are sure there\'s nothing that needs to be committed' % dirty)

    no_clean = args.no_clean
    tinfoil = setup_tinfoil(basepath=basepath, tracking=True)
    try:
        rd = parse_recipe(config, tinfoil, args.recipename, True)
        if not rd:
            return 1

        destlayerdir = _get_layer(args.destination, tinfoil.config_data)
        recipefile = rd.getVar('FILE')
        recipedir = os.path.dirname(recipefile)
        origlayerdir = oe.recipeutils.find_layerdir(recipefile)

        if not os.path.isdir(destlayerdir):
            raise DevtoolError('Unable to find layer or directory matching "%s"' % args.destination)

        if os.path.abspath(destlayerdir) == config.workspace_path:
            raise DevtoolError('"%s" specifies the workspace layer - that is not a valid destination' % args.destination)

        # If it's an upgrade, grab the original path
        origpath = None
        origfilelist = None
        append = workspace[args.recipename]['bbappend']
        with open(append, 'r') as f:
            for line in f:
                if line.startswith('# original_path:'):
                    origpath = line.split(':')[1].strip()
                elif line.startswith('# original_files:'):
                    origfilelist = line.split(':')[1].split()

        destlayerbasedir = oe.recipeutils.find_layerdir(destlayerdir)

        if origlayerdir == config.workspace_path:
            # Recipe file itself is in workspace, update it there first
            appendlayerdir = None
            origrelpath = None
            if origpath:
                origlayerpath = oe.recipeutils.find_layerdir(origpath)
                if origlayerpath:
                    origrelpath = os.path.relpath(origpath, origlayerpath)
            destpath = oe.recipeutils.get_bbfile_path(rd, destlayerdir, origrelpath)
            if not destpath:
                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))
            # Warn if the layer isn't in bblayers.conf (the code to create a bbappend will do this in other cases)
            layerdirs = [os.path.abspath(layerdir) for layerdir in rd.getVar('BBLAYERS').split()]
            if not os.path.abspath(destlayerbasedir) in layerdirs:
                bb.warn('Specified destination layer is not currently enabled in bblayers.conf, so the %s recipe will now be unavailable in your current configuration until you add the layer there' % args.recipename)

        elif destlayerdir == origlayerdir:
            # Same layer, update the original recipe
            appendlayerdir = None
            destpath = None
        else:
            # Create/update a bbappend in the specified layer
            appendlayerdir = destlayerdir
            destpath = None

        # Actually update the recipe / bbappend
        removing_original = (origpath and origfilelist and oe.recipeutils.find_layerdir(origpath) == destlayerbasedir)
        dry_run_output = None
        dry_run_outdir = None
        if args.dry_run:
            dry_run_output = tempfile.TemporaryDirectory(prefix='devtool')
            dry_run_outdir = dry_run_output.name
        updated, appendfile, removed = _update_recipe(args.recipename, workspace, rd, args.mode, appendlayerdir, wildcard_version=True, no_remove=False, no_report_remove=removing_original, initial_rev=args.initial_rev, dry_run_outdir=dry_run_outdir, no_overrides=args.no_overrides, force_patch_refresh=args.force_patch_refresh)
        removed = [os.path.relpath(pth, recipedir) for pth in removed]

        # Remove any old files in the case of an upgrade
        if removing_original:
            for fn in origfilelist:
                fnp = os.path.join(origpath, fn)
                if fn in removed or not os.path.exists(os.path.join(recipedir, fn)):
                    logger.info('Removing file %s%s' % (fnp, dry_run_suffix))
                if not args.dry_run:
                    try:
                        os.remove(fnp)
                    except FileNotFoundError:
                        pass

        if origlayerdir == config.workspace_path and destpath:
            # Recipe file itself is in the workspace - need to move it and any
            # associated files to the specified layer
            no_clean = True
            logger.info('Moving recipe file to %s%s' % (destpath, dry_run_suffix))
            for root, _, files in os.walk(recipedir):
                for fn in files:
                    srcpath = os.path.join(root, fn)
                    relpth = os.path.relpath(os.path.dirname(srcpath), recipedir)
                    destdir = os.path.abspath(os.path.join(destpath, relpth))
                    destfp = os.path.join(destdir, fn)
                    _move_file(srcpath, destfp, dry_run_outdir=dry_run_outdir, base_outdir=destpath)

        if dry_run_outdir:
            import difflib
            comparelist = []
            for root, _, files in os.walk(dry_run_outdir):
                for fn in files:
                    outf = os.path.join(root, fn)
                    relf = os.path.relpath(outf, dry_run_outdir)
                    logger.debug('dry-run: output file %s' % relf)
                    if fn.endswith('.bb'):
                        if origfilelist and origpath and destpath:
                            # Need to match this up with the pre-upgrade recipe file
                            for origf in origfilelist:
                                if origf.endswith('.bb'):
                                    comparelist.append((os.path.abspath(os.path.join(origpath, origf)),
                                                        outf,
                                                        os.path.abspath(os.path.join(destpath, relf))))
                                    break
                        else:
                            # Compare to the existing recipe
                            comparelist.append((recipefile, outf, recipefile))
                    elif fn.endswith('.bbappend'):
                        if appendfile:
                            if os.path.exists(appendfile):
                                comparelist.append((appendfile, outf, appendfile))
                            else:
                                comparelist.append((None, outf, appendfile))
                    else:
                        if destpath:
                            recipedest = destpath
                        elif appendfile:
                            recipedest = os.path.dirname(appendfile)
                        else:
                            recipedest = os.path.dirname(recipefile)
                        destfp = os.path.join(recipedest, relf)
                        if os.path.exists(destfp):
                            comparelist.append((destfp, outf, destfp))
            output = ''
            for oldfile, newfile, newfileshow in comparelist:
                if oldfile:
                    with open(oldfile, 'r') as f:
                        oldlines = f.readlines()
                else:
                    oldfile = '/dev/null'
                    oldlines = []
                with open(newfile, 'r') as f:
                    newlines = f.readlines()
                if not newfileshow:
                    newfileshow = newfile
                diff = difflib.unified_diff(oldlines, newlines, oldfile, newfileshow)
                difflines = list(diff)
                if difflines:
                    output += ''.join(difflines)
            if output:
                logger.info('Diff of changed files:\n%s' % output)
    finally:
        tinfoil.shutdown()

    # Everything else has succeeded, we can now reset
    if args.dry_run:
        logger.info('Resetting recipe (dry-run)')
    else:
        _reset([args.recipename], no_clean=no_clean, config=config, basepath=basepath, workspace=workspace)

    return 0


def get_default_srctree(config, recipename=''):
    """Get the default srctree path"""
    srctreeparent = config.get('General', 'default_source_parent_dir', config.workspace_path)
    if recipename:
        return os.path.join(srctreeparent, 'sources', recipename)
    else:
        return os.path.join(srctreeparent, 'sources')

def register_commands(subparsers, context):
    """Register devtool subcommands from this plugin"""

    defsrctree = get_default_srctree(context.config)
    parser_add = subparsers.add_parser('add', help='Add a new recipe',
                                       description='Adds a new recipe to the workspace to build a specified source tree. Can optionally fetch a remote URI and unpack it to create the source tree.',
                                       group='starting', order=100)
    parser_add.add_argument('recipename', nargs='?', help='Name for new recipe to add (just name - no version, path or extension). If not specified, will attempt to auto-detect it.')
    parser_add.add_argument('srctree', nargs='?', help='Path to external source tree. If not specified, a subdirectory of %s will be used.' % defsrctree)
    parser_add.add_argument('fetchuri', nargs='?', help='Fetch the specified URI and extract it to create the source tree')
    group = parser_add.add_mutually_exclusive_group()
    group.add_argument('--same-dir', '-s', help='Build in same directory as source', action="store_true")
    group.add_argument('--no-same-dir', help='Force build in a separate build directory', action="store_true")
    parser_add.add_argument('--fetch', '-f', help='Fetch the specified URI and extract it to create the source tree (deprecated - pass as positional argument instead)', metavar='URI')
    parser_add.add_argument('--fetch-dev', help='For npm, also fetch devDependencies', action="store_true")
    parser_add.add_argument('--version', '-V', help='Version to use within recipe (PV)')
    parser_add.add_argument('--no-git', '-g', help='If fetching source, do not set up source tree as a git repository', action="store_true")
    group = parser_add.add_mutually_exclusive_group()
    group.add_argument('--srcrev', '-S', help='Source revision to fetch if fetching from an SCM such as git (default latest)')
    group.add_argument('--autorev', '-a', help='When fetching from a git repository, set SRCREV in the recipe to a floating revision instead of fixed', action="store_true")
    parser_add.add_argument('--srcbranch', '-B', help='Branch in source repository if fetching from an SCM such as git (default master)')
    parser_add.add_argument('--binary', '-b', help='Treat the source tree as something that should be installed verbatim (no compilation, same directory structure). Useful with binary packages e.g. RPMs.', action='store_true')
    parser_add.add_argument('--also-native', help='Also add native variant (i.e. support building recipe for the build host as well as the target machine)', action='store_true')
    parser_add.add_argument('--src-subdir', help='Specify subdirectory within source tree to use', metavar='SUBDIR')
    parser_add.add_argument('--mirrors', help='Enable PREMIRRORS and MIRRORS for source tree fetching (disable by default).', action="store_true")
    parser_add.add_argument('--provides', '-p', help='Specify an alias for the item provided by the recipe. E.g. virtual/libgl')
    parser_add.set_defaults(func=add, fixed_setup=context.fixed_setup)

    parser_modify = subparsers.add_parser('modify', help='Modify the source for an existing recipe',
                                       description='Sets up the build environment to modify the source for an existing recipe. The default behaviour is to extract the source being fetched by the recipe into a git tree so you can work on it; alternatively if you already have your own pre-prepared source tree you can specify -n/--no-extract.',
                                       group='starting', order=90)
    parser_modify.add_argument('recipename', help='Name of existing recipe to edit (just name - no version, path or extension)')
    parser_modify.add_argument('srctree', nargs='?', help='Path to external source tree. If not specified, a subdirectory of %s will be used.' % defsrctree)
    parser_modify.add_argument('--wildcard', '-w', action="store_true", help='Use wildcard for unversioned bbappend')
    group = parser_modify.add_mutually_exclusive_group()
    group.add_argument('--extract', '-x', action="store_true", help='Extract source for recipe (default)')
    group.add_argument('--no-extract', '-n', action="store_true", help='Do not extract source, expect it to exist')
    group = parser_modify.add_mutually_exclusive_group()
    group.add_argument('--same-dir', '-s', help='Build in same directory as source', action="store_true")
    group.add_argument('--no-same-dir', help='Force build in a separate build directory', action="store_true")
    parser_modify.add_argument('--branch', '-b', default="devtool", help='Name for development branch to checkout (when not using -n/--no-extract) (default "%(default)s")')
    parser_modify.add_argument('--no-overrides', '-O', action="store_true", help='Do not create branches for other override configurations')
    parser_modify.add_argument('--keep-temp', help='Keep temporary directory (for debugging)', action="store_true")
    parser_modify.set_defaults(func=modify, fixed_setup=context.fixed_setup)

    parser_extract = subparsers.add_parser('extract', help='Extract the source for an existing recipe',
                                       description='Extracts the source for an existing recipe',
                                       group='advanced')
    parser_extract.add_argument('recipename', help='Name of recipe to extract the source for')
    parser_extract.add_argument('srctree', help='Path to where to extract the source tree')
    parser_extract.add_argument('--branch', '-b', default="devtool", help='Name for development branch to checkout (default "%(default)s")')
    parser_extract.add_argument('--no-overrides', '-O', action="store_true", help='Do not create branches for other override configurations')
    parser_extract.add_argument('--keep-temp', action="store_true", help='Keep temporary directory (for debugging)')
    parser_extract.set_defaults(func=extract, fixed_setup=context.fixed_setup)

    parser_sync = subparsers.add_parser('sync', help='Synchronize the source tree for an existing recipe',
                                       description='Synchronize the previously extracted source tree for an existing recipe',
                                       formatter_class=argparse.ArgumentDefaultsHelpFormatter,
                                       group='advanced')
    parser_sync.add_argument('recipename', help='Name of recipe to sync the source for')
    parser_sync.add_argument('srctree', help='Path to the source tree')
    parser_sync.add_argument('--branch', '-b', default="devtool", help='Name for development branch to checkout')
    parser_sync.add_argument('--keep-temp', action="store_true", help='Keep temporary directory (for debugging)')
    parser_sync.set_defaults(func=sync, fixed_setup=context.fixed_setup)

    parser_rename = subparsers.add_parser('rename', help='Rename a recipe file in the workspace',
                                       description='Renames the recipe file for a recipe in the workspace, changing the name or version part or both, ensuring that all references within the workspace are updated at the same time. Only works when the recipe file itself is in the workspace, e.g. after devtool add. Particularly useful when devtool add did not automatically determine the correct name.',
                                       group='working', order=10)
    parser_rename.add_argument('recipename', help='Current name of recipe to rename')
    parser_rename.add_argument('newname', nargs='?', help='New name for recipe (optional, not needed if you only want to change the version)')
    parser_rename.add_argument('--version', '-V', help='Change the version (NOTE: this does not change the version fetched by the recipe, just the version in the recipe file name)')
    parser_rename.add_argument('--no-srctree', '-s', action='store_true', help='Do not rename the source tree directory (if the default source tree path has been used) - keeping the old name may be desirable if there are internal/other external references to this path')
    parser_rename.set_defaults(func=rename)

    parser_update_recipe = subparsers.add_parser('update-recipe', help='Apply changes from external source tree to recipe',
                                       description='Applies changes from external source tree to a recipe (updating/adding/removing patches as necessary, or by updating SRCREV). Note that these changes need to have been committed to the git repository in order to be recognised.',
                                       group='working', order=-90)
    parser_update_recipe.add_argument('recipename', help='Name of recipe to update')
    parser_update_recipe.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')
    parser_update_recipe.add_argument('--initial-rev', help='Override starting revision for patches')
    parser_update_recipe.add_argument('--append', '-a', help='Write changes to a bbappend in the specified layer instead of the recipe', metavar='LAYERDIR')
    parser_update_recipe.add_argument('--wildcard-version', '-w', help='In conjunction with -a/--append, use a wildcard to make the bbappend apply to any recipe version', action='store_true')
    parser_update_recipe.add_argument('--no-remove', '-n', action="store_true", help='Don\'t remove patches, only add or update')
    parser_update_recipe.add_argument('--no-overrides', '-O', action="store_true", help='Do not handle other override branches (if they exist)')
    parser_update_recipe.add_argument('--dry-run', '-N', action="store_true", help='Dry-run (just report changes instead of writing them)')
    parser_update_recipe.add_argument('--force-patch-refresh', action="store_true", help='Update patches in the layer even if they have not been modified (useful for refreshing patch context)')
    parser_update_recipe.set_defaults(func=update_recipe)

    parser_status = subparsers.add_parser('status', help='Show workspace status',
                                          description='Lists recipes currently in your workspace and the paths to their respective external source trees',
                                          group='info', order=100)
    parser_status.set_defaults(func=status)

    parser_reset = subparsers.add_parser('reset', help='Remove a recipe from your workspace',
                                         description='Removes the specified recipe(s) from your workspace (resetting its state back to that defined by the metadata).',
                                         group='working', order=-100)
    parser_reset.add_argument('recipename', nargs='*', help='Recipe to reset')
    parser_reset.add_argument('--all', '-a', action="store_true", help='Reset all recipes (clear workspace)')
    parser_reset.add_argument('--no-clean', '-n', action="store_true", help='Don\'t clean the sysroot to remove recipe output')
    parser_reset.set_defaults(func=reset)

    parser_finish = subparsers.add_parser('finish', help='Finish working on a recipe in your workspace',
                                         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. Note that your changes must have been committed to the git repository in order to be recognised.',
                                         group='working', order=-100)
    parser_finish.add_argument('recipename', help='Recipe to finish')
    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.')
    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')
    parser_finish.add_argument('--initial-rev', help='Override starting revision for patches')
    parser_finish.add_argument('--force', '-f', action="store_true", help='Force continuing even if there are uncommitted changes in the source tree repository')
    parser_finish.add_argument('--no-clean', '-n', action="store_true", help='Don\'t clean the sysroot to remove recipe output')
    parser_finish.add_argument('--no-overrides', '-O', action="store_true", help='Do not handle other override branches (if they exist)')
    parser_finish.add_argument('--dry-run', '-N', action="store_true", help='Dry-run (just report changes instead of writing them)')
    parser_finish.add_argument('--force-patch-refresh', action="store_true", help='Update patches in the layer even if they have not been modified (useful for refreshing patch context)')
    parser_finish.set_defaults(func=finish)
