#!/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>
#
# SPDX-License-Identifier: GPL-2.0-only
#

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.read_file(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.warning("%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'):
                        if file.endswith(os.path.sep):
                            continue
                        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(mode='wt') 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(mode='wt') 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()
        bb.utils.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(mode='wt', 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)
