dependabot-python 0.104.5 → 0.104.6

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