forked from sds/overcommit
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathconfiguration_loader.rb
100 lines (86 loc) · 3.22 KB
/
configuration_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
# frozen_string_literal: true
require 'yaml'
module Overcommit
# Manages configuration file loading.
class ConfigurationLoader
DEFAULT_CONFIG_PATH = File.join(Overcommit::HOME, 'config', 'default.yml')
class << self
# Loads and returns the default configuration.
#
# @return [Overcommit::Configuration]
def default_configuration
@default_configuration ||= load_from_file(DEFAULT_CONFIG_PATH, default: true, verify: false)
end
# Loads configuration from file.
#
# @param file [String] path to file
# @param options [Hash]
# @option default [Boolean] whether this is the default built-in configuration
# @option verify [Boolean] whether to verify the signature of the configuration
# @option logger [Overcommit::Logger]
# @return [Overcommit::Configuration]
def load_from_file(file, options = {})
hash =
if yaml = YAML.load_file(file)
yaml.to_hash
else
{}
end
Overcommit::Configuration.new(hash, options)
end
end
# Create a configuration loader which writes warnings/errors to the given
# {Overcommit::Logger} instance.
#
# @param logger [Overcommit::Logger]
# @param options [Hash]
# @option verify [Boolean] whether to verify signatures
def initialize(logger, options = {})
@log = logger
@options = options
end
# Loads and returns the configuration for the repository we're running in.
#
# @return [Overcommit::Configuration]
def load_repo_config
overcommit_yml = File.join(Overcommit::Utils.repo_root,
Overcommit::CONFIG_FILE_NAME)
if File.exist?(overcommit_yml)
load_file(overcommit_yml)
else
self.class.default_configuration
end
end
# Loads a configuration, ensuring it extends the default configuration.
def load_file(file)
config = load_file_with_inheritance(file)
if @options.fetch(:verify) { config.verify_signatures? }
verify_signatures(config)
end
config
rescue Overcommit::Exceptions::ConfigurationSignatureChanged
raise
rescue StandardError => error
raise Overcommit::Exceptions::ConfigurationError,
"Unable to load configuration from '#{file}': #{error}",
error.backtrace
end
private
def load_file_with_inheritance(file)
config = self.class.load_from_file(file, default: false, logger: @log)
base_config = config['inherit_from'] ? load_file_with_inheritance(config['inherit_from']) : self.class.default_configuration
base_config.merge(config)
end
def verify_signatures(config)
if !config.previous_signature?
raise Overcommit::Exceptions::ConfigurationSignatureChanged,
"No previously recorded signature for configuration file.\n" \
'Run `overcommit --sign` if you trust the hooks in this repository.'
elsif config.signature_changed?
raise Overcommit::Exceptions::ConfigurationSignatureChanged,
"Signature of configuration file has changed!\n" \
"Run `overcommit --sign` once you've verified the configuration changes."
end
end
end
end