diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2021-01-25 13:26:11 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2021-01-25 13:26:35 +0000 |
commit | 4fee3e091a8d79a40f70ff9c1f87b29b9340049a (patch) | |
tree | 465ad9629a8ee56548bd6c51c3fc710907564911 /gitlint/cli.py | |
parent | Releasing debian version 0.14.0-1. (diff) | |
download | gitlint-4fee3e091a8d79a40f70ff9c1f87b29b9340049a.tar.xz gitlint-4fee3e091a8d79a40f70ff9c1f87b29b9340049a.zip |
Merging upstream version 0.15.0.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'gitlint/cli.py')
-rw-r--r-- | gitlint/cli.py | 100 |
1 files changed, 51 insertions, 49 deletions
diff --git a/gitlint/cli.py b/gitlint/cli.py index f284792..b162e5b 100644 --- a/gitlint/cli.py +++ b/gitlint/cli.py @@ -8,19 +8,20 @@ import stat import sys import click -# Error codes -MAX_VIOLATION_ERROR_CODE = 252 # noqa -USAGE_ERROR_CODE = 253 # noqa -GIT_CONTEXT_ERROR_CODE = 254 # noqa -CONFIG_ERROR_CODE = 255 # noqa - import gitlint from gitlint.lint import GitLinter from gitlint.config import LintConfigBuilder, LintConfigError, LintConfigGenerator from gitlint.git import GitContext, GitContextError, git_version from gitlint import hooks from gitlint.shell import shell -from gitlint.utils import ustr, LOG_FORMAT, IS_PY2 +from gitlint.utils import LOG_FORMAT +from gitlint.exception import GitlintError + +# Error codes +MAX_VIOLATION_ERROR_CODE = 252 +USAGE_ERROR_CODE = 253 +GIT_CONTEXT_ERROR_CODE = 254 +CONFIG_ERROR_CODE = 255 DEFAULT_CONFIG_FILE = ".gitlint" # -n: disable swap files. This fixes a vim error on windows (E303: Unable to open swap file for <path>) @@ -34,7 +35,7 @@ click.UsageError.exit_code = USAGE_ERROR_CODE LOG = logging.getLogger("gitlint.cli") -class GitLintUsageError(Exception): +class GitLintUsageError(GitlintError): """ Exception indicating there is an issue with how gitlint is used. """ pass @@ -134,7 +135,7 @@ def get_stdin_data(): # Only return the input data if there's actually something passed # i.e. don't consider empty piped data if input_data: - return ustr(input_data) + return str(input_data) return False @@ -151,7 +152,7 @@ def build_git_context(lint_config, msg_filename, refspec): # 1. Any data specified via --msg-filename if msg_filename: LOG.debug("Using --msg-filename.") - return from_commit_msg(ustr(msg_filename.read())) + return from_commit_msg(str(msg_filename.read())) # 2. Any data sent to stdin (unless stdin is being ignored) if not lint_config.ignore_stdin: @@ -162,15 +163,28 @@ def build_git_context(lint_config, msg_filename, refspec): return from_commit_msg(stdin_input) if lint_config.staged: - raise GitLintUsageError(u"The 'staged' option (--staged) can only be used when using '--msg-filename' or " - u"when piping data to gitlint via stdin.") + raise GitLintUsageError("The 'staged' option (--staged) can only be used when using '--msg-filename' or " + "when piping data to gitlint via stdin.") # 3. Fallback to reading from local repository LOG.debug("No --msg-filename flag, no or empty data passed to stdin. Using the local repo.") return GitContext.from_local_repository(lint_config.target, refspec) -class ContextObj(object): +def handle_gitlint_error(ctx, exc): + """ Helper function to handle exceptions """ + if isinstance(exc, GitContextError): + click.echo(exc) + ctx.exit(GIT_CONTEXT_ERROR_CODE) + elif isinstance(exc, GitLintUsageError): + click.echo(f"Error: {exc}") + ctx.exit(USAGE_ERROR_CODE) + elif isinstance(exc, LintConfigError): + click.echo(f"Config Error: {exc}") + ctx.exit(CONFIG_ERROR_CODE) + + +class ContextObj: """ Simple class to hold data that is passed between Click commands via the Click context. """ def __init__(self, config, config_builder, refspec, msg_filename, gitcontext=None): @@ -187,7 +201,7 @@ class ContextObj(object): type=click.Path(exists=True, resolve_path=True, file_okay=False, readable=True), help="Path of the target git repository. [default: current working directory]") @click.option('-C', '--config', type=click.Path(exists=True, dir_okay=False, readable=True, resolve_path=True), - help="Config file location [default: {0}]".format(DEFAULT_CONFIG_FILE)) + help=f"Config file location [default: {DEFAULT_CONFIG_FILE}]") @click.option('-c', multiple=True, help="Config flags in format <rule>.<option>=<value> (e.g.: -c T1.line-length=80). " + "Flag can be used multiple times to set multiple config values.") # pylint: disable=bad-continuation @@ -230,7 +244,7 @@ def cli( # pylint: disable=too-many-arguments # store it in the context (click allows storing an arbitrary object in ctx.obj). config, config_builder = build_config(target, config, c, extra_path, ignore, contrib, ignore_stdin, staged, verbose, silent, debug) - LOG.debug(u"Configuration\n%s", ustr(config)) + LOG.debug("Configuration\n%s", config) ctx.obj = ContextObj(config, config_builder, commits, msg_filename) @@ -238,15 +252,8 @@ def cli( # pylint: disable=too-many-arguments if ctx.invoked_subcommand is None: ctx.invoke(lint) - except GitContextError as e: - click.echo(ustr(e)) - ctx.exit(GIT_CONTEXT_ERROR_CODE) - except GitLintUsageError as e: - click.echo(u"Error: {0}".format(ustr(e))) - ctx.exit(USAGE_ERROR_CODE) - except LintConfigError as e: - click.echo(u"Config Error: {0}".format(ustr(e))) - ctx.exit(CONFIG_ERROR_CODE) + except GitlintError as e: + handle_gitlint_error(ctx, e) @cli.command("lint") @@ -294,7 +301,7 @@ def lint(ctx): if violations: # Display the commit hash & new lines intelligently if number_of_commits > 1 and commit.sha: - linter.display.e(u"{0}Commit {1}:".format( + linter.display.e("{0}Commit {1}:".format( "\n" if not first_violation or commit is last_commit else "", commit.sha[:10] )) @@ -315,10 +322,10 @@ def install_hook(ctx): try: hooks.GitHookInstaller.install_commit_msg_hook(ctx.obj.config) hook_path = hooks.GitHookInstaller.commit_msg_hook_path(ctx.obj.config) - click.echo(u"Successfully installed gitlint commit-msg hook in {0}".format(hook_path)) + click.echo(f"Successfully installed gitlint commit-msg hook in {hook_path}") ctx.exit(0) except hooks.GitHookInstallerError as e: - click.echo(ustr(e), err=True) + click.echo(e, err=True) ctx.exit(GIT_CONTEXT_ERROR_CODE) @@ -329,10 +336,10 @@ def uninstall_hook(ctx): try: hooks.GitHookInstaller.uninstall_commit_msg_hook(ctx.obj.config) hook_path = hooks.GitHookInstaller.commit_msg_hook_path(ctx.obj.config) - click.echo(u"Successfully uninstalled gitlint commit-msg hook from {0}".format(hook_path)) + click.echo(f"Successfully uninstalled gitlint commit-msg hook from {hook_path}") ctx.exit(0) except hooks.GitHookInstallerError as e: - click.echo(ustr(e), err=True) + click.echo(e, err=True) ctx.exit(GIT_CONTEXT_ERROR_CODE) @@ -344,8 +351,10 @@ def run_hook(ctx): exit_code = 1 while exit_code > 0: try: - click.echo(u"gitlint: checking commit message...") + click.echo("gitlint: checking commit message...") ctx.invoke(lint) + except GitlintError as e: + handle_gitlint_error(ctx, e) except click.exceptions.Exit as e: # Flush stderr andstdout, this resolves an issue with output ordering in Cygwin sys.stderr.flush() @@ -353,11 +362,11 @@ def run_hook(ctx): exit_code = e.exit_code if exit_code == 0: - click.echo(u"gitlint: " + click.style("OK", fg='green') + u" (no violations in commit message)") + click.echo("gitlint: " + click.style("OK", fg='green') + " (no violations in commit message)") continue - click.echo(u"-----------------------------------------------") - click.echo(u"gitlint: " + click.style("Your commit message contains the above violations.", fg='red')) + click.echo("-----------------------------------------------") + click.echo("gitlint: " + click.style("Your commit message contains the above violations.", fg='red')) value = None while value not in ["y", "n", "e"]: @@ -374,14 +383,7 @@ def run_hook(ctx): # - https://github.com/pallets/click/pull/1372 # - From https://click.palletsprojects.com/en/7.x/utils/#getting-characters-from-terminal # Note that this function will always read from the terminal, even if stdin is instead a pipe. - # - # We also need a to use raw_input() in Python2 as input() is unsafe (and raw_input() doesn't exist in - # Python3). See https://stackoverflow.com/a/4960216/381010 - input_func = input - if IS_PY2: - input_func = raw_input # noqa pylint: disable=undefined-variable - - value = input_func() + value = input() if value == "y": LOG.debug("run-hook: commit message accepted") @@ -396,15 +398,15 @@ def run_hook(ctx): LOG.debug("run-hook: %s %s", editor, msg_filename_path) shell(editor + " " + msg_filename_path) else: - click.echo(u"Editing only possible when --msg-filename is specified.") + click.echo("Editing only possible when --msg-filename is specified.") ctx.exit(exit_code) elif value == "n": LOG.debug("run-hook: commit message declined") - click.echo(u"Commit aborted.") - click.echo(u"Your commit message: ") - click.echo(u"-----------------------------------------------") + click.echo("Commit aborted.") + click.echo("Your commit message: ") + click.echo("-----------------------------------------------") click.echo(ctx.obj.gitcontext.commits[0].message.full) - click.echo(u"-----------------------------------------------") + click.echo("-----------------------------------------------") ctx.exit(exit_code) ctx.exit(exit_code) @@ -418,14 +420,14 @@ def generate_config(ctx): path = os.path.realpath(path) dir_name = os.path.dirname(path) if not os.path.exists(dir_name): - click.echo(u"Error: Directory '{0}' does not exist.".format(dir_name), err=True) + click.echo(f"Error: Directory '{dir_name}' does not exist.", err=True) ctx.exit(USAGE_ERROR_CODE) elif os.path.exists(path): - click.echo(u"Error: File \"{0}\" already exists.".format(path), err=True) + click.echo(f"Error: File \"{path}\" already exists.", err=True) ctx.exit(USAGE_ERROR_CODE) LintConfigGenerator.generate_config(path) - click.echo(u"Successfully generated {0}".format(path)) + click.echo(f"Successfully generated {path}") ctx.exit(0) |