overcommit 0.22.0 → 0.23.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 (42) hide show
  1. checksums.yaml +4 -4
  2. data/config/default.yml +169 -41
  3. data/lib/overcommit/configuration.rb +0 -2
  4. data/lib/overcommit/git_repo.rb +10 -3
  5. data/lib/overcommit/hook/base.rb +4 -0
  6. data/lib/overcommit/hook/post_checkout/index_tags.rb +2 -19
  7. data/lib/overcommit/hook/post_commit/base.rb +10 -0
  8. data/lib/overcommit/hook/post_commit/git_guilt.rb +39 -0
  9. data/lib/overcommit/hook/post_commit/index_tags.rb +9 -0
  10. data/lib/overcommit/hook/post_merge/base.rb +10 -0
  11. data/lib/overcommit/hook/post_merge/index_tags.rb +9 -0
  12. data/lib/overcommit/hook/post_rewrite/base.rb +10 -0
  13. data/lib/overcommit/hook/post_rewrite/index_tags.rb +12 -0
  14. data/lib/overcommit/hook/pre_commit/css_lint.rb +20 -2
  15. data/lib/overcommit/hook/pre_commit/es_lint.rb +18 -0
  16. data/lib/overcommit/hook/pre_commit/html_tidy.rb +35 -0
  17. data/lib/overcommit/hook/pre_commit/image_optim.rb +1 -1
  18. data/lib/overcommit/hook/pre_commit/java_checkstyle.rb +19 -0
  19. data/lib/overcommit/hook/pre_commit/js_hint.rb +9 -3
  20. data/lib/overcommit/hook/pre_commit/pep257.rb +19 -0
  21. data/lib/overcommit/hook/pre_commit/pep8.rb +19 -0
  22. data/lib/overcommit/hook/pre_commit/pyflakes.rb +28 -0
  23. data/lib/overcommit/hook/pre_commit/pylint.rb +28 -0
  24. data/lib/overcommit/hook/pre_commit/python_flake8.rb +18 -1
  25. data/lib/overcommit/hook/pre_commit/scalastyle.rb +26 -0
  26. data/lib/overcommit/hook/pre_commit/semi_standard.rb +17 -0
  27. data/lib/overcommit/hook/pre_commit/standard.rb +17 -0
  28. data/lib/overcommit/hook/pre_commit/w3c_css.rb +77 -0
  29. data/lib/overcommit/hook/pre_commit/w3c_html.rb +74 -0
  30. data/lib/overcommit/hook/pre_commit/xml_lint.rb +20 -0
  31. data/lib/overcommit/hook_context/post_commit.rb +31 -0
  32. data/lib/overcommit/hook_context/post_merge.rb +35 -0
  33. data/lib/overcommit/hook_context/post_rewrite.rb +18 -0
  34. data/lib/overcommit/hook_context/run_all.rb +12 -9
  35. data/lib/overcommit/utils.rb +25 -6
  36. data/lib/overcommit/version.rb +1 -1
  37. data/template-dir/hooks/post-commit +81 -0
  38. data/template-dir/hooks/post-merge +81 -0
  39. data/template-dir/hooks/post-rewrite +81 -0
  40. metadata +48 -10
  41. data/lib/overcommit/hook/pre_commit/jsx_hint.rb +0 -13
  42. data/lib/overcommit/hook/pre_commit/jsxcs.rb +0 -20
@@ -0,0 +1,19 @@
1
+ module Overcommit::Hook::PreCommit
2
+ # Runs `pep8` against any modified Python files.
3
+ class Pep8 < Base
4
+ def run
5
+ result = execute(command + applicable_files)
6
+ output = result.stdout.chomp
7
+
8
+ return :pass if result.success? && output.empty?
9
+
10
+ # example message:
11
+ # path/to/file.py:88:5: E301 expected 1 blank line, found 0
12
+ extract_messages(
13
+ output.split("\n"),
14
+ /^(?<file>[^:]+):(?<line>\d+):\d+:\s(?<type>E|W)/,
15
+ lambda { |type| type.include?('W') ? :warning : :error }
16
+ )
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,28 @@
1
+ module Overcommit::Hook::PreCommit
2
+ # Runs `pyflakes` against any modified Python files.
3
+ class Pyflakes < Base
4
+ MESSAGE_REGEX = /^(?<file>[^:]+):(?<line>\d+):/
5
+
6
+ def run
7
+ result = execute(command + applicable_files)
8
+ return :pass if result.success?
9
+
10
+ errors = get_messages(result.stderr, :error)
11
+ warnings = get_messages(result.stdout, :warning)
12
+
13
+ errors + warnings
14
+ end
15
+
16
+ private
17
+
18
+ def get_messages(output, type)
19
+ # example message:
20
+ # path/to/file.py:57: local variable 'x' is assigned to but never used
21
+ extract_messages(
22
+ output.split("\n").grep(MESSAGE_REGEX),
23
+ MESSAGE_REGEX,
24
+ proc { type }
25
+ )
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,28 @@
1
+ module Overcommit::Hook::PreCommit
2
+ # Runs `pylint` against any modified Python files.
3
+ class Pylint < Base
4
+ MESSAGE_REGEX = /^(?<file>.+):(?<line>\d+):(?<type>[CEFRW])/
5
+
6
+ # Classify 'E' and 'F' message codes as errors,
7
+ # everything else as warnings.
8
+ # http://pylint.readthedocs.org/en/latest/tutorial.html#getting-started
9
+ MESSAGE_TYPE_CATEGORIZER = lambda do |type|
10
+ 'EF'.include?(type) ? :error : :warning
11
+ end
12
+
13
+ def run
14
+ result = execute(command + applicable_files)
15
+ return :pass if result.success?
16
+
17
+ output = result.stdout.chomp
18
+
19
+ # example message:
20
+ # path/to/file.py:64:C: Missing function docstring (missing-docstring)
21
+ extract_messages(
22
+ output.split("\n").grep(MESSAGE_REGEX),
23
+ MESSAGE_REGEX,
24
+ MESSAGE_TYPE_CATEGORIZER
25
+ )
26
+ end
27
+ end
28
+ end
@@ -1,11 +1,28 @@
1
1
  module Overcommit::Hook::PreCommit
2
2
  # Runs `flake8` against any modified Python files.
3
3
  class PythonFlake8 < Base
4
+ MESSAGE_REGEX = /^(?<file>.+):(?<line>\d+):\d+:\s(?<type>\w\d+)/
5
+
6
+ # Classify 'Exxx' and 'Fxxx' message codes as errors,
7
+ # everything else as warnings.
8
+ # http://flake8.readthedocs.org/en/latest/warnings.html
9
+ MESSAGE_TYPE_CATEGORIZER = lambda do |type|
10
+ 'EF'.include?(type[0]) ? :error : :warning
11
+ end
12
+
4
13
  def run
5
14
  result = execute(command + applicable_files)
6
15
  return :pass if result.success?
7
16
 
8
- [:fail, result.stdout]
17
+ output = result.stdout.chomp
18
+
19
+ # example message:
20
+ # path/to/file.py:2:13: F812 list comprehension redefines name from line 1
21
+ extract_messages(
22
+ output.split("\n").grep(MESSAGE_REGEX),
23
+ MESSAGE_REGEX,
24
+ MESSAGE_TYPE_CATEGORIZER
25
+ )
9
26
  end
10
27
  end
11
28
  end
@@ -0,0 +1,26 @@
1
+ module Overcommit::Hook::PreCommit
2
+ # Runs `scalastyle` against any modified Scala files.
3
+ class Scalastyle < Base
4
+ MESSAGE_REGEX = /
5
+ ^(?<type>error|warning)\s
6
+ file=(?<file>.+)\s
7
+ message=.+\s
8
+ line=(?<line>\d+)
9
+ /x
10
+
11
+ def run
12
+ result = execute(command + applicable_files)
13
+ output = result.stdout.chomp
14
+ messages = output.split("\n").grep(MESSAGE_REGEX)
15
+ return :pass if result.success? && messages.empty?
16
+
17
+ # example message:
18
+ # error file=/path/to/file.scala message=Error message line=1 column=1
19
+ extract_messages(
20
+ messages,
21
+ MESSAGE_REGEX,
22
+ lambda { |type| type.to_sym }
23
+ )
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,17 @@
1
+ module Overcommit::Hook::PreCommit
2
+ # Runs `semistandard` against any modified JavaScript files.
3
+ class SemiStandard < Base
4
+ def run
5
+ result = execute(command + applicable_files)
6
+ output = result.stderr.chomp
7
+ return :pass if result.success? && output.empty?
8
+
9
+ # example message:
10
+ # path/to/file.js:1:1: Error message (ruleName)
11
+ extract_messages(
12
+ output.split("\n")[1..-1], # ignore header line
13
+ /^(?<file>[^:]+):(?<line>\d+)/
14
+ )
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,17 @@
1
+ module Overcommit::Hook::PreCommit
2
+ # Runs `standard` against any modified JavaScript files.
3
+ class Standard < Base
4
+ def run
5
+ result = execute(command + applicable_files)
6
+ output = result.stderr.chomp
7
+ return :pass if result.success? && output.empty?
8
+
9
+ # example message:
10
+ # path/to/file.js:1:1: Error message (ruleName)
11
+ extract_messages(
12
+ output.split("\n")[1..-1], # ignore header line
13
+ /^(?<file>[^:]+):(?<line>\d+)/
14
+ )
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,77 @@
1
+ module Overcommit::Hook::PreCommit
2
+ # Runs `w3c_validators` against any modified CSS files.
3
+ class W3cCss < Base
4
+ def run
5
+ begin
6
+ require 'w3c_validators'
7
+ rescue LoadError
8
+ return :fail, 'w3c_validators not installed -- run `gem install w3c_validators`'
9
+ end
10
+
11
+ result_messages =
12
+ begin
13
+ collect_messages
14
+ rescue W3CValidators::ValidatorUnavailable => e
15
+ return :fail, e.message
16
+ rescue W3CValidators::ParsingError => e
17
+ return :fail, e.message
18
+ end
19
+
20
+ return :pass if result_messages.empty?
21
+
22
+ result_messages
23
+ end
24
+
25
+ private
26
+
27
+ def collect_messages
28
+ applicable_files.collect do |path|
29
+ results = validator.validate_file(path)
30
+ messages = results.errors + results.warnings
31
+ messages.collect do |msg|
32
+ # Some warnings are not per-line, so use 0 as a default
33
+ line = Integer(msg.line || 0)
34
+
35
+ # Build message by hand to reduce noise from the validator response
36
+ text = "#{msg.type.to_s.upcase}; URI: #{path}; line #{line}: #{msg.message.strip}"
37
+ Overcommit::Hook::Message.new(msg.type, path, line, text)
38
+ end
39
+ end.flatten
40
+ end
41
+
42
+ def validator
43
+ unless @validator
44
+ @validator = W3CValidators::CSSValidator.new(opts)
45
+ @validator.set_language!(language) unless language.nil?
46
+ @validator.set_profile!(profile) unless profile.nil?
47
+ @validator.set_warn_level!(warn_level) unless warn_level.nil?
48
+ end
49
+ @validator
50
+ end
51
+
52
+ def opts
53
+ @opts ||= {
54
+ validator_uri: config['validator_uri'],
55
+ proxy_server: config['proxy_server'],
56
+ proxy_port: config['proxy_port'],
57
+ proxy_user: config['proxy_user'],
58
+ proxy_pass: config['proxy_pass']
59
+ }
60
+ end
61
+
62
+ def language
63
+ @language ||= config['language']
64
+ end
65
+
66
+ # Values specified at
67
+ # http://www.rubydoc.info/gems/w3c_validators/1.2/W3CValidators#CSS_PROFILES
68
+ def profile
69
+ @profile ||= config['profile']
70
+ end
71
+
72
+ # One of 0, 1, 2, 'no'
73
+ def warn_level
74
+ @warn_level ||= config['warn_level']
75
+ end
76
+ end
77
+ end
@@ -0,0 +1,74 @@
1
+ module Overcommit::Hook::PreCommit
2
+ # Runs `w3c_validators` against any modified HTML files.
3
+ class W3cHtml < Base
4
+ def run
5
+ begin
6
+ require 'w3c_validators'
7
+ rescue LoadError
8
+ return :fail, 'w3c_validators not installed -- run `gem install w3c_validators`'
9
+ end
10
+
11
+ result_messages =
12
+ begin
13
+ collect_messages
14
+ rescue W3CValidators::ValidatorUnavailable => e
15
+ return :fail, e.message
16
+ rescue W3CValidators::ParsingError => e
17
+ return :fail, e.message
18
+ end
19
+
20
+ return :pass if result_messages.empty?
21
+
22
+ result_messages
23
+ end
24
+
25
+ private
26
+
27
+ def collect_messages
28
+ applicable_files.collect do |path|
29
+ results = validator.validate_file(path)
30
+ messages = results.errors + results.warnings
31
+ messages.collect do |msg|
32
+ # Some warnings are not per-line, so use 0 as a default
33
+ line = Integer(msg.line || 0)
34
+
35
+ # Build message by hand to reduce noise from the validator response
36
+ text = "#{msg.type.to_s.upcase}; URI: #{path}; line #{line}: #{msg.message.strip}"
37
+ Overcommit::Hook::Message.new(msg.type, path, line, text)
38
+ end
39
+ end.flatten
40
+ end
41
+
42
+ def validator
43
+ unless @validator
44
+ @validator = W3CValidators::MarkupValidator.new(opts)
45
+ @validator.set_charset!(charset, true) unless charset.nil?
46
+ @validator.set_doctype!(doctype, true) unless doctype.nil?
47
+ @validator.set_debug!
48
+ end
49
+ @validator
50
+ end
51
+
52
+ def opts
53
+ @opts ||= {
54
+ validator_uri: config['validator_uri'],
55
+ proxy_server: config['proxy_server'],
56
+ proxy_port: config['proxy_port'],
57
+ proxy_user: config['proxy_user'],
58
+ proxy_pass: config['proxy_pass']
59
+ }
60
+ end
61
+
62
+ # Values specified at
63
+ # http://www.rubydoc.info/gems/w3c_validators/1.2/W3CValidators#CHARSETS
64
+ def charset
65
+ @charset ||= config['charset']
66
+ end
67
+
68
+ # Values specified at
69
+ # http://www.rubydoc.info/gems/w3c_validators/1.2/W3CValidators#DOCTYPES
70
+ def doctype
71
+ @doctype ||= config['doctype']
72
+ end
73
+ end
74
+ end
@@ -0,0 +1,20 @@
1
+ module Overcommit::Hook::PreCommit
2
+ # Runs `xmllint` against any modified XML files.
3
+ class XmlLint < Base
4
+ MESSAGE_REGEX = /^(?<file>[^:]+):(?<line>\d+):/
5
+
6
+ def run
7
+ result = execute(command + applicable_files)
8
+ output = result.stderr.chomp
9
+
10
+ return :pass if result.success? && output.empty?
11
+
12
+ # example message:
13
+ # path/to/file.xml:1: parser error : Error message
14
+ extract_messages(
15
+ output.split("\n").grep(MESSAGE_REGEX),
16
+ MESSAGE_REGEX
17
+ )
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,31 @@
1
+ module Overcommit::HookContext
2
+ # Contains helpers related to contextual information used by post-commit
3
+ # hooks.
4
+ class PostCommit < Base
5
+ # Get a list of files that were added, copied, or modified in the last
6
+ # commit. Renames and deletions are ignored, since there should be nothing
7
+ # to check.
8
+ def modified_files
9
+ subcmd = 'show --format=%n'
10
+ @modified_files ||= Overcommit::GitRepo.modified_files(subcmd: subcmd)
11
+ end
12
+
13
+ # Returns the set of line numbers corresponding to the lines that were
14
+ # changed in a specified file.
15
+ def modified_lines_in_file(file)
16
+ subcmd = 'show --format=%n'
17
+ @modified_lines ||= {}
18
+ @modified_lines[file] ||=
19
+ Overcommit::GitRepo.extract_modified_lines(file, subcmd: subcmd)
20
+ end
21
+
22
+ # Returns whether the commit that triggered this hook is the first commit on
23
+ # the branch.
24
+ #
25
+ # @return [true,false]
26
+ def initial_commit?
27
+ return @initial_commit unless @initial_commit.nil?
28
+ @initial_commit = !Overcommit::Utils.execute(%w[git rev-parse HEAD~]).success?
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,35 @@
1
+ module Overcommit::HookContext
2
+ # Contains helpers related to contextual information used by post-merge
3
+ # hooks.
4
+ class PostMerge < Base
5
+ attr_accessor :args
6
+ # Get a list of files that were added, copied, or modified in the merge
7
+ # commit. Renames and deletions are ignored, since there should be nothing
8
+ # to check.
9
+ def modified_files
10
+ staged = squash?
11
+ refs = 'HEAD^ HEAD' if merge_commit?
12
+ @modified_files ||= Overcommit::GitRepo.modified_files(staged: staged, refs: refs)
13
+ end
14
+
15
+ # Returns the set of line numbers corresponding to the lines that were
16
+ # changed in a specified file.
17
+ def modified_lines_in_file(file)
18
+ staged = squash?
19
+ refs = 'HEAD^ HEAD' if merge_commit?
20
+ @modified_lines ||= {}
21
+ @modified_lines[file] ||=
22
+ Overcommit::GitRepo.extract_modified_lines(file, staged: staged, refs: refs)
23
+ end
24
+
25
+ # Returns whether this merge was made using --squash
26
+ def squash?
27
+ @args[0].to_i == 1
28
+ end
29
+
30
+ # Returns whether this merge was made without --squash
31
+ def merge_commit?
32
+ !squash?
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,18 @@
1
+ module Overcommit::HookContext
2
+ # Contains helpers for contextual information used by post-rewrite hooks.
3
+ class PostRewrite < Base
4
+ # Returns whether this post-rewrite was triggered by `git commit --amend`.
5
+ #
6
+ # @return [true,false]
7
+ def amend?
8
+ @args[0] == 'amend'
9
+ end
10
+
11
+ # Returns whether this post-rewrite was triggered by `git rebase`.
12
+ #
13
+ # @return [true,false]
14
+ def rebase?
15
+ @args[0] == 'rebase'
16
+ end
17
+ end
18
+ end
@@ -6,16 +6,18 @@ module Overcommit::HookContext
6
6
  # This results in pre-commit hooks running against the entire repository,
7
7
  # which is useful for automated CI scripts.
8
8
  class RunAll < Base
9
- EMPTY_SET = Set.new
10
-
11
9
  def modified_files
12
- all_files
10
+ @modified_files ||= Overcommit::GitRepo.all_files
13
11
  end
14
12
 
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
13
+ # Returns all lines in the file since in this context the entire repo is
14
+ # being scrutinized.
15
+ #
16
+ # @param file [String]
17
+ # @return [Set]
18
+ def modified_lines_in_file(file)
19
+ @modified_lines_in_file ||= {}
20
+ @modified_lines_in_file[file] ||= Set.new(1..(count_lines(file) + 1))
19
21
  end
20
22
 
21
23
  def hook_class_name
@@ -32,8 +34,9 @@ module Overcommit::HookContext
32
34
 
33
35
  private
34
36
 
35
- def all_files
36
- @all_files ||= Overcommit::GitRepo.all_files
37
+ def count_lines(file)
38
+ result = Overcommit::Utils.execute(%w[wc -l] + [file])
39
+ result.success? ? result.stdout.to_i : 0
37
40
  end
38
41
  end
39
42
  end
@@ -101,19 +101,38 @@ module Overcommit
101
101
  false
102
102
  end
103
103
 
104
- # Wrap external subshell calls. This is necessary in order to allow
105
- # Overcommit to call other Ruby executables without requiring that they be
106
- # specified in Overcommit's Gemfile--a nasty consequence of using
107
- # `bundle exec overcommit` while developing locally.
104
+ # Execute a command in a subprocess, capturing exit status and output from
105
+ # both standard and error streams.
106
+ #
107
+ # This is intended to provide a centralized place to perform any checks or
108
+ # filtering of the command before executing it.
109
+ #
110
+ # @param args [Array<String>]
111
+ # @return [Overcommit::Subprocess::Result] status, stdout, and stderr
108
112
  def execute(args)
109
113
  if args.include?('|')
110
114
  raise Overcommit::Exceptions::InvalidCommandArgs,
111
115
  'Cannot pipe commands with the `execute` helper'
112
116
  end
113
117
 
114
- with_environment 'RUBYOPT' => nil do
115
- Subprocess.spawn(args)
118
+ Subprocess.spawn(args)
119
+ end
120
+
121
+ # Execute a command in a subprocess, returning immediately.
122
+ #
123
+ # This provides a convenient way to execute long-running processes for
124
+ # which we do not need to know the result.
125
+ #
126
+ # @param args [Array<String>]
127
+ # @return [Thread] thread watching the resulting child process
128
+ def execute_in_background(args)
129
+ if args.include?('|')
130
+ raise Overcommit::Exceptions::InvalidCommandArgs,
131
+ 'Cannot pipe commands with the `execute_in_background` helper'
116
132
  end
133
+
134
+ # Dissociate process from parent's input/output streams
135
+ Process.detach(Process.spawn({}, *args, [:in, :out, :err] => '/dev/null'))
117
136
  end
118
137
 
119
138
  # Calls a block of code with a modified set of environment variables,
@@ -1,4 +1,4 @@
1
1
  # Defines the gem version.
2
2
  module Overcommit
3
- VERSION = '0.22.0'
3
+ VERSION = '0.23.0'
4
4
  end
@@ -0,0 +1,81 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ # Entrypoint for Overcommit hook integration. Installing Overcommit will result
4
+ # in all of your git hooks being symlinked to this file, allowing the framework
5
+ # to manage your hooks for you.
6
+
7
+ # Prevent a Ruby stack trace from appearing when we interrupt the hook.
8
+ # Note that this will be overridden when Overcommit is loaded, since the
9
+ # InterruptHandler will redefine the trap at that time.
10
+ Signal.trap('INT') do
11
+ puts 'Hook run interrupted'
12
+ exit 130
13
+ end
14
+
15
+ # Allow hooks to be disabled via environment variable so git commands can be run
16
+ # in scripts without Overcommit running hooks
17
+ if ENV['OVERCOMMIT_DISABLE'].to_i != 0 || ENV['OVERCOMMIT_DISABLED'].to_i != 0
18
+ exit
19
+ end
20
+
21
+ hook_type = File.basename($0)
22
+ if hook_type == 'overcommit-hook'
23
+ puts "Don't run `overcommit-hook` directly; it is intended to be symlinked " \
24
+ "by each hook in a repository's .git/hooks directory."
25
+ exit 64 # EX_USAGE
26
+ end
27
+
28
+ begin
29
+ require 'overcommit'
30
+ rescue LoadError
31
+ puts 'This repository contains hooks installed by Overcommit, but the ' \
32
+ "overcommit gem is not installed.\n" \
33
+ 'Install it with `gem install overcommit`.'
34
+ exit
35
+ end
36
+
37
+ begin
38
+ logger = Overcommit::Logger.new(STDOUT)
39
+
40
+ # Ensure master hook is up-to-date
41
+ installer = Overcommit::Installer.new(logger)
42
+ if installer.run(Overcommit::Utils.repo_root, action: :update)
43
+ exec($0, *ARGV) # Execute the updated hook with all original arguments
44
+ end
45
+
46
+ config = Overcommit::ConfigurationLoader.load_repo_config
47
+
48
+ context = Overcommit::HookContext.create(hook_type, config, ARGV)
49
+ config.apply_environment!(context, ENV)
50
+
51
+ printer = Overcommit::Printer.new(logger, context)
52
+ runner = Overcommit::HookRunner.new(config, logger, context, printer)
53
+
54
+ status = runner.run
55
+
56
+ exit(status ? 0 : 65) # 65 = EX_DATAERR
57
+ rescue Overcommit::Exceptions::ConfigurationError => error
58
+ puts error
59
+ exit 78 # EX_CONFIG
60
+ rescue Overcommit::Exceptions::HookContextLoadError => error
61
+ puts error
62
+ puts 'Are you running an old version of Overcommit?'
63
+ exit 69 # EX_UNAVAILABLE
64
+ rescue Overcommit::Exceptions::HookSetupFailed,
65
+ Overcommit::Exceptions::HookCleanupFailed => error
66
+ puts error.message
67
+ exit 74 # EX_IOERR
68
+ rescue Overcommit::Exceptions::HookCancelled
69
+ puts 'You cancelled the hook run'
70
+ exit 130 # Ctrl-C cancel
71
+ rescue Overcommit::Exceptions::InvalidGitRepo => error
72
+ puts error
73
+ exit 64 # EX_USAGE
74
+ rescue Overcommit::Exceptions::InvalidHookSignature
75
+ exit 1
76
+ rescue => error
77
+ puts error.message
78
+ puts error.backtrace
79
+ puts "Report this bug at #{Overcommit::BUG_REPORT_URL}"
80
+ exit 70 # EX_SOFTWARE
81
+ end