githooker 0.2.0 → 0.2.10
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile +2 -12
- data/Gemfile.lock +56 -0
- data/Rakefile +2 -7
- data/VERSION +1 -1
- data/bin/githook +84 -0
- data/githooker.gemspec +12 -23
- data/lib/githooker.rb +9 -5
- data/lib/githooker/action.rb +62 -31
- data/lib/githooker/hook.rb +24 -16
- data/lib/githooker/repo.rb +22 -0
- data/lib/githooker/runner.rb +11 -8
- data/lib/githooker/section.rb +45 -16
- data/lib/githooker/terminal_colors.rb +6 -1
- data/thoughts.txt +78 -0
- metadata +12 -90
data/Gemfile
CHANGED
@@ -1,19 +1,9 @@
|
|
1
1
|
source "http://rubygems.org"
|
2
|
-
# Add dependencies required to use your gem here.
|
3
|
-
# Example:
|
4
|
-
# gem "activesupport", ">= 2.3.5"
|
5
2
|
|
6
|
-
|
7
|
-
|
3
|
+
gem 'colorize', '~> 0.5.8'
|
4
|
+
|
8
5
|
group :development do
|
9
6
|
gem "awesome_print", ">= 0"
|
10
|
-
gem "shoulda", ">= 0"
|
11
|
-
gem "yard", "~> 0.7"
|
12
|
-
gem "rdoc", "~> 3.12"
|
13
|
-
gem "cucumber", ">= 0"
|
14
7
|
gem "bundler", ">= 0"
|
15
8
|
gem "jeweler", "~> 1.8.4"
|
16
|
-
gem "simplecov", ">= 0"
|
17
9
|
end
|
18
|
-
|
19
|
-
gem "inifile", "~> 2.0"
|
data/Gemfile.lock
ADDED
@@ -0,0 +1,56 @@
|
|
1
|
+
GEM
|
2
|
+
remote: http://rubygems.org/
|
3
|
+
specs:
|
4
|
+
addressable (2.3.5)
|
5
|
+
awesome_print (1.1.0)
|
6
|
+
builder (3.2.2)
|
7
|
+
colorize (0.5.8)
|
8
|
+
faraday (0.8.8)
|
9
|
+
multipart-post (~> 1.2.0)
|
10
|
+
git (1.2.5)
|
11
|
+
github_api (0.10.1)
|
12
|
+
addressable
|
13
|
+
faraday (~> 0.8.1)
|
14
|
+
hashie (>= 1.2)
|
15
|
+
multi_json (~> 1.4)
|
16
|
+
nokogiri (~> 1.5.2)
|
17
|
+
oauth2
|
18
|
+
hashie (2.0.5)
|
19
|
+
highline (1.6.19)
|
20
|
+
httpauth (0.2.0)
|
21
|
+
jeweler (1.8.7)
|
22
|
+
builder
|
23
|
+
bundler (~> 1.0)
|
24
|
+
git (>= 1.2.5)
|
25
|
+
github_api (= 0.10.1)
|
26
|
+
highline (>= 1.6.15)
|
27
|
+
nokogiri (= 1.5.10)
|
28
|
+
rake
|
29
|
+
rdoc
|
30
|
+
json (1.8.0)
|
31
|
+
jwt (0.1.8)
|
32
|
+
multi_json (>= 1.5)
|
33
|
+
multi_json (1.7.9)
|
34
|
+
multi_xml (0.5.5)
|
35
|
+
multipart-post (1.2.0)
|
36
|
+
nokogiri (1.5.10)
|
37
|
+
oauth2 (0.9.2)
|
38
|
+
faraday (~> 0.8)
|
39
|
+
httpauth (~> 0.2)
|
40
|
+
jwt (~> 0.1.4)
|
41
|
+
multi_json (~> 1.0)
|
42
|
+
multi_xml (~> 0.5)
|
43
|
+
rack (~> 1.2)
|
44
|
+
rack (1.5.2)
|
45
|
+
rake (10.1.0)
|
46
|
+
rdoc (3.12.2)
|
47
|
+
json (~> 1.4)
|
48
|
+
|
49
|
+
PLATFORMS
|
50
|
+
ruby
|
51
|
+
|
52
|
+
DEPENDENCIES
|
53
|
+
awesome_print
|
54
|
+
bundler
|
55
|
+
colorize (~> 0.5.8)
|
56
|
+
jeweler (~> 1.8.4)
|
data/Rakefile
CHANGED
@@ -23,6 +23,8 @@ Jeweler::Tasks.new do |gem|
|
|
23
23
|
gem.description = %Q{GitHooker provides a framework for building test that can be used with git hooks}
|
24
24
|
gem.email = "rabbitt@gmail.com"
|
25
25
|
gem.authors = ["Carl P. Corliss"]
|
26
|
+
gem.executables = ['githook']
|
27
|
+
gem.files += Dir['bin/*']
|
26
28
|
# dependencies defined in Gemfile
|
27
29
|
end
|
28
30
|
Jeweler::RubygemsDotOrgTasks.new
|
@@ -34,10 +36,3 @@ Rake::TestTask.new(:test) do |test|
|
|
34
36
|
test.verbose = true
|
35
37
|
end
|
36
38
|
|
37
|
-
require 'cucumber/rake/task'
|
38
|
-
Cucumber::Rake::Task.new(:features)
|
39
|
-
|
40
|
-
task :default => :test
|
41
|
-
|
42
|
-
require 'yard'
|
43
|
-
YARD::Rake::YardocTask.new
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.2.
|
1
|
+
0.2.10
|
data/bin/githook
ADDED
@@ -0,0 +1,84 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
# Sublime Text 2 Settings
|
4
|
+
# sublime: x_syntax Packages/Ruby/Ruby.tmLanguage
|
5
|
+
# sublime: translate_tabs_to_spaces true
|
6
|
+
# sublime: tab_size 2
|
7
|
+
|
8
|
+
require 'optparse'
|
9
|
+
require 'ostruct'
|
10
|
+
require 'commander/import'
|
11
|
+
|
12
|
+
begin
|
13
|
+
require 'githooker'
|
14
|
+
rescue GitHooker::Repo::NotAGitRepoError
|
15
|
+
puts "Please switch to a git repository directory."
|
16
|
+
exit 1
|
17
|
+
end
|
18
|
+
|
19
|
+
program :name, 'Foo Bar'
|
20
|
+
program :version, '1.0.0'
|
21
|
+
program :description, 'Stupid command that prints foo or bar.'
|
22
|
+
|
23
|
+
GIT_HOOKS = %w(
|
24
|
+
pre-commit prepare-commit-msg commit-msg post-commit
|
25
|
+
applypatch-msg pre-applypatch post-applypatch
|
26
|
+
pre-rebase post-merge
|
27
|
+
update post-update
|
28
|
+
)
|
29
|
+
|
30
|
+
COMMANDS = %w(stub remove show edit run).collect(&:to_sym)
|
31
|
+
|
32
|
+
STUB_TEMPLATE = <<-EOF
|
33
|
+
#!/usr/bin/env ruby
|
34
|
+
|
35
|
+
require 'githooker'
|
36
|
+
|
37
|
+
GitHooker::Hook.register do
|
38
|
+
section "General"
|
39
|
+
perform ""
|
40
|
+
end
|
41
|
+
|
42
|
+
GitHooker::Runner.start
|
43
|
+
|
44
|
+
EOF
|
45
|
+
|
46
|
+
def usage(error_message = nil, quit = true)
|
47
|
+
$stderr.puts "Error: #{error_message}" if error_message
|
48
|
+
$stderr.puts "Usage: #{Pathname.new($0).basename} COMMAND"
|
49
|
+
$stderr.puts "COMMANDS:"
|
50
|
+
$stderr.puts " assign action <hook> - generates a basic stub for the given <hook>, "
|
51
|
+
$stderr.puts " or all hooks if 'all' is specified"
|
52
|
+
$stderr.puts " list [hook] - removes the given <hook>, or all hooks if "
|
53
|
+
$stderr.puts " 'all' is specified"
|
54
|
+
$stderr.puts " run <hook> - runs the given hook in unstaged mode (specify"
|
55
|
+
$stderr.puts " --stage to use staged mode)"
|
56
|
+
$stderr.puts
|
57
|
+
exit 1 if quit
|
58
|
+
end
|
59
|
+
|
60
|
+
usage unless ARGV.size >= 2
|
61
|
+
|
62
|
+
staged = !!ARGV.delete('--staged')
|
63
|
+
|
64
|
+
command = ARGV.shift.downcase.to_sym
|
65
|
+
usage("invalid command '#{command}'") unless COMMANDS.include? command
|
66
|
+
|
67
|
+
hooks = (ARGV.shift.split(/,/) rescue [])
|
68
|
+
usage("no valid hook provided") if hooks.empty?
|
69
|
+
if !hooks.include?('all') && (hooks - GIT_HOOKS).size > 0
|
70
|
+
usage("Unsupported hook types: #{(hooks - GIT_HOOKS).join(', ')}\nValid Hooks: #{GIT_HOOKS.join(', ')}\n\n")
|
71
|
+
end
|
72
|
+
hooks = GIT_HOOKS.dup if hooks.include? 'all'
|
73
|
+
|
74
|
+
case command
|
75
|
+
when :stub then
|
76
|
+
Dir.chdir GitHooker::REPO_ROOT
|
77
|
+
hooks.each do |hook|
|
78
|
+
File.open
|
79
|
+
when :remove then
|
80
|
+
when :show then
|
81
|
+
when :edit then
|
82
|
+
when :run then
|
83
|
+
end
|
84
|
+
|
data/githooker.gemspec
CHANGED
@@ -5,13 +5,14 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = "githooker"
|
8
|
-
s.version = "0.2.
|
8
|
+
s.version = "0.2.10"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Carl P. Corliss"]
|
12
|
-
s.date = "
|
12
|
+
s.date = "2014-02-27"
|
13
13
|
s.description = "GitHooker provides a framework for building test that can be used with git hooks"
|
14
14
|
s.email = "rabbitt@gmail.com"
|
15
|
+
s.executables = ["githook"]
|
15
16
|
s.extra_rdoc_files = [
|
16
17
|
"LICENSE.txt",
|
17
18
|
"README.md",
|
@@ -20,11 +21,13 @@ Gem::Specification.new do |s|
|
|
20
21
|
s.files = [
|
21
22
|
".document",
|
22
23
|
"Gemfile",
|
24
|
+
"Gemfile.lock",
|
23
25
|
"LICENSE.txt",
|
24
26
|
"README.md",
|
25
27
|
"README.rdoc",
|
26
28
|
"Rakefile",
|
27
29
|
"VERSION",
|
30
|
+
"bin/githook",
|
28
31
|
"features/githooker.feature",
|
29
32
|
"features/step_definitions/githooker_steps.rb",
|
30
33
|
"features/support/env.rb",
|
@@ -44,48 +47,34 @@ Gem::Specification.new do |s|
|
|
44
47
|
"lib/githooker/section.rb",
|
45
48
|
"lib/githooker/terminal_colors.rb",
|
46
49
|
"test/helper.rb",
|
47
|
-
"test/test_githooker.rb"
|
50
|
+
"test/test_githooker.rb",
|
51
|
+
"thoughts.txt"
|
48
52
|
]
|
49
53
|
s.homepage = "http://github.com/rabbitt/githooker"
|
50
54
|
s.licenses = ["GPLv2"]
|
51
55
|
s.require_paths = ["lib"]
|
52
|
-
s.rubygems_version = "
|
56
|
+
s.rubygems_version = "2.0.14"
|
53
57
|
s.summary = "framework for building git hooks tests"
|
54
58
|
|
55
59
|
if s.respond_to? :specification_version then
|
56
|
-
s.specification_version =
|
60
|
+
s.specification_version = 4
|
57
61
|
|
58
62
|
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
59
|
-
s.add_runtime_dependency(%q<
|
63
|
+
s.add_runtime_dependency(%q<colorize>, ["~> 0.5.8"])
|
60
64
|
s.add_development_dependency(%q<awesome_print>, [">= 0"])
|
61
|
-
s.add_development_dependency(%q<shoulda>, [">= 0"])
|
62
|
-
s.add_development_dependency(%q<yard>, ["~> 0.7"])
|
63
|
-
s.add_development_dependency(%q<rdoc>, ["~> 3.12"])
|
64
|
-
s.add_development_dependency(%q<cucumber>, [">= 0"])
|
65
65
|
s.add_development_dependency(%q<bundler>, [">= 0"])
|
66
66
|
s.add_development_dependency(%q<jeweler>, ["~> 1.8.4"])
|
67
|
-
s.add_development_dependency(%q<simplecov>, [">= 0"])
|
68
67
|
else
|
69
|
-
s.add_dependency(%q<
|
68
|
+
s.add_dependency(%q<colorize>, ["~> 0.5.8"])
|
70
69
|
s.add_dependency(%q<awesome_print>, [">= 0"])
|
71
|
-
s.add_dependency(%q<shoulda>, [">= 0"])
|
72
|
-
s.add_dependency(%q<yard>, ["~> 0.7"])
|
73
|
-
s.add_dependency(%q<rdoc>, ["~> 3.12"])
|
74
|
-
s.add_dependency(%q<cucumber>, [">= 0"])
|
75
70
|
s.add_dependency(%q<bundler>, [">= 0"])
|
76
71
|
s.add_dependency(%q<jeweler>, ["~> 1.8.4"])
|
77
|
-
s.add_dependency(%q<simplecov>, [">= 0"])
|
78
72
|
end
|
79
73
|
else
|
80
|
-
s.add_dependency(%q<
|
74
|
+
s.add_dependency(%q<colorize>, ["~> 0.5.8"])
|
81
75
|
s.add_dependency(%q<awesome_print>, [">= 0"])
|
82
|
-
s.add_dependency(%q<shoulda>, [">= 0"])
|
83
|
-
s.add_dependency(%q<yard>, ["~> 0.7"])
|
84
|
-
s.add_dependency(%q<rdoc>, ["~> 3.12"])
|
85
|
-
s.add_dependency(%q<cucumber>, [">= 0"])
|
86
76
|
s.add_dependency(%q<bundler>, [">= 0"])
|
87
77
|
s.add_dependency(%q<jeweler>, ["~> 1.8.4"])
|
88
|
-
s.add_dependency(%q<simplecov>, [">= 0"])
|
89
78
|
end
|
90
79
|
end
|
91
80
|
|
data/lib/githooker.rb
CHANGED
@@ -3,6 +3,7 @@
|
|
3
3
|
require 'pathname'
|
4
4
|
require 'githooker/core_ext'
|
5
5
|
|
6
|
+
|
6
7
|
module GitHooker
|
7
8
|
autoload :Hook, 'githooker/hook'
|
8
9
|
autoload :Repo, 'githooker/repo'
|
@@ -10,20 +11,23 @@ module GitHooker
|
|
10
11
|
autoload :Section, 'githooker/section'
|
11
12
|
autoload :Action, 'githooker/action'
|
12
13
|
autoload :TerminalColors, 'githooker/terminal_colors'
|
13
|
-
autoload :
|
14
|
+
autoload :NotAGitRepoError, 'githooker/repo'
|
15
|
+
autoload :RegistrationError, 'githooker/hook'
|
14
16
|
|
15
17
|
LIB_PATH = Pathname.new(__FILE__).dirname
|
16
18
|
GEM_PATH = LIB_PATH.parent
|
17
19
|
|
18
|
-
SCRIPT_NAME
|
19
|
-
SCRIPT_DIR
|
20
|
-
SCRIPT_PATH
|
20
|
+
SCRIPT_NAME = Pathname.new($0).basename.to_s
|
21
|
+
SCRIPT_DIR = Pathname.new($0).dirname.realpath
|
22
|
+
SCRIPT_PATH = SCRIPT_DIR + SCRIPT_NAME
|
21
23
|
|
22
|
-
REPO_ROOT = Pathname.new(
|
24
|
+
REPO_ROOT = (path = Repo::root_path).empty? ? SCRIPT_DIR : Pathname.new(path)
|
23
25
|
|
24
26
|
HOOK_NAME = SCRIPT_NAME.to_s.underscore.to_sym
|
25
27
|
|
26
28
|
VERSION = IO.read(GEM_PATH + 'VERSION')
|
29
|
+
|
30
|
+
VALID_PHASES = %w{ any pre-commit post-commit commit-msg }.collect(&:to_sym).freeze
|
27
31
|
end
|
28
32
|
|
29
33
|
# # # --- commit_hooks.rb
|
data/lib/githooker/action.rb
CHANGED
@@ -5,67 +5,98 @@ require 'open3'
|
|
5
5
|
module GitHooker
|
6
6
|
class Action
|
7
7
|
include TerminalColors
|
8
|
-
include Repo
|
9
8
|
|
10
|
-
attr_reader :errors, :warnings, :title, :success
|
9
|
+
attr_reader :errors, :warnings, :title, :success, :phase
|
11
10
|
|
12
|
-
def initialize(title, &block)
|
11
|
+
def initialize(title, phase, &block)
|
13
12
|
raise ArgumentError, "Missing required block for Action#new" unless block_given?
|
14
13
|
|
14
|
+
phase = phase.to_s.to_sym
|
15
|
+
unless GitHooker::VALID_PHASES.include? phase
|
16
|
+
raise ArgumentError, "Phase must be one of #{GitHooker::VALID_PHASES.join(', ')}"
|
17
|
+
end
|
18
|
+
|
15
19
|
@title = title.to_s.titleize
|
16
20
|
@success = true
|
21
|
+
@phase = phase || :any
|
17
22
|
@errors = []
|
18
23
|
@warnings = []
|
19
|
-
@action = block
|
20
|
-
end
|
24
|
+
@action = DSL.new(block)
|
21
25
|
|
22
|
-
|
23
|
-
|
24
|
-
def title()
|
25
|
-
success_colored @title
|
26
|
+
waiting!
|
26
27
|
end
|
27
28
|
|
28
|
-
def
|
29
|
-
|
30
|
-
success_colored symbol
|
29
|
+
def colored_title()
|
30
|
+
status_colorize title
|
31
31
|
end
|
32
32
|
|
33
|
-
def
|
34
|
-
success? ?
|
33
|
+
def state_symbol
|
34
|
+
symbol = finished? ? (success? ? "✓" : 'X') : '?'
|
35
|
+
status_colorize symbol
|
35
36
|
end
|
36
37
|
|
37
|
-
def
|
38
|
-
block = block || options.delete(:call)
|
39
|
-
Repo.match_files_on(options).collect { |file|
|
40
|
-
block.call(file)
|
41
|
-
}.all? # test that they all returned true
|
42
|
-
end
|
38
|
+
def success?() @success; end
|
43
39
|
|
44
|
-
def
|
45
|
-
|
40
|
+
def finished?() @status == :finished; end
|
41
|
+
def finished!() @status = :finished; end
|
46
42
|
|
47
|
-
|
48
|
-
|
49
|
-
end
|
43
|
+
def running?() @status == :running; end
|
44
|
+
def running!() @status = :running; end
|
50
45
|
|
51
|
-
|
52
|
-
|
53
|
-
end
|
46
|
+
def waiting?() @status == :waiting; end
|
47
|
+
def waiting!() @status = :waiting; end
|
54
48
|
|
55
|
-
|
56
|
-
|
49
|
+
def status_colorize(text)
|
50
|
+
finished? ? (success? ? bright_green(text) : bright_red(text)) : dark_cyan(text)
|
57
51
|
end
|
58
52
|
|
59
53
|
def run
|
60
54
|
warnings, errors = StringIO.new, StringIO.new
|
61
55
|
begin
|
56
|
+
running!
|
62
57
|
$stdout, $stderr = warnings, errors
|
63
|
-
@success &=
|
58
|
+
@success &= @action.call
|
64
59
|
return @success
|
65
60
|
ensure
|
66
61
|
@errors = errors.tap {|e| e.rewind}.read.split(/\n(?:[\t ]*)/)
|
67
62
|
@warnings = warnings.tap {|w| w.rewind}.read.split(/\n(?:[\t ]*)/)
|
68
63
|
$stdout, $stderr = STDOUT, STDERR
|
64
|
+
finished!
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
class DSL
|
69
|
+
include Repo
|
70
|
+
|
71
|
+
def initialize(block)
|
72
|
+
@block = block
|
73
|
+
end
|
74
|
+
|
75
|
+
def call() instance_eval(&@block); end
|
76
|
+
|
77
|
+
# DSL Methods
|
78
|
+
def args() ARGV.dup; end
|
79
|
+
|
80
|
+
def on(options = {}, &block)
|
81
|
+
block = block || options.delete(:call)
|
82
|
+
Repo.match_files_on(options).collect { |file|
|
83
|
+
block.call(file)
|
84
|
+
}.all? # test that they all returned true
|
85
|
+
end
|
86
|
+
|
87
|
+
def execute(cmd, output_line_prefix=nil)
|
88
|
+
Open3.popen3(cmd) { |i, o, e, t|
|
89
|
+
|
90
|
+
o.read.split(/\n/).each do |line|
|
91
|
+
$stdout.puts output_line_prefix ? "#{output_line_prefix}: #{line}" : line
|
92
|
+
end
|
93
|
+
|
94
|
+
e.read.split(/\n/).each do |line|
|
95
|
+
$stderr.puts output_line_prefix ? "#{output_line_prefix}: #{line}" : line
|
96
|
+
end
|
97
|
+
|
98
|
+
t.value
|
99
|
+
}.success?
|
69
100
|
end
|
70
101
|
end
|
71
102
|
end
|
data/lib/githooker/hook.rb
CHANGED
@@ -7,42 +7,50 @@ module GitHooker
|
|
7
7
|
|
8
8
|
def self.method_missing(*args, &block)
|
9
9
|
return super unless self.instance.respond_to? args.first
|
10
|
-
self.instance.
|
11
|
-
end
|
12
|
-
|
13
|
-
def run
|
14
|
-
@hooks.all? { |hook| hook.run }
|
10
|
+
self.instance.send(*args, &block)
|
15
11
|
end
|
16
12
|
|
17
13
|
def initialize
|
18
|
-
@
|
19
|
-
@section
|
14
|
+
@sections = []
|
15
|
+
@section = nil
|
20
16
|
end
|
21
17
|
|
22
|
-
def register(&block)
|
18
|
+
def register(options = {}, &block)
|
23
19
|
raise ArgumentError, "Missing required block to #register" unless block_given?
|
24
|
-
|
20
|
+
|
21
|
+
@phase = (options.delete(:phase) || :any).to_s.to_sym
|
22
|
+
unless GitHooker::VALID_PHASES.include? phase
|
23
|
+
raise ArgumentError, "Phase must be one of #{GitHooker::VALID_PHASES.join(', ')}"
|
24
|
+
end
|
25
|
+
|
26
|
+
instance_eval(&block) if Repo.match_phase(@phase)
|
25
27
|
self
|
26
28
|
end
|
27
29
|
|
30
|
+
def run
|
31
|
+
@sections.collect { |section| section.run }.all?
|
32
|
+
end
|
33
|
+
|
34
|
+
# DSL methods
|
35
|
+
|
28
36
|
def section(name)
|
29
|
-
@
|
37
|
+
@sections << (@section = Section.new(name))
|
30
38
|
self
|
31
39
|
end
|
32
40
|
|
33
41
|
def sections
|
34
|
-
@
|
42
|
+
@sections
|
35
43
|
end
|
36
44
|
|
37
|
-
def
|
38
|
-
raise RegistrationError, "#
|
39
|
-
@section.
|
45
|
+
def stop_on_error(value)
|
46
|
+
raise RegistrationError, "#stop_on_error called before section defined" unless @section
|
47
|
+
@section.stop_on_error = value
|
40
48
|
end
|
41
49
|
|
42
|
-
def perform(title, &block)
|
50
|
+
def perform(title, options = {}, &block)
|
43
51
|
raise RegistrationError, "#perform called before section defined" unless @section
|
44
52
|
raise ArgumentError, "Missing required block to #perform" unless block_given?
|
45
|
-
@section << Action.new(title, &block)
|
53
|
+
@section << Action.new(title, options.delete(:phase) || @phase, &block)
|
46
54
|
end
|
47
55
|
end
|
48
56
|
end
|
data/lib/githooker/repo.rb
CHANGED
@@ -14,8 +14,25 @@ module GitHooker
|
|
14
14
|
|
15
15
|
DEFAULT_DIFF_INDEX_OPTIONS = { :staged => true, :ref => 'HEAD' }
|
16
16
|
|
17
|
+
class NotAGitRepoError < StandardError; end
|
18
|
+
|
17
19
|
public
|
18
20
|
|
21
|
+
def root_path
|
22
|
+
%x{git rev-parse --show-toplevel 2>&1}.strip.tap { |path|
|
23
|
+
if $? != 0 && path =~ /Not a git repository/
|
24
|
+
# attempt to find the repo
|
25
|
+
warn "couldn't find a git repository in the current path #{Dir.getwd}"
|
26
|
+
return path unless (path = %x{ cd #{GitHooker::SCRIPT_DIR.to_s}; git rev-parse --show-toplevel 2>&1 }) =~ /Not a git repository/
|
27
|
+
unless GitHooker::SCRIPT_NAME == 'irb'
|
28
|
+
raise NotAGitRepoError, "Unable to find a valid git repository"
|
29
|
+
end
|
30
|
+
warn "GitHooker::REPO_ROOT is not set - Use GitHooker::Repo.root_path once you've changed the current directory to a git repo"
|
31
|
+
return ''
|
32
|
+
end
|
33
|
+
}
|
34
|
+
end
|
35
|
+
|
19
36
|
def while_stashed
|
20
37
|
raise ArgumentError, "Missing required block" unless block_given?
|
21
38
|
begin
|
@@ -74,6 +91,11 @@ module GitHooker
|
|
74
91
|
}.values
|
75
92
|
end
|
76
93
|
|
94
|
+
def match_phase(phase = :any)
|
95
|
+
return true if phase == :any
|
96
|
+
return GitHooker::SCRIPT_NAME.to_sym == phase.to_s.to_sym
|
97
|
+
end
|
98
|
+
|
77
99
|
def match_file(file, matchtype, matchvalue)
|
78
100
|
attr_value = case matchtype
|
79
101
|
when :name then file.path
|
data/lib/githooker/runner.rb
CHANGED
@@ -10,22 +10,25 @@ module GitHooker
|
|
10
10
|
|
11
11
|
Hook.sections.each do |section|
|
12
12
|
hash_tail_length = (max_section_length - section.name.length)
|
13
|
-
printf "===== %s %s=====\n", section.
|
13
|
+
printf "===== %s %s=====\n", section.colored_name, ("=" * hash_tail_length)
|
14
14
|
|
15
|
-
|
16
|
-
|
15
|
+
shown_incomplete = false
|
16
|
+
section.actions.each_with_index do |action, index|
|
17
|
+
if not section.completed? and action.waiting? and not shown_incomplete
|
18
|
+
shown_incomplete = true
|
19
|
+
puts bright_yellow(" -- this section incomplete due 'stop_on_error' setting and previous errors -- ")
|
20
|
+
end
|
21
|
+
|
22
|
+
printf " %d. [ %s ] %s\n", (index + 1), action.state_symbol, action.colored_title
|
17
23
|
|
18
24
|
action.errors.each do |error|
|
19
|
-
printf " %s %s\n", bright_red(
|
25
|
+
printf " %s %s\n", bright_red(MARK_FAILURE), error
|
20
26
|
end unless action.errors.empty?
|
21
27
|
|
22
28
|
action.warnings.each do |warning|
|
23
|
-
printf " %s %s\n", ( action.success? ? bright_green(
|
29
|
+
printf " %s %s\n", ( action.success? ? bright_green(MARK_SUCCESS) : bright_yellow(MARK_UNKNOWN) ), warning
|
24
30
|
end unless action.warnings.empty?
|
25
|
-
|
26
|
-
exit 1 if section.exit_on_error and not action.errors.empty?
|
27
31
|
end
|
28
|
-
|
29
32
|
puts
|
30
33
|
end
|
31
34
|
|
data/lib/githooker/section.rb
CHANGED
@@ -4,33 +4,62 @@ module GitHooker
|
|
4
4
|
class Section < DelegateClass(Array)
|
5
5
|
include TerminalColors
|
6
6
|
|
7
|
-
|
8
|
-
attr_accessor :exit_on_error
|
9
|
-
|
10
|
-
attr_reader :actions
|
11
|
-
alias :__getobj__ :actions
|
7
|
+
attr_accessor :stop_on_error
|
12
8
|
|
13
9
|
def initialize(name)
|
14
10
|
@name = name.to_s.titleize
|
15
11
|
@success = true
|
16
|
-
@
|
12
|
+
@stop_on_error = false
|
17
13
|
@actions = []
|
14
|
+
|
15
|
+
waiting!
|
16
|
+
end
|
17
|
+
|
18
|
+
def actions
|
19
|
+
@actions.collect { |action| Repo.match_phase(action.phase) }
|
20
|
+
end
|
21
|
+
alias :__getobj__ :actions
|
22
|
+
|
23
|
+
def stop_on_error?() @stop_on_error; end
|
24
|
+
|
25
|
+
def success?() @success; end
|
26
|
+
|
27
|
+
def finished?() @status == :finished; end
|
28
|
+
def finished!() @status = :finished; end
|
29
|
+
|
30
|
+
def running?() @status == :running; end
|
31
|
+
def running!() @status = :running; end
|
32
|
+
|
33
|
+
def waiting?() @status == :waiting; end
|
34
|
+
def waiting!() @status = :waiting; end
|
35
|
+
|
36
|
+
def completed?
|
37
|
+
@actions.all? { |action| action.finished? }
|
38
|
+
end
|
39
|
+
|
40
|
+
def wait_count()
|
41
|
+
@actions.select { |action| action.waiting? }.size
|
18
42
|
end
|
19
43
|
|
20
44
|
def name()
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
45
|
+
"#{GitHooker::SCRIPT_NAME.camelize} :: #{@name}"
|
46
|
+
end
|
47
|
+
|
48
|
+
def colored_name()
|
49
|
+
status_colorize name
|
50
|
+
end
|
51
|
+
|
52
|
+
def status_colorize(text)
|
53
|
+
finished? && completed? ? (success? ? bright_green(text) : bright_red(text)) : dark_cyan(text)
|
26
54
|
end
|
27
55
|
|
28
56
|
def run()
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
57
|
+
running!
|
58
|
+
if stop_on_error?
|
59
|
+
@actions.all? { |action| @success &= action.run }
|
60
|
+
else
|
61
|
+
@actions.collect { |action| @success &= action.run }.all?
|
62
|
+
end.tap { finished! }
|
34
63
|
end
|
35
64
|
end
|
36
65
|
end
|
@@ -1,9 +1,14 @@
|
|
1
|
+
# encoding: utf-8
|
1
2
|
module GitHooker
|
2
3
|
module TerminalColors
|
3
4
|
extend self
|
4
5
|
|
5
6
|
NORMAL = "\033[0;0m"
|
6
7
|
|
8
|
+
MARK_SUCCESS = '✓'
|
9
|
+
MARK_FAILURE = 'X'
|
10
|
+
MARK_UNKNOWN = '?'
|
11
|
+
|
7
12
|
def color(name)
|
8
13
|
return "" unless $stdout.tty? && $stderr.tty?
|
9
14
|
return NORMAL if !!name.to_s.match(/norm/)
|
@@ -32,7 +37,7 @@ module GitHooker
|
|
32
37
|
%w(black red green yellow blue magenta purple cyan white).each do |color|
|
33
38
|
name = "#{style}_#{shade}_#{color}".gsub(/(^_+|_+$)/, '').gsub(/_{2,}/, '_')
|
34
39
|
const_set(name.upcase, color(name))
|
35
|
-
define_method(name) { |text
|
40
|
+
define_method(name) { |text| "#{self.color(name)}#{text}#{self.color(:normal)}" }
|
36
41
|
end
|
37
42
|
end
|
38
43
|
end
|
data/thoughts.txt
ADDED
@@ -0,0 +1,78 @@
|
|
1
|
+
|
2
|
+
githook config --global hook.path <path>
|
3
|
+
-- sets hook.path in .gitconfig global
|
4
|
+
|
5
|
+
githook config hook.path <path>
|
6
|
+
-- sets hook.path in .git/config local to repository
|
7
|
+
|
8
|
+
githook list --hook <hook>
|
9
|
+
-- lists available tests for the given hook(s)
|
10
|
+
|
11
|
+
githook assign <scripts> --hook <hook>
|
12
|
+
-- assigns the listed scripts (which must be available in the hook path, and registerd) to the given hooks
|
13
|
+
in the .git/config file under the githooks.<hookname>.tests config path
|
14
|
+
|
15
|
+
GitHook::HookGroup::register(name) do
|
16
|
+
hook :pre_commit, :depends_on => { :command => 'puppet'} do
|
17
|
+
perform "Syntax Check" do
|
18
|
+
on :type => [ :modified, :added ], :name => %r{\.pp$} do
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
[hook.path]
|
24
|
+
/pre_commit
|
25
|
+
puppet.rb
|
26
|
+
Hook.register(pre_commit, "PUPPET") do
|
27
|
+
depends_on :command => 'puppet'
|
28
|
+
subsection 'General'
|
29
|
+
peform "Syntax Check" do
|
30
|
+
on :type => [ :modified, :added ], :name => %r{\.pp$} do
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
bind.rb
|
36
|
+
Hook.register(:pre_commit, "BIND") do
|
37
|
+
depends_on :command => 'puppet'
|
38
|
+
subsection 'General'
|
39
|
+
peform "Syntax Check" do
|
40
|
+
on :type => [ :modified, :added ], :name => %r{/modules/bind/files/} do
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
ruby.rb
|
46
|
+
Hook.register(:pre_commit, "RUBY") do
|
47
|
+
depends_on :command => 'ruby'
|
48
|
+
subsection 'General'
|
49
|
+
peform "Syntax Check" do
|
50
|
+
on :type => [ :modified, :added ], :name => %r{/modules/bind/files/} do
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
php.rb
|
56
|
+
Hook.register(:pre_commit, "PHP") do
|
57
|
+
depends_on :command => 'php'
|
58
|
+
subsection "General"
|
59
|
+
perform "Syntax Check" do
|
60
|
+
on :type => [ :modified, :added ], :name => %r{\.php$} do
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
policy.rb
|
66
|
+
Hook.register(commit_msg, "POLICY") do
|
67
|
+
subsection "Standards"
|
68
|
+
perform "Tabs Vs Spaces"
|
69
|
+
perform
|
70
|
+
end
|
71
|
+
|
72
|
+
/commit_msg
|
73
|
+
policy.rb
|
74
|
+
Hook.register(:commit_msg, "POLICY") do
|
75
|
+
subsection "Standards"
|
76
|
+
perform "Commit Message Length"
|
77
|
+
perform "Has ticket reference"
|
78
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: githooker
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.10
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,16 +9,16 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2014-02-27 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
|
-
name:
|
15
|
+
name: colorize
|
16
16
|
requirement: !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ~>
|
20
20
|
- !ruby/object:Gem::Version
|
21
|
-
version:
|
21
|
+
version: 0.5.8
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
24
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -26,7 +26,7 @@ dependencies:
|
|
26
26
|
requirements:
|
27
27
|
- - ~>
|
28
28
|
- !ruby/object:Gem::Version
|
29
|
-
version:
|
29
|
+
version: 0.5.8
|
30
30
|
- !ruby/object:Gem::Dependency
|
31
31
|
name: awesome_print
|
32
32
|
requirement: !ruby/object:Gem::Requirement
|
@@ -43,70 +43,6 @@ dependencies:
|
|
43
43
|
- - ! '>='
|
44
44
|
- !ruby/object:Gem::Version
|
45
45
|
version: '0'
|
46
|
-
- !ruby/object:Gem::Dependency
|
47
|
-
name: shoulda
|
48
|
-
requirement: !ruby/object:Gem::Requirement
|
49
|
-
none: false
|
50
|
-
requirements:
|
51
|
-
- - ! '>='
|
52
|
-
- !ruby/object:Gem::Version
|
53
|
-
version: '0'
|
54
|
-
type: :development
|
55
|
-
prerelease: false
|
56
|
-
version_requirements: !ruby/object:Gem::Requirement
|
57
|
-
none: false
|
58
|
-
requirements:
|
59
|
-
- - ! '>='
|
60
|
-
- !ruby/object:Gem::Version
|
61
|
-
version: '0'
|
62
|
-
- !ruby/object:Gem::Dependency
|
63
|
-
name: yard
|
64
|
-
requirement: !ruby/object:Gem::Requirement
|
65
|
-
none: false
|
66
|
-
requirements:
|
67
|
-
- - ~>
|
68
|
-
- !ruby/object:Gem::Version
|
69
|
-
version: '0.7'
|
70
|
-
type: :development
|
71
|
-
prerelease: false
|
72
|
-
version_requirements: !ruby/object:Gem::Requirement
|
73
|
-
none: false
|
74
|
-
requirements:
|
75
|
-
- - ~>
|
76
|
-
- !ruby/object:Gem::Version
|
77
|
-
version: '0.7'
|
78
|
-
- !ruby/object:Gem::Dependency
|
79
|
-
name: rdoc
|
80
|
-
requirement: !ruby/object:Gem::Requirement
|
81
|
-
none: false
|
82
|
-
requirements:
|
83
|
-
- - ~>
|
84
|
-
- !ruby/object:Gem::Version
|
85
|
-
version: '3.12'
|
86
|
-
type: :development
|
87
|
-
prerelease: false
|
88
|
-
version_requirements: !ruby/object:Gem::Requirement
|
89
|
-
none: false
|
90
|
-
requirements:
|
91
|
-
- - ~>
|
92
|
-
- !ruby/object:Gem::Version
|
93
|
-
version: '3.12'
|
94
|
-
- !ruby/object:Gem::Dependency
|
95
|
-
name: cucumber
|
96
|
-
requirement: !ruby/object:Gem::Requirement
|
97
|
-
none: false
|
98
|
-
requirements:
|
99
|
-
- - ! '>='
|
100
|
-
- !ruby/object:Gem::Version
|
101
|
-
version: '0'
|
102
|
-
type: :development
|
103
|
-
prerelease: false
|
104
|
-
version_requirements: !ruby/object:Gem::Requirement
|
105
|
-
none: false
|
106
|
-
requirements:
|
107
|
-
- - ! '>='
|
108
|
-
- !ruby/object:Gem::Version
|
109
|
-
version: '0'
|
110
46
|
- !ruby/object:Gem::Dependency
|
111
47
|
name: bundler
|
112
48
|
requirement: !ruby/object:Gem::Requirement
|
@@ -139,26 +75,11 @@ dependencies:
|
|
139
75
|
- - ~>
|
140
76
|
- !ruby/object:Gem::Version
|
141
77
|
version: 1.8.4
|
142
|
-
- !ruby/object:Gem::Dependency
|
143
|
-
name: simplecov
|
144
|
-
requirement: !ruby/object:Gem::Requirement
|
145
|
-
none: false
|
146
|
-
requirements:
|
147
|
-
- - ! '>='
|
148
|
-
- !ruby/object:Gem::Version
|
149
|
-
version: '0'
|
150
|
-
type: :development
|
151
|
-
prerelease: false
|
152
|
-
version_requirements: !ruby/object:Gem::Requirement
|
153
|
-
none: false
|
154
|
-
requirements:
|
155
|
-
- - ! '>='
|
156
|
-
- !ruby/object:Gem::Version
|
157
|
-
version: '0'
|
158
78
|
description: GitHooker provides a framework for building test that can be used with
|
159
79
|
git hooks
|
160
80
|
email: rabbitt@gmail.com
|
161
|
-
executables:
|
81
|
+
executables:
|
82
|
+
- githook
|
162
83
|
extensions: []
|
163
84
|
extra_rdoc_files:
|
164
85
|
- LICENSE.txt
|
@@ -167,11 +88,13 @@ extra_rdoc_files:
|
|
167
88
|
files:
|
168
89
|
- .document
|
169
90
|
- Gemfile
|
91
|
+
- Gemfile.lock
|
170
92
|
- LICENSE.txt
|
171
93
|
- README.md
|
172
94
|
- README.rdoc
|
173
95
|
- Rakefile
|
174
96
|
- VERSION
|
97
|
+
- bin/githook
|
175
98
|
- features/githooker.feature
|
176
99
|
- features/step_definitions/githooker_steps.rb
|
177
100
|
- features/support/env.rb
|
@@ -192,6 +115,7 @@ files:
|
|
192
115
|
- lib/githooker/terminal_colors.rb
|
193
116
|
- test/helper.rb
|
194
117
|
- test/test_githooker.rb
|
118
|
+
- thoughts.txt
|
195
119
|
homepage: http://github.com/rabbitt/githooker
|
196
120
|
licenses:
|
197
121
|
- GPLv2
|
@@ -205,9 +129,6 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
205
129
|
- - ! '>='
|
206
130
|
- !ruby/object:Gem::Version
|
207
131
|
version: '0'
|
208
|
-
segments:
|
209
|
-
- 0
|
210
|
-
hash: -1407532413498943980
|
211
132
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
212
133
|
none: false
|
213
134
|
requirements:
|
@@ -218,6 +139,7 @@ requirements: []
|
|
218
139
|
rubyforge_project:
|
219
140
|
rubygems_version: 1.8.23
|
220
141
|
signing_key:
|
221
|
-
specification_version:
|
142
|
+
specification_version: 4
|
222
143
|
summary: framework for building git hooks tests
|
223
144
|
test_files: []
|
145
|
+
has_rdoc:
|