dependabot-python 0.95.58 → 0.95.59

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: dea39898a311aabfdfeed788e75fcd6ad6e2b42636f317b01a6cf0216d2ba069
4
- data.tar.gz: '069170b809ae713b3291b85718e6b13bae2a2db9ce32c63d9f59a800f7ade91e'
3
+ metadata.gz: 366c91fb1e2085cfeb25e78ae9892afea7ab90a5087711f687424998b0f74e93
4
+ data.tar.gz: f2003811eb623bb96682481a87fa89653032190d351fe076ff9ade7eb17e165b
5
5
  SHA512:
6
- metadata.gz: e6d41cd16b815f8679e3051724d15472934bfb962d91b4a029d240c26b19a427289e100aa9808635c14ee63150de6cefe8d3da761df79d24a8e5f189eabb3f89
7
- data.tar.gz: 678ed8722437bc738a5f64442f7a6383e4717439f25ab625a9f22315f54fb822ad55d1b26a7e3f6f735d29ca6af97e7314a722ccadfebcf012b055d874b4f5c6
6
+ metadata.gz: 77b70b748b3a1076f2fad8821e596929f375dd8432b2ae3f4116c04d2d5d5e770951a5ac54b21ef75082dd36b51ec8aab3d85ea0e3ea8fbe2630b017b35ebc34
7
+ data.tar.gz: cb47c3f64b83edc3f2c83d4d8d591dabc38c5b1090db64578a51911e85c23b5d162292cf072ea612146211b5a2bad10636d8ab3903819b7d1e3d687e687d44b4
@@ -187,6 +187,7 @@ module Dependabot
187
187
  SharedHelpers.in_a_temporary_directory do
188
188
  SharedHelpers.with_git_configured(credentials: credentials) do
189
189
  write_temporary_dependency_files(prepared_pipfile_content)
190
+ install_required_python
190
191
 
191
192
  # Initialize a git repo to appease pip-tools
192
193
  IO.popen("git init", err: %i(child out)) if setup_files.any?
@@ -238,14 +239,14 @@ module Dependabot
238
239
  )
239
240
  end
240
241
 
241
- def run_pipenv_command(command)
242
+ def run_command(command)
242
243
  start = Time.now
243
244
  stdout, process = Open3.capture2e(command)
244
245
  time_taken = Time.now - start
245
246
 
246
247
  # Raise an error with the output from the shell session if Pipenv
247
248
  # returns a non-zero status
248
- return if process.success?
249
+ return stdout if process.success?
249
250
 
250
251
  raise SharedHelpers::HelperSubprocessFailed.new(
251
252
  message: stdout,
@@ -255,6 +256,11 @@ module Dependabot
255
256
  process_exit_value: process.to_s
256
257
  }
257
258
  )
259
+ end
260
+
261
+ def run_pipenv_command(command)
262
+ local_command = "pyenv local #{python_version} && " + command
263
+ run_command(local_command)
258
264
  rescue SharedHelpers::HelperSubprocessFailed => error
259
265
  original_error ||= error
260
266
  msg = error.message
@@ -265,10 +271,16 @@ module Dependabot
265
271
  end
266
272
 
267
273
  raise relevant_error unless error_suggests_bad_python_version?(msg)
268
- raise relevant_error if command.include?("--two")
274
+ raise relevant_error if python_version.start_with?("2")
269
275
 
270
- command = command.gsub("pipenv ", "pipenv --two ")
276
+ # Clear the existing virtualenv, so that we use the new Python version
277
+ run_command("pyenv local #{python_version} && pyenv exec pipenv --rm")
278
+
279
+ @python_version = "2.7.15"
271
280
  retry
281
+ ensure
282
+ @python_version = nil
283
+ FileUtils.remove_entry(".python-version", true)
272
284
  end
273
285
 
274
286
  def error_suggests_bad_python_version?(message)
@@ -279,13 +291,14 @@ module Dependabot
279
291
 
280
292
  def write_temporary_dependency_files(pipfile_content)
281
293
  dependency_files.each do |file|
282
- next if file.name == ".python-version"
283
-
284
294
  path = file.name
285
295
  FileUtils.mkdir_p(Pathname.new(path).dirname)
286
296
  File.write(path, file.content)
287
297
  end
288
298
 
299
+ # Overwrite the .python-version with updated content
300
+ File.write(".python-version", python_version)
301
+
289
302
  setup_files.each do |file|
290
303
  path = file.name
291
304
  FileUtils.mkdir_p(Pathname.new(path).dirname)
@@ -302,6 +315,21 @@ module Dependabot
302
315
  File.write("Pipfile", pipfile_content)
303
316
  end
304
317
 
318
+ def install_required_python
319
+ # Initialize a git repo to appease pip-tools
320
+ begin
321
+ run_command("git init") if setup_files.any?
322
+ rescue Dependabot::SharedHelpers::HelperSubprocessFailed
323
+ nil
324
+ end
325
+
326
+ return if run_command("pyenv versions").include?(python_version)
327
+
328
+ requirements_path = NativeHelpers.python_requirements_path
329
+ run_command("pyenv install -s")
330
+ run_command("pyenv exec pip install -r #{requirements_path}")
331
+ end
332
+
305
333
  def sanitized_setup_file_content(file)
306
334
  @sanitized_setup_file_content ||= {}
307
335
  if @sanitized_setup_file_content[file.name]
@@ -314,6 +342,59 @@ module Dependabot
314
342
  sanitized_content
315
343
  end
316
344
 
345
+ def python_version
346
+ @python_version ||= python_version_from_supported_versions
347
+ end
348
+
349
+ def python_version_from_supported_versions
350
+ requirement_string =
351
+ if @using_python_two then "2.7.*"
352
+ elsif user_specified_python_requirement
353
+ parts = user_specified_python_requirement.split(".")
354
+ parts.fill("*", (parts.length)..2).join(".")
355
+ else PythonVersions::PRE_INSTALLED_PYTHON_VERSIONS.first
356
+ end
357
+
358
+ # Ideally, the requirement is satisfied by a Python version we support
359
+ requirement = Python::Requirement.new(requirement_string)
360
+ version =
361
+ PythonVersions::SUPPORTED_VERSIONS_TO_ITERATE.
362
+ find { |v| requirement.satisfied_by?(Python::Version.new(v)) }
363
+ return version if version
364
+
365
+ # If not, and changing the patch version would fix things, we do that
366
+ # as the patch version is unlikely to affect resolution
367
+ requirement =
368
+ Python::Requirement.new(requirement_string.gsub(/\.\d+$/, ".*"))
369
+ version =
370
+ PythonVersions::SUPPORTED_VERSIONS_TO_ITERATE.
371
+ find { |v| requirement.satisfied_by?(Python::Version.new(v)) }
372
+ return version if version
373
+
374
+ # Otherwise we have to raise, giving details of the Python versions
375
+ # that Dependabot supports
376
+ msg = "Dependabot detected the following Python requirement "\
377
+ "for your project: '#{requirement_string}'.\n\nCurrently, the "\
378
+ "following Python versions are supported in Dependabot: "\
379
+ "#{PythonVersions::SUPPORTED_VERSIONS.join(', ')}."
380
+ raise DependencyFileNotResolvable, msg
381
+ end
382
+
383
+ def user_specified_python_requirement
384
+ if pipfile_python_requirement&.match?(/^\d/)
385
+ return pipfile_python_requirement
386
+ end
387
+
388
+ python_version_file&.content&.strip
389
+ end
390
+
391
+ def pipfile_python_requirement
392
+ parsed_pipfile = TomlRB.parse(pipfile.content)
393
+
394
+ parsed_pipfile.dig("requires", "python_full_version") ||
395
+ parsed_pipfile.dig("requires", "python_version")
396
+ end
397
+
317
398
  def setup_cfg(file)
318
399
  dependency_files.find do |f|
319
400
  f.name == file.name.sub(/\.py$/, ".cfg")
@@ -382,6 +463,10 @@ module Dependabot
382
463
  dependency_files.select { |f| f.name.end_with?(".txt") }
383
464
  end
384
465
 
466
+ def python_version_file
467
+ dependency_files.find { |f| f.name == ".python-version" }
468
+ end
469
+
385
470
  def pipenv_environment_variables
386
471
  environment_variables = [
387
472
  "PIPENV_YES=true", # Install new Python versions if needed
@@ -214,7 +214,7 @@ module Dependabot
214
214
 
215
215
  requirements = Python::Requirement.requirements_array(requirement)
216
216
 
217
- PythonVersions::PYTHON_VERSIONS.find do |version|
217
+ PythonVersions::SUPPORTED_VERSIONS.find do |version|
218
218
  requirements.any? do |r|
219
219
  r.satisfied_by?(Python::Version.new(version))
220
220
  end
@@ -3,23 +3,26 @@
3
3
  module Dependabot
4
4
  module Python
5
5
  module PythonVersions
6
- # Poetry doesn't handle Python versions, so we have to do so manually
7
- # (checking from a list of versions Poetry supports).
8
- # This list gets iterated through to find a valid version, so we have
9
- # the two pre-installed versions listed first.
10
- PYTHON_VERSIONS = %w(
6
+ PRE_INSTALLED_PYTHON_VERSIONS = %w(
11
7
  3.6.8 2.7.15
8
+ ).freeze
9
+
10
+ # Due to an OpenSSL issue we can only install the following versions in
11
+ # the Dependabot container.
12
+ SUPPORTED_VERSIONS = %w(
12
13
  3.7.2 3.7.1 3.7.0
13
14
  3.6.8 3.6.7 3.6.6 3.6.5 3.6.4 3.6.3 3.6.2 3.6.1 3.6.0
14
- 3.5.6 3.5.5 3.5.4 3.5.3 3.5.2 3.5.1 3.5.0
15
- 3.4.9 3.4.8 3.4.7 3.4.6 3.4.5 3.4.4 3.4.3 3.4.2 3.4.1 3.4.0
16
- 2.7.15 2.7.14 2.7.13 2.7.12 2.7.11 2.7.10 2.7.9 2.7.8 2.7.7 2.7.6 2.7.5
17
- 2.7.4 2.7.3 2.7.2 2.7.1 2.7
15
+ 3.5.6 3.5.5 3.5.4 3.5.3
16
+ 2.7.15 2.7.14 2.7.13
18
17
  ).freeze
19
18
 
20
- PRE_INSTALLED_PYTHON_VERSIONS = %w(
21
- 3.6.8 2.7.15
22
- ).freeze
19
+ # This list gets iterated through to find a valid version, so we have
20
+ # the two pre-installed versions listed first.
21
+ SUPPORTED_VERSIONS_TO_ITERATE =
22
+ [
23
+ *PRE_INSTALLED_PYTHON_VERSIONS,
24
+ *SUPPORTED_VERSIONS
25
+ ].freeze
23
26
  end
24
27
  end
25
28
  end
@@ -71,6 +71,7 @@ module Dependabot
71
71
  SharedHelpers.in_a_temporary_directory do
72
72
  SharedHelpers.with_git_configured(credentials: credentials) do
73
73
  write_temporary_dependency_files
74
+ install_required_python
74
75
 
75
76
  # Shell out to Pipenv, which handles everything for us.
76
77
  # Whilst calling `lock` avoids doing an install as part of the
@@ -158,7 +159,7 @@ module Dependabot
158
159
 
159
160
  if error.message.include?("UnsupportedPythonVersion") &&
160
161
  error.message.include?(dependency.name) &&
161
- python_requirement_specified?
162
+ user_specified_python_requirement
162
163
  # The latest version of the dependency we're updating to needs a
163
164
  # different Python version. Skip the update.
164
165
  check_original_requirements_resolvable
@@ -240,13 +241,14 @@ module Dependabot
240
241
 
241
242
  def write_temporary_dependency_files(update_pipfile: true)
242
243
  dependency_files.each do |file|
243
- next if file.name == ".python-version"
244
-
245
244
  path = file.name
246
245
  FileUtils.mkdir_p(Pathname.new(path).dirname)
247
246
  File.write(path, file.content)
248
247
  end
249
248
 
249
+ # Overwrite the .python-version with updated content
250
+ File.write(".python-version", python_version)
251
+
250
252
  setup_files.each do |file|
251
253
  path = file.name
252
254
  FileUtils.mkdir_p(Pathname.new(path).dirname)
@@ -266,6 +268,21 @@ module Dependabot
266
268
  )
267
269
  end
268
270
 
271
+ def install_required_python
272
+ # Initialize a git repo to appease pip-tools
273
+ begin
274
+ run_command("git init") if setup_files.any?
275
+ rescue Dependabot::SharedHelpers::HelperSubprocessFailed
276
+ nil
277
+ end
278
+
279
+ return if run_command("pyenv versions").include?(python_version)
280
+
281
+ requirements_path = NativeHelpers.python_requirements_path
282
+ run_command("pyenv install -s")
283
+ run_command("pyenv exec pip install -r #{requirements_path}")
284
+ end
285
+
269
286
  def sanitized_setup_file_content(file)
270
287
  @sanitized_setup_file_content ||= {}
271
288
  @sanitized_setup_file_content[file.name] ||=
@@ -321,72 +338,57 @@ module Dependabot
321
338
  replace_sources(credentials)
322
339
  end
323
340
 
324
- def add_python_two_requirement_to_pipfile
325
- content = File.read("Pipfile")
326
-
327
- updated_content =
328
- Python::FileUpdater::PipfilePreparer.
329
- new(pipfile_content: content).
330
- update_python_requirement("2.7.15")
331
-
332
- File.write("Pipfile", updated_content)
333
- end
334
-
335
- def pipfile_python_requirement
336
- parsed_pipfile = TomlRB.parse(pipfile.content)
337
-
338
- parsed_pipfile.dig("requires", "python_full_version") ||
339
- parsed_pipfile.dig("requires", "python_version")
340
- end
341
-
342
- def python_requirement_specified?
343
- return true if pipfile_python_requirement
344
-
345
- !python_version_file.nil?
346
- end
347
-
348
- def set_up_python_environment
349
- # Initialize a git repo to appease pip-tools
350
- begin
351
- SharedHelpers.run_shell_command("git init") if setup_files.any?
352
- rescue Dependabot::SharedHelpers::HelperSubprocessFailed
353
- nil
354
- end
355
-
356
- SharedHelpers.run_shell_command(
357
- "pyenv install -s #{python_version}"
358
- )
359
- SharedHelpers.run_shell_command("pyenv local #{python_version}")
360
- return if pre_installed_python?(python_version)
361
-
362
- SharedHelpers.run_shell_command(
363
- "pyenv exec pip install -r " + \
364
- NativeHelpers.python_requirements_path
365
- )
341
+ def python_version
342
+ @python_version ||= python_version_from_supported_versions
366
343
  end
367
344
 
368
- def python_version
369
- requirement =
370
- if @using_python_two
371
- "2.7.*"
372
- elsif pipfile_python_requirement&.match?(/^\d/)
373
- parts = pipfile_python_requirement.split(".")
345
+ def python_version_from_supported_versions
346
+ requirement_string =
347
+ if @using_python_two then "2.7.*"
348
+ elsif user_specified_python_requirement
349
+ parts = user_specified_python_requirement.split(".")
374
350
  parts.fill("*", (parts.length)..2).join(".")
375
- elsif python_version_file
376
- python_version_file.content
377
- else
378
- PythonVersions::PRE_INSTALLED_PYTHON_VERSIONS.first
351
+ else PythonVersions::PRE_INSTALLED_PYTHON_VERSIONS.first
379
352
  end
380
353
 
381
- requirement = Python::Requirement.new(requirement)
354
+ # Ideally, the requirement is satisfied by a Python version we support
355
+ requirement = Python::Requirement.new(requirement_string)
356
+ version =
357
+ PythonVersions::SUPPORTED_VERSIONS_TO_ITERATE.
358
+ find { |v| requirement.satisfied_by?(Python::Version.new(v)) }
359
+ return version if version
382
360
 
383
- PythonVersions::PYTHON_VERSIONS.find do |version|
384
- requirement.satisfied_by?(Python::Version.new(version))
361
+ # If not, and changing the patch version would fix things, we do that
362
+ # as the patch version is unlikely to affect resolution
363
+ requirement =
364
+ Python::Requirement.new(requirement_string.gsub(/\.\d+$/, ".*"))
365
+ version =
366
+ PythonVersions::SUPPORTED_VERSIONS_TO_ITERATE.
367
+ find { |v| requirement.satisfied_by?(Python::Version.new(v)) }
368
+ return version if version
369
+
370
+ # Otherwise we have to raise, giving details of the Python versions
371
+ # that Dependabot supports
372
+ msg = "Dependabot detected the following Python requirement "\
373
+ "for your project: '#{requirement_string}'.\n\nCurrently, the "\
374
+ "following Python versions are supported in Dependabot: "\
375
+ "#{PythonVersions::SUPPORTED_VERSIONS.join(', ')}."
376
+ raise DependencyFileNotResolvable, msg
377
+ end
378
+
379
+ def user_specified_python_requirement
380
+ if pipfile_python_requirement&.match?(/^\d/)
381
+ return pipfile_python_requirement
385
382
  end
383
+
384
+ python_version_file&.content&.strip
386
385
  end
387
386
 
388
- def pre_installed_python?(version)
389
- PythonVersions::PRE_INSTALLED_PYTHON_VERSIONS.include?(version)
387
+ def pipfile_python_requirement
388
+ parsed_pipfile = TomlRB.parse(pipfile.content)
389
+
390
+ parsed_pipfile.dig("requires", "python_full_version") ||
391
+ parsed_pipfile.dig("requires", "python_version")
390
392
  end
391
393
 
392
394
  def check_private_sources_are_reachable
@@ -452,17 +454,13 @@ module Dependabot
452
454
  end
453
455
  end
454
456
 
455
- # rubocop:disable Metrics/MethodLength
456
- def run_pipenv_command(command)
457
- set_up_python_environment
458
-
457
+ def run_command(command)
458
+ command = command.dup
459
459
  start = Time.now
460
460
  stdout, process = Open3.capture2e(command)
461
461
  time_taken = Time.now - start
462
462
 
463
- # Raise an error with the output from the shell session if Pipenv
464
- # returns a non-zero status
465
- return if process.success?
463
+ return stdout if process.success?
466
464
 
467
465
  raise SharedHelpers::HelperSubprocessFailed.new(
468
466
  message: stdout,
@@ -472,6 +470,11 @@ module Dependabot
472
470
  process_exit_value: process.to_s
473
471
  }
474
472
  )
473
+ end
474
+
475
+ def run_pipenv_command(command)
476
+ local_command = "pyenv local #{python_version} && " + command
477
+ run_command(local_command)
475
478
  rescue SharedHelpers::HelperSubprocessFailed => error
476
479
  original_error ||= error
477
480
  msg = error.message
@@ -482,19 +485,20 @@ module Dependabot
482
485
  end
483
486
 
484
487
  raise relevant_error unless may_be_using_wrong_python_version?(msg)
485
- raise relevant_error if @using_python_two
488
+ raise relevant_error if python_version.start_with?("2")
489
+
490
+ # Clear the existing virtualenv, so that we use the new Python version
491
+ run_command("pyenv local #{python_version} && pyenv exec pipenv --rm")
486
492
 
487
- @using_python_two = true
488
- add_python_two_requirement_to_pipfile
489
- command = command.gsub("pipenv ", "pipenv --two ")
493
+ @python_version = "2.7.15"
490
494
  retry
491
495
  ensure
492
- @using_python_two = nil
496
+ @python_version = nil
497
+ FileUtils.remove_entry(".python-version", true)
493
498
  end
494
- # rubocop:enable Metrics/MethodLength
495
499
 
496
500
  def may_be_using_wrong_python_version?(error_message)
497
- return false if python_requirement_specified?
501
+ return false if user_specified_python_requirement
498
502
  return true if error_message.include?("UnsupportedPythonVersion")
499
503
 
500
504
  error_message.include?('Command "python setup.py egg_info" failed')
@@ -152,11 +152,16 @@ module Dependabot
152
152
  requirements =
153
153
  Python::Requirement.requirements_array(requirement)
154
154
 
155
- PythonVersions::PYTHON_VERSIONS.find do |version|
156
- requirements.any? do |req|
157
- req.satisfied_by?(Python::Version.new(version))
158
- end
155
+ version = PythonVersions::SUPPORTED_VERSIONS.find do |v|
156
+ requirements.any? { |r| r.satisfied_by?(Python::Version.new(v)) }
159
157
  end
158
+ return version if version
159
+
160
+ msg = "Dependabot detected the following Python requirement "\
161
+ "for your project: '#{requirement}'.\n\nCurrently, the "\
162
+ "following Python versions are supported in Dependabot: "\
163
+ "#{PythonVersions::SUPPORTED_VERSIONS.join(', ')}."
164
+ raise DependencyFileNotResolvable, msg
160
165
  end
161
166
 
162
167
  def pre_installed_python?(version)
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dependabot-python
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.95.58
4
+ version: 0.95.59
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-22 00:00:00.000000000 Z
11
+ date: 2019-02-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: dependabot-common
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - '='
18
18
  - !ruby/object:Gem::Version
19
- version: 0.95.58
19
+ version: 0.95.59
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - '='
25
25
  - !ruby/object:Gem::Version
26
- version: 0.95.58
26
+ version: 0.95.59
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: byebug
29
29
  requirement: !ruby/object:Gem::Requirement