overcommit 0.23.0 → 0.24.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 -1
- data/config/default.yml +154 -18
- data/config/starter.yml +3 -3
- data/lib/overcommit.rb +2 -1
- data/lib/overcommit/cli.rb +11 -8
- data/lib/overcommit/configuration.rb +18 -4
- data/lib/overcommit/configuration_loader.rb +45 -28
- data/lib/overcommit/configuration_validator.rb +33 -1
- data/lib/overcommit/constants.rb +5 -3
- data/lib/overcommit/exceptions.rb +3 -0
- data/lib/overcommit/git_repo.rb +116 -0
- data/lib/overcommit/git_version.rb +15 -0
- data/lib/overcommit/hook/base.rb +42 -5
- data/lib/overcommit/hook/commit_msg/capitalized_subject.rb +13 -0
- data/lib/overcommit/hook/commit_msg/spell_check.rb +41 -0
- data/lib/overcommit/hook/post_checkout/submodule_status.rb +30 -0
- data/lib/overcommit/hook/post_commit/submodule_status.rb +30 -0
- data/lib/overcommit/hook/post_merge/submodule_status.rb +30 -0
- data/lib/overcommit/hook/post_rewrite/submodule_status.rb +30 -0
- data/lib/overcommit/hook/pre_commit/base.rb +2 -2
- data/lib/overcommit/hook/pre_commit/bundle_check.rb +1 -1
- data/lib/overcommit/hook/pre_commit/case_conflicts.rb +20 -0
- data/lib/overcommit/hook/pre_commit/coffee_lint.rb +29 -2
- data/lib/overcommit/hook/pre_commit/css_lint.rb +1 -8
- data/lib/overcommit/hook/pre_commit/go_lint.rb +8 -2
- data/lib/overcommit/hook/pre_commit/go_vet.rb +20 -0
- data/lib/overcommit/hook/pre_commit/html_tidy.rb +1 -10
- data/lib/overcommit/hook/pre_commit/image_optim.rb +11 -28
- data/lib/overcommit/hook/pre_commit/js_lint.rb +18 -0
- data/lib/overcommit/hook/pre_commit/jsl.rb +24 -0
- data/lib/overcommit/hook/pre_commit/json_syntax.rb +4 -7
- data/lib/overcommit/hook/pre_commit/rails_schema_up_to_date.rb +1 -1
- data/lib/overcommit/hook/pre_commit/ruby_lint.rb +19 -0
- data/lib/overcommit/hook/pre_commit/scss_lint.rb +8 -1
- data/lib/overcommit/hook/pre_commit/w3c_css.rb +4 -18
- data/lib/overcommit/hook/pre_commit/w3c_html.rb +4 -18
- data/lib/overcommit/hook/pre_commit/xml_syntax.rb +19 -0
- data/lib/overcommit/hook/pre_commit/yaml_syntax.rb +4 -8
- data/lib/overcommit/hook/pre_push/base.rb +10 -0
- data/lib/overcommit/hook/pre_push/protected_branches.rb +27 -0
- data/lib/overcommit/hook/pre_push/r_spec.rb +12 -0
- data/lib/overcommit/hook/pre_rebase/base.rb +11 -0
- data/lib/overcommit/hook_context.rb +2 -2
- data/lib/overcommit/hook_context/base.rb +5 -7
- data/lib/overcommit/hook_context/pre_commit.rb +66 -16
- data/lib/overcommit/hook_context/pre_push.rb +44 -0
- data/lib/overcommit/hook_context/pre_rebase.rb +36 -0
- data/lib/overcommit/hook_runner.rb +27 -7
- data/lib/overcommit/installer.rb +46 -7
- data/lib/overcommit/message_processor.rb +3 -0
- data/lib/overcommit/printer.rb +8 -12
- data/lib/overcommit/subprocess.rb +11 -0
- data/lib/overcommit/utils.rb +28 -6
- data/lib/overcommit/version.rb +1 -1
- data/template-dir/hooks/commit-msg +2 -2
- data/template-dir/hooks/overcommit-hook +2 -2
- data/template-dir/hooks/post-checkout +2 -2
- data/template-dir/hooks/post-commit +2 -2
- data/template-dir/hooks/post-merge +2 -2
- data/template-dir/hooks/post-rewrite +2 -2
- data/template-dir/hooks/pre-commit +2 -2
- data/template-dir/hooks/pre-push +81 -0
- data/template-dir/hooks/pre-rebase +81 -0
- metadata +33 -13
- data/lib/overcommit/hook/pre_commit/pry_binding.rb +0 -14
data/config/starter.yml
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# Use this file to configure the Overcommit hooks you wish to use. This will
|
2
2
|
# extend the default configuration defined in:
|
3
|
-
# https://github.com/
|
3
|
+
# https://github.com/brigade/overcommit/blob/master/config/default.yml
|
4
4
|
#
|
5
5
|
# At the topmost level of this YAML file is a key representing type of hook
|
6
6
|
# being run (e.g. pre-commit, commit-msg, etc.). Within each type you can
|
@@ -8,10 +8,10 @@
|
|
8
8
|
# `include`), whether to only display output if it fails (via `quiet`), etc.
|
9
9
|
#
|
10
10
|
# For a complete list of hooks, see:
|
11
|
-
# https://github.com/
|
11
|
+
# https://github.com/brigade/overcommit/tree/master/lib/overcommit/hook
|
12
12
|
#
|
13
13
|
# For a complete list of options that you can use to customize hooks, see:
|
14
|
-
# https://github.com/
|
14
|
+
# https://github.com/brigade/overcommit#configuration
|
15
15
|
#
|
16
16
|
# Uncomment the following lines to make the configuration take effect.
|
17
17
|
|
data/lib/overcommit.rb
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
require 'overcommit/constants'
|
2
2
|
require 'overcommit/exceptions'
|
3
|
+
require 'overcommit/utils'
|
4
|
+
require 'overcommit/git_version'
|
3
5
|
require 'overcommit/configuration_validator'
|
4
6
|
require 'overcommit/configuration'
|
5
7
|
require 'overcommit/configuration_loader'
|
@@ -16,5 +18,4 @@ require 'overcommit/printer'
|
|
16
18
|
require 'overcommit/hook_runner'
|
17
19
|
require 'overcommit/installer'
|
18
20
|
require 'overcommit/logger'
|
19
|
-
require 'overcommit/utils'
|
20
21
|
require 'overcommit/version'
|
data/lib/overcommit/cli.rb
CHANGED
@@ -4,8 +4,9 @@ module Overcommit
|
|
4
4
|
# Responsible for parsing command-line options and executing appropriate
|
5
5
|
# application logic based on those options.
|
6
6
|
class CLI # rubocop:disable ClassLength
|
7
|
-
def initialize(arguments, logger)
|
7
|
+
def initialize(arguments, input, logger)
|
8
8
|
@arguments = arguments
|
9
|
+
@input = input
|
9
10
|
@log = logger
|
10
11
|
@options = {}
|
11
12
|
end
|
@@ -127,7 +128,7 @@ module Overcommit
|
|
127
128
|
end
|
128
129
|
|
129
130
|
def print_template_directory_path
|
130
|
-
puts File.join(
|
131
|
+
puts File.join(Overcommit::HOME, 'template-dir')
|
131
132
|
halt
|
132
133
|
end
|
133
134
|
|
@@ -145,8 +146,6 @@ module Overcommit
|
|
145
146
|
# Prints the hooks available in the current repo and whether they're
|
146
147
|
# enabled/disabled.
|
147
148
|
def print_installed_hooks
|
148
|
-
config = Overcommit::ConfigurationLoader.load_repo_config
|
149
|
-
|
150
149
|
config.all_hook_configs.each do |hook_type, hook_configs|
|
151
150
|
print_hooks_for_hook_type(config, hook_configs, hook_type)
|
152
151
|
end
|
@@ -174,10 +173,10 @@ module Overcommit
|
|
174
173
|
end
|
175
174
|
|
176
175
|
def sign_plugins
|
177
|
-
config = Overcommit::ConfigurationLoader.load_repo_config
|
178
176
|
context = Overcommit::HookContext.create(@options[:hook_to_sign],
|
179
177
|
config,
|
180
|
-
@arguments
|
178
|
+
@arguments,
|
179
|
+
@input)
|
181
180
|
Overcommit::HookLoader::PluginHookLoader.new(config,
|
182
181
|
context,
|
183
182
|
log).update_signatures
|
@@ -185,8 +184,7 @@ module Overcommit
|
|
185
184
|
end
|
186
185
|
|
187
186
|
def run_all
|
188
|
-
|
189
|
-
context = Overcommit::HookContext.create('run-all', config, @arguments)
|
187
|
+
context = Overcommit::HookContext.create('run-all', config, @arguments, @input)
|
190
188
|
config.apply_environment!(context, ENV)
|
191
189
|
|
192
190
|
printer = Overcommit::Printer.new(log, context)
|
@@ -201,5 +199,10 @@ module Overcommit
|
|
201
199
|
def halt(status = 0)
|
202
200
|
exit status
|
203
201
|
end
|
202
|
+
|
203
|
+
# Returns the configuration for this repository.
|
204
|
+
def config
|
205
|
+
@config ||= Overcommit::ConfigurationLoader.new(log).load_repo_config
|
206
|
+
end
|
204
207
|
end
|
205
208
|
end
|
@@ -2,8 +2,15 @@ module Overcommit
|
|
2
2
|
# Stores configuration for Overcommit and the hooks it runs.
|
3
3
|
class Configuration # rubocop:disable ClassLength
|
4
4
|
# Creates a configuration from the given hash.
|
5
|
-
|
6
|
-
|
5
|
+
#
|
6
|
+
# @param hash [Hash] loaded YAML config file as a hash
|
7
|
+
# @param options [Hash]
|
8
|
+
# @option default [Boolean] whether this is the default built-in configuration
|
9
|
+
# @option logger [Overcommit::Logger]
|
10
|
+
def initialize(hash, options = {})
|
11
|
+
@options = options.dup
|
12
|
+
@options[:logger] ||= Overcommit::Logger.silent
|
13
|
+
@hash = Overcommit::ConfigurationValidator.new.validate(hash, options)
|
7
14
|
end
|
8
15
|
|
9
16
|
def ==(other)
|
@@ -145,7 +152,7 @@ module Overcommit
|
|
145
152
|
def built_in_hook?(hook_context, hook_name)
|
146
153
|
hook_name = Overcommit::Utils.snake_case(hook_name)
|
147
154
|
|
148
|
-
File.exist?(File.join(
|
155
|
+
File.exist?(File.join(Overcommit::HOME, 'lib', 'overcommit', 'hook',
|
149
156
|
hook_context.hook_type_name, "#{hook_name}.rb"))
|
150
157
|
end
|
151
158
|
|
@@ -164,10 +171,17 @@ module Overcommit
|
|
164
171
|
all_enabled = @hash[hook_type]['ALL']['enabled']
|
165
172
|
return all_enabled unless all_enabled.nil?
|
166
173
|
|
167
|
-
|
174
|
+
false
|
168
175
|
end
|
169
176
|
|
170
177
|
def smart_merge(parent, child)
|
178
|
+
# Treat the ALL hook specially so that it overrides any configuration
|
179
|
+
# specified by the default configuration.
|
180
|
+
child_all = child['ALL']
|
181
|
+
unless child_all.nil?
|
182
|
+
parent = Hash[parent.collect { |k, v| [k, smart_merge(v, child_all)] }]
|
183
|
+
end
|
184
|
+
|
171
185
|
parent.merge(child) do |_key, old, new|
|
172
186
|
case old
|
173
187
|
when Hash
|
@@ -3,38 +3,24 @@ require 'yaml'
|
|
3
3
|
module Overcommit
|
4
4
|
# Manages configuration file loading.
|
5
5
|
class ConfigurationLoader
|
6
|
-
DEFAULT_CONFIG_PATH = File.join(
|
6
|
+
DEFAULT_CONFIG_PATH = File.join(Overcommit::HOME, 'config', 'default.yml')
|
7
7
|
|
8
8
|
class << self
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
if File.exist?(overcommit_yml)
|
14
|
-
load_file(overcommit_yml)
|
15
|
-
else
|
16
|
-
default_configuration
|
17
|
-
end
|
18
|
-
end
|
19
|
-
|
9
|
+
# Loads and returns the default configuration.
|
10
|
+
#
|
11
|
+
# @return [Overcommit::Configuration]
|
20
12
|
def default_configuration
|
21
|
-
@default_config ||= load_from_file(DEFAULT_CONFIG_PATH)
|
22
|
-
end
|
23
|
-
|
24
|
-
private
|
25
|
-
|
26
|
-
# Loads a configuration, ensuring it extends the default configuration.
|
27
|
-
def load_file(file)
|
28
|
-
config = load_from_file(file)
|
29
|
-
|
30
|
-
default_configuration.merge(config)
|
31
|
-
rescue => error
|
32
|
-
raise Overcommit::Exceptions::ConfigurationError,
|
33
|
-
"Unable to load configuration from '#{file}': #{error}",
|
34
|
-
error.backtrace
|
13
|
+
@default_config ||= load_from_file(DEFAULT_CONFIG_PATH, default: true)
|
35
14
|
end
|
36
15
|
|
37
|
-
|
16
|
+
# Loads configuration from file.
|
17
|
+
#
|
18
|
+
# @param file [String] path to file
|
19
|
+
# @param options [Hash]
|
20
|
+
# @option default [Boolean] whether this is the default built-in configuration
|
21
|
+
# @option logger [Overcommit::Logger]
|
22
|
+
# @return [Overcommit::Configuration]
|
23
|
+
def load_from_file(file, options = {})
|
38
24
|
hash =
|
39
25
|
if yaml = YAML.load_file(file)
|
40
26
|
yaml.to_hash
|
@@ -42,8 +28,39 @@ module Overcommit
|
|
42
28
|
{}
|
43
29
|
end
|
44
30
|
|
45
|
-
Overcommit::Configuration.new(hash)
|
31
|
+
Overcommit::Configuration.new(hash, options)
|
46
32
|
end
|
47
33
|
end
|
34
|
+
|
35
|
+
# Create a configuration loader which writes warnings/errors to the given
|
36
|
+
# {Overcommit::Logger} instance.
|
37
|
+
def initialize(logger)
|
38
|
+
@log = logger
|
39
|
+
end
|
40
|
+
|
41
|
+
# Loads and returns the configuration for the repository we're running in.
|
42
|
+
#
|
43
|
+
# @return [Overcommit::Configuration]
|
44
|
+
def load_repo_config
|
45
|
+
overcommit_yml = File.join(Overcommit::Utils.repo_root,
|
46
|
+
Overcommit::CONFIG_FILE_NAME)
|
47
|
+
|
48
|
+
if File.exist?(overcommit_yml)
|
49
|
+
load_file(overcommit_yml)
|
50
|
+
else
|
51
|
+
self.class.default_configuration
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
# Loads a configuration, ensuring it extends the default configuration.
|
56
|
+
def load_file(file)
|
57
|
+
config = self.class.load_from_file(file, default: false, logger: @log)
|
58
|
+
|
59
|
+
self.class.default_configuration.merge(config)
|
60
|
+
rescue => error
|
61
|
+
raise Overcommit::Exceptions::ConfigurationError,
|
62
|
+
"Unable to load configuration from '#{file}': #{error}",
|
63
|
+
error.backtrace
|
64
|
+
end
|
48
65
|
end
|
49
66
|
end
|
@@ -2,9 +2,19 @@ module Overcommit
|
|
2
2
|
# Validates and normalizes a configuration.
|
3
3
|
class ConfigurationValidator
|
4
4
|
# Validates hash for any invalid options, normalizing where possible.
|
5
|
-
|
5
|
+
#
|
6
|
+
# @param hash [Hash] hash representation of YAML config
|
7
|
+
# @param options[Hash]
|
8
|
+
# @option default [Boolean] whether hash represents the default built-in config
|
9
|
+
# @option logger [Overcommit::Logger] logger to output warnings to
|
10
|
+
# @return [Hash] validated hash (potentially modified)
|
11
|
+
def validate(hash, options)
|
12
|
+
@options = options.dup
|
13
|
+
@log = options[:logger]
|
14
|
+
|
6
15
|
hash = convert_nils_to_empty_hashes(hash)
|
7
16
|
ensure_hook_type_sections_exist(hash)
|
17
|
+
check_for_missing_enabled_option(hash) unless @options[:default]
|
8
18
|
|
9
19
|
hash
|
10
20
|
end
|
@@ -36,5 +46,27 @@ module Overcommit
|
|
36
46
|
end
|
37
47
|
end
|
38
48
|
end
|
49
|
+
|
50
|
+
# Prints a warning if there are any hooks listed in the configuration
|
51
|
+
# without `enabled` explicitly set.
|
52
|
+
def check_for_missing_enabled_option(hash)
|
53
|
+
return unless @log
|
54
|
+
|
55
|
+
any_warnings = false
|
56
|
+
|
57
|
+
Overcommit::Utils.supported_hook_type_classes.each do |hook_type|
|
58
|
+
hash.fetch(hook_type, {}).each do |hook_name, hook_config|
|
59
|
+
next if hook_name == 'ALL'
|
60
|
+
|
61
|
+
if hook_config['enabled'].nil?
|
62
|
+
@log.warning "#{hook_type}::#{hook_name} hook does not explicitly " \
|
63
|
+
'set `enabled` option in .overcommit.yml'
|
64
|
+
any_warnings = true
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
@log.newline if any_warnings
|
70
|
+
end
|
39
71
|
end
|
40
72
|
end
|
data/lib/overcommit/constants.rb
CHANGED
@@ -1,8 +1,10 @@
|
|
1
1
|
# Global application constants.
|
2
2
|
module Overcommit
|
3
|
-
|
4
|
-
|
3
|
+
HOME = File.expand_path(File.join(File.dirname(__FILE__), '..', '..'))
|
4
|
+
CONFIG_FILE_NAME = '.overcommit.yml'
|
5
5
|
|
6
|
-
|
6
|
+
HOOK_DIRECTORY = File.join(HOME, 'lib', 'overcommit', 'hook')
|
7
|
+
|
8
|
+
REPO_URL = 'https://github.com/brigade/overcommit'
|
7
9
|
BUG_REPORT_URL = "#{REPO_URL}/issues"
|
8
10
|
end
|
@@ -5,6 +5,9 @@ module Overcommit::Exceptions
|
|
5
5
|
# Raised when trying to read/write to/from the local repo git config fails.
|
6
6
|
class GitConfigError < StandardError; end
|
7
7
|
|
8
|
+
# Raised when there was a problem reading submodule information for a repo.
|
9
|
+
class GitSubmoduleError < StandardError; end
|
10
|
+
|
8
11
|
# Raised when a {HookContext} is unable to setup the environment before a run.
|
9
12
|
class HookSetupFailed < StandardError; end
|
10
13
|
|
data/lib/overcommit/git_repo.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'iniparse'
|
2
|
+
|
1
3
|
module Overcommit
|
2
4
|
# Provide a set of utilities for certain interactions with `git`.
|
3
5
|
module GitRepo
|
@@ -11,6 +13,50 @@ module Overcommit
|
|
11
13
|
\s@@.*$
|
12
14
|
/x
|
13
15
|
|
16
|
+
# Regular expression used to extract information from lines of
|
17
|
+
# `git submodule status` output
|
18
|
+
SUBMODULE_STATUS_REGEX = /
|
19
|
+
^\s*(?<prefix>[-+U]?)(?<sha1>\w+)
|
20
|
+
\s(?<path>[^\s]+?)
|
21
|
+
(?:\s\((?<describe>.+)\))?$
|
22
|
+
/x
|
23
|
+
|
24
|
+
# Struct encapsulating submodule information extracted from the
|
25
|
+
# output of `git submodule status`
|
26
|
+
SubmoduleStatus = Struct.new(:prefix, :sha1, :path, :describe) do
|
27
|
+
# Returns whether the submodule has not been initialized
|
28
|
+
def uninitialized?
|
29
|
+
prefix == '-'
|
30
|
+
end
|
31
|
+
|
32
|
+
# Returns whether the submodule is out of date with the current
|
33
|
+
# index, i.e. its checked-out commit differs from that stored in
|
34
|
+
# the index of the parent repo
|
35
|
+
def outdated?
|
36
|
+
prefix == '+'
|
37
|
+
end
|
38
|
+
|
39
|
+
# Returns whether the submodule reference has a merge conflict
|
40
|
+
def merge_conflict?
|
41
|
+
prefix == 'U'
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
# Returns a list of SubmoduleStatus objects, one for each submodule in the
|
46
|
+
# parent repository.
|
47
|
+
#
|
48
|
+
# @option options [Boolean] recursive check submodules recursively
|
49
|
+
# @return [Array<SubmoduleStatus>]
|
50
|
+
def submodule_statuses(options = {})
|
51
|
+
flags = '--recursive' if options[:recursive]
|
52
|
+
|
53
|
+
`git submodule status #{flags}`.
|
54
|
+
scan(SUBMODULE_STATUS_REGEX).
|
55
|
+
map do |prefix, sha1, path, describe|
|
56
|
+
SubmoduleStatus.new(prefix, sha1, path, describe)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
14
60
|
# Extract the set of modified lines from a given file.
|
15
61
|
#
|
16
62
|
# @param file_path [String]
|
@@ -54,6 +100,19 @@ module Overcommit
|
|
54
100
|
map { |relative_file| File.expand_path(relative_file) }
|
55
101
|
end
|
56
102
|
|
103
|
+
# Returns the names of files in the given paths that are tracked by git.
|
104
|
+
#
|
105
|
+
# @param paths [Array<String>] list of paths to check
|
106
|
+
# @option options [String] ref ('HEAD') Git ref to check
|
107
|
+
# @return [Array<String>] list of absolute file paths
|
108
|
+
def list_files(paths = [], options = {})
|
109
|
+
ref = options[:ref] || 'HEAD'
|
110
|
+
`git ls-tree --name-only #{ref} #{paths.join(' ')}`.
|
111
|
+
split(/\n/).
|
112
|
+
map { |relative_file| File.expand_path(relative_file) }.
|
113
|
+
reject { |file| File.directory?(file) } # Exclude submodule directories
|
114
|
+
end
|
115
|
+
|
57
116
|
# Returns the names of all files that are tracked by git.
|
58
117
|
#
|
59
118
|
# @return [Array<String>] list of absolute file paths
|
@@ -132,5 +191,62 @@ module Overcommit
|
|
132
191
|
@cherry_head = nil
|
133
192
|
end
|
134
193
|
end
|
194
|
+
|
195
|
+
# Contains information about a registered submodule.
|
196
|
+
Submodule = Struct.new(:path, :url)
|
197
|
+
|
198
|
+
# Returns the submodules that have been staged for removal.
|
199
|
+
#
|
200
|
+
# `git` has an unexpected behavior where removing a submodule without
|
201
|
+
# committing (i.e. such that the submodule directory is removed and the
|
202
|
+
# changes to the index are staged) and then doing a hard reset results in
|
203
|
+
# the index being wiped but the empty directory of the once existent
|
204
|
+
# submodule being restored (but with no content).
|
205
|
+
#
|
206
|
+
# This prevents restoration of the stash of the submodule index changes,
|
207
|
+
# which breaks pre-commit hook restorations of the working index.
|
208
|
+
#
|
209
|
+
# Thus we expose this helper so the restoration code can manually delete the
|
210
|
+
# directory.
|
211
|
+
#
|
212
|
+
# @raise [Overcommit::Exceptions::GitSubmoduleError] when
|
213
|
+
def staged_submodule_removals
|
214
|
+
# There were no submodules before, so none could have been removed
|
215
|
+
return [] if `git ls-files .gitmodules`.empty?
|
216
|
+
|
217
|
+
previous = submodules(ref: 'HEAD')
|
218
|
+
current = submodules
|
219
|
+
|
220
|
+
previous - current
|
221
|
+
end
|
222
|
+
|
223
|
+
# Returns the current set of registered submodules.
|
224
|
+
#
|
225
|
+
# @param options [Hash]
|
226
|
+
# @return [Array<Overcommit::GitRepo::Submodule>]
|
227
|
+
def submodules(options = {})
|
228
|
+
ref = options[:ref]
|
229
|
+
|
230
|
+
modules = []
|
231
|
+
IniParse.parse(`git show #{ref}:.gitmodules`).each do |section|
|
232
|
+
# git < 1.8.5 does not update the .gitmodules file with submodule
|
233
|
+
# changes, so when we are looking at the current state of the work tree,
|
234
|
+
# we need to check if the submodule actually exists via another method,
|
235
|
+
# since the .gitmodules file we parsed does not represent reality.
|
236
|
+
if ref.nil? && GIT_VERSION < '1.8.5'
|
237
|
+
result = Overcommit::Utils.execute(%W[
|
238
|
+
git submodule status #{section['path']}
|
239
|
+
])
|
240
|
+
next unless result.success?
|
241
|
+
end
|
242
|
+
|
243
|
+
modules << Submodule.new(section['path'], section['url'])
|
244
|
+
end
|
245
|
+
|
246
|
+
modules
|
247
|
+
rescue IniParse::IniParseError => ex
|
248
|
+
raise Overcommit::Exceptions::GitSubmoduleError,
|
249
|
+
"Unable to read submodule information from #{ref}:.gitmodules file: #{ex.message}"
|
250
|
+
end
|
135
251
|
end
|
136
252
|
end
|