dependabot-uv 0.349.0 → 0.351.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 +4 -4
- data/helpers/requirements.txt +1 -1
- data/lib/dependabot/uv/authed_url_builder.rb +3 -27
- data/lib/dependabot/uv/file_updater/lock_file_updater.rb +38 -27
- data/lib/dependabot/uv/language.rb +6 -76
- data/lib/dependabot/uv/language_version_manager.rb +6 -131
- data/lib/dependabot/uv/metadata_finder.rb +6 -210
- data/lib/dependabot/uv/name_normaliser.rb +3 -17
- data/lib/dependabot/uv/native_helpers.rb +4 -30
- data/lib/dependabot/uv/package.rb +27 -0
- data/lib/dependabot/uv/requirement.rb +4 -196
- data/lib/dependabot/uv/requirement_parser.rb +5 -53
- data/lib/dependabot/uv/update_checker/latest_version_finder.rb +10 -16
- data/lib/dependabot/uv/version.rb +4 -321
- metadata +19 -8
- data/lib/dependabot/uv/file_parser/setup_file_parser.rb +0 -194
- data/lib/dependabot/uv/package/package_details_fetcher.rb +0 -486
- data/lib/dependabot/uv/package/package_registry_finder.rb +0 -288
- data/lib/dependabot/uv/pipenv_runner.rb +0 -110
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.
|
|
4
|
+
version: 0.351.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Dependabot
|
|
@@ -15,14 +15,28 @@ dependencies:
|
|
|
15
15
|
requirements:
|
|
16
16
|
- - '='
|
|
17
17
|
- !ruby/object:Gem::Version
|
|
18
|
-
version: 0.
|
|
18
|
+
version: 0.351.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.
|
|
25
|
+
version: 0.351.0
|
|
26
|
+
- !ruby/object:Gem::Dependency
|
|
27
|
+
name: dependabot-python
|
|
28
|
+
requirement: !ruby/object:Gem::Requirement
|
|
29
|
+
requirements:
|
|
30
|
+
- - '='
|
|
31
|
+
- !ruby/object:Gem::Version
|
|
32
|
+
version: 0.351.0
|
|
33
|
+
type: :runtime
|
|
34
|
+
prerelease: false
|
|
35
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
36
|
+
requirements:
|
|
37
|
+
- - '='
|
|
38
|
+
- !ruby/object:Gem::Version
|
|
39
|
+
version: 0.351.0
|
|
26
40
|
- !ruby/object:Gem::Dependency
|
|
27
41
|
name: debug
|
|
28
42
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -253,7 +267,6 @@ files:
|
|
|
253
267
|
- lib/dependabot/uv/file_parser.rb
|
|
254
268
|
- lib/dependabot/uv/file_parser/pyproject_files_parser.rb
|
|
255
269
|
- lib/dependabot/uv/file_parser/python_requirement_parser.rb
|
|
256
|
-
- lib/dependabot/uv/file_parser/setup_file_parser.rb
|
|
257
270
|
- lib/dependabot/uv/file_updater.rb
|
|
258
271
|
- lib/dependabot/uv/file_updater/compile_file_updater.rb
|
|
259
272
|
- lib/dependabot/uv/file_updater/lock_file_updater.rb
|
|
@@ -265,10 +278,8 @@ files:
|
|
|
265
278
|
- lib/dependabot/uv/metadata_finder.rb
|
|
266
279
|
- lib/dependabot/uv/name_normaliser.rb
|
|
267
280
|
- lib/dependabot/uv/native_helpers.rb
|
|
268
|
-
- lib/dependabot/uv/package
|
|
269
|
-
- lib/dependabot/uv/package/package_registry_finder.rb
|
|
281
|
+
- lib/dependabot/uv/package.rb
|
|
270
282
|
- lib/dependabot/uv/package_manager.rb
|
|
271
|
-
- lib/dependabot/uv/pipenv_runner.rb
|
|
272
283
|
- lib/dependabot/uv/requirement.rb
|
|
273
284
|
- lib/dependabot/uv/requirement_parser.rb
|
|
274
285
|
- lib/dependabot/uv/requirements_file_matcher.rb
|
|
@@ -284,7 +295,7 @@ licenses:
|
|
|
284
295
|
- MIT
|
|
285
296
|
metadata:
|
|
286
297
|
bug_tracker_uri: https://github.com/dependabot/dependabot-core/issues
|
|
287
|
-
changelog_uri: https://github.com/dependabot/dependabot-core/releases/tag/v0.
|
|
298
|
+
changelog_uri: https://github.com/dependabot/dependabot-core/releases/tag/v0.351.0
|
|
288
299
|
rdoc_options: []
|
|
289
300
|
require_paths:
|
|
290
301
|
- lib
|
|
@@ -1,194 +0,0 @@
|
|
|
1
|
-
# typed: strict
|
|
2
|
-
# frozen_string_literal: true
|
|
3
|
-
|
|
4
|
-
require "dependabot/dependency"
|
|
5
|
-
require "dependabot/errors"
|
|
6
|
-
require "dependabot/file_parsers/base/dependency_set"
|
|
7
|
-
require "dependabot/shared_helpers"
|
|
8
|
-
require "dependabot/uv/file_parser"
|
|
9
|
-
require "dependabot/uv/native_helpers"
|
|
10
|
-
require "dependabot/uv/name_normaliser"
|
|
11
|
-
require "sorbet-runtime"
|
|
12
|
-
|
|
13
|
-
module Dependabot
|
|
14
|
-
module Uv
|
|
15
|
-
class FileParser
|
|
16
|
-
class SetupFileParser
|
|
17
|
-
extend T::Sig
|
|
18
|
-
|
|
19
|
-
INSTALL_REQUIRES_REGEX = /install_requires\s*=\s*\[/m
|
|
20
|
-
SETUP_REQUIRES_REGEX = /setup_requires\s*=\s*\[/m
|
|
21
|
-
TESTS_REQUIRE_REGEX = /tests_require\s*=\s*\[/m
|
|
22
|
-
EXTRAS_REQUIRE_REGEX = /extras_require\s*=\s*\{/m
|
|
23
|
-
|
|
24
|
-
CLOSING_BRACKET = T.let({ "[" => "]", "{" => "}" }.freeze, T.any(T.untyped, T.untyped))
|
|
25
|
-
|
|
26
|
-
sig { params(dependency_files: T::Array[Dependabot::DependencyFile]).void }
|
|
27
|
-
def initialize(dependency_files:)
|
|
28
|
-
@dependency_files = dependency_files
|
|
29
|
-
end
|
|
30
|
-
|
|
31
|
-
sig { returns(Dependabot::FileParsers::Base::DependencySet) }
|
|
32
|
-
def dependency_set
|
|
33
|
-
dependencies = Dependabot::FileParsers::Base::DependencySet.new
|
|
34
|
-
|
|
35
|
-
parsed_setup_file.each do |dep|
|
|
36
|
-
# If a requirement has a `<` or `<=` marker then updating it is
|
|
37
|
-
# probably blocked. Ignore it.
|
|
38
|
-
next if dep["markers"].include?("<")
|
|
39
|
-
|
|
40
|
-
# If the requirement is our inserted version, ignore it
|
|
41
|
-
# (we wouldn't be able to update it)
|
|
42
|
-
next if dep["version"] == "0.0.1+dependabot"
|
|
43
|
-
|
|
44
|
-
dependencies <<
|
|
45
|
-
Dependency.new(
|
|
46
|
-
name: normalised_name(dep["name"], dep["extras"]),
|
|
47
|
-
version: dep["version"]&.include?("*") ? nil : dep["version"],
|
|
48
|
-
requirements: [{
|
|
49
|
-
requirement: dep["requirement"],
|
|
50
|
-
file: Pathname.new(dep["file"]).cleanpath.to_path,
|
|
51
|
-
source: nil,
|
|
52
|
-
groups: [dep["requirement_type"]]
|
|
53
|
-
}],
|
|
54
|
-
package_manager: "uv"
|
|
55
|
-
)
|
|
56
|
-
end
|
|
57
|
-
dependencies
|
|
58
|
-
end
|
|
59
|
-
|
|
60
|
-
private
|
|
61
|
-
|
|
62
|
-
sig { returns(T::Array[Dependabot::DependencyFile]) }
|
|
63
|
-
attr_reader :dependency_files
|
|
64
|
-
|
|
65
|
-
sig { returns(T.untyped) }
|
|
66
|
-
def parsed_setup_file
|
|
67
|
-
SharedHelpers.in_a_temporary_directory do
|
|
68
|
-
write_temporary_dependency_files
|
|
69
|
-
|
|
70
|
-
requirements = SharedHelpers.run_helper_subprocess(
|
|
71
|
-
command: "pyenv exec python3 #{NativeHelpers.python_helper_path}",
|
|
72
|
-
function: "parse_setup",
|
|
73
|
-
args: [Dir.pwd]
|
|
74
|
-
)
|
|
75
|
-
|
|
76
|
-
check_requirements(requirements)
|
|
77
|
-
requirements
|
|
78
|
-
end
|
|
79
|
-
rescue SharedHelpers::HelperSubprocessFailed => e
|
|
80
|
-
raise Dependabot::DependencyFileNotEvaluatable, e.message if e.message.start_with?("InstallationError")
|
|
81
|
-
|
|
82
|
-
return [] unless setup_file
|
|
83
|
-
|
|
84
|
-
parsed_sanitized_setup_file
|
|
85
|
-
end
|
|
86
|
-
|
|
87
|
-
sig { returns(T.nilable(T.any(T::Hash[String, T.untyped], String, T::Array[T::Hash[String, T.untyped]]))) }
|
|
88
|
-
def parsed_sanitized_setup_file
|
|
89
|
-
SharedHelpers.in_a_temporary_directory do
|
|
90
|
-
write_sanitized_setup_file
|
|
91
|
-
|
|
92
|
-
requirements = SharedHelpers.run_helper_subprocess(
|
|
93
|
-
command: "pyenv exec python3 #{NativeHelpers.python_helper_path}",
|
|
94
|
-
function: "parse_setup",
|
|
95
|
-
args: [Dir.pwd]
|
|
96
|
-
)
|
|
97
|
-
|
|
98
|
-
check_requirements(requirements)
|
|
99
|
-
requirements
|
|
100
|
-
end
|
|
101
|
-
rescue SharedHelpers::HelperSubprocessFailed
|
|
102
|
-
# Assume there are no dependencies in setup.py files that fail to
|
|
103
|
-
# parse. This isn't ideal, and we should continue to improve
|
|
104
|
-
# parsing, but there are a *lot* of things that can go wrong at
|
|
105
|
-
# the moment!
|
|
106
|
-
[]
|
|
107
|
-
end
|
|
108
|
-
|
|
109
|
-
sig { params(requirements: T.untyped).returns(T.untyped) }
|
|
110
|
-
def check_requirements(requirements)
|
|
111
|
-
requirements&.each do |dep|
|
|
112
|
-
next unless dep["requirement"]
|
|
113
|
-
|
|
114
|
-
Uv::Requirement.new(dep["requirement"].split(","))
|
|
115
|
-
rescue Gem::Requirement::BadRequirementError => e
|
|
116
|
-
raise Dependabot::DependencyFileNotEvaluatable, e.message
|
|
117
|
-
end
|
|
118
|
-
end
|
|
119
|
-
|
|
120
|
-
sig { void }
|
|
121
|
-
def write_temporary_dependency_files
|
|
122
|
-
dependency_files
|
|
123
|
-
.reject { |f| f.name == ".python-version" }
|
|
124
|
-
.each do |file|
|
|
125
|
-
path = file.name
|
|
126
|
-
FileUtils.mkdir_p(Pathname.new(path).dirname)
|
|
127
|
-
File.write(path, file.content)
|
|
128
|
-
end
|
|
129
|
-
end
|
|
130
|
-
|
|
131
|
-
# Write a setup.py with only entries for the requires fields.
|
|
132
|
-
#
|
|
133
|
-
# This sanitization is far from perfect (it will fail if any of the
|
|
134
|
-
# entries are dynamic), but it is an alternative approach to the one
|
|
135
|
-
# used in parser.py which sometimes succeeds when that has failed.
|
|
136
|
-
sig { void }
|
|
137
|
-
def write_sanitized_setup_file
|
|
138
|
-
install_requires = get_regexed_req_array(INSTALL_REQUIRES_REGEX)
|
|
139
|
-
setup_requires = get_regexed_req_array(SETUP_REQUIRES_REGEX)
|
|
140
|
-
tests_require = get_regexed_req_array(TESTS_REQUIRE_REGEX)
|
|
141
|
-
extras_require = get_regexed_req_dict(EXTRAS_REQUIRE_REGEX)
|
|
142
|
-
|
|
143
|
-
tmp = "from setuptools import setup\n\n" \
|
|
144
|
-
"setup(name=\"sanitized-package\",version=\"0.0.1\","
|
|
145
|
-
|
|
146
|
-
tmp += "install_requires=#{install_requires}," if install_requires
|
|
147
|
-
tmp += "setup_requires=#{setup_requires}," if setup_requires
|
|
148
|
-
tmp += "tests_require=#{tests_require}," if tests_require
|
|
149
|
-
tmp += "extras_require=#{extras_require}," if extras_require
|
|
150
|
-
tmp += ")"
|
|
151
|
-
|
|
152
|
-
File.write("setup.py", tmp)
|
|
153
|
-
end
|
|
154
|
-
|
|
155
|
-
sig { params(regex: Regexp).returns(T.nilable(String)) }
|
|
156
|
-
def get_regexed_req_array(regex)
|
|
157
|
-
return unless (mch = setup_file.content.match(regex))
|
|
158
|
-
|
|
159
|
-
"[#{mch.post_match[0..closing_bracket_index(mch.post_match, '[')]}"
|
|
160
|
-
end
|
|
161
|
-
|
|
162
|
-
sig { params(regex: Regexp).returns(T.nilable(String)) }
|
|
163
|
-
def get_regexed_req_dict(regex)
|
|
164
|
-
return unless (mch = setup_file.content.match(regex))
|
|
165
|
-
|
|
166
|
-
"{#{mch.post_match[0..closing_bracket_index(mch.post_match, '{')]}"
|
|
167
|
-
end
|
|
168
|
-
|
|
169
|
-
sig { params(string: String, bracket: String).returns(Integer) }
|
|
170
|
-
def closing_bracket_index(string, bracket)
|
|
171
|
-
closes_required = 1
|
|
172
|
-
|
|
173
|
-
string.chars.each_with_index do |char, index|
|
|
174
|
-
closes_required += 1 if char == bracket
|
|
175
|
-
closes_required -= 1 if char == CLOSING_BRACKET.fetch(bracket)
|
|
176
|
-
return index if closes_required.zero?
|
|
177
|
-
end
|
|
178
|
-
|
|
179
|
-
0
|
|
180
|
-
end
|
|
181
|
-
|
|
182
|
-
sig { params(name: String, extras: T::Array[String]).returns(String) }
|
|
183
|
-
def normalised_name(name, extras)
|
|
184
|
-
NameNormaliser.normalise_including_extras(name, extras)
|
|
185
|
-
end
|
|
186
|
-
|
|
187
|
-
sig { returns(T.untyped) }
|
|
188
|
-
def setup_file
|
|
189
|
-
dependency_files.find { |f| f.name == "setup.py" }
|
|
190
|
-
end
|
|
191
|
-
end
|
|
192
|
-
end
|
|
193
|
-
end
|
|
194
|
-
end
|