dependabot-uv 0.332.0 → 0.333.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/lib/dependabot/uv/authed_url_builder.rb +8 -3
- data/lib/dependabot/uv/file_fetcher.rb +16 -2
- data/lib/dependabot/uv/file_parser/pyproject_files_parser.rb +1 -0
- data/lib/dependabot/uv/file_parser/python_requirement_parser.rb +39 -16
- data/lib/dependabot/uv/file_parser/setup_file_parser.rb +1 -0
- data/lib/dependabot/uv/file_updater/compile_file_updater.rb +149 -70
- data/lib/dependabot/uv/file_updater/lock_file_updater.rb +3 -2
- data/lib/dependabot/uv/file_updater/requirement_file_updater.rb +8 -8
- data/lib/dependabot/uv/file_updater/requirement_replacer.rb +61 -24
- data/lib/dependabot/uv/file_updater.rb +2 -2
- data/lib/dependabot/uv/language.rb +1 -0
- data/lib/dependabot/uv/metadata_finder.rb +41 -10
- data/lib/dependabot/uv/package/package_registry_finder.rb +116 -61
- data/lib/dependabot/uv/requirement.rb +28 -19
- data/lib/dependabot/uv/update_checker/lock_file_resolver.rb +26 -2
- data/lib/dependabot/uv/update_checker/pip_compile_version_resolver.rb +133 -54
- data/lib/dependabot/uv/update_checker/pip_version_resolver.rb +58 -22
- data/lib/dependabot/uv/update_checker/requirements_updater.rb +79 -31
- data/lib/dependabot/uv/update_checker.rb +120 -36
- data/lib/dependabot/uv/version.rb +22 -14
- metadata +6 -6
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 9fd131434f7311972e5cb5f18dac008d471445b715dc45be558bd503ea2311d1
|
|
4
|
+
data.tar.gz: 1d6f177e73bfabbf8e7c2b109743b3e286fc6442782c36f86531a112ff57ca8a
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 33a61475c14eee350de8b5c437867311746a92518d4769cc983dc986c5c1deae73a7cc66911c2a2cdc71adee8af20274ad563ba6522cdea95ad7e0add51415d1
|
|
7
|
+
data.tar.gz: e2e942f0af3f09b03dcb913ad2c214cfb2e9dc7f7ebe80d12407afb5b989d3535d1e0e7f90e106cfd912ac71ac3d452dead20856298a528e8c535ef65577fdf7
|
|
@@ -1,12 +1,17 @@
|
|
|
1
|
-
# typed:
|
|
1
|
+
# typed: strong
|
|
2
2
|
# frozen_string_literal: true
|
|
3
3
|
|
|
4
|
+
require "sorbet-runtime"
|
|
5
|
+
|
|
4
6
|
module Dependabot
|
|
5
7
|
module Uv
|
|
6
8
|
class AuthedUrlBuilder
|
|
9
|
+
extend T::Sig
|
|
10
|
+
|
|
11
|
+
sig { params(credential: Credential).returns(String) }
|
|
7
12
|
def self.authed_url(credential:)
|
|
8
|
-
token = credential.fetch("token", nil)
|
|
9
|
-
url = credential.fetch("index-url", nil)
|
|
13
|
+
token = T.let(credential.fetch("token", nil), T.nilable(String))
|
|
14
|
+
url = T.let(credential.fetch("index-url", nil), T.nilable(String))
|
|
10
15
|
return "" unless url
|
|
11
16
|
return url unless token
|
|
12
17
|
|
|
@@ -13,10 +13,11 @@ require "dependabot/uv/requirement_parser"
|
|
|
13
13
|
require "dependabot/uv/file_parser/pyproject_files_parser"
|
|
14
14
|
require "dependabot/uv/file_parser/python_requirement_parser"
|
|
15
15
|
require "dependabot/errors"
|
|
16
|
+
require "dependabot/file_filtering"
|
|
16
17
|
|
|
17
18
|
module Dependabot
|
|
18
19
|
module Uv
|
|
19
|
-
class FileFetcher < Dependabot::FileFetchers::Base
|
|
20
|
+
class FileFetcher < Dependabot::FileFetchers::Base # rubocop:disable Metrics/ClassLength
|
|
20
21
|
extend T::Sig
|
|
21
22
|
extend T::Helpers
|
|
22
23
|
|
|
@@ -87,7 +88,12 @@ module Dependabot
|
|
|
87
88
|
fetched_files += project_files
|
|
88
89
|
fetched_files << python_version_file if python_version_file
|
|
89
90
|
|
|
90
|
-
uniq_files(fetched_files)
|
|
91
|
+
uniques = uniq_files(fetched_files)
|
|
92
|
+
filtered_files = uniques.reject do |file|
|
|
93
|
+
Dependabot::FileFiltering.should_exclude_path?(file.name, "file from final collection", @exclude_paths)
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
filtered_files
|
|
91
97
|
end
|
|
92
98
|
|
|
93
99
|
private
|
|
@@ -235,6 +241,14 @@ module Dependabot
|
|
|
235
241
|
next if previously_fetched_files.map(&:name).include?(path)
|
|
236
242
|
next if file.name == path
|
|
237
243
|
|
|
244
|
+
if Dependabot::Experiments.enabled?(:enable_exclude_paths_subdirectory_manifest_files) &&
|
|
245
|
+
!@exclude_paths.empty? && Dependabot::FileFiltering.exclude_path?(path, @exclude_paths)
|
|
246
|
+
raise Dependabot::DependencyFileNotEvaluatable,
|
|
247
|
+
"Cannot process requirements: '#{file.name}' references excluded file '#{path}'. " \
|
|
248
|
+
"Please either remove the reference from '#{file.name}' " \
|
|
249
|
+
"or update your exclude_paths configuration."
|
|
250
|
+
end
|
|
251
|
+
|
|
238
252
|
fetched_file = fetch_file_from_host(path)
|
|
239
253
|
grandchild_requirement_files = fetch_child_requirement_files(
|
|
240
254
|
file: fetched_file,
|
|
@@ -1,8 +1,10 @@
|
|
|
1
|
-
# typed:
|
|
1
|
+
# typed: strict
|
|
2
2
|
# frozen_string_literal: true
|
|
3
3
|
|
|
4
|
-
require "toml-rb"
|
|
5
4
|
require "open3"
|
|
5
|
+
require "sorbet-runtime"
|
|
6
|
+
require "toml-rb"
|
|
7
|
+
|
|
6
8
|
require "dependabot/errors"
|
|
7
9
|
require "dependabot/shared_helpers"
|
|
8
10
|
require "dependabot/uv/file_parser"
|
|
@@ -13,12 +15,17 @@ module Dependabot
|
|
|
13
15
|
module Uv
|
|
14
16
|
class FileParser
|
|
15
17
|
class PythonRequirementParser
|
|
18
|
+
extend T::Sig
|
|
19
|
+
|
|
20
|
+
sig { returns(T::Array[Dependabot::DependencyFile]) }
|
|
16
21
|
attr_reader :dependency_files
|
|
17
22
|
|
|
23
|
+
sig { params(dependency_files: T::Array[Dependabot::DependencyFile]).void }
|
|
18
24
|
def initialize(dependency_files:)
|
|
19
25
|
@dependency_files = dependency_files
|
|
20
26
|
end
|
|
21
27
|
|
|
28
|
+
sig { returns(T::Array[String]) }
|
|
22
29
|
def user_specified_requirements
|
|
23
30
|
[
|
|
24
31
|
pyproject_python_requirement,
|
|
@@ -30,22 +37,24 @@ module Dependabot
|
|
|
30
37
|
|
|
31
38
|
# TODO: Add better Python version detection using dependency versions
|
|
32
39
|
# (e.g., Django 2.x implies Python 3)
|
|
40
|
+
sig { returns(T::Array[String]) }
|
|
33
41
|
def imputed_requirements
|
|
34
42
|
requirement_files.flat_map do |file|
|
|
35
|
-
file.content.lines
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
43
|
+
T.must(file.content).lines
|
|
44
|
+
.select { |l| l.include?(";") && l.include?("python") }
|
|
45
|
+
.filter_map { |l| l.match(/python_version(?<req>.*?["'].*?['"])/) }
|
|
46
|
+
.map { |re| T.must(re.named_captures.fetch("req")).gsub(/['"]/, "") }
|
|
47
|
+
.select { |r| valid_requirement?(r) }
|
|
40
48
|
end
|
|
41
49
|
end
|
|
42
50
|
|
|
43
51
|
private
|
|
44
52
|
|
|
53
|
+
sig { returns(T.nilable(String)) }
|
|
45
54
|
def pyproject_python_requirement
|
|
46
55
|
return unless pyproject
|
|
47
56
|
|
|
48
|
-
pyproject_object = TomlRB.parse(pyproject.content)
|
|
57
|
+
pyproject_object = TomlRB.parse(T.must(pyproject).content)
|
|
49
58
|
|
|
50
59
|
# Check for PEP621 requires-python
|
|
51
60
|
pep621_python = pyproject_object.dig("project", "requires-python")
|
|
@@ -58,9 +67,10 @@ module Dependabot
|
|
|
58
67
|
poetry_object&.dig("dev-dependencies", "python")
|
|
59
68
|
end
|
|
60
69
|
|
|
70
|
+
sig { returns(T.nilable(String)) }
|
|
61
71
|
def pip_compile_python_requirement
|
|
62
72
|
requirement_files.each do |file|
|
|
63
|
-
next unless requirements_in_file_matcher.compiled_file?(file)
|
|
73
|
+
next unless T.must(requirements_in_file_matcher).compiled_file?(file)
|
|
64
74
|
|
|
65
75
|
marker = /^# This file is autogenerated by pip-compile with [pP]ython (?<version>\d+.\d+)$/m
|
|
66
76
|
match = marker.match(file.content)
|
|
@@ -72,48 +82,56 @@ module Dependabot
|
|
|
72
82
|
nil
|
|
73
83
|
end
|
|
74
84
|
|
|
85
|
+
sig { returns(T.nilable(String)) }
|
|
75
86
|
def python_version_file_version
|
|
76
87
|
return unless python_version_file
|
|
77
88
|
|
|
78
89
|
# read the content, split into lines and remove any lines with '#'
|
|
79
|
-
content_lines = python_version_file.content.each_line.map do |line|
|
|
90
|
+
content_lines = T.must(T.must(python_version_file).content).each_line.map do |line|
|
|
80
91
|
line.sub(/#.*$/, " ").strip
|
|
81
92
|
end.reject(&:empty?)
|
|
82
93
|
|
|
83
94
|
file_version = content_lines.first
|
|
84
95
|
return if file_version&.empty?
|
|
85
|
-
return unless pyenv_versions.include?("#{file_version}\n")
|
|
96
|
+
return unless T.must(pyenv_versions).include?("#{file_version}\n")
|
|
86
97
|
|
|
87
98
|
file_version
|
|
88
99
|
end
|
|
89
100
|
|
|
101
|
+
sig { returns(T.nilable(String)) }
|
|
90
102
|
def runtime_file_python_version
|
|
91
103
|
return unless runtime_file
|
|
92
104
|
|
|
93
|
-
file_version = runtime_file.content
|
|
94
|
-
|
|
105
|
+
file_version = T.must(T.must(runtime_file).content)
|
|
106
|
+
.match(/(?<=python-).*/)&.to_s&.strip
|
|
95
107
|
return if file_version&.empty?
|
|
96
|
-
return unless pyenv_versions.include?("#{file_version}\n")
|
|
108
|
+
return unless T.must(pyenv_versions).include?("#{file_version}\n")
|
|
97
109
|
|
|
98
110
|
file_version
|
|
99
111
|
end
|
|
100
112
|
|
|
113
|
+
sig { returns(T.nilable(String)) }
|
|
101
114
|
def pyenv_versions
|
|
102
|
-
@pyenv_versions
|
|
115
|
+
@pyenv_versions = T.let(run_command("pyenv install --list"), T.nilable(String))
|
|
103
116
|
end
|
|
104
117
|
|
|
118
|
+
sig { params(command: String, env: T::Hash[String, String]).returns(String) }
|
|
105
119
|
def run_command(command, env: {})
|
|
106
120
|
SharedHelpers.run_shell_command(command, env: env, stderr_to_stdout: true)
|
|
107
121
|
end
|
|
108
122
|
|
|
123
|
+
sig { returns(T.nilable(RequiremenstFileMatcher)) }
|
|
109
124
|
def requirements_in_file_matcher
|
|
110
|
-
@requirements_in_file_matcher
|
|
125
|
+
@requirements_in_file_matcher = T.let(RequiremenstFileMatcher.new(pip_compile_files),
|
|
126
|
+
T.nilable(RequiremenstFileMatcher))
|
|
111
127
|
end
|
|
112
128
|
|
|
129
|
+
sig { returns(T.class_of(Dependabot::Uv::Requirement)) }
|
|
113
130
|
def requirement_class
|
|
114
131
|
Dependabot::Uv::Requirement
|
|
115
132
|
end
|
|
116
133
|
|
|
134
|
+
sig { params(req_string: String).returns(T::Boolean) }
|
|
117
135
|
def valid_requirement?(req_string)
|
|
118
136
|
requirement_class.new(req_string)
|
|
119
137
|
true
|
|
@@ -121,22 +139,27 @@ module Dependabot
|
|
|
121
139
|
false
|
|
122
140
|
end
|
|
123
141
|
|
|
142
|
+
sig { returns(T.nilable(Dependabot::DependencyFile)) }
|
|
124
143
|
def pyproject
|
|
125
144
|
dependency_files.find { |f| f.name == "pyproject.toml" }
|
|
126
145
|
end
|
|
127
146
|
|
|
147
|
+
sig { returns(T.nilable(Dependabot::DependencyFile)) }
|
|
128
148
|
def python_version_file
|
|
129
149
|
dependency_files.find { |f| f.name == ".python-version" }
|
|
130
150
|
end
|
|
131
151
|
|
|
152
|
+
sig { returns(T.nilable(Dependabot::DependencyFile)) }
|
|
132
153
|
def runtime_file
|
|
133
154
|
dependency_files.find { |f| f.name.end_with?("runtime.txt") }
|
|
134
155
|
end
|
|
135
156
|
|
|
157
|
+
sig { returns(T::Array[Dependabot::DependencyFile]) }
|
|
136
158
|
def requirement_files
|
|
137
159
|
dependency_files.select { |f| f.name.end_with?(".txt") }
|
|
138
160
|
end
|
|
139
161
|
|
|
162
|
+
sig { returns(T::Array[Dependabot::DependencyFile]) }
|
|
140
163
|
def pip_compile_files
|
|
141
164
|
dependency_files.select { |f| f.name.end_with?(".in") }
|
|
142
165
|
end
|