Skip to content

Instantly share code, notes, and snippets.

@crimeminister
Created January 1, 2012 00:11
Show Gist options
  • Save crimeminister/1545725 to your computer and use it in GitHub Desktop.
Save crimeminister/1545725 to your computer and use it in GitHub Desktop.
Git hook to insert word count into commit message.
#!/usr/bin/python3
#
# A hook script to prepare the commit log message.
#
# Called by git-commit with the name of the file that has the commit
# message, followed by the description of the commit message's source.
# The hook's purpose is to edit the commit message file. If the hook
# fails with a non-zero status, the commit is aborted.
import glob
import os.path
import sys
# Count the number of words in an English language text.
def count_words(chapter_path):
word_count = 0
chapters = glob.glob(os.path.join(chapter_path, '*.txt'))
for chapter in chapters:
with open(chapter, mode='r', encoding='utf-8') as chapter_file:
chapter_text = chapter_file.read()
word_count += len(chapter_text.split())
return word_count
# Get the top-level repository path.
def get_project_path():
# First argv entry is path to this hook file.
hook_file = sys.argv[0]
from os.path import dirname
project_path = dirname(dirname(dirname(hook_file)))
return project_path
# Read the commit message.
def get_commit_message(commit_filename):
with open(commit_filename, mode='r', encoding='utf-8') as commit_file:
lines = commit_file.readlines()
return lines
# Write the new commit message contents.
def set_commit_message(commit_filename, lines):
with open(commit_filename, mode='w', encoding='utf-8') as commit_file:
commit_file.writelines(lines)
def inject_stats_message(commit_filename, stats):
# Read the lines of the raw commit message.
lines = get_commit_message(commit_filename)
# NB: you can skip quotes around a dictionary key name within a
# replacement field. Cf. PEP 3101: Advanced String Formatting.
stat_string = "words: {stats[word_count]}".format(stats=stats)
# The text to prepend to the commit message.
message = ["\n", "\n", stat_string]
message.reverse()
# Inject our message text into the commit message.
for line in message:
lines.insert(0, line)
# Store the updated commit message.
set_commit_message(commit_filename, lines)
def get_statistics(chapter_path):
# Add the utils/ directory to the python path so we can import the
# word_count utilities.
python_path = os.path.join(get_project_path(), 'utils')
sys.path.append(python_path)
import word_count
# Data to be injected into the commit message.
stats = {}
# Get total word count for all files in chapters directory.
stats['word_count'] = word_count.count_words(chapter_path)
return stats
def main():
# The only script argument is the name of the file where the commit
# message is located.
commit_filename = sys.argv[1]
# Get the path to the chapters/ directory.
chapter_path = os.path.realpath(os.path.join(get_project_path(), 'chapters'))
# Collect some statistics about the text corpus.
stats = get_statistics(chapter_path)
# Inject the statistics into the commit message.
inject_stats_message(commit_filename, stats)
if __name__ == '__main__':
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment