#!/usr/bin/env python3
# ex:ts=4:sw=4:sts=4:et
# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
#
# Copyright 2011 Intel Corporation
# Authored-by:  Yu Ke <ke.yu@intel.com>
#               Paul Eggleton <paul.eggleton@intel.com>
#               Richard Purdie <richard.purdie@intel.com>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 as
# published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.

import fnmatch
import os, sys
import optparse
import logging
import subprocess
import tempfile
import configparser
import re
import copy
import pipes
import shutil
from collections import OrderedDict
from string import Template
from functools import reduce

__version__ = "0.2.1"

def logger_create():
    logger = logging.getLogger("")
    loggerhandler = logging.StreamHandler()
    loggerhandler.setFormatter(logging.Formatter("[%(asctime)s] %(message)s","%H:%M:%S"))
    logger.addHandler(loggerhandler)
    logger.setLevel(logging.INFO)
    return logger

logger = logger_create()

def get_current_branch(repodir=None):
    try:
        if not os.path.exists(os.path.join(repodir if repodir else '', ".git")):
            # Repo not created yet (i.e. during init) so just assume master
            return "master"
        branchname = runcmd("git symbolic-ref HEAD 2>/dev/null", repodir).strip()
        if branchname.startswith("refs/heads/"):
            branchname = branchname[11:]
        return branchname
    except subprocess.CalledProcessError:
        return ""

class Configuration(object):
    """
    Manages the configuration

    For an example config file, see combo-layer.conf.example

    """
    def __init__(self, options):
        for key, val in options.__dict__.items():
            setattr(self, key, val)

        def readsection(parser, section, repo):
            for (name, value) in parser.items(section):
                if value.startswith("@"):
                    self.repos[repo][name] = eval(value.strip("@"))
                else:
                    # Apply special type transformations for some properties.
                    # Type matches the RawConfigParser.get*() methods.
                    types = {'signoff': 'boolean', 'update': 'boolean', 'history': 'boolean'}
                    if name in types:
                        value = getattr(parser, 'get' + types[name])(section, name)
                    self.repos[repo][name] = value

        def readglobalsection(parser, section):
            for (name, value) in parser.items(section):
                if name == "commit_msg":
                    self.commit_msg_template = value

        logger.debug("Loading config file %s" % self.conffile)
        self.parser = configparser.ConfigParser()
        with open(self.conffile) as f:
            self.parser.readfp(f)

        # initialize default values
        self.commit_msg_template = "Automatic commit to update last_revision"

        self.repos = {}
        for repo in self.parser.sections():
            if repo == "combo-layer-settings":
                # special handling for global settings
                readglobalsection(self.parser, repo)
            else:
                self.repos[repo] = {}
                readsection(self.parser, repo, repo)

        # Load local configuration, if available
        self.localconffile = None
        self.localparser = None
        self.combobranch = None
        if self.conffile.endswith('.conf'):
            lcfile = self.conffile.replace('.conf', '-local.conf')
            if os.path.exists(lcfile):
                # Read combo layer branch
                self.combobranch = get_current_branch()
                logger.debug("Combo layer branch is %s" % self.combobranch)

                self.localconffile = lcfile
                logger.debug("Loading local config file %s" % self.localconffile)
                self.localparser = configparser.ConfigParser()
                with open(self.localconffile) as f:
                    self.localparser.readfp(f)

                for section in self.localparser.sections():
                    if '|' in section:
                        sectionvals = section.split('|')
                        repo = sectionvals[0]
                        if sectionvals[1] != self.combobranch:
                            continue
                    else:
                        repo = section
                    if repo in self.repos:
                        readsection(self.localparser, section, repo)

    def update(self, repo, option, value, initmode=False):
        # If the main config has the option already, that is what we
        # are expected to modify.
        if self.localparser and not self.parser.has_option(repo, option):
            parser = self.localparser
            section = "%s|%s" % (repo, self.combobranch)
            conffile = self.localconffile
            if initmode and not parser.has_section(section):
                parser.add_section(section)
        else:
            parser = self.parser
            section = repo
            conffile = self.conffile
        parser.set(section, option, value)
        with open(conffile, "w") as f:
            parser.write(f)
        self.repos[repo][option] = value

    def sanity_check(self, initmode=False):
        required_options=["src_uri", "local_repo_dir", "dest_dir", "last_revision"]
        if initmode:
            required_options.remove("last_revision")
        msg = ""
        missing_options = []
        for name in self.repos:
            for option in required_options:
                if option not in self.repos[name]:
                    msg = "%s\nOption %s is not defined for component %s" %(msg, option, name)
                    missing_options.append(option)
            # Sanitize dest_dir so that we do not have to deal with edge cases
            # (unset, empty string, double slashes) in the rest of the code.
            # It not being set will still be flagged as error because it is
            # listed as required option above; that could be changed now.
            dest_dir = os.path.normpath(self.repos[name].get("dest_dir", "."))
            self.repos[name]["dest_dir"] = "." if not dest_dir else dest_dir
        if msg != "":
            logger.error("configuration file %s has the following error: %s" % (self.conffile,msg))
            if self.localconffile and 'last_revision' in missing_options:
                logger.error("local configuration file %s may be missing configuration for combo branch %s" % (self.localconffile, self.combobranch))
            sys.exit(1)

        # filterdiff is required by action_splitpatch, so check its availability
        if subprocess.call("which filterdiff > /dev/null 2>&1", shell=True) != 0:
            logger.error("ERROR: patchutils package is missing, please install it (e.g. # apt-get install patchutils)")
            sys.exit(1)

def runcmd(cmd,destdir=None,printerr=True,out=None,env=None):
    """
        execute command, raise CalledProcessError if fail
        return output if succeed
    """
    logger.debug("run cmd '%s' in %s" % (cmd, os.getcwd() if destdir is None else destdir))
    if not out:
        out = tempfile.TemporaryFile()
        err = out
    else:
        err = tempfile.TemporaryFile()
    try:
        subprocess.check_call(cmd, stdout=out, stderr=err, cwd=destdir, shell=isinstance(cmd, str), env=env or os.environ)
    except subprocess.CalledProcessError as e:
        err.seek(0)
        if printerr:
            logger.error("%s" % err.read())
        raise e

    err.seek(0)
    output = err.read().decode('utf-8')
    logger.debug("output: %s" % output.replace(chr(0), '\\0'))
    return output

def action_init(conf, args):
    """
        Clone component repositories
        Check git is initialised; if not, copy initial data from component repos
    """
    for name in conf.repos:
        ldir = conf.repos[name]['local_repo_dir']
        if not os.path.exists(ldir):
            logger.info("cloning %s to %s" %(conf.repos[name]['src_uri'], ldir))
            subprocess.check_call("git clone %s %s" % (conf.repos[name]['src_uri'], ldir), shell=True)
    if not os.path.exists(".git"):
        runcmd("git init")
        if conf.history:
            # Need a common ref for all trees.
            runcmd('git commit -m "initial empty commit" --allow-empty')
            startrev = runcmd('git rev-parse master').strip()

        for name in conf.repos:
            repo = conf.repos[name]
            ldir = repo['local_repo_dir']
            branch = repo.get('branch', "master")
            lastrev = repo.get('last_revision', None)
            if lastrev and lastrev != "HEAD":
                initialrev = lastrev
                if branch:
                    if not check_rev_branch(name, ldir, lastrev, branch):
                        sys.exit(1)
                logger.info("Copying data from %s at specified revision %s..." % (name, lastrev))
            else:
                lastrev = None
                initialrev = branch
                logger.info("Copying data from %s..." % name)
            # Sanity check initialrev and turn it into hash (required for copying history,
            # because resolving a name ref only works in the component repo).
            rev = runcmd('git rev-parse %s' % initialrev, ldir).strip()
            if rev != initialrev:
                try:
                    refs = runcmd('git show-ref -s %s' % initialrev, ldir).split('\n')
                    if len(set(refs)) > 1:
                        # Happens for example when configured to track
                        # "master" and there is a refs/heads/master. The
                        # traditional behavior from "git archive" (preserved
                        # here) it to choose the first one. This might not be
                        # intended, so at least warn about it.
                        logger.warn("%s: initial revision '%s' not unique, picking result of rev-parse = %s" %
                                    (name, initialrev, refs[0]))
                        initialrev = rev
                except:
                    # show-ref fails for hashes. Skip the sanity warning in that case.
                    pass
                initialrev = rev
            dest_dir = repo['dest_dir']
            if dest_dir != ".":
                extract_dir = os.path.join(os.getcwd(), dest_dir)
                if not os.path.exists(extract_dir):
                    os.makedirs(extract_dir)
            else:
                extract_dir = os.getcwd()
            file_filter = repo.get('file_filter', "")
            exclude_patterns = repo.get('file_exclude', '').split()
            def copy_selected_files(initialrev, extract_dir, file_filter, exclude_patterns, ldir,
                                    subdir=""):
                # When working inside a filtered branch which had the
                # files already moved, we need to prepend the
                # subdirectory to all filters, otherwise they would
                # not match.
                if subdir == '.':
                    subdir = ''
                elif subdir:
                    subdir = os.path.normpath(subdir)
                    file_filter = ' '.join([subdir + '/' + x for x in file_filter.split()])
                    exclude_patterns = [subdir + '/' + x for x in exclude_patterns]
                # To handle both cases, we cd into the target
                # directory and optionally tell tar to strip the path
                # prefix when the files were already moved.
                subdir_components = len(subdir.split(os.path.sep)) if subdir else 0
                strip=('--strip-components=%d' % subdir_components) if subdir else ''
                # TODO: file_filter wild cards do not work (and haven't worked before either), because
                # a) GNU tar requires a --wildcards parameter before turning on wild card matching.
                # b) The semantic is not as intendend (src/*.c also matches src/foo/bar.c,
                #    in contrast to the other use of file_filter as parameter of "git archive"
                #    where it only matches .c files directly in src).
                files = runcmd("git archive %s %s | tar -x -v %s -C %s %s" %
                               (initialrev, subdir,
                                strip, extract_dir, file_filter),
                               ldir)
                if exclude_patterns:
                    # Implement file removal by letting tar create the
                    # file and then deleting it in the file system
                    # again. Uses the list of files created by tar (easier
                    # than walking the tree).
                    for file in files.split('\n'):
                        for pattern in exclude_patterns:
                            if fnmatch.fnmatch(file, pattern):
                                os.unlink(os.path.join(*([extract_dir] + ['..'] * subdir_components + [file])))
                                break

            if not conf.history:
                copy_selected_files(initialrev, extract_dir, file_filter, exclude_patterns, ldir)
            else:
                # First fetch remote history into local repository.
                # We need a ref for that, so ensure that there is one.
                refname = "combo-layer-init-%s" % name
                runcmd("git branch -f %s %s" % (refname, initialrev), ldir)
                runcmd("git fetch %s %s" % (ldir, refname))
                runcmd("git branch -D %s" % refname, ldir)
                # Make that the head revision.
                runcmd("git checkout -b %s %s" % (name, initialrev))
                # Optional: cut the history by replacing the given
                # start point(s) with commits providing the same
                # content (aka tree), but with commit information that
                # makes it clear that this is an artifically created
                # commit and nothing the original authors had anything
                # to do with.
                since_rev = repo.get('since_revision', '')
                if since_rev:
                    committer = runcmd('git var GIT_AUTHOR_IDENT').strip()
                    # Same time stamp, no name.
                    author = re.sub('.* (\d+ [+-]\d+)', r'unknown <unknown> \1', committer)
                    logger.info('author %s' % author)
                    for rev in since_rev.split():
                        # Resolve in component repo...
                        rev = runcmd('git log --oneline --no-abbrev-commit -n1 %s' % rev, ldir).split()[0]
                        # ... and then get the tree in current
                        # one. The commit should be in both repos with
                        # the same tree, but better check here.
                        tree = runcmd('git show -s --pretty=format:%%T %s' % rev).strip()
                        with tempfile.NamedTemporaryFile() as editor:
                            editor.write('''cat >$1 <<EOF
tree %s
author %s
committer %s

%s: squashed import of component

This commit copies the entire set of files as found in
%s %s

For more information about previous commits, see the
upstream repository.

Commit created by combo-layer.
EOF
''' % (tree, author, committer, name, name, since_rev))
                            editor.flush()
                            os.environ['GIT_EDITOR'] = 'sh %s' % editor.name
                            runcmd('git replace --edit %s' % rev)

                # Optional: rewrite history to change commit messages or to move files.
                if 'hook' in repo or dest_dir != ".":
                    filter_branch = ['git', 'filter-branch', '--force']
                    with tempfile.NamedTemporaryFile() as hookwrapper:
                        if 'hook' in repo:
                            # Create a shell script wrapper around the original hook that
                            # can be used by git filter-branch. Hook may or may not have
                            # an absolute path.
                            hook = repo['hook']
                            hook = os.path.join(os.path.dirname(conf.conffile), '..', hook)
                            # The wrappers turns the commit message
                            # from stdin into a fake patch header.
                            # This is good enough for changing Subject
                            # and commit msg body with normal
                            # combo-layer hooks.
                            hookwrapper.write('''set -e
tmpname=$(mktemp)
trap "rm $tmpname" EXIT
echo -n 'Subject: [PATCH] ' >>$tmpname
cat >>$tmpname
if ! [ $(tail -c 1 $tmpname | od -A n -t x1) == '0a' ]; then
    echo >>$tmpname
fi
echo '---' >>$tmpname
%s $tmpname $GIT_COMMIT %s
tail -c +18 $tmpname | head -c -4
''' % (hook, name))
                            hookwrapper.flush()
                            filter_branch.extend(['--msg-filter', 'bash %s' % hookwrapper.name])
                        if dest_dir != ".":
                            parent = os.path.dirname(dest_dir)
                            if not parent:
                                parent = '.'
                            # May run outside of the current directory, so do not assume that .git exists.
                            filter_branch.extend(['--tree-filter', 'mkdir -p .git/tmptree && find . -mindepth 1 -maxdepth 1 ! -name .git -print0 | xargs -0 -I SOURCE mv SOURCE .git/tmptree && mkdir -p %s && mv .git/tmptree %s' % (parent, dest_dir)])
                        filter_branch.append('HEAD')
                        runcmd(filter_branch)
                        runcmd('git update-ref -d refs/original/refs/heads/%s' % name)
                repo['rewritten_revision'] = runcmd('git rev-parse HEAD').strip()
                repo['stripped_revision'] = repo['rewritten_revision']
                # Optional filter files: remove everything and re-populate using the normal filtering code.
                # Override any potential .gitignore.
                if file_filter or exclude_patterns:
                    runcmd('git rm -rf .')
                    if not os.path.exists(extract_dir):
                        os.makedirs(extract_dir)
                    copy_selected_files('HEAD', extract_dir, file_filter, exclude_patterns, '.',
                                        subdir=dest_dir)
                    runcmd('git add --all --force .')
                    if runcmd('git status --porcelain'):
                        # Something to commit.
                        runcmd(['git', 'commit', '-m',
                                '''%s: select file subset

Files from the component repository were chosen based on
the following filters:
file_filter = %s
file_exclude = %s''' % (name, file_filter or '<empty>', repo.get('file_exclude', '<empty>'))])
                        repo['stripped_revision'] = runcmd('git rev-parse HEAD').strip()

            if not lastrev:
                lastrev = runcmd('git rev-parse %s' % initialrev, ldir).strip()
                conf.update(name, "last_revision", lastrev, initmode=True)

        if not conf.history:
            runcmd("git add .")
        else:
            # Create Octopus merge commit according to http://stackoverflow.com/questions/10874149/git-octopus-merge-with-unrelated-repositoies
            runcmd('git checkout master')
            merge = ['git', 'merge', '--no-commit']
            for name in conf.repos:
                repo = conf.repos[name]
                # Use branch created earlier.
                merge.append(name)
                # Root all commits which have no parent in the common
                # ancestor in the new repository.
                for start in runcmd('git log --pretty=format:%%H --max-parents=0 %s' % name).split('\n'):
                    runcmd('git replace --graft %s %s' % (start, startrev))
            try:
                runcmd(merge)
            except Exception as error:
                logger.info('''Merging component repository history failed, perhaps because of merge conflicts.
It may be possible to commit anyway after resolving these conflicts.

%s''' % error)
            # Create MERGE_HEAD and MERGE_MSG. "git merge" itself
            # does not create MERGE_HEAD in case of a (harmless) failure,
            # and we want certain auto-generated information in the
            # commit message for future reference and/or automation.
            with open('.git/MERGE_HEAD', 'w') as head:
                with open('.git/MERGE_MSG', 'w') as msg:
                    msg.write('repo: initial import of components\n\n')
                    # head.write('%s\n' % startrev)
                    for name in conf.repos:
                        repo = conf.repos[name]
                        # <upstream ref> <rewritten ref> <rewritten + files removed>
                        msg.write('combo-layer-%s: %s %s %s\n' % (name,
                                                                  repo['last_revision'],
                                                                  repo['rewritten_revision'],
                                                                  repo['stripped_revision']))
                        rev = runcmd('git rev-parse %s' % name).strip()
                        head.write('%s\n' % rev)

        if conf.localconffile:
            localadded = True
            try:
                runcmd("git rm --cached %s" % conf.localconffile, printerr=False)
            except subprocess.CalledProcessError:
                localadded = False
            if localadded:
                localrelpath = os.path.relpath(conf.localconffile)
                runcmd("grep -q %s .gitignore || echo %s >> .gitignore" % (localrelpath, localrelpath))
                runcmd("git add .gitignore")
                logger.info("Added local configuration file %s to .gitignore", localrelpath)
        logger.info("Initial combo layer repository data has been created; please make any changes if desired and then use 'git commit' to make the initial commit.")
    else:
        logger.info("Repository already initialised, nothing to do.")


def check_repo_clean(repodir):
    """
        check if the repo is clean
        exit if repo is dirty
    """
    output=runcmd("git status --porcelain", repodir)
    r = re.compile('\?\? patch-.*/')
    dirtyout = [item for item in output.splitlines() if not r.match(item)]
    if dirtyout:
        logger.error("git repo %s is dirty, please fix it first", repodir)
        sys.exit(1)

def check_patch(patchfile):
    f = open(patchfile, 'rb')
    ln = f.readline()
    of = None
    in_patch = False
    beyond_msg = False
    pre_buf = b''
    while ln:
        if not beyond_msg:
            if ln == b'---\n':
                if not of:
                    break
                in_patch = False
                beyond_msg = True
            elif ln.startswith(b'--- '):
                # We have a diff in the commit message
                in_patch = True
                if not of:
                    print('WARNING: %s contains a diff in its commit message, indenting to avoid failure during apply' % patchfile)
                    of = open(patchfile + '.tmp', 'wb')
                    of.write(pre_buf)
                    pre_buf = b''
            elif in_patch and not ln[0] in b'+-@ \n\r':
                in_patch = False
        if of:
            if in_patch:
                of.write(b' ' + ln)
            else:
                of.write(ln)
        else:
            pre_buf += ln
        ln = f.readline()
    f.close()
    if of:
        of.close()
        os.rename(patchfile + '.tmp', patchfile)

def drop_to_shell(workdir=None):
    if not sys.stdin.isatty():
        print("Not a TTY so can't drop to shell for resolution, exiting.")
        return False

    shell = os.environ.get('SHELL', 'bash')
    print('Dropping to shell "%s"\n' \
          'When you are finished, run the following to continue:\n' \
          '       exit    -- continue to apply the patches\n' \
          '       exit 1  -- abort\n' % shell);
    ret = subprocess.call([shell], cwd=workdir)
    if ret != 0:
        print("Aborting")
        return False
    else:
        return True

def check_rev_branch(component, repodir, rev, branch):
    try:
        actualbranch = runcmd("git branch --contains %s" % rev, repodir, printerr=False)
    except subprocess.CalledProcessError as e:
        if e.returncode == 129:
            actualbranch = ""
        else:
            raise

    if not actualbranch:
        logger.error("%s: specified revision %s is invalid!" % (component, rev))
        return False

    branches = []
    branchlist = actualbranch.split("\n")
    for b in branchlist:
        branches.append(b.strip().split(' ')[-1])

    if branch not in branches:
        logger.error("%s: specified revision %s is not on specified branch %s!" % (component, rev, branch))
        return False
    return True

def get_repos(conf, repo_names):
    repos = []
    for name in repo_names:
        if name.startswith('-'):
            break
        else:
            repos.append(name)
    for repo in repos:
        if not repo in conf.repos:
            logger.error("Specified component '%s' not found in configuration" % repo)
            sys.exit(1)

    if not repos:
        repos = [ repo for repo in conf.repos if conf.repos[repo].get("update", True) ]

    return repos

def action_pull(conf, args):
    """
        update the component repos only
    """
    repos = get_repos(conf, args[1:])

    # make sure all repos are clean
    for name in repos:
        check_repo_clean(conf.repos[name]['local_repo_dir'])

    for name in repos:
        repo = conf.repos[name]
        ldir = repo['local_repo_dir']
        branch = repo.get('branch', "master")
        logger.info("update branch %s of component repo %s in %s ..." % (branch, name, ldir))
        if not conf.hard_reset:
            # Try to pull only the configured branch. Beware that this may fail
            # when the branch is currently unknown (for example, after reconfiguring
            # combo-layer). In that case we need to fetch everything and try the check out
            # and pull again.
            try:
                runcmd("git checkout %s" % branch, ldir, printerr=False)
            except subprocess.CalledProcessError:
                output=runcmd("git fetch", ldir)
                logger.info(output)
                runcmd("git checkout %s" % branch, ldir)
                runcmd("git pull --ff-only", ldir)
            else:
                output=runcmd("git pull --ff-only", ldir)
                logger.info(output)
        else:
            output=runcmd("git fetch", ldir)
            logger.info(output)
            runcmd("git checkout %s" % branch, ldir)
            runcmd("git reset --hard FETCH_HEAD", ldir)

def action_update(conf, args):
    """
        update the component repos
        either:
           generate the patch list
           apply the generated patches
        or:
           re-creates the entire component history and merges them
           into the current branch with a merge commit
    """
    components = [arg.split(':')[0] for arg in args[1:]]
    revisions = {}
    for arg in args[1:]:
        if ':' in arg:
            a = arg.split(':', 1)
            revisions[a[0]] = a[1]
    repos = get_repos(conf, components)

    # make sure combo repo is clean
    check_repo_clean(os.getcwd())

    # Check whether we keep the component histories. Must be
    # set either via --history command line parameter or consistently
    # in combo-layer.conf. Mixing modes is (currently, and probably
    # permanently because it would be complicated) not supported.
    if conf.history:
        history = True
    else:
        history = None
        for name in repos:
            repo = conf.repos[name]
            repo_history = repo.get('history', False)
            if history is None:
                history = repo_history
            elif history != repo_history:
                logger.error("'history' property is set inconsistently")
                sys.exit(1)

    # Step 1: update the component repos
    if conf.nopull:
        logger.info("Skipping pull (-n)")
    else:
        action_pull(conf, ['arg0'] + components)

    if history:
        update_with_history(conf, components, revisions, repos)
    else:
        update_with_patches(conf, components, revisions, repos)

def update_with_patches(conf, components, revisions, repos):
    import uuid
    patch_dir = "patch-%s" % uuid.uuid4()
    if not os.path.exists(patch_dir):
        os.mkdir(patch_dir)

    for name in repos:
        revision = revisions.get(name, None)
        repo = conf.repos[name]
        ldir = repo['local_repo_dir']
        dest_dir = repo['dest_dir']
        branch = repo.get('branch', "master")
        repo_patch_dir = os.path.join(os.getcwd(), patch_dir, name)

        # Step 2: generate the patch list and store to patch dir
        logger.info("Generating patches from %s..." % name)
        top_revision = revision or branch
        if not check_rev_branch(name, ldir, top_revision, branch):
            sys.exit(1)
        if dest_dir != ".":
            prefix = "--src-prefix=a/%s/ --dst-prefix=b/%s/" % (dest_dir, dest_dir)
        else:
            prefix = ""
        if repo['last_revision'] == "":
            logger.info("Warning: last_revision of component %s is not set, starting from the first commit" % name)
            patch_cmd_range = "--root %s" % top_revision
            rev_cmd_range = top_revision
        else:
            if not check_rev_branch(name, ldir, repo['last_revision'], branch):
                sys.exit(1)
            patch_cmd_range = "%s..%s" % (repo['last_revision'], top_revision)
            rev_cmd_range = patch_cmd_range

        file_filter = repo.get('file_filter',".")

        # Filter out unwanted files
        exclude = repo.get('file_exclude', '')
        if exclude:
            for path in exclude.split():
                p = "%s/%s" % (dest_dir, path) if dest_dir != '.' else path
                file_filter += " ':!%s'" % p

        patch_cmd = "git format-patch -N %s --output-directory %s %s -- %s" % \
            (prefix,repo_patch_dir, patch_cmd_range, file_filter)
        output = runcmd(patch_cmd, ldir)
        logger.debug("generated patch set:\n%s" % output)
        patchlist = output.splitlines()

        rev_cmd = "git rev-list --no-merges %s -- %s" % (rev_cmd_range, file_filter)
        revlist = runcmd(rev_cmd, ldir).splitlines()

        # Step 3: Call repo specific hook to adjust patch
        if 'hook' in repo:
            # hook parameter is: ./hook patchpath revision reponame
            count=len(revlist)-1
            for patch in patchlist:
                runcmd("%s %s %s %s" % (repo['hook'], patch, revlist[count], name))
                count=count-1

        # Step 4: write patch list and revision list to file, for user to edit later
        patchlist_file = os.path.join(os.getcwd(), patch_dir, "patchlist-%s" % name)
        repo['patchlist'] = patchlist_file
        f = open(patchlist_file, 'w')
        count=len(revlist)-1
        for patch in patchlist:
            f.write("%s %s\n" % (patch, revlist[count]))
            check_patch(os.path.join(patch_dir, patch))
            count=count-1
        f.close()

    # Step 5: invoke bash for user to edit patch and patch list
    if conf.interactive:
        print('You may now edit the patch and patch list in %s\n' \
              'For example, you can remove unwanted patch entries from patchlist-*, so that they will be not applied later' % patch_dir);
        if not drop_to_shell(patch_dir):
            sys.exit(1)

    # Step 6: apply the generated and revised patch
    apply_patchlist(conf, repos)
    runcmd("rm -rf %s" % patch_dir)

    # Step 7: commit the updated config file if it's being tracked
    commit_conf_file(conf, components)

def conf_commit_msg(conf, components):
    # create the "components" string
    component_str = "all components"
    if len(components) > 0:
        # otherwise tell which components were actually changed
        component_str = ", ".join(components)

    # expand the template with known values
    template = Template(conf.commit_msg_template)
    msg = template.substitute(components = component_str)
    return msg

def commit_conf_file(conf, components, commit=True):
    relpath = os.path.relpath(conf.conffile)
    try:
        output = runcmd("git status --porcelain %s" % relpath, printerr=False)
    except:
        # Outside the repository
        output = None
    if output:
        if output.lstrip().startswith("M"):
            logger.info("Committing updated configuration file")
            if commit:
                msg = conf_commit_msg(conf, components)
                runcmd('git commit -m'.split() + [msg, relpath])
            else:
                runcmd('git add %s' % relpath)
            return True
    return False

def apply_patchlist(conf, repos):
    """
        apply the generated patch list to combo repo
    """
    for name in repos:
        repo = conf.repos[name]
        lastrev = repo["last_revision"]
        prevrev = lastrev

        # Get non-blank lines from patch list file
        patchlist = []
        if os.path.exists(repo['patchlist']) or not conf.interactive:
            # Note: we want this to fail here if the file doesn't exist and we're not in
            # interactive mode since the file should exist in this case
            with open(repo['patchlist']) as f:
                for line in f:
                    line = line.rstrip()
                    if line:
                        patchlist.append(line)

        ldir = conf.repos[name]['local_repo_dir']
        branch = conf.repos[name].get('branch', "master")
        branchrev = runcmd("git rev-parse %s" % branch, ldir).strip()

        if patchlist:
            logger.info("Applying patches from %s..." % name)
            linecount = len(patchlist)
            i = 1
            for line in patchlist:
                patchfile = line.split()[0]
                lastrev = line.split()[1]
                patchdisp = os.path.relpath(patchfile)
                if os.path.getsize(patchfile) == 0:
                    logger.info("(skipping %d/%d %s - no changes)" % (i, linecount, patchdisp))
                else:
                    cmd = "git am --keep-cr %s-p1 %s" % ('-s ' if repo.get('signoff', True) else '', patchfile)
                    logger.info("Applying %d/%d: %s" % (i, linecount, patchdisp))
                    try:
                        runcmd(cmd)
                    except subprocess.CalledProcessError:
                        logger.info('Running "git am --abort" to cleanup repo')
                        runcmd("git am --abort")
                        logger.error('"%s" failed' % cmd)
                        logger.info("Please manually apply patch %s" % patchdisp)
                        logger.info("Note: if you exit and continue applying without manually applying the patch, it will be skipped")
                        if not drop_to_shell():
                            if prevrev != repo['last_revision']:
                                conf.update(name, "last_revision", prevrev)
                            sys.exit(1)
                prevrev = lastrev
                i += 1
            # Once all patches are applied, we should update
            # last_revision to the branch head instead of the last
            # applied patch. The two are not necessarily the same when
            # the last commit is a merge commit or when the patches at
            # the branch head were intentionally excluded.
            #
            # If we do not do that for a merge commit, the next
            # combo-layer run will only exclude patches reachable from
            # one of the merged branches and try to re-apply patches
            # from other branches even though they were already
            # copied.
            #
            # If patches were intentionally excluded, the next run will
            # present them again instead of skipping over them. This
            # may or may not be intended, so the code here is conservative
            # and only addresses the "head is merge commit" case.
            if lastrev != branchrev and \
               len(runcmd("git show --pretty=format:%%P --no-patch %s" % branch, ldir).split()) > 1:
                lastrev = branchrev
        else:
            logger.info("No patches to apply from %s" % name)
            lastrev = branchrev

        if lastrev != repo['last_revision']:
            conf.update(name, "last_revision", lastrev)

def action_splitpatch(conf, args):
    """
        generate the commit patch and
        split the patch per repo
    """
    logger.debug("action_splitpatch")
    if len(args) > 1:
        commit = args[1]
    else:
        commit = "HEAD"
    patchdir = "splitpatch-%s" % commit
    if not os.path.exists(patchdir):
        os.mkdir(patchdir)

    # filerange_root is for the repo whose dest_dir is root "."
    # and it should be specified by excluding all other repo dest dir
    # like "-x repo1 -x repo2 -x repo3 ..."
    filerange_root = ""
    for name in conf.repos:
        dest_dir = conf.repos[name]['dest_dir']
        if dest_dir != ".":
            filerange_root = '%s -x "%s/*"' % (filerange_root, dest_dir)

    for name in conf.repos:
        dest_dir = conf.repos[name]['dest_dir']
        patch_filename = "%s/%s.patch" % (patchdir, name)
        if dest_dir == ".":
            cmd = "git format-patch -n1 --stdout %s^..%s | filterdiff -p1 %s > %s" % (commit, commit, filerange_root, patch_filename)
        else:
            cmd = "git format-patch --no-prefix -n1 --stdout %s^..%s -- %s > %s" % (commit, commit, dest_dir, patch_filename)
        runcmd(cmd)
        # Detect empty patches (including those produced by filterdiff above
        # that contain only preamble text)
        if os.path.getsize(patch_filename) == 0 or runcmd("filterdiff %s" % patch_filename) == "":
            os.remove(patch_filename)
            logger.info("(skipping %s - no changes)", name)
        else:
            logger.info(patch_filename)

def update_with_history(conf, components, revisions, repos):
    '''Update all components with full history.

    Works by importing all commits reachable from a component's
    current head revision.  If those commits are rooted in an already
    imported commit, their content gets mixed with the content of the
    combined repo of that commit (new or modified files overwritten,
    removed files removed).

    The last commit is an artificial merge commit that merges all the
    updated components into the combined repository.

    The HEAD ref only gets updated at the very end. All intermediate work
    happens in a worktree which will get garbage collected by git eventually
    after a failure.
    '''
    # Remember current HEAD and what we need to add to it.
    head = runcmd("git rev-parse HEAD").strip()
    additional_heads = {}

    # Track the mapping between original commit and commit in the
    # combined repo. We do not have to distinguish between components,
    # because commit hashes are different anyway. Often we can
    # skip find_revs() entirely (for example, when all new commits
    # are derived from the last imported revision).
    #
    # Using "head" (typically the merge commit) instead of the actual
    # commit for the component leads to a nicer history in the combined
    # repo.
    old2new_revs = {}
    for name in repos:
        repo = conf.repos[name]
        revision = repo['last_revision']
        if revision:
            old2new_revs[revision] = head

    def add_p(parents):
        '''Insert -p before each entry.'''
        parameters = []
        for p in parents:
            parameters.append('-p')
            parameters.append(p)
        return parameters

    # Do all intermediate work with a separate work dir and index,
    # chosen via env variables (can't use "git worktree", it is too
    # new). This is useful (no changes to current work tree unless the
    # update succeeds) and required (otherwise we end up temporarily
    # removing the combo-layer hooks that we currently use when
    # importing a new component).
    #
    # Not cleaned up after a failure at the moment.
    wdir = os.path.join(os.getcwd(), ".git", "combo-layer")
    windex = wdir + ".index"
    if os.path.isdir(wdir):
        shutil.rmtree(wdir)
    os.mkdir(wdir)
    wenv = copy.deepcopy(os.environ)
    wenv["GIT_WORK_TREE"] = wdir
    wenv["GIT_INDEX_FILE"] = windex
    # This one turned out to be needed in practice.
    wenv["GIT_OBJECT_DIRECTORY"] = os.path.join(os.getcwd(), ".git", "objects")
    wargs = {"destdir": wdir, "env": wenv}

    for name in repos:
        revision = revisions.get(name, None)
        repo = conf.repos[name]
        ldir = repo['local_repo_dir']
        dest_dir = repo['dest_dir']
        branch = repo.get('branch', "master")
        hook = repo.get('hook', None)
        largs = {"destdir": ldir, "env": None}
        file_include = repo.get('file_filter', '').split()
        file_include.sort() # make sure that short entries like '.' come first.
        file_exclude = repo.get('file_exclude', '').split()

        def include_file(file):
            if not file_include:
                # No explicit filter set, include file.
                return True
            for filter in file_include:
                if filter == '.':
                    # Another special case: include current directory and thus all files.
                    return True
                if os.path.commonprefix((filter, file)) == filter:
                    # Included in directory or direct file match.
                    return True
                # Check for wildcard match *with* allowing * to match /, i.e.
                # src/*.c does match src/foobar/*.c. That's not how it is done elsewhere
                # when passing the filtering to "git archive", but it is unclear what
                # the intended semantic is (the comment on file_exclude that "append a * wildcard
                # at the end" to match the full content of a directories implies that
                # slashes are indeed not special), so here we simply do what's easy to
                # implement in Python.
                logger.debug('fnmatch(%s, %s)' % (file, filter))
                if fnmatch.fnmatchcase(file, filter):
                    return True
            return False

        def exclude_file(file):
            for filter in file_exclude:
                if fnmatch.fnmatchcase(file, filter):
                    return True
            return False

        def file_filter(files):
            '''Clean up file list so that only included files remain.'''
            index = 0
            while index < len(files):
                file = files[index]
                if not include_file(file) or exclude_file(file):
                    del files[index]
                else:
                    index += 1


        # Generate the revision list.
        logger.info("Analyzing commits from %s..." % name)
        top_revision = revision or branch
        if not check_rev_branch(name, ldir, top_revision, branch):
            sys.exit(1)

        last_revision = repo['last_revision']
        rev_list_args = "--full-history --sparse --topo-order --reverse"
        if not last_revision:
            logger.info("Warning: last_revision of component %s is not set, starting from the first commit" % name)
            rev_list_args = rev_list_args + ' ' + top_revision
        else:
            if not check_rev_branch(name, ldir, last_revision, branch):
                sys.exit(1)
            rev_list_args = "%s %s..%s" % (rev_list_args, last_revision, top_revision)

            # By definition, the current HEAD contains the latest imported
            # commit of each component. We use that as initial mapping even
            # though the commits do not match exactly because
            # a) it always works (in contrast to find_revs, which relies on special
            #    commit messages)
            # b) it is faster than find_revs, which will only be called on demand
            #    and can be skipped entirely in most cases
            # c) last but not least, the combined history looks nicer when all
            #    new commits are rooted in the same merge commit
            old2new_revs[last_revision] = head

        # We care about all commits (--full-history and --sparse) and
        # we want reconstruct the topology and thus do not care
        # about ordering by time (--topo-order). We ask for the ones
        # we need to import first to be listed first (--reverse).
        revs = runcmd("git rev-list %s" % rev_list_args, **largs).split()
        logger.debug("To be imported: %s" % revs)
        # Now 'revs' contains all revisions reachable from the top revision.
        # All revisions derived from the 'last_revision' definitely are new,
        # whereas the others may or may not have been imported before. For
        # a linear history in the component, that second set will be empty.
        # To distinguish between them, we also get the shorter list
        # of revisions starting at the ancestor.
        if last_revision:
            ancestor_revs = runcmd("git rev-list --ancestry-path %s" % rev_list_args, **largs).split()
        else:
            ancestor_revs = []
        logger.debug("Ancestors: %s" % ancestor_revs)

        # Now import each revision.
        logger.info("Importing commits from %s..." % name)
        def import_rev(rev):
            global scanned_revs

            # If it is part of the new commits, we definitely need
            # to import it. Otherwise we need to check, we might have
            # imported it before. If it was imported and we merely
            # fail to find it because commit messages did not track
            # the mapping, then we end up importing it again. So
            # combined repos using "updating with history" really should
            # enable the "From ... rev:" commit header modifications.
            if rev not in ancestor_revs and rev not in old2new_revs and not scanned_revs:
                logger.debug("Revision %s triggers log analysis." % rev)
                find_revs(old2new_revs, head)
                scanned_revs = True
            new_rev = old2new_revs.get(rev, None)
            if new_rev:
                return new_rev

            # If the commit is not in the original list of revisions
            # to be imported, then it must be a parent of one of those
            # commits and it was skipped during earlier imports or not
            # found. Importing such merge commits leads to very ugly
            # history (long cascade of merge commits which all point
            # to to older commits) when switching from "update via
            # patches" to "update with history".
            #
            # We can avoid importing merge commits if all non-merge commits
            # reachable from it were already imported. In that case we
            # can root the new commits in the current head revision.
            def is_imported(prev):
                parents = runcmd("git show --no-patch --pretty=format:%P " + prev, **largs).split()
                if len(parents) > 1:
                    for p in parents:
                        if not is_imported(p):
                            logger.debug("Must import %s because %s is not imported." % (rev, p))
                            return False
                    return True
                elif prev in old2new_revs:
                    return True
                else:
                    logger.debug("Must import %s because %s is not imported." % (rev, prev))
                    return False
            if rev not in revs and is_imported(rev):
                old2new_revs[rev] = head
                return head

            # Need to import rev. Collect some information about it.
            logger.debug("Importing %s" % rev)
            (parents, author_name, author_email, author_timestamp, body) = \
                runcmd("git show --no-patch --pretty=format:%P%x00%an%x00%ae%x00%at%x00%B " + rev, **largs).split(chr(0))
            parents = parents.split()
            if parents:
                # Arbitrarily pick the first parent as base. It may or may not have
                # been imported before. For example, if the parent is a merge commit
                # and previously the combined repository used patching as update
                # method, then the actual merge commit parent never was imported.
                # To cover this, We recursively import parents.
                parent = parents[0]
                new_parent = import_rev(parent)
                # Clean index and working tree. TODO: can we combine this and the
                # next into one command with less file IO?
                # "git reset --hard" does not work, it changes HEAD of the parent
                # repo, which we wanted to avoid. Probably need to keep
                # track of the rev that corresponds to the index and use apply_commit().
                runcmd("git rm -q --ignore-unmatch -rf .", **wargs)
                # Update index and working tree to match the parent.
                runcmd("git checkout -q -f %s ." % new_parent, **wargs)
            else:
                parent = None
                # Clean index and working tree.
                runcmd("git rm -q --ignore-unmatch -rf .", **wargs)

            # Modify index and working tree such that it mirrors the commit.
            apply_commit(parent, rev, largs, wargs, dest_dir, file_filter=file_filter)

            # Now commit.
            new_tree = runcmd("git write-tree", **wargs).strip()
            env = copy.deepcopy(wenv)
            env['GIT_AUTHOR_NAME'] = author_name
            env['GIT_AUTHOR_EMAIL'] = author_email
            env['GIT_AUTHOR_DATE'] = author_timestamp
            if hook:
                # Need to turn the verbatim commit message into something resembling a patch header
                # for the hook.
                with tempfile.NamedTemporaryFile(delete=False) as patch:
                    patch.write('Subject: [PATCH] ')
                    patch.write(body)
                    patch.write('\n---\n')
                    patch.close()
                    runcmd([hook, patch.name, rev, name])
                    with open(patch.name) as f:
                        body = f.read()[len('Subject: [PATCH] '):][:-len('\n---\n')]

            # We can skip non-merge commits that did not change any files. Those are typically
            # the result of file filtering, although they could also have been introduced
            # intentionally upstream, in which case we drop some information here.
            if len(parents) == 1:
                parent_rev = import_rev(parents[0])
                old_tree = runcmd("git show -s --pretty=format:%T " + parent_rev, **wargs).strip()
                commit = old_tree != new_tree
                if not commit:
                    new_rev = parent_rev
            else:
                commit = True
            if commit:
                new_rev = runcmd("git commit-tree".split() + add_p([import_rev(p) for p in parents]) +
                                 ["-m", body, new_tree],
                                 env=env).strip()
            old2new_revs[rev] = new_rev

            return new_rev

        if revs:
            for rev in revs:
                import_rev(rev)
            # Remember how to update our current head. New components get added,
            # updated components get the delta between current head and the updated component
            # applied.
            additional_heads[old2new_revs[revs[-1]]] = head if repo['last_revision'] else None
            repo['last_revision'] = revs[-1]

    # Now construct the final merge commit. We create the tree by
    # starting with the head and applying the changes from each
    # components imported head revision.
    if additional_heads:
        runcmd("git reset --hard", **wargs)
        for rev, base in additional_heads.items():
            apply_commit(base, rev, wargs, wargs, None)

        # Commit with all component branches as parents as well as the previous head.
        logger.info("Writing final merge commit...")
        msg = conf_commit_msg(conf, components)
        new_tree = runcmd("git write-tree", **wargs).strip()
        new_rev = runcmd("git commit-tree".split() +
                         add_p([head] + list(additional_heads.keys())) +
                         ["-m", msg, new_tree],
                         **wargs).strip()
        # And done! This is the first time we change the HEAD in the actual work tree.
        runcmd("git reset --hard %s" % new_rev)

        # Update and stage the (potentially modified)
        # combo-layer.conf, but do not commit separately.
        for name in repos:
            repo = conf.repos[name]
            rev = repo['last_revision']
            conf.update(name, "last_revision", rev)
        if commit_conf_file(conf, components, False):
            # Must augment the previous commit.
            runcmd("git commit --amend -C HEAD")


scanned_revs = False
def find_revs(old2new, head):
    '''Construct mapping from original commit hash to commit hash in
    combined repo by looking at the commit messages. Depends on the
    "From ... rev: ..." convention.'''
    logger.info("Analyzing log messages to find previously imported commits...")
    num_known = len(old2new)
    log = runcmd("git log --grep='From .* rev: [a-fA-F0-9][a-fA-F0-9]*' --pretty=format:%H%x00%B%x00 " + head).split(chr(0))
    regex = re.compile(r'From .* rev: ([a-fA-F0-9]+)')
    for new_rev, body in zip(*[iter(log)]* 2):
        # Use the last one, in the unlikely case there are more than one.
        rev = regex.findall(body)[-1]
        if rev not in old2new:
            old2new[rev] = new_rev.strip()
    logger.info("Found %d additional commits, leading to: %s" % (len(old2new) - num_known, old2new))


def apply_commit(parent, rev, largs, wargs, dest_dir, file_filter=None):
    '''Compare revision against parent, remove files deleted in the
    commit, re-write new or modified ones. Moves them into dest_dir.
    Optionally filters files.
    '''
    if not dest_dir:
        dest_dir = "."
    # -r recurses into sub-directories, given is the full overview of
    # what changed.  We do not care about copy/edits or renames, so we
    # can disable those with --no-renames (but we still parse them,
    # because it was not clear from git documentation whether C and M
    # lines can still occur).
    logger.debug("Applying changes between %s and %s in %s" % (parent, rev, largs["destdir"]))
    delete = []
    update = []
    if parent:
        # Apply delta.
        changes = runcmd("git diff-tree --no-commit-id --no-renames --name-status -r --raw -z %s %s" % (parent, rev), **largs).split(chr(0))
        for status, name in zip(*[iter(changes)]*2):
            if status[0] in "ACMRT":
                update.append(name)
            elif status[0] in "D":
                delete.append(name)
            else:
                logger.error("Unknown status %s of file %s in revision %s" % (status, name, rev))
                sys.exit(1)
    else:
        # Copy all files.
        update.extend(runcmd("git ls-tree -r --name-only -z %s" % rev, **largs).split(chr(0)))

    # Include/exclude files as define in the component config.
    # Both updated and deleted file lists get filtered, because it might happen
    # that a file gets excluded, pulled from a different component, and then the
    # excluded file gets deleted. In that case we must keep the copy.
    if file_filter:
        file_filter(update)
        file_filter(delete)

    # We export into a tar archive here and extract with tar because it is simple (no
    # need to implement file and symlink writing ourselves) and gives us some degree
    # of parallel IO. The downside is that we have to pass the list of files via
    # command line parameters - hopefully there will never be too many at once.
    if update:
        target = os.path.join(wargs["destdir"], dest_dir)
        if not os.path.isdir(target):
            os.makedirs(target)
        quoted_target = pipes.quote(target)
        # os.sysconf('SC_ARG_MAX') is lying: running a command with
        # string length 629343 already failed with "Argument list too
        # long" although SC_ARG_MAX = 2097152. "man execve" explains
        # the limitations, but those are pretty complicated. So here
        # we just hard-code a fixed value which is more likely to work.
        max_cmdsize = 64 * 1024
        while update:
            quoted_args = []
            unquoted_args = []
            cmdsize = 100 + len(quoted_target)
            while update:
                quoted_next = pipes.quote(update[0])
                size_next = len(quoted_next) + len(dest_dir) + 1
                logger.debug('cmdline length %d + %d < %d?' % (cmdsize, size_next, os.sysconf('SC_ARG_MAX')))
                if cmdsize + size_next < max_cmdsize:
                    quoted_args.append(quoted_next)
                    unquoted_args.append(update.pop(0))
                    cmdsize += size_next
                else:
                    logger.debug('Breaking the cmdline at length %d' % cmdsize)
                    break
            logger.debug('Final cmdline length %d / %d' % (cmdsize, os.sysconf('SC_ARG_MAX')))
            cmd = "git archive %s %s | tar -C %s -xf -" % (rev, ' '.join(quoted_args), quoted_target)
            logger.debug('First cmdline length %d' % len(cmd))
            runcmd(cmd, **largs)
            cmd = "git add -f".split() + [os.path.join(dest_dir, x) for x in unquoted_args]
            logger.debug('Second cmdline length %d' % reduce(lambda x, y: x + len(y), cmd, 0))
            runcmd(cmd, **wargs)
    if delete:
        for path in delete:
            if dest_dir:
                path = os.path.join(dest_dir, path)
        runcmd("git rm -f --ignore-unmatch".split() + [os.path.join(dest_dir, x) for x in delete], **wargs)

def action_error(conf, args):
    logger.info("invalid action %s" % args[0])

actions = {
    "init": action_init,
    "update": action_update,
    "pull": action_pull,
    "splitpatch": action_splitpatch,
}

def main():
    parser = optparse.OptionParser(
        version = "Combo Layer Repo Tool version %s" % __version__,
        usage = """%prog [options] action

Create and update a combination layer repository from multiple component repositories.

Action:
  init                 initialise the combo layer repo
  update [components]  get patches from component repos and apply them to the combo repo
  pull [components]    just pull component repos only
  splitpatch [commit]  generate commit patch and split per component, default commit is HEAD""")

    parser.add_option("-c", "--conf", help = "specify the config file (conf/combo-layer.conf is the default).",
               action = "store", dest = "conffile", default = "conf/combo-layer.conf")

    parser.add_option("-i", "--interactive", help = "interactive mode, user can edit the patch list and patches",
               action = "store_true", dest = "interactive", default = False)

    parser.add_option("-D", "--debug", help = "output debug information",
               action = "store_true", dest = "debug", default = False)

    parser.add_option("-n", "--no-pull", help = "skip pulling component repos during update",
               action = "store_true", dest = "nopull", default = False)

    parser.add_option("--hard-reset",
               help = "instead of pull do fetch and hard-reset in component repos",
               action = "store_true", dest = "hard_reset", default = False)

    parser.add_option("-H", "--history", help = "import full history of components during init",
                      action = "store_true", default = False)

    options, args = parser.parse_args(sys.argv)

    # Dispatch to action handler
    if len(args) == 1:
        logger.error("No action specified, exiting")
        parser.print_help()
    elif args[1] not in actions:
        logger.error("Unsupported action %s, exiting\n" % (args[1]))
        parser.print_help()
    elif not os.path.exists(options.conffile):
        logger.error("No valid config file, exiting\n")
        parser.print_help()
    else:
        if options.debug:
            logger.setLevel(logging.DEBUG)
        confdata = Configuration(options)
        initmode = (args[1] == 'init')
        confdata.sanity_check(initmode)
        actions.get(args[1], action_error)(confdata, args[1:])

if __name__ == "__main__":
    try:
        ret = main()
    except Exception:
        ret = 1
        import traceback
        traceback.print_exc()
    sys.exit(ret)
