Last active
August 31, 2015 15:27
-
-
Save amacdougall/1602cd2671a9050ddfa6 to your computer and use it in GitHub Desktop.
Viewport pre-commit hook
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/ruby | |
# | |
# Prevents commit, with an informative message, if any of the following | |
# conditions are true: | |
# | |
# Any js file in the src directory does not pass eslint. | |
# | |
# Any js file in the src directory requires formatting with js-beautify. | |
# | |
# Must have eslint and js-beautify installed as CLI apps. If they are not | |
# installed, error messages will offer a helping hand. | |
# | |
# Must be saved as .git/hooks/pre-commit, and must be executable. | |
# Use chmod a+x .git/hooks/pre-commmit if necessary. | |
# hack to permit user input during commit hook | |
# http://stackoverflow.com/questions/3417896/how-do-i-prompt-the-user-from-within-a-commit-msg-hook | |
STDIN.reopen('/dev/tty') | |
if `which npm`.empty? | |
puts "npm is not installed as a CLI app; pre-commit hook cannot run. See http://npmjs.com/." | |
print "Ask for help! Your dev setup is incomplete." | |
end | |
if `which eslint`.empty? | |
puts "eslint is not installed as a CLI app; pre-commit hook cannot run. See http://eslint.org/." | |
print "Install it now? y/n > " | |
if STDIN.gets =~ /[Yy]/ | |
puts "Installing eslint..." | |
`npm install -g eslint` | |
puts "Complete! Proceeding..." | |
else | |
puts "Run again after installing eslint; or rename/delete .git/hooks/pre-commit to disable this script." | |
exit 1 # exit with error, preventing commit | |
end | |
end | |
if `npm list -g babel-eslint` =~ /empty/ | |
puts "The babel-eslint module is not installed; pre-commit hook cannot run. See https://github.com/babel/babel-eslint." | |
print "Install it now? y/n > " | |
if STDIN.gets =~ /[Yy]/ | |
puts "Installing babel-eslint..." | |
`npm install -g babel-eslint` | |
puts "Complete! Proceeding..." | |
else | |
puts "Run again after installing babel-eslint; or rename/delete .git/hooks/pre-commit to disable this script." | |
exit 1 # exit with error, preventing commit | |
end | |
end | |
if `which js-beautify`.empty? | |
puts "js-beautify is not installed as a CLI app; pre-commit hook cannot run. See https://github.com/beautify-web/js-beautify." | |
print "Install it now? y/n > " | |
if STDIN.gets =~ /[Yy]/ | |
puts "Installing js-beautify..." | |
`npm install -g js-beautify` | |
puts "Installed! Proceeding..." | |
else | |
puts "Run again after installing js-beautify; or rename/delete .git/hooks/pre-commit to disable this script." | |
exit 1 # exit with error, preventing commit | |
end | |
end | |
jsbeautify_config = "../paperless-post/app/javascripts/design/.jsbeautifyrc" | |
eslint_config = "../paperless-post/app/javascripts/design/.eslintrc" | |
unless File.exists?(jsbeautify_config) | |
puts "File #{jsbeautify_config} not found; update your Rails repo." | |
end | |
unless File.exists?(eslint_config) | |
puts "File #{eslint_config} not found; update your Rails repo." | |
end | |
modified_files = `git diff --name-only --cached --diff-filter=AM`.split # only staged files, ignore deleted | |
if modified_files.empty? | |
exit 0 # nothing to commit; this hook passes, but git will issue an error message | |
end | |
files_to_beautify = [] # array of filenames | |
eslint_errors = [] # array of eslint error outputs | |
results = modified_files.each do |fname| | |
# js-beautify sends the beautified version to stdout; | |
# sed adds a trailing newline if there is not one already; | |
# diff compares the beautified and newlinified version to the original. | |
# | |
# Why add the newline? Curiously, js-beautify produces slightly different | |
# output from the grunt plugin, even if they run precisely the same | |
# executable; this is a workaround. | |
beautify_result = `js-beautify -f #{fname} --config="#{jsbeautify_config}" | sed -e '$a\\' | diff #{fname} -` | |
files_to_beautify << fname unless beautify_result.length == 0 | |
eslint_result = `eslint --config="#{eslint_config}" #{fname}` | |
eslint_errors << eslint_result if eslint_result =~ /\d+:\d+\s+error/ # must be in "col:row error" format | |
end | |
unless files_to_beautify.empty? | |
puts "The following #{files_to_beautify.count} files must be formatted with js-beautify:" | |
files_to_beautify.each {|f| puts f} | |
end | |
unless eslint_errors.empty? | |
puts "The following #{eslint_errors.count} files have lint errors:" | |
eslint_errors.each {|error| puts error} | |
end | |
if eslint_errors.empty? && files_to_beautify.empty? | |
exit 0 # exit without error, allowing commit | |
else | |
exit 1 # exit with error, preventing commit | |
end |
Updated to check only staged files, ignoring unstaged ones.
Updated to ignored deleted files.
Updated to read .eslintrc
from ../paperless-post/app/javascripts/design/.eslintrc
.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Updated to allow eslint warnings; only blocks on errors.