dependabot-python 0.225.0 → 0.227.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 +4 -5
- data/lib/dependabot/python/file_fetcher.rb +28 -17
- data/lib/dependabot/python/file_parser/pyproject_files_parser.rb +1 -13
- data/lib/dependabot/python/file_parser/subdependency_type_parser.rb +34 -0
- data/lib/dependabot/python/file_parser.rb +0 -4
- data/lib/dependabot/python/file_updater/pip_compile_file_updater.rb +0 -4
- data/lib/dependabot/python/file_updater/pipfile_file_updater.rb +3 -6
- data/lib/dependabot/python/file_updater/pipfile_preparer.rb +7 -6
- data/lib/dependabot/python/file_updater/poetry_file_updater.rb +14 -25
- data/lib/dependabot/python/file_updater/requirement_file_updater.rb +0 -3
- data/lib/dependabot/python/file_updater.rb +1 -5
- data/lib/dependabot/python/language_version_manager.rb +24 -43
- data/lib/dependabot/python/metadata_finder.rb +0 -1
- data/lib/dependabot/python/update_checker/pip_compile_version_resolver.rb +2 -19
- data/lib/dependabot/python/update_checker/pipenv_version_resolver.rb +0 -1
- data/lib/dependabot/python/update_checker/poetry_version_resolver.rb +20 -42
- data/lib/dependabot/python/update_checker.rb +2 -6
- metadata +8 -8
- data/lib/dependabot/python/python_versions.rb +0 -34
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: eb1b6edd3b3d295491ad39866fa4a7d480f9322bd60a6a05e2d9a8e7eb3c9462
|
|
4
|
+
data.tar.gz: 3b6397f0af03444908c3b87cc6dfbc173b38f0e5ae54bc5528c6588ea3e4655a
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 295996b49310faa8aa04502f057963a0a3e21289a800be24780fcdc38c4533d0496e88a4b9a0b6722d526e707ee51cadb30a91916a882db4fb95aa8f8f2d9ebd
|
|
7
|
+
data.tar.gz: 71b07d3ed46fe06aeecce18cf2dc42da67143be4953e9b45e051cad4e57f84332fda400b071139695847a1e7eaf8ee4c4fc6da50a03dfc9d00a81979e0ffc10c
|
data/helpers/requirements.txt
CHANGED
|
@@ -1,10 +1,9 @@
|
|
|
1
|
-
pip
|
|
2
|
-
pip-tools
|
|
1
|
+
pip==23.2.0
|
|
2
|
+
pip-tools==7.2.0
|
|
3
3
|
hashin==0.17.0
|
|
4
4
|
pipenv==2022.4.8
|
|
5
5
|
pipfile==0.0.2
|
|
6
|
-
poetry
|
|
7
|
-
wheel==0.37.1
|
|
6
|
+
poetry==1.5.1
|
|
8
7
|
|
|
9
8
|
# Some dependencies will only install if Cython is present
|
|
10
|
-
Cython==0.
|
|
9
|
+
Cython==3.0.0
|
|
@@ -91,7 +91,7 @@ module Dependabot
|
|
|
91
91
|
end
|
|
92
92
|
|
|
93
93
|
def pyproject_files
|
|
94
|
-
[pyproject,
|
|
94
|
+
[pyproject, poetry_lock, pdm_lock].compact
|
|
95
95
|
end
|
|
96
96
|
|
|
97
97
|
def requirement_files
|
|
@@ -116,21 +116,27 @@ module Dependabot
|
|
|
116
116
|
end
|
|
117
117
|
|
|
118
118
|
def setup_file
|
|
119
|
-
@setup_file
|
|
119
|
+
return @setup_file if defined?(@setup_file)
|
|
120
|
+
|
|
121
|
+
@setup_file = fetch_file_if_present("setup.py")
|
|
120
122
|
end
|
|
121
123
|
|
|
122
124
|
def setup_cfg_file
|
|
123
|
-
@setup_cfg_file
|
|
125
|
+
return @setup_cfg_file if defined?(@setup_cfg_file)
|
|
126
|
+
|
|
127
|
+
@setup_cfg_file = fetch_file_if_present("setup.cfg")
|
|
124
128
|
end
|
|
125
129
|
|
|
126
130
|
def pip_conf
|
|
127
|
-
@pip_conf
|
|
128
|
-
|
|
131
|
+
return @pip_conf if defined?(@pip_conf)
|
|
132
|
+
|
|
133
|
+
@pip_conf = fetch_support_file("pip.conf")
|
|
129
134
|
end
|
|
130
135
|
|
|
131
136
|
def python_version_file
|
|
132
|
-
@python_version_file
|
|
133
|
-
|
|
137
|
+
return @python_version_file if defined?(@python_version_file)
|
|
138
|
+
|
|
139
|
+
@python_version_file = fetch_support_file(".python-version")
|
|
134
140
|
|
|
135
141
|
return @python_version_file if @python_version_file
|
|
136
142
|
return if [".", "/"].include?(directory)
|
|
@@ -138,33 +144,38 @@ module Dependabot
|
|
|
138
144
|
# Check the top-level for a .python-version file, too
|
|
139
145
|
reverse_path = Pathname.new(directory[0]).relative_path_from(directory)
|
|
140
146
|
@python_version_file ||=
|
|
141
|
-
|
|
142
|
-
tap { |f| f.support_file = true }&.
|
|
147
|
+
fetch_support_file(File.join(reverse_path, ".python-version"))&.
|
|
143
148
|
tap { |f| f.name = ".python-version" }
|
|
144
149
|
end
|
|
145
150
|
|
|
146
151
|
def pipfile
|
|
147
|
-
@pipfile
|
|
152
|
+
return @pipfile if defined?(@pipfile)
|
|
153
|
+
|
|
154
|
+
@pipfile = fetch_file_if_present("Pipfile")
|
|
148
155
|
end
|
|
149
156
|
|
|
150
157
|
def pipfile_lock
|
|
151
|
-
@pipfile_lock
|
|
158
|
+
return @pipfile_lock if defined?(@pipfile_lock)
|
|
159
|
+
|
|
160
|
+
@pipfile_lock = fetch_file_if_present("Pipfile.lock")
|
|
152
161
|
end
|
|
153
162
|
|
|
154
163
|
def pyproject
|
|
155
|
-
@pyproject
|
|
156
|
-
end
|
|
164
|
+
return @pyproject if defined?(@pyproject)
|
|
157
165
|
|
|
158
|
-
|
|
159
|
-
@pyproject_lock ||= fetch_file_if_present("pyproject.lock")
|
|
166
|
+
@pyproject = fetch_file_if_present("pyproject.toml")
|
|
160
167
|
end
|
|
161
168
|
|
|
162
169
|
def poetry_lock
|
|
163
|
-
@poetry_lock
|
|
170
|
+
return @poetry_lock if defined?(@poetry_lock)
|
|
171
|
+
|
|
172
|
+
@poetry_lock = fetch_file_if_present("poetry.lock")
|
|
164
173
|
end
|
|
165
174
|
|
|
166
175
|
def pdm_lock
|
|
167
|
-
@pdm_lock
|
|
176
|
+
return @pdm_lock if defined?(@pdm_lock)
|
|
177
|
+
|
|
178
|
+
@pdm_lock = fetch_file_if_present("pdm.lock")
|
|
168
179
|
end
|
|
169
180
|
|
|
170
181
|
def requirements_txt_files
|
|
@@ -194,12 +194,6 @@ module Dependabot
|
|
|
194
194
|
raise Dependabot::DependencyFileNotParseable, pyproject.path
|
|
195
195
|
end
|
|
196
196
|
|
|
197
|
-
def parsed_pyproject_lock
|
|
198
|
-
@parsed_pyproject_lock ||= TomlRB.parse(pyproject_lock.content)
|
|
199
|
-
rescue TomlRB::ParseError, TomlRB::ValueOverwriteError
|
|
200
|
-
raise Dependabot::DependencyFileNotParseable, pyproject_lock.path
|
|
201
|
-
end
|
|
202
|
-
|
|
203
197
|
def parsed_poetry_lock
|
|
204
198
|
@parsed_poetry_lock ||= TomlRB.parse(poetry_lock.content)
|
|
205
199
|
rescue TomlRB::ParseError, TomlRB::ValueOverwriteError
|
|
@@ -212,7 +206,7 @@ module Dependabot
|
|
|
212
206
|
end
|
|
213
207
|
|
|
214
208
|
def lockfile
|
|
215
|
-
poetry_lock
|
|
209
|
+
poetry_lock
|
|
216
210
|
end
|
|
217
211
|
|
|
218
212
|
def parsed_pep621_dependencies
|
|
@@ -235,12 +229,6 @@ module Dependabot
|
|
|
235
229
|
|
|
236
230
|
def parsed_lockfile
|
|
237
231
|
return parsed_poetry_lock if poetry_lock
|
|
238
|
-
return parsed_pyproject_lock if pyproject_lock
|
|
239
|
-
end
|
|
240
|
-
|
|
241
|
-
def pyproject_lock
|
|
242
|
-
@pyproject_lock ||=
|
|
243
|
-
dependency_files.find { |f| f.name == "pyproject.lock" }
|
|
244
232
|
end
|
|
245
233
|
|
|
246
234
|
def poetry_lock
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "toml-rb"
|
|
4
|
+
require "dependabot/python/file_parser"
|
|
5
|
+
require "dependabot/python/name_normaliser"
|
|
6
|
+
|
|
7
|
+
module Dependabot
|
|
8
|
+
module Python
|
|
9
|
+
class FileParser
|
|
10
|
+
class PoetrySubdependencyTypeParser
|
|
11
|
+
def initialize(lockfile:)
|
|
12
|
+
@lockfile = lockfile
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def subdep_type(dep)
|
|
16
|
+
category =
|
|
17
|
+
TomlRB.parse(lockfile.content).fetch("package", []).
|
|
18
|
+
find { |dets| normalise(dets.fetch("name")) == dep.name }.
|
|
19
|
+
fetch("category")
|
|
20
|
+
|
|
21
|
+
category == "dev" ? "dev-dependencies" : "dependencies"
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
private
|
|
25
|
+
|
|
26
|
+
attr_reader :lockfile
|
|
27
|
+
|
|
28
|
+
def normalise(name)
|
|
29
|
+
NameNormaliser.normalise(name)
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
@@ -208,10 +208,6 @@ module Dependabot
|
|
|
208
208
|
@pyproject ||= get_original_file("pyproject.toml")
|
|
209
209
|
end
|
|
210
210
|
|
|
211
|
-
def pyproject_lock
|
|
212
|
-
@pyproject_lock ||= get_original_file("pyproject.lock")
|
|
213
|
-
end
|
|
214
|
-
|
|
215
211
|
def poetry_lock
|
|
216
212
|
@poetry_lock ||= get_original_file("poetry.lock")
|
|
217
213
|
end
|
|
@@ -9,7 +9,6 @@ require "dependabot/python/file_updater"
|
|
|
9
9
|
require "dependabot/shared_helpers"
|
|
10
10
|
require "dependabot/python/language_version_manager"
|
|
11
11
|
require "dependabot/python/native_helpers"
|
|
12
|
-
require "dependabot/python/python_versions"
|
|
13
12
|
require "dependabot/python/name_normaliser"
|
|
14
13
|
require "dependabot/python/authed_url_builder"
|
|
15
14
|
|
|
@@ -37,9 +36,6 @@ module Dependabot
|
|
|
37
36
|
end
|
|
38
37
|
|
|
39
38
|
def updated_dependency_files
|
|
40
|
-
return @updated_dependency_files if @update_already_attempted
|
|
41
|
-
|
|
42
|
-
@update_already_attempted = true
|
|
43
39
|
@updated_dependency_files ||= fetch_updated_dependency_files
|
|
44
40
|
end
|
|
45
41
|
|
|
@@ -30,9 +30,6 @@ module Dependabot
|
|
|
30
30
|
end
|
|
31
31
|
|
|
32
32
|
def updated_dependency_files
|
|
33
|
-
return @updated_dependency_files if @update_already_attempted
|
|
34
|
-
|
|
35
|
-
@update_already_attempted = true
|
|
36
33
|
@updated_dependency_files ||= fetch_updated_dependency_files
|
|
37
34
|
end
|
|
38
35
|
|
|
@@ -92,7 +89,7 @@ module Dependabot
|
|
|
92
89
|
|
|
93
90
|
# Find any requirement files that list the same dependencies as
|
|
94
91
|
# the (old) Pipfile.lock. Any such files were almost certainly
|
|
95
|
-
# generated using `pipenv
|
|
92
|
+
# generated using `pipenv requirements`
|
|
96
93
|
requirements_files.select do |req_file|
|
|
97
94
|
deps = []
|
|
98
95
|
req_file.content.scan(regex) { deps << Regexp.last_match }
|
|
@@ -237,12 +234,12 @@ module Dependabot
|
|
|
237
234
|
|
|
238
235
|
def generate_updated_requirements_files
|
|
239
236
|
req_content = run_pipenv_command(
|
|
240
|
-
"pyenv exec pipenv
|
|
237
|
+
"pyenv exec pipenv requirements"
|
|
241
238
|
)
|
|
242
239
|
File.write("req.txt", req_content)
|
|
243
240
|
|
|
244
241
|
dev_req_content = run_pipenv_command(
|
|
245
|
-
"pyenv exec pipenv
|
|
242
|
+
"pyenv exec pipenv requirements --dev"
|
|
246
243
|
)
|
|
247
244
|
File.write("dev-req.txt", dev_req_content)
|
|
248
245
|
end
|
|
@@ -109,9 +109,7 @@ module Dependabot
|
|
|
109
109
|
end
|
|
110
110
|
|
|
111
111
|
def pipfile_sources
|
|
112
|
-
@pipfile_sources ||=
|
|
113
|
-
TomlRB.parse(pipfile_content).fetch("source", []).
|
|
114
|
-
map { |h| h.dup.merge("url" => h["url"].gsub(%r{/*$}, "") + "/") }
|
|
112
|
+
@pipfile_sources ||= TomlRB.parse(pipfile_content).fetch("source", [])
|
|
115
113
|
end
|
|
116
114
|
|
|
117
115
|
def sub_auth_url(source, credentials)
|
|
@@ -132,9 +130,12 @@ module Dependabot
|
|
|
132
130
|
|
|
133
131
|
def config_variable_sources(credentials)
|
|
134
132
|
@config_variable_sources ||=
|
|
135
|
-
credentials.
|
|
136
|
-
|
|
137
|
-
|
|
133
|
+
credentials.select { |cred| cred["type"] == "python_index" }.map.with_index do |c, i|
|
|
134
|
+
{
|
|
135
|
+
"name" => "dependabot-inserted-index-#{i}",
|
|
136
|
+
"url" => AuthedUrlBuilder.authed_url(credential: c)
|
|
137
|
+
}
|
|
138
|
+
end
|
|
138
139
|
end
|
|
139
140
|
end
|
|
140
141
|
end
|
|
@@ -7,8 +7,8 @@ require "dependabot/shared_helpers"
|
|
|
7
7
|
require "dependabot/python/language_version_manager"
|
|
8
8
|
require "dependabot/python/version"
|
|
9
9
|
require "dependabot/python/requirement"
|
|
10
|
-
require "dependabot/python/python_versions"
|
|
11
10
|
require "dependabot/python/file_parser/python_requirement_parser"
|
|
11
|
+
require "dependabot/python/file_parser/subdependency_type_parser"
|
|
12
12
|
require "dependabot/python/file_updater"
|
|
13
13
|
require "dependabot/python/native_helpers"
|
|
14
14
|
require "dependabot/python/name_normaliser"
|
|
@@ -28,9 +28,6 @@ module Dependabot
|
|
|
28
28
|
end
|
|
29
29
|
|
|
30
30
|
def updated_dependency_files
|
|
31
|
-
return @updated_dependency_files if @update_already_attempted
|
|
32
|
-
|
|
33
|
-
@update_already_attempted = true
|
|
34
31
|
@updated_dependency_files ||= fetch_updated_dependency_files
|
|
35
32
|
end
|
|
36
33
|
|
|
@@ -160,17 +157,10 @@ module Dependabot
|
|
|
160
157
|
end
|
|
161
158
|
|
|
162
159
|
def create_declaration_at_new_version!(poetry_object, dep)
|
|
163
|
-
|
|
164
|
-
poetry_object[subdep_type][dependency.name] = dep.version
|
|
165
|
-
end
|
|
160
|
+
subdep_type = subdependency_type_parser.subdep_type(dep)
|
|
166
161
|
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
TomlRB.parse(lockfile.content).fetch("package", []).
|
|
170
|
-
find { |dets| normalise(dets.fetch("name")) == dependency.name }.
|
|
171
|
-
fetch("category")
|
|
172
|
-
|
|
173
|
-
category == "dev" ? "dev-dependencies" : "dependencies"
|
|
162
|
+
poetry_object[subdep_type] ||= {}
|
|
163
|
+
poetry_object[subdep_type][dep.name] = dep.version
|
|
174
164
|
end
|
|
175
165
|
|
|
176
166
|
def sanitize(pyproject_content)
|
|
@@ -188,15 +178,11 @@ module Dependabot
|
|
|
188
178
|
language_version_manager.install_required_python
|
|
189
179
|
|
|
190
180
|
# use system git instead of the pure Python dulwich
|
|
191
|
-
|
|
192
|
-
run_poetry_command("pyenv exec poetry config experimental.system-git-client true")
|
|
193
|
-
end
|
|
181
|
+
run_poetry_command("pyenv exec poetry config experimental.system-git-client true")
|
|
194
182
|
|
|
195
183
|
run_poetry_update_command
|
|
196
184
|
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
File.read("pyproject.lock")
|
|
185
|
+
File.read("poetry.lock")
|
|
200
186
|
end
|
|
201
187
|
end
|
|
202
188
|
end
|
|
@@ -305,6 +291,13 @@ module Dependabot
|
|
|
305
291
|
)
|
|
306
292
|
end
|
|
307
293
|
|
|
294
|
+
def subdependency_type_parser
|
|
295
|
+
@subdependency_type_parser ||=
|
|
296
|
+
FileParser::PoetrySubdependencyTypeParser.new(
|
|
297
|
+
lockfile: lockfile
|
|
298
|
+
)
|
|
299
|
+
end
|
|
300
|
+
|
|
308
301
|
def language_version_manager
|
|
309
302
|
@language_version_manager ||=
|
|
310
303
|
LanguageVersionManager.new(
|
|
@@ -318,17 +311,13 @@ module Dependabot
|
|
|
318
311
|
end
|
|
319
312
|
|
|
320
313
|
def lockfile
|
|
321
|
-
@lockfile ||=
|
|
314
|
+
@lockfile ||= poetry_lock
|
|
322
315
|
end
|
|
323
316
|
|
|
324
317
|
def python_helper_path
|
|
325
318
|
NativeHelpers.python_helper_path
|
|
326
319
|
end
|
|
327
320
|
|
|
328
|
-
def pyproject_lock
|
|
329
|
-
dependency_files.find { |f| f.name == "pyproject.lock" }
|
|
330
|
-
end
|
|
331
|
-
|
|
332
321
|
def poetry_lock
|
|
333
322
|
dependency_files.find { |f| f.name == "poetry.lock" }
|
|
334
323
|
end
|
|
@@ -77,7 +77,7 @@ module Dependabot
|
|
|
77
77
|
|
|
78
78
|
def subdependency_resolver
|
|
79
79
|
return :pipfile if pipfile_lock
|
|
80
|
-
return :poetry if poetry_lock
|
|
80
|
+
return :poetry if poetry_lock
|
|
81
81
|
return :pip_compile if pip_compile_files.any?
|
|
82
82
|
|
|
83
83
|
raise "Claimed to be a sub-dependency, but no lockfile exists!"
|
|
@@ -144,10 +144,6 @@ module Dependabot
|
|
|
144
144
|
@pyproject ||= get_original_file("pyproject.toml")
|
|
145
145
|
end
|
|
146
146
|
|
|
147
|
-
def pyproject_lock
|
|
148
|
-
@pyproject_lock ||= get_original_file("pyproject.lock")
|
|
149
|
-
end
|
|
150
|
-
|
|
151
147
|
def poetry_lock
|
|
152
148
|
@poetry_lock ||= get_original_file("poetry.lock")
|
|
153
149
|
end
|
|
@@ -6,6 +6,14 @@ require "dependabot/python/version"
|
|
|
6
6
|
module Dependabot
|
|
7
7
|
module Python
|
|
8
8
|
class LanguageVersionManager
|
|
9
|
+
# This list must match the versions specified at the top of `python/Dockerfile`
|
|
10
|
+
PRE_INSTALLED_PYTHON_VERSIONS = %w(
|
|
11
|
+
3.11.4
|
|
12
|
+
3.10.12
|
|
13
|
+
3.9.17
|
|
14
|
+
3.8.17
|
|
15
|
+
).freeze
|
|
16
|
+
|
|
9
17
|
def initialize(python_requirement_parser:)
|
|
10
18
|
@python_requirement_parser = python_requirement_parser
|
|
11
19
|
end
|
|
@@ -14,27 +22,13 @@ module Dependabot
|
|
|
14
22
|
# The leading space is important in the version check
|
|
15
23
|
return if SharedHelpers.run_shell_command("pyenv versions").include?(" #{python_major_minor}.")
|
|
16
24
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
)
|
|
21
|
-
return if SharedHelpers.run_shell_command("pyenv versions").
|
|
22
|
-
include?(" #{python_major_minor}.")
|
|
23
|
-
end
|
|
24
|
-
|
|
25
|
-
Dependabot.logger.info("Installing required Python #{python_version}.")
|
|
26
|
-
start = Time.now
|
|
27
|
-
SharedHelpers.run_shell_command("pyenv install -s #{python_version}")
|
|
28
|
-
SharedHelpers.run_shell_command("pyenv exec pip install --upgrade pip")
|
|
29
|
-
SharedHelpers.run_shell_command("pyenv exec pip install -r" \
|
|
30
|
-
"#{NativeHelpers.python_requirements_path}")
|
|
31
|
-
time_taken = Time.now - start
|
|
32
|
-
Dependabot.logger.info("Installing Python #{python_version} took #{time_taken}s.")
|
|
25
|
+
SharedHelpers.run_shell_command(
|
|
26
|
+
"tar xzf /usr/local/.pyenv/#{python_major_minor}.tar.gz -C /usr/local/.pyenv/"
|
|
27
|
+
)
|
|
33
28
|
end
|
|
34
29
|
|
|
35
30
|
def python_major_minor
|
|
36
|
-
@
|
|
37
|
-
"#{@python.segments[0]}.#{@python.segments[1]}"
|
|
31
|
+
@python_major_minor ||= Python::Version.new(python_version).segments[0..1].join(".")
|
|
38
32
|
end
|
|
39
33
|
|
|
40
34
|
def python_version
|
|
@@ -59,32 +53,19 @@ module Dependabot
|
|
|
59
53
|
def python_version_from_supported_versions
|
|
60
54
|
requirement_string = python_requirement_string
|
|
61
55
|
|
|
62
|
-
#
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
version =
|
|
66
|
-
PythonVersions::SUPPORTED_VERSIONS_TO_ITERATE.
|
|
67
|
-
find { |v| requirement.satisfied_by?(Python::Version.new(v)) }
|
|
68
|
-
return version if version
|
|
56
|
+
# If the requirement string isn't already a range (eg ">3.10"), coerce it to "major.minor.*".
|
|
57
|
+
# The patch version is ignored because a non-matching patch version is unlikely to affect resolution.
|
|
58
|
+
requirement_string = requirement_string.gsub(/\.\d+$/, ".*") if requirement_string.start_with?(/\d/)
|
|
69
59
|
|
|
70
|
-
#
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
if
|
|
74
|
-
requirement =
|
|
75
|
-
Python::Requirement.new(requirement_string.gsub(/\.\d+$/, ".*"))
|
|
76
|
-
version =
|
|
77
|
-
PythonVersions::SUPPORTED_VERSIONS_TO_ITERATE.
|
|
78
|
-
find { |v| requirement.satisfied_by?(Python::Version.new(v)) }
|
|
79
|
-
return version if version
|
|
80
|
-
end
|
|
60
|
+
# Try to match one of our pre-installed Python versions
|
|
61
|
+
requirement = Python::Requirement.requirements_array(requirement_string).first
|
|
62
|
+
version = PRE_INSTALLED_PYTHON_VERSIONS.find { |v| requirement.satisfied_by?(Python::Version.new(v)) }
|
|
63
|
+
return version if version
|
|
81
64
|
|
|
82
|
-
# Otherwise we have to raise
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
"
|
|
86
|
-
"following Python versions are supported in Dependabot: " \
|
|
87
|
-
"#{PythonVersions::SUPPORTED_VERSIONS.join(', ')}."
|
|
65
|
+
# Otherwise we have to raise
|
|
66
|
+
msg = "Dependabot detected the following Python requirement for your project: '#{python_requirement_string}'." \
|
|
67
|
+
"\n\nCurrently, the following Python versions are supported in Dependabot: " \
|
|
68
|
+
"#{PRE_INSTALLED_PYTHON_VERSIONS.map { |x| x.gsub(/\.\d+$/, '.*') }.join(', ')}."
|
|
88
69
|
raise DependencyFileNotResolvable, msg
|
|
89
70
|
end
|
|
90
71
|
|
|
@@ -101,7 +82,7 @@ module Dependabot
|
|
|
101
82
|
end
|
|
102
83
|
|
|
103
84
|
def python_version_matching(requirements)
|
|
104
|
-
|
|
85
|
+
PRE_INSTALLED_PYTHON_VERSIONS.find do |version_string|
|
|
105
86
|
version = Python::Version.new(version_string)
|
|
106
87
|
requirements.all? do |req|
|
|
107
88
|
next req.any? { |r| r.satisfied_by?(version) } if req.is_a?(Array)
|
|
@@ -27,7 +27,6 @@ module Dependabot
|
|
|
27
27
|
potential_source_urls = [
|
|
28
28
|
pypi_listing.dig("info", "project_urls", "Source"),
|
|
29
29
|
pypi_listing.dig("info", "home_page"),
|
|
30
|
-
pypi_listing.dig("info", "bugtrack_url"),
|
|
31
30
|
pypi_listing.dig("info", "download_url"),
|
|
32
31
|
pypi_listing.dig("info", "docs_url")
|
|
33
32
|
].compact
|
|
@@ -13,7 +13,6 @@ require "dependabot/python/version"
|
|
|
13
13
|
require "dependabot/shared_helpers"
|
|
14
14
|
require "dependabot/python/language_version_manager"
|
|
15
15
|
require "dependabot/python/native_helpers"
|
|
16
|
-
require "dependabot/python/python_versions"
|
|
17
16
|
require "dependabot/python/name_normaliser"
|
|
18
17
|
require "dependabot/python/authed_url_builder"
|
|
19
18
|
|
|
@@ -23,7 +22,6 @@ module Dependabot
|
|
|
23
22
|
# This class does version resolution for pip-compile. Its approach is:
|
|
24
23
|
# - Unlock the dependency we're checking in the requirements.in file
|
|
25
24
|
# - Run `pip-compile` and see what the result is
|
|
26
|
-
# rubocop:disable Metrics/ClassLength
|
|
27
25
|
class PipCompileVersionResolver
|
|
28
26
|
GIT_DEPENDENCY_UNREACHABLE_REGEX = /git clone --filter=blob:none --quiet (?<url>[^\s]+).* /
|
|
29
27
|
GIT_REFERENCE_NOT_FOUND_REGEX = /Did not find branch or tag '(?<tag>[^\n"]+)'/m
|
|
@@ -236,10 +234,6 @@ module Dependabot
|
|
|
236
234
|
)
|
|
237
235
|
end
|
|
238
236
|
|
|
239
|
-
def new_resolver_supported?
|
|
240
|
-
language_version_manager.python_version >= Python::Version.new("3.7")
|
|
241
|
-
end
|
|
242
|
-
|
|
243
237
|
def pip_compile_options_fingerprint(options)
|
|
244
238
|
options.sub(
|
|
245
239
|
/--output-file=\S+/, "--output-file=<output_file>"
|
|
@@ -253,8 +247,9 @@ module Dependabot
|
|
|
253
247
|
def pip_compile_options(filename)
|
|
254
248
|
options = @build_isolation ? ["--build-isolation"] : ["--no-build-isolation"]
|
|
255
249
|
options += pip_compile_index_options
|
|
250
|
+
# TODO: Stop explicitly specifying `allow-unsafe` once it becomes the default:
|
|
251
|
+
# https://github.com/jazzband/pip-tools/issues/989#issuecomment-1661254701
|
|
256
252
|
options += ["--allow-unsafe"]
|
|
257
|
-
options += ["--resolver backtracking"] if new_resolver_supported?
|
|
258
253
|
|
|
259
254
|
if (requirements_file = compiled_file_for_filename(filename))
|
|
260
255
|
options << "--output-file=#{requirements_file.name}"
|
|
@@ -301,17 +296,6 @@ module Dependabot
|
|
|
301
296
|
env
|
|
302
297
|
end
|
|
303
298
|
|
|
304
|
-
def error_certainly_bad_python_version?(message)
|
|
305
|
-
return true if message.include?("UnsupportedPythonVersion")
|
|
306
|
-
|
|
307
|
-
unless message.include?('"python setup.py egg_info" failed') ||
|
|
308
|
-
message.include?("exit status 1: python setup.py egg_info")
|
|
309
|
-
return false
|
|
310
|
-
end
|
|
311
|
-
|
|
312
|
-
message.include?("SyntaxError")
|
|
313
|
-
end
|
|
314
|
-
|
|
315
299
|
def write_temporary_dependency_files(updated_req: nil,
|
|
316
300
|
update_requirement: true)
|
|
317
301
|
dependency_files.each do |file|
|
|
@@ -513,7 +497,6 @@ module Dependabot
|
|
|
513
497
|
dependency_files.select { |f| f.name.end_with?("setup.cfg") }
|
|
514
498
|
end
|
|
515
499
|
end
|
|
516
|
-
# rubocop:enable Metrics/ClassLength
|
|
517
500
|
end
|
|
518
501
|
end
|
|
519
502
|
end
|
|
@@ -11,7 +11,6 @@ require "dependabot/python/file_parser/python_requirement_parser"
|
|
|
11
11
|
require "dependabot/python/file_updater/pipfile_preparer"
|
|
12
12
|
require "dependabot/python/file_updater/setup_file_sanitizer"
|
|
13
13
|
require "dependabot/python/update_checker"
|
|
14
|
-
require "dependabot/python/python_versions"
|
|
15
14
|
require "dependabot/python/native_helpers"
|
|
16
15
|
require "dependabot/python/name_normaliser"
|
|
17
16
|
require "dependabot/python/version"
|
|
@@ -9,12 +9,12 @@ require "dependabot/errors"
|
|
|
9
9
|
require "dependabot/shared_helpers"
|
|
10
10
|
require "dependabot/python/file_parser"
|
|
11
11
|
require "dependabot/python/file_parser/python_requirement_parser"
|
|
12
|
+
require "dependabot/python/file_parser/subdependency_type_parser"
|
|
12
13
|
require "dependabot/python/file_updater/pyproject_preparer"
|
|
13
14
|
require "dependabot/python/update_checker"
|
|
14
15
|
require "dependabot/python/version"
|
|
15
16
|
require "dependabot/python/requirement"
|
|
16
17
|
require "dependabot/python/native_helpers"
|
|
17
|
-
require "dependabot/python/python_versions"
|
|
18
18
|
require "dependabot/python/authed_url_builder"
|
|
19
19
|
require "dependabot/python/name_normaliser"
|
|
20
20
|
|
|
@@ -24,30 +24,19 @@ module Dependabot
|
|
|
24
24
|
# This class does version resolution for pyproject.toml files.
|
|
25
25
|
class PoetryVersionResolver
|
|
26
26
|
GIT_REFERENCE_NOT_FOUND_REGEX = /
|
|
27
|
-
(
|
|
28
|
-
'checkout',
|
|
29
|
-
'(?<tag>.+?)'
|
|
30
|
-
|
|
|
31
|
-
Failed to checkout
|
|
27
|
+
(Failed to checkout
|
|
32
28
|
(?<tag>.+?)
|
|
33
29
|
(?<url>.+?).git at '(?<tag>.+?)'
|
|
34
30
|
|
|
|
35
31
|
...Failedtoclone
|
|
36
32
|
(?<url>.+?).gitat'(?<tag>.+?)',
|
|
37
33
|
verifyrefexistsonremote)
|
|
38
|
-
/x
|
|
34
|
+
/x
|
|
39
35
|
GIT_DEPENDENCY_UNREACHABLE_REGEX = /
|
|
40
|
-
(?:'\['git',
|
|
41
|
-
\s+'clone',
|
|
42
|
-
\s+'--recurse-submodules',
|
|
43
|
-
\s+'(--)?',
|
|
44
|
-
\s+'(?<url>.+?)'.*
|
|
45
|
-
\s+exit\s+status\s+128
|
|
46
|
-
|
|
|
47
36
|
\s+Failed\sto\sclone
|
|
48
37
|
\s+(?<url>.+?),
|
|
49
|
-
\s+check\syour\sgit\sconfiguration
|
|
50
|
-
/mx
|
|
38
|
+
\s+check\syour\sgit\sconfiguration
|
|
39
|
+
/mx
|
|
51
40
|
|
|
52
41
|
attr_reader :dependency, :dependency_files, :credentials
|
|
53
42
|
|
|
@@ -74,8 +63,7 @@ module Dependabot
|
|
|
74
63
|
false
|
|
75
64
|
end
|
|
76
65
|
rescue SharedHelpers::HelperSubprocessFailed => e
|
|
77
|
-
raise unless e.message.include?("
|
|
78
|
-
e.message.include?("version solving failed.")
|
|
66
|
+
raise unless e.message.include?("version solving failed.")
|
|
79
67
|
|
|
80
68
|
@resolvable[version] = false
|
|
81
69
|
end
|
|
@@ -95,18 +83,12 @@ module Dependabot
|
|
|
95
83
|
language_version_manager.install_required_python
|
|
96
84
|
|
|
97
85
|
# use system git instead of the pure Python dulwich
|
|
98
|
-
|
|
99
|
-
run_poetry_command("pyenv exec poetry config experimental.system-git-client true")
|
|
100
|
-
end
|
|
86
|
+
run_poetry_command("pyenv exec poetry config experimental.system-git-client true")
|
|
101
87
|
|
|
102
88
|
# Shell out to Poetry, which handles everything for us.
|
|
103
89
|
run_poetry_update_command
|
|
104
90
|
|
|
105
|
-
updated_lockfile =
|
|
106
|
-
if File.exist?("poetry.lock") then File.read("poetry.lock")
|
|
107
|
-
else
|
|
108
|
-
File.read("pyproject.lock")
|
|
109
|
-
end
|
|
91
|
+
updated_lockfile = File.read("poetry.lock")
|
|
110
92
|
updated_lockfile = TomlRB.parse(updated_lockfile)
|
|
111
93
|
|
|
112
94
|
fetch_version_from_parsed_lockfile(updated_lockfile)
|
|
@@ -147,7 +129,7 @@ module Dependabot
|
|
|
147
129
|
end
|
|
148
130
|
|
|
149
131
|
raise unless error.message.include?("SolverProblemError") ||
|
|
150
|
-
error.message.include?("
|
|
132
|
+
error.message.include?("not found") ||
|
|
151
133
|
error.message.include?("version solving failed.")
|
|
152
134
|
|
|
153
135
|
check_original_requirements_resolvable
|
|
@@ -182,7 +164,7 @@ module Dependabot
|
|
|
182
164
|
@original_reqs_resolvable = true
|
|
183
165
|
rescue SharedHelpers::HelperSubprocessFailed => e
|
|
184
166
|
raise unless e.message.include?("SolverProblemError") ||
|
|
185
|
-
e.message.include?("
|
|
167
|
+
e.message.include?("not found") ||
|
|
186
168
|
e.message.include?("version solving failed.")
|
|
187
169
|
|
|
188
170
|
msg = clean_error_message(e.message)
|
|
@@ -278,6 +260,8 @@ module Dependabot
|
|
|
278
260
|
|
|
279
261
|
# If this is a sub-dependency, add the new requirement
|
|
280
262
|
unless dependency.requirements.find { |r| r[:file] == pyproject.name }
|
|
263
|
+
subdep_type = subdependency_type_parser.subdep_type(dependency)
|
|
264
|
+
|
|
281
265
|
poetry_object[subdep_type] ||= {}
|
|
282
266
|
poetry_object[subdep_type][dependency.name] = updated_requirement
|
|
283
267
|
end
|
|
@@ -297,15 +281,6 @@ module Dependabot
|
|
|
297
281
|
end
|
|
298
282
|
end
|
|
299
283
|
|
|
300
|
-
def subdep_type
|
|
301
|
-
category =
|
|
302
|
-
TomlRB.parse(lockfile.content).fetch("package", []).
|
|
303
|
-
find { |dets| normalise(dets.fetch("name")) == dependency.name }.
|
|
304
|
-
fetch("category")
|
|
305
|
-
|
|
306
|
-
category == "dev" ? "dev-dependencies" : "dependencies"
|
|
307
|
-
end
|
|
308
|
-
|
|
309
284
|
def python_requirement_parser
|
|
310
285
|
@python_requirement_parser ||=
|
|
311
286
|
FileParser::PythonRequirementParser.new(
|
|
@@ -313,6 +288,13 @@ module Dependabot
|
|
|
313
288
|
)
|
|
314
289
|
end
|
|
315
290
|
|
|
291
|
+
def subdependency_type_parser
|
|
292
|
+
@subdependency_type_parser ||=
|
|
293
|
+
FileParser::PoetrySubdependencyTypeParser.new(
|
|
294
|
+
lockfile: lockfile
|
|
295
|
+
)
|
|
296
|
+
end
|
|
297
|
+
|
|
316
298
|
def language_version_manager
|
|
317
299
|
@language_version_manager ||=
|
|
318
300
|
LanguageVersionManager.new(
|
|
@@ -324,16 +306,12 @@ module Dependabot
|
|
|
324
306
|
dependency_files.find { |f| f.name == "pyproject.toml" }
|
|
325
307
|
end
|
|
326
308
|
|
|
327
|
-
def pyproject_lock
|
|
328
|
-
dependency_files.find { |f| f.name == "pyproject.lock" }
|
|
329
|
-
end
|
|
330
|
-
|
|
331
309
|
def poetry_lock
|
|
332
310
|
dependency_files.find { |f| f.name == "poetry.lock" }
|
|
333
311
|
end
|
|
334
312
|
|
|
335
313
|
def lockfile
|
|
336
|
-
poetry_lock
|
|
314
|
+
poetry_lock
|
|
337
315
|
end
|
|
338
316
|
|
|
339
317
|
def run_poetry_command(command, fingerprint: nil)
|
|
@@ -74,7 +74,7 @@ module Dependabot
|
|
|
74
74
|
requirements: requirements,
|
|
75
75
|
latest_resolvable_version: preferred_resolvable_version&.to_s,
|
|
76
76
|
update_strategy: requirements_update_strategy,
|
|
77
|
-
has_lockfile: !(pipfile_lock || poetry_lock
|
|
77
|
+
has_lockfile: !(pipfile_lock || poetry_lock).nil?
|
|
78
78
|
).updated_requirements
|
|
79
79
|
end
|
|
80
80
|
|
|
@@ -143,7 +143,7 @@ module Dependabot
|
|
|
143
143
|
|
|
144
144
|
def subdependency_resolver
|
|
145
145
|
return :pipenv if pipfile_lock
|
|
146
|
-
return :poetry if poetry_lock
|
|
146
|
+
return :poetry if poetry_lock
|
|
147
147
|
return :pip_compile if pip_compile_files.any?
|
|
148
148
|
|
|
149
149
|
raise "Claimed to be a sub-dependency, but no lockfile exists!"
|
|
@@ -315,10 +315,6 @@ module Dependabot
|
|
|
315
315
|
dependency_files.find { |f| f.name == "pyproject.toml" }
|
|
316
316
|
end
|
|
317
317
|
|
|
318
|
-
def pyproject_lock
|
|
319
|
-
dependency_files.find { |f| f.name == "pyproject.lock" }
|
|
320
|
-
end
|
|
321
|
-
|
|
322
318
|
def poetry_lock
|
|
323
319
|
dependency_files.find { |f| f.name == "poetry.lock" }
|
|
324
320
|
end
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: dependabot-python
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.227.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Dependabot
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2023-
|
|
11
|
+
date: 2023-08-18 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: dependabot-common
|
|
@@ -16,14 +16,14 @@ dependencies:
|
|
|
16
16
|
requirements:
|
|
17
17
|
- - '='
|
|
18
18
|
- !ruby/object:Gem::Version
|
|
19
|
-
version: 0.
|
|
19
|
+
version: 0.227.0
|
|
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.
|
|
26
|
+
version: 0.227.0
|
|
27
27
|
- !ruby/object:Gem::Dependency
|
|
28
28
|
name: debug
|
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -128,14 +128,14 @@ dependencies:
|
|
|
128
128
|
requirements:
|
|
129
129
|
- - "~>"
|
|
130
130
|
- !ruby/object:Gem::Version
|
|
131
|
-
version: 1.
|
|
131
|
+
version: 1.19.0
|
|
132
132
|
type: :development
|
|
133
133
|
prerelease: false
|
|
134
134
|
version_requirements: !ruby/object:Gem::Requirement
|
|
135
135
|
requirements:
|
|
136
136
|
- - "~>"
|
|
137
137
|
- !ruby/object:Gem::Version
|
|
138
|
-
version: 1.
|
|
138
|
+
version: 1.19.0
|
|
139
139
|
- !ruby/object:Gem::Dependency
|
|
140
140
|
name: stackprof
|
|
141
141
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -200,6 +200,7 @@ files:
|
|
|
200
200
|
- lib/dependabot/python/file_parser/pyproject_files_parser.rb
|
|
201
201
|
- lib/dependabot/python/file_parser/python_requirement_parser.rb
|
|
202
202
|
- lib/dependabot/python/file_parser/setup_file_parser.rb
|
|
203
|
+
- lib/dependabot/python/file_parser/subdependency_type_parser.rb
|
|
203
204
|
- lib/dependabot/python/file_updater.rb
|
|
204
205
|
- lib/dependabot/python/file_updater/pip_compile_file_updater.rb
|
|
205
206
|
- lib/dependabot/python/file_updater/pipfile_file_updater.rb
|
|
@@ -214,7 +215,6 @@ files:
|
|
|
214
215
|
- lib/dependabot/python/metadata_finder.rb
|
|
215
216
|
- lib/dependabot/python/name_normaliser.rb
|
|
216
217
|
- lib/dependabot/python/native_helpers.rb
|
|
217
|
-
- lib/dependabot/python/python_versions.rb
|
|
218
218
|
- lib/dependabot/python/requirement.rb
|
|
219
219
|
- lib/dependabot/python/requirement_parser.rb
|
|
220
220
|
- lib/dependabot/python/update_checker.rb
|
|
@@ -231,7 +231,7 @@ licenses:
|
|
|
231
231
|
- Nonstandard
|
|
232
232
|
metadata:
|
|
233
233
|
bug_tracker_uri: https://github.com/dependabot/dependabot-core/issues
|
|
234
|
-
changelog_uri: https://github.com/dependabot/dependabot-core/releases/tag/v0.
|
|
234
|
+
changelog_uri: https://github.com/dependabot/dependabot-core/releases/tag/v0.227.0
|
|
235
235
|
post_install_message:
|
|
236
236
|
rdoc_options: []
|
|
237
237
|
require_paths:
|
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Dependabot
|
|
4
|
-
module Python
|
|
5
|
-
module PythonVersions
|
|
6
|
-
PRE_INSTALLED_PYTHON_VERSIONS = %w(
|
|
7
|
-
3.11.4
|
|
8
|
-
).freeze
|
|
9
|
-
|
|
10
|
-
# Due to an OpenSSL issue we can only install the following versions in
|
|
11
|
-
# the Dependabot container.
|
|
12
|
-
# NOTE: When adding one version, always doublecheck for additional releases: https://www.python.org/downloads/
|
|
13
|
-
#
|
|
14
|
-
# WARNING: 3.9.3 is purposefully omitted as it was recalled: https://www.python.org/downloads/release/python-393/
|
|
15
|
-
SUPPORTED_VERSIONS = %w(
|
|
16
|
-
3.11.4 3.11.3 3.11.2 3.11.1 3.11.0
|
|
17
|
-
3.10.12 3.10.11 3.10.10 3.10.9 3.10.8 3.10.7 3.10.6 3.10.5 3.10.4 3.10.3 3.10.2 3.10.1 3.10.0
|
|
18
|
-
3.9.17 3.9.16 3.9.15 3.9.14 3.9.13 3.9.12 3.9.11 3.9.10 3.9.9 3.9.8 3.9.7 3.9.6 3.9.5 3.9.4 3.9.2 3.9.1 3.9.0
|
|
19
|
-
3.8.17 3.8.15 3.8.14 3.8.13 3.8.12 3.8.11 3.8.10 3.8.9 3.8.8 3.8.7 3.8.6 3.8.5 3.8.4 3.8.3 3.8.2 3.8.1 3.8.0
|
|
20
|
-
3.7.17 3.7.15 3.7.14 3.7.13 3.7.12 3.7.11 3.7.10 3.7.9 3.7.8 3.7.7 3.7.6 3.7.5 3.7.4 3.7.3 3.7.2 3.7.1 3.7.0
|
|
21
|
-
3.6.15 3.6.14 3.6.13 3.6.12 3.6.11 3.6.10 3.6.9 3.6.8 3.6.7 3.6.6 3.6.5 3.6.4 3.6.3 3.6.2 3.6.1 3.6.0
|
|
22
|
-
3.5.10 3.5.8 3.5.7 3.5.6 3.5.5 3.5.4 3.5.3
|
|
23
|
-
).freeze
|
|
24
|
-
|
|
25
|
-
# This list gets iterated through to find a valid version, so we have
|
|
26
|
-
# the pre-installed versions listed first.
|
|
27
|
-
SUPPORTED_VERSIONS_TO_ITERATE =
|
|
28
|
-
[
|
|
29
|
-
*PRE_INSTALLED_PYTHON_VERSIONS,
|
|
30
|
-
*SUPPORTED_VERSIONS
|
|
31
|
-
].freeze
|
|
32
|
-
end
|
|
33
|
-
end
|
|
34
|
-
end
|