dependabot-uv 0.390.0 → 0.392.0

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: 8321e87aabcd72cae64306b506846ed940e8b1209ccacd81b01053f8e8fa60eb
4
- data.tar.gz: 3c4321de425ebb554694d0fc3636383978a79f9b8c8a4fdda0d29f6d174ca672
3
+ metadata.gz: b1c6b85902cc78b5c3624f68a39a32e05a4d5206081bac206d54e8afa732489f
4
+ data.tar.gz: 401140b860009a2650a5b96fde815fc50f3813ad60104516d5d50c8f9635799c
5
5
  SHA512:
6
- metadata.gz: e42ae4dad39bee817e1036b3b0eb43d390acb1be78882b4fc691ff13f7508ad0587c83b1ccda1579db016bc3095221bce548c9ac8b377bcd41dde4670d058753
7
- data.tar.gz: 3f2d360fd9efb8afd3d23a3d41977763e04e5e193e210f04be6d0f863358a36b4dc824d03b41f1cfa32d86c55b328808fa9f20307b907e2dc65d8f73f779a61c
6
+ metadata.gz: 399a2740238ae91547e49246a5fd309bfe228d2efbf05f9d8c9699201960158e92e115dd625b940a7a49a7664f683777957a371d9e5326af74823d883947a6f2
7
+ data.tar.gz: 7a2307ab70008dcbb760977f20c226e3b659df68cc4adf867f237e8196db5fc7462f18a10ef5cfe5ba008d04641cc009e40b8def58596c70b1bc5346e0bae253
@@ -7,7 +7,7 @@ plette==2.2.1
7
7
  poetry==2.3.4
8
8
  # TODO: Replace 3p package `tomli` with 3.11's new stdlib `tomllib` once we drop support for Python 3.10.
9
9
  tomli==2.4.1
10
- uv==0.11.8
10
+ uv==0.12.1
11
11
 
12
12
  # Some dependencies will only install if Cython is present
13
13
  Cython==3.2.4
@@ -12,8 +12,8 @@ require "toml-rb"
12
12
  module Dependabot
13
13
  module Uv
14
14
  class DependencyGrapher < Dependabot::DependencyGraphers::Base
15
- RUNTIME_GROUP = T.let("dependencies", String)
16
- DEV_GROUP = T.let("dev-dependencies", String)
15
+ RUNTIME_GROUP = "dependencies"
16
+ DEV_GROUP = "dev-dependencies"
17
17
 
18
18
  sig { override.returns(Dependabot::DependencyFile) }
19
19
  def relevant_dependency_file
@@ -12,7 +12,7 @@ module Dependabot
12
12
  class WorkspaceFetcher
13
13
  extend T::Sig
14
14
 
15
- README_FILENAMES = T.let(%w(README.md README.rst README.txt README).freeze, T::Array[String])
15
+ README_FILENAMES = %w(README.md README.rst README.txt README).freeze
16
16
 
17
17
  sig do
18
18
  params(
@@ -16,7 +16,7 @@ module Dependabot
16
16
  class FileFetcher < Dependabot::Python::SharedFileFetcher
17
17
  extend T::Sig
18
18
 
19
- ECOSYSTEM_SPECIFIC_FILES = T.let(%w(uv.lock).freeze, T::Array[String])
19
+ ECOSYSTEM_SPECIFIC_FILES = %w(uv.lock).freeze
20
20
 
21
21
  REQUIREMENT_FILE_PATTERNS = T.let(
22
22
  {
@@ -27,7 +27,7 @@ module Dependabot
27
27
  )
28
28
 
29
29
  # Projects that use README files for metadata may use any of these common names
30
- README_FILENAMES = T.let(%w(README.md README.rst README.txt README).freeze, T::Array[String])
30
+ README_FILENAMES = %w(README.md README.rst README.txt README).freeze
31
31
 
32
32
  # Type alias for path dependency hashes
33
33
  PathDependency = T.type_alias { T::Hash[Symbol, String] }
@@ -92,7 +92,7 @@ module Dependabot
92
92
  end.reject(&:empty?)
93
93
 
94
94
  file_version = content_lines.first
95
- return if file_version&.empty?
95
+ return if file_version && file_version.empty?
96
96
  return unless T.must(pyenv_versions).include?("#{file_version}\n")
97
97
 
98
98
  file_version
@@ -104,7 +104,7 @@ module Dependabot
104
104
 
105
105
  file_version = T.must(T.must(runtime_file).content)
106
106
  .match(/(?<=python-).*/)&.to_s&.strip
107
- return if file_version&.empty?
107
+ return if file_version && file_version.empty?
108
108
  return unless T.must(pyenv_versions).include?("#{file_version}\n")
109
109
 
110
110
  file_version
@@ -26,19 +26,14 @@ module Dependabot
26
26
  require_relative "requirement_file_updater"
27
27
  require_relative "lock_file_error_handler"
28
28
 
29
- UNSAFE_PACKAGES = T.let(%w(setuptools distribute pip).freeze, T::Array[String])
30
- INCOMPATIBLE_VERSIONS_REGEX = T.let(
31
- /There are incompatible versions in the resolved dependencies:.*\z/m,
32
- Regexp
33
- )
34
- WARNINGS = T.let(/\s*# WARNING:.*\Z/m, Regexp)
35
- UNSAFE_NOTE = T.let(/\s*# The following packages are considered to be unsafe.*\Z/m, Regexp)
36
- RESOLVER_REGEX = T.let(/(?<=--resolver=)(\w+)/, Regexp)
37
- NATIVE_COMPILATION_ERROR = T.let(
38
- "pip._internal.exceptions.InstallationSubprocessError: Getting requirements to build wheel exited with 1",
39
- String
40
- )
41
- PYTHON_VERSION_REGEX = T.let(/--python-version[=\s]+(?<version>\d+\.\d+(?:\.\d+)?)/, Regexp)
29
+ UNSAFE_PACKAGES = %w(setuptools distribute pip).freeze
30
+ INCOMPATIBLE_VERSIONS_REGEX = /There are incompatible versions in the resolved dependencies:.*\z/m
31
+ WARNINGS = /\s*# WARNING:.*\Z/m
32
+ UNSAFE_NOTE = /\s*# The following packages are considered to be unsafe.*\Z/m
33
+ RESOLVER_REGEX = /(?<=--resolver=)(\w+)/
34
+ NATIVE_COMPILATION_ERROR =
35
+ "pip._internal.exceptions.InstallationSubprocessError: Getting requirements to build wheel exited with 1"
36
+ PYTHON_VERSION_REGEX = /--python-version[=\s]+(?<version>\d+\.\d+(?:\.\d+)?)/
42
37
 
43
38
  sig { returns(T::Array[Dependabot::Dependency]) }
44
39
  attr_reader :dependencies
@@ -58,10 +53,10 @@ module Dependabot
58
53
  ).void
59
54
  end
60
55
  def initialize(dependencies:, dependency_files:, credentials:, index_urls: nil)
61
- @dependencies = T.let(dependencies, T::Array[Dependabot::Dependency])
62
- @dependency_files = T.let(dependency_files, T::Array[Dependabot::DependencyFile])
63
- @credentials = T.let(credentials, T::Array[Dependabot::Credential])
64
- @index_urls = T.let(index_urls, T.nilable(T::Array[T.nilable(String)]))
56
+ @dependencies = dependencies
57
+ @dependency_files = dependency_files
58
+ @credentials = credentials
59
+ @index_urls = index_urls
65
60
  @build_isolation = T.let(true, T::Boolean)
66
61
  end
67
62
 
@@ -183,9 +178,9 @@ module Dependabot
183
178
  def update_uncompiled_files(updated_files)
184
179
  updated_filenames = updated_files.map(&:name)
185
180
  all_old_reqs = T.must(dependency).previous_requirements
186
- old_reqs = T.must(all_old_reqs).reject { |r| updated_filenames.include?(r[:file]) }
181
+ old_reqs = T.must(all_old_reqs).reject { |r| updated_filenames.include?(r.file) }
187
182
  all_new_reqs = T.must(dependency).requirements
188
- new_reqs = all_new_reqs.reject { |r| updated_filenames.include?(r[:file]) }
183
+ new_reqs = all_new_reqs.reject { |r| updated_filenames.include?(r.file) }
189
184
 
190
185
  return [] if new_reqs.none?
191
186
 
@@ -288,15 +283,15 @@ module Dependabot
288
283
  return file.content unless file.name.end_with?(".in")
289
284
 
290
285
  old_req = T.must(dependency).previous_requirements
291
- old_req = old_req&.find { |r| r[:file] == file.name }
286
+ old_req = old_req&.find { |r| r.file == file.name }
292
287
 
293
288
  return file.content unless old_req
294
- return file.content if old_req == "==#{T.must(dependency).version}"
289
+ return file.content if old_req.requirement_string == "==#{T.must(dependency).version}"
295
290
 
296
291
  RequirementReplacer.new(
297
292
  content: T.must(file.content),
298
293
  dependency_name: T.must(dependency).name,
299
- old_requirement: old_req[:requirement],
294
+ old_requirement: old_req.requirement_string,
300
295
  new_requirement: "==#{T.must(dependency).version}",
301
296
  index_urls: @index_urls
302
297
  ).updated_content
@@ -307,17 +302,17 @@ module Dependabot
307
302
  return file.content unless file.name.end_with?(".in")
308
303
 
309
304
  old_req = T.must(dependency).previous_requirements
310
- old_req = old_req&.find { |r| r[:file] == file.name }
305
+ old_req = old_req&.find { |r| r.file == file.name }
311
306
  new_req = T.must(dependency).requirements
312
- new_req = new_req.find { |r| r[:file] == file.name }
313
- return file.content unless old_req&.fetch(:requirement)
307
+ new_req = new_req.find { |r| r.file == file.name }
308
+ return file.content unless old_req&.requirement_string
314
309
  return file.content if old_req == new_req
315
310
 
316
311
  RequirementReplacer.new(
317
312
  content: T.must(file.content),
318
313
  dependency_name: T.must(dependency).name,
319
- old_requirement: old_req[:requirement],
320
- new_requirement: T.must(new_req)[:requirement],
314
+ old_requirement: old_req.requirement_string,
315
+ new_requirement: T.must(T.must(new_req).requirement_string),
321
316
  index_urls: @index_urls
322
317
  ).updated_content
323
318
  end
@@ -552,7 +547,7 @@ module Dependabot
552
547
  def filenames_to_compile
553
548
  files_from_reqs =
554
549
  T.must(dependency).requirements
555
- .map { |r| r[:file] }
550
+ .filter_map(&:file)
556
551
  .select { |fn| fn.end_with?(".in") }
557
552
 
558
553
  files_from_compiled_files =
@@ -11,35 +11,17 @@ module Dependabot
11
11
  class LockFileErrorHandler
12
12
  extend T::Sig
13
13
 
14
- UV_UNRESOLVABLE_REGEX = T.let(/× No solution found when resolving dependencies.*[\s\S]*$/, Regexp)
15
- UV_BUILD_FAILED_REGEX = T.let(/× Failed to build.*[\s\S]*$/, Regexp)
16
- RESOLUTION_IMPOSSIBLE_ERROR = T.let("ResolutionImpossible", String)
17
-
18
- GIT_DEPENDENCY_UNREACHABLE_REGEX = T.let(%r{git clone.*(?<url>https?://[^\s]+)}, Regexp)
19
- GIT_REFERENCE_NOT_FOUND_REGEX = T.let(
20
- /Did not find branch or tag '(?<tag>[^\n"']+)'/m,
21
- Regexp
22
- )
23
- GIT_CREDENTIALS_ERROR_REGEX = T.let(
24
- /could not read Username for '(?<url>[^']+)'/,
25
- Regexp
26
- )
27
- GIT_DEPENDENCY_URL_FROM_UV_REGEX = T.let(
28
- %r{git\+(?<url>https?://[^\s@#]+)},
29
- Regexp
30
- )
31
- PYTHON_VERSION_ERROR_REGEX = T.let(
32
- /Requires-Python|requires-python|python_requires|Python version/i,
33
- Regexp
34
- )
35
- AUTH_ERROR_REGEX = T.let(
36
- /authentication|unauthorized|forbidden|HTTP status code: 40[13]/i,
37
- Regexp
38
- )
39
- TIMEOUT_ERROR_REGEX = T.let(
40
- /timed?\s*out|connection.*reset|read timeout|connect timeout/i,
41
- Regexp
42
- )
14
+ UV_UNRESOLVABLE_REGEX = /× No solution found when resolving dependencies.*[\s\S]*$/
15
+ UV_BUILD_FAILED_REGEX = /× Failed to build.*[\s\S]*$/
16
+ RESOLUTION_IMPOSSIBLE_ERROR = "ResolutionImpossible"
17
+
18
+ GIT_DEPENDENCY_UNREACHABLE_REGEX = %r{git clone.*(?<url>https?://[^\s]+)}
19
+ GIT_REFERENCE_NOT_FOUND_REGEX = /Did not find branch or tag '(?<tag>[^\n"']+)'/m
20
+ GIT_CREDENTIALS_ERROR_REGEX = /could not read Username for '(?<url>[^']+)'/
21
+ GIT_DEPENDENCY_URL_FROM_UV_REGEX = %r{git\+(?<url>https?://[^\s@#]+)}
22
+ PYTHON_VERSION_ERROR_REGEX = /Requires-Python|requires-python|python_requires|Python version/i
23
+ AUTH_ERROR_REGEX = /authentication|unauthorized|forbidden|HTTP status code: 40[13]/i
24
+ TIMEOUT_ERROR_REGEX = /timed?\s*out|connection.*reset|read timeout|connect timeout/i
43
25
  NETWORK_ERROR_REGEX = T.let(
44
26
  Regexp.union(
45
27
  /ConnectionError/i,
@@ -52,39 +34,17 @@ module Dependabot
52
34
  ),
53
35
  Regexp
54
36
  )
55
- PACKAGE_NOT_FOUND_REGEX = T.let(
56
- /No matching distribution found|package.*not found|No versions found/i,
57
- Regexp
58
- )
59
- UV_REQUIRED_VERSION_REGEX = T.let(
60
- /Required uv version `(?<required>[^`]+)` does not match the running version `(?<running>[^`]+)`/,
61
- Regexp
62
- )
63
- TOML_PARSE_ERROR_REGEX = T.let(
64
- /Failed to parse:?\s*`?(?<file>[^`\n]+\.toml)`?|TOML parse error/i,
65
- Regexp
66
- )
37
+ PACKAGE_NOT_FOUND_REGEX = /No matching distribution found|package.*not found|No versions found/i
38
+ UV_REQUIRED_VERSION_REGEX =
39
+ /Required uv version `(?<required>[^`]+)` does not match the running version `(?<running>[^`]+)`/
40
+ TOML_PARSE_ERROR_REGEX = /Failed to parse:?\s*`?(?<file>[^`\n]+\.toml)`?|TOML parse error/i
67
41
  # uv prefixes errors with interpreter info that should be stripped
68
- USING_CPYTHON_LINE_REGEX = T.let(
69
- /\AUsing CPython \S+ interpreter at: [^\n]+\n?/,
70
- Regexp
71
- )
72
- PYPROJECT_SCHEMA_ERROR_REGEX = T.let(
73
- /missing field `project`|missing.*\[project\].*table|Field `project\.name` is required/i,
74
- Regexp
75
- )
76
- WORKSPACE_MEMBER_ERROR_REGEX = T.let(
77
- /Failed to find workspace member|No `pyproject\.toml` found in workspace member/i,
78
- Regexp
79
- )
80
- PATH_DEPENDENCY_ERROR_REGEX = T.let(
81
- /Failed to read `(?<path>[^`]+)`|failed to read from file `(?<path>[^`]+)`/i,
82
- Regexp
83
- )
84
- HTTP_STATUS_ERROR_REGEX = T.let(
85
- /HTTP status code: (?<code>\d{3})/i,
86
- Regexp
87
- )
42
+ USING_CPYTHON_LINE_REGEX = /\AUsing CPython \S+ interpreter at: [^\n]+\n?/
43
+ PYPROJECT_SCHEMA_ERROR_REGEX =
44
+ /missing field `project`|missing.*\[project\].*table|Field `project\.name` is required/i
45
+ WORKSPACE_MEMBER_ERROR_REGEX = /Failed to find workspace member|No `pyproject\.toml` found in workspace member/i
46
+ PATH_DEPENDENCY_ERROR_REGEX = /Failed to read `(?<path>[^`]+)`|failed to read from file `(?<path>[^`]+)`/i
47
+ HTTP_STATUS_ERROR_REGEX = /HTTP status code: (?<code>\d{3})/i
88
48
  UV_MISCONFIGURED_REGEX = T.let(
89
49
  Regexp.union(
90
50
  /unknown field `[^`]+`, expected one of/i,
@@ -100,7 +60,7 @@ module Dependabot
100
60
  # This limit ensures error messages remain readable while providing enough
101
61
  # context for debugging. Most uv error messages convey the key information
102
62
  # within the first few lines.
103
- MAX_ERROR_LINES = T.let(10, Integer)
63
+ MAX_ERROR_LINES = 10
104
64
 
105
65
  sig { params(error: SharedHelpers::HelperSubprocessFailed).returns(T.noreturn) }
106
66
  def handle_uv_error(error)
@@ -3,6 +3,7 @@
3
3
 
4
4
  require "toml-rb"
5
5
  require "open3"
6
+ require "uri"
6
7
  require "dependabot/dependency"
7
8
  require "dependabot/shared_helpers"
8
9
  require "dependabot/uv/language_version_manager"
@@ -83,7 +84,7 @@ module Dependabot
83
84
  def build_system_only_dependency?
84
85
  return false unless dependency
85
86
 
86
- groups = T.must(dependency).requirements.flat_map { |req| req[:groups] || [] }.compact.uniq
87
+ groups = T.must(dependency).requirements.flat_map { |req| req.groups || [] }.compact.uniq
87
88
  return false if groups.empty?
88
89
 
89
90
  groups.all?("build-system")
@@ -132,7 +133,7 @@ module Dependabot
132
133
  updated_content = content.dup
133
134
 
134
135
  T.must(dependency).requirements.zip(T.must(T.must(dependency).previous_requirements)).each do |new_r, old_r|
135
- next unless new_r[:file] == file.name && T.must(old_r)[:file] == file.name
136
+ next unless new_r.file == file.name && T.must(old_r).file == file.name
136
137
 
137
138
  updated_content = replace_dep(T.must(dependency), updated_content, new_r, T.must(old_r))
138
139
  end
@@ -146,13 +147,13 @@ module Dependabot
146
147
  params(
147
148
  dep: Dependabot::Dependency,
148
149
  content: String,
149
- new_r: T::Hash[Symbol, T.untyped],
150
- old_r: T::Hash[Symbol, T.untyped]
150
+ new_r: Dependabot::DependencyRequirement,
151
+ old_r: Dependabot::DependencyRequirement
151
152
  ).returns(String)
152
153
  end
153
154
  def replace_dep(dep, content, new_r, old_r)
154
- new_req = new_r[:requirement]
155
- old_req = old_r[:requirement]
155
+ new_req = new_r.requirement_string
156
+ old_req = old_r.requirement_string
156
157
  escaped_name = escape_package_name(dep.name)
157
158
 
158
159
  regex = /(["']#{escaped_name})([^"']+)(["'])/x
@@ -399,9 +400,12 @@ module Dependabot
399
400
  .reject { |cred| skip_lock_index_credential?(cred) }
400
401
  end
401
402
 
403
+ # Skip credentials whose index is already declared in pyproject.toml; those are
404
+ # authenticated via UV_INDEX_<NAME>_* env vars (see #pyproject_index_env_vars) so uv
405
+ # uses the pyproject.toml index entry directly, avoiding a duplicate --index flag.
402
406
  sig { params(credential: Dependabot::Credential).returns(T::Boolean) }
403
407
  def skip_lock_index_credential?(credential)
404
- credential.replaces_base? ? defined_in_pyproject?(credential) : explicit_index?(credential)
408
+ defined_in_pyproject?(credential)
405
409
  end
406
410
 
407
411
  sig do
@@ -504,16 +508,6 @@ module Dependabot
504
508
  []
505
509
  end
506
510
 
507
- sig { params(credential: Dependabot::Credential).returns(T::Boolean) }
508
- def explicit_index?(credential)
509
- return false if credential.replaces_base?
510
-
511
- cred_url = normalize_index_url(credential["index-url"].to_s)
512
- uv_indices.any? do |_name, config|
513
- config["explicit"] == true && normalize_index_url(config["url"].to_s) == cred_url
514
- end
515
- end
516
-
517
511
  # Checks if a credential's index URL matches any index defined in pyproject.toml.
518
512
  # When true, authentication is provided via env vars so uv uses the pyproject.toml URL,
519
513
  # preserving URL format alignment between pyproject.toml and uv.lock.
@@ -522,8 +516,15 @@ module Dependabot
522
516
  !find_index_name_for_credential(credential).nil?
523
517
  end
524
518
 
519
+ # Strips trailing slashes and any embedded userinfo so a pyproject.toml URL like
520
+ # https://oauth2accesstoken@host/path matches a credential URL like https://host/path.
525
521
  sig { params(url: String).returns(String) }
526
522
  def normalize_index_url(url)
523
+ uri = URI.parse(url.chomp("/"))
524
+ uri.user = nil
525
+ uri.password = nil
526
+ uri.to_s
527
+ rescue URI::InvalidURIError
527
528
  url.chomp("/")
528
529
  end
529
530
 
@@ -545,8 +546,7 @@ module Dependabot
545
546
  next unless name
546
547
 
547
548
  result[name] = {
548
- "url" => index["url"],
549
- "explicit" => index["explicit"] == true
549
+ "url" => index["url"]
550
550
  }
551
551
  end
552
552
  rescue TomlRB::ParseError
@@ -634,7 +634,7 @@ module Dependabot
634
634
  return false unless file
635
635
 
636
636
  dependencies.any? do |dep|
637
- dep.requirements.any? { |r| r[:file] == file.name } &&
637
+ dep.requirements.any? { |r| r.file == file.name } &&
638
638
  requirement_changed?(file, dep)
639
639
  end
640
640
  end
@@ -647,7 +647,7 @@ module Dependabot
647
647
  changed_requirements =
648
648
  dependency.requirements - T.must(dependency.previous_requirements)
649
649
 
650
- changed_requirements.any? { |f| f[:file] == T.must(file).name }
650
+ changed_requirements.any? { |f| f.file == T.must(file).name }
651
651
  end
652
652
 
653
653
  sig { params(file: Dependabot::DependencyFile, content: String).returns(Dependabot::DependencyFile) }
@@ -719,7 +719,7 @@ module Dependabot
719
719
  def create_or_update_lock_file?
720
720
  return true if lockfile && T.must(dependency).requirements.empty?
721
721
 
722
- T.must(dependency).requirements.select { _1[:file].end_with?(*REQUIRED_FILES) }.any?
722
+ T.must(dependency).requirements.any? { |req| req.file&.end_with?(*REQUIRED_FILES) }
723
723
  end
724
724
 
725
725
  sig { returns(T::Hash[String, String]) }
@@ -8,13 +8,10 @@ module Dependabot
8
8
  module RequirementSuffixHelper
9
9
  extend T::Sig
10
10
 
11
- REQUIREMENT_SUFFIX_REGEX = T.let(
12
- Regexp.new(
13
- "\\A(?<requirement>.*?)(?<suffix>\\s*(?:;|#).*)?\\z",
14
- Regexp::MULTILINE
15
- ).freeze,
16
- Regexp
17
- )
11
+ REQUIREMENT_SUFFIX_REGEX = Regexp.new(
12
+ "\\A(?<requirement>.*?)(?<suffix>\\s*(?:;|#).*)?\\z",
13
+ Regexp::MULTILINE
14
+ ).freeze
18
15
 
19
16
  sig { params(segment: String).returns(T::Array[String]) }
20
17
  def self.split(segment)
@@ -28,26 +28,18 @@ module Dependabot
28
28
  class PipCompileVersionResolver
29
29
  extend T::Sig
30
30
 
31
- GIT_DEPENDENCY_UNREACHABLE_REGEX = T.let(/git clone --filter=blob:none --quiet (?<url>[^\s]+).* /, Regexp)
32
- GIT_REFERENCE_NOT_FOUND_REGEX = T.let(/Did not find branch or tag '(?<tag>[^\n"]+)'/m, Regexp)
33
- GIT_CREDENTIALS_ERROR_REGEX = T.let(
34
- /could not read Username for '(?<url>[^']+)'/,
35
- Regexp
36
- )
37
- GIT_DEPENDENCY_URL_FROM_UV_REGEX = T.let(
38
- %r{git\+(?<url>https?://[^\s@#]+)},
39
- Regexp
40
- )
41
- NATIVE_COMPILATION_ERROR = T.let(
42
- "pip._internal.exceptions.InstallationSubprocessError: Getting requirements to build wheel exited with 1",
43
- String
44
- )
31
+ GIT_DEPENDENCY_UNREACHABLE_REGEX = /git clone --filter=blob:none --quiet (?<url>[^\s]+).* /
32
+ GIT_REFERENCE_NOT_FOUND_REGEX = /Did not find branch or tag '(?<tag>[^\n"]+)'/m
33
+ GIT_CREDENTIALS_ERROR_REGEX = /could not read Username for '(?<url>[^']+)'/
34
+ GIT_DEPENDENCY_URL_FROM_UV_REGEX = %r{git\+(?<url>https?://[^\s@#]+)}
35
+ NATIVE_COMPILATION_ERROR =
36
+ "pip._internal.exceptions.InstallationSubprocessError: Getting requirements to build wheel exited with 1"
45
37
  # See https://packaging.python.org/en/latest/tutorials/packaging-projects/#configuring-metadata
46
- PYTHON_PACKAGE_NAME_REGEX = T.let(/[A-Za-z0-9_\-]+/, Regexp)
47
- RESOLUTION_IMPOSSIBLE_ERROR = T.let("ResolutionImpossible", String)
48
- ERROR_REGEX = T.let(/(?<=ERROR\:\W).*$/, Regexp)
49
- UV_UNRESOLVABLE_REGEX = T.let(/ × No solution found when resolving dependencies:[\s\S]*$/, Regexp)
50
- PYTHON_VERSION_REGEX = T.let(/--python-version[=\s]+(?<version>\d+\.\d+(?:\.\d+)?)/, Regexp)
38
+ PYTHON_PACKAGE_NAME_REGEX = /[A-Za-z0-9_\-]+/
39
+ RESOLUTION_IMPOSSIBLE_ERROR = "ResolutionImpossible"
40
+ ERROR_REGEX = /(?<=ERROR\:\W).*$/
41
+ UV_UNRESOLVABLE_REGEX = / × No solution found when resolving dependencies:[\s\S]*$/
42
+ PYTHON_VERSION_REGEX = /--python-version[=\s]+(?<version>\d+\.\d+(?:\.\d+)?)/
51
43
 
52
44
  sig { returns(Dependabot::Dependency) }
53
45
  attr_reader :dependency
@@ -73,10 +65,10 @@ module Dependabot
73
65
  ).void
74
66
  end
75
67
  def initialize(dependency:, dependency_files:, credentials:, repo_contents_path:)
76
- @dependency = T.let(dependency, Dependabot::Dependency)
77
- @dependency_files = T.let(dependency_files, T::Array[Dependabot::DependencyFile])
78
- @credentials = T.let(credentials, T::Array[Dependabot::Credential])
79
- @repo_contents_path = T.let(repo_contents_path, T.nilable(String))
68
+ @dependency = dependency
69
+ @dependency_files = dependency_files
70
+ @credentials = credentials
71
+ @repo_contents_path = repo_contents_path
80
72
  @build_isolation = T.let(true, T::Boolean)
81
73
  @error_handler = T.let(PipCompileErrorHandler.new, PipCompileErrorHandler)
82
74
  end
@@ -417,14 +409,14 @@ module Dependabot
417
409
  def update_req_file(file, updated_req)
418
410
  return T.must(file.content) unless file.name.end_with?(".in")
419
411
 
420
- req = dependency.requirements.find { |r| r[:file] == file.name }
412
+ req = dependency.requirements.find { |r| r.file == file.name }
421
413
 
422
- return T.must(file.content) + "\n#{dependency.name} #{updated_req}" unless req&.fetch(:requirement)
414
+ return T.must(file.content) + "\n#{dependency.name} #{updated_req}" unless req&.requirement_string
423
415
 
424
416
  Uv::FileUpdater::RequirementReplacer.new(
425
417
  content: T.must(file.content),
426
418
  dependency_name: dependency.name,
427
- old_requirement: req[:requirement],
419
+ old_requirement: req.requirement_string,
428
420
  new_requirement: updated_req
429
421
  ).updated_content
430
422
  end
@@ -462,7 +454,7 @@ module Dependabot
462
454
  def filenames_to_compile
463
455
  files_from_reqs =
464
456
  dependency.requirements
465
- .map { |r| r[:file] }
457
+ .filter_map(&:file)
466
458
  .select { |fn| fn.end_with?(".in") }
467
459
 
468
460
  files_from_compiled_files =
@@ -609,13 +601,13 @@ module Dependabot
609
601
  class PipCompileErrorHandler
610
602
  extend T::Sig
611
603
 
612
- SUBPROCESS_ERROR = T.let(/subprocess-exited-with-error/, Regexp)
604
+ SUBPROCESS_ERROR = /subprocess-exited-with-error/
613
605
 
614
- INSTALLATION_ERROR = T.let(/InstallationError/, Regexp)
606
+ INSTALLATION_ERROR = /InstallationError/
615
607
 
616
- INSTALLATION_SUBPROCESS_ERROR = T.let(/InstallationSubprocessError/, Regexp)
608
+ INSTALLATION_SUBPROCESS_ERROR = /InstallationSubprocessError/
617
609
 
618
- HASH_MISMATCH = T.let(/HashMismatch/, Regexp)
610
+ HASH_MISMATCH = /HashMismatch/
619
611
 
620
612
  sig { params(error: String).void }
621
613
  def handle_pipcompile_error(error)
@@ -98,10 +98,9 @@ module Dependabot
98
98
  raise "Claimed to be a sub-dependency, but no lockfile exists!"
99
99
  end
100
100
 
101
- sig { override.params(reqs: T::Array[T::Hash[Symbol, T.untyped]]).returns(T::Boolean) }
101
+ sig { override.params(reqs: T::Array[Dependabot::DependencyRequirement]).returns(T::Boolean) }
102
102
  def exact_requirement?(reqs)
103
- reqs = reqs.map { |r| r.fetch(:requirement) }
104
- reqs = reqs.compact
103
+ reqs = reqs.filter_map(&:requirement_string)
105
104
  reqs = reqs.flat_map { |r| r.split(",").map(&:strip) }
106
105
  reqs.any? { |r| Uv::Requirement.new(r).exact? }
107
106
  end
@@ -157,12 +156,13 @@ module Dependabot
157
156
  return if reqs.none?
158
157
 
159
158
  requirement = reqs.find do |r|
160
- file = r[:file]
159
+ file = r.file
160
+ next false unless file
161
161
 
162
162
  file == "uv.lock" || file.end_with?("pyproject.toml") || file.end_with?(".in") || file.end_with?(".txt")
163
163
  end
164
164
 
165
- requirement&.fetch(:requirement)
165
+ requirement&.requirement_string
166
166
  end
167
167
 
168
168
  sig { override.returns(String) }
@@ -187,7 +187,7 @@ module Dependabot
187
187
  return ">=#{dependency.version}" if dependency.version
188
188
 
189
189
  version_for_requirement =
190
- requirements.filter_map { |r| r[:requirement] }
190
+ requirements.filter_map(&:requirement_string)
191
191
  .reject { |req_string| req_string.start_with?("<") }
192
192
  .select { |req_string| req_string.match?(VERSION_REGEX) }
193
193
  .map { |req_string| req_string.match(VERSION_REGEX).to_s }
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dependabot-uv
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.390.0
4
+ version: 0.392.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dependabot
@@ -15,28 +15,28 @@ dependencies:
15
15
  requirements:
16
16
  - - '='
17
17
  - !ruby/object:Gem::Version
18
- version: 0.390.0
18
+ version: 0.392.0
19
19
  type: :runtime
20
20
  prerelease: false
21
21
  version_requirements: !ruby/object:Gem::Requirement
22
22
  requirements:
23
23
  - - '='
24
24
  - !ruby/object:Gem::Version
25
- version: 0.390.0
25
+ version: 0.392.0
26
26
  - !ruby/object:Gem::Dependency
27
27
  name: dependabot-python
28
28
  requirement: !ruby/object:Gem::Requirement
29
29
  requirements:
30
30
  - - '='
31
31
  - !ruby/object:Gem::Version
32
- version: 0.390.0
32
+ version: 0.392.0
33
33
  type: :runtime
34
34
  prerelease: false
35
35
  version_requirements: !ruby/object:Gem::Requirement
36
36
  requirements:
37
37
  - - '='
38
38
  - !ruby/object:Gem::Version
39
- version: 0.390.0
39
+ version: 0.392.0
40
40
  - !ruby/object:Gem::Dependency
41
41
  name: debug
42
42
  requirement: !ruby/object:Gem::Requirement
@@ -301,7 +301,7 @@ licenses:
301
301
  - MIT
302
302
  metadata:
303
303
  bug_tracker_uri: https://github.com/dependabot/dependabot-core/issues
304
- changelog_uri: https://github.com/dependabot/dependabot-core/releases/tag/v0.390.0
304
+ changelog_uri: https://github.com/dependabot/dependabot-core/releases/tag/v0.392.0
305
305
  rdoc_options: []
306
306
  require_paths:
307
307
  - lib