class Pod::Downloader::Git

Concreted Downloader class that provides support for specifications with git sources.

Public Class Methods

options() click to toggle source
# File lib/cocoapods-downloader/git.rb, line 7
def self.options
  [:commit, :tag, :branch, :submodules]
end
preprocess_options(options) click to toggle source
# File lib/cocoapods-downloader/git.rb, line 23
def self.preprocess_options(options)
  return options unless options[:branch]

  input = [options[:git], options[:commit]].map(&:to_s)
  invalid = input.compact.any? { |value| value.start_with?('--') || value.include?(' --') }
  raise DownloaderError, "Provided unsafe input for git #{options}." if invalid

  command = ['ls-remote',
             '--',
             options[:git],
             options[:branch]]

  output = Git.execute_command('git', command)
  match = commit_from_ls_remote output, options[:branch]

  return options if match.nil?

  options[:commit] = match
  options.delete(:branch)

  options
end

Private Class Methods

commit_from_ls_remote(output, branch_name) click to toggle source

Matches a commit from the branches reported by git ls-remote.

@note When there is a branch and tag with the same name, it will match

the branch, since `refs/heads` is sorted before `refs/tags`.

@param [String] output

The output from git ls-remote.

@param [String] branch_name

The desired branch to match a commit to.

@return [String] commit hash string, or nil if no match found

# File lib/cocoapods-downloader/git.rb, line 59
def self.commit_from_ls_remote(output, branch_name)
  return nil if branch_name.nil?
  encoded_branch_name = branch_name.dup.force_encoding(Encoding::ASCII_8BIT)
  match = %r{([a-z0-9]*)\trefs\/(heads|tags)\/#{Regexp.quote(encoded_branch_name)}}.match(output)
  match[1] unless match.nil?
end

Public Instance Methods

checkout_options() click to toggle source
# File lib/cocoapods-downloader/git.rb, line 15
def checkout_options
  options = {}
  options[:git] = url
  options[:commit] = target_git('rev-parse', 'HEAD').chomp
  options[:submodules] = true if self.options[:submodules]
  options
end
options_specific?() click to toggle source
# File lib/cocoapods-downloader/git.rb, line 11
def options_specific?
  !(options[:commit] || options[:tag]).nil?
end

Private Instance Methods

checkout_commit() click to toggle source

Checks out a specific commit of the cloned repo.

# File lib/cocoapods-downloader/git.rb, line 154
def checkout_commit
  target_git 'checkout', '--quiet', options[:commit]
  update_submodules
end
clone(force_head = false, shallow_clone = true) click to toggle source

Clones the repo. If possible the repo will be shallowly cloned.

@note The ‘:commit` option requires a specific strategy as it is not

possible to specify the commit to the `clone` command.

@note ‘–branch` command line option can also take tags and detaches

the HEAD.

@param [Bool] force_head

If any specific option should be ignored and the HEAD of the
repo should be cloned.

@param [Bool] shallow_clone

Whether a shallow clone of the repo should be attempted, if
possible given the specified {#options}.
# File lib/cocoapods-downloader/git.rb, line 104
def clone(force_head = false, shallow_clone = true)
  ui_sub_action('Git download') do
    begin
      git! clone_arguments(force_head, shallow_clone)
      update_submodules
    rescue DownloaderError => e
      if e.message =~ /^fatal:.*does not support (--depth|shallow capabilities)$/im
        clone(force_head, false)
      else
        raise
      end
    end
  end
end
clone_arguments(force_head, shallow_clone) click to toggle source

The arguments to pass to ‘git` to clone the repo.

@param [Bool] force_head

If any specific option should be ignored and the HEAD of the
repo should be cloned.

@param [Bool] shallow_clone

Whether a shallow clone of the repo should be attempted, if
possible given the specified {#options}.

@return [Array<String>] arguments to pass to ‘git` to clone the repo.

# File lib/cocoapods-downloader/git.rb, line 136
def clone_arguments(force_head, shallow_clone)
  command = ['clone', url, target_path, '--template=']

  if shallow_clone && !options[:commit]
    command += %w(--single-branch --depth 1)
  end

  unless force_head
    if tag_or_branch = options[:tag] || options[:branch]
      command += ['--branch', tag_or_branch]
    end
  end

  command
end
download!() click to toggle source

@!group Base class hooks

# File lib/cocoapods-downloader/git.rb, line 72
def download!
  clone
  checkout_commit if options[:commit]
end
download_head!() click to toggle source

@return [void] Checks out the HEAD of the git source in the destination

path.
# File lib/cocoapods-downloader/git.rb, line 80
def download_head!
  clone(true)
end
target_git(*args) click to toggle source
# File lib/cocoapods-downloader/git.rb, line 159
def target_git(*args)
  git!(['-C', target_path] + args)
end
update_submodules() click to toggle source
# File lib/cocoapods-downloader/git.rb, line 119
def update_submodules
  return unless options[:submodules]
  target_git %w(submodule update --init --recursive)
end
validate_input() click to toggle source
# File lib/cocoapods-downloader/git.rb, line 163
def validate_input
  input = [url, options[:branch], options[:commit], options[:tag]].map(&:to_s)
  invalid = input.compact.any? { |value| value.start_with?('--') || value.include?(' --') }
  raise DownloaderError, "Provided unsafe input for git #{options}." if invalid
end