forked from sds/overcommit
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathplugin_hook_loader.rb
102 lines (81 loc) · 2.92 KB
/
plugin_hook_loader.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
# frozen_string_literal: true
require 'digest'
module Overcommit::HookLoader
# Responsible for loading hooks that are specific to the repository Overcommit
# is running in.
class PluginHookLoader < Base
def load_hooks
check_for_modified_plugins if @config.verify_signatures?
hooks = plugin_paths.map do |plugin_path|
require plugin_path
hook_name = Overcommit::Utils.camel_case(File.basename(plugin_path, '.rb'))
create_hook(hook_name)
end
hooks + ad_hoc_hook_names.map do |hook_name|
create_ad_hoc_hook(hook_name)
end
end
def update_signatures
log.success('No plugin signatures have changed') if modified_plugins.empty?
modified_plugins.each do |plugin|
plugin.update_signature!
log.warning "Updated signature of plugin #{plugin.hook_name}"
end
end
private
def plugin_paths
directory = File.join(@config.plugin_directory, @context.hook_type_name)
Dir[File.join(directory, '*.rb')].sort
end
def plugin_hook_names
plugin_paths.map do |path|
Overcommit::Utils.camel_case(File.basename(path, '.rb'))
end
end
def ad_hoc_hook_names
@config.enabled_ad_hoc_hooks(@context)
end
def modified_plugins
(plugin_hook_names + ad_hoc_hook_names).
map { |hook_name| Overcommit::HookSigner.new(hook_name, @config, @context) }.
select(&:signature_changed?)
end
def check_for_modified_plugins
return if modified_plugins.empty?
log.bold_warning "The following #{@context.hook_script_name} plugins " \
'have been added, changed, or had their configuration modified:'
log.newline
modified_plugins.each do |signer|
log.warning " * #{signer.hook_name} in #{signer.hook_path}"
end
log.newline
log.bold_warning 'You should verify the changes and then run:'
log.newline
log.warning "overcommit --sign #{@context.hook_script_name}"
log.newline
log.log "For more information, see #{Overcommit::REPO_URL}#security"
raise Overcommit::Exceptions::InvalidHookSignature
end
def create_ad_hoc_hook(hook_name)
hook_module = Overcommit::Hook.const_get(@context.hook_class_name)
hook_base = hook_module.const_get('Base')
# Implement a simple class that executes the command and returns pass/fail
# based on the exit status
hook_class = Class.new(hook_base) do
def run
result = @context.execute_hook(command)
if result.success?
:pass
else
[:fail, result.stdout + result.stderr]
end
end
end
hook_module.const_set(hook_name, hook_class).new(@config, @context)
rescue LoadError, NameError => error
raise Overcommit::Exceptions::HookLoadError,
"Unable to load hook '#{hook_name}': #{error}",
error.backtrace
end
end
end