overcommit 0.17.0 → 0.18.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/bin/overcommit +1 -3
- data/config/default.yml +38 -2
- data/lib/overcommit/cli.rb +37 -2
- data/lib/overcommit/configuration.rb +79 -15
- data/lib/overcommit/configuration_loader.rb +1 -1
- data/lib/overcommit/configuration_validator.rb +1 -1
- data/lib/overcommit/git_repo.rb +3 -3
- data/lib/overcommit/hook/base.rb +30 -2
- data/lib/overcommit/hook/post_checkout/index_tags.rb +1 -1
- data/lib/overcommit/hook/pre_commit/berksfile_check.rb +1 -5
- data/lib/overcommit/hook/pre_commit/brakeman.rb +1 -5
- data/lib/overcommit/hook/pre_commit/broken_symlinks.rb +15 -0
- data/lib/overcommit/hook/pre_commit/bundle_check.rb +2 -6
- data/lib/overcommit/hook/pre_commit/chamber_security.rb +1 -5
- data/lib/overcommit/hook/pre_commit/coffee_lint.rb +1 -5
- data/lib/overcommit/hook/pre_commit/css_lint.rb +1 -5
- data/lib/overcommit/hook/pre_commit/go_lint.rb +1 -5
- data/lib/overcommit/hook/pre_commit/haml_lint.rb +1 -5
- data/lib/overcommit/hook/pre_commit/image_optim.rb +2 -2
- data/lib/overcommit/hook/pre_commit/js_hint.rb +1 -5
- data/lib/overcommit/hook/pre_commit/jscs.rb +1 -5
- data/lib/overcommit/hook/pre_commit/jsx_hint.rb +1 -5
- data/lib/overcommit/hook/pre_commit/python_flake8.rb +1 -5
- data/lib/overcommit/hook/pre_commit/rails_schema_up_to_date.rb +2 -2
- data/lib/overcommit/hook/pre_commit/rubocop.rb +1 -5
- data/lib/overcommit/hook/pre_commit/scss_lint.rb +1 -5
- data/lib/overcommit/hook/pre_commit/travis_lint.rb +1 -5
- data/lib/overcommit/hook_context/commit_msg.rb +1 -1
- data/lib/overcommit/hook_context/pre_commit.rb +3 -1
- data/lib/overcommit/hook_loader/base.rb +1 -1
- data/lib/overcommit/hook_loader/plugin_hook_loader.rb +3 -3
- data/lib/overcommit/hook_runner.rb +1 -1
- data/lib/overcommit/hook_signer.rb +1 -1
- data/lib/overcommit/installer.rb +1 -1
- data/lib/overcommit/logger.rb +16 -15
- data/lib/overcommit/printer.rb +1 -1
- data/lib/overcommit/user_input.rb +1 -1
- data/lib/overcommit/utils.rb +10 -1
- data/lib/overcommit/version.rb +1 -1
- metadata +7 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b609412f41e430a857ae1b1b9b5a3d31cf97eb9b
|
4
|
+
data.tar.gz: 1f3ebdf4981de86e51503d69fdc7ed851cb91aca
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 46b3a66583a3522bbec747ba4a0a579839b5fe09ea77ac62b57149b52e7413b05388fbd1db399d953d2503ff590331f6d8bf789191f45983027aea6dd11bcbb2
|
7
|
+
data.tar.gz: 072a5ce0c265bc2da606332369a5e2ea53e77f4f4aec07b3f94f056fb2e8644358737192ff6c495a4e5fda27fd5fa9b3e5625ad58f916a562056195895e88d26
|
data/bin/overcommit
CHANGED
data/config/default.yml
CHANGED
@@ -22,8 +22,8 @@ PostCheckout:
|
|
22
22
|
required: false
|
23
23
|
quiet: false
|
24
24
|
IndexTags:
|
25
|
-
description: 'Generating tags file from source'
|
26
25
|
enabled: false
|
26
|
+
description: 'Generating tags file from source'
|
27
27
|
|
28
28
|
# Hooks that are run after `git commit` is executed, before the commit message
|
29
29
|
# editor is displayed. These hooks are ideal for syntax checkers, linters, and
|
@@ -50,6 +50,8 @@ PreCommit:
|
|
50
50
|
|
51
51
|
BerksfileCheck:
|
52
52
|
description: 'Checking Berksfile lock'
|
53
|
+
required_executable: 'berks'
|
54
|
+
install_command: 'gem install berks'
|
53
55
|
include:
|
54
56
|
- 'Berksfile'
|
55
57
|
- 'Berksfile.lock'
|
@@ -57,11 +59,19 @@ PreCommit:
|
|
57
59
|
Brakeman:
|
58
60
|
enabled: false
|
59
61
|
description: 'Checking for security vulnerabilities'
|
62
|
+
required_executable: 'brakeman'
|
63
|
+
install_command: 'gem install brakeman'
|
60
64
|
include:
|
61
65
|
- '**/*.rb'
|
62
66
|
|
67
|
+
BrokenSymlinks:
|
68
|
+
description: 'Checking for broken symlinks'
|
69
|
+
quiet: true
|
70
|
+
|
63
71
|
BundleCheck:
|
64
72
|
description: 'Checking Gemfile dependencies'
|
73
|
+
required_executable: 'bundle'
|
74
|
+
install_command: 'gem install bundler'
|
65
75
|
include:
|
66
76
|
- 'Gemfile'
|
67
77
|
- 'Gemfile.lock'
|
@@ -70,22 +80,34 @@ PreCommit:
|
|
70
80
|
ChamberSecurity:
|
71
81
|
enabled: false
|
72
82
|
description: 'Checking that settings have been secured with Chamber'
|
73
|
-
|
83
|
+
required_executable: 'chamber'
|
84
|
+
install_command: 'gem install chamber'
|
85
|
+
include:
|
86
|
+
- 'config/settings.yml'
|
87
|
+
- 'config/settings/**/*.yml'
|
74
88
|
|
75
89
|
CoffeeLint:
|
76
90
|
description: 'Analyzing with coffeelint'
|
91
|
+
required_executable: 'coffeelint'
|
92
|
+
install_command: 'npm install -g coffeelint'
|
77
93
|
include: '**/*.coffee'
|
78
94
|
|
79
95
|
CssLint:
|
80
96
|
description: 'Analyzing with csslint'
|
97
|
+
required_executable: 'csslint'
|
98
|
+
install_command: 'npm install -g csslint'
|
81
99
|
include: '**/*.css'
|
82
100
|
|
83
101
|
GoLint:
|
84
102
|
description: 'Analyzing with golint'
|
103
|
+
required_executable: 'golint'
|
104
|
+
install_command: 'go get github.com/golang/lint/golint'
|
85
105
|
include: '**/*.go'
|
86
106
|
|
87
107
|
HamlLint:
|
88
108
|
description: 'Analyzing with haml-lint'
|
109
|
+
required_executable: 'haml-lint'
|
110
|
+
install_command: 'gem install haml-lint'
|
89
111
|
include: '**/*.haml'
|
90
112
|
|
91
113
|
HardTabs:
|
@@ -105,10 +127,14 @@ PreCommit:
|
|
105
127
|
|
106
128
|
Jscs:
|
107
129
|
description: 'Analyzing with JSCS'
|
130
|
+
required_executable: 'jscs'
|
131
|
+
install_command: 'npm install -g jscs'
|
108
132
|
include: '**/*.js'
|
109
133
|
|
110
134
|
JsHint:
|
111
135
|
description: 'Analyzing with JSHint'
|
136
|
+
required_executable: 'jshint'
|
137
|
+
install_command: 'npm install -g jshint'
|
112
138
|
include: '**/*.js'
|
113
139
|
|
114
140
|
JsonSyntax:
|
@@ -117,6 +143,8 @@ PreCommit:
|
|
117
143
|
|
118
144
|
JsxHint:
|
119
145
|
description: 'Analyzing with JSXHint'
|
146
|
+
required_executable: 'jsxhint'
|
147
|
+
install_command: 'npm install -g jsxhint'
|
120
148
|
include: '**/*.jsx'
|
121
149
|
|
122
150
|
LocalPathsInGemfile:
|
@@ -134,6 +162,8 @@ PreCommit:
|
|
134
162
|
|
135
163
|
PythonFlake8:
|
136
164
|
description: 'Analyzing with flake8'
|
165
|
+
required_executable: 'flake8'
|
166
|
+
install_command: 'pip install flake8'
|
137
167
|
include: '**/*.py'
|
138
168
|
|
139
169
|
RailsSchemaUpToDate:
|
@@ -145,6 +175,8 @@ PreCommit:
|
|
145
175
|
|
146
176
|
Rubocop:
|
147
177
|
description: 'Analyzing with Rubocop'
|
178
|
+
required_executable: 'rubocop'
|
179
|
+
install_command: 'gem install rubocop'
|
148
180
|
include:
|
149
181
|
- '**/*.gemspec'
|
150
182
|
- '**/*.rake'
|
@@ -154,6 +186,8 @@ PreCommit:
|
|
154
186
|
|
155
187
|
ScssLint:
|
156
188
|
description: 'Analyzing with scss-lint'
|
189
|
+
required_executable: 'scss-lint'
|
190
|
+
install_command: 'gem install scss-lint'
|
157
191
|
include: '**/*.scss'
|
158
192
|
|
159
193
|
TrailingWhitespace:
|
@@ -163,6 +197,8 @@ PreCommit:
|
|
163
197
|
|
164
198
|
TravisLint:
|
165
199
|
description: 'Checking Travis CI configuration'
|
200
|
+
required_executable: 'travis-lint'
|
201
|
+
install_command: 'gem install travis-lint'
|
166
202
|
include: '.travis.yml'
|
167
203
|
|
168
204
|
YamlSyntax:
|
data/lib/overcommit/cli.rb
CHANGED
@@ -3,7 +3,7 @@ require 'optparse'
|
|
3
3
|
module Overcommit
|
4
4
|
# Responsible for parsing command-line options and executing appropriate
|
5
5
|
# application logic based on those options.
|
6
|
-
class CLI
|
6
|
+
class CLI # rubocop:disable ClassLength
|
7
7
|
def initialize(arguments, logger)
|
8
8
|
@arguments = arguments
|
9
9
|
@log = logger
|
@@ -21,7 +21,7 @@ module Overcommit
|
|
21
21
|
end
|
22
22
|
end
|
23
23
|
|
24
|
-
|
24
|
+
private
|
25
25
|
|
26
26
|
attr_reader :log
|
27
27
|
|
@@ -59,6 +59,10 @@ module Overcommit
|
|
59
59
|
opts.on_tail('-v', '--version', 'Show version') do
|
60
60
|
print_version(opts.program_name)
|
61
61
|
end
|
62
|
+
|
63
|
+
opts.on_tail('-l', '--list-hooks', 'List installed hooks') do
|
64
|
+
print_installed_hooks
|
65
|
+
end
|
62
66
|
end
|
63
67
|
|
64
68
|
def add_installation_options(opts)
|
@@ -122,6 +126,37 @@ module Overcommit
|
|
122
126
|
halt
|
123
127
|
end
|
124
128
|
|
129
|
+
# Prints the hooks available in the current repo and whether they're
|
130
|
+
# enabled/disabled.
|
131
|
+
def print_installed_hooks
|
132
|
+
config = Overcommit::ConfigurationLoader.load_repo_config
|
133
|
+
|
134
|
+
config.all_hook_configs.each do |hook_type, hook_configs|
|
135
|
+
print_hooks_for_hook_type(config, hook_configs, hook_type)
|
136
|
+
end
|
137
|
+
|
138
|
+
halt
|
139
|
+
end
|
140
|
+
|
141
|
+
def print_hooks_for_hook_type(repo_config, hook_configs, hook_type)
|
142
|
+
log.log "#{hook_type}:"
|
143
|
+
hook_configs.each do |hook_name, config|
|
144
|
+
log.partial " #{hook_name}: "
|
145
|
+
|
146
|
+
if config['enabled']
|
147
|
+
log.success('enabled', true)
|
148
|
+
else
|
149
|
+
log.error('disabled', true)
|
150
|
+
end
|
151
|
+
|
152
|
+
if repo_config.plugin_hook?(hook_type, hook_name)
|
153
|
+
log.warning(' (plugin)')
|
154
|
+
else
|
155
|
+
log.log
|
156
|
+
end
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
125
160
|
# Used for ease of stubbing in tests
|
126
161
|
def halt(status = 0)
|
127
162
|
exit status
|
@@ -1,6 +1,6 @@
|
|
1
1
|
module Overcommit
|
2
2
|
# Stores configuration for Overcommit and the hooks it runs.
|
3
|
-
class Configuration
|
3
|
+
class Configuration # rubocop:disable ClassLength
|
4
4
|
# Creates a configuration from the given hash.
|
5
5
|
def initialize(hash)
|
6
6
|
@hash = ConfigurationValidator.new.validate(hash)
|
@@ -21,6 +21,58 @@ module Overcommit
|
|
21
21
|
@hash['verify_plugin_signatures'] != false
|
22
22
|
end
|
23
23
|
|
24
|
+
# Returns configuration for all hooks in each hook type.
|
25
|
+
#
|
26
|
+
# @return [Hash]
|
27
|
+
def all_hook_configs
|
28
|
+
smart_merge(all_builtin_hook_configs, all_plugin_hook_configs)
|
29
|
+
end
|
30
|
+
|
31
|
+
# Returns configuration for all built-in hooks in each hook type.
|
32
|
+
#
|
33
|
+
# @return [Hash]
|
34
|
+
def all_builtin_hook_configs
|
35
|
+
hook_configs = {}
|
36
|
+
|
37
|
+
Overcommit::Utils.supported_hook_type_classes.each do |hook_type|
|
38
|
+
hook_names = @hash[hook_type].keys.reject { |name| name == 'ALL' }
|
39
|
+
|
40
|
+
hook_configs[hook_type] = Hash[
|
41
|
+
hook_names.map do |hook_name|
|
42
|
+
[hook_name, for_hook(hook_name, hook_type)]
|
43
|
+
end
|
44
|
+
]
|
45
|
+
end
|
46
|
+
|
47
|
+
hook_configs
|
48
|
+
end
|
49
|
+
|
50
|
+
# Returns configuration for all plugin hooks in each hook type.
|
51
|
+
#
|
52
|
+
# @return [Hash]
|
53
|
+
def all_plugin_hook_configs
|
54
|
+
hook_configs = {}
|
55
|
+
|
56
|
+
Overcommit::Utils.supported_hook_types.each do |hook_type|
|
57
|
+
hook_type_class_name = Overcommit::Utils.camel_case(hook_type)
|
58
|
+
|
59
|
+
directory = File.join(plugin_directory, hook_type.gsub('-', '_'))
|
60
|
+
plugin_paths = Dir[File.join(directory, '*.rb')].sort
|
61
|
+
|
62
|
+
hook_names = plugin_paths.map do |path|
|
63
|
+
Overcommit::Utils.camel_case(File.basename(path, '.rb'))
|
64
|
+
end
|
65
|
+
|
66
|
+
hook_configs[hook_type_class_name] = Hash[
|
67
|
+
hook_names.map do |hook_name|
|
68
|
+
[hook_name, for_hook(hook_name, Overcommit::Utils.camel_case(hook_type))]
|
69
|
+
end
|
70
|
+
]
|
71
|
+
end
|
72
|
+
|
73
|
+
hook_configs
|
74
|
+
end
|
75
|
+
|
24
76
|
# Returns the built-in hooks that have been enabled for a hook type.
|
25
77
|
def enabled_builtin_hooks(hook_context)
|
26
78
|
@hash[hook_context.hook_class_name].keys.
|
@@ -38,7 +90,13 @@ module Overcommit
|
|
38
90
|
end
|
39
91
|
|
40
92
|
# Merge hook configuration with special 'ALL' config
|
41
|
-
smart_merge(@hash[hook_type]['ALL'], @hash[hook_type][hook] || {})
|
93
|
+
hook_config = smart_merge(@hash[hook_type]['ALL'], @hash[hook_type][hook] || {})
|
94
|
+
|
95
|
+
# Need to specially handle `enabled` option since not setting it does not
|
96
|
+
# necessarily mean the hook is disabled
|
97
|
+
hook_config['enabled'] = hook_enabled?(hook_type, hook)
|
98
|
+
|
99
|
+
hook_config.freeze
|
42
100
|
end
|
43
101
|
|
44
102
|
# Merges the given configuration with this one, returning a new
|
@@ -66,11 +124,23 @@ module Overcommit
|
|
66
124
|
end
|
67
125
|
end
|
68
126
|
|
69
|
-
|
127
|
+
def plugin_hook?(hook_context_or_type, hook_name)
|
128
|
+
hook_type_name =
|
129
|
+
if hook_context_or_type.is_a?(String)
|
130
|
+
Overcommit::Utils.snake_case(hook_context_or_type)
|
131
|
+
else
|
132
|
+
hook_context_or_type.hook_type_name
|
133
|
+
end
|
134
|
+
hook_name = Overcommit::Utils.snake_case(hook_name)
|
135
|
+
|
136
|
+
File.exist?(File.join(plugin_directory, hook_type_name, "#{hook_name}.rb"))
|
137
|
+
end
|
138
|
+
|
139
|
+
protected
|
70
140
|
|
71
141
|
attr_reader :hash
|
72
142
|
|
73
|
-
|
143
|
+
private
|
74
144
|
|
75
145
|
def built_in_hook?(hook_context, hook_name)
|
76
146
|
hook_name = Overcommit::Utils.snake_case(hook_name)
|
@@ -79,22 +149,16 @@ module Overcommit
|
|
79
149
|
hook_context.hook_type_name, "#{hook_name}.rb"))
|
80
150
|
end
|
81
151
|
|
82
|
-
def plugin_hook?(hook_context, hook_name)
|
83
|
-
hook_name = Overcommit::Utils.snake_case(hook_name)
|
84
|
-
|
85
|
-
File.exist?(File.join(plugin_directory,
|
86
|
-
hook_context.hook_type_name,
|
87
|
-
"#{hook_name}.rb"))
|
88
|
-
end
|
89
|
-
|
90
152
|
def hook_exists?(hook_context, hook_name)
|
91
153
|
built_in_hook?(hook_context, hook_name) ||
|
92
154
|
plugin_hook?(hook_context, hook_name)
|
93
155
|
end
|
94
156
|
|
95
|
-
def hook_enabled?(
|
96
|
-
hook_type =
|
97
|
-
|
157
|
+
def hook_enabled?(hook_context_or_type, hook_name)
|
158
|
+
hook_type = hook_context_or_type.is_a?(String) ? hook_context_or_type :
|
159
|
+
hook_context_or_type.hook_class_name
|
160
|
+
|
161
|
+
individual_enabled = @hash[hook_type].fetch(hook_name, {})['enabled']
|
98
162
|
return individual_enabled unless individual_enabled.nil?
|
99
163
|
|
100
164
|
all_enabled = @hash[hook_type]['ALL']['enabled']
|
data/lib/overcommit/git_repo.rb
CHANGED
@@ -66,10 +66,10 @@ module Overcommit
|
|
66
66
|
# conflict. This is necessary since stashing removes the merge state.
|
67
67
|
if merge_head != 'MERGE_HEAD'
|
68
68
|
@merge_head = merge_head
|
69
|
-
|
70
|
-
merge_msg_file = File.expand_path('.git/MERGE_MSG', Overcommit::Utils.repo_root)
|
71
|
-
@merge_msg = File.open(merge_msg_file).read if File.exist?(merge_msg_file)
|
72
69
|
end
|
70
|
+
|
71
|
+
merge_msg_file = File.expand_path('.git/MERGE_MSG', Overcommit::Utils.repo_root)
|
72
|
+
@merge_msg = File.open(merge_msg_file).read if File.exist?(merge_msg_file)
|
73
73
|
end
|
74
74
|
|
75
75
|
# Store any relevant files that are present when repo is in the middle of a
|
data/lib/overcommit/hook/base.rb
CHANGED
@@ -8,6 +8,8 @@ module Overcommit::Hook
|
|
8
8
|
def_delegators :@context, :modified_files
|
9
9
|
attr_reader :config
|
10
10
|
|
11
|
+
# @param config [Overcommit::Configuration]
|
12
|
+
# @param context [Overcommit::HookContext]
|
11
13
|
def initialize(config, context)
|
12
14
|
@config = config.for_hook(self)
|
13
15
|
@context = context
|
@@ -25,7 +27,11 @@ module Overcommit::Hook
|
|
25
27
|
# implement `#run`, and we needed a wrapper step to transform the status
|
26
28
|
# based on any custom configuration.
|
27
29
|
def run_and_transform
|
28
|
-
|
30
|
+
if output = check_for_executable
|
31
|
+
status = :fail
|
32
|
+
else
|
33
|
+
status, output = run
|
34
|
+
end
|
29
35
|
|
30
36
|
[transform_status(status), output]
|
31
37
|
end
|
@@ -68,13 +74,21 @@ module Overcommit::Hook
|
|
68
74
|
Overcommit::Utils.execute(cmd)
|
69
75
|
end
|
70
76
|
|
77
|
+
def executable
|
78
|
+
@config['required_executable']
|
79
|
+
end
|
80
|
+
|
81
|
+
def install_command
|
82
|
+
@config['install_command']
|
83
|
+
end
|
84
|
+
|
71
85
|
# Gets a list of staged files that apply to this hook based on its
|
72
86
|
# configured `include` and `exclude` lists.
|
73
87
|
def applicable_files
|
74
88
|
@applicable_files ||= modified_files.select { |file| applicable_file?(file) }
|
75
89
|
end
|
76
90
|
|
77
|
-
|
91
|
+
private
|
78
92
|
|
79
93
|
def requires_modified_files?
|
80
94
|
@config['requires_files']
|
@@ -107,6 +121,20 @@ module Overcommit::Hook
|
|
107
121
|
)
|
108
122
|
end
|
109
123
|
|
124
|
+
# If the hook defines a required executable, check if it's in the path and
|
125
|
+
# display the install command if one exists.
|
126
|
+
def check_for_executable
|
127
|
+
return unless executable && !in_path?(executable)
|
128
|
+
|
129
|
+
output = "'#{executable}' is not installed (or is not in your PATH)"
|
130
|
+
|
131
|
+
if install_command
|
132
|
+
output += "\nInstall it by running: #{install_command}"
|
133
|
+
end
|
134
|
+
|
135
|
+
output
|
136
|
+
end
|
137
|
+
|
110
138
|
# Transforms the hook's status based on custom configuration.
|
111
139
|
#
|
112
140
|
# This allows users to change failures into warnings, or vice versa.
|
@@ -5,15 +5,11 @@ module Overcommit::Hook::PreCommit
|
|
5
5
|
LOCK_FILE = 'Berksfile.lock'
|
6
6
|
|
7
7
|
def run
|
8
|
-
unless in_path?('berks')
|
9
|
-
return :warn, 'Berkshelf not installed -- run `gem install berkshelf`'
|
10
|
-
end
|
11
|
-
|
12
8
|
# Ignore if Berksfile.lock is not tracked by git
|
13
9
|
ignored_files = execute(%w[git ls-files -o -i --exclude-standard]).stdout.split("\n")
|
14
10
|
return :pass if ignored_files.include?(LOCK_FILE)
|
15
11
|
|
16
|
-
result = execute(%
|
12
|
+
result = execute(%W[#{executable} list --quiet])
|
17
13
|
unless result.success?
|
18
14
|
return :fail, result.stderr
|
19
15
|
end
|
@@ -2,11 +2,7 @@ module Overcommit::Hook::PreCommit
|
|
2
2
|
# Runs `brakeman` against any modified Ruby/Rails files.
|
3
3
|
class Brakeman < Base
|
4
4
|
def run
|
5
|
-
|
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] +
|
10
6
|
applicable_files)
|
11
7
|
return :pass if result.success?
|
12
8
|
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module Overcommit::Hook::PreCommit
|
2
|
+
# Checks for broken symlinks.
|
3
|
+
class BrokenSymlinks < Base
|
4
|
+
def run
|
5
|
+
broken_symlinks = applicable_files.
|
6
|
+
select { |file| Overcommit::Utils.broken_symlink?(file) }
|
7
|
+
|
8
|
+
if broken_symlinks.any?
|
9
|
+
return :fail, "Broken symlinks detected:\n#{broken_symlinks.join("\n")}"
|
10
|
+
end
|
11
|
+
|
12
|
+
:pass
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -5,22 +5,18 @@ module Overcommit::Hook::PreCommit
|
|
5
5
|
LOCK_FILE = 'Gemfile.lock'
|
6
6
|
|
7
7
|
def run
|
8
|
-
unless in_path?('bundle')
|
9
|
-
return :warn, 'bundler not installed -- run `gem install bundler`'
|
10
|
-
end
|
11
|
-
|
12
8
|
# Ignore if Gemfile.lock is not tracked by git
|
13
9
|
ignored_files = execute(%w[git ls-files -o -i --exclude-standard]).stdout.split("\n")
|
14
10
|
return :pass if ignored_files.include?(LOCK_FILE)
|
15
11
|
|
16
|
-
result = execute(%
|
12
|
+
result = execute(%W[#{executable} check])
|
17
13
|
unless result.success?
|
18
14
|
return :fail, result.stdout
|
19
15
|
end
|
20
16
|
|
21
17
|
result = execute(%w[git diff --quiet --] + [LOCK_FILE])
|
22
18
|
unless result.success?
|
23
|
-
return :fail, "#{LOCK_FILE} is not up-to-date -- run
|
19
|
+
return :fail, "#{LOCK_FILE} is not up-to-date -- run `#{executable} check`"
|
24
20
|
end
|
25
21
|
|
26
22
|
:pass
|
@@ -2,11 +2,7 @@ module Overcommit::Hook::PreCommit
|
|
2
2
|
# Runs `chamber secure` against any modified Chamber settings files
|
3
3
|
class ChamberSecurity < Base
|
4
4
|
def run
|
5
|
-
|
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 --files] + applicable_files)
|
10
6
|
|
11
7
|
return :pass if result.stdout.empty?
|
12
8
|
[:fail, "These settings appear to need to be secured but were not: #{result.stdout}"]
|
@@ -2,11 +2,7 @@ module Overcommit::Hook::PreCommit
|
|
2
2
|
# Runs `coffeelint` against any modified CoffeeScript files.
|
3
3
|
class CoffeeLint < Base
|
4
4
|
def run
|
5
|
-
|
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)
|
10
6
|
return :pass if result.success?
|
11
7
|
|
12
8
|
[:fail, result.stdout]
|
@@ -2,11 +2,7 @@ module Overcommit::Hook::PreCommit
|
|
2
2
|
# Runs `csslint` against any modified CSS files.
|
3
3
|
class CssLint < Base
|
4
4
|
def run
|
5
|
-
|
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)
|
10
6
|
return :pass if result.stdout !~ /Error - (?!Unknown @ rule)/
|
11
7
|
|
12
8
|
[:fail, result.stdout]
|
@@ -2,11 +2,7 @@ module Overcommit::Hook::PreCommit
|
|
2
2
|
# Runs `golint` against any modified Golang files.
|
3
3
|
class GoLint < Base
|
4
4
|
def run
|
5
|
-
|
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)
|
10
6
|
# Unfortunately the exit code is always 0
|
11
7
|
return :pass if result.stdout.empty?
|
12
8
|
|
@@ -2,11 +2,7 @@ module Overcommit::Hook::PreCommit
|
|
2
2
|
# Runs `haml-lint` against any modified HAML files.
|
3
3
|
class HamlLint < Base
|
4
4
|
def run
|
5
|
-
|
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)
|
10
6
|
return :pass if result.success?
|
11
7
|
|
12
8
|
# Keep lines from the output for files that we actually modified
|
@@ -11,7 +11,7 @@ module Overcommit::Hook::PreCommit
|
|
11
11
|
optimized_images =
|
12
12
|
begin
|
13
13
|
optimize_images(applicable_files)
|
14
|
-
rescue ::ImageOptim::
|
14
|
+
rescue ::ImageOptim::BinResolver::BinNotFound => e
|
15
15
|
return :fail, "#{e.message}. The image_optim gem is dependendent on this binary."
|
16
16
|
end
|
17
17
|
|
@@ -25,7 +25,7 @@ module Overcommit::Hook::PreCommit
|
|
25
25
|
:pass
|
26
26
|
end
|
27
27
|
|
28
|
-
|
28
|
+
private
|
29
29
|
|
30
30
|
def optimize_images(image_paths)
|
31
31
|
image_optim = ::ImageOptim.new(:pngout => false)
|
@@ -2,11 +2,7 @@ module Overcommit::Hook::PreCommit
|
|
2
2
|
# Runs `jshint` against any modified JavaScript files.
|
3
3
|
class JsHint < Base
|
4
4
|
def run
|
5
|
-
|
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)
|
10
6
|
output = result.stdout
|
11
7
|
|
12
8
|
return :pass if output.empty?
|
@@ -3,11 +3,7 @@ module Overcommit::Hook::PreCommit
|
|
3
3
|
# files.
|
4
4
|
class Jscs < Base
|
5
5
|
def run
|
6
|
-
|
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)
|
11
7
|
return :pass if result.success?
|
12
8
|
|
13
9
|
if result.status == 1
|
@@ -2,11 +2,7 @@ module Overcommit::Hook::PreCommit
|
|
2
2
|
# Runs `jsxhint` against any modified JSX files.
|
3
3
|
class JsxHint < Base
|
4
4
|
def run
|
5
|
-
|
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)
|
10
6
|
output = result.stdout
|
11
7
|
|
12
8
|
return :pass if output.empty?
|
@@ -2,11 +2,7 @@ module Overcommit::Hook::PreCommit
|
|
2
2
|
# Runs `flake8` against any modified Python files.
|
3
3
|
class PythonFlake8 < Base
|
4
4
|
def run
|
5
|
-
|
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)
|
10
6
|
return :pass if result.success?
|
11
7
|
|
12
8
|
[:fail, result.stdout]
|
@@ -1,7 +1,7 @@
|
|
1
1
|
module Overcommit::Hook::PreCommit
|
2
2
|
# Check to see whether the schema file is in line with the migrations
|
3
3
|
class RailsSchemaUpToDate < Base
|
4
|
-
def run # rubocop:disable CyclomaticComplexity
|
4
|
+
def run # rubocop:disable CyclomaticComplexity, PerceivedComplexity
|
5
5
|
if migration_files.any? && schema_files.none?
|
6
6
|
return :fail, "It looks like you're adding a migration, but did not update the schema file"
|
7
7
|
elsif migration_files.none? && schema_files.any?
|
@@ -28,7 +28,7 @@ module Overcommit::Hook::PreCommit
|
|
28
28
|
:pass
|
29
29
|
end
|
30
30
|
|
31
|
-
|
31
|
+
private
|
32
32
|
|
33
33
|
def migration_files
|
34
34
|
@migration_files ||= applicable_files.select do |file|
|
@@ -2,11 +2,7 @@ module Overcommit::Hook::PreCommit
|
|
2
2
|
# Runs `rubocop` against any modified Ruby files.
|
3
3
|
class Rubocop < Base
|
4
4
|
def run
|
5
|
-
|
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)
|
10
6
|
return :pass if result.success?
|
11
7
|
|
12
8
|
output = result.stdout + result.stderr
|
@@ -2,11 +2,7 @@ module Overcommit::Hook::PreCommit
|
|
2
2
|
# Runs `scss-lint` against any modified SCSS files.
|
3
3
|
class ScssLint < Base
|
4
4
|
def run
|
5
|
-
|
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)
|
10
6
|
return :pass if result.success?
|
11
7
|
|
12
8
|
# Keep lines from the output for files that we actually modified
|
@@ -2,11 +2,7 @@ module Overcommit::Hook::PreCommit
|
|
2
2
|
# Runs `travis-lint` against any modified Travis CI files.
|
3
3
|
class TravisLint < Base
|
4
4
|
def run
|
5
|
-
|
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)
|
10
6
|
return :pass if result.success?
|
11
7
|
|
12
8
|
[:fail, result.stdout.strip]
|
@@ -67,7 +67,7 @@ module Overcommit::HookContext
|
|
67
67
|
@modified_lines[file] ||= Overcommit::GitRepo.extract_modified_lines(file, :staged => true)
|
68
68
|
end
|
69
69
|
|
70
|
-
|
70
|
+
private
|
71
71
|
|
72
72
|
# Clears the working tree so that the stash can be applied.
|
73
73
|
def clear_working_tree
|
@@ -114,6 +114,7 @@ module Overcommit::HookContext
|
|
114
114
|
@modified_times = {}
|
115
115
|
|
116
116
|
modified_files.each do |file|
|
117
|
+
next if Overcommit::Utils.broken_symlink?(file)
|
117
118
|
@modified_times[file] = File.mtime(file)
|
118
119
|
end
|
119
120
|
end
|
@@ -122,6 +123,7 @@ module Overcommit::HookContext
|
|
122
123
|
# appear like they never changed.
|
123
124
|
def restore_modified_times
|
124
125
|
modified_files.each do |file|
|
126
|
+
next if Overcommit::Utils.broken_symlink?(file)
|
125
127
|
time = @modified_times[file]
|
126
128
|
File.utime(time, time, file)
|
127
129
|
end
|
@@ -18,12 +18,12 @@ module Overcommit::HookLoader
|
|
18
18
|
end
|
19
19
|
end
|
20
20
|
|
21
|
-
|
21
|
+
private
|
22
22
|
|
23
23
|
def check_for_modified_plugins(plugin_paths)
|
24
24
|
modified_plugins = plugin_paths.
|
25
25
|
map { |path| Overcommit::HookSigner.new(path, @config, @context) }.
|
26
|
-
select
|
26
|
+
select(&:signature_changed?)
|
27
27
|
|
28
28
|
return if modified_plugins.empty?
|
29
29
|
|
@@ -45,7 +45,7 @@ module Overcommit::HookLoader
|
|
45
45
|
raise Overcommit::Exceptions::HookCancelled
|
46
46
|
end
|
47
47
|
|
48
|
-
modified_plugins.each
|
48
|
+
modified_plugins.each(&:update_signature!)
|
49
49
|
end
|
50
50
|
end
|
51
51
|
end
|
data/lib/overcommit/installer.rb
CHANGED
data/lib/overcommit/logger.rb
CHANGED
@@ -18,34 +18,35 @@ module Overcommit
|
|
18
18
|
@out.puts(*args)
|
19
19
|
end
|
20
20
|
|
21
|
-
def bold(
|
22
|
-
color('1',
|
21
|
+
def bold(*args)
|
22
|
+
color('1', *args)
|
23
23
|
end
|
24
24
|
|
25
|
-
def error(
|
26
|
-
color(31,
|
25
|
+
def error(*args)
|
26
|
+
color(31, *args)
|
27
27
|
end
|
28
28
|
|
29
|
-
def bold_error(
|
30
|
-
color('1;31',
|
29
|
+
def bold_error(*args)
|
30
|
+
color('1;31', *args)
|
31
31
|
end
|
32
32
|
|
33
|
-
def success(
|
34
|
-
color(32,
|
33
|
+
def success(*args)
|
34
|
+
color(32, *args)
|
35
35
|
end
|
36
36
|
|
37
|
-
def warning(
|
38
|
-
color(33,
|
37
|
+
def warning(*args)
|
38
|
+
color(33, *args)
|
39
39
|
end
|
40
40
|
|
41
|
-
def bold_warning(
|
42
|
-
color('1;33',
|
41
|
+
def bold_warning(*args)
|
42
|
+
color('1;33', *args)
|
43
43
|
end
|
44
44
|
|
45
|
-
|
45
|
+
private
|
46
46
|
|
47
|
-
def color(code, str)
|
48
|
-
|
47
|
+
def color(code, str, partial = false)
|
48
|
+
send(partial ? :partial : :log,
|
49
|
+
@out.tty? ? "\033[#{code}m#{str}\033[0m" : str)
|
49
50
|
end
|
50
51
|
end
|
51
52
|
end
|
data/lib/overcommit/printer.rb
CHANGED
data/lib/overcommit/utils.rb
CHANGED
@@ -42,7 +42,7 @@ module Overcommit
|
|
42
42
|
# Returns a list of supported hook classes (PreCommit, CommitMsg, etc.)
|
43
43
|
def supported_hook_type_classes
|
44
44
|
supported_hook_types.map do |file|
|
45
|
-
file.split('-').map
|
45
|
+
file.split('-').map(&:capitalize).join
|
46
46
|
end
|
47
47
|
end
|
48
48
|
|
@@ -86,6 +86,15 @@ module Overcommit
|
|
86
86
|
ensure
|
87
87
|
old_env.each { |var, value| ENV[var.to_s] = value }
|
88
88
|
end
|
89
|
+
|
90
|
+
# Returns whether a file is a broken symlink.
|
91
|
+
#
|
92
|
+
# @return [true,false]
|
93
|
+
def broken_symlink?(file)
|
94
|
+
# JRuby's implementation of File.exist? returns true for broken
|
95
|
+
# symlinks, so we need use File.size?
|
96
|
+
File.symlink?(file) && File.size?(file).nil?
|
97
|
+
end
|
89
98
|
end
|
90
99
|
end
|
91
100
|
end
|
data/lib/overcommit/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: overcommit
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.18.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Causes Engineering
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2014-09-
|
12
|
+
date: 2014-09-21 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: childprocess
|
@@ -31,14 +31,14 @@ dependencies:
|
|
31
31
|
requirements:
|
32
32
|
- - ~>
|
33
33
|
- !ruby/object:Gem::Version
|
34
|
-
version: 0.
|
34
|
+
version: 0.15.0
|
35
35
|
type: :development
|
36
36
|
prerelease: false
|
37
37
|
version_requirements: !ruby/object:Gem::Requirement
|
38
38
|
requirements:
|
39
39
|
- - ~>
|
40
40
|
- !ruby/object:Gem::Version
|
41
|
-
version: 0.
|
41
|
+
version: 0.15.0
|
42
42
|
- !ruby/object:Gem::Dependency
|
43
43
|
name: rspec
|
44
44
|
requirement: !ruby/object:Gem::Requirement
|
@@ -59,14 +59,14 @@ dependencies:
|
|
59
59
|
requirements:
|
60
60
|
- - '='
|
61
61
|
- !ruby/object:Gem::Version
|
62
|
-
version: 0.
|
62
|
+
version: 0.26.0
|
63
63
|
type: :development
|
64
64
|
prerelease: false
|
65
65
|
version_requirements: !ruby/object:Gem::Requirement
|
66
66
|
requirements:
|
67
67
|
- - '='
|
68
68
|
- !ruby/object:Gem::Version
|
69
|
-
version: 0.
|
69
|
+
version: 0.26.0
|
70
70
|
description: Utility to install, configure, and extend Git hooks
|
71
71
|
email:
|
72
72
|
- eng@causes.com
|
@@ -123,6 +123,7 @@ files:
|
|
123
123
|
- lib/overcommit/hook/pre_commit/jscs.rb
|
124
124
|
- lib/overcommit/hook/pre_commit/scss_lint.rb
|
125
125
|
- lib/overcommit/hook/pre_commit/base.rb
|
126
|
+
- lib/overcommit/hook/pre_commit/broken_symlinks.rb
|
126
127
|
- lib/overcommit/hook/pre_commit/json_syntax.rb
|
127
128
|
- lib/overcommit/hook_signer.rb
|
128
129
|
- lib/overcommit/git_repo.rb
|