dependabot-conda 0.325.1

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.
@@ -0,0 +1,196 @@
1
+ # typed: strict
2
+ # frozen_string_literal: true
3
+
4
+ require "sorbet-runtime"
5
+ require "dependabot/update_checkers"
6
+ require "dependabot/update_checkers/base"
7
+ require "dependabot/conda/version"
8
+ require "dependabot/conda/requirement"
9
+ require "dependabot/conda/python_package_classifier"
10
+
11
+ module Dependabot
12
+ module Conda
13
+ class UpdateChecker < Dependabot::UpdateCheckers::Base
14
+ extend T::Sig
15
+
16
+ sig do
17
+ params(
18
+ dependency: Dependabot::Dependency,
19
+ dependency_files: T::Array[Dependabot::DependencyFile],
20
+ credentials: T::Array[Dependabot::Credential],
21
+ repo_contents_path: T.nilable(String),
22
+ ignored_versions: T::Array[String],
23
+ raise_on_ignored: T::Boolean,
24
+ security_advisories: T::Array[Dependabot::SecurityAdvisory],
25
+ requirements_update_strategy: T.nilable(Dependabot::RequirementsUpdateStrategy),
26
+ dependency_group: T.nilable(Dependabot::DependencyGroup),
27
+ update_cooldown: T.nilable(Dependabot::Package::ReleaseCooldownOptions),
28
+ options: T::Hash[Symbol, T.untyped]
29
+ )
30
+ .void
31
+ end
32
+ def initialize(dependency:, dependency_files:, credentials:,
33
+ repo_contents_path: nil, ignored_versions: [],
34
+ raise_on_ignored: false, security_advisories: [],
35
+ requirements_update_strategy: nil, dependency_group: nil,
36
+ update_cooldown: nil, options: {})
37
+ super
38
+ @latest_version = T.let(nil, T.nilable(T.any(String, Dependabot::Version)))
39
+ @lowest_resolvable_security_fix_version = T.let(nil, T.nilable(Dependabot::Version))
40
+ @lowest_resolvable_security_fix_version_fetched = T.let(false, T::Boolean)
41
+ end
42
+
43
+ sig { override.returns(T.nilable(T.any(String, Dependabot::Version))) }
44
+ def latest_version
45
+ @latest_version ||= fetch_latest_version
46
+ end
47
+
48
+ sig { override.returns(T.nilable(T.any(String, Dependabot::Version))) }
49
+ def latest_resolvable_version_with_no_unlock
50
+ # For now, same as latest_version since we're not doing full dependency resolution
51
+ latest_version
52
+ end
53
+
54
+ sig { override.returns(T.nilable(T.any(String, Dependabot::Version))) }
55
+ def latest_resolvable_version
56
+ # For Phase 3, delegate to latest_version_finder
57
+ # This will be enhanced with actual conda search and PyPI integration
58
+ latest_version
59
+ end
60
+
61
+ sig { override.returns(T::Boolean) }
62
+ def up_to_date?
63
+ return true if latest_version.nil?
64
+
65
+ # If dependency has no version (range constraint like >=2.0),
66
+ # we can't determine if it's up-to-date, so assume it needs checking
67
+ return false if dependency.version.nil?
68
+
69
+ T.must(latest_version) <= Dependabot::Conda::Version.new(dependency.version)
70
+ end
71
+
72
+ sig { override.returns(T::Boolean) }
73
+ def requirements_unlocked_or_can_be?
74
+ # For conda, we don't have lock files, so requirements can always be updated
75
+ # This is unlike other ecosystems that have lock files (package-lock.json, Pipfile.lock, etc.)
76
+ true
77
+ end
78
+
79
+ sig { override.returns(T.nilable(Dependabot::Version)) }
80
+ def lowest_security_fix_version
81
+ latest_version_finder.lowest_security_fix_version
82
+ end
83
+
84
+ sig { override.returns(T.nilable(Dependabot::Version)) }
85
+ def lowest_resolvable_security_fix_version
86
+ raise "Dependency not vulnerable!" unless vulnerable?
87
+
88
+ return @lowest_resolvable_security_fix_version if @lowest_resolvable_security_fix_version_fetched
89
+
90
+ @lowest_resolvable_security_fix_version = fetch_lowest_resolvable_security_fix_version
91
+ @lowest_resolvable_security_fix_version_fetched = true
92
+ @lowest_resolvable_security_fix_version
93
+ end
94
+
95
+ sig { override.returns(T::Array[T::Hash[Symbol, T.untyped]]) }
96
+ def updated_requirements
97
+ target_version = preferred_resolvable_version
98
+ return dependency.requirements unless target_version
99
+
100
+ dependency.requirements.map do |req|
101
+ req.merge(
102
+ requirement: update_requirement_string(
103
+ req[:requirement] || "=#{dependency.version}",
104
+ target_version.to_s
105
+ )
106
+ )
107
+ end
108
+ end
109
+
110
+ private
111
+
112
+ sig { returns(T.nilable(T.any(String, Dependabot::Version))) }
113
+ def fetch_latest_version
114
+ latest_version_finder.latest_version
115
+ end
116
+
117
+ sig { returns(LatestVersionFinder) }
118
+ def latest_version_finder
119
+ @latest_version_finder ||= T.let(
120
+ LatestVersionFinder.new(
121
+ dependency: dependency,
122
+ dependency_files: dependency_files,
123
+ credentials: credentials,
124
+ ignored_versions: ignored_versions,
125
+ raise_on_ignored: @raise_on_ignored,
126
+ cooldown_options: @update_cooldown,
127
+ security_advisories: security_advisories
128
+ ),
129
+ T.nilable(LatestVersionFinder)
130
+ )
131
+ end
132
+
133
+ sig { returns(T.nilable(Dependabot::Version)) }
134
+ def fetch_lowest_resolvable_security_fix_version
135
+ # Delegate to latest_version_finder for security fix resolution
136
+ # This leverages Python ecosystem's security advisory infrastructure
137
+ latest_version_finder.lowest_security_fix_version
138
+ end
139
+
140
+ sig { override.returns(T::Boolean) }
141
+ def latest_version_resolvable_with_full_unlock?
142
+ # For Phase 3, return false as placeholder since we're not doing full dependency resolution
143
+ false
144
+ end
145
+
146
+ sig { override.returns(T::Array[Dependabot::Dependency]) }
147
+ def updated_dependencies_after_full_unlock
148
+ # For Phase 3, return empty array as placeholder
149
+ []
150
+ end
151
+
152
+ sig { params(requirement_string: String, new_version: String).returns(String) }
153
+ def update_requirement_string(requirement_string, new_version)
154
+ # Parse the current requirement to preserve the operator type
155
+ case requirement_string
156
+ when /^=([0-9])/
157
+ # Conda exact version: =1.26 -> =2.3.2
158
+ "=#{new_version}"
159
+ when /^==([0-9])/
160
+ # Pip exact version: ==1.26 -> ==2.3.2
161
+ "==#{new_version}"
162
+ when /^>=([0-9])/
163
+ # Range constraint: preserve as range but update to new version
164
+ ">=#{new_version}"
165
+ when /^>([0-9])/
166
+ # Greater than: >1.26 -> >2.3.2
167
+ ">#{new_version}"
168
+ when /^<=([0-9])/
169
+ # Less than or equal: keep as is (shouldn't be updated)
170
+ requirement_string
171
+ when /^<([0-9])/
172
+ # Less than: keep as is (shouldn't be updated)
173
+ requirement_string
174
+ when /^!=([0-9])/
175
+ # Not equal: keep as is
176
+ requirement_string
177
+ when /^~=([0-9])/
178
+ # Compatible release: ~=1.26 -> ~=2.3.2
179
+ "~=#{new_version}"
180
+ else
181
+ # Default to conda-style equality for unknown patterns
182
+ "=#{new_version}"
183
+ end
184
+ end
185
+
186
+ sig { params(package_name: String).returns(T::Boolean) }
187
+ def python_package?(package_name)
188
+ PythonPackageClassifier.python_package?(package_name)
189
+ end
190
+ end
191
+ end
192
+ end
193
+
194
+ require_relative "update_checker/latest_version_finder"
195
+
196
+ Dependabot::UpdateCheckers.register("conda", Dependabot::Conda::UpdateChecker)
@@ -0,0 +1,23 @@
1
+ # typed: strong
2
+ # frozen_string_literal: true
3
+
4
+ require "sorbet-runtime"
5
+ require "dependabot/python/version"
6
+
7
+ module Dependabot
8
+ module Conda
9
+ # Conda version handling delegates to Python version since conda primarily manages Python packages
10
+ class Version < Dependabot::Python::Version
11
+ extend T::Sig
12
+
13
+ # Conda supports the same version formats as Python packages from PyPI
14
+ # This includes standard semver, epochs, pre-releases, dev releases, etc.
15
+ sig { override.params(version: VersionParameter).returns(Dependabot::Conda::Version) }
16
+ def self.new(version)
17
+ T.cast(super, Dependabot::Conda::Version)
18
+ end
19
+ end
20
+ end
21
+ end
22
+
23
+ Dependabot::Utils.register_version_class("conda", Dependabot::Conda::Version)
@@ -0,0 +1,35 @@
1
+ # typed: strict
2
+ # frozen_string_literal: true
3
+
4
+ # These all need to be required so the various classes can be registered in a
5
+ # lookup table of package manager names to concrete classes.
6
+ require "dependabot/conda/file_fetcher"
7
+ require "dependabot/conda/file_parser"
8
+ require "dependabot/conda/update_checker"
9
+ require "dependabot/conda/file_updater"
10
+ require "dependabot/conda/metadata_finder"
11
+ require "dependabot/conda/requirement"
12
+ require "dependabot/conda/version"
13
+ require "dependabot/conda/name_normaliser"
14
+
15
+ require "dependabot/pull_request_creator/labeler"
16
+ Dependabot::PullRequestCreator::Labeler
17
+ .register_label_details("conda", name: "conda", colour: "44a047")
18
+
19
+ require "dependabot/dependency"
20
+ # Conda manages Python packages, so use the same production check as Python
21
+ Dependabot::Dependency.register_production_check(
22
+ "conda",
23
+ lambda do |groups|
24
+ return true if groups.empty?
25
+ return true if groups.include?("default")
26
+ return true if groups.include?("dependencies")
27
+
28
+ groups.include?("pip")
29
+ end
30
+ )
31
+
32
+ Dependabot::Dependency.register_name_normaliser(
33
+ "conda",
34
+ ->(name) { Dependabot::Conda::NameNormaliser.normalise(name) }
35
+ )
metadata ADDED
@@ -0,0 +1,294 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: dependabot-conda
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.325.1
5
+ platform: ruby
6
+ authors:
7
+ - Dependabot
8
+ bindir: bin
9
+ cert_chain: []
10
+ date: 1980-01-02 00:00:00.000000000 Z
11
+ dependencies:
12
+ - !ruby/object:Gem::Dependency
13
+ name: dependabot-common
14
+ requirement: !ruby/object:Gem::Requirement
15
+ requirements:
16
+ - - '='
17
+ - !ruby/object:Gem::Version
18
+ version: 0.325.1
19
+ type: :runtime
20
+ prerelease: false
21
+ version_requirements: !ruby/object:Gem::Requirement
22
+ requirements:
23
+ - - '='
24
+ - !ruby/object:Gem::Version
25
+ version: 0.325.1
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.325.1
33
+ type: :runtime
34
+ prerelease: false
35
+ version_requirements: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - '='
38
+ - !ruby/object:Gem::Version
39
+ version: 0.325.1
40
+ - !ruby/object:Gem::Dependency
41
+ name: debug
42
+ requirement: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - "~>"
45
+ - !ruby/object:Gem::Version
46
+ version: '1.9'
47
+ type: :development
48
+ prerelease: false
49
+ version_requirements: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - "~>"
52
+ - !ruby/object:Gem::Version
53
+ version: '1.9'
54
+ - !ruby/object:Gem::Dependency
55
+ name: gpgme
56
+ requirement: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - "~>"
59
+ - !ruby/object:Gem::Version
60
+ version: '2.0'
61
+ type: :development
62
+ prerelease: false
63
+ version_requirements: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - "~>"
66
+ - !ruby/object:Gem::Version
67
+ version: '2.0'
68
+ - !ruby/object:Gem::Dependency
69
+ name: rake
70
+ requirement: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - "~>"
73
+ - !ruby/object:Gem::Version
74
+ version: '13.2'
75
+ type: :development
76
+ prerelease: false
77
+ version_requirements: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - "~>"
80
+ - !ruby/object:Gem::Version
81
+ version: '13.2'
82
+ - !ruby/object:Gem::Dependency
83
+ name: rspec
84
+ requirement: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - "~>"
87
+ - !ruby/object:Gem::Version
88
+ version: '3.12'
89
+ type: :development
90
+ prerelease: false
91
+ version_requirements: !ruby/object:Gem::Requirement
92
+ requirements:
93
+ - - "~>"
94
+ - !ruby/object:Gem::Version
95
+ version: '3.12'
96
+ - !ruby/object:Gem::Dependency
97
+ name: rspec-its
98
+ requirement: !ruby/object:Gem::Requirement
99
+ requirements:
100
+ - - "~>"
101
+ - !ruby/object:Gem::Version
102
+ version: '1.3'
103
+ type: :development
104
+ prerelease: false
105
+ version_requirements: !ruby/object:Gem::Requirement
106
+ requirements:
107
+ - - "~>"
108
+ - !ruby/object:Gem::Version
109
+ version: '1.3'
110
+ - !ruby/object:Gem::Dependency
111
+ name: rspec-sorbet
112
+ requirement: !ruby/object:Gem::Requirement
113
+ requirements:
114
+ - - "~>"
115
+ - !ruby/object:Gem::Version
116
+ version: '1.9'
117
+ type: :development
118
+ prerelease: false
119
+ version_requirements: !ruby/object:Gem::Requirement
120
+ requirements:
121
+ - - "~>"
122
+ - !ruby/object:Gem::Version
123
+ version: '1.9'
124
+ - !ruby/object:Gem::Dependency
125
+ name: rubocop
126
+ requirement: !ruby/object:Gem::Requirement
127
+ requirements:
128
+ - - "~>"
129
+ - !ruby/object:Gem::Version
130
+ version: '1.67'
131
+ type: :development
132
+ prerelease: false
133
+ version_requirements: !ruby/object:Gem::Requirement
134
+ requirements:
135
+ - - "~>"
136
+ - !ruby/object:Gem::Version
137
+ version: '1.67'
138
+ - !ruby/object:Gem::Dependency
139
+ name: rubocop-performance
140
+ requirement: !ruby/object:Gem::Requirement
141
+ requirements:
142
+ - - "~>"
143
+ - !ruby/object:Gem::Version
144
+ version: '1.22'
145
+ type: :development
146
+ prerelease: false
147
+ version_requirements: !ruby/object:Gem::Requirement
148
+ requirements:
149
+ - - "~>"
150
+ - !ruby/object:Gem::Version
151
+ version: '1.22'
152
+ - !ruby/object:Gem::Dependency
153
+ name: rubocop-rspec
154
+ requirement: !ruby/object:Gem::Requirement
155
+ requirements:
156
+ - - "~>"
157
+ - !ruby/object:Gem::Version
158
+ version: '2.29'
159
+ type: :development
160
+ prerelease: false
161
+ version_requirements: !ruby/object:Gem::Requirement
162
+ requirements:
163
+ - - "~>"
164
+ - !ruby/object:Gem::Version
165
+ version: '2.29'
166
+ - !ruby/object:Gem::Dependency
167
+ name: rubocop-sorbet
168
+ requirement: !ruby/object:Gem::Requirement
169
+ requirements:
170
+ - - "~>"
171
+ - !ruby/object:Gem::Version
172
+ version: '0.8'
173
+ type: :development
174
+ prerelease: false
175
+ version_requirements: !ruby/object:Gem::Requirement
176
+ requirements:
177
+ - - "~>"
178
+ - !ruby/object:Gem::Version
179
+ version: '0.8'
180
+ - !ruby/object:Gem::Dependency
181
+ name: simplecov
182
+ requirement: !ruby/object:Gem::Requirement
183
+ requirements:
184
+ - - "~>"
185
+ - !ruby/object:Gem::Version
186
+ version: '0.22'
187
+ type: :development
188
+ prerelease: false
189
+ version_requirements: !ruby/object:Gem::Requirement
190
+ requirements:
191
+ - - "~>"
192
+ - !ruby/object:Gem::Version
193
+ version: '0.22'
194
+ - !ruby/object:Gem::Dependency
195
+ name: turbo_tests
196
+ requirement: !ruby/object:Gem::Requirement
197
+ requirements:
198
+ - - "~>"
199
+ - !ruby/object:Gem::Version
200
+ version: 2.2.5
201
+ type: :development
202
+ prerelease: false
203
+ version_requirements: !ruby/object:Gem::Requirement
204
+ requirements:
205
+ - - "~>"
206
+ - !ruby/object:Gem::Version
207
+ version: 2.2.5
208
+ - !ruby/object:Gem::Dependency
209
+ name: vcr
210
+ requirement: !ruby/object:Gem::Requirement
211
+ requirements:
212
+ - - "~>"
213
+ - !ruby/object:Gem::Version
214
+ version: '6.1'
215
+ type: :development
216
+ prerelease: false
217
+ version_requirements: !ruby/object:Gem::Requirement
218
+ requirements:
219
+ - - "~>"
220
+ - !ruby/object:Gem::Version
221
+ version: '6.1'
222
+ - !ruby/object:Gem::Dependency
223
+ name: webmock
224
+ requirement: !ruby/object:Gem::Requirement
225
+ requirements:
226
+ - - "~>"
227
+ - !ruby/object:Gem::Version
228
+ version: '3.18'
229
+ type: :development
230
+ prerelease: false
231
+ version_requirements: !ruby/object:Gem::Requirement
232
+ requirements:
233
+ - - "~>"
234
+ - !ruby/object:Gem::Version
235
+ version: '3.18'
236
+ - !ruby/object:Gem::Dependency
237
+ name: webrick
238
+ requirement: !ruby/object:Gem::Requirement
239
+ requirements:
240
+ - - "~>"
241
+ - !ruby/object:Gem::Version
242
+ version: '1.9'
243
+ type: :development
244
+ prerelease: false
245
+ version_requirements: !ruby/object:Gem::Requirement
246
+ requirements:
247
+ - - "~>"
248
+ - !ruby/object:Gem::Version
249
+ version: '1.9'
250
+ description: Dependabot-Conda provides support for bumping Python packages in Conda
251
+ environment.yml files via Dependabot. If you want support for multiple package managers,
252
+ you probably want the meta-gem dependabot-omnibus.
253
+ email: opensource@github.com
254
+ executables: []
255
+ extensions: []
256
+ extra_rdoc_files: []
257
+ files:
258
+ - lib/dependabot/conda.rb
259
+ - lib/dependabot/conda/file_fetcher.rb
260
+ - lib/dependabot/conda/file_parser.rb
261
+ - lib/dependabot/conda/file_updater.rb
262
+ - lib/dependabot/conda/metadata_finder.rb
263
+ - lib/dependabot/conda/name_normaliser.rb
264
+ - lib/dependabot/conda/package_manager.rb
265
+ - lib/dependabot/conda/python_package_classifier.rb
266
+ - lib/dependabot/conda/requirement.rb
267
+ - lib/dependabot/conda/update_checker.rb
268
+ - lib/dependabot/conda/update_checker/latest_version_finder.rb
269
+ - lib/dependabot/conda/update_checker/requirement_translator.rb
270
+ - lib/dependabot/conda/version.rb
271
+ homepage: https://github.com/dependabot/dependabot-core
272
+ licenses:
273
+ - MIT
274
+ metadata:
275
+ bug_tracker_uri: https://github.com/dependabot/dependabot-core/issues
276
+ changelog_uri: https://github.com/dependabot/dependabot-core/releases/tag/v0.325.1
277
+ rdoc_options: []
278
+ require_paths:
279
+ - lib
280
+ required_ruby_version: !ruby/object:Gem::Requirement
281
+ requirements:
282
+ - - ">="
283
+ - !ruby/object:Gem::Version
284
+ version: 3.3.0
285
+ required_rubygems_version: !ruby/object:Gem::Requirement
286
+ requirements:
287
+ - - ">="
288
+ - !ruby/object:Gem::Version
289
+ version: 3.3.0
290
+ requirements: []
291
+ rubygems_version: 3.6.9
292
+ specification_version: 4
293
+ summary: Provides Dependabot support for Conda
294
+ test_files: []