Skip to content

Commit ed12c31

Browse files
committed
Convert built-in hooks to use required_executable option
The new `required_executable` option (and its accompanying `install_command` option) allows us to remove a ton of boilerplate code and specs, since it takes care of checking for the existence of the executable. This does introduce a behavior change in that all these hooks will now fail (instead of warn or whatever their previous behavior was) in the event the executable doesn't exist. This is acceptable since if you have a hook enabled you shouldn't be ignoring it. If it isn't useful you should disable it. Change-Id: Icfe06e844e9ffe5f5234fd7c4629a1d54e02fe93 Reviewed-on: http://gerrit.causes.com/42289 Tested-by: jenkins <jenkins@causes.com> Reviewed-by: Shane da Silva <shane.dasilva@brigade.com>
1 parent 99b1ea6 commit ed12c31

31 files changed

+102
-267
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
* Add `required_executable` and `install_command` options that allow a hook
1010
to define an executable that must be in the `PATH` in order for it to work,
1111
and a command the user can use to install the executable if it doesn't exist
12+
* All built-in hooks will now fail if the required executable is not present
1213

1314
## 0.17.0
1415

config/default.yml

+31-1
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,8 @@ PostCheckout:
2222
required: false
2323
quiet: false
2424
IndexTags:
25-
description: 'Generating tags file from source'
2625
enabled: false
26+
description: 'Generating tags file from source'
2727

2828
# Hooks that are run after `git commit` is executed, before the commit message
2929
# editor is displayed. These hooks are ideal for syntax checkers, linters, and
@@ -50,18 +50,24 @@ PreCommit:
5050

5151
BerksfileCheck:
5252
description: 'Checking Berksfile lock'
53+
required_executable: 'berks'
54+
install_command: 'gem install berks'
5355
include:
5456
- 'Berksfile'
5557
- 'Berksfile.lock'
5658

5759
Brakeman:
5860
enabled: false
5961
description: 'Checking for security vulnerabilities'
62+
required_executable: 'brakeman'
63+
install_command: 'gem install brakeman'
6064
include:
6165
- '**/*.rb'
6266

6367
BundleCheck:
6468
description: 'Checking Gemfile dependencies'
69+
required_executable: 'bundle'
70+
install_command: 'gem install bundler'
6571
include:
6672
- 'Gemfile'
6773
- 'Gemfile.lock'
@@ -70,22 +76,32 @@ PreCommit:
7076
ChamberSecurity:
7177
enabled: false
7278
description: 'Checking that settings have been secured with Chamber'
79+
required_executable: 'chamber'
80+
install_command: 'gem install chamber'
7381
include: 'config/settings.yml'
7482

7583
CoffeeLint:
7684
description: 'Analyzing with coffeelint'
85+
required_executable: 'coffeelint'
86+
install_command: 'npm install -g coffeelint'
7787
include: '**/*.coffee'
7888

7989
CssLint:
8090
description: 'Analyzing with csslint'
91+
required_executable: 'csslint'
92+
install_command: 'npm install -g csslint'
8193
include: '**/*.css'
8294

8395
GoLint:
8496
description: 'Analyzing with golint'
97+
required_executable: 'golint'
98+
install_command: 'go get github.com/golang/lint/golint'
8599
include: '**/*.go'
86100

87101
HamlLint:
88102
description: 'Analyzing with haml-lint'
103+
required_executable: 'haml-lint'
104+
install_command: 'gem install haml-lint'
89105
include: '**/*.haml'
90106

91107
HardTabs:
@@ -105,10 +121,14 @@ PreCommit:
105121

106122
Jscs:
107123
description: 'Analyzing with JSCS'
124+
required_executable: 'jscs'
125+
install_command: 'npm install -g jscs'
108126
include: '**/*.js'
109127

110128
JsHint:
111129
description: 'Analyzing with JSHint'
130+
required_executable: 'jshint'
131+
install_command: 'npm install -g jshint'
112132
include: '**/*.js'
113133

114134
JsonSyntax:
@@ -117,6 +137,8 @@ PreCommit:
117137

118138
JsxHint:
119139
description: 'Analyzing with JSXHint'
140+
required_executable: 'jsxhint'
141+
install_command: 'npm install -g jsxhint'
120142
include: '**/*.jsx'
121143

122144
LocalPathsInGemfile:
@@ -134,6 +156,8 @@ PreCommit:
134156

135157
PythonFlake8:
136158
description: 'Analyzing with flake8'
159+
required_executable: 'flake8'
160+
install_command: 'pip install flake8'
137161
include: '**/*.py'
138162

139163
RailsSchemaUpToDate:
@@ -145,6 +169,8 @@ PreCommit:
145169

146170
Rubocop:
147171
description: 'Analyzing with Rubocop'
172+
required_executable: 'rubocop'
173+
install_command: 'gem install rubocop'
148174
include:
149175
- '**/*.gemspec'
150176
- '**/*.rake'
@@ -154,6 +180,8 @@ PreCommit:
154180

155181
ScssLint:
156182
description: 'Analyzing with scss-lint'
183+
required_executable: 'scss-lint'
184+
install_command: 'gem install scss-lint'
157185
include: '**/*.scss'
158186

159187
TrailingWhitespace:
@@ -163,6 +191,8 @@ PreCommit:
163191

164192
TravisLint:
165193
description: 'Checking Travis CI configuration'
194+
required_executable: 'travis-lint'
195+
install_command: 'gem install travis-lint'
166196
include: '.travis.yml'
167197

168198
YamlSyntax:

lib/overcommit/hook/pre_commit/berksfile_check.rb

+1-5
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,11 @@ class BerksfileCheck < Base
55
LOCK_FILE = 'Berksfile.lock'
66

77
def run
8-
unless in_path?('berks')
9-
return :warn, 'Berkshelf not installed -- run `gem install berkshelf`'
10-
end
11-
128
# Ignore if Berksfile.lock is not tracked by git
139
ignored_files = execute(%w[git ls-files -o -i --exclude-standard]).stdout.split("\n")
1410
return :pass if ignored_files.include?(LOCK_FILE)
1511

16-
result = execute(%w[berks list --quiet])
12+
result = execute(%W[#{executable} list --quiet])
1713
unless result.success?
1814
return :fail, result.stderr
1915
end

lib/overcommit/hook/pre_commit/brakeman.rb

+1-5
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,7 @@ module Overcommit::Hook::PreCommit
22
# Runs `brakeman` against any modified Ruby/Rails files.
33
class Brakeman < Base
44
def run
5-
unless in_path?('brakeman')
6-
return :warn, 'Run `gem install brakeman`'
7-
end
8-
9-
result = execute(%w[brakeman --exit-on-warn --quiet --summary --only-files] +
5+
result = execute(%W[#{executable} --exit-on-warn --quiet --summary --only-files] +
106
applicable_files)
117
return :pass if result.success?
128

lib/overcommit/hook/pre_commit/bundle_check.rb

+2-6
Original file line numberDiff line numberDiff line change
@@ -5,22 +5,18 @@ class BundleCheck < Base
55
LOCK_FILE = 'Gemfile.lock'
66

77
def run
8-
unless in_path?('bundle')
9-
return :warn, 'bundler not installed -- run `gem install bundler`'
10-
end
11-
128
# Ignore if Gemfile.lock is not tracked by git
139
ignored_files = execute(%w[git ls-files -o -i --exclude-standard]).stdout.split("\n")
1410
return :pass if ignored_files.include?(LOCK_FILE)
1511

16-
result = execute(%w[bundle check])
12+
result = execute(%W[#{executable} check])
1713
unless result.success?
1814
return :fail, result.stdout
1915
end
2016

2117
result = execute(%w[git diff --quiet --] + [LOCK_FILE])
2218
unless result.success?
23-
return :fail, "#{LOCK_FILE} is not up-to-date -- run `bundle check`"
19+
return :fail, "#{LOCK_FILE} is not up-to-date -- run `#{executable} check`"
2420
end
2521

2622
:pass

lib/overcommit/hook/pre_commit/chamber_security.rb

+1-5
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,7 @@ module Overcommit::Hook::PreCommit
22
# Runs `chamber secure` against any modified Chamber settings files
33
class ChamberSecurity < Base
44
def run
5-
unless in_path?('chamber')
6-
return :warn, 'Run `gem install chamber`'
7-
end
8-
9-
result = execute(%w[chamber secure --echo --files] + applicable_files)
5+
result = execute(%W[#{executable} secure --echo --files] + applicable_files)
106

117
return :pass if result.stdout.empty?
128
[:fail, "These settings appear to need to be secured but were not: #{result.stdout}"]

lib/overcommit/hook/pre_commit/coffee_lint.rb

+1-5
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,7 @@ module Overcommit::Hook::PreCommit
22
# Runs `coffeelint` against any modified CoffeeScript files.
33
class CoffeeLint < Base
44
def run
5-
unless in_path?('coffeelint')
6-
return :warn, 'Run `npm install -g coffeelint`'
7-
end
8-
9-
result = execute(%w[coffeelint --quiet] + applicable_files)
5+
result = execute(%W[#{executable} --quiet] + applicable_files)
106
return :pass if result.success?
117

128
[:fail, result.stdout]

lib/overcommit/hook/pre_commit/css_lint.rb

+1-5
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,7 @@ module Overcommit::Hook::PreCommit
22
# Runs `csslint` against any modified CSS files.
33
class CssLint < Base
44
def run
5-
unless in_path?('csslint')
6-
return :warn, 'csslint not installed -- run `npm install -g csslint`'
7-
end
8-
9-
result = execute(%w[csslint --quiet --format=compact] + applicable_files)
5+
result = execute(%W[#{executable} --quiet --format=compact] + applicable_files)
106
return :pass if result.stdout !~ /Error - (?!Unknown @ rule)/
117

128
[:fail, result.stdout]

lib/overcommit/hook/pre_commit/go_lint.rb

+1-5
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,7 @@ module Overcommit::Hook::PreCommit
22
# Runs `golint` against any modified Golang files.
33
class GoLint < Base
44
def run
5-
unless in_path?('golint')
6-
return :warn, 'Run `go get `github.com/golang/lint/golint`'
7-
end
8-
9-
result = execute(%w[golint] + applicable_files)
5+
result = execute([executable] + applicable_files)
106
# Unfortunately the exit code is always 0
117
return :pass if result.stdout.empty?
128

lib/overcommit/hook/pre_commit/haml_lint.rb

+1-5
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,7 @@ module Overcommit::Hook::PreCommit
22
# Runs `haml-lint` against any modified HAML files.
33
class HamlLint < Base
44
def run
5-
unless in_path?('haml-lint')
6-
return :warn, 'haml-lint not installed -- run `gem install haml-lint`'
7-
end
8-
9-
result = execute(%w[haml-lint] + applicable_files)
5+
result = execute([executable] + applicable_files)
106
return :pass if result.success?
117

128
# Keep lines from the output for files that we actually modified

lib/overcommit/hook/pre_commit/js_hint.rb

+1-5
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,7 @@ module Overcommit::Hook::PreCommit
22
# Runs `jshint` against any modified JavaScript files.
33
class JsHint < Base
44
def run
5-
unless in_path?('jshint')
6-
return :warn, 'jshint not installed -- run `npm install -g jshint`'
7-
end
8-
9-
result = execute(%w[jshint] + applicable_files)
5+
result = execute([executable] + applicable_files)
106
output = result.stdout
117

128
return :pass if output.empty?

lib/overcommit/hook/pre_commit/jscs.rb

+1-5
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,7 @@ module Overcommit::Hook::PreCommit
33
# files.
44
class Jscs < Base
55
def run
6-
unless in_path?('jscs')
7-
return :warn, 'jscs not installed -- run `npm install -g jscs`'
8-
end
9-
10-
result = execute(%w[jscs --reporter=inline] + applicable_files)
6+
result = execute(%W[#{executable} --reporter=inline] + applicable_files)
117
return :pass if result.success?
128

139
if result.status == 1

lib/overcommit/hook/pre_commit/jsx_hint.rb

+1-5
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,7 @@ module Overcommit::Hook::PreCommit
22
# Runs `jsxhint` against any modified JSX files.
33
class JsxHint < Base
44
def run
5-
unless in_path?('jsxhint')
6-
return :warn, 'jsxhint not installed -- run `npm install -g jsxhint`'
7-
end
8-
9-
result = execute(%w[jsxhint] + applicable_files)
5+
result = execute([executable] + applicable_files)
106
output = result.stdout
117

128
return :pass if output.empty?

lib/overcommit/hook/pre_commit/python_flake8.rb

+1-5
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,7 @@ module Overcommit::Hook::PreCommit
22
# Runs `flake8` against any modified Python files.
33
class PythonFlake8 < Base
44
def run
5-
unless in_path?('flake8')
6-
return :warn, 'flake8 not installed -- run `pip install flake8`'
7-
end
8-
9-
result = execute(%w[flake8] + applicable_files)
5+
result = execute([executable] + applicable_files)
106
return :pass if result.success?
117

128
[:fail, result.stdout]

lib/overcommit/hook/pre_commit/rubocop.rb

+1-5
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,7 @@ module Overcommit::Hook::PreCommit
22
# Runs `rubocop` against any modified Ruby files.
33
class Rubocop < Base
44
def run
5-
unless in_path?('rubocop')
6-
return :warn, 'Rubocop not installed -- run `gem install rubocop`'
7-
end
8-
9-
result = execute(%w[rubocop --format=emacs --force-exclusion] + applicable_files)
5+
result = execute(%W[#{executable} --format=emacs --force-exclusion] + applicable_files)
106
return :pass if result.success?
117

128
output = result.stdout + result.stderr

lib/overcommit/hook/pre_commit/scss_lint.rb

+1-5
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,7 @@ module Overcommit::Hook::PreCommit
22
# Runs `scss-lint` against any modified SCSS files.
33
class ScssLint < Base
44
def run
5-
unless in_path?('scss-lint')
6-
return :warn, 'scss-lint not installed -- run `gem install scss-lint`'
7-
end
8-
9-
result = execute(%w[scss-lint] + applicable_files)
5+
result = execute([executable] + applicable_files)
106
return :pass if result.success?
117

128
# Keep lines from the output for files that we actually modified

lib/overcommit/hook/pre_commit/travis_lint.rb

+1-5
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,7 @@ module Overcommit::Hook::PreCommit
22
# Runs `travis-lint` against any modified Travis CI files.
33
class TravisLint < Base
44
def run
5-
unless in_path?('travis-lint')
6-
return :warn, 'Run `gem install travis-lint`'
7-
end
8-
9-
result = execute(%w[travis-lint] + applicable_files)
5+
result = execute([executable] + applicable_files)
106
return :pass if result.success?
117

128
[:fail, result.stdout.strip]

0 commit comments

Comments
 (0)