Example #1
0
def main():
    """entry point"""
    try:
        o = Options()
    except ValueError as e:
        LOG.err('Config format error: {}'.format(str(e)))
        return False

    ret = True
    try:

        if o.cmd_list:
            # list existing profiles
            if o.debug:
                LOG.dbg('running cmd: list')
            cmd_list_profiles(o)

        elif o.cmd_listfiles:
            # list files for selected profile
            if o.debug:
                LOG.dbg('running cmd: listfiles')
            cmd_list_files(o)

        elif o.cmd_install:
            # install the dotfiles stored in dotdrop
            if o.debug:
                LOG.dbg('running cmd: install')
            ret = cmd_install(o)

        elif o.cmd_compare:
            # compare local dotfiles with dotfiles stored in dotdrop
            if o.debug:
                LOG.dbg('running cmd: compare')
            tmp = get_tmpdir()
            ret = cmd_compare(o, tmp)
            # clean tmp directory
            remove(tmp)

        elif o.cmd_import:
            # import dotfile(s)
            if o.debug:
                LOG.dbg('running cmd: import')
            ret = cmd_importer(o)

        elif o.cmd_update:
            # update a dotfile
            if o.debug:
                LOG.dbg('running cmd: update')
            ret = cmd_update(o)

        elif o.cmd_detail:
            # detail files
            if o.debug:
                LOG.dbg('running cmd: update')
            cmd_detail(o)

    except KeyboardInterrupt:
        LOG.err('interrupted')
        ret = False

    return ret
Example #2
0
def main():
    """entry point"""
    # check dependencies are met
    try:
        dependencies_met()
    except Exception as e:
        LOG.err(e)
        return False

    t0 = time.time()
    try:
        o = Options()
    except YamlException as e:
        LOG.err('config error: {}'.format(str(e)))
        return False
    except UndefinedException as e:
        LOG.err('config error: {}'.format(str(e)))
        return False

    if o.debug:
        LOG.dbg('\n\n')
    options_time = time.time() - t0

    ret = True
    t0 = time.time()
    command = ''
    try:

        if o.cmd_profiles:
            # list existing profiles
            command = 'profiles'
            if o.debug:
                LOG.dbg('running cmd: {}'.format(command))
            cmd_list_profiles(o)

        elif o.cmd_files:
            # list files for selected profile
            command = 'files'
            if o.debug:
                LOG.dbg('running cmd: {}'.format(command))
            cmd_files(o)

        elif o.cmd_install:
            # install the dotfiles stored in dotdrop
            command = 'install'
            if o.debug:
                LOG.dbg('running cmd: {}'.format(command))
            ret = cmd_install(o)

        elif o.cmd_compare:
            # compare local dotfiles with dotfiles stored in dotdrop
            command = 'compare'
            if o.debug:
                LOG.dbg('running cmd: {}'.format(command))
            tmp = get_tmpdir()
            ret = cmd_compare(o, tmp)
            # clean tmp directory
            removepath(tmp, LOG)

        elif o.cmd_import:
            # import dotfile(s)
            command = 'import'
            if o.debug:
                LOG.dbg('running cmd: {}'.format(command))
            ret = cmd_importer(o)

        elif o.cmd_update:
            # update a dotfile
            command = 'update'
            if o.debug:
                LOG.dbg('running cmd: {}'.format(command))
            ret = cmd_update(o)

        elif o.cmd_detail:
            # detail files
            command = 'detail'
            if o.debug:
                LOG.dbg('running cmd: {}'.format(command))
            cmd_detail(o)

        elif o.cmd_remove:
            # remove dotfile
            command = 'remove'
            if o.debug:
                LOG.dbg('running cmd: {}'.format(command))
            cmd_remove(o)

    except KeyboardInterrupt:
        LOG.err('interrupted')
        ret = False
    cmd_time = time.time() - t0

    if o.debug:
        LOG.dbg('done executing command \"{}\"'.format(command))
        LOG.dbg('options loaded in {}'.format(options_time))
        LOG.dbg('command executed in {}'.format(cmd_time))

    if ret and o.conf.save():
        LOG.log('config file updated')

    if o.debug:
        LOG.dbg('return {}'.format(ret))
    return ret
Example #3
0
def cmd_install(o):
    """install dotfiles for this profile"""
    dotfiles = o.dotfiles
    if o.install_keys:
        # filtered dotfiles to install
        dotfiles = [d for d in dotfiles if d.key in set(o.install_keys)]
    if not dotfiles:
        msg = 'no dotfile to install for this profile (\"{}\")'
        LOG.warn(msg.format(o.profile))
        return False

    t = Templategen(base=o.dotpath, variables=o.variables, debug=o.debug)
    tmpdir = None
    if o.install_temporary:
        tmpdir = get_tmpdir()
    inst = Installer(create=o.create,
                     backup=o.backup,
                     dry=o.dry,
                     safe=o.safe,
                     base=o.dotpath,
                     workdir=o.workdir,
                     diff=o.install_diff,
                     debug=o.debug,
                     totemp=tmpdir,
                     showdiff=o.install_showdiff,
                     backup_suffix=o.install_backup_suffix)
    installed = []
    for dotfile in dotfiles:
        preactions = []
        if not o.install_temporary and dotfile.actions \
                and Cfg.key_actions_pre in dotfile.actions:
            for action in dotfile.actions[Cfg.key_actions_pre]:
                preactions.append(action)
        if o.debug:
            LOG.dbg('installing {}'.format(dotfile))
        if hasattr(dotfile, 'link') and dotfile.link == LinkTypes.PARENTS:
            r = inst.link(t, dotfile.src, dotfile.dst, actions=preactions)
        elif hasattr(dotfile, 'link') and dotfile.link == LinkTypes.CHILDREN:
            r = inst.link_children(t,
                                   dotfile.src,
                                   dotfile.dst,
                                   actions=preactions)
        else:
            src = dotfile.src
            tmp = None
            if dotfile.trans_r:
                tmp = apply_trans(o.dotpath, dotfile, debug=o.debug)
                if not tmp:
                    continue
                src = tmp
            r = inst.install(t,
                             src,
                             dotfile.dst,
                             actions=preactions,
                             noempty=dotfile.noempty)
            if tmp:
                tmp = os.path.join(o.dotpath, tmp)
                if os.path.exists(tmp):
                    remove(tmp)
        if len(r) > 0:
            if not o.install_temporary and \
                    Cfg.key_actions_post in dotfile.actions:
                actions = dotfile.actions[Cfg.key_actions_post]
                # execute action
                for action in actions:
                    if o.dry:
                        LOG.dry('would execute action: {}'.format(action))
                    else:
                        if o.debug:
                            LOG.dbg('executing post action {}'.format(action))
                        action.execute()
        installed.extend(r)
    if o.install_temporary:
        LOG.log('\nInstalled to tmp \"{}\".'.format(tmpdir))
    LOG.log('\n{} dotfile(s) installed.'.format(len(installed)))
    return True
Example #4
0
def _exec_command(opts):
    """execute command"""
    ret = True
    command = ''
    try:

        if opts.cmd_profiles:
            # list existing profiles
            command = 'profiles'
            LOG.dbg('running cmd: {}'.format(command))
            cmd_list_profiles(opts)

        elif opts.cmd_files:
            # list files for selected profile
            command = 'files'
            LOG.dbg('running cmd: {}'.format(command))
            cmd_files(opts)

        elif opts.cmd_install:
            # install the dotfiles stored in dotdrop
            command = 'install'
            LOG.dbg('running cmd: {}'.format(command))
            ret = cmd_install(opts)

        elif opts.cmd_compare:
            # compare local dotfiles with dotfiles stored in dotdrop
            command = 'compare'
            LOG.dbg('running cmd: {}'.format(command))
            tmp = get_tmpdir()
            ret = cmd_compare(opts, tmp)
            # clean tmp directory
            removepath(tmp, LOG)

        elif opts.cmd_import:
            # import dotfile(s)
            command = 'import'
            LOG.dbg('running cmd: {}'.format(command))
            ret = cmd_importer(opts)

        elif opts.cmd_update:
            # update a dotfile
            command = 'update'
            LOG.dbg('running cmd: {}'.format(command))
            ret = cmd_update(opts)

        elif opts.cmd_detail:
            # detail files
            command = 'detail'
            LOG.dbg('running cmd: {}'.format(command))
            cmd_detail(opts)

        elif opts.cmd_remove:
            # remove dotfile
            command = 'remove'
            LOG.dbg('running cmd: {}'.format(command))
            cmd_remove(opts)

    except KeyboardInterrupt:
        LOG.err('interrupted')
        ret = False

    return ret, command
Example #5
0
def cmd_install(o):
    """install dotfiles for this profile"""
    dotfiles = o.dotfiles
    prof = o.conf.get_profile()

    adapt_workers(o, LOG)

    pro_pre_actions = prof.get_pre_actions() if prof else []
    pro_post_actions = prof.get_post_actions() if prof else []

    if o.install_keys:
        # filtered dotfiles to install
        uniq = uniq_list(o.install_keys)
        dotfiles = [d for d in dotfiles if d.key in uniq]
    if not dotfiles:
        msg = 'no dotfile to install for this profile (\"{}\")'
        LOG.warn(msg.format(o.profile))
        return False

    # the installer
    tmpdir = None
    if o.install_temporary:
        tmpdir = get_tmpdir()

    installed = []

    # execute profile pre-action
    if o.debug:
        LOG.dbg('run {} profile pre actions'.format(len(pro_pre_actions)))
    t = _get_templater(o)
    ret, err = action_executor(o, pro_pre_actions, [], t, post=False)()
    if not ret:
        return False

    # install each dotfile
    if o.workers > 1:
        # in parallel
        if o.debug:
            LOG.dbg('run with {} workers'.format(o.workers))
        ex = futures.ThreadPoolExecutor(max_workers=o.workers)

        wait_for = []
        for dotfile in dotfiles:
            j = ex.submit(_dotfile_install, o, dotfile, tmpdir=tmpdir)
            wait_for.append(j)
        # check result
        for f in futures.as_completed(wait_for):
            r, key, err = f.result()
            if r:
                installed.append(key)
            elif err:
                LOG.err('installing \"{}\" failed: {}'.format(key, err))
    else:
        # sequentially
        for dotfile in dotfiles:
            r, key, err = _dotfile_install(o, dotfile, tmpdir=tmpdir)
            # check result
            if r:
                installed.append(key)
            elif err:
                LOG.err('installing \"{}\" failed: {}'.format(key, err))

    # execute profile post-action
    if len(installed) > 0 or o.install_force_action:
        if o.debug:
            msg = 'run {} profile post actions'
            LOG.dbg(msg.format(len(pro_post_actions)))
        ret, err = action_executor(o, pro_post_actions, [], t, post=False)()
        if not ret:
            return False

    if o.debug:
        LOG.dbg('install done: installed \"{}\"'.format(','.join(installed)))

    if o.install_temporary:
        LOG.log('\ninstalled to tmp \"{}\".'.format(tmpdir))
    LOG.log('\n{} dotfile(s) installed.'.format(len(installed)))
    return True
Example #6
0
def cmd_install(opts):
    """install dotfiles for this profile"""
    dotfiles = opts.dotfiles
    prof = opts.conf.get_profile()

    adapt_workers(opts, LOG)

    pro_pre_actions = prof.get_pre_actions() if prof else []
    pro_post_actions = prof.get_post_actions() if prof else []

    if opts.install_keys:
        # filtered dotfiles to install
        uniq = uniq_list(opts.install_keys)
        dotfiles = [d for d in dotfiles if d.key in uniq]

    if not dotfiles:
        msg = 'no dotfile to install for this profile (\"{}\")'
        LOG.warn(msg.format(opts.profile))
        return False

    LOG.dbg('dotfiles registered for install: {}'.format(
        [k.key for k in dotfiles]))

    # the installer
    tmpdir = None
    if opts.install_temporary:
        tmpdir = get_tmpdir()

    installed = []

    # clear the workdir
    if opts.install_clear_workdir and not opts.dry:
        LOG.dbg('clearing the workdir under {}'.format(opts.workdir))
        for root, _, files in os.walk(opts.workdir):
            for file in files:
                fpath = os.path.join(root, file)
                removepath(fpath, logger=LOG)

    # execute profile pre-action
    LOG.dbg('run {} profile pre actions'.format(len(pro_pre_actions)))
    templ = _get_templater(opts)
    ret, _ = action_executor(opts, pro_pre_actions, [], templ, post=False)()
    if not ret:
        return False

    # install each dotfile
    if opts.workers > 1:
        # in parallel
        LOG.dbg('run with {} workers'.format(opts.workers))
        ex = futures.ThreadPoolExecutor(max_workers=opts.workers)

        wait_for = []
        for dotfile in dotfiles:
            j = ex.submit(_dotfile_install, opts, dotfile, tmpdir=tmpdir)
            wait_for.append(j)
        # check result
        for fut in futures.as_completed(wait_for):
            tmpret, key, err = fut.result()
            # check result
            if tmpret:
                installed.append(key)
            elif err:
                LOG.err('installing \"{}\" failed: {}'.format(key, err))
    else:
        # sequentially
        for dotfile in dotfiles:
            tmpret, key, err = _dotfile_install(opts, dotfile, tmpdir=tmpdir)
            # check result
            if tmpret:
                installed.append(key)
            elif err:
                LOG.err('installing \"{}\" failed: {}'.format(key, err))

    # execute profile post-action
    if len(installed) > 0 or opts.install_force_action:
        msg = 'run {} profile post actions'
        LOG.dbg(msg.format(len(pro_post_actions)))
        ret, _ = action_executor(opts, pro_post_actions, [], templ,
                                 post=False)()
        if not ret:
            return False

    LOG.dbg('install done: installed \"{}\"'.format(','.join(installed)))

    if opts.install_temporary:
        LOG.log('\ninstalled to tmp \"{}\".'.format(tmpdir))
    LOG.log('\n{} dotfile(s) installed.'.format(len(installed)))
    return True
Example #7
0
def cmd_install(o):
    """install dotfiles for this profile"""
    dotfiles = o.dotfiles
    prof = o.conf.get_profile()
    pro_pre_actions = prof.get_pre_actions() if prof else []
    pro_post_actions = prof.get_post_actions() if prof else []

    if o.install_keys:
        # filtered dotfiles to install
        uniq = uniq_list(o.install_keys)
        dotfiles = [d for d in dotfiles if d.key in uniq]
    if not dotfiles:
        msg = 'no dotfile to install for this profile (\"{}\")'
        LOG.warn(msg.format(o.profile))
        return False

    t = Templategen(base=o.dotpath,
                    variables=o.variables,
                    func_file=o.func_file,
                    filter_file=o.filter_file,
                    debug=o.debug)
    tmpdir = None
    if o.install_temporary:
        tmpdir = get_tmpdir()
    inst = Installer(create=o.create,
                     backup=o.backup,
                     dry=o.dry,
                     safe=o.safe,
                     base=o.dotpath,
                     workdir=o.workdir,
                     diff=o.install_diff,
                     debug=o.debug,
                     totemp=tmpdir,
                     showdiff=o.install_showdiff,
                     backup_suffix=o.install_backup_suffix,
                     diff_cmd=o.diff_command)
    installed = 0
    tvars = t.add_tmp_vars()

    # execute profile pre-action
    if o.debug:
        LOG.dbg('run {} profile pre actions'.format(len(pro_pre_actions)))
    ret, err = action_executor(o, pro_pre_actions, [], t, post=False)()
    if not ret:
        return False

    # install each dotfile
    for dotfile in dotfiles:
        # add dotfile variables
        t.restore_vars(tvars)
        newvars = dotfile.get_dotfile_variables()
        t.add_tmp_vars(newvars=newvars)

        preactions = []
        if not o.install_temporary:
            preactions.extend(dotfile.get_pre_actions())
        defactions = o.install_default_actions_pre
        pre_actions_exec = action_executor(o,
                                           preactions,
                                           defactions,
                                           t,
                                           post=False)

        if o.debug:
            LOG.dbg('installing dotfile: \"{}\"'.format(dotfile.key))
            LOG.dbg(dotfile.prt())
        if hasattr(dotfile, 'link') and dotfile.link == LinkTypes.LINK:
            r, err = inst.link(t,
                               dotfile.src,
                               dotfile.dst,
                               actionexec=pre_actions_exec)
        elif hasattr(dotfile, 'link') and \
                dotfile.link == LinkTypes.LINK_CHILDREN:
            r, err = inst.link_children(t,
                                        dotfile.src,
                                        dotfile.dst,
                                        actionexec=pre_actions_exec)
        else:
            src = dotfile.src
            tmp = None
            if dotfile.trans_r:
                tmp = apply_trans(o.dotpath, dotfile, t, debug=o.debug)
                if not tmp:
                    continue
                src = tmp
            ignores = list(set(o.install_ignore + dotfile.instignore))
            ignores = patch_ignores(ignores, dotfile.dst, debug=o.debug)
            r, err = inst.install(t,
                                  src,
                                  dotfile.dst,
                                  actionexec=pre_actions_exec,
                                  noempty=dotfile.noempty,
                                  ignore=ignores)
            if tmp:
                tmp = os.path.join(o.dotpath, tmp)
                if os.path.exists(tmp):
                    remove(tmp)
        if r:
            # dotfile was installed
            if not o.install_temporary:
                defactions = o.install_default_actions_post
                postactions = dotfile.get_post_actions()
                post_actions_exec = action_executor(o,
                                                    postactions,
                                                    defactions,
                                                    t,
                                                    post=True)
                post_actions_exec()
            installed += 1
        elif not r:
            # dotfile was NOT installed
            if o.install_force_action:
                # pre-actions
                if o.debug:
                    LOG.dbg('force pre action execution ...')
                pre_actions_exec()
                # post-actions
                if o.debug:
                    LOG.dbg('force post action execution ...')
                postactions = dotfile.get_post_actions()
                post_actions_exec = action_executor(o,
                                                    postactions,
                                                    defactions,
                                                    t,
                                                    post=True)
                post_actions_exec()
            if err:
                LOG.err('installing \"{}\" failed: {}'.format(
                    dotfile.key, err))

    # execute profile post-action
    if installed > 0 or o.install_force_action:
        if o.debug:
            msg = 'run {} profile post actions'
            LOG.dbg(msg.format(len(pro_post_actions)))
        ret, err = action_executor(o, pro_post_actions, [], t, post=False)()
        if not ret:
            return False

    if o.debug:
        LOG.dbg('install done')

    if o.install_temporary:
        LOG.log('\ninstalled to tmp \"{}\".'.format(tmpdir))
    LOG.log('\n{} dotfile(s) installed.'.format(installed))
    return True
Example #8
0
def main():
    """entry point"""
    try:
        o = Options()
    except YamlException as e:
        LOG.err('config file error: {}'.format(str(e)))
        return False

    if o.debug:
        LOG.dbg('\n\n')

    # check dependencies are met
    try:
        dependencies_met()
    except Exception as e:
        LOG.err(e)
        return False

    ret = True
    try:

        if o.cmd_profiles:
            # list existing profiles
            if o.debug:
                LOG.dbg('running cmd: profiles')
            cmd_list_profiles(o)

        elif o.cmd_files:
            # list files for selected profile
            if o.debug:
                LOG.dbg('running cmd: files')
            cmd_list_files(o)

        elif o.cmd_install:
            # install the dotfiles stored in dotdrop
            if o.debug:
                LOG.dbg('running cmd: install')
            ret = cmd_install(o)

        elif o.cmd_compare:
            # compare local dotfiles with dotfiles stored in dotdrop
            if o.debug:
                LOG.dbg('running cmd: compare')
            tmp = get_tmpdir()
            ret = cmd_compare(o, tmp)
            # clean tmp directory
            remove(tmp)

        elif o.cmd_import:
            # import dotfile(s)
            if o.debug:
                LOG.dbg('running cmd: import')
            ret = cmd_importer(o)

        elif o.cmd_update:
            # update a dotfile
            if o.debug:
                LOG.dbg('running cmd: update')
            ret = cmd_update(o)

        elif o.cmd_detail:
            # detail files
            if o.debug:
                LOG.dbg('running cmd: detail')
            cmd_detail(o)

        elif o.cmd_remove:
            # remove dotfile
            if o.debug:
                LOG.dbg('running cmd: remove')
            cmd_remove(o)

    except KeyboardInterrupt:
        LOG.err('interrupted')
        ret = False

    if ret and o.conf.save():
        LOG.log('config file updated')

    return ret
Example #9
0
def cmd_install(opts, conf, temporary=False, keys=[]):
    """install dotfiles for this profile"""
    dotfiles = conf.get_dotfiles(opts['profile'])
    if keys:
        # filtered dotfiles to install
        dotfiles = [d for d in dotfiles if d.key in set(keys)]
    if not dotfiles:
        msg = 'no dotfile to install for this profile (\"{}\")'
        LOG.warn(msg.format(opts['profile']))
        return False

    t = Templategen(base=opts['dotpath'],
                    variables=opts['variables'],
                    debug=opts['debug'])
    tmpdir = None
    if temporary:
        tmpdir = get_tmpdir()
    inst = Installer(create=opts['create'],
                     backup=opts['backup'],
                     dry=opts['dry'],
                     safe=opts['safe'],
                     base=opts['dotpath'],
                     workdir=opts['workdir'],
                     diff=opts['installdiff'],
                     debug=opts['debug'],
                     totemp=tmpdir,
                     showdiff=opts['showdiff'])
    installed = []
    for dotfile in dotfiles:
        preactions = []
        if not temporary and dotfile.actions \
                and Cfg.key_actions_pre in dotfile.actions:
            for action in dotfile.actions[Cfg.key_actions_pre]:
                preactions.append(action)
        if opts['debug']:
            LOG.dbg('installing {}'.format(dotfile))
        if hasattr(dotfile, 'link') and dotfile.link == LinkTypes.PARENTS:
            r = inst.link(t, dotfile.src, dotfile.dst, actions=preactions)
        elif hasattr(dotfile, 'link') and dotfile.link == LinkTypes.CHILDREN:
            r = inst.linkall(t, dotfile.src, dotfile.dst, actions=preactions)
        else:
            src = dotfile.src
            tmp = None
            if dotfile.trans_r:
                tmp = apply_trans(opts, dotfile)
                if not tmp:
                    continue
                src = tmp
            r = inst.install(t,
                             src,
                             dotfile.dst,
                             actions=preactions,
                             noempty=dotfile.noempty)
            if tmp:
                tmp = os.path.join(opts['dotpath'], tmp)
                if os.path.exists(tmp):
                    remove(tmp)
        if len(r) > 0:
            if not temporary and Cfg.key_actions_post in dotfile.actions:
                actions = dotfile.actions[Cfg.key_actions_post]
                # execute action
                for action in actions:
                    if opts['dry']:
                        LOG.dry('would execute action: {}'.format(action))
                    else:
                        if opts['debug']:
                            LOG.dbg('executing post action {}'.format(action))
                        action.execute()
        installed.extend(r)
    if temporary:
        LOG.log('\nInstalled to tmp \"{}\".'.format(tmpdir))
    LOG.log('\n{} dotfile(s) installed.'.format(len(installed)))
    return True
Example #10
0
def main():
    """entry point"""
    ret = True
    args = docopt(USAGE, version=VERSION)

    try:
        conf = Cfg(os.path.expanduser(args['--cfg']), debug=args['--verbose'])
    except ValueError as e:
        LOG.err('Config format error: {}'.format(str(e)))
        return False

    opts = conf.get_settings()
    opts['dry'] = args['--dry']
    opts['profile'] = args['--profile']
    opts['safe'] = not args['--force']
    opts['debug'] = args['--verbose']
    opts['installdiff'] = not args['--nodiff']
    opts['link'] = LinkTypes.NOLINK
    if opts['link_by_default']:
        opts['link'] = LinkTypes.PARENTS

    # Only invert link type from NOLINK to PARENTS and vice-versa
    if args['--inv-link'] and opts['link'] == LinkTypes.NOLINK:
        opts['link'] = LinkTypes.PARENTS
    if args['--inv-link'] and opts['link'] == LinkTypes.PARENTS:
        opts['link'] = LinkTypes.NOLINK

    opts['variables'] = conf.get_variables(opts['profile'],
                                           debug=opts['debug'])
    opts['showdiff'] = opts['showdiff'] or args['--showdiff']

    if opts['debug']:
        LOG.dbg('config file: {}'.format(args['--cfg']))
        LOG.dbg('options:\n{}'.format(opts))
        LOG.dbg('configs:\n{}'.format(conf.dump()))

    # resolve dynamic paths
    conf.eval_dotfiles(opts['profile'], opts['variables'], debug=opts['debug'])

    if ENV_NOBANNER not in os.environ \
            and opts['banner'] \
            and not args['--no-banner']:
        _header()

    try:

        if args['list']:
            # list existing profiles
            if opts['debug']:
                LOG.dbg('running cmd: list')
            cmd_list_profiles(conf)

        elif args['listfiles']:
            # list files for selected profile
            if opts['debug']:
                LOG.dbg('running cmd: listfiles')
            cmd_list_files(opts, conf, templateonly=args['--template'])

        elif args['install']:
            # install the dotfiles stored in dotdrop
            if opts['debug']:
                LOG.dbg('running cmd: install')
            ret = cmd_install(opts,
                              conf,
                              temporary=args['--temp'],
                              keys=args['<key>'])

        elif args['compare']:
            # compare local dotfiles with dotfiles stored in dotdrop
            if opts['debug']:
                LOG.dbg('running cmd: compare')
            tmp = get_tmpdir()
            opts['dopts'] = args['--dopts']
            ret = cmd_compare(opts,
                              conf,
                              tmp,
                              focus=args['--file'],
                              ignore=args['--ignore'])
            # clean tmp directory
            remove(tmp)

        elif args['import']:
            # import dotfile(s)
            if opts['debug']:
                LOG.dbg('running cmd: import')
            ret = cmd_importer(opts, conf, args['<path>'])

        elif args['update']:
            # update a dotfile
            if opts['debug']:
                LOG.dbg('running cmd: update')
            iskey = args['--key']
            ret = cmd_update(opts,
                             conf,
                             args['<path>'],
                             iskey=iskey,
                             ignore=args['--ignore'],
                             showpatch=args['--show-patch'])

        elif args['detail']:
            # detail files
            if opts['debug']:
                LOG.dbg('running cmd: update')
            cmd_detail(opts, conf, keys=args['<key>'])

    except KeyboardInterrupt:
        LOG.err('interrupted')
        ret = False

    if opts['debug']:
        LOG.dbg('configs:\n{}'.format(conf.dump()))

    return ret