dependabot-python 0.95.58 → 0.95.59

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: 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