Skip to content

Instantly share code, notes, and snippets.

@moyuanhuang
Last active May 1, 2020 23:53
Show Gist options
  • Save moyuanhuang/8aaa736e22578cbedf9e3a11c9a03830 to your computer and use it in GitHub Desktop.
Save moyuanhuang/8aaa736e22578cbedf9e3a11c9a03830 to your computer and use it in GitHub Desktop.
Quick spelling check after commit
#!/usr/bin/env ruby
# frozen_string_literal: true
# 1. Install hunspell
# $ brew install hunspell
# 2. Download a dictionary from
# https://cgit.freedesktop.org/libreoffice/dictionaries/tree/en
# You'll need to put both `.aff` and `.dic` file in "~/Library/Spelling"
# 3. Set up a global git hooks for future usage
# $ git config --global init.templatedir '~/.git-templates'
# $ mkdir -p ~/.git-templates/hooks
# $ mv commit-msg ~/.git-templates/hooks
# $ chmod +x ~/.git-templates/hooks/commit-msg
# 4. Enable the after commit hook in the repositories that you want
# $ cd path/to/repo | git init
# 5. Get mad each time you try to commit :)
# $ git commit -m "Mark watns to commmit but he can't spelll English rihgt"
# Custom dictionary can be added in ~/Library/Spelling/LocalDictionary, where each words should be
# in its own line.
# Inspired by https://gist.github.com/javierg/1243024/ba0566413c9443d7563b2f3bbaefa8c09decdb10
class GitSpellCheckeCommit
COMMON_BOTTOM_SEPARATOR = '# Please enter the commit message for your changes.'
def initialize(file, locale:)
@file = file
@locale = locale
end
def validate!
content = File.read(@file).split(COMMON_BOTTOM_SEPARATOR).first
escaped_content = escape_content(content)
cmd = "echo \"#{escaped_content}\" | " \
"LC_ALL=#{@locale} hunspell -p ~/Library/Spelling/LocalDictionary"
@check = `#{cmd}`
end
def valid?
validate!.match?(/&/) ? false : true
end
def spelling_errors
@check.split("\n").select{ |line| line =~ /^&/ }.map do |line|
matches = line.match(/^&\s([^\s]+)\s\d+\s\d+:\s(.+)$/)
"- You used “#{matches[1]}” and hunspell suggested instead “#{matches[2]}”"
end
end
private
def escape_content(content)
content.gsub('`', '\\\`')
end
end
class String
# rubocop:disable Style/SingleLineMethods, Layout/EmptyLineBetweenDefs
def black; "\033[30m#{self}\033[0m" end
def red; "\033[31m#{self}\033[0m" end
def green; "\033[32m#{self}\033[0m" end
def brown; "\033[33m#{self}\033[0m" end
def blue; "\033[34m#{self}\033[0m" end
def magenta; "\033[35m#{self}\033[0m" end
def cyan; "\033[36m#{self}\033[0m" end
def gray; "\033[37m#{self}\033[0m" end
def bg_black; "\033[40m#{self}\033[0m" end
def bg_red; "\033[41m#{self}\033[0m" end
def bg_green; "\033[42m#{self}\033[0m" end
def bg_brown; "\033[43m#{self}\033[0m" end
def bg_blue; "\033[44m#{self}\033[0m" end
def bg_magenta; "\033[45m#{self}\033[0m" end
def bg_cyan; "\033[46m#{self}\033[0m" end
def bg_gray; "\033[47m#{self}\033[0m" end
def bold; "\033[1m#{self}\033[22m" end
def reverse_color; "\033[7m#{self}\033[27m" end
# rubocop:enable Style/SingleLineMethods, Layout/EmptyLineBetweenDefs
end
LOCALE = :en_US
commit = GitSpellCheckeCommit.new(ARGV.first, locale: LOCALE)
unless commit.valid?
puts '---------------------------------------------------------------------'.red
puts 'It looks like you have spell checking errors in your commit message:'.red
puts commit.spelling_errors.join("\n").green
puts '---------------------------------------------------------------------'.red
# exit 1 # uncomment this line if you want block this commit
end
exit 0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment