class BetweenMeals::Repo::Git

Public Instance Methods

changes(start_ref, end_ref) click to toggle source

Return files changed between two revisions

# File lib/between_meals/repo/git.rb, line 89
def changes(start_ref, end_ref)
  valid_ref?(start_ref)
  valid_ref?(end_ref) if end_ref
  stdout = @cmd.diff(start_ref, end_ref).stdout
  begin
    parse_status(stdout).compact
  rescue StandardError => e
    # We've seen some weird non-reproducible failures here
    @logger.error(
      'Something went wrong. Please report this output.',
    )
    @logger.error(e)
    stdout.lines.each do |line|
      @logger.error(line.strip)
    end
    exit(1)
  end
end
checkout(url) click to toggle source
# File lib/between_meals/repo/git.rb, line 83
def checkout(url)
  @cmd.clone(url, @repo_path)
  @repo = Rugged::Repository.new(File.expand_path(@repo_path))
end
email() click to toggle source
# File lib/between_meals/repo/git.rb, line 135
def email
  @cmd.config('user.email').stdout.strip
end
exists?() click to toggle source
# File lib/between_meals/repo/git.rb, line 52
def exists?
  !@repo.nil?
end
files() click to toggle source

Return all files

# File lib/between_meals/repo/git.rb, line 113
def files
  @repo.index.map { |x| { :path => x[:path], :status => :created } }
end
head_parents() click to toggle source
# File lib/between_meals/repo/git.rb, line 77
def head_parents
  @repo.head.target.parents.map do |x|
    { :rev => x.tree.oid, :time => x.time }
  end
end
head_rev() click to toggle source
# File lib/between_meals/repo/git.rb, line 56
def head_rev
  @repo.head.target.oid
end
last_author() click to toggle source
# File lib/between_meals/repo/git.rb, line 73
def last_author
  @repo.head.target.to_hash[:author]
end
last_msg() click to toggle source
# File lib/between_meals/repo/git.rb, line 60
def last_msg
  @repo.head.target.message
end
last_msg=(msg) click to toggle source
# File lib/between_meals/repo/git.rb, line 64
def last_msg=(msg)
  @repo.head.target.amend(
    {
      :message => msg,
      :update_ref => 'HEAD',
    },
  )
end
name() click to toggle source
# File lib/between_meals/repo/git.rb, line 131
def name
  @cmd.config('user.name').stdout.strip
end
repo_object() click to toggle source

Allow people to get access to the underlying Rugged object for their hooks

# File lib/between_meals/repo/git.rb, line 48
def repo_object
  @repo
end
setup() click to toggle source
# File lib/between_meals/repo/git.rb, line 28
def setup
  if File.exist?(File.expand_path(@repo_path))
    begin
      @repo = Rugged::Repository.new(File.expand_path(@repo_path))
    rescue StandardError
      @repo = nil
    end
  else
    @repo = nil
  end
  @bin = 'git'
  @cmd = BetweenMeals::Repo::Git::Cmd.new(
    :bin => @bin,
    :cwd => @repo_path,
    :logger => @logger,
  )
end
status() click to toggle source
# File lib/between_meals/repo/git.rb, line 127
def status
  @cmd.status.stdout.strip
end
update() click to toggle source
# File lib/between_meals/repo/git.rb, line 108
def update
  @cmd.pull.stdout
end
upstream?(rev, master = 'upstream/master') click to toggle source
# File lib/between_meals/repo/git.rb, line 117
def upstream?(rev, master = 'upstream/master')
  if @cmd.merge_base(rev, master).stdout.strip == rev
    return true
  end

  return false
rescue StandardError
  return false
end
valid_ref?(ref) click to toggle source
# File lib/between_meals/repo/git.rb, line 139
def valid_ref?(ref)
  unless @repo.exists?(ref)
    fail Changeset::ReferenceError
  end
end

Private Instance Methods

parse_status(changes) click to toggle source
# File lib/between_meals/repo/git.rb, line 147
def parse_status(changes)
  # man git-diff-files
  # Possible status letters are:
  #
  # A: addition of a file
  # C: copy of a file into a new one
  # D: deletion of a file
  # M: modification of the contents or mode of a file
  # R: renaming of a file
  # T: change in the type of the file
  # U: file is unmerged (you must complete the merge before it can
  #    be committed)
  # X: "unknown" change type (most probably a bug, please report it)

  # rubocop:disable MultilineBlockChain
  changes.lines.map do |line|
    parts = line.chomp.split("\t")
    case parts[0]
    when 'A'
      # A path
      {
        :status => :modified,
        :path => parts[1],
      }
    when /^C(?:\d*)/
      # C<numbers> path1 path2
      {
        :status => :modified,
        :path => parts[2],
      }
    when 'D'
      # D path
      {
        :status => :deleted,
        :path => parts[1],
      }
    when /^M(?:\d*)/
      # M<numbers> path
      {
        :status => :modified,
        :path => parts[1],
      }
    when /^R(?:\d*)/
      # R<numbers> path1 path2
      [
        {
          :status => :deleted,
          :path => parts[1],
        },
        {
          :status => :modified,
          :path => parts[2],
        },
      ]
    when 'T'
      # T path
      [
        {
          :status => :deleted,
          :path => parts[1],
        },
        {
          :status => :modified,
          :path => parts[1],
        },
      ]
    else
      fail 'Failed to parse repo diff line.'
    end
  end.flatten.map do |x|
    {
      :status => x[:status],
      :path => x[:path].sub("#{@repo_path}/", ''),
    }
  end
  # rubocop:enable MultilineBlockChain
end