def color_options(f): colors = cycle([ "fg-yellow", "fg-blue", "bold-True,fg-yellow", "bold-True,fg-blue", "bold-True,fg-cyan", "bold-True,fg-green", "bold-True,fg-magenta", "fg-red", "bold-True,fg-red", ]) f = flag("--with-legend/--without-legend", help="Start with a legend on colors", deprecated="please use --legend instead")(f) f = flag("--legend/--no-legend", default=config.get_value('config.color.legend') or False, help="Start with a legend on colors")(f) f = flag('--color/--no-color', default=True, help="Show levels in color")(f) f = option('--global-color', help="Color to show the global level", type=ColorType(), default="fg-cyan")(f) recipename_color = {} if config.project: f = option('--workgroup-color', help="Color to show the workgroup level", type=ColorType(), default="fg-magenta")(f) f = option('--local-color', help="Color to show the local level", type=ColorType(), default="fg-green")(f) for recipe in config.all_recipes: if recipe.short_name not in recipename_color: recipename_color[recipe.short_name] = next(colors) f = option('--{}-color'.format(recipe.name.replace('/', '-')), help="Color to show the {} level".format(recipe.name), type=ColorType(), default=recipename_color[recipe.short_name])(f) return f
def decorator(f): colors = cycle([ "fg-yellow", "fg-blue", "bold-True,fg-yellow", "bold-True,fg-blue", "bold-True,fg-cyan", "bold-True,fg-green", "bold-True,fg-magenta", "fg-red", "bold-True,fg-red", ]) f = flag("--legend/--no-legend", default=config.get_value('config.show.legend', True), help="Start with a legend on colors")(f) f = flag('--color/--no-color', default=config.get_value("config.show.color", True), help="Show profiles in color")(f) f = flag( '--full/--explicit-only', default=config.get_value('config.show.full', full_default), help= "Show the full information, even those guessed from the context" )(f) shortname_color = {} for profile in config.all_enabled_profiles: if profile.default_color is None: if profile.short_name not in shortname_color: shortname_color[profile.short_name] = next(colors) default_color = shortname_color[profile.short_name] else: default_color = profile.default_color f = option(f'--{profile.name.replace("/", "-")}-color', f"""{profile.name.replace("/", "_slash_")}_color""", help=f"Color to show the {profile.name} profile", type=ColorType(), default=default_color)(f) return f
def _get_command(self, path, parent=None): name = path.replace("@", ".") cmdhelp = "external command" command_name = name paths = self.cmddirs command_path = os.path.abspath( which(command_name, os.pathsep.join(paths))) options = [] arguments = [] flags = [] remaining_args = False ignore_unknown_options = False try: process = subprocess.Popen([command_path, "--help"], stdout=subprocess.PIPE, stderr=subprocess.PIPE) out, err = process.communicate() if process.returncode == 0: out = out.decode("utf-8") cmdhelp_lines = out.splitlines() + [''] try: index_desc = cmdhelp_lines.index('') + 1 except ValueError: index_desc = 0 try: metadata_desc = cmdhelp_lines.index('--') except ValueError: metadata_desc = -1 # then, we don't bother parsing the arguments. Let the # remaining arguments and unknown options pass through ignore_unknown_options = True remaining_args = "Remaining arguments" cmdhelp = "\n".join(cmdhelp_lines[index_desc:metadata_desc]) cmdhelp = cmdhelp.strip() metadata_out = out[metadata_desc:] ignore_unknown_options = False for l in metadata_out.splitlines(): if l.startswith("O:"): m = re.match( "^O:(?P<name>[^:]+):(?P<type>[^:]+):(?P<help>[^:]+)(:(?P<default>[^:]+))?$", l) if m is None: raise click.UsageError( "Expected format in {} is O:name:type:help[:defautl]," " got {}".format(path, l)) options.append(m.groupdict()) if l.startswith("F:"): m = re.match( "^F:(?P<name>[^:]+):(?P<help>[^:]+)(:(?P<default>[^:]+))?$", l) if m is None: raise click.UsageError( "Expected format in {} is F:name:help[:defautl]," " got {}".format(path, l)) flags.append(m.groupdict()) if l.startswith("A:"): m = re.match( "^A:(?P<name>[^:]+):(?P<type>[^:]+):(?P<help>[^:]+)(:(?P<nargs>[^:]+))?$", l) if m is None: raise click.UsageError( "Expected format in {} is A:name:type:help[:nargs]," " got {}".format(path, l)) arguments.append(m.groupdict()) m = re.match("^N:(?P<help>[^:]+)$", l) if m is not None: remaining_args = m.group("help") m = re.match("^M:(?P<meta>.+)$", l) if m is not None: meta = m.group("meta") if "I" in meta: ignore_unknown_options = True cmdflowdepends = re.search('flowdepends: (.+)', out) if cmdflowdepends: cmdflowdepends = cmdflowdepends.group(1).split(', ') else: cmdflowdepends = [] else: cmdflowdepends = [] cmdhelp = "No help found... (the command is most likely broken)" process.wait() except Exception as e: LOGGER.warning("When loading command {}: {}".format(name, e)) from click_project.overloads import on_command_loading_error on_command_loading_error() raise from click_project.decorators import command, argument, option, flag 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, ) types = { "int": int, "float": float, "str": str, } def get_type(t): if t.startswith("["): t = click.Choice(json.loads(t)) elif "." in t: t = t.split(".") m = importlib.import_module(".".join(t[:-1])) t = getattr(m, t[-1]) elif t.startswith("date("): format = re.match("date\((?P<format>.+)\)", t).group("format") from click_project.lib import parsedatetime t = lambda value: parsedatetime(value)[0].strftime(format) else: t = types[t] return t if remaining_args: external_command = argument('args', nargs=-1, help=remaining_args)(external_command) for o in options: if "type" in o: t = get_type(o["type"]) external_command = option( *(o["name"].split(",")), help=o["help"], type=t or str, default=o.get("default"), )(external_command) for a in reversed(arguments): if "type" in a: t = get_type(a["type"]) external_command = argument( a["name"], help=a["help"], type=t or str, nargs=int(a["nargs"] or "1"), )(external_command) for f in flags: external_command = flag( *(f["name"].split(",")), help=f["help"], default=f["default"] == "True", )(external_command) external_command = command( name=name, ignore_unknown_options=ignore_unknown_options, help=cmdhelp, short_help=cmdhelp.splitlines()[0] if cmdhelp else "", handle_dry_run=True, flowdepends=cmdflowdepends)(external_command) external_command.params.append( AutomaticOption(["--edit-customcommand"], help="Edit the external command", expose_value=False, is_flag=True, callback=lambda ctx, param, value: edit_external_command(command_path) if value is True else None)) external_command.customcommand_path = command_path return external_command
def _get_command(self, path, parent=None): prefix = config.app_name + "-" name = path.replace("@", ".") cmdhelp = "external command" command_name = prefix + name paths = external_cmds_paths() command_path = which(command_name, os.pathsep.join(paths)) options = [] arguments = [] flags = [] remaining_args = "Remaining arguments" try: process = subprocess.Popen([command_path, "--help"], stdout=subprocess.PIPE, stderr=subprocess.PIPE) out, err = process.communicate() if process.returncode == 0: out = out.decode("utf-8") cmdhelp_lines = out.splitlines() + [''] try: index_desc = cmdhelp_lines.index('') + 1 except ValueError: index_desc = 0 try: metadata_desc = cmdhelp_lines.index('--') remaining_args = False except ValueError: metadata_desc = -1 cmdhelp = "\n".join(cmdhelp_lines[index_desc:metadata_desc]) cmdhelp = cmdhelp.strip() metadata_out = out[metadata_desc:] for l in metadata_out.splitlines(): if l.startswith("O:"): m = re.match( "^O:(?P<name>[^:]+):(?P<type>[^:]+):(?P<help>[^:]+)$", l) if m is None: raise click.UsageError( "Expected format in {} is O:name:type:help," " got {}".format(path, l)) options.append(m.groupdict()) if l.startswith("F:"): m = re.match( "^F:(?P<name>[^:]+):(?P<help>[^:]+)(:(?P<default>[^:]+))?$", l) if m is None: raise click.UsageError( "Expected format in {} is F:name:help," " got {}".format(path, l)) flags.append(m.groupdict()) if l.startswith("A:"): m = re.match( "^A:(?P<name>[^:]+):(?P<type>[^:]+):(?P<help>[^:]+)(:(?P<nargs>[^:]+))?$", l) if m is None: raise click.UsageError( "Expected format in {} is A:name:type:help[:nargs]," " got {}".format(path, l)) arguments.append(m.groupdict()) m = re.match("^N:(?P<help>[^:]+)$", l) if m is not None: remaining_args = m.group("help") cmdflowdepends = re.search('flowdepends: (.+)', out) if cmdflowdepends: cmdflowdepends = cmdflowdepends.group(1).split(', ') else: cmdflowdepends = [] else: cmdflowdepends = [] cmdhelp = "No help found... (the command is most likely broken)" process.wait() except Exception as e: LOGGER.warning("When loading command {}: {}".format(name, e)) from click_project.overloads import on_command_loading_error on_command_loading_error() raise from click_project.decorators import command, argument, option, flag 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) types = { "int": int, "float": float, "str": str, } for o in options: if "type" in o: if "." in o["type"]: t = o["type"].split(".") m = importlib.import_module(".".join(t[:-1])) t = getattr(m, t[-1]) else: t = types[o["type"]] external_command = option( o["name"], help=o["help"], type=t or str, )(external_command) for a in arguments: if "type" in a: if "." in a["type"]: t = a["type"].split(".") m = importlib.import_module(".".join(t[:-1])) t = getattr(m, t[-1]) else: t = types[a["type"]] external_command = argument( a["name"], help=a["help"], type=t or str, nargs=int(a["nargs"] or "1"), )(external_command) for f in flags: external_command = flag( f["name"], help=f["help"], default=f["default"] == "True", )(external_command) if remaining_args: external_command = argument('args', nargs=-1, help=remaining_args)(external_command) external_command = command( name=name, help=cmdhelp, short_help=cmdhelp.splitlines()[0] if cmdhelp else "", handle_dry_run=True, flowdepends=cmdflowdepends)(external_command) return external_command