rgithook 3.0.2
Sign up to get free protection for your applications and to get access to all the features.
- data.tar.gz.sig +0 -0
- data/CHANGELOG +3 -0
- data/Manifest +42 -0
- data/README.rdoc +12 -0
- data/Rakefile +22 -0
- data/TODO.txt +4 -0
- data/bin/rgithook +13 -0
- data/lib/plugins/custom.rb +18 -0
- data/lib/plugins/db.rb +34 -0
- data/lib/plugins/email.rb +39 -0
- data/lib/plugins/html.rb +53 -0
- data/lib/plugins/html/commit.html.erb +26 -0
- data/lib/plugins/html/diff.html.erb +16 -0
- data/lib/plugins/rake.rb +14 -0
- data/lib/plugins/spec/rgithook_formatter.rb +74 -0
- data/lib/plugins/spec/spec_result.rb +5 -0
- data/lib/plugins/temp.rb +41 -0
- data/lib/plugins/test.rb +37 -0
- data/lib/plugins/twitter.rb +13 -0
- data/lib/rgithook.rb +36 -0
- data/lib/rgithook/command_line.rb +47 -0
- data/lib/rgithook/hook.rb +39 -0
- data/lib/rgithook/plugin.rb +105 -0
- data/lib/rgithook/rgithook.rb +229 -0
- data/lib/rgithook/runner.rb +178 -0
- data/lib/rgithook/templates/hook.rb +6 -0
- data/lib/rgithook/templates/rgithook.rb +18 -0
- data/lib/rgithook/test/unit.rb +70 -0
- data/rgithook.gemspec +42 -0
- data/test/fixtures/sample_plugin.rb +28 -0
- data/test/fixtures/sample_repo.zip +0 -0
- data/test/integration/test_install.rb +68 -0
- data/test/integration/test_pull_and_push.rb +20 -0
- data/test/plugins/test_email.rb +8 -0
- data/test/plugins/test_html.rb +6 -0
- data/test/plugins/test_spec.rb +6 -0
- data/test/plugins/test_test.rb +14 -0
- data/test/test_helper.rb +12 -0
- data/test/unit/test_command_line.rb +59 -0
- data/test/unit/test_hook.rb +31 -0
- data/test/unit/test_plugin.rb +36 -0
- data/test/unit/test_rgithook.rb +143 -0
- data/test/unit/test_runner.rb +95 -0
- metadata +174 -0
- metadata.gz.sig +2 -0
data.tar.gz.sig
ADDED
Binary file
|
data/CHANGELOG
ADDED
data/Manifest
ADDED
@@ -0,0 +1,42 @@
|
|
1
|
+
bin/rgithook
|
2
|
+
CHANGELOG
|
3
|
+
lib/plugins/custom.rb
|
4
|
+
lib/plugins/db.rb
|
5
|
+
lib/plugins/email.rb
|
6
|
+
lib/plugins/html/commit.html.erb
|
7
|
+
lib/plugins/html/diff.html.erb
|
8
|
+
lib/plugins/html.rb
|
9
|
+
lib/plugins/rake.rb
|
10
|
+
lib/plugins/spec/rgithook_formatter.rb
|
11
|
+
lib/plugins/spec/spec_result.rb
|
12
|
+
lib/plugins/temp.rb
|
13
|
+
lib/plugins/test.rb
|
14
|
+
lib/plugins/twitter.rb
|
15
|
+
lib/rgithook/command_line.rb
|
16
|
+
lib/rgithook/hook.rb
|
17
|
+
lib/rgithook/plugin.rb
|
18
|
+
lib/rgithook/rgithook.rb
|
19
|
+
lib/rgithook/runner.rb
|
20
|
+
lib/rgithook/templates/hook.rb
|
21
|
+
lib/rgithook/templates/rgithook.rb
|
22
|
+
lib/rgithook/test/unit.rb
|
23
|
+
lib/rgithook.rb
|
24
|
+
Manifest
|
25
|
+
Rakefile
|
26
|
+
README.rdoc
|
27
|
+
rgithook.gemspec
|
28
|
+
test/fixtures/sample_plugin.rb
|
29
|
+
test/fixtures/sample_repo.zip
|
30
|
+
test/integration/test_install.rb
|
31
|
+
test/integration/test_pull_and_push.rb
|
32
|
+
test/plugins/test_email.rb
|
33
|
+
test/plugins/test_html.rb
|
34
|
+
test/plugins/test_spec.rb
|
35
|
+
test/plugins/test_test.rb
|
36
|
+
test/test_helper.rb
|
37
|
+
test/unit/test_command_line.rb
|
38
|
+
test/unit/test_hook.rb
|
39
|
+
test/unit/test_plugin.rb
|
40
|
+
test/unit/test_rgithook.rb
|
41
|
+
test/unit/test_runner.rb
|
42
|
+
TODO.txt
|
data/README.rdoc
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
= RGitHook
|
2
|
+
|
3
|
+
RGitHook is:
|
4
|
+
* GitHooks made easy
|
5
|
+
* Center all the hooks in one ruby file
|
6
|
+
* Plugin system for make concrete actions on hooks. (twitter, email, test, etc...)
|
7
|
+
|
8
|
+
You may want GINST. A configuration and web interface for projects
|
9
|
+
|
10
|
+
= Install
|
11
|
+
|
12
|
+
sudo gem install guillermo-rgithook
|
data/Rakefile
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
begin
|
3
|
+
require 'rake'
|
4
|
+
require 'echoe'
|
5
|
+
rescue LoadError
|
6
|
+
puts 'This script should only be accessed via the "rake" command.'
|
7
|
+
puts 'Installation: gem install rake -y'
|
8
|
+
exit
|
9
|
+
end
|
10
|
+
|
11
|
+
|
12
|
+
Echoe.new('rgithook') do |p|
|
13
|
+
p.description = "Ruby gem specify for git hooks."
|
14
|
+
p.summary = "You can deploy updated code, restart the web server, run the tests, email the diff, etc...\nYou can use a cron to pull or a githook to run when pushed to the repo."
|
15
|
+
p.url = "http://github.com/guillermo/rgithook2"
|
16
|
+
p.author = "Guillermo Álvarez"
|
17
|
+
p.email = "guillermo@cientifico.net"
|
18
|
+
p.runtime_dependencies = ["mojombo-grit"]
|
19
|
+
p.ignore_pattern = ["tmp/*", "script/*", "demo?/*", "pkg/*", "*.tmproj","*.org"]
|
20
|
+
p.development_dependencies = ["mocha"]
|
21
|
+
end
|
22
|
+
|
data/TODO.txt
ADDED
data/bin/rgithook
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
if File.exist?(file = File.join(File.dirname(File.expand_path(__FILE__)), '..', 'lib','rgithook.rb'))
|
4
|
+
puts "Using development rgithook"
|
5
|
+
require file
|
6
|
+
else
|
7
|
+
require 'rubygems'
|
8
|
+
require 'rgithook'
|
9
|
+
end
|
10
|
+
|
11
|
+
|
12
|
+
|
13
|
+
RGitHook::CommandLine.execute(ARGV)
|
@@ -0,0 +1,18 @@
|
|
1
|
+
|
2
|
+
class Custom < RGitHook::Plugin
|
3
|
+
|
4
|
+
option :post_code, 'Post Code to execute ', '', String
|
5
|
+
option :pre_code , 'Post code to execute', '', String
|
6
|
+
|
7
|
+
module RunnerMethods
|
8
|
+
|
9
|
+
def pre_code
|
10
|
+
eval(options[:Custom][:pre_code],binding,'custom_pre_commit_code',0)
|
11
|
+
end
|
12
|
+
|
13
|
+
def post_code
|
14
|
+
eval(options[:Custom][:pre_code],binding,'custom_post_commit_code',0)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
data/lib/plugins/db.rb
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'dbm'
|
2
|
+
|
3
|
+
class CommitDB < RGitHook::Plugin
|
4
|
+
module GritCommit
|
5
|
+
# Read properties from a commit
|
6
|
+
def properties
|
7
|
+
db = get_commit_database
|
8
|
+
@properties ||= (v = db[self.sha] and Marshal.load v) || {}
|
9
|
+
ensure
|
10
|
+
db.close
|
11
|
+
end
|
12
|
+
|
13
|
+
# Write properties for a commit
|
14
|
+
def properties=(data)
|
15
|
+
@properties = data
|
16
|
+
db = get_commit_database
|
17
|
+
db[self.sha] = Marshal.dump data
|
18
|
+
ensure
|
19
|
+
db.close
|
20
|
+
end
|
21
|
+
|
22
|
+
def save_properties
|
23
|
+
db = get_commit_database
|
24
|
+
db[self.sha] = Marshal.dump(@properties || {})
|
25
|
+
ensure
|
26
|
+
db.close
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
def get_commit_database
|
31
|
+
::DBM.new(File.join(@repo.path,'hooks','commitsdb'))
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'tmail'
|
2
|
+
require 'socket'
|
3
|
+
|
4
|
+
class Email < RGitHook::Plugin
|
5
|
+
|
6
|
+
option :destination, "Destination of email functions", %x(who am i), [String]
|
7
|
+
|
8
|
+
module RunnerMethods
|
9
|
+
include TMail
|
10
|
+
|
11
|
+
|
12
|
+
# Send a multipart html email, converting html to text for plain_text emails
|
13
|
+
# In Uses Tmail
|
14
|
+
#
|
15
|
+
# mail('test resutls', '<html><body>Good results!</body></html>')
|
16
|
+
def email(subject,body,to=nil)
|
17
|
+
part = Mail.new
|
18
|
+
part.set_content_type "text", "html"
|
19
|
+
part.body = body.to_html
|
20
|
+
mail = Mail.new
|
21
|
+
mail.to = to
|
22
|
+
mail.from = "rgithook@#{Socket.gethostname}"
|
23
|
+
mail.subject = subject
|
24
|
+
mail.body = body.gsub('</p>',"\n").gsub('</br>',"\n").gsub(/<\/?[^>]*>/, "")
|
25
|
+
mail.parts << part
|
26
|
+
mail
|
27
|
+
sendmail(mail)
|
28
|
+
mail
|
29
|
+
end
|
30
|
+
|
31
|
+
private
|
32
|
+
def sendmail(mail)
|
33
|
+
sendmail = IO.popen("/usr/sbin/sendmail #{mail.to}", "w")
|
34
|
+
sendmail.write mail.to_s
|
35
|
+
sendmail.close
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
data/lib/plugins/html.rb
ADDED
@@ -0,0 +1,53 @@
|
|
1
|
+
require 'erb'
|
2
|
+
|
3
|
+
module ToHtml
|
4
|
+
def to_html
|
5
|
+
filename = self.class.to_s.gsub(/.*::/,'').downcase+'.html.erb'
|
6
|
+
template = File.join(File.dirname(__FILE__),'html',filename)
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
|
11
|
+
|
12
|
+
module ToHtml
|
13
|
+
def to_html
|
14
|
+
filename = self.class.to_s.gsub(/.*::/,'').downcase+'.html.erb'
|
15
|
+
template = File.join(File.dirname(__FILE__),'html',filename)
|
16
|
+
::ERB.new(File.read(template)).result(binding)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
class ::Grit::Commit
|
21
|
+
include ToHtml
|
22
|
+
end
|
23
|
+
|
24
|
+
class ::Grit::Diff
|
25
|
+
include ToHtml
|
26
|
+
end
|
27
|
+
|
28
|
+
class Object
|
29
|
+
def to_html
|
30
|
+
to_s
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
class Array
|
35
|
+
def to_html
|
36
|
+
self.map{|e| e.to_html}.join("\n")
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
class String
|
41
|
+
HTML_ESCAPE = { '&'=>'&', '<'=>'<', '>'=>'>', '"'=>'"', "'"=>''', }
|
42
|
+
|
43
|
+
# Returns a copy of <tt>text</tt> with ampersands, angle brackets and quotes
|
44
|
+
# escaped into HTML entities.
|
45
|
+
def html_escape
|
46
|
+
self.gsub(/[\"><&]/) { |s| HTML_ESCAPE[s] }
|
47
|
+
end
|
48
|
+
|
49
|
+
def color_diff
|
50
|
+
self.gsub( /^(\+[^+].*)$/, '<ins style="background:#dfd;text-decoration:none;padding:0 10px;">\1</ins>').
|
51
|
+
gsub( /^(\-[^-].*)$/, '<del style="background:#fdd;text-decoration:none;padding:0 10px;">\1</del>')
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
<div name='<%=id%>'>
|
2
|
+
<dl style='font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; border: 1px #006 solid; background: #369; padding: 6px; color: #fff;'>
|
3
|
+
<dt style='float: left; width: 6em; font-weight: bold;'>sha1:</dt>
|
4
|
+
<dd><%= id %></dd>
|
5
|
+
|
6
|
+
<dt style='float: left; width: 6em; font-weight: bold;'>author:</dt>
|
7
|
+
<dd><a href="mailto:<%=author.email%>"><%=author.name.html_escape%></a></dd>
|
8
|
+
|
9
|
+
|
10
|
+
<dt style='float: left; width: 6em; font-weight: bold;'>date:</dt>
|
11
|
+
<dd><%=date.to_s.html_escape%></dd>
|
12
|
+
|
13
|
+
<dt style='float: left; width: 6em; font-weight: bold;'>message:</dt>
|
14
|
+
<dd><%=message.html_escape%></dd>
|
15
|
+
<!--
|
16
|
+
<% stats = @repo.commit_stats(id).first[1].to_hash %>
|
17
|
+
<% stats.each do |key,value| %>
|
18
|
+
<dt><%=key%></dt><dd><%=value%></dd>
|
19
|
+
<% end %>
|
20
|
+
-->
|
21
|
+
</dl>
|
22
|
+
|
23
|
+
<div><%=diffs.map{|d| d.to_html}%></div>
|
24
|
+
</div>
|
25
|
+
|
26
|
+
|
@@ -0,0 +1,16 @@
|
|
1
|
+
<div style='margin: 5px 0px 10px 20px'>
|
2
|
+
<div style='font-weight: bolder;display: inline;'><%=a_path.html_escape%></div>
|
3
|
+
<% if new_file %>
|
4
|
+
<div style='color: green; display: inline;'>New file</div>
|
5
|
+
<% elsif deleted_file %>
|
6
|
+
<div style='color:red; display: inline;'>Deleted file</div>
|
7
|
+
<% end %>
|
8
|
+
<% unless deleted_file %>
|
9
|
+
<div style='width: 100%;'>
|
10
|
+
<pre style='padding:0;line-height:1.2em;margin:0; overflow: auto; background: #ffc; border: 1px #fc0 solid; padding: 6px;'>
|
11
|
+
<%=diff.html_escape.color_diff%>
|
12
|
+
</pre>
|
13
|
+
</div>
|
14
|
+
<% end %>
|
15
|
+
</div>
|
16
|
+
|
data/lib/plugins/rake.rb
ADDED
@@ -0,0 +1,74 @@
|
|
1
|
+
|
2
|
+
|
3
|
+
class RGitHookFormatter < Spec::Runner::Formatter::BaseFormatter
|
4
|
+
attr_accessor :example_group, :options, :where
|
5
|
+
def initialize(options, where)
|
6
|
+
@options = options
|
7
|
+
@where = where
|
8
|
+
end
|
9
|
+
|
10
|
+
# This method is invoked before any examples are run, right after
|
11
|
+
# they have all been collected. This can be useful for special
|
12
|
+
# formatters that need to provide progress on feedback (graphical ones)
|
13
|
+
#
|
14
|
+
# This method will only be invoked once, and the next one to be invoked
|
15
|
+
# is #add_example_group
|
16
|
+
def start(example_count)
|
17
|
+
end
|
18
|
+
|
19
|
+
# This method is invoked at the beginning of the execution of each example_group.
|
20
|
+
# +example_group+ is the example_group.
|
21
|
+
#
|
22
|
+
# The next method to be invoked after this is #example_failed or #example_finished
|
23
|
+
def add_example_group(example_group)
|
24
|
+
@example_group = example_group
|
25
|
+
end
|
26
|
+
|
27
|
+
# This method is invoked when an +example+ starts.
|
28
|
+
def example_started(example)
|
29
|
+
end
|
30
|
+
|
31
|
+
# This method is invoked when an +example+ passes.
|
32
|
+
def example_passed(example)
|
33
|
+
end
|
34
|
+
|
35
|
+
# This method is invoked when an +example+ fails, i.e. an exception occurred
|
36
|
+
# inside it (such as a failed should or other exception). +counter+ is the
|
37
|
+
# sequence number of the failure (starting at 1) and +failure+ is the associated
|
38
|
+
# Failure object.
|
39
|
+
def example_failed(example, counter, failure)
|
40
|
+
end
|
41
|
+
|
42
|
+
# This method is invoked when an example is not yet implemented (i.e. has not
|
43
|
+
# been provided a block), or when an ExamplePendingError is raised.
|
44
|
+
# +message+ is the message from the ExamplePendingError, if it exists, or the
|
45
|
+
# default value of "Not Yet Implemented"
|
46
|
+
# +pending_caller+ is the file and line number of the spec which
|
47
|
+
# has called the pending method
|
48
|
+
def example_pending(example, message, pending_caller)
|
49
|
+
end
|
50
|
+
|
51
|
+
# This method is invoked after all of the examples have executed. The next method
|
52
|
+
# to be invoked after this one is #dump_failure (once for each failed example),
|
53
|
+
def start_dump
|
54
|
+
end
|
55
|
+
|
56
|
+
# Dumps detailed information about an example failure.
|
57
|
+
# This method is invoked for each failed example after all examples have run. +counter+ is the sequence number
|
58
|
+
# of the associated example. +failure+ is a Failure object, which contains detailed
|
59
|
+
# information about the failure.
|
60
|
+
def dump_failure(counter, failure)
|
61
|
+
end
|
62
|
+
|
63
|
+
# This method is invoked after the dumping of examples and failures.
|
64
|
+
def dump_summary(duration, example_count, failure_count, pending_count)
|
65
|
+
end
|
66
|
+
|
67
|
+
# This gets invoked after the summary if option is set to do so.
|
68
|
+
def dump_pending
|
69
|
+
end
|
70
|
+
|
71
|
+
# This method is invoked at the very end. Allows the formatter to clean up, like closing open streams.
|
72
|
+
def close
|
73
|
+
end
|
74
|
+
end
|
data/lib/plugins/temp.rb
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
require 'fileutils'
|
2
|
+
require 'tempfile'
|
3
|
+
|
4
|
+
|
5
|
+
class Temp < RGitHook::Plugin
|
6
|
+
|
7
|
+
module RunnerMethods
|
8
|
+
|
9
|
+
# Run tests in a temp dir.
|
10
|
+
# One argument is passed repo, that is a instance of the new Grit.repo
|
11
|
+
# You can use repo.path to see where is it.
|
12
|
+
# It receives a block with repo passed.
|
13
|
+
def in_temp_commit(commit,&block)
|
14
|
+
raise ArgumentError unless block_given?
|
15
|
+
in_temp_dir do |temp_dir|
|
16
|
+
repo_dir = File.join(temp_dir,commit.to_s)
|
17
|
+
|
18
|
+
old_dir = Dir.pwd
|
19
|
+
%x(git clone #{repo.path} #{repo_dir})
|
20
|
+
Dir.chdir repo_dir
|
21
|
+
|
22
|
+
%x(git checkout #{commit.is_a?(::Grit::Commit) ? commit.sha : commit})
|
23
|
+
yield ::Grit::Repo.new(repo_dir)
|
24
|
+
Dir.chdir old_dir
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def in_temp_dir(&block)
|
29
|
+
old_dir = Dir.pwd
|
30
|
+
raise LocalJumpError, 'no block given' unless block_given?
|
31
|
+
|
32
|
+
tmpdir = File.expand_path(File.join(Dir.tmpdir,'rgithook-'+Time.now.usec.to_s+rand.to_s[2..-1]))
|
33
|
+
FileUtils.mkdir_p(tmpdir)
|
34
|
+
Dir.chdir tmpdir
|
35
|
+
ret_val = yield tmpdir
|
36
|
+
Dir.chdir old_dir
|
37
|
+
FileUtils.remove_dir(tmpdir)
|
38
|
+
ret_val
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|