class Vanagon::Component::Source::Git

Attributes

clone_options[RW]
default_options[R]
log_url[RW]
ref[RW]
repo[R]
url[RW]
version[R]
workdir[RW]

Public Class Methods

new(url, workdir:, **options) click to toggle source

Constructor for the Git source type

@param url [String] url of git repo to use as source @param ref [String] ref to checkout from git repo @param workdir [String] working directory to clone into

# File lib/vanagon/component/source/git.rb, line 76
def initialize(url, workdir:, **options) # rubocop:disable Metrics/AbcSize
  opts = default_options.merge(options.reject { |k, v| v.nil? })

  # Ensure that #url returns a URI object
  @url = URI.parse(url.to_s)
  @log_url = @url.host + @url.path unless @url.host.nil? || @url.path.nil?
  @ref = opts[:ref]
  @dirname = opts[:dirname]
  @workdir = File.realpath(workdir)
  @clone_options = opts[:clone_options] ||= {}

  # We can test for Repo existence without cloning
  raise Vanagon::InvalidRepo, "url is not a valid Git repo" unless valid_remote?
end
valid_remote?(url, timeout = 0) click to toggle source

def valid_remote?(url, timeout = 0)

Timeout.timeout(timeout) do
  !!::Git.ls_remote(url)
end

rescue ::Git::GitExecuteError

false

rescue Timeout::Error

false

end

# File lib/vanagon/component/source/git.rb, line 51
def valid_remote?(url, timeout = 0)
  Timeout.timeout(timeout) do
    Vanagon::Utilities.local_command("git ls-remote --heads #{url} > /dev/null 2>&1")
    return false unless $?.exitstatus.zero?
    return true
  end
rescue Timeout::Error
  return false
rescue RuntimeError
  return false
end

Public Instance Methods

cleanup() click to toggle source

Return the correct incantation to cleanup the source directory for a given source

@return [String] command to cleanup the source

# File lib/vanagon/component/source/git.rb, line 104
def cleanup
  "rm -rf #{dirname}"
end
clone() click to toggle source

Perform a git clone of @url as a lazy-loaded accessor for @clone

# File lib/vanagon/component/source/git.rb, line 128
def clone
  if @clone_options.empty?
    @clone ||= ::Git.clone(url, dirname, path: workdir)
  else
    @clone ||= ::Git.clone(url, dirname, path: workdir, **clone_options)
  end
end
dirname() click to toggle source

The dirname to reference when building from the repo

@return [String] the directory where the repo was cloned

# File lib/vanagon/component/source/git.rb, line 117
def dirname
  @dirname || File.basename(url.path, ".git")
end
fetch() click to toggle source

Fetch the source. In this case, clone the repository into the workdir and check out the ref. Also sets the version if there is a git tag as a side effect.

# File lib/vanagon/component/source/git.rb, line 94
def fetch
  clone!
  checkout!
  version
  update_submodules
end
verify() click to toggle source

There is no md5 to manually verify here, so this is a noop.

# File lib/vanagon/component/source/git.rb, line 109
def verify
  # nothing to do here, so just tell users that and return
  VanagonLogger.info "Nothing to verify for '#{dirname}' (using Git reference '#{ref}')"
end

Private Instance Methods

checkout!() click to toggle source

Checkout desired ref/sha, make noise about it, and fail entirely if we're unable to checkout that given ref/sha

# File lib/vanagon/component/source/git.rb, line 170
def checkout!
  VanagonLogger.info "Checking out '#{ref}' from Git repo '#{dirname}'"
  clone.checkout(ref)
rescue ::Git::GitExecuteError
  raise Vanagon::CheckoutFailed, "unable to checkout #{ref} from '#{log_url}'"
end
clone!() click to toggle source

Clone a remote repo, make noise about it, and fail entirely if we're unable to retrieve the remote repo

# File lib/vanagon/component/source/git.rb, line 160
def clone!
  VanagonLogger.info "Cloning Git repo '#{log_url}'"
  VanagonLogger.info "Successfully cloned '#{dirname}'" if clone
rescue ::Git::GitExecuteError
  raise Vanagon::InvalidRepo, "Unable to clone from '#{log_url}'"
end
describe() click to toggle source

Determines a version for the given directory based on the git describe for the repository

@return [String] The version of the directory according to git describe

# File lib/vanagon/component/source/git.rb, line 190
def describe
  clone.describe(ref, tags: true)
rescue ::Git::GitExecuteError
  VanagonLogger.info "Directory '#{dirname}' cannot be versioned by Git. Maybe it hasn't been tagged yet?"
end
refs() click to toggle source

Provide a list of local refs (branches and tags)

# File lib/vanagon/component/source/git.rb, line 153
def refs
  (clone.tags.map(&:name) + clone.branches.map(&:name)).uniq
end
remote_refs() click to toggle source

Provide a list of remote refs (branches and tags)

# File lib/vanagon/component/source/git.rb, line 147
def remote_refs
  (remote['tags'].keys + remote['branches'].keys).uniq
end
update_submodules() click to toggle source

Attempt to update submodules, and do not panic if there are no submodules to initialize

# File lib/vanagon/component/source/git.rb, line 180
def update_submodules
  VanagonLogger.info "Attempting to update submodules for repo '#{dirname}'"
  clone.update_submodules(init: true)
end
valid_remote?() click to toggle source

Attempt to connect to whatever URL is provided and return True or False depending on whether or not `git` thinks it's a valid Git repo.

@return [Boolean] whether url is a valid Git repo or not

# File lib/vanagon/component/source/git.rb, line 141
def valid_remote?
  self.class.valid_remote? url
end