dependabot-python 0.104.5 → 0.104.6

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: 0ecab0b693f416dd04e4cd877f89895b2e3fe5978ce1b8bb090da21982ddd199
4
- data.tar.gz: 43e25134101d6934acc6c46481f4321068b7301586958514e52db0a1ef18ac26
3
+ metadata.gz: 86a22a74e2cfeb8d600f160d2078900565de559537249b34d6e8d31d3475f01f
4
+ data.tar.gz: 7a0b0874123f7decd66511a39b1ebe207c98fd8968e6194b0906ca5ef68e6d8a
5
5
  SHA512:
6
- metadata.gz: f11657970a15938cd1277a1264de43202900be7b992a55e03fed6efc9681c0b0a1616ebe8d9f1f71cfb9864f361929481e09b7a605d99bbeb30e9dc9e58c8555
7
- data.tar.gz: ed0cdd9468b12f6e6ec37f736a319e952791852481562218e1a4ba75671bbf984833d9de61b888a1cd64e9ed01f3ce41d6bd50e0cd730cda43f748c5880a21d4
6
+ metadata.gz: 30592c176e2ce1dadc2b1f4d689861fd57388377827af9d1a189cb9ae37aa790eba4ef9a727e325c6ef696b8364c93703a9116657c26840091e9de95bbfecc9e
7
+ data.tar.gz: cbc364db1c7a3de0b4c7643af272c424946e32b16e90742cc911d9e728eb42f97e850bd5d4c304e66fe27fa3b7fa322c4b2b25724a72134a2bb3377dfb068cb2
@@ -22,6 +22,7 @@ module Dependabot
22
22
  https://pypi.python.org/simple/
23
23
  https://pypi.org/simple/
24
24
  ).freeze
25
+ VERSION_REGEX = /[0-9]+(?:\.[A-Za-z0-9\-_]+)*/.freeze
25
26
 
26
27
  def latest_version
27
28
  @latest_version ||= fetch_latest_version
@@ -31,11 +32,17 @@ module Dependabot
31
32
  @latest_resolvable_version ||=
32
33
  case resolver_type
33
34
  when :pipenv
34
- pipenv_version_resolver.latest_resolvable_version
35
+ pipenv_version_resolver.latest_resolvable_version(
36
+ requirement: unlocked_requirement_string
37
+ )
35
38
  when :poetry
36
- poetry_version_resolver.latest_resolvable_version
39
+ poetry_version_resolver.latest_resolvable_version(
40
+ requirement: unlocked_requirement_string
41
+ )
37
42
  when :pip_compile
38
- pip_compile_version_resolver.latest_resolvable_version
43
+ pip_compile_version_resolver.latest_resolvable_version(
44
+ requirement: unlocked_requirement_string
45
+ )
39
46
  when :requirements
40
47
  # pip doesn't (yet) do any dependency resolution, so if we don't
41
48
  # have a Pipfile or a pip-compile file, we just return the latest
@@ -49,17 +56,17 @@ module Dependabot
49
56
  @latest_resolvable_version_with_no_unlock ||=
50
57
  case resolver_type
51
58
  when :pipenv
52
- pipenv_version_resolver(
53
- unlock_requirement: false
54
- ).latest_resolvable_version
59
+ pipenv_version_resolver.latest_resolvable_version(
60
+ requirement: current_requirement_string
61
+ )
55
62
  when :poetry
56
- poetry_version_resolver(
57
- unlock_requirement: false
58
- ).latest_resolvable_version
63
+ poetry_version_resolver.latest_resolvable_version(
64
+ requirement: current_requirement_string
65
+ )
59
66
  when :pip_compile
60
- pip_compile_version_resolver(
61
- unlock_requirement: false
62
- ).latest_resolvable_version
67
+ pip_compile_version_resolver.latest_resolvable_version(
68
+ requirement: current_requirement_string
69
+ )
63
70
  when :requirements
64
71
  latest_pip_version_with_no_unlock
65
72
  else raise "Unexpected resolver type #{resolver_type}"
@@ -154,36 +161,72 @@ module Dependabot
154
161
  reqs.any? { |r| Python::Requirement.new(r).exact? }
155
162
  end
156
163
 
157
- def pipenv_version_resolver(unlock_requirement: true)
158
- @pipenv_version_resolver ||= {}
159
- @pipenv_version_resolver[unlock_requirement] ||=
160
- PipenvVersionResolver.
161
- new(resolver_args.merge(unlock_requirement: unlock_requirement))
164
+ def pipenv_version_resolver
165
+ @pipenv_version_resolver ||= PipenvVersionResolver.new(resolver_args)
162
166
  end
163
167
 
164
- def pip_compile_version_resolver(unlock_requirement: true)
165
- @pip_compile_version_resolver ||= {}
166
- @pip_compile_version_resolver[unlock_requirement] ||=
167
- PipCompileVersionResolver.
168
- new(resolver_args.merge(unlock_requirement: unlock_requirement))
168
+ def pip_compile_version_resolver
169
+ @pip_compile_version_resolver ||=
170
+ PipCompileVersionResolver.new(resolver_args)
169
171
  end
170
172
 
171
- def poetry_version_resolver(unlock_requirement: true)
172
- @poetry_version_resolver ||= {}
173
- @poetry_version_resolver[unlock_requirement] ||=
174
- PoetryVersionResolver.
175
- new(resolver_args.merge(unlock_requirement: unlock_requirement))
173
+ def poetry_version_resolver
174
+ @poetry_version_resolver ||= PoetryVersionResolver.new(resolver_args)
176
175
  end
177
176
 
178
177
  def resolver_args
179
178
  {
180
179
  dependency: dependency,
181
180
  dependency_files: dependency_files,
182
- credentials: credentials,
183
- latest_allowable_version: latest_version
181
+ credentials: credentials
184
182
  }
185
183
  end
186
184
 
185
+ def current_requirement_string
186
+ reqs = dependency.requirements
187
+ return if reqs.none?
188
+
189
+ requirement =
190
+ case resolver_type
191
+ when :pipenv then reqs.find { |r| r[:file] == "Pipfile" }
192
+ when :poetry then reqs.find { |r| r[:file] == "pyproject.toml" }
193
+ when :pip_compile then reqs.find { |r| r[:file].end_with?(".in") }
194
+ when :requirements then reqs.find { |r| r[:file].end_with?(".txt") }
195
+ end
196
+
197
+ requirement.fetch(:requirement)
198
+ end
199
+
200
+ def unlocked_requirement_string
201
+ lower_bound_req = updated_version_req_lower_bound
202
+
203
+ # Add the latest_version as an upper bound. This means
204
+ # ignore conditions are considered when checking for the latest
205
+ # resolvable version.
206
+ #
207
+ # NOTE: This isn't perfect. If v2.x is ignored and v3 is out but
208
+ # unresolvable then the `latest_version` will be v3, and
209
+ # we won't be ignoring v2.x releases like we should be.
210
+ return lower_bound_req if latest_version.nil?
211
+ return lower_bound_req unless Python::Version.correct?(latest_version)
212
+
213
+ lower_bound_req + ", <= #{latest_version}"
214
+ end
215
+
216
+ def updated_version_req_lower_bound
217
+ return ">= #{dependency.version}" if dependency.version
218
+
219
+ version_for_requirement =
220
+ dependency.requirements.map { |r| r[:requirement] }.compact.
221
+ reject { |req_string| req_string.start_with?("<") }.
222
+ select { |req_string| req_string.match?(VERSION_REGEX) }.
223
+ map { |req_string| req_string.match(VERSION_REGEX) }.
224
+ select { |version| Gem::Version.correct?(version) }.
225
+ max_by { |version| Gem::Version.new(version) }
226
+
227
+ ">= #{version_for_requirement || 0}"
228
+ end
229
+
187
230
  def fetch_latest_version
188
231
  latest_version_finder.latest_version
189
232
  end
@@ -20,39 +20,34 @@ module Dependabot
20
20
  # - Run `pip-compile` and see what the result is
21
21
  # rubocop:disable Metrics/ClassLength
22
22
  class PipCompileVersionResolver
23
- VERSION_REGEX = /[0-9]+(?:\.[A-Za-z0-9\-_]+)*/.freeze
24
-
25
23
  attr_reader :dependency, :dependency_files, :credentials
26
24
 
27
- def initialize(dependency:, dependency_files:, credentials:,
28
- unlock_requirement:, latest_allowable_version:)
25
+ def initialize(dependency:, dependency_files:, credentials:)
29
26
  @dependency = dependency
30
27
  @dependency_files = dependency_files
31
28
  @credentials = credentials
32
- @latest_allowable_version = latest_allowable_version
33
- @unlock_requirement = unlock_requirement
34
29
  end
35
30
 
36
- def latest_resolvable_version
37
- return @latest_resolvable_version if @resolution_already_attempted
31
+ def latest_resolvable_version(requirement: nil)
32
+ version_string =
33
+ fetch_latest_resolvable_version_string(requirement: requirement)
38
34
 
39
- @resolution_already_attempted = true
40
- @latest_resolvable_version ||= fetch_latest_resolvable_version
35
+ version_string.nil? ? nil : Python::Version.new(version_string)
41
36
  end
42
37
 
43
38
  private
44
39
 
45
- attr_reader :latest_allowable_version
46
-
47
- def unlock_requirement?
48
- @unlock_requirement
49
- end
40
+ # rubocop:disable Metrics/MethodLength
41
+ def fetch_latest_resolvable_version_string(requirement:)
42
+ @latest_resolvable_version_string ||= {}
43
+ if @latest_resolvable_version_string.key?(requirement)
44
+ return @latest_resolvable_version_string[requirement]
45
+ end
50
46
 
51
- def fetch_latest_resolvable_version
52
- @latest_resolvable_version_string ||=
47
+ @latest_resolvable_version_string[requirement] ||=
53
48
  SharedHelpers.in_a_temporary_directory do
54
49
  SharedHelpers.with_git_configured(credentials: credentials) do
55
- write_temporary_dependency_files
50
+ write_temporary_dependency_files(updated_req: requirement)
56
51
  install_required_python
57
52
 
58
53
  filenames_to_compile.each do |filename|
@@ -80,10 +75,8 @@ module Dependabot
80
75
  rescue SharedHelpers::HelperSubprocessFailed => e
81
76
  handle_pip_compile_errors(e)
82
77
  end
83
- return unless @latest_resolvable_version_string
84
-
85
- Python::Version.new(@latest_resolvable_version_string)
86
78
  end
79
+ # rubocop:enable Metrics/MethodLength
87
80
 
88
81
  def handle_pip_compile_errors(error)
89
82
  if error.message.include?("Could not find a version")
@@ -159,7 +152,7 @@ module Dependabot
159
152
  def check_original_requirements_resolvable
160
153
  SharedHelpers.in_a_temporary_directory do
161
154
  SharedHelpers.with_git_configured(credentials: credentials) do
162
- write_temporary_dependency_files(unlock_requirement: false)
155
+ write_temporary_dependency_files(update_requirement: false)
163
156
 
164
157
  filenames_to_compile.each do |filename|
165
158
  run_command("pyenv exec pip-compile --allow-unsafe #{filename}")
@@ -243,14 +236,16 @@ module Dependabot
243
236
  message.include?('Command "python setup.py egg_info" failed')
244
237
  end
245
238
 
246
- def write_temporary_dependency_files(unlock_requirement: true)
239
+ def write_temporary_dependency_files(updated_req: nil,
240
+ update_requirement: true)
247
241
  dependency_files.each do |file|
248
242
  path = file.name
249
243
  FileUtils.mkdir_p(Pathname.new(path).dirname)
250
- File.write(
251
- path,
252
- unlock_requirement ? unlock_dependency(file) : file.content
253
- )
244
+ updated_content =
245
+ if update_requirement then update_req_file(file, updated_req)
246
+ else file.content
247
+ end
248
+ File.write(path, updated_content)
254
249
  end
255
250
 
256
251
  # Overwrite the .python-version with updated content
@@ -297,10 +292,8 @@ module Dependabot
297
292
  end
298
293
  end
299
294
 
300
- def unlock_dependency(file)
295
+ def update_req_file(file, updated_req)
301
296
  return file.content unless file.name.end_with?(".in")
302
- return file.content unless dependency.version
303
- return file.content unless unlock_requirement?
304
297
 
305
298
  req = dependency.requirements.find { |r| r[:file] == file.name }
306
299
  return file.content unless req&.fetch(:requirement)
@@ -309,44 +302,10 @@ module Dependabot
309
302
  content: file.content,
310
303
  dependency_name: dependency.name,
311
304
  old_requirement: req[:requirement],
312
- new_requirement: updated_version_requirement_string
305
+ new_requirement: updated_req
313
306
  ).updated_content
314
307
  end
315
308
 
316
- def updated_version_requirement_string
317
- lower_bound_req = updated_version_req_lower_bound
318
-
319
- # Add the latest_allowable_version as an upper bound. This means
320
- # ignore conditions are considered when checking for the latest
321
- # resolvable version.
322
- #
323
- # NOTE: This isn't perfect. If v2.x is ignored and v3 is out but
324
- # unresolvable then the `latest_allowable_version` will be v3, and
325
- # we won't be ignoring v2.x releases like we should be.
326
- return lower_bound_req if latest_allowable_version.nil?
327
- unless Python::Version.correct?(latest_allowable_version)
328
- return lower_bound_req
329
- end
330
-
331
- lower_bound_req + ", <= #{latest_allowable_version}"
332
- end
333
-
334
- def updated_version_req_lower_bound
335
- if dependency.version
336
- ">= #{dependency.version}"
337
- else
338
- version_for_requirement =
339
- dependency.requirements.map { |r| r[:requirement] }.compact.
340
- reject { |req_string| req_string.start_with?("<") }.
341
- select { |req_string| req_string.match?(VERSION_REGEX) }.
342
- map { |req_string| req_string.match(VERSION_REGEX) }.
343
- select { |version| Gem::Version.correct?(version) }.
344
- max_by { |version| Gem::Version.new(version) }
345
-
346
- ">= #{version_for_requirement || 0}"
347
- end
348
- end
349
-
350
309
  # See https://www.python.org/dev/peps/pep-0503/#normalized-names
351
310
  def normalise(name)
352
311
  name.downcase.gsub(/[-_.]+/, "-")
@@ -28,7 +28,6 @@ module Dependabot
28
28
  # just raise if the latest version can't be resolved. Knowing that is
29
29
  # still better than nothing, though.
30
30
  class PipenvVersionResolver
31
- VERSION_REGEX = /[0-9]+(?:\.[A-Za-z0-9\-_]+)*/.freeze
32
31
  GIT_DEPENDENCY_UNREACHABLE_REGEX =
33
32
  /Command "git clone -q (?<url>[^\s]+).*" failed/.freeze
34
33
  GIT_REFERENCE_NOT_FOUND_REGEX =
@@ -41,37 +40,33 @@ module Dependabot
41
40
 
42
41
  attr_reader :dependency, :dependency_files, :credentials
43
42
 
44
- def initialize(dependency:, dependency_files:, credentials:,
45
- unlock_requirement:, latest_allowable_version:)
43
+ def initialize(dependency:, dependency_files:, credentials:)
46
44
  @dependency = dependency
47
45
  @dependency_files = dependency_files
48
46
  @credentials = credentials
49
- @latest_allowable_version = latest_allowable_version
50
- @unlock_requirement = unlock_requirement
51
47
 
52
48
  check_private_sources_are_reachable
53
49
  end
54
50
 
55
- def latest_resolvable_version
56
- return @latest_resolvable_version if @resolution_already_attempted
51
+ def latest_resolvable_version(requirement: nil)
52
+ version_string =
53
+ fetch_latest_resolvable_version_string(requirement: requirement)
57
54
 
58
- @resolution_already_attempted = true
59
- @latest_resolvable_version ||= fetch_latest_resolvable_version
55
+ version_string.nil? ? nil : Python::Version.new(version_string)
60
56
  end
61
57
 
62
58
  private
63
59
 
64
- attr_reader :latest_allowable_version
65
-
66
- def unlock_requirement?
67
- @unlock_requirement
68
- end
60
+ def fetch_latest_resolvable_version_string(requirement:)
61
+ @latest_resolvable_version_string ||= {}
62
+ if @latest_resolvable_version_string.key?(requirement)
63
+ return @latest_resolvable_version_string[requirement]
64
+ end
69
65
 
70
- def fetch_latest_resolvable_version
71
- @latest_resolvable_version_string ||=
66
+ @latest_resolvable_version_string[requirement] ||=
72
67
  SharedHelpers.in_a_temporary_directory do
73
68
  SharedHelpers.with_git_configured(credentials: credentials) do
74
- write_temporary_dependency_files
69
+ write_temporary_dependency_files(updated_req: requirement)
75
70
  install_required_python
76
71
 
77
72
  # Shell out to Pipenv, which handles everything for us.
@@ -87,9 +82,6 @@ module Dependabot
87
82
  rescue SharedHelpers::HelperSubprocessFailed => e
88
83
  handle_pipenv_errors(e)
89
84
  end
90
- return unless @latest_resolvable_version_string
91
-
92
- Python::Version.new(@latest_resolvable_version_string)
93
85
  end
94
86
 
95
87
  def fetch_version_from_parsed_lockfile(updated_lockfile)
@@ -252,7 +244,8 @@ module Dependabot
252
244
  msg.gsub(/http.*?(?=\s)/, "<redacted>")
253
245
  end
254
246
 
255
- def write_temporary_dependency_files(update_pipfile: true)
247
+ def write_temporary_dependency_files(updated_req: nil,
248
+ update_pipfile: true)
256
249
  dependency_files.each do |file|
257
250
  path = file.name
258
251
  FileUtils.mkdir_p(Pathname.new(path).dirname)
@@ -273,11 +266,12 @@ module Dependabot
273
266
  FileUtils.mkdir_p(Pathname.new(path).dirname)
274
267
  File.write(path, "[metadata]\nname = sanitized-package\n")
275
268
  end
269
+ return unless update_pipfile
276
270
 
277
271
  # Overwrite the pipfile with updated content
278
272
  File.write(
279
273
  "Pipfile",
280
- pipfile_content(update_pipfile: update_pipfile)
274
+ pipfile_content(updated_requirement: updated_req)
281
275
  )
282
276
  end
283
277
 
@@ -312,12 +306,10 @@ module Dependabot
312
306
  dependency_files.find { |f| f.name == config_name }
313
307
  end
314
308
 
315
- def pipfile_content(update_pipfile: true)
309
+ def pipfile_content(updated_requirement:)
316
310
  content = pipfile.content
317
- return content unless update_pipfile
318
-
319
311
  content = freeze_other_dependencies(content)
320
- content = unlock_target_dependency(content) if unlock_requirement?
312
+ content = set_target_dependency_req(content, updated_requirement)
321
313
  content = add_private_sources(content)
322
314
  content
323
315
  end
@@ -328,7 +320,9 @@ module Dependabot
328
320
  freeze_top_level_dependencies_except([dependency])
329
321
  end
330
322
 
331
- def unlock_target_dependency(pipfile_content)
323
+ def set_target_dependency_req(pipfile_content, updated_requirement)
324
+ return pipfile_content unless updated_requirement
325
+
332
326
  pipfile_object = TomlRB.parse(pipfile_content)
333
327
 
334
328
  %w(packages dev-packages).each do |type|
@@ -337,11 +331,9 @@ module Dependabot
337
331
  next unless pkg_name
338
332
 
339
333
  if pipfile_object.dig(type, pkg_name).is_a?(Hash)
340
- pipfile_object[type][pkg_name]["version"] =
341
- updated_version_requirement_string
334
+ pipfile_object[type][pkg_name]["version"] = updated_requirement
342
335
  else
343
- pipfile_object[type][pkg_name] =
344
- updated_version_requirement_string
336
+ pipfile_object[type][pkg_name] = updated_requirement
345
337
  end
346
338
  end
347
339
 
@@ -445,40 +437,6 @@ module Dependabot
445
437
  end
446
438
  end
447
439
 
448
- def updated_version_requirement_string
449
- lower_bound_req = updated_version_req_lower_bound
450
-
451
- # Add the latest_allowable_version as an upper bound. This means
452
- # ignore conditions are considered when checking for the latest
453
- # resolvable version.
454
- #
455
- # NOTE: This isn't perfect. If v2.x is ignored and v3 is out but
456
- # unresolvable then the `latest_allowable_version` will be v3, and
457
- # we won't be ignoring v2.x releases like we should be.
458
- return lower_bound_req if latest_allowable_version.nil?
459
- unless Python::Version.correct?(latest_allowable_version)
460
- return lower_bound_req
461
- end
462
-
463
- lower_bound_req + ", <= #{latest_allowable_version}"
464
- end
465
-
466
- def updated_version_req_lower_bound
467
- if dependency.version
468
- ">= #{dependency.version}"
469
- else
470
- version_for_requirement =
471
- dependency.requirements.map { |r| r[:requirement] }.compact.
472
- reject { |req_string| req_string.start_with?("<") }.
473
- select { |req_string| req_string.match?(VERSION_REGEX) }.
474
- map { |req_string| req_string.match(VERSION_REGEX) }.
475
- select { |version| Gem::Version.correct?(version) }.
476
- max_by { |version| Gem::Version.new(version) }
477
-
478
- ">= #{version_for_requirement || 0}"
479
- end
480
- end
481
-
482
440
  def run_command(command, env: {})
483
441
  start = Time.now
484
442
  command = SharedHelpers.escape_command(command)
@@ -14,46 +14,39 @@ require "dependabot/python/native_helpers"
14
14
  require "dependabot/python/python_versions"
15
15
  require "dependabot/python/authed_url_builder"
16
16
 
17
- # rubocop:disable Metrics/ClassLength
18
17
  module Dependabot
19
18
  module Python
20
19
  class UpdateChecker
21
20
  # This class does version resolution for pyproject.toml files.
22
21
  class PoetryVersionResolver
23
- VERSION_REGEX = /[0-9]+(?:\.[A-Za-z0-9\-_]+)*/.freeze
24
-
25
22
  attr_reader :dependency, :dependency_files, :credentials
26
23
 
27
- def initialize(dependency:, dependency_files:, credentials:,
28
- unlock_requirement:, latest_allowable_version:)
24
+ def initialize(dependency:, dependency_files:, credentials:)
29
25
  @dependency = dependency
30
26
  @dependency_files = dependency_files
31
27
  @credentials = credentials
32
- @latest_allowable_version = latest_allowable_version
33
- @unlock_requirement = unlock_requirement
34
28
 
35
29
  check_private_sources_are_reachable
36
30
  end
37
31
 
38
- def latest_resolvable_version
39
- return @latest_resolvable_version if @resolution_already_attempted
32
+ def latest_resolvable_version(requirement: nil)
33
+ version_string =
34
+ fetch_latest_resolvable_version_string(requirement: requirement)
40
35
 
41
- @resolution_already_attempted = true
42
- @latest_resolvable_version ||= fetch_latest_resolvable_version
36
+ version_string.nil? ? nil : Python::Version.new(version_string)
43
37
  end
44
38
 
45
39
  private
46
40
 
47
- attr_reader :latest_allowable_version
48
-
49
- def unlock_requirement?
50
- @unlock_requirement
51
- end
41
+ def fetch_latest_resolvable_version_string(requirement:)
42
+ @latest_resolvable_version_string ||= {}
43
+ if @latest_resolvable_version_string.key?(requirement)
44
+ return @latest_resolvable_version_string[requirement]
45
+ end
52
46
 
53
- def fetch_latest_resolvable_version
54
- latest_resolvable_version_string =
47
+ @latest_resolvable_version_string[requirement] ||=
55
48
  SharedHelpers.in_a_temporary_directory do
56
- write_temporary_dependency_files
49
+ write_temporary_dependency_files(updated_req: requirement)
57
50
 
58
51
  if python_version && !pre_installed_python?(python_version)
59
52
  run_poetry_command("pyenv install -s #{python_version}")
@@ -77,9 +70,6 @@ module Dependabot
77
70
  rescue SharedHelpers::HelperSubprocessFailed => e
78
71
  handle_poetry_errors(e)
79
72
  end
80
- return unless latest_resolvable_version_string
81
-
82
- Python::Version.new(latest_resolvable_version_string)
83
73
  end
84
74
 
85
75
  def fetch_version_from_parsed_lockfile(updated_lockfile)
@@ -131,7 +121,8 @@ module Dependabot
131
121
  message.gsub(/http.*?(?=\s)/, "<redacted>")
132
122
  end
133
123
 
134
- def write_temporary_dependency_files(update_pyproject: true)
124
+ def write_temporary_dependency_files(updated_req: nil,
125
+ update_pyproject: true)
135
126
  dependency_files.each do |file|
136
127
  path = file.name
137
128
  FileUtils.mkdir_p(Pathname.new(path).dirname)
@@ -143,7 +134,10 @@ module Dependabot
143
134
 
144
135
  # Overwrite the pyproject with updated content
145
136
  if update_pyproject
146
- File.write("pyproject.toml", updated_pyproject_content)
137
+ File.write(
138
+ "pyproject.toml",
139
+ updated_pyproject_content(updated_requirement: updated_req)
140
+ )
147
141
  else
148
142
  File.write("pyproject.toml", sanitized_pyproject_content)
149
143
  end
@@ -191,15 +185,12 @@ module Dependabot
191
185
  PythonVersions::PRE_INSTALLED_PYTHON_VERSIONS.include?(version)
192
186
  end
193
187
 
194
- def updated_pyproject_content
195
- @updated_pyproject_content ||=
196
- begin
197
- content = pyproject.content
198
- content = sanitize_pyproject_content(content)
199
- content = freeze_other_dependencies(content)
200
- content = unlock_target_dependency(content) if unlock_requirement?
201
- content
202
- end
188
+ def updated_pyproject_content(updated_requirement:)
189
+ content = pyproject.content
190
+ content = sanitize_pyproject_content(content)
191
+ content = freeze_other_dependencies(content)
192
+ content = set_target_dependency_req(content, updated_requirement)
193
+ content
203
194
  end
204
195
 
205
196
  def sanitized_pyproject_content
@@ -220,7 +211,9 @@ module Dependabot
220
211
  freeze_top_level_dependencies_except([dependency])
221
212
  end
222
213
 
223
- def unlock_target_dependency(pyproject_content)
214
+ def set_target_dependency_req(pyproject_content, updated_requirement)
215
+ return pyproject_content unless updated_requirement
216
+
224
217
  pyproject_object = TomlRB.parse(pyproject_content)
225
218
  poetry_object = pyproject_object.dig("tool", "poetry")
226
219
 
@@ -230,11 +223,9 @@ module Dependabot
230
223
  next unless pkg_name
231
224
 
232
225
  if poetry_object.dig(type, pkg_name).is_a?(Hash)
233
- poetry_object[type][pkg_name]["version"] =
234
- updated_version_requirement_string
226
+ poetry_object[type][pkg_name]["version"] = updated_requirement
235
227
  else
236
- poetry_object[type][pkg_name] =
237
- updated_version_requirement_string
228
+ poetry_object[type][pkg_name] = updated_requirement
238
229
  end
239
230
  end
240
231
 
@@ -266,40 +257,6 @@ module Dependabot
266
257
  end
267
258
  end
268
259
 
269
- def updated_version_requirement_string
270
- lower_bound_req = updated_version_req_lower_bound
271
-
272
- # Add the latest_allowable_version as an upper bound. This means
273
- # ignore conditions are considered when checking for the latest
274
- # resolvable version.
275
- #
276
- # NOTE: This isn't perfect. If v2.x is ignored and v3 is out but
277
- # unresolvable then the `latest_allowable_version` will be v3, and
278
- # we won't be ignoring v2.x releases like we should be.
279
- return lower_bound_req if latest_allowable_version.nil?
280
- unless Python::Version.correct?(latest_allowable_version)
281
- return lower_bound_req
282
- end
283
-
284
- lower_bound_req + ", <= #{latest_allowable_version}"
285
- end
286
-
287
- def updated_version_req_lower_bound
288
- if dependency.version
289
- ">= #{dependency.version}"
290
- else
291
- version_for_requirement =
292
- dependency.requirements.map { |r| r[:requirement] }.compact.
293
- reject { |req_string| req_string.start_with?("<") }.
294
- select { |req_string| req_string.match?(VERSION_REGEX) }.
295
- map { |req_string| req_string.match(VERSION_REGEX) }.
296
- select { |version| Gem::Version.correct?(version) }.
297
- max_by { |version| Gem::Version.new(version) }
298
-
299
- ">= #{version_for_requirement || 0}"
300
- end
301
- end
302
-
303
260
  def pyproject
304
261
  dependency_files.find { |f| f.name == "pyproject.toml" }
305
262
  end
@@ -372,4 +329,3 @@ module Dependabot
372
329
  end
373
330
  end
374
331
  end
375
- # rubocop:enable Metrics/ClassLength
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.104.5
4
+ version: 0.104.6
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.104.5
19
+ version: 0.104.6
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.104.5
26
+ version: 0.104.6
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: byebug
29
29
  requirement: !ruby/object:Gem::Requirement