Loading hooks/squash.py +70 −1 Original line number Diff line number Diff line Loading @@ -20,18 +20,23 @@ Block commit starting with "squash!" or "fixup!" from being pushed These commits must be squashed before a push to a remote """ import argparse import os import sys from collections import defaultdict from fnmatch import fnmatch from pathlib import Path from subprocess import PIPE from subprocess import Popen from textwrap import dedent from urllib.parse import urlparse Z40 = '0' * 40 GIT_EXEC_PATH = 'GIT_EXEC_PATH' PRE_COMMIT_TO_REF = 'PRE_COMMIT_TO_REF' PRE_COMMIT_FROM_REF = 'PRE_COMMIT_FROM_REF' PRE_COMMIT_REMOTE_URL = 'PRE_COMMIT_REMOTE_URL' PRE_COMMIT_REMOTE_BRANCH = 'PRE_COMMIT_REMOTE_BRANCH' class CommitDict(defaultdict): Loading Loading @@ -103,10 +108,74 @@ def catalogue_commits(): yield from commits.values() def parse_arguments(): """ Parse command line arguments and handle any that have an immediate effect """ parser = argparse.ArgumentParser() parser.add_argument('--skip-branch', action='append') parser.add_argument('--skip-remote', action='append') opts = parser.parse_args() if opts.skip_branch: skip_branch(*opts.skip_branch) if opts.skip_remote: skip_remote(*opts.skip_remote) def skip_branch(*skip_branches: str): """ Exit (0) if PRE_COMMIT_REMOTE_BRANCH is set and matches a provided fnmatch() pattern """ if PRE_COMMIT_REMOTE_BRANCH not in os.environ: sys.stderr.write(dedent(""" The --skip-branch feature does not support your version of pre-commit. If this check fails you need to push to branches matching the skipped patterns with: git push --no-verify ... """)) return branch = os.environ[PRE_COMMIT_REMOTE_BRANCH] for pattern in skip_branches: if fnmatch(branch, pattern): sys.exit(0) def skip_remote(*skip_remotes: str): """ Exit (0) if PRE_COMMIT_REMOTE_URL is set and matches a provided URL pattern """ if PRE_COMMIT_REMOTE_URL not in os.environ: sys.stderr.write(dedent(""" The --skip-remote feature does not support your version of pre-commit. If this check fails you need to push to branches matching the skipped patterns with: git push --no-verify ... """)) return remote_url = urlparse(os.environ[PRE_COMMIT_REMOTE_URL]) for skip_url in (urlparse(u, scheme='') for u in skip_remotes): if skip_url.scheme and skip_url.scheme != remote_url.scheme: continue if skip_url.netloc != remote_url.netloc: continue if skip_url.path and not fnmatch(remote_url.path, skip_url.path): continue sys.exit(0) def main(): """ CLI entrypoint """ parse_arguments() retcode = 0 output = sys.stderr.write for commit in catalogue_commits(): Loading Loading
hooks/squash.py +70 −1 Original line number Diff line number Diff line Loading @@ -20,18 +20,23 @@ Block commit starting with "squash!" or "fixup!" from being pushed These commits must be squashed before a push to a remote """ import argparse import os import sys from collections import defaultdict from fnmatch import fnmatch from pathlib import Path from subprocess import PIPE from subprocess import Popen from textwrap import dedent from urllib.parse import urlparse Z40 = '0' * 40 GIT_EXEC_PATH = 'GIT_EXEC_PATH' PRE_COMMIT_TO_REF = 'PRE_COMMIT_TO_REF' PRE_COMMIT_FROM_REF = 'PRE_COMMIT_FROM_REF' PRE_COMMIT_REMOTE_URL = 'PRE_COMMIT_REMOTE_URL' PRE_COMMIT_REMOTE_BRANCH = 'PRE_COMMIT_REMOTE_BRANCH' class CommitDict(defaultdict): Loading Loading @@ -103,10 +108,74 @@ def catalogue_commits(): yield from commits.values() def parse_arguments(): """ Parse command line arguments and handle any that have an immediate effect """ parser = argparse.ArgumentParser() parser.add_argument('--skip-branch', action='append') parser.add_argument('--skip-remote', action='append') opts = parser.parse_args() if opts.skip_branch: skip_branch(*opts.skip_branch) if opts.skip_remote: skip_remote(*opts.skip_remote) def skip_branch(*skip_branches: str): """ Exit (0) if PRE_COMMIT_REMOTE_BRANCH is set and matches a provided fnmatch() pattern """ if PRE_COMMIT_REMOTE_BRANCH not in os.environ: sys.stderr.write(dedent(""" The --skip-branch feature does not support your version of pre-commit. If this check fails you need to push to branches matching the skipped patterns with: git push --no-verify ... """)) return branch = os.environ[PRE_COMMIT_REMOTE_BRANCH] for pattern in skip_branches: if fnmatch(branch, pattern): sys.exit(0) def skip_remote(*skip_remotes: str): """ Exit (0) if PRE_COMMIT_REMOTE_URL is set and matches a provided URL pattern """ if PRE_COMMIT_REMOTE_URL not in os.environ: sys.stderr.write(dedent(""" The --skip-remote feature does not support your version of pre-commit. If this check fails you need to push to branches matching the skipped patterns with: git push --no-verify ... """)) return remote_url = urlparse(os.environ[PRE_COMMIT_REMOTE_URL]) for skip_url in (urlparse(u, scheme='') for u in skip_remotes): if skip_url.scheme and skip_url.scheme != remote_url.scheme: continue if skip_url.netloc != remote_url.netloc: continue if skip_url.path and not fnmatch(remote_url.path, skip_url.path): continue sys.exit(0) def main(): """ CLI entrypoint """ parse_arguments() retcode = 0 output = sys.stderr.write for commit in catalogue_commits(): Loading