dependabot-core 0.94.3 → 0.94.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 9b9ca1b04d83b74e88958e5d5993404cfc65a0f1f732431c97ff2fc5c28c3528
4
- data.tar.gz: 51925653e14e70c182fcd12bf232b4e65a500708d823dfe6d8a9791f5c4ca2cb
3
+ metadata.gz: 4b11e37fb0e013f8771d0a7d3d2d43eb70ca034a5b1f34750ba221dc869a43b6
4
+ data.tar.gz: 33eaade27acbe4aefe07238a9c760358e76c56541cfed364f0ea890dfe2effea
5
5
  SHA512:
6
- metadata.gz: 000d8d39f5d6afe274272cbab57ae364e6ee571594820d5517b3a8b8583c660bb8527212ba34df392d702a73f204bdc37c92cac8aa299db6d6ebee4fbeba78b6
7
- data.tar.gz: 91eae6edc6bfc30d26fb0c70b2bef65c707b524a2d298ba7734e1558caabeedd159c190e334a3022885a8e19a7a323efffda2afe9fb1bf4a121506f23eafdf97
6
+ metadata.gz: 2794a272a65b70afc8a1c70273994931320e5fc3ef186006d5dfdfc30651a4f802b91b44dcf54efa2eeb72afa72676f64c8abcd8a6f076af521e54ddb3b2ec50
7
+ data.tar.gz: 330ce862b3214c35c5ece45690422598e06cf5129bdf88d1d956a4cfc5f5db3e015d34aa5d6bdf9a3941fda2414f8a2bb5e795e0d94dad954332888577b511c6
@@ -1,3 +1,8 @@
1
+ ## v0.94.4, 3 February 2019
2
+
3
+ - Fetch files that are nested in submodules if asked
4
+ - Clean up file fetcher base class
5
+
1
6
  ## v0.94.3, 2 February 2019
2
7
 
3
8
  - Better name for language label details
@@ -8,11 +8,18 @@ require "dependabot/clients/bitbucket"
8
8
  require "dependabot/clients/gitlab"
9
9
  require "dependabot/shared_helpers"
10
10
 
11
+ # rubocop:disable Metrics/ClassLength
11
12
  module Dependabot
12
13
  module FileFetchers
13
14
  class Base
14
15
  attr_reader :source, :credentials
15
16
 
17
+ CLIENT_NOT_FOUND_ERRORS = [
18
+ Octokit::NotFound,
19
+ Gitlab::Error::NotFound,
20
+ Dependabot::Clients::Bitbucket::NotFound
21
+ ].freeze
22
+
16
23
  def self.required_files_in?(_filename_array)
17
24
  raise NotImplementedError
18
25
  end
@@ -48,8 +55,7 @@ module Dependabot
48
55
  branch = target_branch || default_branch_for_repo
49
56
 
50
57
  @commit ||= client_for_provider.fetch_commit(repo, branch)
51
- rescue Octokit::NotFound, Gitlab::Error::NotFound,
52
- Dependabot::Clients::Bitbucket::NotFound
58
+ rescue *CLIENT_NOT_FOUND_ERRORS
53
59
  raise Dependabot::BranchNotFound, branch
54
60
  rescue Octokit::Conflict => error
55
61
  raise unless error.message.include?("Repository is empty")
@@ -57,117 +63,119 @@ module Dependabot
57
63
 
58
64
  private
59
65
 
60
- def client_for_provider
61
- case source.provider
62
- when "github"
63
- github_client_for_source
64
- when "gitlab"
65
- gitlab_client
66
- when "bitbucket"
67
- bitbucket_client
68
- else raise "Unsupported provider '#{source.provider}'."
69
- end
70
- end
71
-
72
- def default_branch_for_repo
73
- @default_branch_for_repo ||=
74
- client_for_provider.fetch_default_branch(repo)
75
- rescue Octokit::NotFound, Gitlab::Error::NotFound,
76
- Dependabot::Clients::Bitbucket::NotFound
77
- raise Dependabot::RepoNotFound, source
78
- end
79
-
80
- def fetch_file_if_present(filename)
66
+ def fetch_file_if_present(filename, fetch_submodules: false)
81
67
  dir = File.dirname(filename)
82
68
  basename = File.basename(filename)
83
- return unless repo_contents(dir: dir).map(&:name).include?(basename)
84
69
 
85
- fetch_file_from_host(filename)
86
- rescue Octokit::NotFound, Gitlab::Error::NotFound,
87
- Dependabot::Clients::Bitbucket::NotFound
70
+ repo_includes_basename =
71
+ repo_contents(dir: dir, fetch_submodules: fetch_submodules).
72
+ reject { |f| f.type == "dir" }.
73
+ map(&:name).include?(basename)
74
+ return unless repo_includes_basename
75
+
76
+ fetch_file_from_host(filename, fetch_submodules: fetch_submodules)
77
+ rescue *CLIENT_NOT_FOUND_ERRORS
88
78
  path = Pathname.new(File.join(directory, filename)).cleanpath.to_path
89
79
  raise Dependabot::DependencyFileNotFound, path
90
80
  end
91
81
 
92
- def fetch_file_from_host(filename, type: "file")
82
+ def fetch_file_from_host(filename, type: "file", fetch_submodules: false)
93
83
  path = Pathname.new(File.join(directory, filename)).cleanpath.to_path
94
84
 
95
85
  DependencyFile.new(
96
86
  name: Pathname.new(filename).cleanpath.to_path,
97
- content: fetch_file_content(path),
98
87
  directory: directory,
99
- type: type
88
+ type: type,
89
+ content: _fetch_file_content(path, fetch_submodules: fetch_submodules)
100
90
  )
101
- rescue Octokit::NotFound, Gitlab::Error::NotFound,
102
- Dependabot::Clients::Bitbucket::NotFound
91
+ rescue *CLIENT_NOT_FOUND_ERRORS
103
92
  raise Dependabot::DependencyFileNotFound, path
104
93
  end
105
94
 
106
- def fetch_file_from_host_or_submodule(filename, type: "file")
107
- fetch_file_from_host(filename, type: type)
108
- rescue Dependabot::DependencyFileNotFound => error
109
- begin
110
- repo_contents(dir: File.dirname(filename))
111
- rescue StandardError
112
- raise error
113
- end
95
+ def repo_contents(dir: ".", ignore_base_directory: false,
96
+ raise_errors: true, fetch_submodules: false)
97
+ dir = File.join(directory, dir) unless ignore_base_directory
98
+ path = Pathname.new(File.join(dir)).cleanpath.to_path.gsub(%r{^/*}, "")
114
99
 
115
- fetch_file_from_host(filename, type: type)
100
+ @repo_contents ||= {}
101
+ @repo_contents[dir] ||= _fetch_repo_contents(
102
+ path,
103
+ raise_errors: raise_errors,
104
+ fetch_submodules: fetch_submodules
105
+ )
116
106
  end
117
107
 
118
- def repo_contents(dir: ".", raise_errors: true)
119
- path = Pathname.new(File.join(directory, dir)).
120
- cleanpath.to_path.gsub(%r{^/*}, "")
121
-
122
- # Don't fetch contents of repos nested in submodules
123
- submods = @submodule_directories
124
- if submods.keys.any? { |k| path.match?(%r{#{Regexp.quote(k)}(/|$)}) }
125
- return []
126
- end
108
+ #################################################
109
+ # INTERNAL METHODS (not for use by sub-classes) #
110
+ #################################################
127
111
 
128
- @repo_contents ||= {}
129
- @repo_contents[dir] ||=
130
- case source.provider
131
- when "github" then github_repo_contents(path)
132
- when "gitlab" then gitlab_repo_contents(path)
133
- when "bitbucket" then bitbucket_repo_contents(path)
134
- else raise "Unsupported provider '#{source.provider}'."
135
- end
136
- rescue Octokit::NotFound, Gitlab::Error::NotFound,
137
- Dependabot::Clients::Bitbucket::NotFound
138
- raise if raise_errors
112
+ def _fetch_repo_contents(path, fetch_submodules: false,
113
+ raise_errors: true)
114
+ path = path.gsub(" ", "%20")
115
+ provider, repo, tmp_path, commit =
116
+ _full_specification_for(path, fetch_submodules: fetch_submodules).
117
+ values_at(:provider, :repo, :path, :commit)
118
+
119
+ _fetch_repo_contents_fully_specified(provider, repo, tmp_path, commit)
120
+ rescue *CLIENT_NOT_FOUND_ERRORS
121
+ result = raise_errors ? -> { raise } : -> { [] }
122
+ retrying ||= false
123
+
124
+ # If the path changes after calling _fetch_repo_contents_fully_specified
125
+ # it's because we've found a sub-module (and are fetching them). Trigger
126
+ # a retry to get its contents.
127
+ updated_path =
128
+ _full_specification_for(path, fetch_submodules: fetch_submodules).
129
+ fetch(:path)
130
+ retry if updated_path != tmp_path
131
+
132
+ return result.call unless fetch_submodules && !retrying
133
+
134
+ _find_submodules(path)
135
+ return result.call unless _submodule_for(path)
136
+
137
+ retrying = true
138
+ retry
139
+ end
139
140
 
140
- []
141
+ def _fetch_repo_contents_fully_specified(provider, repo, path, commit)
142
+ case provider
143
+ when "github"
144
+ _github_repo_contents(repo, path, commit)
145
+ when "gitlab"
146
+ _gitlab_repo_contents(repo, path, commit)
147
+ when "bitbucket"
148
+ _bitbucket_repo_contents(repo, path, commit)
149
+ else raise "Unsupported provider '#{provider}'."
150
+ end
141
151
  end
142
152
 
143
- def github_repo_contents(path)
153
+ def _github_repo_contents(repo, path, commit)
144
154
  path = path.gsub(" ", "%20")
145
- github_response = github_client_for_source.
146
- contents(repo, path: path, ref: commit)
155
+ github_response = github_client.contents(repo, path: path, ref: commit)
147
156
 
148
157
  if github_response.respond_to?(:type) &&
149
158
  github_response.type == "submodule"
150
159
  @submodule_directories[path] = github_response
151
-
152
- sub_source = Source.from_url(github_response.submodule_git_url)
153
- github_response = github_client_for_source.
154
- contents(sub_source.repo, ref: github_response.sha)
160
+ raise Octokit::NotFound
155
161
  elsif github_response.respond_to?(:type)
156
162
  raise Octokit::NotFound
157
163
  end
158
164
 
159
- github_response.map do |f|
160
- OpenStruct.new(
161
- name: f.name,
162
- path: f.path,
163
- type: f.type,
164
- sha: f.sha,
165
- size: f.size
166
- )
167
- end
165
+ github_response.map { |f| _build_github_file_struct(f) }
166
+ end
167
+
168
+ def _build_github_file_struct(file)
169
+ OpenStruct.new(
170
+ name: file.name,
171
+ path: file.path,
172
+ type: file.type,
173
+ sha: file.sha,
174
+ size: file.size
175
+ )
168
176
  end
169
177
 
170
- def gitlab_repo_contents(path)
178
+ def _gitlab_repo_contents(repo, path, commit)
171
179
  gitlab_client.
172
180
  repo_tree(repo, path: path, ref_name: commit, per_page: 100).
173
181
  map do |file|
@@ -180,7 +188,7 @@ module Dependabot
180
188
  end
181
189
  end
182
190
 
183
- def bitbucket_repo_contents(path)
191
+ def _bitbucket_repo_contents(repo, path, commit)
184
192
  response = bitbucket_client.fetch_repo_contents(
185
193
  repo,
186
194
  commit,
@@ -203,54 +211,67 @@ module Dependabot
203
211
  end
204
212
  end
205
213
 
206
- def fetch_file_content(path)
207
- path = path.gsub(%r{^/*}, "")
208
- dir = Pathname.new(path).dirname.to_path.gsub(%r{^/*}, "")
209
-
210
- if @submodule_directories.key?(dir)
211
- return fetch_submodule_file_content(path)
212
- end
213
-
214
- case source.provider
215
- when "github"
216
- fetch_file_content_from_github(path, repo, commit)
217
- when "gitlab"
218
- tmp = gitlab_client.get_file(repo, path, commit).content
219
- Base64.decode64(tmp).force_encoding("UTF-8").encode
220
- when "bitbucket"
221
- bitbucket_client.fetch_file_contents(repo, commit, path)
222
- else raise "Unsupported provider '#{source.provider}'."
214
+ def _full_specification_for(path, fetch_submodules:)
215
+ if fetch_submodules && _submodule_for(path)
216
+ submodule_details = @submodule_directories[_submodule_for(path)]
217
+ sub_source = Source.from_url(submodule_details.submodule_git_url)
218
+ {
219
+ repo: sub_source.repo,
220
+ commit: submodule_details.sha,
221
+ provider: sub_source.provider,
222
+ path: path.gsub(%r{^#{Regexp.quote(_submodule_for(path))}(/|$)}, "")
223
+ }
224
+ else
225
+ {
226
+ repo: source.repo,
227
+ path: path,
228
+ commit: commit,
229
+ provider: source.provider
230
+ }
223
231
  end
224
232
  end
225
233
 
226
- def fetch_submodule_file_content(path)
234
+ def _fetch_file_content(path, fetch_submodules: false)
227
235
  path = path.gsub(%r{^/*}, "")
228
- dir = Pathname.new(path).dirname.to_path.gsub(%r{^/*}, "")
229
- submodule = @submodule_directories[dir]
230
236
 
231
- provider = Source.from_url(submodule.submodule_git_url).provider
232
- repo = Source.from_url(submodule.submodule_git_url).repo
233
- commit = submodule.sha
234
- path = path.gsub("#{dir}/", "")
237
+ provider, repo, path, commit =
238
+ _full_specification_for(path, fetch_submodules: fetch_submodules).
239
+ values_at(:provider, :repo, :path, :commit)
240
+
241
+ _fetch_file_content_fully_specified(provider, repo, path, commit)
242
+ rescue *CLIENT_NOT_FOUND_ERRORS
243
+ retrying ||= false
244
+
245
+ raise unless fetch_submodules && !retrying && !_submodule_for(path)
246
+
247
+ _find_submodules(path)
248
+ raise unless _submodule_for(path)
235
249
 
250
+ retrying = true
251
+ retry
252
+ end
253
+
254
+ def _fetch_file_content_fully_specified(provider, repo, path, commit)
236
255
  case provider
237
256
  when "github"
238
- fetch_file_content_from_github(path, repo, commit)
257
+ _fetch_file_content_from_github(path, repo, commit)
239
258
  when "gitlab"
240
259
  tmp = gitlab_client.get_file(repo, path, commit).content
241
260
  Base64.decode64(tmp).force_encoding("UTF-8").encode
242
261
  when "bitbucket"
243
262
  bitbucket_client.fetch_file_contents(repo, commit, path)
244
- else raise "Unsupported provider '#{provider}'."
263
+ else raise "Unsupported provider '#{source.provider}'."
245
264
  end
246
265
  end
247
266
 
248
267
  # rubocop:disable Metrics/AbcSize
249
- def fetch_file_content_from_github(path, repo, commit)
250
- tmp = github_client_for_source.contents(repo, path: path, ref: commit)
268
+ def _fetch_file_content_from_github(path, repo, commit)
269
+ tmp = github_client.contents(repo, path: path, ref: commit)
270
+
271
+ raise Octokit::NotFound if tmp.is_a?(Array)
251
272
 
252
273
  if tmp.type == "symlink"
253
- tmp = github_client_for_source.contents(
274
+ tmp = github_client.contents(
254
275
  repo,
255
276
  path: tmp.target,
256
277
  ref: commit
@@ -268,15 +289,55 @@ module Dependabot
268
289
  file_details = repo_contents(dir: dir).find { |f| f.name == basename }
269
290
  raise unless file_details
270
291
 
271
- tmp = github_client_for_source.blob(repo, file_details.sha)
292
+ tmp = github_client.blob(repo, file_details.sha)
272
293
  return tmp.content if tmp.encoding == "utf-8"
273
294
 
274
295
  Base64.decode64(tmp.content).force_encoding("UTF-8").encode
275
296
  end
276
297
  # rubocop:enable Metrics/AbcSize
277
298
 
278
- def github_client_for_source
279
- @github_client_for_source ||=
299
+ def default_branch_for_repo
300
+ @default_branch_for_repo ||= client_for_provider.
301
+ fetch_default_branch(repo)
302
+ rescue *CLIENT_NOT_FOUND_ERRORS
303
+ raise Dependabot::RepoNotFound, source
304
+ end
305
+
306
+ # Update the @submodule_directories hash by exploiting a side-effect of
307
+ # recursively calling `repo_contents` for each directory up the tree
308
+ # until a submodule is found
309
+ def _find_submodules(path)
310
+ path = Pathname.new(path).cleanpath.to_path.gsub(%r{^/*}, "")
311
+ dir = File.dirname(path)
312
+
313
+ return if [directory, "."].include?(dir)
314
+
315
+ repo_contents(
316
+ dir: dir,
317
+ ignore_base_directory: true,
318
+ fetch_submodules: true,
319
+ raise_errors: false
320
+ )
321
+ end
322
+
323
+ def _submodule_for(path)
324
+ submodules = @submodule_directories.keys
325
+ submodules.
326
+ select { |k| path.match?(%r{^#{Regexp.quote(k)}(/|$)}) }.
327
+ max_by(&:length)
328
+ end
329
+
330
+ def client_for_provider
331
+ case source.provider
332
+ when "github" then github_client
333
+ when "gitlab" then gitlab_client
334
+ when "bitbucket" then bitbucket_client
335
+ else raise "Unsupported provider '#{source.provider}'."
336
+ end
337
+ end
338
+
339
+ def github_client
340
+ @github_client ||=
280
341
  Dependabot::Clients::GithubWithRetries.for_source(
281
342
  source: source,
282
343
  credentials: credentials
@@ -301,3 +362,4 @@ module Dependabot
301
362
  end
302
363
  end
303
364
  end
365
+ # rubocop:enable Metrics/ClassLength
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Dependabot
4
- VERSION = "0.94.3"
4
+ VERSION = "0.94.4"
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dependabot-core
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.94.3
4
+ version: 0.94.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dependabot
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-02-02 00:00:00.000000000 Z
11
+ date: 2019-02-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: aws-sdk-ecr