diff options
author | Joris Roovers <joris.roovers@gmail.com> | 2022-09-01 10:04:34 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-09-01 10:04:34 +0200 |
commit | 871b66a9224af8817e115f6fd8fddab7bf8128c2 (patch) | |
tree | e782bf5af010a6af491a034f05f4ad2e5cbbbaf6 | |
parent | 800f6fd26c72e35388065281bfd8def084440825 (diff) |
Black formatting (#327)
- Removes flake8 as code style checker in favor of black
- Added fmt:on, fmt:off commenting guards to overrule black in specific
scenarios
- Updated docs, ./run_tests.sh, removed references to pep8
65 files changed, 1969 insertions, 1491 deletions
diff --git a/.github/workflows/checks.yml b/.github/workflows/checks.yml index 588ade0..4e71df4 100644 --- a/.github/workflows/checks.yml +++ b/.github/workflows/checks.yml @@ -58,8 +58,8 @@ jobs: GITLINT_USE_SH_LIB: 0 run: ./run_tests.sh -i - - name: PEP8 - run: ./run_tests.sh -p + - name: Code formatting (black) + run: ./run_tests.sh -f - name: PyLint run: ./run_tests.sh -l @@ -136,8 +136,8 @@ jobs: run: pytest -rw -s qa continue-on-error: true # Known to fail at this point - - name: PEP8 - run: flake8 gitlint-core qa examples + - name: Code formatting (black) + run: black . - name: PyLint run: pylint gitlint-core\gitlint qa --rcfile=".pylintrc" -r n diff --git a/docs/contributing.md b/docs/contributing.md index 1002676..4798e71 100644 --- a/docs/contributing.md +++ b/docs/contributing.md @@ -59,11 +59,11 @@ To run tests: ./run_tests.sh --collect-only --no-coverage # Only collect, don't run unit tests ./run_tests.sh --integration # Run integration tests (requires that you have gitlint installed) ./run_tests.sh --build # Run build tests (=build python package) -./run_tests.sh --pep8 # pep8 checks +./run_tests.sh --format # format checks ./run_tests.sh --stats # print some code stats ./run_tests.sh --git # inception: run gitlint against itself ./run_tests.sh --lint # run pylint checks -./run_tests.sh --all # Run unit, integration, pep8 and gitlint checks +./run_tests.sh --all # Run unit, integration, format and gitlint checks ``` The `Vagrantfile` comes with `virtualenv`s for python 3.6, 3.7, 3.8, 3.9 and pypy3.6. @@ -71,7 +71,7 @@ You can easily run tests against specific python environments by using the follo ```sh ./run_tests.sh --envs 36 # Run the unit tests against Python 3.6 ./run_tests.sh --envs 36,37,pypy36 # Run the unit tests against Python 3.6, Python 3.7 and Pypy3.6 -./run_tests.sh --envs 36,37 --pep8 # Run pep8 checks against Python 3.6 and Python 3.7 (also works for --git, --integration, --pep8, --stats and --lint. +./run_tests.sh --envs 36,37 --format # Run format checks against Python 3.6 and Python 3.7 (also works for --git, --integration, --format, --stats and --lint. ./run_tests.sh --envs all --all # Run all tests against all environments ./run_tests.sh --all-env --all # Idem: Run all tests against all environments ``` diff --git a/examples/my_commit_rules.py b/examples/my_commit_rules.py index 2805501..ad1d21d 100644 --- a/examples/my_commit_rules.py +++ b/examples/my_commit_rules.py @@ -27,20 +27,20 @@ class BodyMaxLineCount(CommitRule): id = "UC1" # A rule MAY have an option_spec if its behavior should be configurable. - options_spec = [IntOption('max-line-count', 3, "Maximum body line count")] + options_spec = [IntOption("max-line-count", 3, "Maximum body line count")] def validate(self, commit): self.log.debug("BodyMaxLineCount: This will be visible when running `gitlint --debug`") line_count = len(commit.message.body) - max_line_count = self.options['max-line-count'].value + max_line_count = self.options["max-line-count"].value if line_count > max_line_count: message = f"Body contains too many lines ({line_count} > {max_line_count})" return [RuleViolation(self.id, message, line_nr=1)] class SignedOffBy(CommitRule): - """ This rule will enforce that each commit contains a "Signed-off-by" line. + """This rule will enforce that each commit contains a "Signed-off-by" line. We keep things simple here and just check whether the commit body contains a line that starts with "Signed-off-by". """ @@ -61,8 +61,8 @@ class SignedOffBy(CommitRule): class BranchNamingConventions(CommitRule): - """ This rule will enforce that a commit is part of a branch that meets certain naming conventions. - See GitFlow for real-world example of this: https://nvie.com/posts/a-successful-git-branching-model/ + """This rule will enforce that a commit is part of a branch that meets certain naming conventions. + See GitFlow for real-world example of this: https://nvie.com/posts/a-successful-git-branching-model/ """ # A rule MUST have a human friendly name @@ -72,13 +72,13 @@ class BranchNamingConventions(CommitRule): id = "UC3" # A rule MAY have an option_spec if its behavior should be configurable. - options_spec = [ListOption('branch-prefixes', ["feature/", "hotfix/", "release/"], "Allowed branch prefixes")] + options_spec = [ListOption("branch-prefixes", ["feature/", "hotfix/", "release/"], "Allowed branch prefixes")] def validate(self, commit): self.log.debug("BranchNamingConventions: This line will be visible when running `gitlint --debug`") violations = [] - allowed_branch_prefixes = self.options['branch-prefixes'].value + allowed_branch_prefixes = self.options["branch-prefixes"].value for branch in commit.branches: valid_branch_name = False diff --git a/examples/my_configuration_rules.py b/examples/my_configuration_rules.py index 7c00707..ee3e981 100644 --- a/examples/my_configuration_rules.py +++ b/examples/my_configuration_rules.py @@ -36,7 +36,7 @@ class ReleaseConfigurationRule(ConfigurationRule): id = "UCR1" # A rule MAY have an option_spec if its behavior should be configurable. - options_spec = [IntOption('custom-verbosity', 2, "Gitlint verbosity for release commits")] + options_spec = [IntOption("custom-verbosity", 2, "Gitlint verbosity for release commits")] def apply(self, config, commit): self.log.debug("ReleaseConfigurationRule: This will be visible when running `gitlint --debug`") @@ -44,7 +44,6 @@ class ReleaseConfigurationRule(ConfigurationRule): # If the commit title starts with 'Release', we want to modify # how all subsequent rules interpret that commit if commit.message.title.startswith("Release"): - # If your Release commit messages are auto-generated, the # body might contain trailing whitespace. Let's ignore that config.ignore.append("body-trailing-whitespace") @@ -60,7 +59,7 @@ class ReleaseConfigurationRule(ConfigurationRule): # config.set_general_option(<general-option>, <value>) config.set_general_option("verbosity", 2) # Wwe can also use custom options to make this configurable - config.set_general_option("verbosity", self.options['custom-verbosity'].value) + config.set_general_option("verbosity", self.options["custom-verbosity"].value) # Strip any lines starting with $ from the commit message # (this only affects how gitlint sees your commit message, it does diff --git a/examples/my_line_rules.py b/examples/my_line_rules.py index 3a1ef36..777854b 100644 --- a/examples/my_line_rules.py +++ b/examples/my_line_rules.py @@ -21,8 +21,8 @@ that fits your needs. class SpecialChars(LineRule): - """ This rule will enforce that the commit message title does not contain any of the following characters: - $^%@!*() """ + """This rule will enforce that the commit message title does not contain any of the following characters: + $^%@!*()""" # A rule MUST have a human friendly name name = "title-no-special-chars" @@ -35,15 +35,20 @@ class SpecialChars(LineRule): target = CommitMessageTitle # A rule MAY have an option_spec if its behavior should be configurable. - options_spec = [ListOption('special-chars', ['$', '^', '%', '@', '!', '*', '(', ')'], - "Comma separated list of characters that should not occur in the title")] + options_spec = [ + ListOption( + "special-chars", + ["$", "^", "%", "@", "!", "*", "(", ")"], + "Comma separated list of characters that should not occur in the title", + ) + ] def validate(self, line, _commit): self.log.debug("SpecialChars: This will be visible when running `gitlint --debug`") violations = [] # options can be accessed by looking them up by their name in self.options - for char in self.options['special-chars'].value: + for char in self.options["special-chars"].value: if char in line: msg = f"Title contains the special character '{char}'" violation = RuleViolation(self.id, msg, line) diff --git a/gitlint-core/gitlint/cache.py b/gitlint-core/gitlint/cache.py index 1b6558f..b84c904 100644 --- a/gitlint-core/gitlint/cache.py +++ b/gitlint-core/gitlint/cache.py @@ -1,31 +1,31 @@ class PropertyCache: - """ Mixin class providing a simple cache. """ + """Mixin class providing a simple cache.""" def __init__(self): self._cache = {} def _try_cache(self, cache_key, cache_populate_func): - """ Tries to get a value from the cache identified by `cache_key`. - If no value is found in the cache, do a function call to `cache_populate_func` to populate the cache - and then return the value from the cache. """ + """Tries to get a value from the cache identified by `cache_key`. + If no value is found in the cache, do a function call to `cache_populate_func` to populate the cache + and then return the value from the cache.""" if cache_key not in self._cache: cache_populate_func() return self._cache[cache_key] def cache(original_func=None, cachekey=None): # pylint: disable=unused-argument - """ Cache decorator. Caches function return values. - Requires the parent class to extend and initialize PropertyCache. - Usage: - # Use function name as cache key - @cache - def myfunc(args): - ... - - # Specify cache key - @cache(cachekey="foobar") - def myfunc(args): - ... + """Cache decorator. Caches function return values. + Requires the parent class to extend and initialize PropertyCache. + Usage: + # Use function name as cache key + @cache + def myfunc(args): + ... + + # Specify cache key + @cache(cachekey="foobar") + def myfunc(args): + ... """ # Decorators with optional arguments are a bit convoluted in python, see some of the links below for details. @@ -41,6 +41,7 @@ def cache(original_func=None, cachekey=None): # pylint: disable=unused-argument def cache_func_result(): # Call decorated function and store its result in the cache args[0]._cache[cachekey] = func(*args) + return args[0]._try_cache(cachekey, cache_func_result) return wrapped diff --git a/gitlint-core/gitlint/cli.py b/gitlint-core/gitlint/cli.py index 415a8d3..5ba5d4c 100644 --- a/gitlint-core/gitlint/cli.py +++ b/gitlint-core/gitlint/cli.py @@ -37,12 +37,13 @@ LOG = logging.getLogger("gitlint.cli") class GitLintUsageError(GitlintError): - """ Exception indicating there is an issue with how gitlint is used. """ + """Exception indicating there is an issue with how gitlint is used.""" + pass def setup_logging(): - """ Setup gitlint logging """ + """Setup gitlint logging""" root_log = logging.getLogger("gitlint") root_log.propagate = False # Don't propagate to child loggers, the gitlint root logger handles everything handler = logging.StreamHandler() @@ -62,10 +63,20 @@ def log_system_info(): def build_config( # pylint: disable=too-many-arguments - target, config_path, c, extra_path, ignore, contrib, ignore_stdin, staged, fail_without_commits, verbose, - silent, debug + target, + config_path, + c, + extra_path, + ignore, + contrib, + ignore_stdin, + staged, + fail_without_commits, + verbose, + silent, + debug, ): - """ Creates a LintConfig object based on a set of commandline parameters. """ + """Creates a LintConfig object based on a set of commandline parameters.""" config_builder = LintConfigBuilder() # Config precedence: # First, load default config or config from configfile @@ -79,33 +90,33 @@ def build_config( # pylint: disable=too-many-arguments # Finally, overwrite with any convenience commandline flags if ignore: - config_builder.set_option('general', 'ignore', ignore) + config_builder.set_option("general", "ignore", ignore) if contrib: - config_builder.set_option('general', 'contrib', contrib) + config_builder.set_option("general", "contrib", contrib) if ignore_stdin: - config_builder.set_option('general', 'ignore-stdin', ignore_stdin) + config_builder.set_option("general", "ignore-stdin", ignore_stdin) if silent: - config_builder.set_option('general', 'verbosity', 0) + config_builder.set_option("general", "verbosity", 0) elif verbose > 0: - config_builder.set_option('general', 'verbosity', verbose) + config_builder.set_option("general", "verbosity", verbose) if extra_path: - config_builder.set_option('general', 'extra-path', extra_path) + config_builder.set_option("general", "extra-path", extra_path) if target: - config_builder.set_option('general', 'target', target) + config_builder.set_option("general", "target", target) if debug: - config_builder.set_option('general', 'debug', debug) + config_builder.set_option("general", "debug", debug) if staged: - config_builder.set_option('general', 'staged', staged) + config_builder.set_option("general", "staged", staged) if fail_without_commits: - config_builder.set_option('general', 'fail-without-commits', fail_without_commits) + config_builder.set_option("general", "fail-without-commits", fail_without_commits) config = config_builder.build() @@ -113,7 +124,7 @@ def build_config( # pylint: disable=too-many-arguments def get_stdin_data(): - """ Helper function that returns data sent to stdin or False if nothing is sent """ + """Helper function that returns data sent to stdin or False if nothing is sent""" # STDIN can only be 3 different types of things ("modes") # 1. An interactive terminal device (i.e. a TTY -> sys.stdin.isatty() or stat.S_ISCHR) # 2. A (named) pipe (stat.S_ISFIFO) @@ -145,7 +156,7 @@ def get_stdin_data(): def build_git_context(lint_config, msg_filename, commit_hash, refspec): - """ Builds a git context based on passed parameters and order of precedence """ + """Builds a git context based on passed parameters and order of precedence""" # Determine which GitContext method to use if a custom message is passed from_commit_msg = GitContext.from_commit_msg @@ -168,8 +179,10 @@ def build_git_context(lint_config, msg_filename, commit_hash, refspec): return from_commit_msg(stdin_input) if lint_config.staged: - raise GitLintUsageError("The 'staged' option (--staged) can only be used when using '--msg-filename' or " - "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.") @@ -195,7 +208,7 @@ def build_git_context(lint_config, msg_filename, commit_hash, refspec): def handle_gitlint_error(ctx, exc): - """ Helper function to handle exceptions """ + """Helper function to handle exceptions""" if isinstance(exc, GitContextError): click.echo(exc) ctx.exit(GIT_CONTEXT_ERROR_CODE) @@ -208,7 +221,7 @@ def handle_gitlint_error(ctx, exc): class ContextObj: - """ Simple class to hold data that is passed between Click commands via the Click context. """ + """Simple class to hold data that is passed between Click commands via the Click context.""" def __init__(self, config, config_builder, commit_hash, refspec, msg_filename, gitcontext=None): self.config = config @@ -219,6 +232,7 @@ class ContextObj: self.gitcontext = gitcontext +# fmt: off @click.group(invoke_without_command=True, context_settings={'max_content_width': 120}, epilog="When no COMMAND is specified, gitlint defaults to 'gitlint lint'.") @click.option('--target', envvar='GITLINT_TARGET', @@ -263,7 +277,6 @@ def cli( # pylint: disable=too-many-arguments Documentation: http://jorisroovers.github.io/gitlint """ - try: if debug: logging.getLogger("gitlint").setLevel(logging.DEBUG) @@ -273,8 +286,8 @@ def cli( # pylint: disable=too-many-arguments # Get the lint config from the commandline parameters and # 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, - fail_without_commits, verbose, silent, debug) + config, config_builder = build_config(target, config, c, extra_path, ignore, contrib, ignore_stdin, + staged, fail_without_commits, verbose, silent, debug) LOG.debug("Configuration\n%s", config) ctx.obj = ContextObj(config, config_builder, commit, commits, msg_filename) @@ -285,12 +298,13 @@ def cli( # pylint: disable=too-many-arguments except GitlintError as e: handle_gitlint_error(ctx, e) +# fmt: on @cli.command("lint") @click.pass_context def lint(ctx): - """ Lints a git repository [default command] """ + """Lints a git repository [default command]""" lint_config = ctx.obj.config refspec = ctx.obj.refspec commit_hash = ctx.obj.commit_hash @@ -312,7 +326,7 @@ def lint(ctx): raise GitLintUsageError(f'No commits in range "{refspec}"') ctx.exit(GITLINT_SUCCESS) - LOG.debug('Linting %d commit(s)', number_of_commits) + LOG.debug("Linting %d commit(s)", number_of_commits) general_config_builder = ctx.obj.config_builder last_commit = gitcontext.commits[-1] @@ -351,7 +365,7 @@ def lint(ctx): @cli.command("install-hook") @click.pass_context def install_hook(ctx): - """ Install gitlint as a git commit-msg hook. """ + """Install gitlint as a git commit-msg hook.""" try: hooks.GitHookInstaller.install_commit_msg_hook(ctx.obj.config) hook_path = hooks.GitHookInstaller.commit_msg_hook_path(ctx.obj.config) @@ -365,7 +379,7 @@ def install_hook(ctx): @cli.command("uninstall-hook") @click.pass_context def uninstall_hook(ctx): - """ Uninstall gitlint commit-msg hook. """ + """Uninstall gitlint commit-msg hook.""" try: hooks.GitHookInstaller.uninstall_commit_msg_hook(ctx.obj. |