rgithook 3.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (45) hide show
  1. data.tar.gz.sig +0 -0
  2. data/CHANGELOG +3 -0
  3. data/Manifest +42 -0
  4. data/README.rdoc +12 -0
  5. data/Rakefile +22 -0
  6. data/TODO.txt +4 -0
  7. data/bin/rgithook +13 -0
  8. data/lib/plugins/custom.rb +18 -0
  9. data/lib/plugins/db.rb +34 -0
  10. data/lib/plugins/email.rb +39 -0
  11. data/lib/plugins/html.rb +53 -0
  12. data/lib/plugins/html/commit.html.erb +26 -0
  13. data/lib/plugins/html/diff.html.erb +16 -0
  14. data/lib/plugins/rake.rb +14 -0
  15. data/lib/plugins/spec/rgithook_formatter.rb +74 -0
  16. data/lib/plugins/spec/spec_result.rb +5 -0
  17. data/lib/plugins/temp.rb +41 -0
  18. data/lib/plugins/test.rb +37 -0
  19. data/lib/plugins/twitter.rb +13 -0
  20. data/lib/rgithook.rb +36 -0
  21. data/lib/rgithook/command_line.rb +47 -0
  22. data/lib/rgithook/hook.rb +39 -0
  23. data/lib/rgithook/plugin.rb +105 -0
  24. data/lib/rgithook/rgithook.rb +229 -0
  25. data/lib/rgithook/runner.rb +178 -0
  26. data/lib/rgithook/templates/hook.rb +6 -0
  27. data/lib/rgithook/templates/rgithook.rb +18 -0
  28. data/lib/rgithook/test/unit.rb +70 -0
  29. data/rgithook.gemspec +42 -0
  30. data/test/fixtures/sample_plugin.rb +28 -0
  31. data/test/fixtures/sample_repo.zip +0 -0
  32. data/test/integration/test_install.rb +68 -0
  33. data/test/integration/test_pull_and_push.rb +20 -0
  34. data/test/plugins/test_email.rb +8 -0
  35. data/test/plugins/test_html.rb +6 -0
  36. data/test/plugins/test_spec.rb +6 -0
  37. data/test/plugins/test_test.rb +14 -0
  38. data/test/test_helper.rb +12 -0
  39. data/test/unit/test_command_line.rb +59 -0
  40. data/test/unit/test_hook.rb +31 -0
  41. data/test/unit/test_plugin.rb +36 -0
  42. data/test/unit/test_rgithook.rb +143 -0
  43. data/test/unit/test_runner.rb +95 -0
  44. metadata +174 -0
  45. metadata.gz.sig +2 -0
@@ -0,0 +1,178 @@
1
+ module RGitHook
2
+ class Runner
3
+
4
+ attr_reader :binding
5
+
6
+ def initialize(repo) #::nodoc::
7
+ raise ArgumentError unless repo.is_a? ::Grit::Repo
8
+ @_repo = repo
9
+ @_hooks = {}
10
+ @_bg_hooks = {}
11
+ @options = Plugin.options_to_hash
12
+ end
13
+
14
+ # Define a hook that is executed when git-commands call these hook
15
+ # These is the very most important part of rgithook. These are all
16
+ # the hooks that you can run from git.
17
+ #
18
+ # # GIT_DIR/hooks/rgithook.rb (edit by rgithook -e)
19
+ #
20
+ # #These will make that you will never can commit anthing that brake the tests
21
+ # on :pre_commit do
22
+ # system(rake test)
23
+ # end
24
+ #
25
+ # #These will send test results of the master branch when the repo is updated
26
+ # on :post_receive do |old_rev,new_rev,ref|
27
+ # if ref =~ /master$/
28
+ # %x(rake test | mail -s 'Updated #{ref}' guillermo@cientifico.net)
29
+ # end
30
+ # end
31
+ #
32
+ # Also you can make the hooks run in a separate process with background option
33
+ #
34
+ # #These will run in background
35
+ # on :post_receive, :background => true do |old_rev,new_rev,ref|
36
+ # run_tests(repo) # These is a long runing operation
37
+ # end
38
+ #
39
+ # The abailable hooks within git docs are:
40
+ #
41
+ # * <em>on <b>:applypatch_msg</b> do |commit_msg_path| </em>- Check the commit log message
42
+ # taken by applypatch from an e-mail message.
43
+ # The hook should exit with non-zero status after issuing an
44
+ # appropriate message if it wants to stop the commit. The hook is
45
+ # allowed to edit the commit message file.<br/>
46
+ # <em>commit_msg_path</em> - Is the file_path of the commit_message
47
+ #
48
+ # * <em>on <b>:commit_msg</b> do |commit_msg_path| </em>- Check the commit log message.
49
+ # Called by git-commit with one argument, the name of the file
50
+ # that has the commit message. The hook should exit with non-zero
51
+ # status after issuing an appropriate message if it wants to stop the
52
+ # commit. The hook is allowed to edit the commit message file.
53
+ # These hook have *params*:
54
+ # <em>commit_msg_path</em> - Is the file_path of the commit_message
55
+ #
56
+ # * <em>on <b>:post_commit</b> do </em>- Is called after a successful commit is made.
57
+ #
58
+ # * <em>on <b>:post_receive</b> do |old_rev,new_rev,ref| </em>- Is run after receive-pack has accepted a pack
59
+ # and the repository has been updated. <em>old_rev</em>/<em>new_rev</em> Is the string old/new sha1 commit id.
60
+ # <em>ref</em> is the string of the updated ref (<em>ref/head/master</em>).
61
+ # These is the perfect hook to put your code in a bare central repo.
62
+ #
63
+ # # Send to the authors off the commits the results of their commits
64
+ # on :post_receive do |old_rev,new_rev,ref|
65
+ # if ref =~ /master$/
66
+ # emails = repo.commits_between(old_rev, new_rev).map{|c| c.author.email}.uniq
67
+ # test = %x(rake test)
68
+ # emails.each do |mail|
69
+ # IO.popen("mail -s 'Updated #{repo_name}' #{mail}",'w') {|mail| mail.write test}
70
+ # end
71
+ # end
72
+ # end
73
+ #
74
+ # * <em>on <b>:post_update</b> do</em> - Prepare a packed repository for use over
75
+ # dumb transports.
76
+ #
77
+ # * <em>on <b>:pre_apply_patch</b> do</em> - Verify what is about to be committed
78
+ # by applypatch from an e-mail message.
79
+ # The hook should return non zero after issuing an
80
+ # appropriate message if it wants to stop the commit.
81
+ #
82
+ # * <em>on <b>:pre_commit</b> do</em> - Verify what is about to be committed.
83
+ # Called by git-commit with no arguments. The hook should
84
+ # return non-zero after issuing an appropriate message if
85
+ # it wants to stop the commit.
86
+ #
87
+ # * <em>on <b>:pre_rebase</b> do</em> - Run just before "git-rebase" starts doing
88
+ # its job, and can prevent the command from running by exiting with
89
+ # non-zero status.
90
+ #
91
+ # * <em>on <b>:prepare_commit_msg</b> do |commit_msg_path,commit_src|</em> - Prepare the commit log message.
92
+ # Called by git-commit with the name of the file that has the
93
+ # commit message, followed by the description of the commit
94
+ # message's source. The hook's purpose is to edit the commit
95
+ # message file. If the hook returns non-zero status,
96
+ # the commit is aborted.
97
+ #
98
+ # In case of an unrescue exception rgithook will show a warning with the error and return 255 to git.
99
+ # In case of more than one block for the same hook, rgithook return to git the max value of all returns values of the same hook
100
+ #
101
+ #
102
+ def on(hook, options = {}, &block)
103
+ raise ArgumentError, "No block given for #{hook.to_s} in #{caller[0]}" unless block_given?
104
+ if HOOKS.include? hook.to_s
105
+ if options.delete(:background)
106
+ @_bg_hooks[hook] ||= []
107
+ @_bg_hooks[hook] << block
108
+ else
109
+ @_hooks[hook] ||= []
110
+ @_hooks[hook] << block
111
+ end
112
+ else
113
+ raise ArgumentError, "Not available hook #{hook.to_s} in #{caller[0]}"
114
+ end
115
+ end
116
+
117
+
118
+ # Run arbitrary code in runner context
119
+ def run(code,file=nil,line=nil)
120
+ file,line = caller.first.split(':') unless file && line
121
+ eval(code,binding,file,line.to_i)
122
+ end
123
+
124
+ def load(file)
125
+ hooks = File.file?(file) && File.read(file) || ''
126
+ eval(hooks, binding, file,0)
127
+ end
128
+
129
+ # Execute all the hooks defined in the configuration file
130
+ # Return a two dimension array. The first element is the outputs of the foreground_hooks.
131
+ # The second element is another array with the pids of the background_hooks
132
+ # fg_hook_val, bg_hook_val = @runner.run_hooks(hook_name)
133
+ def run_hooks(hook_name, *args)
134
+ Plugin.load!
135
+ [run_foreground_hooks(hook_name,*args),run_background_hooks(hook_name,*args)]
136
+ end
137
+
138
+
139
+
140
+
141
+ def run_foreground_hooks(hook_name,*args)
142
+ ret_vals = []
143
+ @_hooks[hook_name.to_sym] && @_hooks[hook_name.to_sym].each do |hook|
144
+ ret_vals << hook.call(*args)
145
+ end
146
+ ret_vals
147
+ end
148
+
149
+ # Execute all the hooks in a new process
150
+ # Return an array with the pids of each hook process
151
+ def run_background_hooks(hook_name, *args)
152
+ ret_vals = []
153
+ @_bg_hooks[hook_name.to_sym] && @_bg_hooks[hook_name.to_sym].each do |hook|
154
+ ret_vals << fork {hook.call(*args)}
155
+ end
156
+ ret_vals
157
+ end
158
+
159
+ def repo
160
+ @_repo
161
+ end
162
+
163
+ # Hash with all the plugin options
164
+ # option[:PluginName][:option] => option_value
165
+ #
166
+ # option[PluginClass.to_sym][:option_group][:option_name] => option_value
167
+ #
168
+ def options
169
+ @options
170
+ end
171
+
172
+ # ::nodoc::
173
+ def load_options(options_file)
174
+ @options = YAML.load(File.read(options_file)) if File.file?(options_file)
175
+ @options ||={}
176
+ end
177
+ end
178
+ end
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'rubygems'
4
+ require 'rgithook'
5
+
6
+ exit RGitHook::Hook.execute
@@ -0,0 +1,18 @@
1
+ # RGitHook hooks_file
2
+ # To define a hook just type:
3
+ #
4
+ # on :hook_name do |hook_params|
5
+ # ... Actions ...
6
+ # end
7
+ #
8
+ # Just simple.
9
+ #
10
+ # There is a few factory-made plugins ready to use
11
+ # * test (spec/cucumber/test::unit)
12
+ # * db Persisten layer for commit properties.
13
+
14
+
15
+
16
+
17
+
18
+
@@ -0,0 +1,70 @@
1
+
2
+
3
+ class Test::Unit::TestCase
4
+ def mock_repo
5
+ repo = mock('grit_repo')
6
+ repo.stubs(:'is_a?').with(::Grit::Repo).returns(true)
7
+ repo.stubs(:path).returns('path')
8
+ repo
9
+ end
10
+
11
+ def create_rgithook_instance
12
+ # This is not really a rgithook_instance ;-P
13
+ ::RGitHook::Plugin.stubs(:load!)
14
+ ::RGitHook::RGitHook.stubs(:parse_path).with(@repo).returns(@repo)
15
+ ::RGitHook::Runner.stubs(:new).with(@repo).returns(@runner)
16
+ @runner.stubs(:load_options).with('plugin_conf_file')
17
+ @runner.stubs(:load).with('hooks_file')
18
+ ::RGitHook::RGitHook.any_instance.stubs(:plugin_conf_file).returns('plugin_conf_file')
19
+ ::RGitHook::RGitHook.any_instance.stubs(:hooks_file).returns('hooks_file')
20
+ ::RGitHook::RGitHook.new(@repo)
21
+ end
22
+
23
+ def in_temp_dir(&block)
24
+ old_dir = Dir.pwd
25
+ raise LocalJumpError, 'no block given' unless block_given?
26
+
27
+ tmpdir = File.expand_path(File.join(Dir.tmpdir,'rgithook-'+Time.now.usec.to_s+rand.to_s[2..-1]))
28
+ FileUtils.mkdir_p(tmpdir)
29
+ Dir.chdir tmpdir
30
+ ret_val = yield tmpdir
31
+ Dir.chdir old_dir
32
+ FileUtils.remove_dir(tmpdir)
33
+ ret_val
34
+ end
35
+
36
+ def in_sample_repo
37
+ in_temp_dir do |temp_file|
38
+ %x(unzip #{fixture_path('sample_repo.zip')})
39
+ yield ::Grit::Repo.new(temp_file)
40
+ end
41
+ end
42
+
43
+
44
+ def with_sample_rgithook
45
+ in_sample_repo do |repo|
46
+ @rgithook = ::RGitHook::RGitHook.new(repo)
47
+ yield @rgithook
48
+ end
49
+ end
50
+
51
+ # Execute something in the runner
52
+ # @rgithook must exists
53
+ def in_runner(code,file=nil,line=nil)
54
+ file,line = caller.first.split(":") unless file && line
55
+ if @rgithook
56
+ @rgithook.run(code,file,line)
57
+ else
58
+ with_sample_rgithook do
59
+ RGitHook::Plugin.load!
60
+ @rgithook.run(code,file,line)
61
+ end
62
+ end
63
+ end
64
+
65
+ private
66
+ def fixture_path(fixture_name)
67
+ file = File.join(::RGitHook::PATH,'..','test','fixtures',fixture_name)
68
+ file if File.file?(file) or raise "Not found fixture in #{file}"
69
+ end
70
+ end
data/rgithook.gemspec ADDED
@@ -0,0 +1,42 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = %q{rgithook}
5
+ s.version = "3.0.2"
6
+
7
+ s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
8
+ s.authors = ["Guillermo \303\201lvarez"]
9
+ s.cert_chain = ["/Users/guillermo/.rubygems/gem-public_cert.pem"]
10
+ s.date = %q{2009-02-02}
11
+ s.default_executable = %q{rgithook}
12
+ s.description = %q{Ruby gem specify for git hooks.}
13
+ s.email = %q{guillermo@cientifico.net}
14
+ s.executables = ["rgithook"]
15
+ s.extra_rdoc_files = ["bin/rgithook", "CHANGELOG", "lib/plugins/custom.rb", "lib/plugins/db.rb", "lib/plugins/email.rb", "lib/plugins/html/commit.html.erb", "lib/plugins/html/diff.html.erb", "lib/plugins/html.rb", "lib/plugins/rake.rb", "lib/plugins/spec/rgithook_formatter.rb", "lib/plugins/spec/spec_result.rb", "lib/plugins/temp.rb", "lib/plugins/test.rb", "lib/plugins/twitter.rb", "lib/rgithook/command_line.rb", "lib/rgithook/hook.rb", "lib/rgithook/plugin.rb", "lib/rgithook/rgithook.rb", "lib/rgithook/runner.rb", "lib/rgithook/templates/hook.rb", "lib/rgithook/templates/rgithook.rb", "lib/rgithook/test/unit.rb", "lib/rgithook.rb", "README.rdoc", "TODO.txt"]
16
+ s.files = ["bin/rgithook", "CHANGELOG", "lib/plugins/custom.rb", "lib/plugins/db.rb", "lib/plugins/email.rb", "lib/plugins/html/commit.html.erb", "lib/plugins/html/diff.html.erb", "lib/plugins/html.rb", "lib/plugins/rake.rb", "lib/plugins/spec/rgithook_formatter.rb", "lib/plugins/spec/spec_result.rb", "lib/plugins/temp.rb", "lib/plugins/test.rb", "lib/plugins/twitter.rb", "lib/rgithook/command_line.rb", "lib/rgithook/hook.rb", "lib/rgithook/plugin.rb", "lib/rgithook/rgithook.rb", "lib/rgithook/runner.rb", "lib/rgithook/templates/hook.rb", "lib/rgithook/templates/rgithook.rb", "lib/rgithook/test/unit.rb", "lib/rgithook.rb", "Manifest", "Rakefile", "README.rdoc", "rgithook.gemspec", "test/fixtures/sample_plugin.rb", "test/fixtures/sample_repo.zip", "test/integration/test_install.rb", "test/integration/test_pull_and_push.rb", "test/plugins/test_email.rb", "test/plugins/test_html.rb", "test/plugins/test_spec.rb", "test/plugins/test_test.rb", "test/test_helper.rb", "test/unit/test_command_line.rb", "test/unit/test_hook.rb", "test/unit/test_plugin.rb", "test/unit/test_rgithook.rb", "test/unit/test_runner.rb", "TODO.txt"]
17
+ s.has_rdoc = true
18
+ s.homepage = %q{http://github.com/guillermo/rgithook2}
19
+ s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Rgithook", "--main", "README.rdoc"]
20
+ s.require_paths = ["lib"]
21
+ s.rubyforge_project = %q{rgithook}
22
+ s.rubygems_version = %q{1.3.1}
23
+ s.signing_key = %q{/Users/guillermo/.rubygems/gem-private_key.pem}
24
+ s.summary = %q{You can deploy updated code, restart the web server, run the tests, email the diff, etc... You can use a cron to pull or a githook to run when pushed to the repo.}
25
+ s.test_files = ["test/integration/test_install.rb", "test/integration/test_pull_and_push.rb", "test/plugins/test_email.rb", "test/plugins/test_html.rb", "test/plugins/test_spec.rb", "test/plugins/test_test.rb", "test/test_helper.rb", "test/unit/test_command_line.rb", "test/unit/test_hook.rb", "test/unit/test_plugin.rb", "test/unit/test_rgithook.rb", "test/unit/test_runner.rb"]
26
+
27
+ if s.respond_to? :specification_version then
28
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
29
+ s.specification_version = 2
30
+
31
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
32
+ s.add_runtime_dependency(%q<mojombo-grit>, [">= 0"])
33
+ s.add_development_dependency(%q<mocha>, [">= 0"])
34
+ else
35
+ s.add_dependency(%q<mojombo-grit>, [">= 0"])
36
+ s.add_dependency(%q<mocha>, [">= 0"])
37
+ end
38
+ else
39
+ s.add_dependency(%q<mojombo-grit>, [">= 0"])
40
+ s.add_dependency(%q<mocha>, [">= 0"])
41
+ end
42
+ end
@@ -0,0 +1,28 @@
1
+ class SamplePluginException < Exception ; end
2
+
3
+ module OtherApp
4
+ class SamplePlugin < ::RGitHook::Plugin
5
+
6
+ option :test_option, 'Test Option description', :default_value, Symbol
7
+
8
+ option_group :test_group, 'Test Option group' do |opt_group|
9
+ opt_group.option :test_option_group_option, 'Test OptionGroup Option', :default_value, Symbol
10
+ end
11
+
12
+ module RunnerMethods
13
+ def test_method
14
+ 'test_result'
15
+ end
16
+
17
+ def raised_method
18
+ raise SamplePluginException
19
+ end
20
+ end
21
+
22
+ module GritCommit
23
+ def test_method
24
+ end
25
+ end
26
+ end
27
+
28
+ end
Binary file
@@ -0,0 +1,68 @@
1
+ require File.dirname(__FILE__)+'/../test_helper'
2
+
3
+ class IntegrationTest < Test::Unit::TestCase
4
+
5
+ def test_inastall_without_confirmation
6
+ in_sample_repo do
7
+ @repo = ::RGitHook::RGitHook.new('.')
8
+ @repo.install(false)
9
+ assert File.file?('.git/hooks/rgithook.rb')
10
+ assert File.file?('.git/hooks/applypatch-msg')
11
+ assert File.file?('.git/hooks/commit-msg')
12
+ assert File.file?('.git/hooks/post-commit')
13
+ assert File.file?('.git/hooks/post-receive')
14
+ assert File.file?('.git/hooks/post-update')
15
+ assert File.file?('.git/hooks/pre-applypatch')
16
+ assert File.file?('.git/hooks/pre-commit')
17
+ assert File.file?('.git/hooks/pre-rebase')
18
+ assert File.file?('.git/hooks/prepare-commit-msg')
19
+ assert File.file?('.git/hooks/update')
20
+ end
21
+ end
22
+
23
+ def test_simple_hook
24
+ with_sample_rgithook do
25
+ File.open(@rgithook.conf_file,'w') do |f|
26
+ hook_file =<<-EOF
27
+ on :post_receive do |old_commit,new_commit,ref|
28
+ %x(touch \#{old_commit})
29
+ %x(touch \#{new_commit})
30
+ %x(touch \#{ref})
31
+ end
32
+
33
+ on :pre_commit do
34
+ %x(rm a b c)
35
+ end
36
+ EOF
37
+ f.write(hook_file)
38
+ end
39
+
40
+ @rgithook = RGitHook::RGitHook.new('.')
41
+ @rgithook.post_receive('a','b','c')
42
+ assert File.file?('a')
43
+ assert File.file?('b')
44
+ assert File.file?('c')
45
+ @rgithook.pre_commit
46
+ assert !File.file?('a')
47
+ assert !File.file?('b')
48
+ assert !File.file?('c')
49
+ end
50
+ end
51
+
52
+ def test_project_name
53
+ with_sample_rgithook do
54
+ assert_match /^rgithook-(.*)/, @rgithook.project_name
55
+ end
56
+ end
57
+
58
+ def test_plugin_options
59
+
60
+ in_sample_repo do
61
+ @repo = RGitHook::RGitHook.new('.')
62
+ @repo.install(false)
63
+ @repo.save_plugin_options
64
+ assert File.file?('.git/hooks/rgithook.yaml')
65
+
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,20 @@
1
+ require File.dirname(__FILE__)+'/../test_helper'
2
+
3
+
4
+ class FetchPullPushTest < Test::Unit::TestCase
5
+
6
+ def test_a_default_installation
7
+ with_sample_rgithook do |rgithook1|
8
+ rgithook1.install(false)
9
+
10
+ in_temp_dir do |dir|
11
+ %x(git clone #{rgithook1.path} sample_test)
12
+ Dir.chdir 'sample_test'
13
+ %x(touch asdf && git add . && git commit -m 'adf')
14
+ push_result = %x(git push)
15
+ assert_equal $?.to_i, 0, "Error:\n#{push_result}"
16
+ end
17
+ end
18
+
19
+ end
20
+ end
@@ -0,0 +1,8 @@
1
+
2
+
3
+ class EmailPluginTest < Test::Unit::TestCase
4
+
5
+ def test_email
6
+ in_runner "email('guillermo@cientifico.net','hello')"
7
+ end
8
+ end