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.
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.349.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.349.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.349.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/package_details_fetcher.rb
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.349.0
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