Skip to main content

Deprecated: project moved to githooks. | Write pretty and concise Git hooks in Python.

Project description

Project moved

This project has been renamed from SimpleGitHooks to GitHooks and moved to a new repository https://github.com/kamil-cy/githooks

Please visit the new home of this library here: ➡️ https://pypi.org/project/githooks/

The old simplegithooks package is no longer maintained.

SimpleGitHooks

Write pretty and concise Git hooks in Python. SimpleGitHooks lets you write an entire Git hook directly in Python, without using YAML. It’s ideal when you want full control and all your logic contained in a single file.

Installing

You can install via pip:

pip install simplegithooks

Hooks

PreCommit

Write simple pre-commit Git hook in your .git/hooks/pre-commit:

#!/usr/bin/env python
from simplegithooks import PreCommit

pre_commit = PreCommit(__file__)
pre_commit.add_ignored_file("src/simplegithooks/pre-commit.py")
pre_commit.check_content_for("FIXME", "❌", "error")
pre_commit.check_content_for("NotImplemented", "🚧", "fail")
pre_commit.check_content_for("TODO", "⚠️", "warning", prevent=False)
pre_commit.check_command("ruff check")
print(pre_commit.results())
print(pre_commit.summary())
exit(pre_commit.rc)

Let's say you have such file in staged changes main_1.py because you've forgot to finish:

import math

def add(b, c):
    # TODO add typing
    return b + c

def divide(a, b):
    # FIXME secure dividing by zero
    return a / b

def sqrt():
    raise NotImplementedError

And when you try to commit this file using git commit -m "message" the output will be:

output_main_1a.png

What happened here? Let's focus only on checks that prevents us from commit this change:

  • by default all checks prevents commit, unless you explicitly pass prevent=False
  • check_content_for("FIXME", "❌", "error") failed because FIXME was found in main_1.py
  • check_content_for("NotImplemented", "🚧", "fail") failed because NotImplemented was found in main_1.py
  • check_command("ruff check") failed because command ruff check returned non-zero output (because of unused import math)

Then if you fix issues the code now looks more on less like this:

import math

def add(b, c):
    # TODO add typing
    return b + c

def divide(a, b):
    try:
        return a / b
    except Exception:
        return float("inf")

def sqrt(x):
    return math.sqrt(x)

The output after commit will be:

output_main_1b.png

Now check_content_for("TODO", "⚠️", "warning", prevent=False) failed because TODO was found in main_1.py, yet this is not preventing us from commit changes, so commit command was succeeded but with warningCommit allowed conditionally.

Still we can do better 😉, so let's try harder:

import math
from typing import Any

def add(b:Any, c:Any):
    return b + c

def divide(a, b):
    try:
        return a / b
    except Exception:
        return float("inf")

def sqrt(x):
    return math.sqrt(x)

Finally we reached our goal:

output_main_1c.png

PrePush

Write simple pre-push Git hook in your .git/hooks/pre-push:

#!/usr/bin/env python
import sys

from simplegithooks import GitHook, PrePushConfig

pre_push = GitHook(__file__, PrePushConfig())
pre_push.add_ignored_files(["pre_push_example.py", "*.svg", "README.md"])
pre_push.check_command("rm -rf build/")
pre_push.check_command("rm -rf dist/")
pre_push.check_command("pytest")
print(pre_push.results())
print(pre_push.summary())
sys.exit(pre_push.rc)

You'll get similar outputs like for pre-commit.

Common config

Ignoring files

pre_commit.add_ignored_file("src/obsolete.py")
pre_commit.add_ignored_files(["src/stub1.py", "src/stub2.py"])

Support for Python's pathlib.Path pattern matching

pre_commit.add_ignored_files(["pre-commit.py", "*.svg", "README.md"])

Filter results

print(pre_commit.results("error"))
print(pre_commit.results("warning"))
print(pre_commit.results("error", preventing_only=True))
print(pre_commit.results("warning", preventing_only=True))

Check commands which RC=0 means failure

pre_commit.check_command("true", rc_zero_succes=False)  # ❯ true (ERROR, RC!=0 SUCCESS) 🔒
pre_commit.check_command("false", rc_zero_succes=False) # ❯ false (OK, RC!=0 SUCCESS)

Creating a symlink

Run simplegithooks pre-commit --install path/to/pre_commit.py or simplegithooks pre-push --install path/to/pre_push.py to create a symlink for you repository:

output_create_symlink.png

If a hook file already exists, an additional message e.g. WARNING: file '/home/user/project/.git/hooks/pre-commit' already exists and will be overwritten. will be shown as below

output_create_symlink.png

Troubleshooting

If you pass a bad hook name you'll receive a hint if there is a typo e.g. Unknown or unsupported hook: preccomyt, did you mean: pre-commit

In case of any problem while creating a symlink you'll get Failure, couldn't create the symbolic link. instead of success message.

License

This repository is licensed under the MIT License

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

simplegithooks-1.2.3.post0.tar.gz (11.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

simplegithooks-1.2.3.post0-py3-none-any.whl (11.6 kB view details)

Uploaded Python 3

File details

Details for the file simplegithooks-1.2.3.post0.tar.gz.

File metadata

  • Download URL: simplegithooks-1.2.3.post0.tar.gz
  • Upload date:
  • Size: 11.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.10.9 {"installer":{"name":"uv","version":"0.10.9","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Debian GNU/Linux","version":"13","id":"trixie","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for simplegithooks-1.2.3.post0.tar.gz
Algorithm Hash digest
SHA256 0316a31ea5f9f3013c0501858e51c82a0ccee48e192be64d46d58d64ec136e36
MD5 fd3251bf4b391a3712cf419d08273b89
BLAKE2b-256 df1362031eece0d20205ffaf1a06837dc560af7a6de5dd9e183c86448a612003

See more details on using hashes here.

File details

Details for the file simplegithooks-1.2.3.post0-py3-none-any.whl.

File metadata

  • Download URL: simplegithooks-1.2.3.post0-py3-none-any.whl
  • Upload date:
  • Size: 11.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.10.9 {"installer":{"name":"uv","version":"0.10.9","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Debian GNU/Linux","version":"13","id":"trixie","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for simplegithooks-1.2.3.post0-py3-none-any.whl
Algorithm Hash digest
SHA256 2939c717d0f6186350bd3beae538e5b74e176a8c25fc0ba6ef89748a7a1d1021
MD5 a4afbe9cda8feb27daf4ac04ff590275
BLAKE2b-256 542caef731af200449d44d6633627d9cf37a71bc46088b07e6807c798d73fd96

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page