def resolve_command(self, ctx, args): # Patch the `resolve_command` function to enable simple commands (eg. cld resource) # Only core commands from API and modules are registered (eg. cld admin) cmd_name = make_str(args[0]) original_cmd_name = cmd_name cmd = self.get_command(ctx, cmd_name) if cmd is None and ctx.token_normalize_func is not None: cmd_name = ctx.token_normalize_func(cmd_name) cmd = self.get_command(ctx, cmd_name) if cmd is None and not ctx.resilient_parsing: if split_opt(cmd_name)[0]: self.parse_args(ctx, ctx.args) if original_cmd_name in api.__dict__: cmd = self.get_command(ctx, "admin") return cmd_name, cmd, args elif original_cmd_name in uploader.__dict__: cmd = self.get_command(ctx, "uploader") return cmd_name, cmd, args else: ctx.fail('No such command "%s".' % original_cmd_name) return cmd_name, cmd, args[1:]
def resolve_command(self, ctx, args): cmd_name = make_str(args[0]) original_cmd_name = cmd_name cmd = self.get_command(ctx, cmd_name) if cmd is None and ctx.token_normalize_func is not None: cmd_name = ctx.token_normalize_func(cmd_name) cmd = self.get_command(ctx, cmd_name) if cmd is None and not ctx.resilient_parsing: if split_opt(cmd_name)[0]: self.parse_args(ctx, ctx.args) if original_cmd_name in api.__dict__: cmd = self.get_command(ctx, "admin") return cmd_name, cmd, args elif original_cmd_name in uploader.__dict__: cmd = self.get_command(ctx, "uploader") return cmd_name, cmd, args elif original_cmd_name in account.__dict__: cmd = self.get_command(ctx, "account") return cmd_name, cmd, args else: ctx.fail('No such command "%s".' % original_cmd_name) return cmd_name, cmd, args[1:]
def resolve_command(self, ctx, args): cmd_name = make_str(args[0]) if cmd_name in self.commands: return super().resolve_command(ctx, args) # Get the enrollment command cmd = self.get_command(ctx, 'enroll') return 'enroll', cmd, args
def resolve_command(self, ctx, args: List[str]) -> Tuple[str, Command, List[str]]: """ Modified version of :class:`click.core.MultiCommand.resolve_command` which bumps the version to the given string if it isn't one of ``major``, ``minor`` or ``patch``. :param ctx: :param args: """ # noqa: D400 # 3rd party from click.parser import split_opt from click.utils import make_str cmd_name = make_str(args[0]) # Get the command cmd = self.get_command(ctx, cmd_name) # If we can't find the command but there is a normalization # function available, we try with that one. if cmd is None and ctx.token_normalize_func is not None: # pragma: no cover cmd_name = ctx.token_normalize_func(cmd_name) cmd = self.get_command(ctx, cmd_name) # If we don't find the command we want to show an error message # to the user that it was not provided. However, there is # something else we should do: if the first argument looks like # an option we want to kick off parsing again for arguments to # resolve things like --help which now should go to the main # place. if cmd is None and not ctx.resilient_parsing: if split_opt(cmd_name)[0]: # pragma: no cover self.parse_args(ctx, ctx.args) @release_options @click.argument( "version", type=click.STRING, ) @release_command() def version(version: str, commit: Optional[bool], message: str, force: bool): # 3rd party from packaging.version import Version # this package from repo_helper.release import Bumper bumper = Bumper(PathPlus.cwd(), force) bumper.bump(Version(version.lstrip('v')), commit, message) return "version", cast(Command, version), args return cmd_name, cmd, args[1:]
def resolve_command(self, ctx, args): """Override how the command is resolved to check for deprecated.""" cmd_name = make_str(args[0]) for item in self.deprecated: if item.old_name == cmd_name: message = ('The `{}` command has moved to `{}` ' 'and will be removed in a future version.') logging.warn(message.format(cmd_name, item.new_name)) return cmd_name, item.cmd, args[1:] return click.Group.resolve_command(self, ctx, args)
def resolve_command(self, ctx, args): """Override how the command is resolved to check for deprecated.""" cmd_name = make_str(args[0]) for item in self.deprecated: if item.old_name == cmd_name: message = ('The `{}` command has moved to `{}` ' 'and will be removed in a future version.') logging.warn(message.format(cmd_name, item.new_name)) return cmd_name, item.cmd, args[1:] return click.Group.resolve_command(self, ctx, args)
def resolve_command( self, ctx: click.Context, args: List[str], ) -> Tuple[str, click.Command, List[str]]: # noqa: D102 """ Resolve the requested command belonging to this group, and print a suggestion if it can't be found. :param ctx: :param args: :return: The name of the matching command, the :class:`click.Command` object itself, and any remaining arguments. """ cmd_name = make_str(args[0]) original_cmd_name = cmd_name # Get the command cmd = self.get_command(ctx, cmd_name) # If we can't find the command but there is a normalization # function available, we try with that one. if cmd is None and ctx.token_normalize_func is not None: cmd_name = ctx.token_normalize_func(cmd_name) cmd = self.get_command(ctx, cmd_name) # If we don't find the command we want to show an error message # to the user that it was not provided. # However, there is something else we should do: # if the first argument looks like an option we want to kick off parsing again # for arguments to resolve things like --help which now should go to the main place. if cmd is None and not ctx.resilient_parsing: if split_opt(cmd_name)[0]: self.parse_args(ctx, ctx.args) closest = difflib.get_close_matches(original_cmd_name, self.commands, n=1) message = [f"No such command '{original_cmd_name}'."] if closest: message.append(f"The most similar command is {closest[0]!r}.") ctx.fail('\n'.join(message)) # TODO: cmd here is Optional[click.Command], typeshed says it should be just click.Command # I think typeshed is wrong. # https://github.com/python/typeshed/blob/484c014665cdf071b292dd9630f207c03e111895/third_party/2and3/click/core.pyi#L171 return cmd_name, cmd, args[1:] # type: ignore
def resolve_command(self, ctx, args): cmd_name = make_str(args[0]) if cmd_name in self.get_configured_aliases(): if cmd_name in self.list_commands(ctx): # Shadowing of existing commands is explicitly disabled. click.secho('"{}" references an existing command. I am ' 'ignoring the alias definition.'.format(cmd_name), fg='yellow') else: # If the command references a configured alias, retrieve it # from the configuration. alias = self.get_config().get('alias', cmd_name) args = args[1:] if alias.startswith('!'): cmd = SubprocessExecuter('') additional_args = ' '.join(shlex.quote(a) for a in args) return '', cmd, [alias[1:] + ' ' + additional_args] else: args = shlex.split(alias) + args return super().resolve_command(ctx, args)
def resolve_command(self, ctx, args): cmd_name = make_str(args[0]) if cmd_name in self.get_configured_aliases(): if cmd_name in self.list_commands(ctx): # Shadowing of existing commands is explicitly disabled. click.secho( '"{}" references an existing command. I am ' "ignoring the alias definition.".format(cmd_name), fg="yellow", ) else: # If the command references a configured alias, retrieve it # from the configuration. alias = self.get_config().get("alias", cmd_name) args = args[1:] if alias.startswith("!"): cmd = SubprocessExecuter("") additional_args = " ".join(shlex.quote(a) for a in args) return "", cmd, [alias[1:] + " " + additional_args] else: args = shlex.split(alias) + args return super().resolve_command(ctx, args)
def cli(ctx, file): """ Docker Factory Utility to build Docker images with any context PATH: Path to Dockerfactory.yml or directory with a Dockerfactory.yml """ if file.name == '-': # Input from stdin base_dir = os.getcwd() else: base_dir = os.path.dirname(file.name) with file as f: content = yaml.load(f) try: conf = DockerFactoryConf(content) except Exception as e: ctx.fail(u'Invalid Dockerfactory.yml: %s' % e) else: conf.validate(strict=True) # Validate context absolute_context = [] for src, dst in conf.context.items(): src = os.path.realpath(os.path.join(base_dir, src)) if not os.path.exists(src): ctx.fail(u'Could not find context source "%s"' % src) elif not dst.startswith('/'): ctx.fail(u'Context destination "%s" must be an absolute path' % dst) absolute_context.append((src, dst)) if conf.dockerfile: conf.dockerfile = os.path.realpath(os.path.join(base_dir, conf.dockerfile)) if not os.path.exists(conf.dockerfile): ctx.fail(u'Could not find Dockerfile "%s"' % conf.dockerfile) package = tempfile.TemporaryFile() # Build context with tarfile.open(fileobj=package, mode='w:gz') as f: for src, dst in absolute_context: f.add(src, dst) f.add(conf.dockerfile, '/Dockerfile') args = [] for k, v in conf.items(): if k not in ('context', 'dockerfile') and v is not None: param_name = '--%s' % k.replace('_', '-') if isinstance(v, bool): if v is True: args.append(param_name) else: args.extend((param_name, make_str(v))) package.seek(0) args = ['docker', 'build'] + args + ['-'] click.echo( u'Dockerfactory building:\n' u' With command: {command}\n' u' With Dockerfile: {dockerfile}\n' u' With context:\n - {context}\n'.format( dockerfile=conf.dockerfile, command=' '.join(args), context='\n - '.join([ '%s: %s' % (src, dst) for src, dst in absolute_context ]) ) ) with package: subprocess.check_call( args, stdin=package )
def _main( self: click.Command, *, args: Optional[Sequence[str]] = None, prog_name: Optional[str] = None, complete_var: Optional[str] = None, standalone_mode: bool = True, windows_expand_args: bool = True, **extra: Any, ) -> Any: # Typer override, duplicated from click.main() to handle custom rich exceptions # Verify that the environment is configured correctly, or reject # further execution to avoid a broken script. if args is None: args = sys.argv[1:] # Covered in Click tests if os.name == "nt" and windows_expand_args: # pragma: no cover args = click.utils._expand_args(args) else: args = list(args) if prog_name is None: if _get_click_major() > 7: prog_name = click.utils._detect_program_name() else: from click.utils import make_str prog_name = make_str( os.path.basename(sys.argv[0] if sys.argv else __file__)) # Process shell completion requests and exit early. if _get_click_major() > 7: self._main_shell_completion(extra, prog_name, complete_var) else: completion_init() from click.core import _bashcomplete # type: ignore _bashcomplete(self, prog_name, complete_var) try: try: with self.make_context(prog_name, args, **extra) as ctx: rv = self.invoke(ctx) if not standalone_mode: return rv # it's not safe to `ctx.exit(rv)` here! # note that `rv` may actually contain data like "1" which # has obvious effects # more subtle case: `rv=[None, None]` can come out of # chained commands which all returned `None` -- so it's not # even always obvious that `rv` indicates success/failure # by its truthiness/falsiness ctx.exit() except (EOFError, KeyboardInterrupt): click.echo(file=sys.stderr) raise click.Abort() except click.ClickException as e: if not standalone_mode: raise # Typer override if rich: rich_utils.rich_format_error(e) else: e.show() # Typer override end sys.exit(e.exit_code) except OSError as e: if e.errno == errno.EPIPE: sys.stdout = cast(TextIO, click.utils.PacifyFlushWrapper(sys.stdout)) sys.stderr = cast(TextIO, click.utils.PacifyFlushWrapper(sys.stderr)) sys.exit(1) else: raise except click.exceptions.Exit as e: if standalone_mode: sys.exit(e.exit_code) else: # in non-standalone mode, return the exit code # note that this is only reached if `self.invoke` above raises # an Exit explicitly -- thus bypassing the check there which # would return its result # the results of non-standalone execution may therefore be # somewhat ambiguous: if there are codepaths which lead to # `ctx.exit(1)` and to `return 1`, the caller won't be able to # tell the difference between the two return e.exit_code except click.Abort: if not standalone_mode: raise # Typer override if rich: rich_utils.rich_abort_error() else: click.echo(_("Aborted!"), file=sys.stderr) # Typer override end sys.exit(1)