dependabot-python 0.98.7 → 0.98.8

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: 6d309884fb08b759885ec446fcd51a1527a21cdc43a6aa1d1a647adfd67be5d4
4
- data.tar.gz: c4a011bad8bece6a1caf78952af0c667962319056dfa8f082b3b95d5c39a6992
3
+ metadata.gz: fb408ef9461ee63b60df855f633f8b27eebfb464f630e4c22366aa57d2e15f29
4
+ data.tar.gz: ce8f327163ab06b16a13592a8b9abaaf5e25377a78483a070da4665dcaba3444
5
5
  SHA512:
6
- metadata.gz: 5b03d21b2f4f6f7d9b943878477a9db2c9f4ff7972e50ef599689fb04150a358320213a2ec0598ad7e1f13eafab445d512b134d09a00c7d80cdfbd35c12aa1d2
7
- data.tar.gz: eb9ef187a794d4c437f3a970c3da0172e44e32ab438326bb3f6eed32ba8352561e21ce903d4c8ff22116989e7e552819b7c190cde3f14846aa3514b74a48deb4
6
+ metadata.gz: 9536b0e57c8146a6581f4b26f1faf610603a400479b00abdae7eef2cea69578da22eaf9643cc11b4a9859f39e3587febc6cdb72f9a943d4aaad07e61b9ade391
7
+ data.tar.gz: c1f692639f551b64b2546a1da106e4ed8f1c87a0cccce728f95675c393f97eea299728636baf01002eabdf60167ff830755b02053c987a0a5cd116dd4f86033e
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "toml-rb"
4
-
4
+ require "shellwords"
5
5
  require "dependabot/dependency"
6
6
  require "dependabot/file_parsers"
7
7
  require "dependabot/file_parsers/base"
@@ -125,8 +125,10 @@ module Dependabot
125
125
  SharedHelpers.in_a_temporary_directory do
126
126
  write_temporary_dependency_files
127
127
 
128
+ command_parts = ["pyenv", "exec", "python",
129
+ NativeHelpers.python_helper_path]
128
130
  requirements = SharedHelpers.run_helper_subprocess(
129
- command: "pyenv exec python #{NativeHelpers.python_helper_path}",
131
+ command: Shellwords.join(command_parts),
130
132
  function: "parse_requirements",
131
133
  args: [Dir.pwd]
132
134
  )
@@ -1,5 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "shellwords"
3
4
  require "dependabot/dependency"
4
5
  require "dependabot/errors"
5
6
  require "dependabot/file_parsers/base/dependency_set"
@@ -57,8 +58,10 @@ module Dependabot
57
58
  SharedHelpers.in_a_temporary_directory do
58
59
  write_temporary_dependency_files
59
60
 
61
+ command_parts = ["pyenv", "exec", "python",
62
+ NativeHelpers.python_helper_path]
60
63
  requirements = SharedHelpers.run_helper_subprocess(
61
- command: "pyenv exec python #{NativeHelpers.python_helper_path}",
64
+ command: Shellwords.join(command_parts),
62
65
  function: "parse_setup",
63
66
  args: [Dir.pwd]
64
67
  )
@@ -78,8 +81,10 @@ module Dependabot
78
81
  SharedHelpers.in_a_temporary_directory do
79
82
  write_sanitized_setup_file
80
83
 
84
+ command_parts = ["pyenv", "exec", "python",
85
+ NativeHelpers.python_helper_path]
81
86
  requirements = SharedHelpers.run_helper_subprocess(
82
- command: "pyenv exec python #{NativeHelpers.python_helper_path}",
87
+ command: Shellwords.join(command_parts),
83
88
  function: "parse_setup",
84
89
  args: [Dir.pwd]
85
90
  )
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "open3"
4
+ require "shellwords"
4
5
  require "dependabot/python/requirement_parser"
5
6
  require "dependabot/python/file_fetcher"
6
7
  require "dependabot/python/file_updater"
@@ -55,6 +56,8 @@ module Dependabot
55
56
  ]
56
57
  end
57
58
 
59
+ # rubocop:disable Metrics/AbcSize
60
+ # rubocop:disable Metrics/MethodLength
58
61
  def compile_new_requirement_files
59
62
  SharedHelpers.in_a_temporary_directory do
60
63
  write_updated_dependency_files
@@ -63,15 +66,20 @@ module Dependabot
63
66
  filenames_to_compile.each do |filename|
64
67
  # Shell out to pip-compile, generate a new set of requirements.
65
68
  # This is slow, as pip-compile needs to do installs.
66
- run_pip_compile_command(
67
- "pyenv exec pip-compile #{pip_compile_options(filename)} "\
68
- "-P #{dependency.name}==#{dependency.version} #{filename}"
69
- )
69
+ cmd_dep_name = Shellwords.join([
70
+ "pyenv", "exec", "pip-compile",
71
+ pip_compile_options(filename),
72
+ "-P", dependency.name
73
+ ].reject(&:empty?))
74
+ cmd_dep_version = Shellwords.join([dependency.version, filename])
75
+ # Don't escape pyenv `dep-name==version` syntax
76
+ run_pip_compile_command(["#{cmd_dep_name}==#{cmd_dep_version}"],
77
+ escape: false)
70
78
  # Run pip-compile a second time, without an update argument, to
71
79
  # ensure it resets the right comments.
72
80
  run_pip_compile_command(
73
- "pyenv exec pip-compile #{pip_compile_options(filename)} "\
74
- "#{filename}"
81
+ ["pyenv", "exec", "pip-compile", pip_compile_options(filename),
82
+ filename].reject(&:empty?)
75
83
  )
76
84
  end
77
85
 
@@ -91,6 +99,8 @@ module Dependabot
91
99
  end.compact
92
100
  end
93
101
  end
102
+ # rubocop:enable Metrics/MethodLength
103
+ # rubocop:enable Metrics/AbcSize
94
104
 
95
105
  def update_manifest_files
96
106
  dependency_files.map do |file|
@@ -129,11 +139,10 @@ module Dependabot
129
139
  ).updated_dependency_files
130
140
  end
131
141
 
132
- def run_command(command)
133
- command = command.dup
134
- env_cmd = [python_env, command].compact
142
+ def run_command(cmd_parts, env: python_env, escape: true)
135
143
  start = Time.now
136
- stdout, process = Open3.capture2e(*env_cmd)
144
+ command = escape ? Shellwords.join(cmd_parts) : cmd_parts.join(" ")
145
+ stdout, process = Open3.capture2e(env, command)
137
146
  time_taken = Time.now - start
138
147
 
139
148
  return stdout if process.success?
@@ -148,9 +157,9 @@ module Dependabot
148
157
  )
149
158
  end
150
159
 
151
- def run_pip_compile_command(command)
152
- local_command = "pyenv local #{python_version} && " + command
153
- run_command(local_command)
160
+ def run_pip_compile_command(command_parts, escape: true)
161
+ run_command(["pyenv", "local", python_version])
162
+ run_command(command_parts, escape: escape)
154
163
  rescue SharedHelpers::HelperSubprocessFailed => error
155
164
  original_error ||= error
156
165
  msg = error.message
@@ -216,13 +225,13 @@ module Dependabot
216
225
  end
217
226
 
218
227
  def install_required_python
219
- if run_command("pyenv versions").include?("#{python_version}\n")
228
+ if run_command(%w(pyenv versions)).include?("#{python_version}\n")
220
229
  return
221
230
  end
222
231
 
223
- run_command("pyenv install -s #{python_version}")
224
- run_command("pyenv exec pip install -r " + \
225
- NativeHelpers.python_requirements_path)
232
+ run_command(["pyenv", "install", "-s", python_version])
233
+ run_command(["pyenv", "exec", "pip", "install", "-r",
234
+ NativeHelpers.python_requirements_path])
226
235
  end
227
236
 
228
237
  def sanitized_setup_file_content(file)
@@ -366,8 +375,10 @@ module Dependabot
366
375
  end
367
376
 
368
377
  def package_hashes_for(name:, version:, algorithm:)
378
+ command_parts = ["pyenv", "exec", "python",
379
+ NativeHelpers.python_helper_path]
369
380
  SharedHelpers.run_helper_subprocess(
370
- command: "pyenv exec python #{NativeHelpers.python_helper_path}",
381
+ command: Shellwords.join(command_parts),
371
382
  function: "get_dependency_hash",
372
383
  args: [name, version, algorithm]
373
384
  ).map { |h| "--hash=#{algorithm}:#{h['hash']}" }
@@ -512,7 +523,7 @@ module Dependabot
512
523
  end
513
524
 
514
525
  def pyenv_versions
515
- @pyenv_versions ||= run_command("pyenv install --list")
526
+ @pyenv_versions ||= run_command(["pyenv", "install", "--list"])
516
527
  end
517
528
 
518
529
  def pre_installed_python?(version)
@@ -2,6 +2,7 @@
2
2
 
3
3
  require "toml-rb"
4
4
  require "open3"
5
+ require "shellwords"
5
6
  require "dependabot/python/requirement_parser"
6
7
  require "dependabot/python/file_updater"
7
8
  require "dependabot/shared_helpers"
@@ -190,10 +191,11 @@ module Dependabot
190
191
  install_required_python
191
192
 
192
193
  # Initialize a git repo to appease pip-tools
193
- IO.popen("git init", err: %i(child out)) if setup_files.any?
194
+ command = Shellwords.join(%w(git init))
195
+ IO.popen(command, err: %i(child out)) if setup_files.any?
194
196
 
195
197
  run_pipenv_command(
196
- pipenv_environment_variables + "pyenv exec pipenv lock"
198
+ %w(pyenv exec pipenv lock)
197
199
  )
198
200
 
199
201
  result = { lockfile: File.read("Pipfile.lock") }
@@ -229,19 +231,21 @@ module Dependabot
229
231
  end
230
232
 
231
233
  def generate_updated_requirements_files
232
- run_pipenv_command(
233
- pipenv_environment_variables +
234
- "pyenv exec pipenv lock -r > req.txt"
234
+ req_content = run_pipenv_command(
235
+ ["pyenv", "exec", "pipenv", "lock", "-r"]
235
236
  )
236
- run_pipenv_command(
237
- pipenv_environment_variables +
238
- "pyenv exec pipenv lock -r -d > dev-req.txt"
237
+ File.write("req.txt", req_content)
238
+
239
+ dev_req_content = run_pipenv_command(
240
+ ["pyenv", "exec", "pipenv", "lock", "-r", "-d"]
239
241
  )
242
+ File.write("dev-req.txt", dev_req_content)
240
243
  end
241
244
 
242
- def run_command(command)
245
+ def run_command(command_parts, env: {})
243
246
  start = Time.now
244
- stdout, process = Open3.capture2e(command)
247
+ command = Shellwords.join(command_parts)
248
+ stdout, process = Open3.capture2e(env, command)
245
249
  time_taken = Time.now - start
246
250
 
247
251
  # Raise an error with the output from the shell session if Pipenv
@@ -258,9 +262,9 @@ module Dependabot
258
262
  )
259
263
  end
260
264
 
261
- def run_pipenv_command(command)
262
- local_command = "pyenv local #{python_version} && " + command
263
- run_command(local_command)
265
+ def run_pipenv_command(command_parts, env: pipenv_env_variables)
266
+ run_command(["pyenv", "local", python_version])
267
+ run_command(command_parts, env: env)
264
268
  rescue SharedHelpers::HelperSubprocessFailed => error
265
269
  original_error ||= error
266
270
  msg = error.message
@@ -274,7 +278,8 @@ module Dependabot
274
278
  raise relevant_error if python_version.start_with?("2")
275
279
 
276
280
  # Clear the existing virtualenv, so that we use the new Python version
277
- run_command("pyenv local #{python_version} && pyenv exec pipenv --rm")
281
+ run_command(["pyenv", "local", python_version])
282
+ run_command(["pyenv", "exec", "pipenv", "--rm"])
278
283
 
279
284
  @python_version = "2.7.15"
280
285
  retry
@@ -318,18 +323,19 @@ module Dependabot
318
323
  def install_required_python
319
324
  # Initialize a git repo to appease pip-tools
320
325
  begin
321
- run_command("git init") if setup_files.any?
326
+ run_command(%w(git init)) if setup_files.any?
322
327
  rescue Dependabot::SharedHelpers::HelperSubprocessFailed
323
328
  nil
324
329
  end
325
330
 
326
- if run_command("pyenv versions").include?("#{python_version}\n")
331
+ if run_command(%w(pyenv versions)).include?("#{python_version}\n")
327
332
  return
328
333
  end
329
334
 
330
335
  requirements_path = NativeHelpers.python_requirements_path
331
- run_command("pyenv install -s #{python_version}")
332
- run_command("pyenv exec pip install -r #{requirements_path}")
336
+ run_command(["pyenv", "install", "-s", python_version])
337
+ run_command(["pyenv", "exec", "pip", "install", "-r",
338
+ requirements_path])
333
339
  end
334
340
 
335
341
  def sanitized_setup_file_content(file)
@@ -400,7 +406,7 @@ module Dependabot
400
406
  end
401
407
 
402
408
  def pyenv_versions
403
- @pyenv_versions ||= run_command("pyenv install --list")
409
+ @pyenv_versions ||= run_command(["pyenv", "install", "--list"])
404
410
  end
405
411
 
406
412
  def pipfile_python_requirement
@@ -419,8 +425,10 @@ module Dependabot
419
425
  def pipfile_hash_for(pipfile_content)
420
426
  SharedHelpers.in_a_temporary_directory do |dir|
421
427
  File.write(File.join(dir, "Pipfile"), pipfile_content)
428
+ command_parts = ["pyenv", "exec", "python",
429
+ NativeHelpers.python_helper_path]
422
430
  SharedHelpers.run_helper_subprocess(
423
- command: "pyenv exec python #{NativeHelpers.python_helper_path}",
431
+ command: Shellwords.join(command_parts),
424
432
  function: "get_pipfile_hash",
425
433
  args: [dir]
426
434
  )
@@ -482,16 +490,14 @@ module Dependabot
482
490
  dependency_files.find { |f| f.name == ".python-version" }
483
491
  end
484
492
 
485
- def pipenv_environment_variables
486
- environment_variables = [
487
- "PIPENV_YES=true", # Install new Python versions if needed
488
- "PIPENV_MAX_RETRIES=3", # Retry timeouts
489
- "PIPENV_NOSPIN=1", # Don't pollute logs with spinner
490
- "PIPENV_TIMEOUT=600", # Set install timeout to 10 minutes
491
- "PIP_DEFAULT_TIMEOUT=60" # Set pip timeout to 1 minute
492
- ]
493
-
494
- environment_variables.join(" ") + " "
493
+ def pipenv_env_variables
494
+ {
495
+ "PIPENV_YES" => "true", # Install new Python ver if needed
496
+ "PIPENV_MAX_RETRIES" => "3", # Retry timeouts
497
+ "PIPENV_NOSPIN" => "1", # Don't pollute logs with spinner
498
+ "PIPENV_TIMEOUT" => "600", # Set install timeout to 10 minutes
499
+ "PIP_DEFAULT_TIMEOUT" => "60" # Set pip timeout to 1 minute
500
+ }
495
501
  end
496
502
  end
497
503
  end
@@ -2,6 +2,7 @@
2
2
 
3
3
  require "toml-rb"
4
4
  require "open3"
5
+ require "shellwords"
5
6
  require "dependabot/shared_helpers"
6
7
  require "dependabot/python/version"
7
8
  require "dependabot/python/requirement"
@@ -153,14 +154,15 @@ module Dependabot
153
154
  write_temporary_dependency_files(pyproject_content)
154
155
 
155
156
  if python_version && !pre_installed_python?(python_version)
156
- run_poetry_command("pyenv install -s #{python_version}")
157
- run_poetry_command("pyenv exec pip install --upgrade pip")
158
- run_poetry_command("pyenv exec pip install -r " + \
159
- NativeHelpers.python_requirements_path)
157
+ run_poetry_command(["pyenv", "install", "-s", python_version])
158
+ run_poetry_command(["pyenv", "exec", "pip", "install",
159
+ "--upgrade", "pip"])
160
+ run_poetry_command(["pyenv", "exec", "pip", "install", "-r",
161
+ NativeHelpers.python_requirements_path])
160
162
  end
161
163
 
162
164
  run_poetry_command(
163
- "pyenv exec poetry update #{dependency.name} --lock"
165
+ ["pyenv", "exec", "poetry", "update", dependency.name, "--lock"]
164
166
  )
165
167
 
166
168
  return File.read("poetry.lock") if File.exist?("poetry.lock")
@@ -169,8 +171,9 @@ module Dependabot
169
171
  end
170
172
  end
171
173
 
172
- def run_poetry_command(command)
174
+ def run_poetry_command(command_parts)
173
175
  start = Time.now
176
+ command = Shellwords.join(command_parts)
174
177
  stdout, process = Open3.capture2e(command)
175
178
  time_taken = Time.now - start
176
179
 
@@ -231,7 +234,7 @@ module Dependabot
231
234
  end
232
235
 
233
236
  def pyenv_versions
234
- @pyenv_versions ||= run_poetry_command("pyenv install --list")
237
+ @pyenv_versions ||= run_poetry_command(["pyenv", "install", "--list"])
235
238
  end
236
239
 
237
240
  def pre_installed_python?(version)
@@ -241,8 +244,10 @@ module Dependabot
241
244
  def pyproject_hash_for(pyproject_content)
242
245
  SharedHelpers.in_a_temporary_directory do |dir|
243
246
  File.write(File.join(dir, "pyproject.toml"), pyproject_content)
247
+ command_parts = ["pyenv", "exec", "python",
248
+ NativeHelpers.python_helper_path]
244
249
  SharedHelpers.run_helper_subprocess(
245
- command: "pyenv exec python #{NativeHelpers.python_helper_path}",
250
+ command: Shellwords.join(command_parts),
246
251
  function: "get_pyproject_hash",
247
252
  args: [dir]
248
253
  )
@@ -1,5 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "shellwords"
3
4
  require "dependabot/python/requirement_parser"
4
5
  require "dependabot/python/file_updater"
5
6
  require "dependabot/shared_helpers"
@@ -139,8 +140,10 @@ module Dependabot
139
140
  end
140
141
 
141
142
  def package_hashes_for(name:, version:, algorithm:)
143
+ command_parts = ["pyenv", "exec", "python",
144
+ NativeHelpers.python_helper_path]
142
145
  SharedHelpers.run_helper_subprocess(
143
- command: "pyenv exec python #{NativeHelpers.python_helper_path}",
146
+ command: Shellwords.join(command_parts),
144
147
  function: "get_dependency_hash",
145
148
  args: [name, version, algorithm]
146
149
  ).map { |h| "--hash=#{algorithm}:#{h['hash']}" }
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "open3"
4
+ require "shellwords"
4
5
  require "dependabot/python/requirement_parser"
5
6
  require "dependabot/python/file_fetcher"
6
7
  require "dependabot/python/file_parser"
@@ -11,14 +12,13 @@ require "dependabot/python/version"
11
12
  require "dependabot/shared_helpers"
12
13
  require "dependabot/python/native_helpers"
13
14
  require "dependabot/python/python_versions"
14
-
15
- # rubocop:disable Metrics/ClassLength
16
15
  module Dependabot
17
16
  module Python
18
17
  class UpdateChecker
19
18
  # This class does version resolution for pip-compile. Its approach is:
20
19
  # - Unlock the dependency we're checking in the requirements.in file
21
20
  # - Run `pip-compile` and see what the result is
21
+ # rubocop:disable Metrics/ClassLength
22
22
  class PipCompileVersionResolver
23
23
  VERSION_REGEX = /[0-9]+(?:\.[A-Za-z0-9\-_]+)*/.freeze
24
24
 
@@ -59,13 +59,13 @@ module Dependabot
59
59
  # Shell out to pip-compile.
60
60
  # This is slow, as pip-compile needs to do installs.
61
61
  run_pip_compile_command(
62
- "pyenv exec pip-compile --allow-unsafe "\
63
- "-P #{dependency.name} #{filename}"
62
+ ["pyenv", "exec", "pip-compile", "--allow-unsafe",
63
+ "-P", dependency.name, filename]
64
64
  )
65
65
  # Run pip-compile a second time, without an update argument,
66
66
  # to ensure it handles markers correctly
67
67
  run_pip_compile_command(
68
- "pyenv exec pip-compile --allow-unsafe #{filename}"
68
+ ["pyenv", "exec", "pip-compile", "--allow-unsafe", filename]
69
69
  )
70
70
  end
71
71
 
@@ -118,8 +118,8 @@ module Dependabot
118
118
  write_temporary_dependency_files(unlock_requirement: false)
119
119
 
120
120
  filenames_to_compile.each do |filename|
121
- cmd = "pyenv exec pip-compile --allow-unsafe #{filename}"
122
- run_command(cmd)
121
+ run_command(["pyenv", "exec", "pip-compile", "--allow-unsafe",
122
+ filename])
123
123
  end
124
124
 
125
125
  true
@@ -134,11 +134,10 @@ module Dependabot
134
134
  end
135
135
  end
136
136
 
137
- def run_command(command)
138
- command = command.dup
139
- env_cmd = [python_env, command].compact
137
+ def run_command(command_parts, env: python_env)
140
138
  start = Time.now
141
- stdout, process = Open3.capture2e(*env_cmd)
139
+ command = Shellwords.join(command_parts)
140
+ stdout, process = Open3.capture2e(env, command)
142
141
  time_taken = Time.now - start
143
142
 
144
143
  return stdout if process.success?
@@ -153,9 +152,9 @@ module Dependabot
153
152
  )
154
153
  end
155
154
 
156
- def run_pip_compile_command(command)
157
- local_command = "pyenv local #{python_version} && " + command
158
- run_command(local_command)
155
+ def run_pip_compile_command(command_parts)
156
+ run_command(["pyenv", "local", python_version])
157
+ run_command(command_parts)
159
158
  rescue SharedHelpers::HelperSubprocessFailed => error
160
159
  original_error ||= error
161
160
  msg = error.message
@@ -225,13 +224,13 @@ module Dependabot
225
224
  end
226
225
 
227
226
  def install_required_python
228
- if run_command("pyenv versions").include?("#{python_version}\n")
227
+ if run_command(%w(pyenv versions)).include?("#{python_version}\n")
229
228
  return
230
229
  end
231
230
 
232
- run_command("pyenv install -s #{python_version}")
233
- run_command("pyenv exec pip install -r " + \
234
- NativeHelpers.python_requirements_path)
231
+ run_command(["pyenv", "install", "-s", python_version])
232
+ run_command(["pyenv", "exec", "pip", "install", "-r",
233
+ NativeHelpers.python_requirements_path])
235
234
  end
236
235
 
237
236
  def sanitized_setup_file_content(file)
@@ -411,7 +410,7 @@ module Dependabot
411
410
  end
412
411
 
413
412
  def pyenv_versions
414
- @pyenv_versions ||= run_command("pyenv install --list")
413
+ @pyenv_versions ||= run_command(["pyenv", "install", "--list"])
415
414
  end
416
415
 
417
416
  def pre_installed_python?(version)
@@ -434,7 +433,7 @@ module Dependabot
434
433
  dependency_files.find { |f| f.name == ".python-version" }
435
434
  end
436
435
  end
436
+ # rubocop:enable Metrics/ClassLength
437
437
  end
438
438
  end
439
439
  end
440
- # rubocop:enable Metrics/ClassLength
@@ -3,6 +3,7 @@
3
3
  require "excon"
4
4
  require "toml-rb"
5
5
  require "open3"
6
+ require "shellwords"
6
7
  require "dependabot/errors"
7
8
  require "dependabot/shared_helpers"
8
9
  require "dependabot/python/file_parser"
@@ -78,7 +79,7 @@ module Dependabot
78
79
  # pipenv flow, an install is still done by pip-tools in order
79
80
  # to resolve the dependencies. That means this is slow.
80
81
  run_pipenv_command(
81
- pipenv_environment_variables + "pyenv exec pipenv lock"
82
+ %w(pyenv exec pipenv lock)
82
83
  )
83
84
 
84
85
  updated_lockfile = JSON.parse(File.read("Pipfile.lock"))
@@ -195,7 +196,7 @@ module Dependabot
195
196
  write_temporary_dependency_files(update_pipfile: false)
196
197
 
197
198
  run_pipenv_command(
198
- pipenv_environment_variables + "pyenv exec pipenv lock"
199
+ %w(pyenv exec pipenv lock)
199
200
  )
200
201
 
201
202
  true
@@ -287,18 +288,19 @@ module Dependabot
287
288
  def install_required_python
288
289
  # Initialize a git repo to appease pip-tools
289
290
  begin
290
- run_command("git init") if setup_files.any?
291
+ run_command(%w(git init)) if setup_files.any?
291
292
  rescue Dependabot::SharedHelpers::HelperSubprocessFailed
292
293
  nil
293
294
  end
294
295
 
295
- if run_command("pyenv versions").include?("#{python_version}\n")
296
+ if run_command(%w(pyenv versions)).include?("#{python_version}\n")
296
297
  return
297
298
  end
298
299
 
299
300
  requirements_path = NativeHelpers.python_requirements_path
300
- run_command("pyenv install -s #{python_version}")
301
- run_command("pyenv exec pip install -r #{requirements_path}")
301
+ run_command(["pyenv", "install", "-s", python_version])
302
+ run_command(["pyenv", "exec", "pip", "install", "-r",
303
+ requirements_path])
302
304
  end
303
305
 
304
306
  def sanitized_setup_file_content(file)
@@ -412,7 +414,7 @@ module Dependabot
412
414
  end
413
415
 
414
416
  def pyenv_versions
415
- @pyenv_versions ||= run_command("pyenv install --list")
417
+ @pyenv_versions ||= run_command(["pyenv", "install", "--list"])
416
418
  end
417
419
 
418
420
  def pipfile_python_requirement
@@ -485,10 +487,10 @@ module Dependabot
485
487
  end
486
488
  end
487
489
 
488
- def run_command(command)
489
- command = command.dup
490
+ def run_command(command_parts, env: {})
490
491
  start = Time.now
491
- stdout, process = Open3.capture2e(command)
492
+ command = Shellwords.join(command_parts)
493
+ stdout, process = Open3.capture2e(env, command)
492
494
  time_taken = Time.now - start
493
495
 
494
496
  return stdout if process.success?
@@ -503,9 +505,9 @@ module Dependabot
503
505
  )
504
506
  end
505
507
 
506
- def run_pipenv_command(command)
507
- local_command = "pyenv local #{python_version} && " + command
508
- run_command(local_command)
508
+ def run_pipenv_command(command_parts, env: pipenv_env_variables)
509
+ run_command(["pyenv", "local", python_version])
510
+ run_command(command_parts, env: env)
509
511
  rescue SharedHelpers::HelperSubprocessFailed => error
510
512
  original_error ||= error
511
513
  msg = error.message
@@ -519,7 +521,8 @@ module Dependabot
519
521
  raise relevant_error if python_version.start_with?("2")
520
522
 
521
523
  # Clear the existing virtualenv, so that we use the new Python version
522
- run_command("pyenv local #{python_version} && pyenv exec pipenv --rm")
524
+ run_command(["pyenv", "local", python_version])
525
+ run_command(["pyenv", "exec", "pipenv", "--rm"])
523
526
 
524
527
  @python_version = "2.7.15"
525
528
  retry
@@ -566,16 +569,14 @@ module Dependabot
566
569
  map { |h| h.dup.merge("url" => h["url"].gsub(%r{/*$}, "") + "/") }
567
570
  end
568
571
 
569
- def pipenv_environment_variables
570
- environment_variables = [
571
- "PIPENV_YES=true", # Install new Python versions if needed
572
- "PIPENV_MAX_RETRIES=3", # Retry timeouts
573
- "PIPENV_NOSPIN=1", # Don't pollute logs with spinner
574
- "PIPENV_TIMEOUT=600", # Set install timeout to 10 minutes
575
- "PIP_DEFAULT_TIMEOUT=60" # Set pip timeout to 1 minute
576
- ]
577
-
578
- environment_variables.join(" ") + " "
572
+ def pipenv_env_variables
573
+ {
574
+ "PIPENV_YES" => "true", # Install new Python ver if needed
575
+ "PIPENV_MAX_RETRIES" => "3", # Retry timeouts
576
+ "PIPENV_NOSPIN" => "1", # Don't pollute logs with spinner
577
+ "PIPENV_TIMEOUT" => "600", # Set install timeout to 10 minutes
578
+ "PIP_DEFAULT_TIMEOUT" => "60" # Set pip timeout to 1 minute
579
+ }
579
580
  end
580
581
 
581
582
  # See https://www.python.org/dev/peps/pep-0503/#normalized-names
@@ -3,6 +3,7 @@
3
3
  require "excon"
4
4
  require "toml-rb"
5
5
  require "open3"
6
+ require "shellwords"
6
7
  require "dependabot/errors"
7
8
  require "dependabot/shared_helpers"
8
9
  require "dependabot/python/file_parser"
@@ -55,15 +56,15 @@ module Dependabot
55
56
  write_temporary_dependency_files
56
57
 
57
58
  if python_version && !pre_installed_python?(python_version)
58
- run_poetry_command("pyenv install -s #{python_version}")
59
- run_poetry_command("pyenv exec pip install -r " + \
60
- NativeHelpers.python_requirements_path)
59
+ run_poetry_command(["pyenv", "install", "-s", python_version])
60
+ run_poetry_command(["pyenv", "exec", "pip", "install", "-r",
61
+ NativeHelpers.python_requirements_path])
61
62
  end
62
63
 
63
64
  # Shell out to Poetry, which handles everything for us.
64
65
  # Using `--lock` avoids doing an install.
65
66
  run_poetry_command(
66
- "pyenv exec poetry update #{dependency.name} --lock"
67
+ ["pyenv", "exec", "poetry", "update", dependency.name, "--lock"]
67
68
  )
68
69
 
69
70
  updated_lockfile =
@@ -105,7 +106,7 @@ module Dependabot
105
106
  write_temporary_dependency_files(update_pyproject: false)
106
107
 
107
108
  run_poetry_command(
108
- "pyenv exec poetry update #{dependency.name} --lock"
109
+ ["pyenv", "exec", "poetry", "update", dependency.name, "--lock"]
109
110
  )
110
111
 
111
112
  true
@@ -175,7 +176,7 @@ module Dependabot
175
176
  end
176
177
 
177
178
  def pyenv_versions
178
- @pyenv_versions ||= run_poetry_command("pyenv install --list")
179
+ @pyenv_versions ||= run_poetry_command(["pyenv", "install", "--list"])
179
180
  end
180
181
 
181
182
  def pre_installed_python?(version)
@@ -311,8 +312,9 @@ module Dependabot
311
312
  dependency_files.find { |f| f.name == ".python-version" }
312
313
  end
313
314
 
314
- def run_poetry_command(command)
315
+ def run_poetry_command(command_parts)
315
316
  start = Time.now
317
+ command = Shellwords.join(command_parts)
316
318
  stdout, process = Open3.capture2e(command)
317
319
  time_taken = Time.now - start
318
320
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dependabot-python
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.98.7
4
+ version: 0.98.8
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dependabot
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - '='
18
18
  - !ruby/object:Gem::Version
19
- version: 0.98.7
19
+ version: 0.98.8
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.98.7
26
+ version: 0.98.8
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: byebug
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -100,14 +100,14 @@ dependencies:
100
100
  requirements:
101
101
  - - "~>"
102
102
  - !ruby/object:Gem::Version
103
- version: 0.65.0
103
+ version: 0.66.0
104
104
  type: :development
105
105
  prerelease: false
106
106
  version_requirements: !ruby/object:Gem::Requirement
107
107
  requirements:
108
108
  - - "~>"
109
109
  - !ruby/object:Gem::Version
110
- version: 0.65.0
110
+ version: 0.66.0
111
111
  - !ruby/object:Gem::Dependency
112
112
  name: vcr
113
113
  requirement: !ruby/object:Gem::Requirement