class GitHooks::Repository

Constants

CHANGE_TYPES
CHANGE_TYPE_SYMBOLS
DEFAULT_DIFF_INDEX_OPTIONS
DiffIndexEntryDelegateClass

Attributes

config[R]
hooks[R]
path[R]

Public Class Methods

new(path = nil) click to toggle source
# File lib/githooks/repository.rb, line 48
def initialize(path = nil)
  @path   = Pathname.new(get_root_path(path || Dir.getwd))
  @hooks  = Pathname.new(@path).join('.git', 'hooks')
  @config = Repository::Config.new(self)
end

Public Instance Methods

branch_point_sha() click to toggle source
# File lib/githooks/repository.rb, line 152
def branch_point_sha
  # Try to backtrack back to where we branched from, and use that as our
  # sha to compare against.

  # HACK: there's a better way but, it's too late and I'm too tired to
  # think of it right now.
  refs = 0.upto(100).to_a.collect { |x| "#{current_branch}~#{x}" }
  previous_branch = git('name-rev', '--name-only', *refs).
                    output_lines.find { |x| x.strip != current_branch }
  revision_sha(previous_branch) if previous_branch != current_branch
end
commit_manifest(options = {})
Alias for: staged_manifest
current_branch() click to toggle source
# File lib/githooks/repository.rb, line 136
def current_branch
  @branch ||= begin
    branch = git('symbolic-ref', '--short', '--quiet', 'HEAD').output.strip
    if branch.empty?
      hash = git('rev-parse', 'HEAD').output.strip
      branch = git('name-rev', '--name-only', hash).output.strip
    end
    branch
  end
end
get_root_path(path) click to toggle source
# File lib/githooks/repository.rb, line 62
def get_root_path(path)
  git('rev-parse', '--show-toplevel', chdir: path).tap do |result|
    unless result.status.success? && result.output !~ /not a git repository/i
      fail Error::NotAGitRepo, "Unable to find a valid git repo in #{path}"
    end
  end.output.strip
end
hooks_path() click to toggle source
# File lib/githooks/repository.rb, line 58
def hooks_path
  config['hooks-path']
end
hooks_script() click to toggle source
# File lib/githooks/repository.rb, line 54
def hooks_script
  config['script']
end
last_unpushed_commit_parent_sha() click to toggle source
# File lib/githooks/repository.rb, line 164
def last_unpushed_commit_parent_sha
  last_unpushed_sha = unpushed_commits.last
  revision_sha("#{last_unpushed_sha}~1") unless last_unpushed_sha.nil?
rescue Error::RemoteNotSet
  nil
end
manifest(options = {}) click to toggle source
# File lib/githooks/repository.rb, line 78
def manifest(options = {})
  ref = options.delete(:ref)

  return staged_manifest(ref: ref) if options.delete(:staged)

  manifest_list = unstaged_manifest(ref: ref)

  tracked_manifest(ref: ref).each_with_object(manifest_list) do |file, list|
    list << file
  end if options.delete(:tracked)

  untracked_manifest(ref: ref).each_with_object(manifest_list) do |file, list|
    list << file
  end if options.delete(:untracked)

  manifest_list.sort
end
remote_branch() click to toggle source
# File lib/githooks/repository.rb, line 147
def remote_branch
  result = git('rev-parse', '--symbolic-full-name', '--abbrev-ref', "#{current_branch}@{u}")
  result.success? ? result.output.strip.split('/').last : nil
end
revision_sha(revision) click to toggle source
# File lib/githooks/repository.rb, line 131
def revision_sha(revision)
  return unless (result = git('rev-parse', revision)).status.success?
  result.output.strip
end
staged_manifest(options = {}) click to toggle source
# File lib/githooks/repository.rb, line 96
def staged_manifest(options = {})
  diff_index(options.merge(staged: true))
end
Also aliased as: commit_manifest
stash() click to toggle source
# File lib/githooks/repository.rb, line 70
def stash
  git(*%w(stash -q --keep-index -a)).status.success?
end
tracked_manifest(*) click to toggle source
# File lib/githooks/repository.rb, line 105
def tracked_manifest(*)
  files = git('ls-files', '--exclude-standard').output.strip.split(/\s*\n\s*/)
  files.collect { |path|
    next unless self.path.join(path).file?
    DiffIndexEntry.from_file_path(self, path, true).to_repo_file
  }.compact
end
unpushed_commits() click to toggle source
# File lib/githooks/repository.rb, line 121
def unpushed_commits
  unless remote_branch
    fail Error::RemoteNotSet, "No upstream remote configured for branch '#{current_branch}'"
  end

  git('log', '--format=%H', '@{upstream}..') do |result|
    fail(Error::CommandExecutionFailure, result.error) if result.failure?
  end.output.split(/\s*\n\s*/).collect(&:strip)
end
unstaged_manifest(options = {}) click to toggle source
# File lib/githooks/repository.rb, line 101
def unstaged_manifest(options = {})
  diff_index(options.merge(staged: false))
end
unstash() click to toggle source
# File lib/githooks/repository.rb, line 74
def unstash
  git(*%w(stash pop -q)).status.success?
end
untracked_manifest(*) click to toggle source
# File lib/githooks/repository.rb, line 113
def untracked_manifest(*)
  files = git('ls-files', '--others', '--exclude-standard').output.strip.split(/\s*\n\s*/)
  files.collect { |path|
    next unless self.path.join(path).file?
    DiffIndexEntry.from_file_path(self, path).to_repo_file
  }.compact
end

Private Instance Methods

diff_index(options = {}) click to toggle source
# File lib/githooks/repository.rb, line 173
def diff_index(options = {}) # rubocop:disable AbcSize
  options = DEFAULT_DIFF_INDEX_OPTIONS.merge(options)

  if $stdout.tty? && !options[:staged]
    cmd = %w(diff-files -C -M -B)
  else
    cmd = %w(diff-index -C -M -B)
    cmd << '--cached' if options[:staged]
    cmd << (options.delete(:ref) || 'HEAD')
  end

  Set.new(
    git(*cmd.flatten.compact).output_lines.collect { |diff_data|
      DiffIndexEntry.new(self, diff_data).to_repo_file
    }.compact
  )
rescue StandardError => e
  puts 'Error Encountered while acquiring manifest'
  puts "Command: git #{cmd.flatten.compact.join(' ')}"
  puts "Error: #{e.class.name}: #{e.message}: #{e.backtrace[0..5].join("\n\t")}"
  exit! 1
end
run_while_stashed(cmd) click to toggle source
# File lib/githooks/repository.rb, line 206
def run_while_stashed(cmd)
  while_stashed { system(cmd) }
  $? == 0
end
while_stashed(&block) click to toggle source
# File lib/githooks/repository.rb, line 196
def while_stashed(&block)
  fail ArgumentError, 'Missing required block' unless block_given?
  begin
    stash
    block.call
  ensure
    unstash
  end
end