Example #1
0
def _try(description, last, command, args, call):
    """Try the completion"""
    if command == config.main_command.path:
        args = [config.main_command.path] + list(args)
    else:
        args = [config.main_command.path, command] + list(args)
    complete_envvar = "_{}_COMPLETE".format(config.main_command.path.upper().replace("-", "_"))
    if description:
        extra_env = {
            "COMMANDLINE": " ".join(quote(arg) for arg in args) + ('' if last else ' '),
            complete_envvar: "complete-fish",
        }
    else:
        extra_env = {
            "COMP_WORDS": " ".join(quote(arg) for arg in args),
            "COMP_CWORD": str(max(0, len(args) - (1 if last else 0))),
            complete_envvar: "complete",
        }
    extra_env.update({CASE_INSENSITIVE_ENV: 'ON'} if config.completion.case_insensitive else {})
    with updated_env(**extra_env):
        if call:
            call_me()
        else:
            oldvalue = click_project.completion.IN_COMPLETION
            click_project.completion.IN_COMPLETION = True
            config.main_command()
            click_project.completion.IN_COMPLETION = oldvalue
Example #2
0
def show(ctx, name_only, cmds, all, fields, format, **kwargs):
    """Show the flow dependencies of a command"""
    show_empty = len(cmds) > 0
    if all:
        cmds = cmds or sorted(get_sub_commands(ctx, config.main_command))
    else:
        cmds = cmds or sorted(config.flowdeps.readonly.keys())
    with TablePrinter(fields, format) as tp, Colorer(kwargs) as colorer:
        for cmd in cmds:
            if name_only:
                click.echo(cmd)
            else:
                if all:
                    deps = get_flow_commands_to_run(cmd)
                    formatted = " ".join(quote(p) for p in deps)
                else:
                    values = {
                        profile.name: " ".join([
                            quote(p) for p in config.flowdeps.all_settings.get(
                                profile.name, {}).get(cmd, [])
                        ])
                        for profile in config.all_enabled_profiles
                    }
                    args = colorer.colorize(values,
                                            config.flowdeps.readprofile)
                    formatted = " ".join(args)
                if show_empty:
                    formatted = formatted or "None"
                if formatted:
                    tp.echo(cmd, formatted)
Example #3
0
 def external_command(**kwargs):
     from click_project.lib import call
     config.merge_settings()
     args = ([command_path] + get_settings_for_path("parameters", path))
     env = {(config.main_command.path + "___" + key).upper():
            (str(value) if value else "")
            for key, value in kwargs.items()}
     ctx = click.get_current_context()
     env[(config.main_command.path +
          "___PATH").upper()] = (ctx.command_path.replace(" ",
                                                          "_").upper())
     while ctx:
         env.update({
             (ctx.command_path.replace(" ", "_") + "__" + key).upper():
             ((" ".join(map(quote, value)) if type(value) is tuple else
               str(value) if value else ""))
             for key, value in ctx.params.items()
         })
         ctx = ctx.parent
     env[(config.main_command.path + "___CMD_OPTIND").upper()] = (str(
         len(config.command_line_settings["parameters"][path])))
     env[(config.main_command.path + "___CMD_ARGS").upper()] = (
         " ".join(
             quote(a)
             for a in config.command_line_settings["parameters"][path]))
     env[(config.main_command.path + "___OPTIND").upper()] = (str(
         len(args[1:])))
     env[(config.main_command.path + "___ARGS").upper()] = (" ".join(
         quote(a) for a in args[1:]))
     with updated_env(**env):
         call(args)
Example #4
0
 def complete(self, ctx, incomplete):
     choices = [
         " ".join([quote(v) for v in value])
         for value in config.settings.get("launchers", {}).values()
     ]
     return [
         launcher for launcher in choices
         if startswith(launcher, incomplete)
     ]
        def external_command(**kwargs):
            from click_project.lib import call
            ctx = click.get_current_context()
            config.merge_settings()
            args = ([command_path] + list(ctx.params.get("args", [])))

            def value_to_string(value):
                return (" ".join(map(quote, value)) if type(value) is tuple
                        else str(value) if value else "")

            env = {("CLK___" + key).upper(): (value_to_string(value))
                   for key, value in kwargs.items()}
            env[("CLK___PATH").upper()] = (ctx.command_path.replace(
                " ", "_").upper())
            if "args" in ctx.params:
                env[("CLK___ARGS").upper()] = " ".join(
                    map(quote, ctx.params["args"]))

            while ctx:
                env.update({
                    (ctx.command_path.replace(" ", "_") + "__" + key).upper():
                    (value_to_string(value))
                    for key, value in ctx.params.items()
                })
                ctx = ctx.parent

            for path, parameters in config.get_settings2("parameters").items():
                env[(f"CLK_P_" + path.replace("-", "__").replace(
                    ".", "_")).upper()] = " ".join(map(quote, parameters))

            env[("CLK___CMD_OPTIND").upper()] = (str(
                len(
                    config.commandline_profile.get_settings("parameters")
                    [path])))
            env[("CLK___CMD_ARGS").upper()] = (" ".join(
                quote(a) for a in config.commandline_profile.get_settings(
                    "parameters")[path]))
            env[("CLK___OPTIND").upper()] = (str(len(args[1:])))
            env[("CLK___ALL").upper()] = (" ".join(quote(a) for a in args[1:]))
            with updated_env(**env):
                call(
                    args,
                    internal=True,
                )
Example #6
0
        def alias_command(ctx, *args, **kwargs):
            if "config" in kwargs:
                del kwargs["config"]
            commands = list(commands_to_run)

            for command_ in commands[:-1]:
                LOGGER.debug("Running command: {}".format(" ".join(
                    quote(c) for c in command_)))
                run(command_)
            arguments = ctx.command.complete_arguments[:]
            arguments = clean_flow_arguments(arguments)
            whole_command = commands[-1] + arguments
            original_command_ctx = get_ctx(whole_command, side_effects=True)
            cur_ctx = original_command_ctx
            ctxs = []
            # if the resolution of the context brought too many commands, we
            # must not call the call back of the children of the original_command
            while cur_ctx and ctx.command.original_command != cur_ctx.command:
                cur_ctx = cur_ctx.parent

            while cur_ctx:
                ctxs.insert(0, cur_ctx)
                cur_ctx = cur_ctx.parent
            LOGGER.develop("Running command: {}".format(" ".join(
                quote(c) for c in commands[-1])))

            def run_callback(_ctx):
                LOGGER.develop(
                    "Running callback of {} with args {}, params {}".format(
                        _ctx.command.path,
                        config.commandline_profile.get_settings("parameters")[
                            _ctx.command.path],
                        _ctx.params,
                    ))
                with _ctx:
                    old_resilient_parsing = _ctx.resilient_parsing
                    _ctx.resilient_parsing = ctx.resilient_parsing
                    _ctx.command.callback(**_ctx.params)
                    _ctx.resilient_parsing = old_resilient_parsing

            for cur_ctx in ctxs:
                run_callback(cur_ctx)
Example #7
0
def show(ctx, name_only, launchers, all, fields, format, **kwargs):
    """Show the launchers"""
    launchers = launchers or sorted(config.settings.get("launchers", {}))
    with TablePrinter(fields, format) as tp, Colorer(kwargs, all) as colorer:
        for launcher_name in launchers:
            if name_only:
                click.echo(launcher_name)
            else:
                if config.launchers.readlevel == "settings-file":
                    args = config.launchers.readonly.get(launcher_name, [])
                else:
                    values = {
                        level_name: " ".join([
                            quote(p) for p in config.launchers.
                            all_settings[level_name].get(launcher_name, [])
                        ])
                        for level_name in colorer.level_to_color
                    }
                    args = colorer.colorize(values, config.launchers.readlevel)
                if args and args[0]:
                    tp.echo(launcher_name, args)
Example #8
0
def show(ctx, name_only, launchers, fields, format, **kwargs):
    """Show the launchers"""
    launchers = launchers or sorted(config.settings.get("launchers", {}))
    with TablePrinter(fields, format) as tp, Colorer(kwargs) as colorer:
        for launcher_name in launchers:
            if name_only:
                click.echo(launcher_name)
            else:
                if config.launchers.readprofile == "settings-file":
                    args = config.launchers.readonly.get(launcher_name, [])
                else:
                    values = {
                        profile.name: " ".join([
                            quote(p) for p in config.launchers.all_settings[
                                profile.name].get(launcher_name, [])
                        ])
                        for profile in config.all_enabled_profiles
                    }
                    args = colorer.colorize(values,
                                            config.launchers.readprofile)
                if any(args):
                    tp.echo(launcher_name, args)
Example #9
0
def format(cmds):
    """Format the trigger command"""
    return " , ".join(" ".join(quote(arg) for arg in cmd) for cmd in cmds)
Example #10
0
 def get_line(profile_name):
     return " ".join([
         quote(p)
         for p in
         config.parameters.all_settings.get(profile_name, {}).get(cmd_name, [])
     ])
Example #11
0
    def _get_command(self, path, parent=None):
        name = path.split(".")[-1]
        commands_to_run = get_settings('alias')[path]["commands"]
        cmdhelp = get_settings('alias')[path]["documentation"]
        cmdhelp = cmdhelp or "Alias for: {}".format(' , '.join(' '.join(quote(arg) for arg in cmd) for cmd in commands_to_run))
        short_help = cmdhelp.splitlines()[0]
        if len(cmdhelp) > 55:
            short_help = cmdhelp[:52] + '...'
        deps = []

        for cmd in commands_to_run:

            cmdctx = get_ctx(cmd)
            # capture the flow of the aliased command only if it is not called
            # with an explicit flow
            if (
                    not cmdctx.params.get("flow") and
                    not cmdctx.params.get("flow_from") and
                    not cmdctx.params.get("flow_after")
            ):
                deps += get_flow_commands_to_run(cmdctx.command.path)
        c = get_ctx(commands_to_run[-1])
        kind = None

        def create_cls(cls):
            return cls(
                name=name,
                help=cmdhelp,
                short_help=short_help,
                ignore_unknown_options=c is not None and c.ignore_unknown_options)
        if c is not None:
            if isinstance(c.command, Group):
                cls = create_cls(group)
                kind = "group"
            elif isinstance(c.command, Command):
                cls = create_cls(command)
                kind = "command"
            elif isinstance(c.command, config.main_command.__class__):
                cls = click.group(cls=config.main_command.__class__, name=name, help=cmdhelp, short_help=short_help)
                kind = config.main_command.path
            else:
                raise NotImplementedError()
        elif commands_to_run[-1][0] == config.main_command.path:
            cls = click.group(cls=config.main_command.__class__, name=name, help=cmdhelp, short_help=short_help)
            del commands_to_run[-1][0]
            c = get_ctx(commands_to_run[-1])
            kind = config.main_command.path
        else:
            cls = create_cls(command)

        def alias_command(ctx, *args, **kwargs):
            if "config" in kwargs:
                del kwargs["config"]
            commands = list(commands_to_run)

            for command_ in commands[:-1]:
                LOGGER.debug("Running command: {}".format(" ".join(quote(c) for c in command_)))
                run(command_)
            arguments = ctx.command.complete_arguments[:]
            arguments = clean_flow_arguments(arguments)
            whole_command = commands[-1] + arguments
            original_command_ctx = get_ctx(whole_command, side_effects=True)
            cur_ctx = original_command_ctx
            ctxs = []
            # if the resolution of the context brought too many commands, we
            # must not call the call back of the children of the original_command
            while cur_ctx and ctx.command.original_command != cur_ctx.command:
                cur_ctx = cur_ctx.parent

            while cur_ctx:
                ctxs.insert(0, cur_ctx)
                cur_ctx = cur_ctx.parent
            LOGGER.develop("Running command: {}".format(" ".join(quote(c) for c in commands[-1])))

            def run_callback(_ctx):
                LOGGER.develop("Running callback of {} with args {}, params {}".format(
                    _ctx.command.path,
                    config.command_line_settings["parameters"][_ctx.command.path],
                    _ctx.params,
                ))
                with _ctx:
                    old_resilient_parsing = _ctx.resilient_parsing
                    _ctx.resilient_parsing = ctx.resilient_parsing
                    _ctx.command.callback(
                        **_ctx.params
                    )
                    _ctx.resilient_parsing = old_resilient_parsing
            for cur_ctx in ctxs:
                run_callback(cur_ctx)
        alias_command = pass_context(alias_command)
        alias_command = cls(alias_command)
        if deps:
            alias_command.clickproject_flowdepends = deps

        alias_command.commands_to_run = commands_to_run
        if c is not None:
            alias_command.original_command = c.command
            if kind == "group":
                if c.command.default_cmd_name is not None:
                    alias_command.set_default_command(c.command.default_cmd_name)
            elif kind == "command":
                alias_command.handle_dry_run = c.command.handle_dry_run
            alias_param_names = list(map(lambda c: c.name, alias_command.params))

            def was_given(param):
                return not (
                    # catched the default value only because it was not
                    # given to the command line
                    param.name in c.click_project_default_catch
                    or
                    # not given for sure
                    c.params.get(param.name) is None
                )
            alias_command.params = [
                param
                for param in c.command.params
                if param.name not in alias_param_names
                and param.name not in ("flow", "flow_from", "flow_after")
                and (
                    # options may be given several times
                    isinstance(param, click.Option)
                    or
                    (
                        # it is an argument then!
                        not was_given(param)
                        or
                        # may be given, but may be given again
                        param.multiple
                        or
                        # may be given, but may be given again
                        param.nargs == -1
                    )
                )
            ] + alias_command.params
            # any option required with nargs=-1 that was already given should be
            # no more required
            for param in alias_command.params:
                if param.nargs == -1 and param.required and was_given(param):
                    param.required = False
        return alias_command
Example #12
0
def compute_dot(cmds=None,
                strict=False,
                cluster=True,
                left_right=False,
                lonely=False):
    import networkx
    g = networkx.digraph.DiGraph()

    def cluster_replace(str):
        return str.replace(".", "_").replace("-", "_")

    dot = """digraph {\n"""
    if left_right:
        dot += """  rankdir = LR;\n"""
    clusters = defaultdict(six.moves.builtins.set)

    def register_cluster(cmd_path):
        if "." in cmd_path:
            parent_path = ".".join([part for part in cmd_path.split(".")[:-1]])
            clusters[parent_path].add(cmd_path)

    aliases = {}

    def fill_graph(cmds):
        for cmd in iter_commands(from_paths=cmds):
            if hasattr(cmd, "commands_to_run"):
                aliases[cmd.path] = cmd.commands_to_run
            LOGGER.develop("Looking at {}".format(cmd.path))
            if strict:
                deps = config.flowdeps.readonly.get(cmd.path, [])
            else:
                path = cmd.path
                deps = list(_flowdeps[path])
                while "." in path:
                    path = ".".join(path.split(".")[:-1])
                    deps += _flowdeps[path]
            for dep in deps:
                g.add_node(dep)
                g.add_node(cmd.path)
                try:
                    networkx.shortest_path(g, dep, cmd.path)
                except networkx.NetworkXNoPath:
                    pass
                else:
                    continue
                g.add_edge(dep, cmd.path)
                register_cluster(dep)
                register_cluster(cmd.path)
                if not dep.startswith("["):
                    fill_graph([dep])
            if lonely:
                g.add_node(cmd.path)
            register_cluster(cmd.path)

    fill_graph(cmds)
    nodes = g.nodes()
    adjacency = g.edges()
    if not adjacency:
        return None
    if cluster:
        for parent_path, cmds in six.iteritems(clusters):
            if lonely or len(cmds.intersection(nodes)) > 1:
                dot += """  subgraph cluster_{} {{\n""".format(
                    cluster_replace(parent_path))
                dot += """    label="{}";\n""".format(parent_path)
                for cmd in cmds:
                    if (lonely or cmd in nodes) and cmd not in clusters.keys():
                        dot += """    "{}";\n""".format(cmd)
                dot += "  }\n"
    for node in nodes:
        if node not in clusters.keys():
            dot += """  "{}" [label= "{}{}", fillcolor = {}, style = filled];\n""".format(
                node,
                node,
                "\n -> {}".format(' , '.join(
                    ' '.join(quote(arg) for arg in cmd)
                    for cmd in aliases[node])) if node in aliases else "",
                "greenyellow" if node in aliases else "skyblue",
            )
    for src, dst in adjacency:
        dot += """  "{}" -> "{}";\n""".format(src, dst)
    dot += "}"
    LOGGER.develop(dot)
    return dot