Skip to content

Commit ac366b1

Browse files
committed
Add command config option to hooks
One feature Overcommit is missing is the ability to execute a command within a particular environment (e.g. `bundle exec` in Ruby or `virtualenv` in Python). In order to support this, add a `command` option which can be configured in `.overcommit.yml`, and update all existing hooks to respect this option. If not specified, it defaults to the required executable for the hook. Change-Id: Id705739021139babf963ba11a47691acb74e4804 Reviewed-on: http://gerrit.causes.com/46312 Tested-by: jenkins <jenkins@brigade.com> Reviewed-by: Shane da Silva <shane.dasilva@brigade.com>
1 parent b468590 commit ac366b1

22 files changed

+47
-23
lines changed

.overcommit.yml

+6
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,9 @@ CommitMsg:
55
PreCommit:
66
Reek:
77
enabled: false
8+
9+
Rubocop:
10+
command: ['bundle', 'exec', 'rubocop']
11+
12+
Travis:
13+
command: ['bundle', 'exec', 'travis']

CHANGELOG.md

+2
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44

55
* Disable `Reek` pre-commit hook by default
66
* Allow `required_executable` to include paths that are in the repo root
7+
* Add `command` hook option allowing the actual command that is executed
8+
to be configured (useful to invoke command via `bundle exec` or similar)
79

810
## 0.21.0
911

README.md

+5
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,11 @@ Within a configuration file, the following high-level concepts exist:
189189
a warning to either `pass` or `fail`
190190
* `required_executable`: Name of an executable that needs to exist in order
191191
for the hook to run
192+
* `command`: Array of command line arguments to use as the command. How each
193+
hook uses this is different, but it ultimately allows hooks to customize
194+
how they are run so they can be invoked in a different context, for example
195+
running `bundle exec rubocop` instead of just `rubocop` so you can use gem
196+
versions specified in your local `Gemfile.lock`
192197
* `install_command`: Command the user can run to install the
193198
`required_executable`
194199

lib/overcommit/hook/base.rb

+13-3
Original file line numberDiff line numberDiff line change
@@ -111,10 +111,20 @@ def execute(cmd)
111111
Overcommit::Utils.execute(cmd)
112112
end
113113

114-
def executable
114+
def required_executable
115115
@config['required_executable']
116116
end
117117

118+
# Return command to execute for this hook.
119+
#
120+
# This is intended to be configurable so hooks can prefix their commands
121+
# with `bundle exec` or similar.
122+
#
123+
# @return [Array<String>]
124+
def command
125+
Array(@config['command'] || required_executable)
126+
end
127+
118128
# Gets a list of staged files that apply to this hook based on its
119129
# configured `include` and `exclude` lists.
120130
def applicable_files
@@ -146,9 +156,9 @@ def applicable_file?(file)
146156
# If the hook defines a required executable, check if it's in the path and
147157
# display the install command if one exists.
148158
def check_for_executable
149-
return unless executable && !in_path?(executable)
159+
return unless required_executable && !in_path?(required_executable)
150160

151-
output = "'#{executable}' is not installed (or is not in your PATH)"
161+
output = "'#{required_executable}' is not installed (or is not in your PATH)"
152162

153163
if install_command = @config['install_command']
154164
output += "\nInstall it by running: #{install_command}"

lib/overcommit/hook/pre_commit/berksfile_check.rb

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ def run
99
ignored_files = execute(%w[git ls-files -o -i --exclude-standard]).stdout.split("\n")
1010
return :pass if ignored_files.include?(LOCK_FILE)
1111

12-
result = execute(%W[#{executable} list --quiet])
12+
result = execute(command + %w[list --quiet])
1313
unless result.success?
1414
return :fail, result.stderr
1515
end

lib/overcommit/hook/pre_commit/brakeman.rb

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

910
[:fail, result.stdout]

lib/overcommit/hook/pre_commit/bundle_check.rb

+2-2
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,14 @@ def run
99
ignored_files = execute(%w[git ls-files -o -i --exclude-standard]).stdout.split("\n")
1010
return :pass if ignored_files.include?(LOCK_FILE)
1111

12-
result = execute(%W[#{executable} check])
12+
result = execute(command + ['check'])
1313
unless result.success?
1414
return :fail, result.stdout
1515
end
1616

1717
result = execute(%w[git diff --quiet --] + [LOCK_FILE])
1818
unless result.success?
19-
return :fail, "#{LOCK_FILE} is not up-to-date -- run `#{executable} check`"
19+
return :fail, "#{LOCK_FILE} is not up-to-date -- run `#{command.join(' ')} check`"
2020
end
2121

2222
:pass

lib/overcommit/hook/pre_commit/chamber_security.rb

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ module Overcommit::Hook::PreCommit
22
# Runs `chamber secure` against any modified Chamber settings files
33
class ChamberSecurity < Base
44
def run
5-
result = execute(%W[#{executable} secure --files] + applicable_files)
5+
result = execute(command + %w[secure --files] + applicable_files)
66

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

lib/overcommit/hook/pre_commit/coffee_lint.rb

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ module Overcommit::Hook::PreCommit
22
# Runs `coffeelint` against any modified CoffeeScript files.
33
class CoffeeLint < Base
44
def run
5-
result = execute(%W[#{executable} --quiet] + applicable_files)
5+
result = execute(command + %w[--quiet] + applicable_files)
66
return :pass if result.success?
77

88
[:fail, result.stdout]

lib/overcommit/hook/pre_commit/css_lint.rb

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ module Overcommit::Hook::PreCommit
22
# Runs `csslint` against any modified CSS files.
33
class CssLint < Base
44
def run
5-
result = execute(%W[#{executable} --quiet --format=compact] + applicable_files)
5+
result = execute(command + %w[--quiet --format=compact] + applicable_files)
66
return :pass if result.stdout !~ /Error - (?!Unknown @ rule)/
77

88
[:fail, result.stdout]

lib/overcommit/hook/pre_commit/go_lint.rb

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ module Overcommit::Hook::PreCommit
22
# Runs `golint` against any modified Golang files.
33
class GoLint < Base
44
def run
5-
result = execute([executable] + applicable_files)
5+
result = execute(command + applicable_files)
66
# Unfortunately the exit code is always 0
77
return :pass if result.stdout.empty?
88

lib/overcommit/hook/pre_commit/haml_lint.rb

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ class HamlLint < Base
66
end
77

88
def run
9-
result = execute([executable] + applicable_files)
9+
result = execute(command + applicable_files)
1010
return :pass if result.success?
1111

1212
extract_messages(

lib/overcommit/hook/pre_commit/js_hint.rb

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ module Overcommit::Hook::PreCommit
22
# Runs `jshint` against any modified JavaScript files.
33
class JsHint < Base
44
def run
5-
result = execute([executable] + applicable_files)
5+
result = execute(command + applicable_files)
66
output = result.stdout
77

88
return :pass if output.empty?

lib/overcommit/hook/pre_commit/jscs.rb

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ module Overcommit::Hook::PreCommit
33
# files.
44
class Jscs < Base
55
def run
6-
result = execute(%W[#{executable} --reporter=inline --verbose] + applicable_files)
6+
result = execute(command + %w[--reporter=inline --verbose] + applicable_files)
77
return :pass if result.success?
88

99
if result.status == 1

lib/overcommit/hook/pre_commit/jsx_hint.rb

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ module Overcommit::Hook::PreCommit
22
# Runs `jsxhint` against any modified JSX files.
33
class JsxHint < Base
44
def run
5-
result = execute([executable] + applicable_files)
5+
result = execute(command + applicable_files)
66
output = result.stdout
77

88
return :pass if output.empty?

lib/overcommit/hook/pre_commit/jsxcs.rb

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ module Overcommit::Hook::PreCommit
33
# against any modified JavaScript files.
44
class Jsxcs < Base
55
def run
6-
result = execute(%W[#{executable} --reporter=inline] + applicable_files)
6+
result = execute(command + %w[--reporter=inline] + applicable_files)
77
return :pass if result.success?
88

99
if result.status == 1

lib/overcommit/hook/pre_commit/python_flake8.rb

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ module Overcommit::Hook::PreCommit
22
# Runs `flake8` against any modified Python files.
33
class PythonFlake8 < Base
44
def run
5-
result = execute([executable] + applicable_files)
5+
result = execute(command + applicable_files)
66
return :pass if result.success?
77

88
[:fail, result.stdout]

lib/overcommit/hook/pre_commit/reek.rb

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ module Overcommit::Hook::PreCommit
22
# Runs `reek` against any modified Ruby files.
33
class Reek < Base
44
def run
5-
result = execute(%W[#{executable} --single-line --no-color] + applicable_files)
5+
result = execute(command + %w[--single-line --no-color] + applicable_files)
66
return :pass if result.success?
77

88
output = scrub_output(result.stdout + result.stderr)

lib/overcommit/hook/pre_commit/rubocop.rb

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ class Rubocop < Base
66
end
77

88
def run
9-
result = execute(%W[#{executable} --format=emacs --force-exclusion] + applicable_files)
9+
result = execute(command + %w[--format=emacs --force-exclusion] + applicable_files)
1010
return :pass if result.success?
1111

1212
extract_messages(

lib/overcommit/hook/pre_commit/scss_lint.rb

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ class ScssLint < Base
66
end
77

88
def run
9-
result = execute([executable] + applicable_files)
9+
result = execute(command + applicable_files)
1010
return :pass if result.success?
1111

1212
extract_messages(

lib/overcommit/hook/pre_commit/shell_check.rb

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ class ShellCheck < Base
66
end
77

88
def run
9-
result = execute(%W[#{executable} --format=gcc] + applicable_files)
9+
result = execute(command + %w[--format=gcc] + applicable_files)
1010
return :pass if result.success?
1111

1212
extract_messages(

lib/overcommit/hook/pre_commit/travis_lint.rb

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ module Overcommit::Hook::PreCommit
22
# Runs `travis-lint` against any modified Travis CI files.
33
class TravisLint < Base
44
def run
5-
result = execute([executable, 'lint'] + applicable_files)
5+
result = execute(command + %w[lint] + applicable_files)
66
return :pass if result.success?
77

88
[:fail, (result.stdout + result.stderr).strip]

0 commit comments

Comments
 (0)