class ManageIQ::CrossRepo::Repository

Attributes

identifier[R]
org[R]
path[R]
ref[R]
repo[R]
server[R]
sha[R]
url[R]

Public Class Methods

new(identifier, server: "https://github.com") click to toggle source

ManageIQ::CrossRepo::Repository

@param identifier [String] the short representation of a repository relative to a server, format [org/]repo @param server [String] The git repo server hosting this repository, default: github.com @example

Repostory.new("ManageIQ/manageiq@master", server: "https://github.com")
# File lib/manageiq/cross_repo/repository.rb, line 12
def initialize(identifier, server: "https://github.com")
  @identifier = identifier
  @server     = server
  @org, @repo, @ref, @sha, @url, @path = parse_identifier
end

Public Instance Methods

==(other) click to toggle source
# File lib/manageiq/cross_repo/repository.rb, line 22
def ==(other)
  repo == other.repo && sha == other.sha
end
core?() click to toggle source
# File lib/manageiq/cross_repo/repository.rb, line 18
def core?
  repo.casecmp("manageiq") == 0
end
ensure_clone() click to toggle source
# File lib/manageiq/cross_repo/repository.rb, line 26
def ensure_clone
  return if path.exist?

  require "mixlib/archive"
  require "open-uri"
  require "tmpdir"
  require "zlib"

  retries ||= 0

  puts "Fetching #{tarball_url}#{retry_count(retries)}"

  Dir.mktmpdir do |dir|
    Mixlib::Archive.new(open_tarball_url(tarball_url)).extract(dir)

    content_dir = Pathname.new(dir).children.detect(&:directory?)
    FileUtils.mkdir_p(path.dirname)
    FileUtils.mv(content_dir, path)
  end
rescue => e
  retries += 1
  raise if retries > 3

  sleep 1
  retry
end

Private Instance Methods

git_branch_to_sha(url, branch) click to toggle source
# File lib/manageiq/cross_repo/repository.rb, line 171
def git_branch_to_sha(url, branch)
  `git ls-remote #{url} #{branch}`.split("\t").first
end
git_pr_to_sha(url, pr) click to toggle source
# File lib/manageiq/cross_repo/repository.rb, line 175
def git_pr_to_sha(url, pr)
  git_branch_to_sha(url, "refs/pull/#{pr}/merge") || git_branch_to_sha(url, "refs/pull/#{pr}/head")
end
local_identifier?() click to toggle source
# File lib/manageiq/cross_repo/repository.rb, line 65
def local_identifier?
  ["/", "~", "."].include?(identifier[0])
end
open_tarball_url(url) click to toggle source
# File lib/manageiq/cross_repo/repository.rb, line 158
def open_tarball_url(url)
  archive = URI.open(tarball_url, "rb")

  if archive.kind_of?(StringIO)
    archive = Tempfile.new('cross_repo').tap do |f|
      f.write(archive.string)
      f.fsync
    end.path
  end

  archive
end
parse_identifier() click to toggle source
# File lib/manageiq/cross_repo/repository.rb, line 55
def parse_identifier
  if local_identifier?
    parse_local_identifier
  elsif url_identifier?
    parse_url_identifier
  else
    parse_repo_identifier
  end
end
parse_local_identifier() click to toggle source
# File lib/manageiq/cross_repo/repository.rb, line 69
def parse_local_identifier
  path = Pathname.new(identifier).expand_path
  raise ArgumentError, "Path #{path} does not exist" unless path.exist?

  org  = nil
  repo = path.basename.to_s
  ref  = Dir.chdir(path) { `git rev-parse HEAD`.chomp }
  sha  = ref
  url  = nil

  return org, repo, ref, sha, url, path
end
parse_repo_identifier() click to toggle source
# File lib/manageiq/cross_repo/repository.rb, line 119
def parse_repo_identifier
  if identifier.include?("#")
    name, pr = identifier.split("#")
  else
    name, ref_or_branch = identifier.split("@")
    if ref_or_branch.nil?
      branch = "master"
    elsif ref_or_branch.match?(/^\h+$/)
      ref = ref_or_branch
    else
      branch = ref_or_branch
    end
  end

  org, repo = name.split("/")
  repo, org = org, "ManageIQ" if repo.nil?

  url = File.join(server, org, repo)

  sha =
    if pr
      git_pr_to_sha(url, pr)
    elsif branch
      git_branch_to_sha(url, branch)
    else
      ref
    end

  raise ArgumentError, "#{identifier} does not exist" if sha.nil?

  path = REPOS_DIR.join("#{org}/#{repo}@#{sha}")

  return org, repo, ref, sha, url, path
end
parse_url_identifier() click to toggle source
# File lib/manageiq/cross_repo/repository.rb, line 86
def parse_url_identifier
  url_path = URI.parse(identifier).path
  _, org, repo, type, commit_branch_or_pr = url_path.split("/")

  case type
  when "tree"
    branch = commit_branch_or_pr
  when "commit"
    commit = commit_branch_or_pr
  when "pull"
    pr = commit_branch_or_pr
  else
    branch = "master"
  end

  url = File.join(server, org, repo)
  sha =
    if pr
      git_pr_to_sha(url, pr)
    elsif branch
      git_branch_to_sha(url, branch)
    else
      commit
    end

  raise ArgumentError, "#{identifier} does not exist" if sha.nil?

  ref  = nil
  path = REPOS_DIR.join("#{org}/#{repo}@#{sha}")

  return org, repo, ref, sha, url, path
end
retry_count(num) click to toggle source
# File lib/manageiq/cross_repo/repository.rb, line 179
def retry_count(num)
  return if num == 0

  "  (retry #{num}/3)"
end
tarball_url() click to toggle source
# File lib/manageiq/cross_repo/repository.rb, line 154
def tarball_url
  url && File.join(url, "tarball", sha)
end
url_identifier?() click to toggle source
# File lib/manageiq/cross_repo/repository.rb, line 82
def url_identifier?
  identifier.start_with?(server)
end