git-commit-notifier 0.11.11 → 0.12.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.
data/CHANGES.md CHANGED
@@ -2,6 +2,11 @@
2
2
 
3
3
  ## Not yet released
4
4
 
5
+ ## Version 0.12.0
6
+
7
+ * Detects renamed files.
8
+ * Fudge email send date to ensure ordering of commit messages.
9
+
5
10
  ## Version 0.11.11
6
11
 
7
12
  * Allow per branch mailing lists.
data/Gemfile CHANGED
@@ -8,3 +8,5 @@ gem "ripper", :group => :development, :platforms => :mri_18
8
8
 
9
9
  gem "coveralls", :require => false, :platforms => [:mri_19, :mri_20], :group => :development
10
10
 
11
+ gem "nokogiri", "~> 1.5.0", :platforms => :mri_18
12
+
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.11.11
1
+ 0.12.0
@@ -217,6 +217,14 @@ ignore_whitespace: all
217
217
  # webooks:
218
218
  # url: http://example.com:8081/commits
219
219
 
220
+ # Adding the similarity detection threshold parameter used by the -M flag when detecting renames
221
+ #
222
+ # The value is a number between 0 and 1
223
+ # with 0 signifying 0% and 1 signifying 100%.
224
+ # The Default value is 0.5, meaning, git will consider a delete/add pair as a rename if
225
+ # more than 50% of it has not changed
226
+ similarity_detection_threshold: "0.5"
227
+
220
228
  # This is developer debugging options. Do not uncomment it if You aren't Jedi
221
229
  # debug:
222
230
  # enabled: true
@@ -95,6 +95,11 @@ module GitCommitNotifier
95
95
  # @return [NilClass] nil
96
96
  # @see config
97
97
  def run(config_name, rev1, rev2, ref_name)
98
+
99
+ if @start_time.nil?
100
+ @start_time = Time.new
101
+ @start_time_offset = 0
102
+ end
98
103
 
99
104
  # Load the configuration
100
105
  if File.exists?(config_name)
@@ -214,7 +219,9 @@ module GitCommitNotifier
214
219
  :from_alias => result[:commit_info][:author],
215
220
  :reply_to_address => config["reply_to_author"] ? result[:commit_info][:email] : config["from"] || result[:commit_info][:email],
216
221
  :subject => subject,
217
- :date => result[:commit_info][:date],
222
+ :commit_date => result[:commit_info][:date],
223
+ :current_date => Time.new.rfc2822,
224
+ :offset_date => (@start_time + @start_time_offset).rfc2822,
218
225
  :text_message => text.join("------------------------------------------\n\n"),
219
226
  :html_message => html.join("<hr /><br />"),
220
227
  :old_rev => rev1,
@@ -238,6 +245,8 @@ module GitCommitNotifier
238
245
  :repo_name => repo_name
239
246
  )
240
247
  webhook.send
248
+
249
+ @start_time_offset += 1
241
250
  end
242
251
  else
243
252
  commit_number = 1
@@ -261,7 +270,9 @@ module GitCommitNotifier
261
270
  :from_alias => result[:commit_info][:author],
262
271
  :reply_to_address => config["reply_to_author"] ? result[:commit_info][:email] : config["from"] || result[:commit_info][:email],
263
272
  :subject => subject,
264
- :date => result[:commit_info][:date],
273
+ :commit_date => result[:commit_info][:date],
274
+ :current_date => Time.new.rfc2822,
275
+ :offset_date => (@start_time + @start_time_offset).rfc2822,
265
276
  :text_message => result[:text_content],
266
277
  :html_message => result[:html_content],
267
278
  :old_rev => rev1,
@@ -288,6 +299,8 @@ module GitCommitNotifier
288
299
  end
289
300
 
290
301
  commit_number += 1
302
+
303
+ @start_time_offset += 1
291
304
  end
292
305
  end
293
306
  nil
@@ -28,7 +28,7 @@ module GitCommitNotifier
28
28
  return m unless match
29
29
  r = { :phrase => match[1] }
30
30
  captures = match[2].split(/[\s\&\,]+/).map { |m| (m =~ /(\d+)/) ? $1 : m }.reject { |c| c.empty? }
31
- r[:links] = captures.map { |mn| { :title => "##{mn}", :url => "#{url}/issues/show/#{mn}" } }
31
+ r[:links] = captures.map { |mn| { :title => "##{mn}", :url => "#{url}/issues/#{mn}" } }
32
32
  r
33
33
  end },
34
34
  :bugzilla => { :search_for => /\bBUG\s*(\d+)/i, :replace_with => '#{url}/show_bug.cgi?id=\1' },
@@ -47,6 +47,9 @@ module GitCommitNotifier
47
47
  @lines_added = 0
48
48
  @file_added = false
49
49
  @file_removed = false
50
+ @file_renamed = false
51
+ @file_renamed_old_name = false
52
+ @file_renamed_new_name = false
50
53
  @file_changes = []
51
54
  @binary = false
52
55
  unless String.method_defined?(:encode!)
@@ -184,6 +187,8 @@ module GitCommitNotifier
184
187
  "Deleted"
185
188
  elsif @file_added
186
189
  "Added"
190
+ elsif @file_renamed
191
+ "Renamed"
187
192
  else
188
193
  "Changed"
189
194
  end
@@ -247,8 +252,15 @@ module GitCommitNotifier
247
252
 
248
253
  @lines_added = 0
249
254
  @diff_result << operation_description
250
- if !@diff_lines.empty? && !@too_many_files
255
+
256
+ if (@file_renamed || !@diff_lines.empty?) && (!@too_many_files)
251
257
  @diff_result << '<table>'
258
+
259
+ ##Adds a ROW in the table for the File Rename Details (if at all present)
260
+ if @file_renamed
261
+ @diff_result << "<tr class='renamed'>\n<td class='ln'>&nbsp;</td><td class='ln'></td><td>&nbsp;<u>#{@file_renamed_old_name}</u> was renamed to <u>#{@file_renamed_new_name}</u></td></tr>"
262
+ end
263
+
252
264
  removals = []
253
265
  additions = []
254
266
 
@@ -290,6 +302,9 @@ module GitCommitNotifier
290
302
  @left_ln = nil
291
303
  @file_added = false
292
304
  @file_removed = false
305
+ @file_renamed = false
306
+ @file_renamed_old_name = false
307
+ @file_renamed_new_name = false
293
308
  @binary = false
294
309
  end
295
310
 
@@ -366,6 +381,11 @@ module GitCommitNotifier
366
381
  elsif line =~ /\/dev\/null differ/ # Binary files ... and /dev/null differ (removal)
367
382
  @binary = true
368
383
  @file_removed = true
384
+ elsif line =~ /^rename from (.*)/
385
+ @file_renamed = true
386
+ @file_renamed_old_name = line.scan(/^rename from (.*)/)[0][0].to_s
387
+ elsif line =~ /^rename to (.*)/
388
+ @file_renamed_new_name = line.scan(/^rename to (.*)/)[0][0].to_s
369
389
  elsif op == '@'
370
390
  @left_ln, @right_ln = range_info(line)
371
391
  end
@@ -9,7 +9,7 @@ class GitCommitNotifier::Emailer
9
9
  # Default ERB template file path
10
10
  TEMPLATE = File.join(File.dirname(__FILE__), *'../../template/email.html.erb'.split('/')).freeze
11
11
  # Instance variable names
12
- PARAMETERS = %w[project_path recipient from_address from_alias reply_to_address date subject text_message html_message repo_name ref_name old_rev new_rev].freeze
12
+ PARAMETERS = %w[project_path recipient from_address from_alias reply_to_address commit_date current_date offset_date subject text_message html_message repo_name ref_name old_rev new_rev].freeze
13
13
 
14
14
  # Gets config.
15
15
  # @return [Hash] Configuration
@@ -194,11 +194,19 @@ class GitCommitNotifier::Emailer
194
194
  content << "Reply-To: #{reply_to}" unless reply_to.nil?
195
195
 
196
196
  # Setting the email date from the commit date is undesired by those
197
- # who sort their email by send date instead of receive date
198
- #content << "Date: #{@date}" if !@date.nil?
197
+ # who sort their email by send date instead of receive date.
198
+ # We currently use @offset_date, which starts with the time the notifier was started,
199
+ # and adds a second of time per commit. This should result in the commits arriving
200
+ # in order by their processing sequence, even when they are all processed within the
201
+ # same second
202
+ #date = @commit_date # Date of the commit
203
+ #date = @current_date # Date we processed this commit
204
+ date = @offset_date # Date notifier started, plus 1 second per commit processed
205
+ date = Time.new.rfc2822 if date.nil? # Fallback to current date if date is nil
199
206
 
200
207
  content.concat [
201
208
  "#{to_tag}: #{quote_if_necessary(@recipient, 'utf-8')}",
209
+ "Date: #{date}",
202
210
  "Subject: #{quote_if_necessary(@subject, 'utf-8')}",
203
211
  "X-Mailer: git-commit-notifier",
204
212
  "X-Git-Repository: #{@repo_name}",
@@ -25,7 +25,7 @@ class GitCommitNotifier::Git
25
25
  end
26
26
 
27
27
  # Runs `git show`
28
- # @note uses "--pretty=fuller" option.
28
+ # @note uses "--pretty=fuller" and "-M" option.
29
29
  # @return [String] Its output
30
30
  # @see from_shell
31
31
  # @param [String] rev Revision
@@ -34,6 +34,7 @@ class GitCommitNotifier::Git
34
34
  def show(rev, opts = {})
35
35
  gitopt = " --date=rfc2822"
36
36
  gitopt += " --pretty=fuller"
37
+ gitopt += " -M#{GitCommitNotifier::CommitHook.config['similarity_detection_threshold'] || "0.5"}"
37
38
  gitopt += " -w" if opts[:ignore_whitespace] == 'all'
38
39
  gitopt += " -b" if opts[:ignore_whitespace] == 'change'
39
40
  from_shell("git show #{rev.strip}#{gitopt}")
@@ -58,13 +59,13 @@ class GitCommitNotifier::Git
58
59
  end
59
60
 
60
61
  # Runs `git log` and extract filenames only
61
- # @note uses "--pretty=oneline" and "--name-status" options.
62
+ # @note uses "--pretty=oneline" and "--name-status" and "-M" options.
62
63
  # @return [Array(String)] File names
63
64
  # @see lines_from_shell
64
65
  # @param [String] rev1 First revision
65
66
  # @param [String] rev2 Second revision
66
67
  def changed_files(rev1, rev2)
67
- lines = lines_from_shell("git log #{rev1}..#{rev2} --name-status --pretty=oneline")
68
+ lines = lines_from_shell("git log #{rev1}..#{rev2} --name-status --pretty=oneline -M#{GitCommitNotifier::CommitHook.config['similarity_detection_threshold'] || "0.5"}")
68
69
  lines = lines.select {|line| line =~ /^\w{1}\s+\w+/} # grep out only filenames
69
70
  lines.uniq
70
71
  end
@@ -79,7 +80,8 @@ class GitCommitNotifier::Git
79
80
  modified = lines.map { |l| l.gsub(/M\s/,'').strip if l[0,1] == 'M' }.select { |l| !l.nil? }
80
81
  added = lines.map { |l| l.gsub(/A\s/,'').strip if l[0,1] == 'A' }.select { |l| !l.nil? }
81
82
  deleted = lines.map { |l| l.gsub(/D\s/,'').strip if l[0,1] == 'D' }.select { |l| !l.nil? }
82
- { :m => modified, :a => added, :d => deleted }
83
+ renamed = lines.map { |l| l.gsub(/R\d+\s/,'').strip if l[0,1] == 'R' }.select { |l| !l.nil? }
84
+ { :m => modified, :a => added, :d => deleted , :r => renamed}
83
85
  end
84
86
 
85
87
  def branch_commits(treeish)
@@ -30,6 +30,7 @@ class GitCommitNotifier::Webhook
30
30
  'added' => @changed[:a],
31
31
  'modified' => @changed[:m],
32
32
  'removed' => @changed[:d],
33
+ 'renamed' => @changed[:r],
33
34
  'committer' => {
34
35
  'name' => @committer,
35
36
  'email' => @email
@@ -206,7 +206,7 @@ describe GitCommitNotifier::DiffToHtml do
206
206
  'mediawiki' => 'http://example.com/wiki', # will rework [[text]] to MediaWiki pages
207
207
  'redmine' => 'http://redmine.example.com' # will rework refs #123, #125 to Redmine issues
208
208
  }
209
- @diff.do_message_integration("[[text]] refs #123, #125").should == "<a href=\"http://example.com/wiki/text\">[[text]]</a> refs <a href=\"http://redmine.example.com/issues/show/123\">#123</a>, <a href=\"http://redmine.example.com/issues/show/125\">#125</a>"
209
+ @diff.do_message_integration("[[text]] refs #123, #125").should == "<a href=\"http://example.com/wiki/text\">[[text]]</a> refs <a href=\"http://redmine.example.com/issues/123\">#123</a>, <a href=\"http://redmine.example.com/issues/125\">#125</a>"
210
210
  end
211
211
  end
212
212
 
@@ -16,18 +16,18 @@ describe GitCommitNotifier::Git do
16
16
  describe :show do
17
17
  it "should get data from shell: git show without whitespaces" do
18
18
  expected = 'some data from git show'
19
- mock(GitCommitNotifier::Git).from_shell("git show #{SAMPLE_REV} --date=rfc2822 --pretty=fuller -w") { expected }
19
+ mock(GitCommitNotifier::Git).from_shell("git show #{SAMPLE_REV} --date=rfc2822 --pretty=fuller -M0.5 -w") { expected }
20
20
  GitCommitNotifier::Git.show(SAMPLE_REV, :ignore_whitespace => 'all').should == expected
21
21
  end
22
22
 
23
23
  it "should get data from shell: git show with whitespaces" do
24
24
  expected = 'some data from git show'
25
- mock(GitCommitNotifier::Git).from_shell("git show #{SAMPLE_REV} --date=rfc2822 --pretty=fuller") { expected }
25
+ mock(GitCommitNotifier::Git).from_shell("git show #{SAMPLE_REV} --date=rfc2822 --pretty=fuller -M0.5") { expected }
26
26
  GitCommitNotifier::Git.show(SAMPLE_REV, :ignore_whitespace => 'none').should == expected
27
27
  end
28
28
 
29
29
  it "should strip given revision" do
30
- mock(GitCommitNotifier::Git).from_shell("git show #{SAMPLE_REV} --date=rfc2822 --pretty=fuller -w")
30
+ mock(GitCommitNotifier::Git).from_shell("git show #{SAMPLE_REV} --date=rfc2822 --pretty=fuller -M0.5 -w")
31
31
  GitCommitNotifier::Git.show("#{SAMPLE_REV}\n", :ignore_whitespace => 'all')
32
32
  end
33
33
  end
@@ -126,7 +126,7 @@ describe GitCommitNotifier::Git do
126
126
  files = ["M README.rdoc\n",
127
127
  "D git_commit_notifier/Rakefile\n",
128
128
  "M post-receive\n"]
129
- mock(GitCommitNotifier::Git).from_shell("git log #{SAMPLE_REV}..#{SAMPLE_REV_2} --name-status --pretty=oneline" ) { IO.read(FIXTURES_PATH + 'git_log_name_status') }
129
+ mock(GitCommitNotifier::Git).from_shell("git log #{SAMPLE_REV}..#{SAMPLE_REV_2} --name-status --pretty=oneline -M0.5" ) { IO.read(FIXTURES_PATH + 'git_log_name_status') }
130
130
  GitCommitNotifier::Git.changed_files(SAMPLE_REV, SAMPLE_REV_2).should == files
131
131
  end
132
132
  end
@@ -136,7 +136,7 @@ describe GitCommitNotifier::Git do
136
136
  files = ["M README.rdoc\n",
137
137
  "D git_commit_notifier/Rakefile\n",
138
138
  "M post-receive\n"]
139
- mock(GitCommitNotifier::Git).from_shell("git log #{SAMPLE_REV}..#{SAMPLE_REV_2} --name-status --pretty=oneline" ) { IO.read(FIXTURES_PATH + 'git_log_name_status') }
139
+ mock(GitCommitNotifier::Git).from_shell("git log #{SAMPLE_REV}..#{SAMPLE_REV_2} --name-status --pretty=oneline -M0.5" ) { IO.read(FIXTURES_PATH + 'git_log_name_status') }
140
140
  output = GitCommitNotifier::Git.split_status(SAMPLE_REV, SAMPLE_REV_2)
141
141
  output[:m].should == [ 'README.rdoc', 'post-receive' ]
142
142
  output[:d].should == [ 'git_commit_notifier/Rakefile' ]
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.11
4
+ version: 0.12.0
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: 2013-05-29 00:00:00.000000000 Z
13
+ date: 2013-06-30 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: diff-lcs
@@ -339,7 +339,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
339
339
  version: '0'
340
340
  segments:
341
341
  - 0
342
- hash: 778864539407809625
342
+ hash: -459626784997908862
343
343
  required_rubygems_version: !ruby/object:Gem::Requirement
344
344
  none: false
345
345
  requirements: