jawshooah-overcommit 0.22.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (82) hide show
  1. checksums.yaml +7 -0
  2. data/bin/overcommit +8 -0
  3. data/config/default.yml +275 -0
  4. data/config/starter.yml +31 -0
  5. data/lib/overcommit.rb +20 -0
  6. data/lib/overcommit/cli.rb +205 -0
  7. data/lib/overcommit/configuration.rb +183 -0
  8. data/lib/overcommit/configuration_loader.rb +49 -0
  9. data/lib/overcommit/configuration_validator.rb +40 -0
  10. data/lib/overcommit/constants.rb +8 -0
  11. data/lib/overcommit/exceptions.rb +35 -0
  12. data/lib/overcommit/git_repo.rb +147 -0
  13. data/lib/overcommit/hook/base.rb +174 -0
  14. data/lib/overcommit/hook/commit_msg/base.rb +11 -0
  15. data/lib/overcommit/hook/commit_msg/gerrit_change_id.rb +18 -0
  16. data/lib/overcommit/hook/commit_msg/hard_tabs.rb +13 -0
  17. data/lib/overcommit/hook/commit_msg/russian_novel.rb +14 -0
  18. data/lib/overcommit/hook/commit_msg/single_line_subject.rb +12 -0
  19. data/lib/overcommit/hook/commit_msg/text_width.rb +38 -0
  20. data/lib/overcommit/hook/commit_msg/trailing_period.rb +12 -0
  21. data/lib/overcommit/hook/post_checkout/base.rb +11 -0
  22. data/lib/overcommit/hook/post_checkout/index_tags.rb +26 -0
  23. data/lib/overcommit/hook/post_commit/base.rb +11 -0
  24. data/lib/overcommit/hook/post_commit/git_guilt.rb +9 -0
  25. data/lib/overcommit/hook/pre_commit/author_email.rb +18 -0
  26. data/lib/overcommit/hook/pre_commit/author_name.rb +17 -0
  27. data/lib/overcommit/hook/pre_commit/base.rb +70 -0
  28. data/lib/overcommit/hook/pre_commit/berksfile_check.rb +20 -0
  29. data/lib/overcommit/hook/pre_commit/brakeman.rb +12 -0
  30. data/lib/overcommit/hook/pre_commit/broken_symlinks.rb +15 -0
  31. data/lib/overcommit/hook/pre_commit/bundle_check.rb +25 -0
  32. data/lib/overcommit/hook/pre_commit/chamber_security.rb +11 -0
  33. data/lib/overcommit/hook/pre_commit/coffee_lint.rb +11 -0
  34. data/lib/overcommit/hook/pre_commit/css_lint.rb +11 -0
  35. data/lib/overcommit/hook/pre_commit/go_lint.rb +12 -0
  36. data/lib/overcommit/hook/pre_commit/haml_lint.rb +19 -0
  37. data/lib/overcommit/hook/pre_commit/hard_tabs.rb +14 -0
  38. data/lib/overcommit/hook/pre_commit/image_optim.rb +41 -0
  39. data/lib/overcommit/hook/pre_commit/js_hint.rb +13 -0
  40. data/lib/overcommit/hook/pre_commit/jscs.rb +22 -0
  41. data/lib/overcommit/hook/pre_commit/json_syntax.rb +22 -0
  42. data/lib/overcommit/hook/pre_commit/jsx_hint.rb +13 -0
  43. data/lib/overcommit/hook/pre_commit/jsxcs.rb +20 -0
  44. data/lib/overcommit/hook/pre_commit/local_paths_in_gemfile.rb +14 -0
  45. data/lib/overcommit/hook/pre_commit/merge_conflicts.rb +14 -0
  46. data/lib/overcommit/hook/pre_commit/pry_binding.rb +14 -0
  47. data/lib/overcommit/hook/pre_commit/python_flake8.rb +11 -0
  48. data/lib/overcommit/hook/pre_commit/rails_schema_up_to_date.rb +45 -0
  49. data/lib/overcommit/hook/pre_commit/reek.rb +22 -0
  50. data/lib/overcommit/hook/pre_commit/rubocop.rb +19 -0
  51. data/lib/overcommit/hook/pre_commit/scss_lint.rb +19 -0
  52. data/lib/overcommit/hook/pre_commit/shell_check.rb +19 -0
  53. data/lib/overcommit/hook/pre_commit/trailing_whitespace.rb +13 -0
  54. data/lib/overcommit/hook/pre_commit/travis_lint.rb +11 -0
  55. data/lib/overcommit/hook/pre_commit/yaml_syntax.rb +22 -0
  56. data/lib/overcommit/hook_context.rb +17 -0
  57. data/lib/overcommit/hook_context/base.rb +69 -0
  58. data/lib/overcommit/hook_context/commit_msg.rb +32 -0
  59. data/lib/overcommit/hook_context/post_checkout.rb +26 -0
  60. data/lib/overcommit/hook_context/post_commit.rb +19 -0
  61. data/lib/overcommit/hook_context/pre_commit.rb +148 -0
  62. data/lib/overcommit/hook_context/run_all.rb +39 -0
  63. data/lib/overcommit/hook_loader/base.rb +36 -0
  64. data/lib/overcommit/hook_loader/built_in_hook_loader.rb +12 -0
  65. data/lib/overcommit/hook_loader/plugin_hook_loader.rb +61 -0
  66. data/lib/overcommit/hook_runner.rb +129 -0
  67. data/lib/overcommit/hook_signer.rb +79 -0
  68. data/lib/overcommit/installer.rb +148 -0
  69. data/lib/overcommit/interrupt_handler.rb +87 -0
  70. data/lib/overcommit/logger.rb +79 -0
  71. data/lib/overcommit/message_processor.rb +132 -0
  72. data/lib/overcommit/printer.rb +116 -0
  73. data/lib/overcommit/subprocess.rb +46 -0
  74. data/lib/overcommit/utils.rb +163 -0
  75. data/lib/overcommit/version.rb +4 -0
  76. data/libexec/gerrit-change-id +174 -0
  77. data/libexec/index-tags +17 -0
  78. data/template-dir/hooks/commit-msg +81 -0
  79. data/template-dir/hooks/overcommit-hook +81 -0
  80. data/template-dir/hooks/post-checkout +81 -0
  81. data/template-dir/hooks/pre-commit +81 -0
  82. metadata +184 -0
@@ -0,0 +1,163 @@
1
+ require 'pathname'
2
+ require 'overcommit/subprocess'
3
+
4
+ module Overcommit
5
+ # Utility functions for general use.
6
+ module Utils
7
+ class << self
8
+ def script_path(script)
9
+ File.join(OVERCOMMIT_HOME, 'libexec', script)
10
+ end
11
+
12
+ # Returns an absolute path to the root of the repository.
13
+ #
14
+ # We do this ourselves rather than call `git rev-parse --show-toplevel` to
15
+ # solve an issue where the .git directory might not actually be valid in
16
+ # tests.
17
+ #
18
+ # @return [String]
19
+ def repo_root
20
+ @repo_root ||=
21
+ begin
22
+ git_dir = Pathname.new(File.expand_path('.')).enum_for(:ascend).find do |path|
23
+ File.exist?(File.join(path, '.git'))
24
+ end
25
+
26
+ unless git_dir
27
+ raise Overcommit::Exceptions::InvalidGitRepo, 'no .git directory found'
28
+ end
29
+
30
+ git_dir.to_s
31
+ end
32
+ end
33
+
34
+ # Returns an absolute path to the .git directory for a repo.
35
+ #
36
+ # @param repo_dir [String] root directory of git repo
37
+ # @return [String]
38
+ def git_dir(repo_dir = repo_root)
39
+ @git_dir ||=
40
+ begin
41
+ git_dir = File.expand_path('.git', repo_dir)
42
+
43
+ # .git could also be a file that contains the location of the git directory
44
+ unless File.directory?(git_dir)
45
+ git_dir = File.read(git_dir)[/^gitdir: (.*)$/, 1]
46
+
47
+ # Resolve relative paths
48
+ unless git_dir.start_with?('/')
49
+ git_dir = File.expand_path(git_dir, repo_dir)
50
+ end
51
+ end
52
+
53
+ git_dir
54
+ end
55
+ end
56
+
57
+ # Shamelessly stolen from:
58
+ # stackoverflow.com/questions/1509915/converting-camel-case-to-underscore-case-in-ruby
59
+ def snake_case(str)
60
+ str.gsub(/::/, '/').
61
+ gsub(/([A-Z]+)([A-Z][a-z])/, '\1_\2').
62
+ gsub(/([a-z\d])([A-Z])/, '\1_\2').
63
+ tr('-', '_').
64
+ downcase
65
+ end
66
+
67
+ # Converts a string containing underscores/hyphens/spaces into CamelCase.
68
+ def camel_case(str)
69
+ str.split(/_|-| /).map { |part| part.sub(/^\w/) { |c| c.upcase } }.join
70
+ end
71
+
72
+ # Returns a list of supported hook types (pre-commit, commit-msg, etc.)
73
+ def supported_hook_types
74
+ Dir[File.join(OVERCOMMIT_HOME, 'lib', 'overcommit', 'hook', '*')].
75
+ select { |file| File.directory?(file) }.
76
+ map { |file| File.basename(file, '.rb').gsub('_', '-') }
77
+ end
78
+
79
+ # Returns a list of supported hook classes (PreCommit, CommitMsg, etc.)
80
+ def supported_hook_type_classes
81
+ supported_hook_types.map do |file|
82
+ file.split('-').map(&:capitalize).join
83
+ end
84
+ end
85
+
86
+ # @param cmd [String]
87
+ # @return [true,false] whether a command can be found given the current
88
+ # environment path.
89
+ def in_path?(cmd)
90
+ # ENV['PATH'] doesn't include the repo root, but that is a valid
91
+ # location for executables, so we want to add it to the list of places
92
+ # we are checking for the executable.
93
+ paths = [repo_root] + ENV['PATH'].split(File::PATH_SEPARATOR)
94
+ exts = ENV['PATHEXT'] ? ENV['PATHEXT'].split(';') : ['']
95
+ paths.each do |path|
96
+ exts.each do |ext|
97
+ exe = File.join(path, "#{cmd}#{ext}")
98
+ return true if File.executable?(exe)
99
+ end
100
+ end
101
+ false
102
+ end
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.
108
+ def execute(args)
109
+ if args.include?('|')
110
+ raise Overcommit::Exceptions::InvalidCommandArgs,
111
+ 'Cannot pipe commands with the `execute` helper'
112
+ end
113
+
114
+ with_environment 'RUBYOPT' => nil do
115
+ Subprocess.spawn(args)
116
+ end
117
+ end
118
+
119
+ # Calls a block of code with a modified set of environment variables,
120
+ # restoring them once the code has executed.
121
+ def with_environment(env)
122
+ old_env = {}
123
+ env.each do |var, value|
124
+ old_env[var] = ENV[var.to_s]
125
+ ENV[var.to_s] = value
126
+ end
127
+
128
+ yield
129
+ ensure
130
+ old_env.each { |var, value| ENV[var.to_s] = value }
131
+ end
132
+
133
+ # Returns whether a file is a broken symlink.
134
+ #
135
+ # @return [true,false]
136
+ def broken_symlink?(file)
137
+ # JRuby's implementation of File.exist? returns true for broken
138
+ # symlinks, so we need use File.size?
139
+ File.symlink?(file) && File.size?(file).nil?
140
+ end
141
+
142
+ # Convert a glob pattern to an absolute path glob pattern rooted from the
143
+ # repository root directory.
144
+ #
145
+ # @param glob [String]
146
+ # @return [String]
147
+ def convert_glob_to_absolute(glob)
148
+ File.join(repo_root, glob)
149
+ end
150
+
151
+ # Return whether a pattern matches the given path.
152
+ #
153
+ # @param pattern [String]
154
+ # @param path [String]
155
+ def matches_path?(pattern, path)
156
+ File.fnmatch?(pattern, path,
157
+ File::FNM_PATHNAME | # Wildcard doesn't match separator
158
+ File::FNM_DOTMATCH # Wildcards match dotfiles
159
+ )
160
+ end
161
+ end
162
+ end
163
+ end
@@ -0,0 +1,4 @@
1
+ # Defines the gem version.
2
+ module Overcommit
3
+ VERSION = '0.22.0'
4
+ end
@@ -0,0 +1,174 @@
1
+ #!/bin/sh
2
+ # From Gerrit Code Review 2.5.1
3
+ #
4
+ # Part of Gerrit Code Review (http://code.google.com/p/gerrit/)
5
+ #
6
+ # Copyright (C) 2009 The Android Open Source Project
7
+ #
8
+ # Licensed under the Apache License, Version 2.0 (the "License");
9
+ # you may not use this file except in compliance with the License.
10
+ # You may obtain a copy of the License at
11
+ #
12
+ # http://www.apache.org/licenses/LICENSE-2.0
13
+ #
14
+ # Unless required by applicable law or agreed to in writing, software
15
+ # distributed under the License is distributed on an "AS IS" BASIS,
16
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17
+ # See the License for the specific language governing permissions and
18
+ # limitations under the License.
19
+ #
20
+
21
+ CHANGE_ID_AFTER="Bug|Issue|Story"
22
+ MSG="$1"
23
+
24
+ # Check for, and add if missing, a unique Change-Id
25
+ #
26
+ add_ChangeId() {
27
+ clean_message=`sed -e '
28
+ /^diff --git a\/.*/{
29
+ s///
30
+ q
31
+ }
32
+ /^Signed-off-by:/d
33
+ /^#/d
34
+ ' "$MSG" | git stripspace`
35
+ if test -z "$clean_message"
36
+ then
37
+ return
38
+ fi
39
+
40
+ # Does Change-Id: already exist? if so, exit (no change).
41
+ if grep -i '^Change-Id:' "$MSG" >/dev/null
42
+ then
43
+ return
44
+ fi
45
+
46
+ id=`_gen_ChangeId`
47
+ T="$MSG.tmp.$$"
48
+ AWK=awk
49
+ if [ -x /usr/xpg4/bin/awk ]; then
50
+ # Solaris AWK is just too broken
51
+ AWK=/usr/xpg4/bin/awk
52
+ fi
53
+
54
+ # How this works:
55
+ # - parse the commit message as (textLine+ blankLine*)*
56
+ # - assume textLine+ to be a footer until proven otherwise
57
+ # - exception: the first block is not footer (as it is the title)
58
+ # - read textLine+ into a variable
59
+ # - then count blankLines
60
+ # - once the next textLine appears, print textLine+ blankLine* as these
61
+ # aren't footer
62
+ # - in END, the last textLine+ block is available for footer parsing
63
+ $AWK '
64
+ BEGIN {
65
+ # while we start with the assumption that textLine+
66
+ # is a footer, the first block is not.
67
+ isFooter = 0
68
+ footerComment = 0
69
+ blankLines = 0
70
+ }
71
+
72
+ # Skip lines starting with "#" without any spaces before it.
73
+ /^#/ { next }
74
+
75
+ # Skip the line starting with the diff command and everything after it,
76
+ # up to the end of the file, assuming it is only patch data.
77
+ # If more than one line before the diff was empty, strip all but one.
78
+ /^diff --git a/ {
79
+ blankLines = 0
80
+ while (getline) { }
81
+ next
82
+ }
83
+
84
+ # Count blank lines outside footer comments
85
+ /^$/ && (footerComment == 0) {
86
+ blankLines++
87
+ next
88
+ }
89
+
90
+ # Catch footer comment
91
+ /^\[[a-zA-Z0-9-]+:/ && (isFooter == 1) {
92
+ footerComment = 1
93
+ }
94
+
95
+ /]$/ && (footerComment == 1) {
96
+ footerComment = 2
97
+ }
98
+
99
+ # We have a non-blank line after blank lines. Handle this.
100
+ (blankLines > 0) {
101
+ print lines
102
+ for (i = 0; i < blankLines; i++) {
103
+ print ""
104
+ }
105
+
106
+ lines = ""
107
+ blankLines = 0
108
+ isFooter = 1
109
+ footerComment = 0
110
+ }
111
+
112
+ # Detect that the current block is not the footer
113
+ (footerComment == 0) && (!/^\[?[a-zA-Z0-9-]+:/ || /^[a-zA-Z0-9-]+:\/\//) {
114
+ isFooter = 0
115
+ }
116
+
117
+ {
118
+ # We need this information about the current last comment line
119
+ if (footerComment == 2) {
120
+ footerComment = 0
121
+ }
122
+ if (lines != "") {
123
+ lines = lines "\n";
124
+ }
125
+ lines = lines $0
126
+ }
127
+
128
+ # Footer handling:
129
+ # If the last block is considered a footer, splice in the Change-Id at the
130
+ # right place.
131
+ # Look for the right place to inject Change-Id by considering
132
+ # CHANGE_ID_AFTER. Keys listed in it (case insensitive) come first,
133
+ # then Change-Id, then everything else (eg. Signed-off-by:).
134
+ #
135
+ # Otherwise just print the last block, a new line and the Change-Id as a
136
+ # block of its own.
137
+ END {
138
+ unprinted = 1
139
+ if (isFooter == 0) {
140
+ print lines "\n"
141
+ lines = ""
142
+ }
143
+ changeIdAfter = "^(" tolower("'"$CHANGE_ID_AFTER"'") "):"
144
+ numlines = split(lines, footer, "\n")
145
+ for (line = 1; line <= numlines; line++) {
146
+ if (unprinted && match(tolower(footer[line]), changeIdAfter) != 1) {
147
+ unprinted = 0
148
+ print "Change-Id: I'"$id"'"
149
+ }
150
+ print footer[line]
151
+ }
152
+ if (unprinted) {
153
+ print "Change-Id: I'"$id"'"
154
+ }
155
+ }' "$MSG" > $T && mv $T "$MSG" || rm -f $T
156
+ }
157
+ _gen_ChangeIdInput() {
158
+ echo "tree `git write-tree`"
159
+ if parent=`git rev-parse "HEAD^0" 2>/dev/null`
160
+ then
161
+ echo "parent $parent"
162
+ fi
163
+ echo "author `git var GIT_AUTHOR_IDENT`"
164
+ echo "committer `git var GIT_COMMITTER_IDENT`"
165
+ echo
166
+ printf '%s' "$clean_message"
167
+ }
168
+ _gen_ChangeId() {
169
+ _gen_ChangeIdInput |
170
+ git hash-object -t commit --stdin
171
+ }
172
+
173
+
174
+ add_ChangeId
@@ -0,0 +1,17 @@
1
+ #!/bin/sh
2
+ # Indexes all tags for this repository for easy navigation with Vim, storing the
3
+ # file in <repo>/.git/tags. If you're using Fugitive.vim, you'll automatically
4
+ # have access to the tags file; otherwise you'll have to modify your `tags`
5
+ # option in your vimrc to search the generated file.
6
+
7
+ set -e
8
+
9
+ trap "rm -f $GIT_DIR/tags.$$" EXIT
10
+ err_file=$GIT_DIR/ctags.err
11
+ if ctags --tag-relative -Rf$GIT_DIR/tags.$$ --exclude=.git "$@" 2>${err_file}; then
12
+ mv $GIT_DIR/tags.$$ $GIT_DIR/tags
13
+ [ -e ${err_file} ] && rm -f ${err_file}
14
+ else
15
+ # Ignore STDERR unless `ctags` returned a non-zero exit code
16
+ cat ${err_file}
17
+ fi
@@ -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
@@ -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