hookify 0.0.1.6
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/MIT-LICENSE +20 -0
- data/README.markdown +54 -0
- data/Rakefile +74 -0
- data/bin/hookify +9 -0
- data/hooks/pre-commit +5 -0
- data/hooks/pre-release +7 -0
- data/init.rb +1 -0
- data/lib/hookify.rb +19 -0
- data/lib/hookify/command.rb +52 -0
- data/lib/hookify/commands/base.rb +71 -0
- data/lib/hookify/commands/pre_commit.rb +15 -0
- data/lib/hookify/commands/pre_release.rb +15 -0
- data/lib/hookify/helpers.rb +45 -0
- data/rails/init.rb +1 -0
- data/test/test_helper.rb +8 -0
- data/test/test_hookify.rb +67 -0
- metadata +79 -0
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2010 Lance Pollard (lancejpollard@gmail.com) and David Crockett
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.markdown
ADDED
@@ -0,0 +1,54 @@
|
|
1
|
+
# Hookify
|
2
|
+
|
3
|
+
Git hooks for Ruby
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
sudo gem install hookify
|
8
|
+
|
9
|
+
### Local Installation
|
10
|
+
|
11
|
+
git clone git@github.com:viatropos/hookify.git
|
12
|
+
cd hookify
|
13
|
+
rake install
|
14
|
+
|
15
|
+
## Usage
|
16
|
+
|
17
|
+
cd my-app
|
18
|
+
hookify pre-release
|
19
|
+
|
20
|
+
Add to `Gemfile` for Rails 3
|
21
|
+
|
22
|
+
group :development do
|
23
|
+
gem 'hookify'
|
24
|
+
gem 'compressible' # as an example that uses it
|
25
|
+
end
|
26
|
+
|
27
|
+
... or to `environments/development.rb` for Rails 2
|
28
|
+
|
29
|
+
config.gem 'hookify'
|
30
|
+
|
31
|
+
### Ruby Scripts
|
32
|
+
|
33
|
+
Because Rake tasks are much slower than plain Ruby scripts, hookify by default runs a Ruby script when a git hook executes.
|
34
|
+
|
35
|
+
The scripts are located in `config/hooks/hook_command_name.rb`.
|
36
|
+
|
37
|
+
### Rake Tasks (deprecated, adding later)
|
38
|
+
|
39
|
+
Hookify will execute a Rake task for each of the different commands available. Currently the list is:
|
40
|
+
|
41
|
+
- `hookify pre-release` or `hookify pre_release`: setup hook that runs just before `git push`
|
42
|
+
|
43
|
+
So you must just create a Rake task like this:
|
44
|
+
|
45
|
+
namespace :hookify do
|
46
|
+
desc "cache assets before push"
|
47
|
+
task :pre_release do
|
48
|
+
Compressible.compress("config/static_assets.yml")
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
### Notes
|
53
|
+
|
54
|
+
There are _client side_ hooks, and _server side_ hooks. Server side include `pre-release` and `post-release`.
|
data/Rakefile
ADDED
@@ -0,0 +1,74 @@
|
|
1
|
+
require 'rake'
|
2
|
+
require "rake/rdoctask"
|
3
|
+
require 'rake/gempackagetask'
|
4
|
+
|
5
|
+
# http://docs.rubygems.org/read/chapter/20
|
6
|
+
spec = Gem::Specification.new do |s|
|
7
|
+
s.name = "hookify"
|
8
|
+
s.authors = ["Lance Pollard", "David Crockett"]
|
9
|
+
s.version = "0.0.1.6"
|
10
|
+
s.summary = "Hookify: Git Hooks for Ruby"
|
11
|
+
s.homepage = "http://github.com/viatropos/hookify"
|
12
|
+
s.email = "lancejpollard@gmail.com"
|
13
|
+
s.description = "Git Hooks for Ruby"
|
14
|
+
s.has_rdoc = false
|
15
|
+
s.executables = ["hookify"]
|
16
|
+
s.rubyforge_project = "hookify"
|
17
|
+
s.platform = Gem::Platform::RUBY
|
18
|
+
s.files = %w(README.markdown Rakefile init.rb MIT-LICENSE) + Dir["{lib,hooks,rails,test,bin}/**/*"] - Dir["test/tmp"]
|
19
|
+
s.require_path = "lib"
|
20
|
+
end
|
21
|
+
|
22
|
+
Rake::GemPackageTask.new(spec) do |pkg|
|
23
|
+
pkg.gem_spec = spec
|
24
|
+
pkg.package_dir = "pkg"
|
25
|
+
end
|
26
|
+
|
27
|
+
desc 'run unit tests'
|
28
|
+
task :test do
|
29
|
+
exec "mkdir -p test/tmp ; ruby test/test_hookify.rb"
|
30
|
+
end
|
31
|
+
|
32
|
+
desc "Create .gemspec file (useful for github)"
|
33
|
+
task :gemspec do
|
34
|
+
File.open("pkg/#{spec.name}.gemspec", "w") do |f|
|
35
|
+
f.puts spec.to_ruby
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
desc "Build the gem into the current directory"
|
40
|
+
task :gem => :gemspec do
|
41
|
+
`gem build pkg/#{spec.name}.gemspec`
|
42
|
+
end
|
43
|
+
|
44
|
+
desc "Publish gem to rubygems"
|
45
|
+
task :publish => [:package] do
|
46
|
+
%x[gem push pkg/#{spec.name}-#{spec.version}.gem]
|
47
|
+
end
|
48
|
+
|
49
|
+
desc "Print a list of the files to be put into the gem"
|
50
|
+
task :manifest do
|
51
|
+
File.open("Manifest", "w") do |f|
|
52
|
+
spec.files.each do |file|
|
53
|
+
f.puts file
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
desc "Install the gem locally"
|
59
|
+
task :install => [:package] do
|
60
|
+
File.mkdir("pkg") unless File.exists?("pkg")
|
61
|
+
sh %{sudo gem install pkg/#{spec.name}-#{spec.version} --no-ri --no-rdoc}
|
62
|
+
end
|
63
|
+
|
64
|
+
desc "Generate the rdoc"
|
65
|
+
Rake::RDocTask.new do |rdoc|
|
66
|
+
files = ["README.markdown", "lib/**/*.rb"]
|
67
|
+
rdoc.rdoc_files.add(files)
|
68
|
+
rdoc.main = "README.markdown"
|
69
|
+
rdoc.title = spec.summary
|
70
|
+
end
|
71
|
+
|
72
|
+
task :yank do
|
73
|
+
`gem yank #{spec.name} -v #{spec.version}`
|
74
|
+
end
|
data/bin/hookify
ADDED
data/hooks/pre-commit
ADDED
data/hooks/pre-release
ADDED
data/init.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
File.dirname(__FILE__) + "/rails/init.rb"
|
data/lib/hookify.rb
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
require "rubygems"
|
2
|
+
gem "activesupport", "= 2.3.5"
|
3
|
+
require 'active_support'
|
4
|
+
require 'fileutils'
|
5
|
+
|
6
|
+
this = File.dirname(__FILE__)
|
7
|
+
library = "#{this}/hookify"
|
8
|
+
|
9
|
+
module Hookify
|
10
|
+
class << self
|
11
|
+
attr_accessor :root
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
Hookify.root = File.expand_path(File.join(File.dirname(__FILE__), ".."))
|
16
|
+
|
17
|
+
require "#{library}/helpers"
|
18
|
+
Dir["#{library}/commands/*"].each { |c| require c }
|
19
|
+
require "#{library}/command"
|
@@ -0,0 +1,52 @@
|
|
1
|
+
# http://progit.org/book/ch7-3.html
|
2
|
+
module Hookify::Command
|
3
|
+
|
4
|
+
class InvalidCommand < RuntimeError; end
|
5
|
+
class CommandFailed < RuntimeError; end
|
6
|
+
|
7
|
+
extend Hookify::Helpers
|
8
|
+
|
9
|
+
class << self
|
10
|
+
|
11
|
+
def run(command, args)
|
12
|
+
begin
|
13
|
+
run_command(command, args.dup)
|
14
|
+
rescue InvalidCommand
|
15
|
+
error "Unknown command '#{command.to_s}'. Run 'hookify help' for usage information."
|
16
|
+
rescue CommandFailed => e
|
17
|
+
error e.message
|
18
|
+
rescue Interrupt => e
|
19
|
+
error "\n[canceled]"
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def run_command(command, args)
|
24
|
+
klass, method = parse(command)
|
25
|
+
runner = klass.new(args)
|
26
|
+
raise InvalidCommand unless runner.respond_to?(method)
|
27
|
+
runner.send(method)
|
28
|
+
end
|
29
|
+
|
30
|
+
def parse(command)
|
31
|
+
parts = command.split(':').collect {|i| i.gsub("-", "_")}
|
32
|
+
case parts.size
|
33
|
+
when 1
|
34
|
+
begin
|
35
|
+
return "Hookify::Command::#{parts[0].camelize}".constantize, :create
|
36
|
+
rescue NameError, NoMethodError
|
37
|
+
return Hookify::Command::Base, parts[0]
|
38
|
+
end
|
39
|
+
when 2
|
40
|
+
begin
|
41
|
+
return "Hookify::Command::#{parts[0].camelize}".constantize, parts[1]
|
42
|
+
rescue NameError
|
43
|
+
raise InvalidCommand
|
44
|
+
end
|
45
|
+
else
|
46
|
+
raise InvalidCommand
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
module Hookify::Command
|
2
|
+
class Base
|
3
|
+
include Hookify::Helpers
|
4
|
+
|
5
|
+
def initialize(args)
|
6
|
+
|
7
|
+
end
|
8
|
+
|
9
|
+
def command_name
|
10
|
+
self.class.to_s.split("::").last.underscore
|
11
|
+
end
|
12
|
+
|
13
|
+
def file_name
|
14
|
+
command_name.gsub("_", "-")
|
15
|
+
end
|
16
|
+
|
17
|
+
def file_path
|
18
|
+
File.join(hooks_directory, file_name)
|
19
|
+
end
|
20
|
+
|
21
|
+
def ruby_script_path
|
22
|
+
"config/hooks/#{command_name}.rb"
|
23
|
+
end
|
24
|
+
|
25
|
+
def run
|
26
|
+
|
27
|
+
end
|
28
|
+
|
29
|
+
def remove_file
|
30
|
+
File.delete(file_path) if File.exists?(file_path)
|
31
|
+
end
|
32
|
+
|
33
|
+
def write_file
|
34
|
+
script = IO.read(File.join(Hookify.root, "hooks/#{file_name}"))
|
35
|
+
remove_file # temporary until I get symlinks working
|
36
|
+
already_exists = File.exists?(file_path)
|
37
|
+
|
38
|
+
# make the pre-x file, only if you haven't manually created one yourself
|
39
|
+
unless already_exists
|
40
|
+
FileUtils.mkdir_p(hooks_directory)
|
41
|
+
File.new(file_path, "w")
|
42
|
+
end
|
43
|
+
|
44
|
+
FileUtils.mkdir_p(File.dirname(ruby_script_path))
|
45
|
+
File.new(ruby_script_path, "w") unless File.exists?(ruby_script_path)
|
46
|
+
|
47
|
+
display("Creating #{file_path}...\n")
|
48
|
+
|
49
|
+
File.open(file_path, "r+") do |file|
|
50
|
+
content = ""
|
51
|
+
# if we want something like this, it needs to be more advanced
|
52
|
+
#if already_exists
|
53
|
+
# content = file.read
|
54
|
+
# content << "\n"
|
55
|
+
#end
|
56
|
+
content << script
|
57
|
+
file.pos = 0
|
58
|
+
file.print content
|
59
|
+
file.truncate(file.pos)
|
60
|
+
end
|
61
|
+
|
62
|
+
executable(file_path)
|
63
|
+
|
64
|
+
display("Add a rake task named 'hookify:#{command_name}'")
|
65
|
+
end
|
66
|
+
|
67
|
+
class << self
|
68
|
+
end
|
69
|
+
|
70
|
+
end
|
71
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
module Hookify
|
2
|
+
module Helpers
|
3
|
+
def hooks_directory
|
4
|
+
".git/hooks"
|
5
|
+
end
|
6
|
+
|
7
|
+
def home_directory
|
8
|
+
running_on_windows? ? ENV['USERPROFILE'] : ENV['HOME']
|
9
|
+
end
|
10
|
+
|
11
|
+
def running_on_windows?
|
12
|
+
RUBY_PLATFORM =~ /mswin32|mingw32/
|
13
|
+
end
|
14
|
+
|
15
|
+
def running_on_a_mac?
|
16
|
+
RUBY_PLATFORM =~ /-darwin\d/
|
17
|
+
end
|
18
|
+
|
19
|
+
def executable(path)
|
20
|
+
FileUtils.chmod(0755, path)
|
21
|
+
end
|
22
|
+
|
23
|
+
def display(msg, newline=true)
|
24
|
+
if newline
|
25
|
+
puts(msg)
|
26
|
+
else
|
27
|
+
print(msg)
|
28
|
+
STDOUT.flush
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def error(msg)
|
33
|
+
STDERR.puts(msg)
|
34
|
+
# exit 1
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
unless String.method_defined?(:shellescape)
|
40
|
+
class String
|
41
|
+
def shellescape
|
42
|
+
empty? ? "''" : gsub(/([^A-Za-z0-9_\-.,:\/@\n])/n, '\\\\\\1').gsub(/\n/, "'\n'")
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
data/rails/init.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "hookify"
|
data/test/test_helper.rb
ADDED
@@ -0,0 +1,67 @@
|
|
1
|
+
require 'fileutils'
|
2
|
+
require File.join(File.dirname(__FILE__), 'test_helper.rb')
|
3
|
+
|
4
|
+
class HookifyTest < Test::Unit::TestCase
|
5
|
+
|
6
|
+
# helper method
|
7
|
+
def create_command(name)
|
8
|
+
@args = name.split(/\s+/) # mimic ARGV (should I stub?)
|
9
|
+
@command = @args[1].strip
|
10
|
+
end
|
11
|
+
|
12
|
+
context "hookify processing commands" do
|
13
|
+
|
14
|
+
setup do
|
15
|
+
@this = File.expand_path(Dir.pwd)
|
16
|
+
Dir.chdir "test/tmp"
|
17
|
+
system("git init")
|
18
|
+
Dir.chdir @this
|
19
|
+
end
|
20
|
+
|
21
|
+
context "run pre-release command" do
|
22
|
+
|
23
|
+
setup { Dir.chdir "test/tmp" }
|
24
|
+
|
25
|
+
should "not raise an error with a valid command" do
|
26
|
+
create_command("hookify pre-release")
|
27
|
+
assert Hookify::Command.run(@command, @args)
|
28
|
+
assert File.exists?(".git/hooks/pre-release")
|
29
|
+
end
|
30
|
+
|
31
|
+
should "be able to parse a destroy command" do
|
32
|
+
create_command("hookify pre-release:destroy")
|
33
|
+
parts = Hookify::Command.parse(@command)
|
34
|
+
assert_equal [Hookify::Command::PreRelease, "destroy"], parts
|
35
|
+
end
|
36
|
+
|
37
|
+
should "be able to run destroy command" do
|
38
|
+
create_command("hookify pre-release:destroy")
|
39
|
+
Hookify::Command.run(@command, @args)
|
40
|
+
assert_equal false, File.exists?(".git/hooks/pre-release")
|
41
|
+
end
|
42
|
+
|
43
|
+
teardown { Dir.chdir @this }
|
44
|
+
|
45
|
+
end
|
46
|
+
|
47
|
+
context "run pre-commit command" do
|
48
|
+
|
49
|
+
setup { Dir.chdir "test/tmp" }
|
50
|
+
|
51
|
+
should "not raise an error with a valid command" do
|
52
|
+
create_command("hookify pre-commit")
|
53
|
+
assert Hookify::Command.run(@command, @args)
|
54
|
+
assert File.exists?(".git/hooks/pre-commit")
|
55
|
+
end
|
56
|
+
|
57
|
+
teardown { Dir.chdir @this }
|
58
|
+
|
59
|
+
end
|
60
|
+
|
61
|
+
teardown do
|
62
|
+
FileUtils.rm_rf("tmp/.git")
|
63
|
+
end
|
64
|
+
|
65
|
+
end
|
66
|
+
|
67
|
+
end
|
metadata
ADDED
@@ -0,0 +1,79 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: hookify
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease: false
|
5
|
+
segments:
|
6
|
+
- 0
|
7
|
+
- 0
|
8
|
+
- 1
|
9
|
+
- 6
|
10
|
+
version: 0.0.1.6
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- Lance Pollard
|
14
|
+
- David Crockett
|
15
|
+
autorequire:
|
16
|
+
bindir: bin
|
17
|
+
cert_chain: []
|
18
|
+
|
19
|
+
date: 2010-06-04 00:00:00 -07:00
|
20
|
+
default_executable:
|
21
|
+
dependencies: []
|
22
|
+
|
23
|
+
description: Git Hooks for Ruby
|
24
|
+
email: lancejpollard@gmail.com
|
25
|
+
executables:
|
26
|
+
- hookify
|
27
|
+
extensions: []
|
28
|
+
|
29
|
+
extra_rdoc_files: []
|
30
|
+
|
31
|
+
files:
|
32
|
+
- README.markdown
|
33
|
+
- Rakefile
|
34
|
+
- init.rb
|
35
|
+
- MIT-LICENSE
|
36
|
+
- lib/hookify/command.rb
|
37
|
+
- lib/hookify/commands/base.rb
|
38
|
+
- lib/hookify/commands/pre_commit.rb
|
39
|
+
- lib/hookify/commands/pre_release.rb
|
40
|
+
- lib/hookify/helpers.rb
|
41
|
+
- lib/hookify.rb
|
42
|
+
- hooks/pre-commit
|
43
|
+
- hooks/pre-release
|
44
|
+
- rails/init.rb
|
45
|
+
- test/test_helper.rb
|
46
|
+
- test/test_hookify.rb
|
47
|
+
- bin/hookify
|
48
|
+
has_rdoc: true
|
49
|
+
homepage: http://github.com/viatropos/hookify
|
50
|
+
licenses: []
|
51
|
+
|
52
|
+
post_install_message:
|
53
|
+
rdoc_options: []
|
54
|
+
|
55
|
+
require_paths:
|
56
|
+
- lib
|
57
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
segments:
|
62
|
+
- 0
|
63
|
+
version: "0"
|
64
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
segments:
|
69
|
+
- 0
|
70
|
+
version: "0"
|
71
|
+
requirements: []
|
72
|
+
|
73
|
+
rubyforge_project: hookify
|
74
|
+
rubygems_version: 1.3.6
|
75
|
+
signing_key:
|
76
|
+
specification_version: 3
|
77
|
+
summary: "Hookify: Git Hooks for Ruby"
|
78
|
+
test_files: []
|
79
|
+
|