Class: PDK::Template::Fetcher::Git

Inherits:
AbstractFetcher show all
Defined in:
lib/pdk/template/fetcher/git.rb

Instance Attribute Summary

Attributes inherited from AbstractFetcher

#fetched, #metadata, #path, #temporary, #uri

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from AbstractFetcher

#initialize

Constructor Details

This class inherits a constructor from PDK::Template::Fetcher::AbstractFetcher

Class Method Details

.fetchable?(uri, _options = {}) ⇒ Boolean

Whether the passed uri is fetchable by Git.

Returns:

  • (Boolean)

See Also:



10
11
12
# File 'lib/pdk/template/fetcher/git.rb', line 10

def self.fetchable?(uri, _options = {})
  PDK::Util::Git.repo?(uri.bare_uri)
end

Instance Method Details

#fetch!Object

See Also:

  • AbstractTemplateFetcher.fetch!


15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
# File 'lib/pdk/template/fetcher/git.rb', line 15

def fetch!
  return if fetched

  super

  # Default metadata for all git fetching methods
  @metadata['template-url'] = uri.

  # We don't do a checkout of local-path repos. There are lots of edge
  # cases or user un-expectations.
  if PDK::Util::Git.work_tree?(uri.shell_path)
    PDK.logger.warn format("Repository '%{repo}' has a work-tree; skipping git reset.", repo: uri.shell_path)
    @path = uri.shell_path
    @temporary = false
    @metadata['template-ref'] = describe_path_and_ref(@path)
    return
  end

  # This is either a bare local repo or a remote. either way it needs cloning.
  # A "remote" can also be git repo on the local filsystem.
  # @todo When switching this over to using rugged, cache the cloned
  # template repo in `%AppData%` or `$XDG_CACHE_DIR` and update before
  # use.
  require 'pdk/util'
  require 'pdk/util/git'

  temp_dir = PDK::Util.make_tmpdir_name('pdk-templates')
  @temporary = true
  origin_repo = uri.bare_uri
  git_ref = uri.uri_fragment

  # Clone the repository
  clone_result = PDK::Util::Git.git('clone', origin_repo, temp_dir)
  unless clone_result[:exit_code].zero?
    PDK.logger.error clone_result[:stdout]
    PDK.logger.error clone_result[:stderr]
    raise PDK::CLI::FatalError, format("Unable to clone git repository at '%{repo}' into '%{dest}'.", repo: origin_repo, dest: temp_dir)
  end
  @path = PDK::Util.canonical_path(temp_dir)

  # Checkout the git reference
  if PDK::Util::Git.work_dir_clean?(temp_dir)
    Dir.chdir(temp_dir) do
      full_ref = PDK::Util::Git.ls_remote(temp_dir, git_ref)
      @metadata['template-ref'] = describe_path_and_ref(temp_dir, full_ref)
      reset_result = PDK::Util::Git.git('reset', '--hard', full_ref)
      return if reset_result[:exit_code].zero?

      PDK.logger.error reset_result[:stdout]
      PDK.logger.error reset_result[:stderr]
      raise PDK::CLI::FatalError, format("Unable to checkout '%{ref}' of git repository at '%{path}'.", ref: git_ref, path: temp_dir)
    end
  else
    PDK.logger.warn format("Uncommitted changes found when attempting to checkout '%{ref}' of git repository at '%{path}'; skipping git reset.", ref: git_ref, path: temp_dir)
    @metadata['template-ref'] = describe_path_and_ref(temp_dir)
  end
end