Module: GitHooker::Repo

Extended by:
Repo
Included in:
Action::DSL, Repo
Defined in:
lib/githooker/repo.rb

Defined Under Namespace

Classes: NotAGitRepoError

Constant Summary collapse

CHANGE_TYPE_SYMBOLS =
{
  :added    => 'A', :copied   => 'C', :deleted  => 'D', :modified => 'M',
  :renamed  => 'R', :retyped  => 'T', :unknown  => 'U', :unmerged => 'X',
  :broken   => 'B', :any      => '*'
}.freeze
CHANGE_TYPES =
CHANGE_TYPE_SYMBOLS.invert.freeze
DEFAULT_DIFF_INDEX_OPTIONS =
{ :staged => true, :ref => 'HEAD' }

Instance Method Summary collapse

Instance Method Details

#diff_index(options = {}) ⇒ Object



63
64
65
66
67
68
69
70
71
# File 'lib/githooker/repo.rb', line 63

def diff_index(options = {})
  options = DEFAULT_DIFF_INDEX_OPTIONS.merge(options)

  cmd = %w(git diff-index -C -M -B)
  cmd << '--cached' if options[:staged]
  cmd << options.delete(:ref) || 'HEAD'

  %x{ #{cmd.join(' ')} }
end

#match(manifest_files, filters) ⇒ Object

returns the intersection of all file filters



88
89
90
91
92
# File 'lib/githooker/repo.rb', line 88

def match(manifest_files, filters)
  manifest_files.tap { |files|
    filters.each {|type, value| files.select! { |name, data| match_file(data, type, value) } }
  }.values
end

#match_file(file, matchtype, matchvalue) ⇒ Object



99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
# File 'lib/githooker/repo.rb', line 99

def match_file(file, matchtype, matchvalue)
  attr_value = case matchtype
    when :name then file.path
    when :type then file.type
    when :mode then file.to.mode
    when :sha then file.to.sha
    when :score then file.score
    else raise ArgumentError, "Invalid match type '#{matchtype}' - expected one of: :name, :type, :mode, :sha, or :score"
  end

  return matchvalue.call(attr_value) if matchvalue.respond_to? :call

  case matchtype
    when :name then
      matchvalue.is_a?(Regexp) ? attr_value =~ matchvalue : attr_value == matchvalue
    when :type then
      matchvalue.is_a?(Array) ? matchvalue.include?(attr_value) : matchvalue == attr_value
    when :mode then
      matchvalue & attr_value == matchvalue
    when :sha then
      attr_value == matchvalue
    when :score then
      attr_value == matchvalue
  end
end

#match_files_on(options) ⇒ Object

Raises:

  • (ArgumentError)


82
83
84
85
# File 'lib/githooker/repo.rb', line 82

def match_files_on(options)
  raise ArgumentError, "options should be a hash" unless options.is_a? Hash
  match(use_unstaged? ? unstaged_manifest : staged_manifest, options.to_a)
end

#match_phase(phase = :any) ⇒ Object



94
95
96
97
# File 'lib/githooker/repo.rb', line 94

def match_phase(phase = :any)
  return true if phase == :any
  return GitHooker::SCRIPT_NAME.to_sym == phase.to_s.to_sym
end

#root_pathObject



21
22
23
24
25
26
27
28
29
30
31
32
33
34
# File 'lib/githooker/repo.rb', line 21

def root_path
  %x{git rev-parse --show-toplevel 2>&1}.strip.tap { |path|
    if $? != 0 && path =~ /Not a git repository/
      # attempt to find the repo
      warn "couldn't find a git repository in the current path #{Dir.getwd}"
      return path unless (path = %x{ cd #{GitHooker::SCRIPT_DIR.to_s}; git rev-parse --show-toplevel 2>&1 }) =~ /Not a git repository/
      unless GitHooker::SCRIPT_NAME == 'irb'
        raise NotAGitRepoError, "Unable to find a valid git repository"
      end
      warn "GitHooker::REPO_ROOT is not set - Use GitHooker::Repo.root_path once you've changed the current directory to a git repo"
      return ''
    end
  }
end

#run_while_stashed(cmd) ⇒ Object



46
47
48
49
# File 'lib/githooker/repo.rb', line 46

def run_while_stashed(cmd)
  while_stashed { system(cmd) }
  $? == 0
end

#staged_manifestObject Also known as: commit_manifest



73
74
75
# File 'lib/githooker/repo.rb', line 73

def staged_manifest
  parse_diff_index_data(diff_index(:staged => true, :ref => 'HEAD'))
end

#stashObject



51
52
53
# File 'lib/githooker/repo.rb', line 51

def stash()
  %x{ git stash -q --keep-index }
end

#unstaged_manifestObject



78
79
80
# File 'lib/githooker/repo.rb', line 78

def unstaged_manifest
  parse_diff_index_data(diff_index(:staged => false, :ref => 'HEAD'))
end

#unstashObject



55
56
57
# File 'lib/githooker/repo.rb', line 55

def unstash()
  %x{ git stash pop -q }
end

#use_unstaged?Boolean

Returns:

  • (Boolean)


59
60
61
# File 'lib/githooker/repo.rb', line 59

def use_unstaged?
  ENV['UNSTAGED']
end

#while_stashedObject

Raises:

  • (ArgumentError)


36
37
38
39
40
41
42
43
44
# File 'lib/githooker/repo.rb', line 36

def while_stashed
  raise ArgumentError, "Missing required block" unless block_given?
  begin
    stash
    return yield
  ensure
    unstash
  end
end