Skip to content

Commit

Permalink
Add precommit hooks for running Rubocop on .rb files
Browse files Browse the repository at this point in the history
  • Loading branch information
nieltg committed Dec 10, 2019
1 parent 41f95d9 commit da2be05
Show file tree
Hide file tree
Showing 3 changed files with 153 additions and 0 deletions.
145 changes: 145 additions & 0 deletions .hooks/pre-commit
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
#!/bin/bash

log_and_quit_if_error() {
log_file="$(mktemp)"
trap "rm -f $log_file" RETURN
(
set -ex
"$@"
) 2>"$log_file"

exit_number=$?
if [ $exit_number -ne 0 ]; then
echo 1>&2
echo "Command is failed. Log:" 1>&2
echo 1>&2
cat "$log_file" 1>&2
fi
return $exit_number
}

stash_changes() {
staged_tree="$(git write-tree)"
git add .
unstaged_tree="$(git write-tree)"
echo "$unstaged_tree"

git read-tree "$staged_tree"
git checkout-index -af
}

generate_diff_from_trees() {
git diff-tree --ignore-submodules --binary --no-color --no-ext-diff --unified=0 "$@"
echo
}

apply_tree() {
current_tree="$(git write-tree)"
target_tree="$1"
generate_diff_from_trees "$current_tree" "$target_tree" | git apply -v --whitespace=nowarn --recount --unidiff-zero
}

list_staged_files() {
git diff -z --staged --diff-filter=ACMR --name-only
}

each_null_terminated() {
command=("$@")
xargs -0 -n1 bash -c '"$@"' _ "${command[@]}"
}

each_staged_files() {
command=("$@")
list_staged_files | each_null_terminated "${command[@]}"
}

lint_file() {
case "$1" in
*.rb)
bundle exec rubocop -a "$1"
;;
esac

git add "$1"
}

ensure_base_directory_exists() {
base_directory_path="$(dirname "$1")"
mkdir -p "$base_directory_path"
}

log_lint_file() {
log_dir="$1"
target_path="$2"
log_file_path="$log_dir/$target_path"
ensure_base_directory_exists "$log_file_path"

if lint_file "$target_path" >"$log_file_path" 2>&1; then
rm "$log_file_path"
else
return 255
fi
}

lint_staged_files() {
log_path="$1"

export -f ensure_base_directory_exists lint_file log_lint_file
each_staged_files log_lint_file "$log_path"
}

each_log_in_path() {
log_path="$1"
shift
command=("$@")

(
cd "$log_path"
find . -type f -exec bash -c '"$@"' _ "${command[@]}" {} ';'
)
}

report_log_entry() {
echo 1>&2
echo "${1:2}:" 1>&2
cat "$1" 1>&2
}

report_logs() {
log_path="$1"

export -f report_log_entry
each_log_in_path "$log_path" report_log_entry
}

lint_staged_files_or_report_error() {
log_dir="$(mktemp -d)"
trap "rm -rf $log_dir" RETURN

if ! lint_staged_files "$log_dir"; then
echo "Lint is failed. Log:" 1>&2
report_logs "$log_dir"
fi
}

unstage_changes() {
unstaged_tree="$1"

git read-tree "$unstaged_tree"
git checkout-index -af
}

prepare_index_for_commit() {
unstaged_tree="$1"
linted_tree="$(git write-tree)"

unstage_changes "$unstaged_tree"
git read-tree "$linted_tree"
}

unstaged_tree="$(log_and_quit_if_error stash_changes)"
exit_status=$?
[ $exit_status -ne 0 ] && exit $exit_status

lint_staged_files_or_report_error
log_and_quit_if_error prepare_index_for_commit "$unstaged_tree"
1 change: 1 addition & 0 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ group :development do
gem 'spring', '<= 2.0.2'
gem 'spring-watcher-listen', '<= 2.0.1'
gem 'web-console', '<= 3.6.2'
gem 'git-hookshot', github: 'brandonweiss/git-hookshot'
end

group :test do
Expand Down
7 changes: 7 additions & 0 deletions Gemfile.lock
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
GIT
remote: https://github.com/brandonweiss/git-hookshot.git
revision: f48aa6748aa413049d83715cc74b12bcf6aed027
specs:
git-hookshot (0.1.0)

GEM
remote: https://rubygems.org/
specs:
Expand Down Expand Up @@ -564,6 +570,7 @@ DEPENDENCIES
fakeredis
figaro (<= 1.1.1)
filterrific
git-hookshot!
jar-dependencies (<= 0.3.12)
jbuilder (<= 2.7.0)
jquery-rails
Expand Down

0 comments on commit da2be05

Please sign in to comment.