-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathgit_mail_notifier.rb
More file actions
executable file
·143 lines (122 loc) · 4.31 KB
/
Copy pathgit_mail_notifier.rb
File metadata and controls
executable file
·143 lines (122 loc) · 4.31 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
#!/usr/bin/ruby
require 'rubygems'
require 'action_mailer'
class GitMailNotifier
# Return the name of the current Git repository.
def repo_name
git_prefix = `git config hooks.emailprefix`.strip
return git_prefix unless git_prefix.empty?
dir_name = `pwd`.chomp.split("/").last.gsub(/\.git$/, '')
return "#{dir_name}"
end
# Return the provided string with placeholders substituted with actual values.
def expand_placeholders(text)
text \
.gsub("REPO_NAME", repo_name) \
.gsub("BRANCH_NAME", @branch_name) \
.gsub("FILE_NAMES", @file_names) \
.gsub("FILE_DIFFS", @file_diffs)
end
# Run the script.
# The script has a single required parameter: a YAML configuration file.
def main(args)
if args.empty?
puts "Configuration file is missing. You need to pass it as an argument."
return
end
config_path = Pathname.new(args.first).expand_path
unless File.exist?(config_path)
puts "Cannot find configuration file #{config_path}."
return
end
@config = YAML::load_file(config_path)
@to = @config["recipients"]
if @to.nil? or @to.empty?
puts "No recipients specified in #{config_path}"
return
end
if @config["from"] and !@config["from"].empty?
@from = @config["from"]
else
@from = "no-reply@nodomain.com"
end
if @config["exclude_branches"]
@exclude_branches = @config["exclude_branches"].split
else
@exclude_branches = []
end
if @config["include_branches"]
@include_branches = @config["include_branches"].split
else
@include_branches = []
end
if @config["include_matches"] and !@config["include_matches"].empty?
@include_matches = Regexp.new(@config["include_matches"])
else
@include_matches = Regexp.new(".*")
end
STDIN.each_line do |line|
oldrev, newrev, ref = line.strip.split
@branch_name = ""
@file_diffs = ""
begin
if ref =~ %r"^refs/heads" and newrev != "0000000000000000000000000000000000000000"
@branch_name = ref.sub('refs/heads/', '')
next if @exclude_branches.include? @branch_name
next if !@include_branches.empty? and !@include_branches.include? @branch_name
tmp_body = @config["body"]
tmp_subject = @config["subject"]
if oldrev == "0000000000000000000000000000000000000000"
# No old revision specified: it has to be a new branch
oldrev = `git rev-list --reverse #{newrev} | head -1`.strip
tmp_body = @config["body_new_branch"]
tmp_subject = @config["subject_new_branch"]
end
files = `git diff --diff-filter=ACMDR --name-status #{oldrev} #{newrev}`.strip
matching_files = []
matching_lines = []
files.each do |file_line|
status, name = file_line.split("\t")
if name =~ @include_matches
matching_files << name.strip
matching_lines << file_line.strip
end
end
@file_names = matching_lines.join("\n")
unless matching_files.empty?
@file_diffs = `git diff #{oldrev} #{newrev} -- #{matching_files.join(" ")}`
archive = `git archive --format=zip #{newrev} #{matching_files.join(" ")}`
Mailer.deliver_zip_message(
@to,
@from,
expand_placeholders(tmp_subject),
archive,
expand_placeholders(tmp_body),
"file_#{repo_name}_#{@branch_name}_#{Time.now.strftime("%Y-%m-%d_%H-%M")}.zip"
)
puts "Sent notification email"
end
end
rescue Exception => e
puts "Exception in GitMailNotifier: #{e}"
puts "Hook params: #{oldrev} #{newrev} #{ref}"
end
end
end
end
class Mailer < ActionMailer::Base
# Send a mail with an attached zip file.
def zip_message(to_field, from_field, subject_field, attachment_body, message_body, filename)
recipients to_field
from from_field
subject subject_field
body message_body
attachment :content_type => "application/zip",
:body => attachment_body,
:filename => filename
end
end
if __FILE__ == $0
n = GitMailNotifier.new
n.main(ARGV)
end