overcommit 0.17.0 → 0.18.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|