git-commit-notifier 0.1.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/lib/emailer.rb ADDED
@@ -0,0 +1,102 @@
1
+ require 'yaml'
2
+ require 'erb'
3
+
4
+ class Emailer
5
+
6
+ def initialize(config, project_path, recipient, from_address, from_alias, subject, text_message, html_diff, old_rev, new_rev, ref_name)
7
+ @config = config
8
+ @config ||= {}
9
+ @project_path = project_path
10
+ @recipient = recipient
11
+ @from_address = from_address
12
+ @from_alias = from_alias
13
+ @subject = subject
14
+ @text_message = text_message
15
+ @ref_name = ref_name
16
+ @old_rev = old_rev
17
+ @new_rev = new_rev
18
+
19
+ template = File.join(File.dirname(__FILE__), '/../template/email.html.erb')
20
+ @html_message = ERB.new(File.read(template)).result(binding)
21
+ end
22
+
23
+ def boundary
24
+ return @boundary if @boundary
25
+ srand
26
+ seed = "#{rand(10000)}#{Time.now}"
27
+ @boundary = Digest::SHA1.hexdigest(seed)
28
+ end
29
+
30
+ def stylesheet_string
31
+ stylesheet = File.join(File.dirname(__FILE__), '/../template/styles.css')
32
+ File.read(stylesheet)
33
+ end
34
+
35
+ def perform_delivery_smtp(content, smtp_settings)
36
+ settings = { }
37
+ %w(address port domain user_name password authentication enable_tls).each do |key|
38
+ val = smtp_settings[key].to_s.empty? ? nil : smtp_settings[key]
39
+ settings.merge!({ key => val})
40
+ end
41
+
42
+ Net::SMTP.start(settings['address'], settings['port'], settings['domain'],
43
+ settings['user_name'], settings['password'], settings['authentication']) do |smtp|
44
+
45
+ smtp.enable_tls if settings['enable_tls']
46
+
47
+ smtp.open_message_stream(@from_address, [@recipient]) do |f|
48
+ content.each do |line|
49
+ f.puts line
50
+ end
51
+ end
52
+ end
53
+ end
54
+
55
+ def perform_delivery_sendmail(content, options = nil)
56
+ sendmail_settings = {
57
+ 'location' => "/usr/sbin/sendmail",
58
+ 'arguments' => "-i -t"
59
+ }.merge(options || {})
60
+ command = "#{sendmail_settings['location']} #{sendmail_settings['arguments']}"
61
+ IO.popen(command, "w+") do |f|
62
+ f.write(content.join("\n"))
63
+ f.flush
64
+ end
65
+ end
66
+
67
+ def send
68
+ from = @from_alias.empty? ? @from_address : "#{@from_alias} <#{@from_address}>"
69
+ content = ["From: #{from}",
70
+ "Reply-To: #{from}",
71
+ "To: #{@recipient}",
72
+ "Subject: #{@subject}",
73
+ "X-Git-Refname: #{@ref_name}",
74
+ "X-Git-Oldrev: #{@old_rev}",
75
+ "X-Git-Newrev: #{@new_rev}",
76
+ "Mime-Version: 1.0",
77
+ "Content-Type: multipart/alternative; boundary=#{boundary}\n\n\n",
78
+ "--#{boundary}",
79
+ "Content-Type: text/plain; charset=utf-8",
80
+ "Content-Transfer-Encoding: 8bit",
81
+ "Content-Disposition: inline\n\n\n",
82
+ @text_message,
83
+ "--#{boundary}",
84
+ "Content-Type: text/html; charset=utf-8",
85
+ "Content-Transfer-Encoding: 8bit",
86
+ "Content-Disposition: inline\n\n\n",
87
+ @html_message,
88
+ "--#{boundary}--"]
89
+
90
+ if @recipient.empty?
91
+ puts content.join("\n")
92
+ return
93
+ end
94
+
95
+ if @config['delivery_method'] == 'smtp'
96
+ perform_delivery_smtp(content, @config['smtp_server'])
97
+ else
98
+ perform_delivery_sendmail(content, @config['sendmail_options'])
99
+ end
100
+ end
101
+
102
+ end
data/lib/git.rb ADDED
@@ -0,0 +1,35 @@
1
+ class Git
2
+ def self.show(rev)
3
+ `git show #{rev.strip} -w`
4
+ end
5
+
6
+ def self.log(rev1, rev2)
7
+ `git log #{rev1}..#{rev2}`.strip
8
+ end
9
+
10
+ def self.branch_commits(treeish)
11
+ args = Git.branch_heads - [Git.branch_head(treeish)]
12
+ args.map! {|tree| "^#{tree}"}
13
+ args << treeish
14
+ `git rev-list #{args.join(' ')}`.to_a.map{|commit| commit.chomp}
15
+ end
16
+
17
+ def self.branch_heads
18
+ `git rev-parse --branches`.to_a.map{|head| head.chomp}
19
+ end
20
+
21
+ def self.branch_head(treeish)
22
+ `git rev-parse #{treeish}`.strip
23
+ end
24
+
25
+ def self.repo_name
26
+ git_prefix = `git config hooks.emailprefix`.strip
27
+ return git_prefix unless git_prefix.empty?
28
+ dir_name = `pwd`.chomp.split("/").last.gsub(/\.git$/, '')
29
+ return "#{dir_name}"
30
+ end
31
+
32
+ def self.mailing_list_address
33
+ `git config hooks.mailinglist`.strip
34
+ end
35
+ end
@@ -0,0 +1,122 @@
1
+ require 'cgi'
2
+
3
+ class ResultProcessor
4
+ # input (loaded in @diff) is an array having Hash elements:
5
+ # { :action => action, :token => string }
6
+ # action can be :discard_a, :discard_b or :match
7
+
8
+ # output: two formatted html strings, one for the removals and one for the additions
9
+
10
+ def results
11
+ close_tags # close last tag
12
+ [array_of_lines(@result[:removal]), array_of_lines(@result[:addition])]
13
+ end
14
+
15
+ private
16
+
17
+ def initialize(diff)
18
+ @diff = diff
19
+ init
20
+ filter_replaced_lines
21
+ process
22
+ end
23
+
24
+ def init
25
+ @result = { :addition => [], :removal => [] }
26
+ @tag_open = { :addition => false, :removal => false}
27
+ end
28
+
29
+ def process
30
+ @highlight = !@diff.select { |d| d[:action] == :match}.empty? # highlight only if block contains both matches and differences
31
+ @diff.each do |diff|
32
+ case diff[:action]
33
+ when :match
34
+ match(diff)
35
+ when :discard_a
36
+ discard_a(diff)
37
+ when :discard_b
38
+ discard_b(diff)
39
+ end
40
+ end
41
+ end
42
+
43
+ def discard_match(position, token)
44
+ # replace it with 2 changes
45
+ @diff[position][:action] = :discard_a
46
+ @diff.insert(position, { :action => :discard_b, :token => token} )
47
+ end
48
+
49
+ def length_in_chars(diff)
50
+ diff.inject(0) { |length, s| length + s[:token].size}
51
+ end
52
+
53
+ def filter_replaced_lines
54
+ # if a block is replaced by an other one, lcs-diff will find even the single common word between the old and the new content
55
+ # no need for intelligent diff in this case, simply show the removed and the added block with no highlighting
56
+ # rule: if less than 33% of a block is not a match, we don't need intelligent diff for that block
57
+ match_length = length_in_chars(@diff.select { |d| d[:action] == :match})
58
+ total_length = length_in_chars(@diff)
59
+
60
+ if total_length.to_f / match_length > 3.3
61
+ @diff.each_with_index do |d, i|
62
+ next if d[:action] != :match
63
+ discard_match(i, d[:token])
64
+ end
65
+ end
66
+ end
67
+
68
+ def match(diff)
69
+ close_tags
70
+ all_actions do |action|
71
+ close_last_tag(diff)
72
+ @result[action] << escape_content(diff[:token])
73
+ end
74
+ end
75
+
76
+ def discard_a(diff)
77
+ open_tag(:removal, diff[:token])
78
+ close_last_tag(diff)
79
+ @result[:removal] << escape_content(diff[:token])
80
+ end
81
+
82
+ def discard_b(diff)
83
+ open_tag(:addition, diff[:token])
84
+ close_last_tag(diff)
85
+ @result[:addition] << escape_content(diff[:token])
86
+ end
87
+
88
+ def all_actions
89
+ [:addition, :removal].each do |action|
90
+ yield(action)
91
+ end
92
+ end
93
+
94
+ def open_tag(action, next_token)
95
+ return if !@highlight || next_token.strip.empty? # don't open span tag if no highlighting is needed or the first token is empty
96
+ unless @tag_open[action]
97
+ klass = action == :addition ? 'aa' : 'rr'
98
+ @result[action] << "<span class=\"#{klass}\">"
99
+ @tag_open[action] = true
100
+ end
101
+ end
102
+
103
+ def close_tags
104
+ return unless @highlight
105
+ all_actions do |action|
106
+ if @tag_open[action]
107
+ @result[action] << "</span>"
108
+ @tag_open[action] = false
109
+ end
110
+ end
111
+ end
112
+
113
+ def close_last_tag(diff)
114
+ return unless @highlight
115
+ close_tags if diff[:token] == "\n"
116
+ end
117
+
118
+ def array_of_lines(tokens)
119
+ tokens.join('').split("\n")
120
+ end
121
+
122
+ end
@@ -0,0 +1,9 @@
1
+ <html><head>
2
+ <style>
3
+ <%= stylesheet_string %>
4
+ </style>
5
+ </head>
6
+ <body>
7
+ <%= html_diff %>
8
+ </body>
9
+ </html>
@@ -0,0 +1,10 @@
1
+ * {font-size:11px;}
2
+ h2 {font-family:Verdana;font-size:12px;background-color: #bbb; font-weight: bold; line-height:25px; margin-bottom:2px; padding-left:5px}
3
+ table {width:100%;border-collapse:collapse}
4
+ .r {background-color: #fdd;}
5
+ .rr {background-color: #faa;}
6
+ .a {background-color: #dfd;}
7
+ .aa {background-color: #afa;}
8
+ .title {background-color: #ddd; padding: 10px;font-family:Verdana;font-size:12px;}
9
+ tr {color:#000;font-family: "Bitstream Vera Sans Mono","Monaco","Courier",monospace}
10
+ .ln {background-color: #ccc; width:23px; text-align:right}
@@ -0,0 +1,34 @@
1
+ commit e28ad77bba0574241e6eb64dfd0c1291b221effe
2
+ Author: Tom Stuart <tom@experthuman.com>
3
+ Date: Wed Oct 8 09:31:00 2008 +0100
4
+
5
+ Allow use of :path_prefix and :name_prefix outside of namespaced routes. [#1188 state:resolved]
6
+
7
+ Signed-off-by: Pratik Naik <pratiknaik@gmail.com>
8
+
9
+ commit a4629e707d80a5769f7a71ca6ed9471015e14dc9
10
+ Author: Michael Koziarski <michael@koziarski.com>
11
+ Date: Mon Sep 29 17:36:09 2008 +0200
12
+
13
+ Extract transliteration code to a seperate method.
14
+
15
+ Use iconv by default, but only when the transliteration is well behaved. When it isn't, fallback to mb_chars
16
+
17
+ commit dce6ade4cdc2833b53bd600ef10f9bce83c7102d
18
+ Author: Andrew Kaspick <andrew@redlinesoftware.com>
19
+ Date: Tue Sep 30 14:15:36 2008 -0500
20
+
21
+ Ensure select_tag#name attribute uses [] when :multiple is true. [#1146 state:resolved]
22
+
23
+ Signed-off-by: Pratik Naik <pratiknaik@gmail.com>
24
+
25
+ commit 51b986619d88f7ba98be7d271188785cbbb541a0
26
+ Author: Tarmo Tänav <tarmo@itech.ee>
27
+ Date: Mon Oct 6 17:35:21 2008 +0300
28
+
29
+ Implement submit_to_remote as a wrapper around a more generic button_to_remote
30
+
31
+ Removed the "return false" from submit_to_remote onclick end as
32
+ button input elements have no default behavior to cancel.
33
+
34
+ Signed-off-by: Pratik Naik <pratiknaik@gmail.com>
@@ -0,0 +1,83 @@
1
+ commit 51b986619d88f7ba98be7d271188785cbbb541a0
2
+ Author: Tarmo Tänav <tarmo@itech.ee>
3
+ Date: Mon Oct 6 17:35:21 2008 +0300
4
+
5
+ Implement submit_to_remote as a wrapper around a more generic button_to_remote
6
+
7
+ Removed the "return false" from submit_to_remote onclick end as
8
+ button input elements have no default behavior to cancel.
9
+
10
+ Signed-off-by: Pratik Naik <pratiknaik@gmail.com>
11
+
12
+ diff --git a/actionpack/CHANGELOG b/actionpack/CHANGELOG
13
+ index 54ea93f..4de93a1 100644
14
+ --- a/actionpack/CHANGELOG
15
+ +++ b/actionpack/CHANGELOG
16
+ @@ -1,5 +1,7 @@
17
+ *Edge*
18
+
19
+ +* Make PrototypeHelper#submit_to_remote a wrapper around PrototypeHelper#button_to_remote. [Tarmo Tänav]
20
+ +
21
+ * Set HttpOnly for the cookie session store's cookie. #1046
22
+
23
+ * Added FormTagHelper#image_submit_tag confirm option #784 [Alastair Brunton]
24
+ diff --git a/actionpack/lib/action_view/helpers/prototype_helper.rb b/actionpack/lib/action_view/helpers/prototype_helper.rb
25
+ index ff41a6d..a3eccc7 100644
26
+ --- a/actionpack/lib/action_view/helpers/prototype_helper.rb
27
+ +++ b/actionpack/lib/action_view/helpers/prototype_helper.rb
28
+ @@ -405,7 +405,7 @@ module ActionView
29
+ # # Generates: <input name="create_btn" onclick="new Ajax.Request('/testing/create',
30
+ # # {asynchronous:true, evalScripts:true, parameters:Form.serialize(this.form)});
31
+ # # return false;" type="button" value="Create" />
32
+ - # <%= button_to_remote 'create_btn', 'Create', :url => { :action => 'create' } %>
33
+ + # <%= submit_to_remote 'create_btn', 'Create', :url => { :action => 'create' } %>
34
+ #
35
+ # # Submit to the remote action update and update the DIV succeed or fail based
36
+ # # on the success or failure of the request
37
+ @@ -413,24 +413,18 @@ module ActionView
38
+ # # Generates: <input name="update_btn" onclick="new Ajax.Updater({success:'succeed',failure:'fail'},
39
+ # # '/testing/update', {asynchronous:true, evalScripts:true, parameters:Form.serialize(this.form)});
40
+ # # return false;" type="button" value="Update" />
41
+ - # <%= button_to_remote 'update_btn', 'Update', :url => { :action => 'update' },
42
+ + # <%= submit_to_remote 'update_btn', 'Update', :url => { :action => 'update' },
43
+ # :update => { :success => "succeed", :failure => "fail" }
44
+ #
45
+ # <tt>options</tt> argument is the same as in form_remote_tag.
46
+ - #
47
+ - # Note: This method used to be called submit_to_remote, but that's now just an alias for button_to_remote
48
+ - def button_to_remote(name, value, options = {})
49
+ + def submit_to_remote(name, value, options = {})
50
+ options[:with] ||= 'Form.serialize(this.form)'
51
+
52
+ - options[:html] ||= {}
53
+ - options[:html][:type] = 'button'
54
+ - options[:html][:onclick] = "#{remote_function(options)}; return false;"
55
+ - options[:html][:name] = name
56
+ - options[:html][:value] = value
57
+ + html_options = options.delete(:html) || {}
58
+ + html_options[:name] = name
59
+
60
+ - tag("input", options[:html], false)
61
+ + button_to_remote(value, options, html_options)
62
+ end
63
+ - alias_method :submit_to_remote, :button_to_remote
64
+
65
+ # Returns '<tt>eval(request.responseText)</tt>' which is the JavaScript function
66
+ # that +form_remote_tag+ can call in <tt>:complete</tt> to evaluate a multiple
67
+ diff --git a/actionpack/test/template/prototype_helper_test.rb b/actionpack/test/template/prototype_helper_test.rb
68
+ index a1f541f..d6b86a3 100644
69
+ --- a/actionpack/test/template/prototype_helper_test.rb
70
+ +++ b/actionpack/test/template/prototype_helper_test.rb
71
+ @@ -218,9 +218,9 @@ class PrototypeHelperTest < PrototypeHelperBaseTest
72
+
73
+ end
74
+
75
+ - def test_button_to_remote
76
+ - assert_dom_equal %(<input name=\"More beer!\" onclick=\"new Ajax.Updater('empty_bottle', 'http://www.example.com/', {asynchronous:true, evalScripts:true, parameters:Form.serialize(this.form)}); return false;\" type=\"button\" value=\"1000000\" />),
77
+ - button_to_remote("More beer!", 1_000_000, :update => "empty_bottle")
78
+ + def test_submit_to_remote
79
+ + assert_dom_equal %(<input name=\"More beer!\" onclick=\"new Ajax.Updater('empty_bottle', 'http://www.example.com/', {asynchronous:true, evalScripts:true, parameters:Form.serialize(this.form)});\" type=\"button\" value=\"1000000\" />),
80
+ + submit_to_remote("More beer!", 1_000_000, :update => "empty_bottle")
81
+ end
82
+
83
+ def test_observe_field
@@ -0,0 +1,49 @@
1
+ commit a4629e707d80a5769f7a71ca6ed9471015e14dc9
2
+ Author: Michael Koziarski <michael@koziarski.com>
3
+ Date: Mon Sep 29 17:36:09 2008 +0200
4
+
5
+ Extract transliteration code to a seperate method.
6
+
7
+ Use iconv by default, but only when the transliteration is well behaved. When it isn't, fallback to mb_chars
8
+
9
+ diff --git a/activesupport/lib/active_support/inflector.rb b/activesupport/lib/active_support/inflector.rb
10
+ index 89a93f4..f1e7abf 100644
11
+ --- a/activesupport/lib/active_support/inflector.rb
12
+ +++ b/activesupport/lib/active_support/inflector.rb
13
+ @@ -1,4 +1,5 @@
14
+ require 'singleton'
15
+ +require 'iconv'
16
+
17
+ module ActiveSupport
18
+ # The Inflector transforms words from singular to plural, class names to table names, modularized class names to ones without,
19
+ @@ -258,14 +259,28 @@ module ActiveSupport
20
+ # # => <a href="/person/1-donald-e-knuth">Donald E. Knuth</a>
21
+ def parameterize(string, sep = '-')
22
+ re_sep = Regexp.escape(sep)
23
+ - string.mb_chars.normalize(:kd). # Decompose accented characters
24
+ - gsub(/[^\x00-\x7F]+/, ''). # Remove anything non-ASCII entirely (e.g. diacritics).
25
+ + transliterate(string).
26
+ gsub(/[^a-z0-9\-_\+]+/i, sep). # Turn unwanted chars into the separator.
27
+ squeeze(sep). # No more than one of the separator in a row.
28
+ gsub(/^#{re_sep}|#{re_sep}$/i, ''). # Remove leading/trailing separator.
29
+ downcase
30
+ end
31
+
32
+ +
33
+ + # Replaces accented characters with their ascii equivalents.
34
+ + def transliterate(string)
35
+ + Iconv.iconv('ascii//translit//IGNORE', 'utf-8', string).to_s
36
+ + end
37
+ +
38
+ + # The iconv transliteration code doesn't function correctly
39
+ + # on some platforms, but it's very fast where it does function.
40
+ + if "foo" != Inflector.transliterate("föö")
41
+ + def transliterate(string)
42
+ + string.mb_chars.normalize(:kd). # Decompose accented characters
43
+ + gsub(/[^\x00-\x7F]+/, '') # Remove anything non-ASCII entirely (e.g. diacritics).
44
+ + end
45
+ + end
46
+ +
47
+ # Create the name of a table like Rails does for models to table names. This method
48
+ # uses the +pluralize+ method on the last word in the string.
49
+ #