overcommit 0.19.0 → 0.20.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.
Files changed (37) hide show
  1. checksums.yaml +4 -4
  2. data/config/default.yml +2 -1
  3. data/lib/overcommit/cli.rb +41 -1
  4. data/lib/overcommit/configuration_validator.rb +1 -2
  5. data/lib/overcommit/exceptions.rb +3 -0
  6. data/lib/overcommit/git_repo.rb +9 -1
  7. data/lib/overcommit/hook/base.rb +54 -32
  8. data/lib/overcommit/hook/commit_msg/text_width.rb +23 -16
  9. data/lib/overcommit/hook/pre_commit/base.rb +61 -1
  10. data/lib/overcommit/hook/pre_commit/haml_lint.rb +9 -13
  11. data/lib/overcommit/hook/pre_commit/image_optim.rb +3 -3
  12. data/lib/overcommit/hook/pre_commit/jscs.rb +5 -13
  13. data/lib/overcommit/hook/pre_commit/jsxcs.rb +5 -13
  14. data/lib/overcommit/hook/pre_commit/reek.rb +8 -15
  15. data/lib/overcommit/hook/pre_commit/rubocop.rb +9 -15
  16. data/lib/overcommit/hook/pre_commit/scss_lint.rb +9 -13
  17. data/lib/overcommit/hook_context/base.rb +3 -2
  18. data/lib/overcommit/hook_context/pre_commit.rb +11 -3
  19. data/lib/overcommit/hook_context/run_all.rb +39 -0
  20. data/lib/overcommit/hook_context.rb +2 -2
  21. data/lib/overcommit/hook_loader/base.rb +1 -3
  22. data/lib/overcommit/hook_loader/plugin_hook_loader.rb +26 -16
  23. data/lib/overcommit/hook_runner.rb +19 -9
  24. data/lib/overcommit/installer.rb +9 -5
  25. data/lib/overcommit/logger.rb +27 -0
  26. data/lib/overcommit/message_processor.rb +132 -0
  27. data/lib/overcommit/printer.rb +21 -27
  28. data/lib/overcommit/subprocess.rb +25 -16
  29. data/lib/overcommit/utils.rb +20 -0
  30. data/lib/overcommit/version.rb +1 -1
  31. data/lib/overcommit.rb +0 -1
  32. data/template-dir/hooks/commit-msg +9 -38
  33. data/template-dir/hooks/overcommit-hook +9 -38
  34. data/template-dir/hooks/post-checkout +9 -38
  35. data/template-dir/hooks/pre-commit +9 -38
  36. metadata +63 -76
  37. data/lib/overcommit/user_input.rb +0 -26
@@ -0,0 +1,39 @@
1
+ require 'set'
2
+
3
+ module Overcommit::HookContext
4
+ # Simulates a pre-commit context pretending that all files have been changed.
5
+ #
6
+ # This results in pre-commit hooks running against the entire repository,
7
+ # which is useful for automated CI scripts.
8
+ class RunAll < Base
9
+ EMPTY_SET = Set.new
10
+
11
+ def modified_files
12
+ all_files
13
+ end
14
+
15
+ # Return an empty set since in this context the user didn't actually touch
16
+ # any lines.
17
+ def modified_lines_in_file(_file)
18
+ EMPTY_SET
19
+ end
20
+
21
+ def hook_class_name
22
+ 'PreCommit'
23
+ end
24
+
25
+ def hook_type_name
26
+ 'pre_commit'
27
+ end
28
+
29
+ def hook_script_name
30
+ 'pre-commit'
31
+ end
32
+
33
+ private
34
+
35
+ def all_files
36
+ @all_files ||= Overcommit::GitRepo.all_files
37
+ end
38
+ end
39
+ end
@@ -1,12 +1,12 @@
1
1
  # Utility module which manages the creation of {HookContext}s.
2
2
  module Overcommit::HookContext
3
- def self.create(hook_type, config, args, input)
3
+ def self.create(hook_type, config, args)
4
4
  hook_type_class = Overcommit::Utils.camel_case(hook_type)
5
5
  underscored_hook_type = Overcommit::Utils.snake_case(hook_type)
6
6
 
7
7
  require "overcommit/hook_context/#{underscored_hook_type}"
8
8
 
9
- Overcommit::HookContext.const_get(hook_type_class).new(config, args, input)
9
+ Overcommit::HookContext.const_get(hook_type_class).new(config, args)
10
10
  rescue LoadError, NameError => error
11
11
  # Could happen when a symlink was created for a hook type Overcommit does
12
12
  # not yet support.
@@ -4,12 +4,10 @@ module Overcommit::HookLoader
4
4
  # @param config [Overcommit::Configuration]
5
5
  # @param context [Overcommit::HookContext]
6
6
  # @param logger [Overcommit::Logger]
7
- # @param input [Overcommit::UserInput]
8
- def initialize(config, context, logger, input)
7
+ def initialize(config, context, logger)
9
8
  @config = config
10
9
  @context = context
11
10
  @log = logger
12
- @input = input
13
11
  end
14
12
 
15
13
  # When implemented in subclasses, loads the hooks for which that subclass is
@@ -5,10 +5,7 @@ module Overcommit::HookLoader
5
5
  # is running in.
6
6
  class PluginHookLoader < Base
7
7
  def load_hooks
8
- directory = File.join(@config.plugin_directory, @context.hook_type_name)
9
- plugin_paths = Dir[File.join(directory, '*.rb')].sort
10
-
11
- check_for_modified_plugins(plugin_paths) if @config.verify_plugin_signatures?
8
+ check_for_modified_plugins if @config.verify_plugin_signatures?
12
9
 
13
10
  plugin_paths.map do |plugin_path|
14
11
  require plugin_path
@@ -18,34 +15,47 @@ module Overcommit::HookLoader
18
15
  end
19
16
  end
20
17
 
18
+ def update_signatures
19
+ log.success('No plugin signatures have changed') if modified_plugins.empty?
20
+
21
+ modified_plugins.each do |plugin|
22
+ plugin.update_signature!
23
+ log.warning "Updated signature of plugin #{plugin.hook_name}"
24
+ end
25
+ end
26
+
21
27
  private
22
28
 
23
- def check_for_modified_plugins(plugin_paths)
24
- modified_plugins = plugin_paths.
29
+ def plugin_paths
30
+ directory = File.join(@config.plugin_directory, @context.hook_type_name)
31
+ Dir[File.join(directory, '*.rb')].sort
32
+ end
33
+
34
+ def modified_plugins
35
+ plugin_paths.
25
36
  map { |path| Overcommit::HookSigner.new(path, @config, @context) }.
26
37
  select(&:signature_changed?)
38
+ end
27
39
 
40
+ def check_for_modified_plugins
28
41
  return if modified_plugins.empty?
29
42
 
30
43
  log.bold_warning "The following #{@context.hook_script_name} plugins " \
31
44
  'have been added, changed, or had their configuration modified:'
32
- log.log
45
+ log.newline
33
46
 
34
47
  modified_plugins.each do |signer|
35
48
  log.warning " * #{signer.hook_name} in #{signer.hook_path}"
36
49
  end
37
50
 
38
- log.log
39
- log.bold_warning 'You should verify the changes before continuing'
51
+ log.newline
52
+ log.bold_warning 'You should verify the changes and then run:'
53
+ log.newline
54
+ log.warning "overcommit --sign #{@context.hook_script_name}"
55
+ log.newline
40
56
  log.log "For more information, see #{Overcommit::REPO_URL}#security"
41
- log.log
42
- log.partial 'Continue? (y/n) '
43
-
44
- unless (answer = @input.get) && answer.strip.downcase.start_with?('y')
45
- raise Overcommit::Exceptions::HookCancelled
46
- end
47
57
 
48
- modified_plugins.each(&:update_signature!)
58
+ raise Overcommit::Exceptions::InvalidHookSignature
49
59
  end
50
60
  end
51
61
  end
@@ -5,12 +5,11 @@ module Overcommit
5
5
  # @param config [Overcommit::Configuration]
6
6
  # @param logger [Overcommit::Logger]
7
7
  # @param context [Overcommit::HookContext]
8
- # @param input [Overcommit::UserInput]
9
- def initialize(config, logger, context, input, printer)
8
+ # @param printer [Overcommit::Printer]
9
+ def initialize(config, logger, context, printer)
10
10
  @config = config
11
11
  @log = logger
12
12
  @context = context
13
- @input = input
14
13
  @printer = printer
15
14
  @hooks = []
16
15
  end
@@ -36,7 +35,7 @@ module Overcommit
36
35
  attr_reader :log
37
36
 
38
37
  def run_hooks
39
- if @hooks.any? { |hook| hook.run? || hook.skip? }
38
+ if @hooks.any?(&:enabled?)
40
39
  @printer.start_run
41
40
 
42
41
  interrupted = false
@@ -54,7 +53,7 @@ module Overcommit
54
53
  end
55
54
  end
56
55
 
57
- @printer.end_run(run_failed, interrupted)
56
+ print_results(run_failed, interrupted)
58
57
 
59
58
  !(run_failed || interrupted)
60
59
  else
@@ -63,6 +62,16 @@ module Overcommit
63
62
  end
64
63
  end
65
64
 
65
+ def print_results(failed, interrupted)
66
+ if interrupted
67
+ @printer.run_interrupted
68
+ elsif failed
69
+ @printer.run_failed
70
+ else
71
+ @printer.run_succeeded
72
+ end
73
+ end
74
+
66
75
  def run_hook(hook)
67
76
  return if should_skip?(hook)
68
77
 
@@ -79,7 +88,7 @@ module Overcommit
79
88
  end
80
89
  rescue => ex
81
90
  status = :fail
82
- output = "Hook raised unexpected error\n#{ex.message}"
91
+ output = "Hook raised unexpected error\n#{ex.message}\n#{ex.backtrace.join("\n")}"
83
92
  rescue Interrupt
84
93
  # At this point, interrupt has been handled and protection is back in
85
94
  # effect thanks to the InterruptHandler.
@@ -99,7 +108,8 @@ module Overcommit
99
108
  if hook.required?
100
109
  @printer.required_hook_not_skipped(hook)
101
110
  else
102
- @printer.hook_skipped(hook)
111
+ # Tell user if hook was skipped only if it actually would have run
112
+ @printer.hook_skipped(hook) if hook.run?
103
113
  return true
104
114
  end
105
115
  end
@@ -110,10 +120,10 @@ module Overcommit
110
120
  def load_hooks
111
121
  require "overcommit/hook/#{@context.hook_type_name}/base"
112
122
 
113
- @hooks += HookLoader::BuiltInHookLoader.new(@config, @context, @log, @input).load_hooks
123
+ @hooks += HookLoader::BuiltInHookLoader.new(@config, @context, @log).load_hooks
114
124
 
115
125
  # Load plugin hooks after so they can subclass existing hooks
116
- @hooks += HookLoader::PluginHookLoader.new(@config, @context, @log, @input).load_hooks
126
+ @hooks += HookLoader::PluginHookLoader.new(@config, @context, @log).load_hooks
117
127
  end
118
128
  end
119
129
  end
@@ -3,8 +3,8 @@ require 'fileutils'
3
3
  module Overcommit
4
4
  # Manages the installation of Overcommit hooks in a git repository.
5
5
  class Installer # rubocop:disable ClassLength
6
- MASTER_HOOK =
7
- File.join(OVERCOMMIT_HOME, 'template-dir', 'hooks', 'overcommit-hook')
6
+ TEMPLATE_DIRECTORY = File.join(OVERCOMMIT_HOME, 'template-dir')
7
+ MASTER_HOOK = File.join(TEMPLATE_DIRECTORY, 'hooks', 'overcommit-hook')
8
8
 
9
9
  def initialize(logger)
10
10
  @log = logger
@@ -115,13 +115,15 @@ module Overcommit
115
115
  def can_replace_file?(file)
116
116
  @options[:force] ||
117
117
  !File.exist?(file) ||
118
- overcommit_symlink?(file)
118
+ overcommit_hook?(file)
119
119
  end
120
120
 
121
121
  def uninstall_hook_symlinks
122
+ return unless File.directory?(hooks_path)
123
+
122
124
  Dir.chdir(hooks_path) do
123
125
  Overcommit::Utils.supported_hook_types.each do |hook_type|
124
- FileUtils.rm_rf(hook_type) if overcommit_symlink?(hook_type)
126
+ FileUtils.rm_rf(hook_type) if overcommit_hook?(hook_type)
125
127
  end
126
128
  end
127
129
  end
@@ -133,7 +135,9 @@ module Overcommit
133
135
  FileUtils.cp(File.join(OVERCOMMIT_HOME, 'config', 'starter.yml'), repo_config_file)
134
136
  end
135
137
 
136
- def overcommit_symlink?(file)
138
+ def overcommit_hook?(file)
139
+ return true if File.read(file) =~ /OVERCOMMIT_DISABLE/
140
+ # TODO: Remove these checks once we hit version 1.0
137
141
  File.symlink?(file) && File.readlink(file) == 'overcommit-hook'
138
142
  rescue Errno::ENOENT
139
143
  # Some Ruby implementations (e.g. JRuby) raise an error when the file
@@ -6,44 +6,71 @@ module Overcommit
6
6
  new(File.open('/dev/null', 'w'))
7
7
  end
8
8
 
9
+ # Creates a logger that will write to the given output stream.
10
+ #
11
+ # @param out [IO]
9
12
  def initialize(out)
10
13
  @out = out
11
14
  end
12
15
 
16
+ # Write output without a trailing newline.
13
17
  def partial(*args)
14
18
  @out.print(*args)
15
19
  end
16
20
 
21
+ # Prints a newline character (alias for readability).
22
+ def newline
23
+ log
24
+ end
25
+
26
+ # Write a line of output.
27
+ #
28
+ # A newline character will always be appended.
17
29
  def log(*args)
18
30
  @out.puts(*args)
19
31
  end
20
32
 
33
+ # Write a line of output that is intended to be emphasized.
21
34
  def bold(*args)
22
35
  color('1', *args)
23
36
  end
24
37
 
38
+ # Write a line of output indicating a problem or error.
25
39
  def error(*args)
26
40
  color(31, *args)
27
41
  end
28
42
 
43
+ # Write a line of output indicating a problem or error which is emphasized
44
+ # over a regular problem or error.
29
45
  def bold_error(*args)
30
46
  color('1;31', *args)
31
47
  end
32
48
 
49
+ # Write a line of output indicating a successful or noteworthy event.
33
50
  def success(*args)
34
51
  color(32, *args)
35
52
  end
36
53
 
54
+ # Write a line of output indicating a potential cause for concern, but not
55
+ # an actual error.
37
56
  def warning(*args)
38
57
  color(33, *args)
39
58
  end
40
59
 
60
+ # Write a line of output indicating a potential cause for concern, but with
61
+ # greater emphasize compared to other warnings.
41
62
  def bold_warning(*args)
42
63
  color('1;33', *args)
43
64
  end
44
65
 
45
66
  private
46
67
 
68
+ # Outputs text wrapped in ANSI escape code necessary to produce a given
69
+ # color/text display.
70
+ #
71
+ # @param code [String] ANSI escape code, e.g. '1;33' for "bold yellow"
72
+ # @param str [String] string to wrap
73
+ # @param partial [true,false] whether to omit a newline
47
74
  def color(code, str, partial = false)
48
75
  send(partial ? :partial : :log,
49
76
  @out.tty? ? "\033[#{code}m#{str}\033[0m" : str)
@@ -0,0 +1,132 @@
1
+ module Overcommit
2
+ # Utility class that encapsulates the handling of hook messages and whether
3
+ # they affect lines the user has modified or not.
4
+ #
5
+ # This class exposes an endpoint that extracts an appropriate hook/status
6
+ # output tuple from an array of {Overcommit::Hook::Message}s, respecting the
7
+ # configuration settings for the given hook.
8
+ class MessageProcessor
9
+ ERRORS_MODIFIED_HEADER = 'Errors on modified lines:'
10
+ WARNINGS_MODIFIED_HEADER = 'Warnings on modified lines:'
11
+ ERRORS_UNMODIFIED_HEADER = "Errors on lines you didn't modify:"
12
+ WARNINGS_UNMODIFIED_HEADER = "Warnings on lines you didn't modify:"
13
+
14
+ # @param hook [Overcommit::Hook::Base]
15
+ # @param unmodified_lines_setting [String] how to treat messages on
16
+ # unmodified lines
17
+ def initialize(hook, unmodified_lines_setting)
18
+ @hook = hook
19
+ @setting = unmodified_lines_setting
20
+ end
21
+
22
+ # Returns a hook status/output tuple from the messages this processor was
23
+ # initialized with.
24
+ #
25
+ # @return [Array<Symbol,String>]
26
+ def hook_result(messages)
27
+ status, output = basic_status_and_output(messages)
28
+
29
+ # Nothing to do if there are no problems to begin with
30
+ return [status, output] if status == :pass
31
+
32
+ # Return as-is if this type of hook doesn't have the concept of modified lines
33
+ return [status, output] unless @hook.respond_to?(:modified_lines_in_file)
34
+
35
+ handle_modified_lines(messages, status)
36
+ end
37
+
38
+ private
39
+
40
+ def handle_modified_lines(messages, status)
41
+ messages = remove_ignored_messages(messages)
42
+
43
+ messages_on_modified_lines, messages_on_unmodified_lines =
44
+ messages.partition { |message| message_on_modified_line?(message) }
45
+
46
+ output = print_messages(
47
+ messages_on_modified_lines,
48
+ ERRORS_MODIFIED_HEADER,
49
+ WARNINGS_MODIFIED_HEADER
50
+ )
51
+ output += print_messages(
52
+ messages_on_unmodified_lines,
53
+ ERRORS_UNMODIFIED_HEADER,
54
+ WARNINGS_UNMODIFIED_HEADER
55
+ )
56
+
57
+ [transform_status(status, messages_on_modified_lines), output]
58
+ end
59
+
60
+ def transform_status(status, messages_on_modified_lines)
61
+ # `report` indicates user wants the original status
62
+ return status if @setting == 'report'
63
+
64
+ error_messages, warning_messages =
65
+ messages_on_modified_lines.partition { |msg| msg.type == :error }
66
+
67
+ if can_upgrade_to_warning?(status, error_messages)
68
+ status = :warn
69
+ end
70
+
71
+ if can_upgrade_to_passing?(status, warning_messages)
72
+ status = :pass
73
+ end
74
+
75
+ status
76
+ end
77
+
78
+ def can_upgrade_to_warning?(status, error_messages)
79
+ status == :fail && error_messages.empty?
80
+ end
81
+
82
+ def can_upgrade_to_passing?(status, warning_messages)
83
+ status == :warn && @setting == 'ignore' && warning_messages.empty?
84
+ end
85
+
86
+ # Returns status and output for messages assuming no special treatment of
87
+ # messages occurring on unmodified lines.
88
+ def basic_status_and_output(messages)
89
+ status =
90
+ if messages.any? { |message| message.type == :error }
91
+ :fail
92
+ elsif messages.any? { |message| message.type == :warning }
93
+ :warn
94
+ else
95
+ :pass
96
+ end
97
+
98
+ output = ''
99
+ if messages.any?
100
+ output += messages.join("\n") + "\n"
101
+ end
102
+
103
+ [status, output]
104
+ end
105
+
106
+ def print_messages(messages, error_heading, warning_heading)
107
+ output = ''
108
+ errors, warnings = messages.partition { |msg| msg.type == :error }
109
+
110
+ if errors.any?
111
+ output += "#{error_heading}\n#{errors.join("\n")}\n"
112
+ end
113
+
114
+ if warnings.any?
115
+ output += "#{warning_heading}\n#{warnings.join("\n")}\n"
116
+ end
117
+
118
+ output
119
+ end
120
+
121
+ def remove_ignored_messages(messages)
122
+ # If user wants to ignore messages on unmodified lines, simply remove them
123
+ return messages unless @setting == 'ignore'
124
+
125
+ messages.select { |message| message_on_modified_line?(message) }
126
+ end
127
+
128
+ def message_on_modified_line?(message)
129
+ @hook.modified_lines_in_file(message.file).include?(message.line)
130
+ end
131
+ end
132
+ end
@@ -20,21 +20,6 @@ module Overcommit
20
20
  log.success "✓ No applicable #{hook_script_name} hooks to run"
21
21
  end
22
22
 
23
- # Executed at the very end of running the collection of hooks.
24
- def end_run(run_failed, interrupted)
25
- log.log # Newline
26
-
27
- if interrupted
28
- log.warning '⚠ Hook run interrupted by user'
29
- elsif run_failed
30
- log.error "✗ One or more #{hook_script_name} hooks failed"
31
- else
32
- log.success "✓ All #{hook_script_name} hooks passed"
33
- end
34
-
35
- log.log # Newline
36
- end
37
-
38
23
  # Executed at the start of an individual hook run.
39
24
  def start_hook(hook)
40
25
  unless hook.quiet?
@@ -59,6 +44,27 @@ module Overcommit
59
44
  print_result(hook, status, output)
60
45
  end
61
46
 
47
+ # Executed when a hook run was interrupted/cancelled by user.
48
+ def run_interrupted
49
+ log.newline
50
+ log.warning '⚠ Hook run interrupted by user'
51
+ log.newline
52
+ end
53
+
54
+ # Executed when one or more hooks by the end of the run.
55
+ def run_failed
56
+ log.newline
57
+ log.error "✗ One or more #{hook_script_name} hooks failed"
58
+ log.newline
59
+ end
60
+
61
+ # Executed when no hooks failed by the end of the run.
62
+ def run_succeeded
63
+ log.newline
64
+ log.success "✓ All #{hook_script_name} hooks passed"
65
+ log.newline
66
+ end
67
+
62
68
  private
63
69
 
64
70
  def print_header(hook)
@@ -103,18 +109,6 @@ module Overcommit
103
109
  log.send(format, output) unless output.nil? || output.empty?
104
110
  end
105
111
 
106
- def run_interrupted
107
- log.warning '⚠ Hook run interrupted by user'
108
- end
109
-
110
- def run_failed
111
- log.error "✗ One or more #{hook_script_name} hooks failed"
112
- end
113
-
114
- def run_succeeded
115
- log.success "✓ All #{hook_script_name} hooks passed"
116
- end
117
-
118
112
  def hook_script_name
119
113
  @context.hook_script_name
120
114
  end
@@ -6,32 +6,41 @@ module Overcommit
6
6
  # standard out/error output.
7
7
  class Subprocess
8
8
  # Encapsulates the result of a process.
9
- Result = Struct.new(:status, :stderr, :stdout) do
9
+ Result = Struct.new(:status, :stdout, :stderr) do
10
10
  def success?
11
11
  status == 0
12
12
  end
13
13
  end
14
14
 
15
- # Spawns a new process using the given array of arguments (the first
16
- # element is the command).
17
- def self.spawn(args)
18
- process = ChildProcess.build(*args)
15
+ class << self
16
+ # Spawns a new process using the given array of arguments (the first
17
+ # element is the command).
18
+ def spawn(args)
19
+ process = ChildProcess.build(*args)
19
20
 
20
- err = ::Tempfile.new('err')
21
- err.sync = true
22
- out = ::Tempfile.new('out')
23
- out.sync = true
21
+ out, err = assign_output_streams(process)
24
22
 
25
- process.io.stderr = err
26
- process.io.stdout = out
23
+ process.start
24
+ process.wait
27
25
 
28
- process.start
29
- process.wait
26
+ err.rewind
27
+ out.rewind
30
28
 
31
- err.rewind
32
- out.rewind
29
+ Result.new(process.exit_code, out.read, err.read)
30
+ end
31
+
32
+ private
33
33
 
34
- Result.new(process.exit_code, err.read, out.read)
34
+ # @param process [ChildProcess]
35
+ # @return [Array<IO>]
36
+ def assign_output_streams(process)
37
+ %w[out err].map do |stream_name|
38
+ ::Tempfile.new(stream_name).tap do |stream|
39
+ stream.sync = true
40
+ process.io.send("std#{stream_name}=", stream)
41
+ end
42
+ end
43
+ end
35
44
  end
36
45
  end
37
46
  end
@@ -132,6 +132,26 @@ module Overcommit
132
132
  # symlinks, so we need use File.size?
133
133
  File.symlink?(file) && File.size?(file).nil?
134
134
  end
135
+
136
+ # Convert a glob pattern to an absolute path glob pattern rooted from the
137
+ # repository root directory.
138
+ #
139
+ # @param glob [String]
140
+ # @return [String]
141
+ def convert_glob_to_absolute(glob)
142
+ File.join(repo_root, glob)
143
+ end
144
+
145
+ # Return whether a pattern matches the given path.
146
+ #
147
+ # @param pattern [String]
148
+ # @param path [String]
149
+ def matches_path?(pattern, path)
150
+ File.fnmatch?(pattern, path,
151
+ File::FNM_PATHNAME | # Wildcard doesn't match separator
152
+ File::FNM_DOTMATCH # Wildcards match dotfiles
153
+ )
154
+ end
135
155
  end
136
156
  end
137
157
  end
@@ -1,4 +1,4 @@
1
1
  # Defines the gem version.
2
2
  module Overcommit
3
- VERSION = '0.19.0'
3
+ VERSION = '0.20.0'
4
4
  end
data/lib/overcommit.rb CHANGED
@@ -6,7 +6,6 @@ require 'overcommit/configuration_loader'
6
6
  require 'overcommit/hook/base'
7
7
  require 'overcommit/hook_context/base'
8
8
  require 'overcommit/hook_context'
9
- require 'overcommit/user_input'
10
9
  require 'overcommit/git_repo'
11
10
  require 'overcommit/hook_signer'
12
11
  require 'overcommit/hook_loader/base'