Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

git hook init works

  • Loading branch information...
commit f7a85539c684a7ad92d0619d62baad9214dc3c54 1 parent dea9d6b
@timcharper authored
View
1  .gitignore
@@ -0,0 +1 @@
+/tmp/
View
3  bin/git-hook 100644 → 100755
@@ -1,5 +1,4 @@
#!/usr/bin/env ruby
-$. << File.dirname(__FILE__) + "/../lib/"
+$: << File.dirname(__FILE__) + "/../lib/"
require "gitty"
-
Gitty::Hook.new(ARGV).run
View
1  cucumber.yml
@@ -0,0 +1 @@
+default: -f pretty -r features
View
2  features/env.rb
@@ -1,5 +1,3 @@
require File.dirname(__FILE__) + "/../lib/gitty"
require 'rubygems'
require 'cucumber'
-
-Gitty::Hook.new(ARGV).run
View
19 features/initialization.feature
@@ -1,12 +1,25 @@
Feature: Initialization
- In order to use custom hooks in the git repository
As a developer
+ In order to use custom hooks in the git repository
I want to initialize gitty for my repository
- Scenario basic initialization
+ Scenario: basic initialization
Given that I have a git repository with some commits
When I run "git hook init"
+
Then the following folders should exist:
| .git/hooks/shared |
| .git/hooks/local |
- And the repository should be gitty activated
+
+ And the following hooks are setup to run all shared and local hooks
+ |applypatch-msg |
+ |pre-applypatch |
+ |post-applypatch |
+ |pre-commit |
+ |prepare-commit-msg |
+ |commit-msg |
+ |post-commit |
+ |pre-rebase |
+ |post-checkout |
+ |post-merge |
+ |pre-auto-gc |
View
4 features/step_definitions/git_repo_steps.rb
@@ -0,0 +1,4 @@
+Given "that I have a git repository with some commits" do
+ run("git init && echo content > README && git add README && git commit -m 'initial commit'")
+end
+
View
10 features/step_definitions/initialization_steps.rb
@@ -0,0 +1,10 @@
+Then "the following hooks are setup to run all shared and local hooks" do |table|
+ table.raw.map(&:first).each do |hook|
+ in_current_dir do
+ unless File.executable?(".git/hooks/#{hook}")
+ raise(Spec::Expectations::ExpectationNotMetError, "expected .git/hooks/#{hook} to be executable")
+ end
+ end
+ end
+end
+
View
157 features/step_definitions/sandbox_steps.rb
@@ -0,0 +1,157 @@
+require 'tempfile'
+class SandboxWorld
+ GITTY_BIN = File.expand_path('../../bin/git-hook', File.dirname(__FILE__))
+ SANDBOX_DIR = File.expand_path('../../tmp/sandbox', File.dirname(__FILE__))
+ RUBY_BINARY = File.join(Config::CONFIG['bindir'], Config::CONFIG['ruby_install_name'])
+ SANDBOX_DIR = File.expand_path(File.join(File.dirname(__FILE__), '../../tmp/sandbox'))
+
+ def initialize
+ @current_dir = SANDBOX_DIR
+ end
+
+ private
+ attr_reader :last_exit_status, :last_stderr, :last_stdout
+ def last_stderr
+ return @last_stderr if @last_stderr
+ if @background_job
+ @last_stderr = @background_job.stderr.read
+ end
+ end
+
+
+ def last_stdout
+ return @last_stdout if @last_stdout
+ if @background_job
+ @last_stdout = @background_job.stdout.read
+ end
+ end
+
+ def create_file(file_name, file_content)
+ file_content.gsub!("SPORK_LIB", "'#{spork_lib_dir}'") # Some files, such as Rakefiles need to use the lib dir
+ in_current_dir do
+ FileUtils.mkdir_p(File.dirname(file_name))
+ File.open(file_name, 'w') { |f| f << file_content }
+ end
+ end
+
+ def in_current_dir(&block)
+ Dir.chdir(@current_dir, &block)
+ end
+
+ def localized_command(command)
+ command, args = command.scan(/^(git-hook|git hook|\w+)\s*(.*)$/).flatten
+ case command
+ when 'git-hook', 'git hook'
+ command = SandboxWorld::GITTY_BIN
+ "#{SandboxWorld::RUBY_BINARY} #{command} #{args}"
+ else
+ [command, args].join(" ")
+ end
+ end
+
+ def run(command)
+ command = localized_command(command)
+ stderr_file = Tempfile.new('gitty')
+ stderr_file.close
+ in_current_dir do
+ @last_stdout = `#{command} 2> #{stderr_file.path}`
+ @last_exit_status = $?.exitstatus
+ end
+ @last_stderr = IO.read(stderr_file.path)
+ if $verbose
+ puts @last_stderr
+ puts @last_stdout
+ end
+ @last_stdout
+ end
+end
+
+World do
+ SandboxWorld.new
+end
+
+Before do
+ FileUtils.rm_rf SandboxWorld::SANDBOX_DIR
+ FileUtils.mkdir_p SandboxWorld::SANDBOX_DIR
+end
+
+
+Given /^I am in the directory "(.*)"$/ do |path|
+ path = File.join(SandboxWorld::SANDBOX_DIR, sandbox_dir_relative_path)
+ FileUtils.mkdir_p(path)
+ @current_dir = File.join(path)
+end
+
+Given /^a file named "([^\"]*)"$/ do |file_name|
+ create_file(file_name, '')
+end
+
+Given /^a file named "([^\"]*)" with:$/ do |file_name, file_content|
+ create_file(file_name, file_content)
+end
+
+When /^the contents of "([^\"]*)" are changed to:$/ do |file_name, file_content|
+ create_file(file_name, file_content)
+end
+
+# the following code appears in "config/environment.rb" after /Rails::Initializer.run/:
+Given /^the following code appears in "([^\"]*)" after \/([^\\\/]*)\/:$/ do |file_name, regex, content|
+ regex = Regexp.new(regex)
+ in_current_dir do
+ content_lines = File.read(file_name).split("\n")
+ 0.upto(content_lines.length - 1) do |line_index|
+ if regex.match(content_lines[line_index])
+ content_lines.insert(line_index + 1, content)
+ break
+ end
+ end
+ File.open(file_name, 'wb') { |f| f << (content_lines * "\n") }
+ end
+end
+
+When /^I run "(.+)"$/ do |command|
+ run(command)
+end
+
+Then /^the file "([^\"]*)" should include "([^\"]*)"$/ do |filename, content|
+ in_current_dir do
+ File.read(filename).should include(content)
+ end
+end
+
+Then /^the following (files|folders) should exist:$/ do |file_or_dir, table|
+ in_current_dir do
+ table.raw.map.each do |path|
+ File.exist?(path.first).should == true
+ end
+ end
+end
+
+Then /^the (error output|output) should contain$/ do |which, text|
+ (which == "error output" ? last_stderr : last_stdout).should include(text)
+end
+
+Then /^the (error output|output) should contain "(.+)"$/ do |which, text|
+ (which == "error output" ? last_stderr : last_stdout).should include(text)
+end
+
+Then /^the (error output|output) should match \/(.+)\/$/ do |which, regex|
+ (which == "error output" ? last_stderr : last_stdout).should match(Regexp.new(regex))
+end
+
+Then /^the (error output|output) should not contain$/ do |which, text|
+ (which == "error output" ? last_stderr : last_stdout).should_not include(text)
+end
+
+Then /^the (error output|output) should not contain "(.+)"$/ do |which, text|
+ (which == "error output" ? last_stderr : last_stdout).should_not include(text)
+end
+
+Then /^the (error output|output) should be empty$/ do |which|
+ (which == "error output" ? last_stderr : last_stdout).should == ""
+end
+
+Then /^the (error output|output) should be$/ do |which, text|
+ (which == "error output" ? last_stderr : last_stdout).should == text
+end
+
View
1  features/support/verbose.rb
@@ -0,0 +1 @@
+$verbose = true
View
6 hooks/hookd_wrapper
@@ -0,0 +1,6 @@
+#!/bin/bash
+dirname=$(dirname $0)
+hooktype=$(basename $0)
+for script in "${dirname}"/{shared,local}/${hooktype}.d/*; do
+ "${script}" || exit $?
+done
View
16 lib/ext.rb
@@ -0,0 +1,16 @@
+class Symbol
+ unless method_defined?(:to_proc)
+ def to_proc
+ proc { |obj, *args| obj.send(self, *args) }
+ end
+ end
+end
+
+class Object
+ unless method_defined?(:tap)
+ def tap
+ yield self
+ self
+ end
+ end
+end
View
9 lib/gitty.rb
@@ -1,6 +1,13 @@
require "pathname"
-GITTY_PATH = Pathname.new(File.dirname(__FILE__)) + "gitty"
+GITTY_LIB_PATH = Pathname.new(File.dirname(__FILE__))
+HOOK_PATH = GITTY_LIB_PATH + "../hooks"
+GITTY_PATH = GITTY_LIB_PATH + "gitty"
+$: << GITTY_LIB_PATH.to_s
+
+module Gitty
+end
require "string.rb"
+require "ext.rb"
require "gitty/runner.rb"
require "gitty/hook.rb"
View
33 lib/gitty/commands/init.rb
@@ -1,17 +1,32 @@
+require 'fileutils'
class Gitty::Hook::Init < Gitty::Runner
+ CLIENT_HOOKS = %w[
+ applypatch-msg
+ pre-applypatch
+ post-applypatch
+ pre-commit
+ prepare-commit-msg
+ commit-msg
+ post-commit
+ pre-rebase
+ post-checkout
+ post-merge
+ pre-auto-gc
+ ]
def run
+ puts "Initializing with gitty"
+ FileUtils.mkdir_p(".git/hooks/shared")
+ FileUtils.mkdir_p(".git/hooks/local")
+
+ CLIENT_HOOKS.each do |hook|
+ FileUtils.cp((HOOK_PATH + "hookd_wrapper").to_s, ".git/hooks/#{hook}")
+ FileUtils.chmod(755, ".git/hooks/#{hook}")
+ end
end
- def option_parser(options)
- OptionParser.new do |opts|
+ def option_parser
+ super.tap do |opts|
opts.banner = "Usage: git hook init"
- opts.separator "Options:"
end
end
-
- def parse_args!(args)
- opt_p = option_parser
- opt_p.banner = banner
- opt_p.parse!(args)
- end
end
View
25 lib/gitty/hook.rb
@@ -3,19 +3,32 @@ class Gitty::Hook < Gitty::Runner
init
]
COMMANDS.each do |cmd|
- autoload cmd.classify.to_sym, GITTY_PATH + "commands/#{cmd}.rb"
+ autoload cmd.classify.to_sym, (GITTY_PATH + "commands/#{cmd}.rb").to_s
end
- def option_parser(options)
- OptionParser.new do |opts|
- opts.banner = "Usage: git hook [command] #{$0} seller email buyer1,buyer2,... [options]"
- opts.separator "Options:"
+ def initialize(args, stdin = STDIN, stdout = STDOUT)
+ @args, @stdin, @stdout = args, stdin, stdout
+ if COMMANDS.include?(args.first)
+ @target = Gitty::Hook.const_get(args.first.classify).new(args, stdin, stdout)
+ else
+ parse_args!
end
end
- def parse_args!(args)
+ def option_parser
+ super.tap do |opts|
+ opts.banner = "Usage: git hook [command]\nCommands are: #{COMMANDS.join(', ')}"
+ end
+ end
+
+ def run
+ @target && @target.run
+ end
+
+ def parse_args!
opt_p = option_parser
opt_p.banner = banner
opt_p.parse!(args)
+ pp args
end
end
View
17 lib/gitty/runner.rb
@@ -1,15 +1,28 @@
+require "optparse"
class Gitty::Runner
- attr_reader :stdin, :stdout
+ attr_reader :stdin, :stdout, :args
attr_reader :options
def initialize(args, stdin = STDIN, stdout = STDOUT)
@args, @stdin, @stdout = args, stdin, stdout
- @options = options[:]
+ @options = {}
+ parse_args!
end
def run
raise NotImplementedError
end
+ def option_parser
+ OptionParser.new do |opts|
+ opts.banner = "Usage: #{$0}"
+ opts.separator "Options:"
+ opts.on('--help', "Show help")
+ end
+ end
+
protected
+ def parse_args!
+ option_parser.parse!(args)
+ end
end
Please sign in to comment.
Something went wrong with that request. Please try again.