Skip to content

Commit 5f5a76d

Browse files
jawshooahsds
authored andcommitted
Add initial implementation of post-commit hooks
Change-Id: I232175d2fcdd54ca2cbda05a20eb9d7d2acc1a46 Reviewed-on: http://gerrit.causes.com/46923 Tested-by: jenkins <jenkins@brigade.com> Reviewed-by: Shane da Silva <shane.dasilva@brigade.com>
1 parent d9ea443 commit 5f5a76d

File tree

6 files changed

+120
-2
lines changed

6 files changed

+120
-2
lines changed

config/default.yml

+6
Original file line numberDiff line numberDiff line change
@@ -292,3 +292,9 @@ CommitMsg:
292292

293293
TrailingPeriod:
294294
description: 'Checking for trailing periods in subject'
295+
296+
PostCommit:
297+
ALL:
298+
requires_files: false
299+
required: false
300+
quiet: false

lib/overcommit/git_repo.rb

+1
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ def extract_modified_lines(file_path, options)
2121
refs = options[:refs]
2222

2323
flags = '--cached' if options[:staged]
24+
refs = options[:refs]
2425

2526
`git diff --no-ext-diff -U0 #{flags} #{refs} -- #{file_path}`.
2627
scan(DIFF_HUNK_REGEX) do |start_line, lines_added|
+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
require 'forwardable'
2+
3+
module Overcommit::Hook::PostCommit
4+
# Functionality common to all post-commit hooks.
5+
class Base < Overcommit::Hook::Base
6+
extend Forwardable
7+
8+
def_delegators :@context, :modified_lines_in_file
9+
end
10+
end
+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
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+
@modified_files ||= Overcommit::GitRepo.modified_files(refs: 'HEAD~ HEAD')
10+
end
11+
12+
# Returns the set of line numbers corresponding to the lines that were
13+
# changed in a specified file.
14+
def modified_lines_in_file(file)
15+
@modified_lines ||= {}
16+
@modified_lines[file] ||=
17+
Overcommit::GitRepo.extract_modified_lines(file, refs: 'HEAD~ HEAD')
18+
end
19+
end
20+
end

spec/overcommit/utils_spec.rb

+2-2
Original file line numberDiff line numberDiff line change
@@ -108,13 +108,13 @@
108108
describe '.supported_hook_types' do
109109
subject { described_class.supported_hook_types }
110110

111-
it { should =~ %w[commit-msg pre-commit post-checkout post-merge] }
111+
it { should =~ %w[commit-msg pre-commit post-checkout post-commit post-merge] }
112112
end
113113

114114
describe '.supported_hook_type_classes' do
115115
subject { described_class.supported_hook_type_classes }
116116

117-
it { should =~ %w[CommitMsg PreCommit PostCheckout PostMerge] }
117+
it { should =~ %w[CommitMsg PreCommit PostCheckout PostCommit PostMerge] }
118118
end
119119

120120
describe '.execute' do

template-dir/hooks/post-commit

+81
Original file line numberDiff line numberDiff line change
@@ -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 commit comments

Comments
 (0)