Class: Dependabot::GitMetadataFetcher

Inherits:
Object
  • Object
show all
Extended by:
T::Sig
Defined in:
lib/dependabot/git_metadata_fetcher.rb

Defined Under Namespace

Classes: GitResponse

Constant Summary collapse

KNOWN_HOSTS =
/github\.com|bitbucket\.org|gitlab.com/i
MAX_COMMITS_PER_PAGE =
100

Instance Method Summary collapse

Constructor Details

#initialize(url:, credentials:) ⇒ GitMetadataFetcher

Returns a new instance of GitMetadataFetcher.



43
44
45
46
# File 'lib/dependabot/git_metadata_fetcher.rb', line 43

def initialize(url:, credentials:)
  @url = url
  @credentials = credentials
end

Instance Method Details

#fetch_tags_with_detail(uri) ⇒ Object



140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
# File 'lib/dependabot/git_metadata_fetcher.rb', line 140

def fetch_tags_with_detail(uri)
  response_with_git = fetch_tags_with_detail_from_git_for(uri)
  return response_with_git.body if response_with_git.status == 200

  raise Dependabot::GitDependenciesNotReachable, [uri] unless uri.match?(KNOWN_HOSTS)

  if response_with_git.status < 400
    raise "Unexpected response: #{response_with_git.status} - #{response_with_git.body}"
  end

  if uri.match?(/github\.com/i)
    response = response_with_git.data
    response[:response_headers] = response[:headers] unless response.nil?
    raise Octokit::Error.from_response(response)
  end

  raise "Server error at #{uri}: #{response_with_git.body}" if response_with_git.status >= 500

  raise Dependabot::GitDependenciesNotReachable, [uri]
rescue Excon::Error::Socket, Excon::Error::Timeout
  raise if uri.match?(KNOWN_HOSTS)

  raise Dependabot::GitDependenciesNotReachable, [uri]
end

#head_commit_for_ref(ref) ⇒ Object



90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
# File 'lib/dependabot/git_metadata_fetcher.rb', line 90

def head_commit_for_ref(ref)
  if ref == "HEAD"
    # Remove the opening clause of the upload pack as this isn't always
    # followed by a line break. When it isn't (e.g., with Bitbucket) it
    # causes problems for our `sha_for_update_pack_line` logic. The format
    # of this opening clause is documented at
    # https://git-scm.com/docs/http-protocol#_smart_server_response
    line = T.must(upload_pack).gsub(/^[0-9a-f]{4}# service=git-upload-pack/, "")
            .lines.find { |l| l.include?(" HEAD") }
    return sha_for_update_pack_line(line) if line
  end

  refs_for_upload_pack
    .find { |r| r.name == ref }
    &.commit_sha
end

#head_commit_for_ref_sha(ref) ⇒ Object



108
109
110
111
112
# File 'lib/dependabot/git_metadata_fetcher.rb', line 108

def head_commit_for_ref_sha(ref)
  refs_for_upload_pack
    .find { |r| r.ref_sha == ref }
    &.commit_sha
end

#parse_refs_for_tag_with_detailObject



123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
# File 'lib/dependabot/git_metadata_fetcher.rb', line 123

def parse_refs_for_tag_with_detail
  result_lines = []
  return result_lines if upload_tag_with_detail.nil?

  T.must(upload_tag_with_detail).lines.each do |line|
    tag, detail = line.split(/\s+/, 2)
    next unless tag && detail

    result_lines << GitTagWithDetail.new(
      tag: tag.strip,
      release_date: detail.strip
    )
  end
  result_lines
end

#ref_details_for_pinned_ref(ref) ⇒ Object



166
167
168
# File 'lib/dependabot/git_metadata_fetcher.rb', line 166

def ref_details_for_pinned_ref(ref)
  Dependabot::RegistryClient.get(url: provider_url(ref))
end

#ref_namesObject



85
86
87
# File 'lib/dependabot/git_metadata_fetcher.rb', line 85

def ref_names
  refs_for_upload_pack.map(&:name)
end

#refs_for_tag_with_detailObject



115
116
117
118
119
120
# File 'lib/dependabot/git_metadata_fetcher.rb', line 115

def refs_for_tag_with_detail
  @refs_for_tag_with_detail ||= T.let(
    parse_refs_for_tag_with_detail,
    T.nilable(T::Array[GitTagWithDetail])
  )
end

#refs_for_upload_packObject



80
81
82
# File 'lib/dependabot/git_metadata_fetcher.rb', line 80

def refs_for_upload_pack
  @refs_for_upload_pack ||= T.let(parse_refs_for_upload_pack, T.nilable(T::Array[GitRef]))
end

#tagsObject



56
57
58
59
60
61
62
63
64
65
66
67
68
69
# File 'lib/dependabot/git_metadata_fetcher.rb', line 56

def tags
  return [] unless upload_pack

  @tags ||= T.let(
    tags_for_upload_pack.map do |ref|
      GitRef.new(
        name: ref.name,
        tag_sha: ref.ref_sha,
        commit_sha: ref.commit_sha
      )
    end,
    T.nilable(T::Array[GitRef])
  )
end

#tags_for_upload_packObject



72
73
74
75
76
77
# File 'lib/dependabot/git_metadata_fetcher.rb', line 72

def tags_for_upload_pack
  @tags_for_upload_pack ||= T.let(
    refs_for_upload_pack.select { |ref| ref.ref_type == RefType::Tag },
    T.nilable(T::Array[GitRef])
  )
end

#upload_packObject



49
50
51
52
53
# File 'lib/dependabot/git_metadata_fetcher.rb', line 49

def upload_pack
  @upload_pack ||= T.let(fetch_upload_pack_for(url), T.nilable(String))
rescue Octokit::ClientError
  raise Dependabot::GitDependenciesNotReachable, [url]
end