dependabot-python 0.98.7 → 0.98.8

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