dependabot-core 0.94.3 → 0.94.4

Sign up to get free protection for your applications and to get access to all the features.
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