class RubyGitHooks::Hook

applypatch-msg, pre-applypatch, post-applypatch prepare-commit-msg, commit-msg pre-rebase, post-checkout, post-merge, update, post-update, pre-auto-gc, post-rewrite

Constants

HOOK_INFO

Instances of Hook delegate these methods to the class methods.

HOOK_TYPE_SETUP

Attributes

branches_changed[RW]

branches included in this push

commit_message[RW]

Commit message for current commit

commit_message_file[RW]

Commit message file for current commit

commit_ref_map[RW]

refs associated with each commit

commits[RW]

the following are for hooks which involve multiple commits (pre-receive, post-receive): (may be empty in other hooks) All current commits

file_contents[RW]

Latest contents of all changed files

file_diffs[RW]

A human-readable diff per file

files_changed[RW]

Array of what files were changed

has_run[R]

Whether .run has ever been called

ls_files[RW]

All filenames in repo

registered_hooks[R]

What hooks are running

run_as[R]

What command line was run

run_as_hook[R]

What git hook is being run

run_from[R]

What directory to run from

Private Class Methods

get_hooks_to_run(hook_specs) click to toggle source
# File lib/ruby_git_hooks.rb, line 248
def self.get_hooks_to_run(hook_specs)
  @registered_hooks ||= {}

  if hook_specs.empty?
    return @registered_hooks.values.inject([], &:+)
  end

  hook_specs.flat_map do |spec|
    if @registered_hooks[spec]
      @registered_hooks[spec]
    elsif spec.is_a?(Hook)
      [ spec ]
    elsif spec.is_a?(String)
      # A string is assumed to be a class name
      @registered_hooks[Object.const_get(spec)]
    else
      raise "Can't find hook for specification: #{spec.inspect}!"
    end
  end
end
initial_setup() click to toggle source
# File lib/ruby_git_hooks.rb, line 232
def self.initial_setup
  return if @run_from

  @run_from = Dir.getwd
  @run_as = $0
end
register(hook) click to toggle source
# File lib/ruby_git_hooks.rb, line 339
def self.register(hook)
  @registered_hooks ||= {}
  @registered_hooks[hook.class.name] ||= []
  @registered_hooks[hook.class.name].push hook

  # Figure out when to set this up...
  #at_exit do
  #  unless RubyGitHooks::Hook.has_run
  #    STDERR.puts "No call to RubyGitHooks.run happened, so no hooks ran!"
  #  end
  #end
end
run(*hook_specs) click to toggle source

Run takes a list of hook specifications. Those can be Hook classnames or instances of type Hook.

@param hook_specs Array[Hook or Class or String] A list of hooks or hook classes

# File lib/ruby_git_hooks.rb, line 274
    def self.run(*hook_specs)
      if @has_run
        STDERR.puts <<ERR
In this version, you can't call .run more than once.  For now, please
register your hooks individually and then call .run with no args, or
else call .run with both as arguments.  This may be fixed in a future
version.  Sorry!
ERR
        exit 1
      end
      @has_run = true

      initial_setup

      run_as_specific_githook

      # By default, run all hooks
      hooks_to_run = get_hooks_to_run(hook_specs.flatten)

      failed_hooks = []
      val = nil
      hooks_to_run.each do |hook|
        begin
          hook.setup { val = hook.check }  # Re-init each time, just in case
          failed_hooks.push(hook) unless val
        rescue
          # Failed.  Return non-zero if that makes a difference.
          STDERR.puts "Hook #{hook.inspect} raised exception: #{$!.inspect}!\n#{$!.backtrace.join("\n")}"
          failed_hooks.push hook
        end
      end

      if CAN_FAIL_HOOKS.include?(@run_as_hook) && failed_hooks.size > 0
        STDERR.puts "Hooks failed: #{failed_hooks}"
        STDERR.puts "Use 'git commit -eF .git/COMMIT_EDITMSG' to restore your commit message" if commit_message
        STDERR.puts "Exiting!"
        exit 1
      end
    end
run_as_specific_githook() click to toggle source
# File lib/ruby_git_hooks.rb, line 314
def self.run_as_specific_githook
  return if @run_as_hook  # Already did this

  self.initial_setup  # Might have already done this

  if ARGV.include? "--hook"
    idx = ARGV.find_index "--hook"
    @run_as_hook = ARGV[idx + 1]
    2.times { ARGV.delete_at(idx) }
  else
    @run_as_hook = HOOK_NAMES.detect { |hook| @run_as.include?(hook) }
  end

  unless @run_as_hook
    STDERR.puts "Name #{@run_as.inspect} doesn't include " +
      "any of: #{HOOK_NAMES.inspect}"
    exit 1
  end
  unless HOOK_TYPE_SETUP[@run_as_hook]
    STDERR.puts "No setup defined for hook type #{@run_as_hook.inspect}!"
    exit 1
  end
  self.instance_eval(&HOOK_TYPE_SETUP[@run_as_hook])
end
shell!(*args) click to toggle source
# File lib/ruby_git_hooks.rb, line 352
def self.shell!(*args)
  output = `#{args.join(" ")}`

  unless $?.success?
    STDERR.puts "Job #{args.inspect} failed in dir #{Dir.getwd.inspect}"
    STDERR.puts "Failed job output:\n#{output}\n======"
    raise "Exec of #{args.inspect} failed: #{$?}!"
  end

  output
end

Private Instance Methods

setup() { || ... } click to toggle source
# File lib/ruby_git_hooks.rb, line 239
def setup
  Dir.chdir Hook.run_from do
    yield
  end

ensure
  # Nothing yet
end