overcommit 0.5.0 → 0.6.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 +3 -4
- data/config/default.yml +139 -0
- data/lib/overcommit.rb +7 -5
- data/lib/overcommit/cli.rb +59 -64
- data/lib/overcommit/configuration.rb +108 -34
- data/lib/overcommit/configuration_loader.rb +47 -0
- data/lib/overcommit/constants.rb +7 -0
- data/lib/overcommit/exceptions.rb +16 -0
- data/lib/overcommit/hook/base.rb +91 -0
- data/lib/overcommit/hook/commit_msg/base.rb +11 -0
- data/lib/overcommit/hook/commit_msg/gerrit_change_id.rb +18 -0
- data/lib/overcommit/{plugins → hook}/commit_msg/hard_tabs.rb +5 -6
- data/lib/overcommit/hook/commit_msg/russian_novel.rb +14 -0
- data/lib/overcommit/hook/commit_msg/single_line_subject.rb +12 -0
- data/lib/overcommit/hook/commit_msg/text_width.rb +20 -0
- data/lib/overcommit/hook/commit_msg/trailing_period.rb +12 -0
- data/lib/overcommit/hook/post_checkout/base.rb +11 -0
- data/lib/overcommit/hook/post_checkout/bundle_check.rb +29 -0
- data/lib/overcommit/hook/post_checkout/index_tags.rb +24 -0
- data/lib/overcommit/hook/pre_commit/author_email.rb +17 -0
- data/lib/overcommit/hook/pre_commit/author_name.rb +17 -0
- data/lib/overcommit/hook/pre_commit/base.rb +10 -0
- data/lib/overcommit/hook/pre_commit/bundle_check.rb +30 -0
- data/lib/overcommit/hook/pre_commit/coffee_lint.rb +14 -0
- data/lib/overcommit/hook/pre_commit/css_lint.rb +16 -0
- data/lib/overcommit/hook/pre_commit/haml_lint.rb +26 -0
- data/lib/overcommit/hook/pre_commit/hard_tabs.rb +16 -0
- data/lib/overcommit/hook/pre_commit/image_optim.rb +41 -0
- data/lib/overcommit/hook/pre_commit/js_hint.rb +15 -0
- data/lib/overcommit/hook/pre_commit/jscs.rb +31 -0
- data/lib/overcommit/hook/pre_commit/python_flake8.rb +14 -0
- data/lib/overcommit/hook/pre_commit/rubocop.rb +26 -0
- data/lib/overcommit/hook/pre_commit/scss_lint.rb +26 -0
- data/lib/overcommit/hook/pre_commit/trailing_whitespace.rb +15 -0
- data/lib/overcommit/hook/pre_commit/yaml_syntax.rb +22 -0
- data/lib/overcommit/hook_context.rb +16 -0
- data/lib/overcommit/hook_context/base.rb +68 -0
- data/lib/overcommit/hook_context/commit_msg.rb +32 -0
- data/lib/overcommit/hook_context/post_checkout.rb +24 -0
- data/lib/overcommit/hook_context/pre_commit.rb +96 -0
- data/lib/overcommit/hook_runner.rb +150 -0
- data/lib/overcommit/installer.rb +61 -68
- data/lib/overcommit/logger.rb +16 -13
- data/lib/overcommit/utils.rb +63 -38
- data/lib/overcommit/version.rb +1 -1
- data/{bin/scripts → libexec}/gerrit-change-id +0 -0
- data/{bin/scripts → libexec}/index-tags +1 -3
- data/template-dir/hooks/commit-msg +83 -0
- data/template-dir/hooks/overcommit-hook +83 -0
- data/template-dir/hooks/post-checkout +83 -0
- data/template-dir/hooks/pre-commit +83 -0
- metadata +76 -57
- data/bin/hooks/commit-msg +0 -8
- data/bin/hooks/post-checkout +0 -9
- data/bin/hooks/post-merge +0 -23
- data/bin/hooks/pre-commit +0 -8
- data/bin/hooks/prepare-commit-msg +0 -159
- data/bin/run-hook +0 -8
- data/bin/scripts/check-gemfile +0 -9
- data/bin/scripts/csslint-rhino.js +0 -9080
- data/bin/scripts/jshint.js +0 -5921
- data/bin/scripts/jshint_runner.js +0 -42
- data/lib/overcommit/errors.rb +0 -3
- data/lib/overcommit/git_hook.rb +0 -89
- data/lib/overcommit/hook_specific_check.rb +0 -110
- data/lib/overcommit/hooks/commit_msg.rb +0 -7
- data/lib/overcommit/hooks/pre_commit.rb +0 -9
- data/lib/overcommit/plugins/commit_msg/change_id.rb +0 -15
- data/lib/overcommit/plugins/commit_msg/release_note.rb +0 -25
- data/lib/overcommit/plugins/commit_msg/russian_novel.rb +0 -16
- data/lib/overcommit/plugins/commit_msg/single_line_subject.rb +0 -13
- data/lib/overcommit/plugins/commit_msg/text_width.rb +0 -20
- data/lib/overcommit/plugins/commit_msg/trailing_period.rb +0 -13
- data/lib/overcommit/plugins/pre_commit/author_name.rb +0 -16
- data/lib/overcommit/plugins/pre_commit/causes_email.rb +0 -15
- data/lib/overcommit/plugins/pre_commit/coffee_lint.rb +0 -16
- data/lib/overcommit/plugins/pre_commit/css_linter.rb +0 -17
- data/lib/overcommit/plugins/pre_commit/haml_style.rb +0 -34
- data/lib/overcommit/plugins/pre_commit/haml_syntax.rb +0 -24
- data/lib/overcommit/plugins/pre_commit/image_optimization.rb +0 -50
- data/lib/overcommit/plugins/pre_commit/js_console_log.rb +0 -16
- data/lib/overcommit/plugins/pre_commit/js_syntax.rb +0 -30
- data/lib/overcommit/plugins/pre_commit/python_flake8.rb +0 -15
- data/lib/overcommit/plugins/pre_commit/ruby_style.rb +0 -67
- data/lib/overcommit/plugins/pre_commit/ruby_syntax.rb +0 -19
- data/lib/overcommit/plugins/pre_commit/scss_lint.rb +0 -66
- data/lib/overcommit/plugins/pre_commit/test_history.rb +0 -58
- data/lib/overcommit/plugins/pre_commit/whitespace.rb +0 -21
- data/lib/overcommit/plugins/pre_commit/yaml_syntax.rb +0 -22
- data/lib/overcommit/reporter.rb +0 -90
- data/lib/overcommit/staged_file.rb +0 -86
@@ -0,0 +1,150 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module Overcommit
|
4
|
+
# Responsible for loading the hooks the repository has configured and running
|
5
|
+
# them, collecting and displaying the results.
|
6
|
+
class HookRunner
|
7
|
+
def initialize(config, logger, context)
|
8
|
+
@config = config
|
9
|
+
@log = logger
|
10
|
+
@context = context
|
11
|
+
@hooks = []
|
12
|
+
end
|
13
|
+
|
14
|
+
# Loads and runs the hooks registered for this {HookRunner}.
|
15
|
+
def run
|
16
|
+
load_hooks
|
17
|
+
@context.setup_environment
|
18
|
+
run_hooks
|
19
|
+
ensure
|
20
|
+
@context.cleanup_environment
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
attr_reader :log
|
26
|
+
|
27
|
+
def run_hooks
|
28
|
+
if @hooks.any? { |hook| hook.run? || hook.skip? }
|
29
|
+
log.bold "Running #{@context.hook_script_name} hooks"
|
30
|
+
|
31
|
+
statuses = @hooks.map { |hook| run_hook(hook) }.compact
|
32
|
+
|
33
|
+
log.log # Newline
|
34
|
+
|
35
|
+
run_failed = statuses.include?(:bad)
|
36
|
+
|
37
|
+
if run_failed
|
38
|
+
log.error "✗ One or more #{@context.hook_script_name} hooks failed"
|
39
|
+
else
|
40
|
+
log.success "✓ All #{@context.hook_script_name} hooks passed"
|
41
|
+
end
|
42
|
+
|
43
|
+
log.log # Newline
|
44
|
+
|
45
|
+
!run_failed
|
46
|
+
else
|
47
|
+
log.success "✓ No applicable #{@context.hook_script_name} hooks to run"
|
48
|
+
true # Run was successful
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def run_hook(hook)
|
53
|
+
return unless hook.enabled?
|
54
|
+
|
55
|
+
if hook.skip?
|
56
|
+
if hook.required?
|
57
|
+
log.warning "Cannot skip #{hook.name} since it is required"
|
58
|
+
else
|
59
|
+
log.warning "Skipping #{hook.name}"
|
60
|
+
return
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
return unless hook.run?
|
65
|
+
|
66
|
+
unless hook.quiet?
|
67
|
+
print_header(hook)
|
68
|
+
end
|
69
|
+
|
70
|
+
begin
|
71
|
+
status, output = hook.run
|
72
|
+
rescue => ex
|
73
|
+
status = :bad
|
74
|
+
output = "Hook raised unexpected error\n#{ex.message}"
|
75
|
+
end
|
76
|
+
|
77
|
+
# Want to print the header in the event the result wasn't good so that the
|
78
|
+
# user knows what failed
|
79
|
+
if hook.quiet? && status != :good
|
80
|
+
print_header(hook)
|
81
|
+
end
|
82
|
+
|
83
|
+
case status
|
84
|
+
when :good
|
85
|
+
log.success 'OK' unless hook.quiet?
|
86
|
+
when :warn
|
87
|
+
log.warning 'WARNING'
|
88
|
+
print_report(output, :bold_warning)
|
89
|
+
when :bad
|
90
|
+
log.error 'FAILED'
|
91
|
+
print_report(output, :bold_error)
|
92
|
+
end
|
93
|
+
|
94
|
+
status
|
95
|
+
end
|
96
|
+
|
97
|
+
def print_header(hook)
|
98
|
+
log.partial hook.description
|
99
|
+
log.partial '.' * (70 - hook.description.length)
|
100
|
+
end
|
101
|
+
|
102
|
+
def print_report(output, format = :log)
|
103
|
+
log.send(format, output) unless output.empty?
|
104
|
+
end
|
105
|
+
|
106
|
+
# Loads hooks that will be run.
|
107
|
+
# This is done explicitly so that we only load hooks which will actually be
|
108
|
+
# used.
|
109
|
+
def load_hooks
|
110
|
+
require "overcommit/hook/#{@context.hook_type_name}/base"
|
111
|
+
|
112
|
+
load_builtin_hooks
|
113
|
+
load_hook_plugins # Load after so they can subclass/modify existing hooks
|
114
|
+
end
|
115
|
+
|
116
|
+
# Load hooks that ship with Overcommit, ignoring ones that are excluded from
|
117
|
+
# the repository's configuration.
|
118
|
+
def load_builtin_hooks
|
119
|
+
@config.enabled_builtin_hooks(@context.hook_class_name).each do |hook_name|
|
120
|
+
underscored_hook_name = Overcommit::Utils.snake_case(hook_name)
|
121
|
+
require "overcommit/hook/#{@context.hook_type_name}/#{underscored_hook_name}"
|
122
|
+
@hooks << create_hook(hook_name)
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
# Load hooks that are stored in the repository's plugin directory.
|
127
|
+
def load_hook_plugins
|
128
|
+
directory = File.join(@config.plugin_directory, @context.hook_type_name)
|
129
|
+
|
130
|
+
Dir[File.join(directory, '*.rb')].sort.each do |plugin|
|
131
|
+
require plugin
|
132
|
+
|
133
|
+
hook_name = Overcommit::Utils.camel_case(File.basename(plugin, '.rb'))
|
134
|
+
@hooks << create_hook(hook_name)
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
# Load and return a {Hook} from a CamelCase hook name and the given
|
139
|
+
# hook configuration.
|
140
|
+
def create_hook(hook_name)
|
141
|
+
Overcommit::Hook.const_get(@context.hook_class_name).
|
142
|
+
const_get(hook_name).
|
143
|
+
new(@config, @context)
|
144
|
+
rescue LoadError, NameError => error
|
145
|
+
raise Overcommit::Exceptions::HookLoadError,
|
146
|
+
"Unable to load hook '#{hook_name}': #{error}",
|
147
|
+
error.backtrace
|
148
|
+
end
|
149
|
+
end
|
150
|
+
end
|
data/lib/overcommit/installer.rb
CHANGED
@@ -1,113 +1,106 @@
|
|
1
1
|
require 'fileutils'
|
2
|
-
require 'yaml'
|
3
2
|
|
4
3
|
module Overcommit
|
4
|
+
# Manages the installation of Overcommit hooks in a git repository.
|
5
5
|
class Installer
|
6
|
-
def initialize(
|
7
|
-
@
|
8
|
-
@target = target
|
6
|
+
def initialize(logger)
|
7
|
+
@log = logger
|
9
8
|
end
|
10
9
|
|
11
|
-
def run
|
10
|
+
def run(target, options)
|
11
|
+
@target = target
|
12
|
+
@options = options
|
12
13
|
validate_target
|
13
|
-
@options[:
|
14
|
+
@options[:action] == :uninstall ? uninstall : install
|
14
15
|
end
|
15
16
|
|
17
|
+
private
|
18
|
+
|
19
|
+
attr_reader :log
|
20
|
+
|
16
21
|
def install
|
17
22
|
log.log "Installing hooks into #{@target}"
|
18
23
|
|
19
|
-
|
20
|
-
|
21
|
-
|
24
|
+
ensure_hooks_directory
|
25
|
+
install_master_hook
|
26
|
+
install_hook_symlinks
|
27
|
+
|
28
|
+
log.success "Successfully installed hooks into #{@target}"
|
22
29
|
end
|
23
30
|
|
24
31
|
def uninstall
|
25
32
|
log.log "Removing hooks from #{@target}"
|
26
33
|
|
27
|
-
|
28
|
-
|
29
|
-
rm_configuration
|
30
|
-
end
|
34
|
+
uninstall_master_hook
|
35
|
+
uninstall_hook_symlinks
|
31
36
|
|
32
|
-
|
37
|
+
log.success "Successfully removed hooks from #{@target}"
|
38
|
+
end
|
33
39
|
|
34
|
-
def
|
35
|
-
|
40
|
+
def hooks_path
|
41
|
+
absolute_target = File.expand_path(@target)
|
42
|
+
File.join(absolute_target, '.git', 'hooks')
|
36
43
|
end
|
37
44
|
|
38
|
-
def
|
39
|
-
|
40
|
-
File.join(absolute_target, '.git/hooks')
|
45
|
+
def ensure_hooks_directory
|
46
|
+
FileUtils.mkdir_p(hooks_path)
|
41
47
|
end
|
42
48
|
|
43
49
|
def validate_target
|
44
|
-
absolute_target = File.expand_path
|
45
|
-
|
46
|
-
|
50
|
+
absolute_target = File.expand_path(@target)
|
51
|
+
|
52
|
+
unless File.directory?(absolute_target)
|
53
|
+
raise Overcommit::Exceptions::InvalidGitRepo, 'is not a directory'
|
47
54
|
end
|
48
55
|
|
49
56
|
unless File.directory?(File.join(absolute_target, '.git'))
|
50
|
-
raise
|
57
|
+
raise Overcommit::Exceptions::InvalidGitRepo, 'does not appear to be a git repository'
|
51
58
|
end
|
52
59
|
end
|
53
60
|
|
54
|
-
|
55
|
-
|
56
|
-
|
61
|
+
def install_master_hook
|
62
|
+
master_hook = File.join(OVERCOMMIT_HOME, 'template-dir', 'hooks', 'overcommit-hook')
|
63
|
+
install_location = File.join(hooks_path, 'overcommit-hook')
|
64
|
+
FileUtils.mkdir_p(hooks_path)
|
65
|
+
FileUtils.cp(master_hook, install_location)
|
57
66
|
end
|
58
67
|
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
FileUtils.cp hook, File.join(hook_path, File.basename(hook))
|
63
|
-
end
|
68
|
+
def uninstall_master_hook
|
69
|
+
install_location = File.join(hooks_path, 'overcommit-hook')
|
70
|
+
FileUtils.rm_rf(install_location)
|
64
71
|
end
|
65
72
|
|
66
|
-
def
|
67
|
-
|
68
|
-
|
73
|
+
def install_hook_symlinks
|
74
|
+
# Link each hook type (pre-commit, commit-msg, etc.) to the master hook.
|
75
|
+
# We change directories so that the relative symlink paths work regardless
|
76
|
+
# of where the repository is located.
|
77
|
+
Dir.chdir(hooks_path) do
|
78
|
+
Overcommit::Utils.supported_hook_types.each do |hook_type|
|
79
|
+
unless can_replace_file?(hook_type)
|
80
|
+
raise Overcommit::Exceptions::PreExistingHooks,
|
81
|
+
"Hook '#{File.expand_path(hook_type)}' already exists and was not installed by Overcommit"
|
82
|
+
end
|
83
|
+
FileUtils.ln_sf('overcommit-hook', hook_type)
|
84
|
+
end
|
69
85
|
end
|
70
86
|
end
|
71
87
|
|
72
|
-
def
|
73
|
-
|
74
|
-
|
88
|
+
def can_replace_file?(file)
|
89
|
+
@options[:force] ||
|
90
|
+
!File.exists?(file) ||
|
91
|
+
overcommit_symlink?(file)
|
75
92
|
end
|
76
93
|
|
77
|
-
def
|
78
|
-
Dir
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
def write_configuration
|
83
|
-
template = @options.fetch(:template, 'default')
|
84
|
-
base_config = Overcommit.config.templates[template]
|
85
|
-
if base_config.nil?
|
86
|
-
raise ArgumentError, "No such template '#{template}'"
|
87
|
-
end
|
88
|
-
|
89
|
-
base_config = base_config.dup
|
90
|
-
(base_config['excludes'] ||= {}).
|
91
|
-
merge!(@options[:excludes] || {}) do |_, a, b|
|
92
|
-
# Concat the arrays together
|
93
|
-
a + b
|
94
|
-
end
|
95
|
-
|
96
|
-
File.open(configuration_location, 'w') do |config|
|
97
|
-
YAML.dump(base_config, config)
|
94
|
+
def uninstall_hook_symlinks
|
95
|
+
Dir.chdir(hooks_path) do
|
96
|
+
Overcommit::Utils.supported_hook_types.each do |hook_type|
|
97
|
+
FileUtils.rm_rf(hook_type) if overcommit_symlink?(hook_type)
|
98
|
+
end
|
98
99
|
end
|
99
100
|
end
|
100
101
|
|
101
|
-
def
|
102
|
-
|
103
|
-
end
|
104
|
-
|
105
|
-
def configuration_location
|
106
|
-
File.join(hook_path, 'overcommit.yml')
|
107
|
-
end
|
108
|
-
|
109
|
-
def delete(file)
|
110
|
-
File.delete file rescue false
|
102
|
+
def overcommit_symlink?(file)
|
103
|
+
File.symlink?(file) && File.readlink(file) == 'overcommit-hook'
|
111
104
|
end
|
112
105
|
end
|
113
106
|
end
|
data/lib/overcommit/logger.rb
CHANGED
@@ -1,18 +1,21 @@
|
|
1
|
-
require 'singleton'
|
2
|
-
|
3
|
-
# This class centralizes all communication to STDOUT
|
4
1
|
module Overcommit
|
2
|
+
# Encapsulates all communication to an output source.
|
5
3
|
class Logger
|
6
|
-
|
4
|
+
# Helper for creating a logger which outputs nothing.
|
5
|
+
def self.silent
|
6
|
+
new(File.open('/dev/null', 'w'))
|
7
|
+
end
|
7
8
|
|
8
|
-
|
9
|
+
def initialize(out)
|
10
|
+
@out = out
|
11
|
+
end
|
9
12
|
|
10
13
|
def partial(*args)
|
11
|
-
out.print
|
14
|
+
@out.print(*args)
|
12
15
|
end
|
13
16
|
|
14
17
|
def log(*args)
|
15
|
-
out.puts
|
18
|
+
@out.puts(*args)
|
16
19
|
end
|
17
20
|
|
18
21
|
def bold(str)
|
@@ -23,6 +26,10 @@ module Overcommit
|
|
23
26
|
color(31, str)
|
24
27
|
end
|
25
28
|
|
29
|
+
def bold_error(str)
|
30
|
+
color('1;31', str)
|
31
|
+
end
|
32
|
+
|
26
33
|
def success(str)
|
27
34
|
color(32, str)
|
28
35
|
end
|
@@ -31,18 +38,14 @@ module Overcommit
|
|
31
38
|
color(33, str)
|
32
39
|
end
|
33
40
|
|
34
|
-
def
|
41
|
+
def bold_warning(str)
|
35
42
|
color('1;33', str)
|
36
43
|
end
|
37
44
|
|
38
|
-
def out
|
39
|
-
self.output ||= $stdout
|
40
|
-
end
|
41
|
-
|
42
45
|
private
|
43
46
|
|
44
47
|
def color(code, str)
|
45
|
-
log(out.
|
48
|
+
log(@out.tty? ? "\033[#{code}m#{str}\033[0m" : str)
|
46
49
|
end
|
47
50
|
end
|
48
51
|
end
|
data/lib/overcommit/utils.rb
CHANGED
@@ -1,62 +1,87 @@
|
|
1
|
+
require 'wopen3'
|
2
|
+
|
1
3
|
module Overcommit
|
4
|
+
# Utility functions for general use.
|
2
5
|
module Utils
|
3
6
|
class << self
|
4
|
-
|
5
|
-
|
6
|
-
def register_hook(hook)
|
7
|
-
@@hooks << hook
|
8
|
-
end
|
9
|
-
|
10
|
-
def run_hooks(*args)
|
11
|
-
@@hooks.each { |hook| hook.new.run(*args) }
|
7
|
+
def script_path(script)
|
8
|
+
File.join(OVERCOMMIT_HOME, 'libexec', script)
|
12
9
|
end
|
13
10
|
|
14
|
-
|
15
|
-
|
11
|
+
# Returns an absolute path to the root of the repository.
|
12
|
+
def repo_root
|
13
|
+
@repo_root ||=
|
14
|
+
begin
|
15
|
+
result = `git rev-parse --show-toplevel`.chomp
|
16
|
+
result if $?.success?
|
17
|
+
end
|
16
18
|
end
|
17
19
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
20
|
+
# Shamelessly stolen from:
|
21
|
+
# stackoverflow.com/questions/1509915/converting-camel-case-to-underscore-case-in-ruby
|
22
|
+
def snake_case(str)
|
23
|
+
str.gsub(/::/, '/').
|
24
|
+
gsub(/([A-Z]+)([A-Z][a-z])/, '\1_\2').
|
25
|
+
gsub(/([a-z\d])([A-Z])/, '\1_\2').
|
26
|
+
tr('-', '_').
|
27
|
+
downcase
|
23
28
|
end
|
24
29
|
|
25
|
-
|
26
|
-
|
30
|
+
# Converts a string containing underscores/hyphens/spaces into CamelCase.
|
31
|
+
def camel_case(str)
|
32
|
+
str.split(/_|-| /).map { |part| part.sub(/^\w/) { |c| c.upcase } }.join
|
27
33
|
end
|
28
34
|
|
29
|
-
|
30
|
-
|
35
|
+
# Returns a list of supported hook types (pre-commit, commit-msg, etc.)
|
36
|
+
def supported_hook_types
|
37
|
+
Dir[File.join(OVERCOMMIT_HOME, 'lib', 'overcommit', 'hook', '*')].
|
38
|
+
select { |file| File.directory?(file) }.
|
39
|
+
map { |file| File.basename(file, '.rb').gsub('_', '-') }
|
31
40
|
end
|
32
41
|
|
33
|
-
#
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
42
|
+
# Returns a list of supported hook classes (PreCommit, CommitMsg, etc.)
|
43
|
+
def supported_hook_type_classes
|
44
|
+
supported_hook_types.map do |file|
|
45
|
+
file.split('-').map { |part| part.capitalize }.join
|
46
|
+
end
|
38
47
|
end
|
39
48
|
|
40
|
-
#
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
49
|
+
# Returns whether a command can be found given the current environment path.
|
50
|
+
def in_path?(cmd)
|
51
|
+
exts = ENV['PATHEXT'] ? ENV['PATHEXT'].split(';') : ['']
|
52
|
+
ENV['PATH'].split(File::PATH_SEPARATOR).each do |path|
|
53
|
+
exts.each do |ext|
|
54
|
+
exe = File.join(path, "#{cmd}#{ext}")
|
55
|
+
return true if File.executable?(exe)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
false
|
48
59
|
end
|
49
60
|
|
50
|
-
#
|
51
|
-
#
|
52
|
-
|
53
|
-
|
61
|
+
# Wrap external subshell calls. This is necessary in order to allow
|
62
|
+
# Overcommit to call other Ruby executables without requiring that they be
|
63
|
+
# specified in Overcommit's Gemfile--a nasty consequence of using
|
64
|
+
# `bundle exec overcommit` while developing locally.
|
65
|
+
def command(command)
|
66
|
+
with_environment 'RUBYOPT' => nil do
|
67
|
+
Wopen3.system(command)
|
68
|
+
end
|
54
69
|
end
|
55
70
|
|
56
71
|
private
|
57
72
|
|
58
|
-
|
59
|
-
|
73
|
+
# Calls a block of code with a modified set of environment variables,
|
74
|
+
# restoring them once the code has executed.
|
75
|
+
def with_environment(env, &block)
|
76
|
+
old_env = {}
|
77
|
+
env.each do |var, value|
|
78
|
+
old_env[var] = ENV[var.to_s]
|
79
|
+
ENV[var.to_s] = value
|
80
|
+
end
|
81
|
+
|
82
|
+
yield
|
83
|
+
ensure
|
84
|
+
old_env.each { |var, value| ENV[var.to_s] = value }
|
60
85
|
end
|
61
86
|
end
|
62
87
|
end
|