git-commit-notifier 0.11.4 → 0.11.5

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.
data/README.md CHANGED
@@ -4,10 +4,10 @@
4
4
 
5
5
  __by Bodo Tasche (bodo 'at' wannawork 'dot' de), Akzhan Abdulin (akzhan 'dot' abdulin 'at' gmail 'dot' com), Csoma Zoltan (info 'at' railsprogrammer 'dot' net)__
6
6
 
7
- Sends email commit messages splitting commits that were pushed in one step.
8
- Email is delivered as text or HTML with changes refined per word. Emails
9
- have a scannable subject containing the first sentence of the commit as well
10
- as the author, project and branch name.
7
+ Sends email commit messages splitting commits that were pushed in one step.
8
+ Email is delivered as text or HTML with changes refined per word. Emails
9
+ have a scannable subject containing the first sentence of the commit as well
10
+ as the author, project and branch name.
11
11
 
12
12
  It's also possible to send a mail to a newsgroup using NNTP.
13
13
 
@@ -15,8 +15,8 @@ For example:
15
15
 
16
16
  [rails][branch] Fix Brasilia timezone. [#1180 state:resolved]
17
17
 
18
- A reply-to header is added containing the author of the commit. This makes
19
- follow up really simple. If multiple commits are pushed at once, emails are
18
+ A reply-to header is added containing the author of the commit. This makes
19
+ follow up really simple. If multiple commits are pushed at once, emails are
20
20
  numbered in chronological order:
21
21
 
22
22
  [rails][branch][0] Added deprecated warning messages to Float#months and Float#years deprications.
@@ -42,7 +42,7 @@ Install the gem:
42
42
  gem install git-commit-notifier
43
43
  ```
44
44
 
45
- After you installed the gem, you need to configure your git repository. Add a file called
45
+ After you installed the gem, you need to configure your git repository. Add a file called
46
46
  "post-receive" to the "hooks" directory of your git repository with this content:
47
47
 
48
48
  ```bash
@@ -69,6 +69,13 @@ Git-commit-notifier supports easy integration with Redmine, Bugzilla and MediaWi
69
69
  * "refs #123" and "fixes #123" sentences in commit message will be replaced with link to issue in Redmine.
70
70
  * "[[SomePage]]" sentence in commit message will be replaced with link to page in MediaWiki.
71
71
 
72
+ ## Github-flavored Webhooks
73
+
74
+ Git-commit-notifier can send a webhook just after sending a mail, This webook will be sent in a POST request to a server specified in the configuration (webhook / url), under JSON format following the same syntax as Github webhooks.
75
+
76
+ * [Cogbot](https://github.com/mose/cogbot) is the irc bot for which that feature was originaly designed for. Only a subset of the Github json file was required for that one so maybe it won't work on all Github webhook recievers.
77
+ * [Github webhooks](https://help.github.com/articles/post-receive-hooks) describes the json format expected and some hints on how to design a webhook reciever.
78
+
72
79
  ## Integration of links to other websites
73
80
 
74
81
  If you need integration with other websites not supported by git-commit-notifier you can use the message\_map property. For that you need to know the basics of regular expressions syntax.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.11.4
1
+ 0.11.5
@@ -1,7 +1,7 @@
1
1
  # set to true if you want to ignore empty merge messages
2
- ignore_merge: false
2
+ ignore_merge: false
3
3
 
4
- # Optional parameter for the subject-line of the mail
4
+ # Optional parameter for the subject-line of the mail
5
5
  # emailprefix: GIT
6
6
 
7
7
  # Set limit on maximum number of lines per file diff
@@ -10,6 +10,9 @@ lines_per_diff: 300
10
10
  # Show file list only when too many files
11
11
  too_many_files: 50
12
12
 
13
+ # Show summary before changes
14
+ show_summary: true
15
+
13
16
  # Whether to expand css inline. May be compatible with more mail readers
14
17
  # but consumes much more space and more cpu. Defaults to true
15
18
  # expand_css: true
@@ -29,13 +32,14 @@ too_many_files: 50
29
32
  # branch_name - Name of the git branch
30
33
  # slash_branch_name - /branch_name (master is "" unless show_master_branch_name)
31
34
  # commit_id - The git commit id (hash)
35
+ # description - The git description tag ("git describe --always")
32
36
  # message - The commit message
33
37
  # commit_number - The commit number within the push; 1-based
34
38
  # commit_count - The number of commits within the push
35
39
  # commit_count_phrase - The number of commits, as "1 commit", "2 commits", etc.
36
40
  # commit_count_phrase2 - "2 commits: ", "3 commits: ", etc, or "" if just one
37
41
  #
38
- # The default subject template varies a little depending on whether
42
+ # The default subject template varies a little depending on whether
39
43
  # or not group_email_by_push is set.
40
44
  #
41
45
  #subject: "[${prefix}${slash_branch_name}] ${commit_count_phrase2}${message}"
@@ -52,10 +56,15 @@ too_many_files: 50
52
56
  # It can send to multiple destinations, just separate email addresses by ",".
53
57
  mailinglist: developers@example.com,dev2@example.com,dev3@example.com,cto@example.com
54
58
 
55
- # The from address. If not defined it will use
59
+ # The from address. If not defined it will use
56
60
  # the address that is configured in git
57
61
  # from: sender@example.com
58
62
 
63
+ # If reply_to_author is set to true, the Reply-To address is same as the author's
64
+ # email address, if not it will be same as the from address.
65
+ # Defaults to false
66
+ # reply_to_author: false
67
+
59
68
  # stylesheet file (embedded template/styles.css by default)
60
69
  # stylesheet: /absolute/path/to/readable/stylesheet.css
61
70
 
@@ -63,7 +72,7 @@ mailinglist: developers@example.com,dev2@example.com,dev3@example.com,cto@exampl
63
72
  # custom_template: /absolute/path/to/readable/email.html.erb
64
73
 
65
74
  # select the delivery method: smtp, nntp, sendmail, or debug
66
- delivery_method: sendmail
75
+ delivery_method: sendmail
67
76
 
68
77
  # Optionally group email by push: don't send an email for each commit when true.
69
78
  # group_email_by_push: false
@@ -101,7 +110,7 @@ nntp_settings:
101
110
 
102
111
  # Decorate files and commit ids with link to a webview. Possible values: none, gitweb,
103
112
  # gitorious, cgit, trac, gitlabhq, or redmine
104
- link_files: none
113
+ link_files: none
105
114
 
106
115
  # If link_files is set to "gitweb", you need to configure the path to your gitweb
107
116
  # instance and the project name.
@@ -173,6 +182,10 @@ show_master_branch_name: false
173
182
  # ignore whitespace?
174
183
  ignore_whitespace: true
175
184
 
185
+ # adding parameters to send webhooks
186
+ # webooks:
187
+ # url: http://example.com:8081/commits
188
+
176
189
  # This is developer debugging options. Do not uncomment it if You aren't Jedi
177
190
  # debug:
178
191
  # enabled: true
@@ -29,14 +29,15 @@ Gem::Specification.new do |s|
29
29
  s.add_runtime_dependency(%q<nntp>, ["~> 1.0"])
30
30
  s.add_runtime_dependency(%q<premailer>, ["~> 1.7", ">= 1.7.1", "!= 1.7.2"])
31
31
  s.add_runtime_dependency(%q<nokogiri>, ["~> 1.4"])
32
+ s.add_runtime_dependency(%q<yajl-ruby>, ["~> 1.0"])
32
33
  s.add_development_dependency(%q<rake>, ["~> 0.8", "!= 0.9.0"])
33
34
  s.add_development_dependency(%q<bundler>, ["~> 1.0", ">=1.0.10"])
34
35
  s.add_development_dependency(%q<code-cleaner>, [">= 0"])
35
36
  s.add_development_dependency(%q<rspec-core>, [">= 0"])
36
37
  s.add_development_dependency(%q<rspec-expectations>, [">= 0"])
37
38
  s.add_development_dependency(%q<rr>, ["~> 1.0"])
38
- s.add_development_dependency(%q<faker>, ["~> 0.9.5"])
39
- s.add_development_dependency(%q<yard>, ["~> 0.7.5"])
40
- s.add_development_dependency(%q<redcarpet>, ["~> 1.17.2"])
39
+ s.add_development_dependency(%q<faker>, ["~> 1.0"])
40
+ s.add_development_dependency(%q<yard>, ["~> 0.8.1"])
41
+ s.add_development_dependency(%q<redcarpet>, ["~> 2.1"])
41
42
  end
42
43
 
@@ -60,6 +60,21 @@ module GitCommitNotifier
60
60
  ! commit_info[:commit_info][:merge].nil?
61
61
  end
62
62
 
63
+ # Gets message subject.
64
+ # @param [Hash] commit_info Commit info.
65
+ # @param [String] template Subject template.
66
+ # @param [Hash] subject_map Map of subject substitutions.
67
+ # @return [String] Message subject.
68
+ def get_subject(commit_info, template, subject_map)
69
+ template.gsub(/\$\{(\w+)\}/) do |m|
70
+ res = subject_map[$1.intern]
71
+ if res.kind_of?(Proc)
72
+ res = res.call(commit_info)
73
+ end
74
+ res
75
+ end
76
+ end
77
+
63
78
  # Runs comit hook handler using specified arguments.
64
79
  # @param [String] config_name Path to the application configuration file in YAML format.
65
80
  # @param [String] rev1 First specified revision.
@@ -117,6 +132,7 @@ module GitCommitNotifier
117
132
  # branch_name
118
133
  # slash_branch_name
119
134
  # commit_id (hash)
135
+ # description ('git describe' tag)
120
136
  # short_message
121
137
  # commit_number
122
138
  # commit_count
@@ -128,6 +144,7 @@ module GitCommitNotifier
128
144
  :branch_name => branch_name,
129
145
  :slash_branch_name => slash_branch_name,
130
146
  :commit_id => nil,
147
+ :description => lambda { |commit_info| Git.describe(commit_info[:commit]) },
131
148
  :message => nil,
132
149
  :commit_number => nil,
133
150
  :commit_count => nil,
@@ -162,13 +179,14 @@ module GitCommitNotifier
162
179
  :commit_count_phrase2 => diffresult.size == 1 ? "" : "#{diffresult.size} commits: "
163
180
  })
164
181
  subject_template = config['subject'] || "[${prefix}${slash_branch_name}] ${commit_count_phrase2}${message}"
165
- subject = subject_template.gsub(/\$\{(\w+)\}/) { |m| revised_subject_words[$1.intern] }
182
+ subject = get_subject(result[:commit_info], subject_template, revised_subject_words)
166
183
 
167
184
  emailer = Emailer.new(config,
168
185
  :project_path => project_path,
169
186
  :recipient => recipient,
170
187
  :from_address => config["from"] || result[:commit_info][:email],
171
188
  :from_alias => result[:commit_info][:author],
189
+ :reply_to_address => config["reply_to_author"] ? result[:commit_info][:email] : config["from"] || result[:commit_info][:email],
172
190
  :subject => subject,
173
191
  :date => result[:commit_info][:date],
174
192
  :text_message => text.join("------------------------------------------\n\n"),
@@ -179,6 +197,22 @@ module GitCommitNotifier
179
197
  :repo_name => repo_name
180
198
  )
181
199
  emailer.send
200
+
201
+ # WEBHOOK patch
202
+ unless config['webhook'].nil?
203
+ webhook = Webhook.new(config,
204
+ :committer => result[:commit_info][:author],
205
+ :email => result[:commit_info][:email],
206
+ :message => result[:commit_info][:message],
207
+ :subject => subject,
208
+ :changed => Git.split_status(rev1,rev2),
209
+ :old_rev => rev1,
210
+ :new_rev => rev2,
211
+ :ref_name => ref_name,
212
+ :repo_name => repo_name
213
+ )
214
+ webhook.send
215
+ end
182
216
  else
183
217
  commit_number = 1
184
218
  diff2html.diff_between_revisions(rev1, rev2, prefix, ref_name) do |count, result|
@@ -192,13 +226,14 @@ module GitCommitNotifier
192
226
  :commit_count_phrase2 => count == 1 ? "" : "#{count} commits: "
193
227
  })
194
228
  subject_template = config['subject'] || "[${prefix}${slash_branch_name}][${commit_number}/${commit_count}] ${message}"
195
- subject = subject_template.gsub(/\$\{(\w+)\}/) { |m| revised_subject_words[$1.intern] }
229
+ subject = get_subject(result[:commit_info], subject_template, revised_subject_words)
196
230
 
197
231
  emailer = Emailer.new(config,
198
232
  :project_path => project_path,
199
233
  :recipient => recipient,
200
234
  :from_address => config["from"] || result[:commit_info][:email],
201
235
  :from_alias => result[:commit_info][:author],
236
+ :reply_to_address => config["reply_to_author"] ? result[:commit_info][:email] : config["from"] || result[:commit_info][:email],
202
237
  :subject => subject,
203
238
  :date => result[:commit_info][:date],
204
239
  :text_message => result[:text_content],
@@ -209,6 +244,23 @@ module GitCommitNotifier
209
244
  :repo_name => repo_name
210
245
  )
211
246
  emailer.send
247
+
248
+ # WEBHOOK patch
249
+ unless config['webhook'].nil?
250
+ webhook = Webhook.new(config,
251
+ :committer => result[:commit_info][:author],
252
+ :email => result[:commit_info][:email],
253
+ :message => result[:commit_info][:message],
254
+ :subject => subject,
255
+ :changed => Git.split_status(rev1,rev2),
256
+ :old_rev => rev1,
257
+ :new_rev => rev2,
258
+ :ref_name => ref_name,
259
+ :repo_name => repo_name
260
+ )
261
+ webhook.send
262
+ end
263
+
212
264
  commit_number += 1
213
265
  end
214
266
  end
@@ -217,4 +269,3 @@ module GitCommitNotifier
217
269
  end
218
270
  end
219
271
  end
220
-
@@ -47,6 +47,7 @@ module GitCommitNotifier
47
47
  @lines_added = 0
48
48
  @file_added = false
49
49
  @file_removed = false
50
+ @file_changes = []
50
51
  @binary = false
51
52
  end
52
53
 
@@ -83,6 +84,11 @@ module GitCommitNotifier
83
84
  config['ignore_merge']
84
85
  end
85
86
 
87
+ # Gets show_summary setting from {#config}.
88
+ def show_summary?
89
+ config['show_summary']
90
+ end
91
+
86
92
  # Gets ignore_whitespace setting from {#config}.
87
93
  # @return [Boolean] true if whitespaces should be ignored in diff; otherwise false.
88
94
  def ignore_whitespaces?
@@ -200,7 +206,12 @@ module GitCommitNotifier
200
206
  end
201
207
 
202
208
  header = "#{op} #{binary}file #{file_name}"
203
- "<h2>#{header}</h2>\n"
209
+
210
+ if show_summary?
211
+ @file_changes << [ file_name, header ]
212
+ end
213
+
214
+ "<h2 id=\"#{file_name}\">#{header}</h2>\n"
204
215
  end
205
216
 
206
217
  # Determines are two lines are sequentially placed in diff (no skipped lines between).
@@ -356,24 +367,33 @@ module GitCommitNotifier
356
367
  end
357
368
 
358
369
  def extract_commit_info_from_git_show_output(content)
359
- result = { :message => [], :commit => '', :author => '', :date => '', :email => '',
360
- :committer => '', :commit_date => '', :committer_email => ''}
370
+ result = {
371
+ :message => [],
372
+ :commit => '',
373
+ :author => '',
374
+ :date => '',
375
+ :email => '',
376
+ :committer => '',
377
+ :commit_date => '',
378
+ :committer_email => ''
379
+ }
361
380
 
362
381
  message = []
363
382
  content.split("\n").each do |line|
364
- if line =~ /^diff/ # end of commit info
365
- break
366
- elsif line =~ /^commit /
383
+ break if line =~ /^diff/ # end of commit info
384
+
385
+ case line
386
+ when /^commit /
367
387
  result[:commit] = line[7..-1]
368
- elsif line =~ /^Author:/
388
+ when /^Author:/
369
389
  result[:author], result[:email] = author_name_and_email(line[12..-1])
370
- elsif line =~ /^AuthorDate:/
390
+ when /^AuthorDate:/
371
391
  result[:date] = line[12..-1]
372
- elsif line =~ /^Commit:/
392
+ when /^Commit:/
373
393
  result[:committer], result[:commit_email] = author_name_and_email(line[12..-1])
374
- elsif line =~ /^CommitDate:/
394
+ when /^CommitDate:/
375
395
  result[:commit_date] = line[12..-1]
376
- elsif line =~ /^Merge:/
396
+ when /^Merge:/
377
397
  result[:merge] = line[7..-1]
378
398
  else
379
399
  message << line.strip
@@ -398,7 +418,7 @@ module GitCommitNotifier
398
418
 
399
419
  def author_name_and_email(info)
400
420
  # input string format: "autor name <author@email.net>"
401
- return [$1, $2] if info =~ /^([^\<]+)\s+\<\s*(.*)\s*\>\s*$/ # normal operation
421
+ return [$1, $2] if info =~ /^([^\<]+)\s+\<\s*(.*)\s*\>\s*$/ # normal operation
402
422
  # incomplete author info - return it as author name
403
423
  [info, '']
404
424
  end
@@ -523,15 +543,32 @@ module GitCommitNotifier
523
543
 
524
544
  multi_line_message = commit_info[:message].count > 1
525
545
  title += "<dt>Message</dt><dd class='#{multi_line_message ? "multi-line" : ""}'>#{message_array_as_html(commit_info[:message])}</dd>\n"
526
-
527
546
  title += "</dl>"
528
547
 
529
- text = "#{raw_diff}"
548
+ @file_changes = []
549
+ text = ""
550
+
551
+ html_diff = diff_for_revision(extract_diff_from_git_show_output(raw_diff))
552
+ message_array = message_array_as_html(changed_files.split("\n"))
553
+
554
+ if show_summary? and @file_changes.respond_to?("each")
555
+ title += "<ul>"
556
+
557
+ @file_changes.each do |file_name, header|
558
+ title += "<li><a href=\"\##{file_name}\">#{header}</a></li>"
559
+ text += "#{header}\n"
560
+ end
561
+
562
+ title += "</ul>"
563
+ text += "\n"
564
+ end
565
+
566
+ text += "#{raw_diff}"
530
567
  text += "#{changed_files}\n\n\n"
531
568
 
532
569
  html = title
533
- html += diff_for_revision(extract_diff_from_git_show_output(raw_diff))
534
- html += message_array_as_html(changed_files.split("\n"))
570
+ html += html_diff
571
+ html += message_array
535
572
  html += "<br /><br />"
536
573
  commit_info[:message] = first_sentence(commit_info[:message])
537
574
 
@@ -750,4 +787,3 @@ module GitCommitNotifier
750
787
  end
751
788
  end
752
789
  end
753
-
@@ -181,6 +181,7 @@ class GitCommitNotifier::Emailer
181
181
  to_tag = config['delivery_method'] == 'nntp' ? 'Newsgroups' : 'To'
182
182
  quoted_from_alias = !@from_alias.nil? ? quote_if_necessary("#{@from_alias}",'utf-8') : nil
183
183
  from = (@from_alias.nil? || @from_alias.empty?) ? @from_address : "#{quoted_from_alias} <#{@from_address}>"
184
+ reply_to = (@from_alias.nil? || !config['reply_to_author']) ? @reply_to_address : "#{@from_alias} <#{@reply_to_address}>"
184
185
 
185
186
  plaintext = if config['add_plaintext'].nil? || config['add_plaintext']
186
187
  @text_message
@@ -190,6 +191,7 @@ class GitCommitNotifier::Emailer
190
191
 
191
192
  content = []
192
193
  content << "From: #{from}" unless from.nil?
194
+ content << "Reply-To: #{reply_to}" unless reply_to.nil?
193
195
 
194
196
  # Setting the email date from the commit date is undesired by those
195
197
  # who sort their email by send date instead of receive date
@@ -1,7 +1,5 @@
1
1
  # -*- coding: utf-8; mode: ruby; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- vim:fenc=utf-8:filetype=ruby:et:sw=2:ts=2:sts=2
2
2
 
3
- require 'set'
4
-
5
3
  # Git methods
6
4
  class GitCommitNotifier::Git
7
5
  class << self
@@ -40,6 +38,14 @@ class GitCommitNotifier::Git
40
38
  from_shell("git show #{rev.strip}#{gitopt}")
41
39
  end
42
40
 
41
+ # Runs `git describe'
42
+ # @return [String] Its output
43
+ # @see from_shell
44
+ # @param [String] rev Revision
45
+ def describe(rev)
46
+ from_shell("git describe --always #{rev.strip}").strip
47
+ end
48
+
43
49
  # Runs `git log`
44
50
  # @note uses "--pretty=fuller" option.
45
51
  # @return [String] Its output
@@ -51,7 +57,7 @@ class GitCommitNotifier::Git
51
57
  end
52
58
 
53
59
  # Runs `git log` and extract filenames only
54
- # @note uses "--pretty=fuller" and "--name-status" options.
60
+ # @note uses "--pretty=oneline" and "--name-status" options.
55
61
  # @return [Array(String)] File names
56
62
  # @see lines_from_shell
57
63
  # @param [String] rev1 First revision
@@ -62,6 +68,18 @@ class GitCommitNotifier::Git
62
68
  lines.uniq
63
69
  end
64
70
 
71
+ # splits the output of changed_files
72
+ # @return [Hash(Array)] file names sorted by status
73
+ # @see changed_files
74
+ # @param [Array(String)] lines
75
+ def split_status(rev1, rev2)
76
+ lines = changed_files(rev1, rev2)
77
+ modified = lines.map { |l| l.gsub(/M\s/,'').strip if l[0,1] == 'M' }.select { |l| !l.nil? }
78
+ added = lines.map { |l| l.gsub(/A\s/,'').strip if l[0,1] == 'A' }.select { |l| !l.nil? }
79
+ deleted = lines.map { |l| l.gsub(/D\s/,'').strip if l[0,1] == 'D' }.select { |l| !l.nil? }
80
+ return { :m => modified, :a => added, :d => deleted }
81
+ end
82
+
65
83
  def branch_commits(treeish)
66
84
  args = branch_heads - [ branch_head(treeish) ]
67
85
  args.map! { |tree| "^#{tree}" }
@@ -90,7 +108,7 @@ class GitCommitNotifier::Git
90
108
  def new_commits(oldrev, newrev, refname, unique_to_current_branch)
91
109
  # We want to get the set of commits (^B1 ^B2 ... ^oldrev newrev)
92
110
  # Where B1, B2, ..., are any other branch
93
- s = Set.new
111
+ a = Array.new
94
112
 
95
113
  # If we want to include only those commits that are
96
114
  # unique to this branch, then exclude commits that occur on
@@ -98,23 +116,23 @@ class GitCommitNotifier::Git
98
116
  if unique_to_current_branch
99
117
  # Make a set of all branches, not'd (^BCURRENT ^B1 ^B2...)
100
118
  not_branches = lines_from_shell("git rev-parse --not --branches")
101
- s.merge(not_branches.to_a.map { |l| l.chomp }.to_set)
119
+ a = not_branches.map { |l| l.chomp }
102
120
 
103
121
  # Remove the current branch (^BCURRENT) from the set
104
122
  current_branch = rev_parse(refname)
105
- s.delete("^#{current_branch}")
123
+ a.delete_at a.index("^#{current_branch}") unless a.index("^#{current_branch}").nil?
106
124
  end
107
125
 
108
126
  # Add not'd oldrev (^oldrev)
109
- s.add("^#{oldrev}") unless oldrev =~ /^0+$/
127
+ a.push("^#{oldrev}") unless oldrev =~ /^0+$/
110
128
 
111
129
  # Add newrev
112
- s.add(newrev)
130
+ a.push(newrev)
113
131
 
114
132
  # We should now have ^B1... ^oldrev newrev
115
133
 
116
134
  # Get all the commits that match that specification
117
- lines = lines_from_shell("git rev-list --reverse #{s.to_a.join(' ')}")
135
+ lines = lines_from_shell("git rev-list --reverse #{a.join(' ')}")
118
136
  commits = lines.to_a.map { |l| l.chomp }
119
137
  end
120
138
 
@@ -0,0 +1,49 @@
1
+ # -*- coding: utf-8; mode: ruby; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- vim:fenc=utf-8:filetype=ruby:et:sw=2:ts=2:sts=2
2
+
3
+ require "yajl"
4
+ require "uri"
5
+ require "cgi"
6
+ require "net/http"
7
+
8
+ class GitCommitNotifier::Webhook
9
+
10
+ PARAMETERS = %w(committer email message subject changed old_rev new_rev ref_name repo_name)
11
+ attr_accessor :config
12
+
13
+ def initialize(config, options = {})
14
+ @config = config || {}
15
+ PARAMETERS.each do |name|
16
+ instance_variable_set("@#{name}".to_sym, options[name.to_sym])
17
+ end
18
+ end
19
+
20
+ def payload
21
+ pay = {
22
+ 'repository' => {
23
+ 'name' => @repo_name
24
+ },
25
+ 'ref' => @ref_name,
26
+ 'before' => @old_rev,
27
+ 'after' => @new_rev,
28
+ 'commits' => [
29
+ {
30
+ 'added' => @changed[:a],
31
+ 'modified' => @changed[:m],
32
+ 'removed' => @changed[:d],
33
+ 'committer' => {
34
+ 'name' => @committer,
35
+ 'email' => @email
36
+ },
37
+ 'message' => CGI::escape(@message)
38
+ }
39
+ ]
40
+ }
41
+ Yajl::Encoder.encode(pay)
42
+ end
43
+
44
+ def send
45
+ Net::HTTP.post_form(URI.parse(@config['webhook']['url']), { 'payload' => payload })
46
+ nil
47
+ end
48
+
49
+ end
@@ -4,6 +4,7 @@ require 'git_commit_notifier/commit_hook'
4
4
  require 'git_commit_notifier/diff_to_html'
5
5
  require 'git_commit_notifier/diff_callback'
6
6
  require 'git_commit_notifier/emailer'
7
+ require 'git_commit_notifier/webhook'
7
8
  require 'git_commit_notifier/escape_helper'
8
9
  require 'git_commit_notifier/git'
9
10
  require 'git_commit_notifier/logger'
@@ -80,6 +80,7 @@ describe GitCommitNotifier::CommitHook do
80
80
  mock(GitCommitNotifier::Git).changed_files('7e4f6b4', '4f13525') { [] }
81
81
  REVISIONS.each do |rev|
82
82
  mock(GitCommitNotifier::Git).show(rev, :ignore_whitespaces => true) { IO.read(FIXTURES_PATH + "git_show_#{rev}") }
83
+ dont_allow(GitCommitNotifier::Git).describe(rev) { IO.read(FIXTURES_PATH + "git_describe_#{rev}") }
83
84
  end
84
85
  end
85
86
 
@@ -133,7 +134,17 @@ describe GitCommitNotifier::CommitHook do
133
134
  mock(GitCommitNotifier::CommitHook).config { { 'include_branches' => 'test, me, yourself' } }
134
135
  GitCommitNotifier::CommitHook.include_branches.should == %w(test me yourself)
135
136
  end
137
+ end
136
138
 
139
+ describe :get_subject do
140
+ it "should run lambda if specified in mapping" do
141
+ mock(GitCommitNotifier::Git).describe("commit_id") { "yo" }
142
+ GitCommitNotifier::CommitHook.get_subject(
143
+ { :commit => "commit_id" },
144
+ "${description}",
145
+ { :description => lambda { |commit_info| GitCommitNotifier::Git.describe(commit_info[:commit]) } }
146
+ ).should == "yo"
147
+ end
137
148
  end
138
149
 
139
150
  end
@@ -101,13 +101,13 @@ describe GitCommitNotifier::DiffToHtml do
101
101
  end
102
102
 
103
103
  it "multiple commits" do
104
-
105
104
  mock(GitCommitNotifier::Git).changed_files('7e4f6b4', '4f13525') { [] }
106
105
  mock(GitCommitNotifier::Git).rev_type(REVISIONS.first) { "commit" }
107
106
  mock(GitCommitNotifier::Git).rev_type(REVISIONS.last) { "commit" }
108
107
  mock(GitCommitNotifier::Git).new_commits(anything, anything, anything, anything) { REVISIONS.reverse }
109
108
  REVISIONS.each do |rev|
110
109
  mock(GitCommitNotifier::Git).show(rev, :ignore_whitespaces => true) { IO.read(FIXTURES_PATH + 'git_show_' + rev) }
110
+ dont_allow(GitCommitNotifier::Git).describe(rev) { IO.read(FIXTURES_PATH + 'git_describe_' + rev) }
111
111
  end
112
112
 
113
113
  diff = GitCommitNotifier::DiffToHtml.new
@@ -162,6 +162,7 @@ describe GitCommitNotifier::DiffToHtml do
162
162
  mock(GitCommitNotifier::Git).new_commits(anything, anything, anything, anything) { [ 'ff037a73fc1094455e7bbf506171a3f3cf873ae6' ] }
163
163
  %w[ ff037a73fc1094455e7bbf506171a3f3cf873ae6 ].each do |rev|
164
164
  mock(GitCommitNotifier::Git).show(rev, :ignore_whitespaces => true) { IO.read(FIXTURES_PATH + 'git_show_' + rev) }
165
+ dont_allow(GitCommitNotifier::Git).describe(rev) { IO.read(FIXTURES_PATH + 'git_describe_' + rev) }
165
166
  end
166
167
  diff = GitCommitNotifier::DiffToHtml.new
167
168
  diff.diff_between_revisions(first_rev, last_rev, 'tm-admin', 'refs/heads/rvm')
@@ -32,6 +32,14 @@ describe GitCommitNotifier::Git do
32
32
  end
33
33
  end
34
34
 
35
+ describe :describe do
36
+ it "should strip given description" do
37
+ expected = 'some descriptio'
38
+ mock(GitCommitNotifier::Git).from_shell("git describe --always #{SAMPLE_REV}") { "#{expected}\n" }
39
+ GitCommitNotifier::Git.describe(SAMPLE_REV).should == expected
40
+ end
41
+ end
42
+
35
43
  describe :branch_heads do
36
44
  before(:each) do
37
45
  mock(GitCommitNotifier::Git).from_shell("git rev-parse --branches") { "some\npopular\ntext\n" }
@@ -94,6 +102,17 @@ describe GitCommitNotifier::Git do
94
102
  end
95
103
  end
96
104
 
105
+ describe :new_empty_branch do
106
+ it "should commit an empty branch and output nothing" do
107
+ mock(GitCommitNotifier::Git).from_shell("git rev-parse --not --branches") {
108
+ "^#{SAMPLE_REV}\n^#{SAMPLE_REV}\n^#{SAMPLE_REV_2}" }
109
+ mock(GitCommitNotifier::Git).rev_parse("refs/heads/branch2") { SAMPLE_REV }
110
+ stub(GitCommitNotifier::Git).from_shell("git rev-list --reverse #{SAMPLE_REV} ^#{SAMPLE_REV_2}") { SAMPLE_REV }
111
+ mock(GitCommitNotifier::Git).from_shell("git rev-list --reverse ^#{SAMPLE_REV} ^#{SAMPLE_REV_2} #{SAMPLE_REV}") { "" }
112
+ GitCommitNotifier::Git.new_commits("0000000000000000000000000000000000000000", SAMPLE_REV, "refs/heads/branch2", true).should == []
113
+ end
114
+ end
115
+
97
116
  describe :changed_files do
98
117
  it "should run git log --name-status --oneline with given args and strip out the result" do
99
118
  files = ["M README.rdoc\n",
@@ -103,4 +122,18 @@ describe GitCommitNotifier::Git do
103
122
  GitCommitNotifier::Git.changed_files(SAMPLE_REV, SAMPLE_REV_2).should == files
104
123
  end
105
124
  end
125
+
126
+ describe :split_status do
127
+ it "should split list of changed files in a hash indexed with statuses" do
128
+ files = ["M README.rdoc\n",
129
+ "D git_commit_notifier/Rakefile\n",
130
+ "M post-receive\n"]
131
+ mock(GitCommitNotifier::Git).from_shell("git log #{SAMPLE_REV}..#{SAMPLE_REV_2} --name-status --pretty=oneline" ) { IO.read(FIXTURES_PATH + 'git_log_name_status') }
132
+ output = GitCommitNotifier::Git.split_status(SAMPLE_REV, SAMPLE_REV_2)
133
+ output[:m].should == [ 'README.rdoc', 'post-receive' ]
134
+ output[:d].should == [ 'git_commit_notifier/Rakefile' ]
135
+ end
136
+ end
137
+
138
+
106
139
  end
@@ -0,0 +1,45 @@
1
+ # -*- coding: utf-8; mode: ruby; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- vim:fenc=utf-8:filetype=ruby:et:sw=2:ts=2:sts=2
2
+
3
+ require File.expand_path('../../../spec_helper', __FILE__)
4
+
5
+ require 'git_commit_notifier'
6
+
7
+ describe GitCommitNotifier::Emailer do
8
+ describe :new do
9
+ it "should assign config if given" do
10
+ GitCommitNotifier::Webhook.new({:a => :b}).config[:a].should == :b
11
+ end
12
+
13
+ it "should use empty hash unless config given" do
14
+ cfg = GitCommitNotifier::Webhook.new(false).config
15
+ cfg.should be_kind_of(Hash)
16
+ cfg.should be_empty
17
+ end
18
+
19
+ it "should assign parameters from options" do
20
+ options = {}
21
+ GitCommitNotifier::Webhook::PARAMETERS.each do |name|
22
+ options[name.to_sym] = Faker::Lorem.sentence
23
+ end
24
+ webhook = GitCommitNotifier::Webhook.new({}, options)
25
+ options.each_pair do |key, value|
26
+ webhook.instance_variable_get("@#{key}").should == value
27
+ end
28
+ end
29
+ end
30
+
31
+ describe :payload do
32
+ it "should produce a valid json payload" do
33
+ options = {}
34
+ GitCommitNotifier::Webhook::PARAMETERS.each do |name|
35
+ options[name.to_sym] = Faker::Lorem.sentence
36
+ end
37
+ options[:changed] = { :a => [], :m => [], :d => [] }
38
+ options[:committer] = "tester"
39
+ webhook = GitCommitNotifier::Webhook.new({}, options)
40
+ payload = Yajl::Parser.parse(webhook.payload)
41
+ payload['commits'][0]['committer']['name'].should == "tester"
42
+ end
43
+ end
44
+
45
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: git-commit-notifier
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.11.4
4
+ version: 0.11.5
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2012-04-24 00:00:00.000000000 Z
13
+ date: 2012-07-18 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: diff-lcs
@@ -88,6 +88,22 @@ dependencies:
88
88
  - - ~>
89
89
  - !ruby/object:Gem::Version
90
90
  version: '1.4'
91
+ - !ruby/object:Gem::Dependency
92
+ name: yajl-ruby
93
+ requirement: !ruby/object:Gem::Requirement
94
+ none: false
95
+ requirements:
96
+ - - ~>
97
+ - !ruby/object:Gem::Version
98
+ version: '1.0'
99
+ type: :runtime
100
+ prerelease: false
101
+ version_requirements: !ruby/object:Gem::Requirement
102
+ none: false
103
+ requirements:
104
+ - - ~>
105
+ - !ruby/object:Gem::Version
106
+ version: '1.0'
91
107
  - !ruby/object:Gem::Dependency
92
108
  name: rake
93
109
  requirement: !ruby/object:Gem::Requirement
@@ -203,7 +219,7 @@ dependencies:
203
219
  requirements:
204
220
  - - ~>
205
221
  - !ruby/object:Gem::Version
206
- version: 0.9.5
222
+ version: '1.0'
207
223
  type: :development
208
224
  prerelease: false
209
225
  version_requirements: !ruby/object:Gem::Requirement
@@ -211,7 +227,7 @@ dependencies:
211
227
  requirements:
212
228
  - - ~>
213
229
  - !ruby/object:Gem::Version
214
- version: 0.9.5
230
+ version: '1.0'
215
231
  - !ruby/object:Gem::Dependency
216
232
  name: yard
217
233
  requirement: !ruby/object:Gem::Requirement
@@ -219,7 +235,7 @@ dependencies:
219
235
  requirements:
220
236
  - - ~>
221
237
  - !ruby/object:Gem::Version
222
- version: 0.7.5
238
+ version: 0.8.1
223
239
  type: :development
224
240
  prerelease: false
225
241
  version_requirements: !ruby/object:Gem::Requirement
@@ -227,7 +243,7 @@ dependencies:
227
243
  requirements:
228
244
  - - ~>
229
245
  - !ruby/object:Gem::Version
230
- version: 0.7.5
246
+ version: 0.8.1
231
247
  - !ruby/object:Gem::Dependency
232
248
  name: redcarpet
233
249
  requirement: !ruby/object:Gem::Requirement
@@ -235,7 +251,7 @@ dependencies:
235
251
  requirements:
236
252
  - - ~>
237
253
  - !ruby/object:Gem::Version
238
- version: 1.17.2
254
+ version: '2.1'
239
255
  type: :development
240
256
  prerelease: false
241
257
  version_requirements: !ruby/object:Gem::Requirement
@@ -243,7 +259,7 @@ dependencies:
243
259
  requirements:
244
260
  - - ~>
245
261
  - !ruby/object:Gem::Version
246
- version: 1.17.2
262
+ version: '2.1'
247
263
  description: This git commit notifier sends html mails with nice diffs for every changed
248
264
  file.
249
265
  email: bodo@bitboxer.de
@@ -276,12 +292,19 @@ files:
276
292
  - lib/git_commit_notifier/git.rb
277
293
  - lib/git_commit_notifier/logger.rb
278
294
  - lib/git_commit_notifier/result_processor.rb
295
+ - lib/git_commit_notifier/webhook.rb
279
296
  - local-run.rb
280
297
  - spec/fixtures/existing_file_one_line.txt
281
298
  - spec/fixtures/git-notifier-group-email-by-push.yml
282
299
  - spec/fixtures/git-notifier-ignore-merge.yml
283
300
  - spec/fixtures/git-notifier-with-branch-restrictions.yml
284
301
  - spec/fixtures/git-notifier-with-merge.yml
302
+ - spec/fixtures/git_describe_055850e7d925110322b8db4e17c3b840d76e144c
303
+ - spec/fixtures/git_describe_51b986619d88f7ba98be7d271188785cbbb541a0
304
+ - spec/fixtures/git_describe_a4629e707d80a5769f7a71ca6ed9471015e14dc9
305
+ - spec/fixtures/git_describe_dce6ade4cdc2833b53bd600ef10f9bce83c7102d
306
+ - spec/fixtures/git_describe_e28ad77bba0574241e6eb64dfd0c1291b221effe
307
+ - spec/fixtures/git_describe_ff037a73fc1094455e7bbf506171a3f3cf873ae6
285
308
  - spec/fixtures/git_log
286
309
  - spec/fixtures/git_log_name_status
287
310
  - spec/fixtures/git_show_055850e7d925110322b8db4e17c3b840d76e144c
@@ -297,6 +320,7 @@ files:
297
320
  - spec/lib/git_commit_notifier/git_spec.rb
298
321
  - spec/lib/git_commit_notifier/logger_spec.rb
299
322
  - spec/lib/git_commit_notifier/result_processor_spec.rb
323
+ - spec/lib/git_commit_notifier/webhook_spec.rb
300
324
  - spec/spec_helper.rb
301
325
  - template/email.html.erb
302
326
  - template/styles.css
@@ -320,30 +344,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
320
344
  version: '0'
321
345
  requirements: []
322
346
  rubyforge_project:
323
- rubygems_version: 1.8.23
347
+ rubygems_version: 1.8.24
324
348
  signing_key:
325
349
  specification_version: 3
326
350
  summary: Sends git commit messages with diffs
327
- test_files:
328
- - spec/fixtures/existing_file_one_line.txt
329
- - spec/fixtures/git-notifier-group-email-by-push.yml
330
- - spec/fixtures/git-notifier-ignore-merge.yml
331
- - spec/fixtures/git-notifier-with-branch-restrictions.yml
332
- - spec/fixtures/git-notifier-with-merge.yml
333
- - spec/fixtures/git_log
334
- - spec/fixtures/git_log_name_status
335
- - spec/fixtures/git_show_055850e7d925110322b8db4e17c3b840d76e144c
336
- - spec/fixtures/git_show_51b986619d88f7ba98be7d271188785cbbb541a0
337
- - spec/fixtures/git_show_a4629e707d80a5769f7a71ca6ed9471015e14dc9
338
- - spec/fixtures/git_show_dce6ade4cdc2833b53bd600ef10f9bce83c7102d
339
- - spec/fixtures/git_show_e28ad77bba0574241e6eb64dfd0c1291b221effe
340
- - spec/fixtures/git_show_ff037a73fc1094455e7bbf506171a3f3cf873ae6
341
- - spec/fixtures/new_file_one_line.txt
342
- - spec/lib/git_commit_notifier/commit_hook_spec.rb
343
- - spec/lib/git_commit_notifier/diff_to_html_spec.rb
344
- - spec/lib/git_commit_notifier/emailer_spec.rb
345
- - spec/lib/git_commit_notifier/git_spec.rb
346
- - spec/lib/git_commit_notifier/logger_spec.rb
347
- - spec/lib/git_commit_notifier/result_processor_spec.rb
348
- - spec/spec_helper.rb
351
+ test_files: []
349
352
  has_rdoc: