dependabot-core 0.89.5 → 0.90.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.
@@ -1,56 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "dependabot/metadata_finders/base"
4
- require "dependabot/utils/go/path_converter"
5
-
6
- module Dependabot
7
- module MetadataFinders
8
- module Go
9
- class Dep < Dependabot::MetadataFinders::Base
10
- private
11
-
12
- def look_up_source
13
- return look_up_git_dependency_source if git_dependency?
14
-
15
- path_str = (specified_source_string || dependency.name)
16
- url = Dependabot::Utils::Go::PathConverter.
17
- git_url_for_path_without_go_helper(path_str)
18
- Source.from_url(url) if url
19
- end
20
-
21
- def git_dependency?
22
- return false unless declared_source_details
23
-
24
- dependency_type =
25
- declared_source_details.fetch(:type, nil) ||
26
- declared_source_details.fetch("type")
27
-
28
- dependency_type == "git"
29
- end
30
-
31
- def look_up_git_dependency_source
32
- specified_url =
33
- declared_source_details.fetch(:url, nil) ||
34
- declared_source_details.fetch("url")
35
-
36
- Source.from_url(specified_url)
37
- end
38
-
39
- def specified_source_string
40
- declared_source_details&.fetch(:source, nil) ||
41
- declared_source_details&.fetch("source", nil)
42
- end
43
-
44
- def declared_source_details
45
- sources = dependency.requirements.
46
- map { |r| r.fetch(:source) }.
47
- uniq.compact
48
-
49
- raise "Multiple sources! #{sources.join(', ')}" if sources.count > 1
50
-
51
- sources.first
52
- end
53
- end
54
- end
55
- end
56
- end
@@ -1,311 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "toml-rb"
4
- require "dependabot/update_checkers/base"
5
-
6
- module Dependabot
7
- module UpdateCheckers
8
- module Go
9
- class Dep < Dependabot::UpdateCheckers::Base
10
- require_relative "dep/file_preparer"
11
- require_relative "dep/latest_version_finder"
12
- require_relative "dep/requirements_updater"
13
- require_relative "dep/version_resolver"
14
-
15
- def latest_version
16
- @latest_version ||=
17
- LatestVersionFinder.new(
18
- dependency: dependency,
19
- dependency_files: dependency_files,
20
- credentials: credentials,
21
- ignored_versions: ignored_versions
22
- ).latest_version
23
- end
24
-
25
- def latest_resolvable_version
26
- @latest_resolvable_version ||=
27
- if modules_dependency?
28
- latest_version
29
- elsif git_dependency?
30
- latest_resolvable_version_for_git_dependency
31
- else
32
- latest_resolvable_released_version(unlock_requirement: true)
33
- end
34
- end
35
-
36
- def latest_resolvable_version_with_no_unlock
37
- @latest_resolvable_version_with_no_unlock ||=
38
- if git_dependency?
39
- latest_resolvable_commit_with_unchanged_git_source
40
- else
41
- latest_resolvable_released_version(unlock_requirement: false)
42
- end
43
- end
44
-
45
- def updated_requirements
46
- @updated_requirements ||=
47
- RequirementsUpdater.new(
48
- requirements: dependency.requirements,
49
- updated_source: updated_source,
50
- update_strategy: requirements_update_strategy,
51
- latest_version: latest_version&.to_s,
52
- latest_resolvable_version: latest_resolvable_version&.to_s
53
- ).updated_requirements
54
- end
55
-
56
- def requirements_update_strategy
57
- # If passed in as an option (in the base class) honour that option
58
- if @requirements_update_strategy
59
- return @requirements_update_strategy.to_sym
60
- end
61
-
62
- # Otherwise, widen ranges for libraries and bump versions for apps
63
- library? ? :widen_ranges : :bump_versions
64
- end
65
-
66
- private
67
-
68
- def latest_version_resolvable_with_full_unlock?
69
- # Full unlock checks aren't implemented for Go (yet)
70
- false
71
- end
72
-
73
- def updated_dependencies_after_full_unlock
74
- raise NotImplementedError
75
- end
76
-
77
- # Override the base class's check for whether this is a git dependency,
78
- # since not all dep git dependencies have a SHA version (sometimes their
79
- # version is the tag)
80
- def existing_version_is_sha?
81
- git_dependency?
82
- end
83
-
84
- def library?
85
- dependency_files.none? { |f| f.type == "package_main" }
86
- end
87
-
88
- # rubocop:disable Metrics/CyclomaticComplexity
89
- # rubocop:disable Metrics/PerceivedComplexity
90
- def latest_resolvable_version_for_git_dependency
91
- return latest_version if modules_dependency?
92
-
93
- latest_release =
94
- begin
95
- latest_resolvable_released_version(unlock_requirement: true)
96
- rescue SharedHelpers::HelperSubprocessFailed => error
97
- raise unless error.message.include?("Solving failure")
98
- end
99
-
100
- # If there's a resolvable release that includes the current pinned
101
- # ref or that the current branch is behind, we switch to that release.
102
- return latest_release if git_branch_or_ref_in_release?(latest_release)
103
-
104
- # Otherwise, if the gem isn't pinned, the latest version is just the
105
- # latest commit for the specified branch.
106
- unless git_commit_checker.pinned?
107
- return latest_resolvable_commit_with_unchanged_git_source
108
- end
109
-
110
- # If the dependency is pinned to a tag that looks like a version then
111
- # we want to update that tag.
112
- if git_commit_checker.pinned_ref_looks_like_version? &&
113
- latest_git_tag_is_resolvable?
114
- new_tag = git_commit_checker.local_tag_for_latest_version
115
- return version_from_tag(new_tag)
116
- end
117
-
118
- # If the dependency is pinned to a tag that doesn't look like a
119
- # version then there's nothing we can do.
120
- nil
121
- end
122
- # rubocop:enable Metrics/CyclomaticComplexity
123
- # rubocop:enable Metrics/PerceivedComplexity
124
-
125
- def version_from_tag(tag)
126
- # To compare with the current version we either use the commit SHA
127
- # (if that's what the parser picked up) of the tag name.
128
- if dependency.version&.match?(/^[0-9a-f]{40}$/)
129
- return tag&.fetch(:commit_sha)
130
- end
131
-
132
- tag&.fetch(:tag)
133
- end
134
-
135
- def latest_resolvable_commit_with_unchanged_git_source
136
- if @commit_lookup_attempted
137
- return @latest_resolvable_commit_with_unchanged_git_source
138
- end
139
-
140
- @commit_lookup_attempted = true
141
- @latest_resolvable_commit_with_unchanged_git_source ||=
142
- begin
143
- prepared_files = FilePreparer.new(
144
- dependency_files: dependency_files,
145
- dependency: dependency,
146
- unlock_requirement: false,
147
- remove_git_source: false,
148
- latest_allowable_version: latest_version
149
- ).prepared_dependency_files
150
-
151
- VersionResolver.new(
152
- dependency: dependency,
153
- dependency_files: prepared_files,
154
- credentials: credentials
155
- ).latest_resolvable_version
156
- end
157
- rescue SharedHelpers::HelperSubprocessFailed => error
158
- # This should rescue resolvability errors in future
159
- raise unless error.message.include?("Solving failure")
160
- end
161
-
162
- def latest_resolvable_released_version(unlock_requirement:)
163
- @latest_resolvable_released_version ||= {}
164
- @latest_resolvable_released_version[unlock_requirement] ||=
165
- begin
166
- prepared_files = FilePreparer.new(
167
- dependency_files: dependency_files,
168
- dependency: dependency,
169
- unlock_requirement: unlock_requirement,
170
- remove_git_source: git_dependency?,
171
- latest_allowable_version: latest_version
172
- ).prepared_dependency_files
173
-
174
- VersionResolver.new(
175
- dependency: dependency,
176
- dependency_files: prepared_files,
177
- credentials: credentials
178
- ).latest_resolvable_version
179
- end
180
- end
181
-
182
- def latest_git_tag_is_resolvable?
183
- return @git_tag_resolvable if @latest_git_tag_is_resolvable_checked
184
-
185
- @latest_git_tag_is_resolvable_checked = true
186
-
187
- return false if git_commit_checker.local_tag_for_latest_version.nil?
188
-
189
- replacement_tag = git_commit_checker.local_tag_for_latest_version
190
-
191
- prepared_files = FilePreparer.new(
192
- dependency: dependency,
193
- dependency_files: dependency_files,
194
- unlock_requirement: false,
195
- remove_git_source: false,
196
- replacement_git_pin: replacement_tag.fetch(:tag)
197
- ).prepared_dependency_files
198
-
199
- VersionResolver.new(
200
- dependency: dependency,
201
- dependency_files: prepared_files,
202
- credentials: credentials
203
- ).latest_resolvable_version
204
-
205
- @git_tag_resolvable = true
206
- rescue SharedHelpers::HelperSubprocessFailed => error
207
- # This should rescue resolvability errors in future
208
- raise unless error.message.include?("Solving failure")
209
-
210
- @git_tag_resolvable = false
211
- end
212
-
213
- def updated_source
214
- # Never need to update source, unless a git_dependency
215
- return dependency_source_details unless git_dependency?
216
-
217
- # Source becomes `nil` if switching to default rubygems
218
- return default_source if should_switch_source_from_ref_to_release?
219
-
220
- # Update the git tag if updating a pinned version
221
- if git_commit_checker.pinned_ref_looks_like_version? &&
222
- latest_git_tag_is_resolvable?
223
- new_tag = git_commit_checker.local_tag_for_latest_version
224
- return dependency_source_details.merge(ref: new_tag.fetch(:tag))
225
- end
226
-
227
- # Otherwise return the original source
228
- dependency_source_details
229
- end
230
-
231
- def dependency_source_details
232
- sources =
233
- dependency.requirements.map { |r| r.fetch(:source) }.uniq.compact
234
-
235
- raise "Multiple sources! #{sources.join(', ')}" if sources.count > 1
236
-
237
- sources.first
238
- end
239
-
240
- def should_switch_source_from_ref_to_release?
241
- return false unless git_dependency?
242
- return false if latest_resolvable_version_for_git_dependency.nil?
243
-
244
- Gem::Version.correct?(latest_resolvable_version_for_git_dependency)
245
- end
246
-
247
- def modules_dependency?
248
- # If dep is being used then we use that to determine the latest
249
- # version we can update to (since it will have resolvability
250
- # requirements, whereas Go modules won't)
251
- !dependency_in_gopkg_lock?
252
- end
253
-
254
- def dependency_in_gopkg_lock?
255
- lockfile = dependency_files.find { |f| f.name == "Gopkg.lock" }
256
- return false unless lockfile
257
-
258
- parsed_file(lockfile).fetch("projects", []).any? do |details|
259
- details.fetch("name") == dependency.name
260
- end
261
- end
262
-
263
- def git_dependency?
264
- git_commit_checker.git_dependency?
265
- end
266
-
267
- def default_source
268
- if modules_dependency?
269
- return { type: "default", source: dependency.name }
270
- end
271
-
272
- original_declaration =
273
- parsed_file(manifest).
274
- values_at(*FileParsers::Go::Dep::REQUIREMENT_TYPES).
275
- flatten.compact.
276
- find { |d| d["name"] == dependency.name }
277
-
278
- {
279
- type: "default",
280
- source:
281
- original_declaration&.fetch("source", nil) || dependency.name
282
- }
283
- end
284
-
285
- def git_branch_or_ref_in_release?(release)
286
- return false unless release
287
-
288
- git_commit_checker.branch_or_ref_in_release?(release)
289
- end
290
-
291
- def parsed_file(file)
292
- @parsed_file ||= {}
293
- @parsed_file[file.name] ||= TomlRB.parse(file.content)
294
- end
295
-
296
- def manifest
297
- @manifest ||= dependency_files.find { |f| f.name == "Gopkg.toml" }
298
- end
299
-
300
- def git_commit_checker
301
- @git_commit_checker ||=
302
- GitCommitChecker.new(
303
- dependency: dependency,
304
- credentials: credentials,
305
- ignored_versions: ignored_versions
306
- )
307
- end
308
- end
309
- end
310
- end
311
- end
@@ -1,221 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "toml-rb"
4
- require "dependabot/dependency_file"
5
- require "dependabot/file_parsers/go/dep"
6
- require "dependabot/update_checkers/go/dep"
7
-
8
- module Dependabot
9
- module UpdateCheckers
10
- module Go
11
- class Dep
12
- # This class takes a set of dependency files and prepares them for use
13
- # in UpdateCheckers::Go::Dep.
14
- class FilePreparer
15
- def initialize(dependency_files:, dependency:,
16
- remove_git_source: false,
17
- unlock_requirement: true,
18
- replacement_git_pin: nil,
19
- latest_allowable_version: nil)
20
- @dependency_files = dependency_files
21
- @dependency = dependency
22
- @unlock_requirement = unlock_requirement
23
- @remove_git_source = remove_git_source
24
- @replacement_git_pin = replacement_git_pin
25
- @latest_allowable_version = latest_allowable_version
26
- end
27
-
28
- def prepared_dependency_files
29
- files = []
30
-
31
- files << manifest_for_update_check
32
- files << lockfile if lockfile
33
-
34
- files
35
- end
36
-
37
- private
38
-
39
- attr_reader :dependency_files, :dependency, :replacement_git_pin,
40
- :latest_allowable_version
41
-
42
- def unlock_requirement?
43
- @unlock_requirement
44
- end
45
-
46
- def remove_git_source?
47
- @remove_git_source
48
- end
49
-
50
- def replace_git_pin?
51
- !replacement_git_pin.nil?
52
- end
53
-
54
- def manifest_for_update_check
55
- DependencyFile.new(
56
- name: manifest.name,
57
- content: manifest_content_for_update_check(manifest),
58
- directory: manifest.directory
59
- )
60
- end
61
-
62
- def manifest_content_for_update_check(file)
63
- content = file.content
64
-
65
- content = remove_git_source(content) if remove_git_source?
66
- content = replace_git_pin(content) if replace_git_pin?
67
- content = replace_version_constraint(content, file.name)
68
- content = add_fsnotify_override(content)
69
-
70
- content
71
- end
72
-
73
- def remove_git_source(content)
74
- parsed_manifest = TomlRB.parse(content)
75
-
76
- FileParsers::Go::Dep::REQUIREMENT_TYPES.each do |type|
77
- (parsed_manifest[type] || []).each do |details|
78
- next unless details["name"] == dependency.name
79
-
80
- details.delete("revision")
81
- details.delete("branch")
82
- end
83
- end
84
-
85
- TomlRB.dump(parsed_manifest)
86
- end
87
-
88
- def replace_git_pin(content)
89
- parsed_manifest = TomlRB.parse(content)
90
-
91
- FileParsers::Go::Dep::REQUIREMENT_TYPES.each do |type|
92
- (parsed_manifest[type] || []).each do |details|
93
- next unless details["name"] == dependency.name
94
-
95
- raise "Invalid details! #{details}" if details["branch"]
96
-
97
- if details["version"]
98
- details["version"] = replacement_git_pin
99
- else
100
- details["revision"] = replacement_git_pin
101
- end
102
- end
103
- end
104
-
105
- TomlRB.dump(parsed_manifest)
106
- end
107
-
108
- # Note: We don't need to care about formatting in this method, since
109
- # we're only using the manifest to find the latest resolvable version
110
- def replace_version_constraint(content, filename)
111
- parsed_manifest = TomlRB.parse(content)
112
-
113
- FileParsers::Go::Dep::REQUIREMENT_TYPES.each do |type|
114
- (parsed_manifest[type] || []).each do |details|
115
- next unless details["name"] == dependency.name
116
- next if details["revision"] || details["branch"]
117
- next if replacement_git_pin
118
-
119
- updated_req = temporary_requirement_for_resolution(filename)
120
-
121
- details["version"] = updated_req
122
- end
123
- end
124
-
125
- TomlRB.dump(parsed_manifest)
126
- end
127
-
128
- # A dep bug means we have to specify a source for gopkg.in/fsnotify.v1
129
- # or we get `panic: version queue is empty` errors
130
- def add_fsnotify_override(content)
131
- parsed_manifest = TomlRB.parse(content)
132
-
133
- overrides = parsed_manifest.fetch("override", [])
134
- dep_name = "gopkg.in/fsnotify.v1"
135
-
136
- override = overrides.find { |s| s["name"] == dep_name }
137
- if override.nil?
138
- override = { "name" => dep_name }
139
- overrides << override
140
- end
141
-
142
- unless override["source"]
143
- override["source"] = "gopkg.in/fsnotify/fsnotify.v1"
144
- end
145
-
146
- parsed_manifest["override"] = overrides
147
- TomlRB.dump(parsed_manifest)
148
- end
149
-
150
- def temporary_requirement_for_resolution(filename)
151
- original_req = dependency.requirements.
152
- find { |r| r.fetch(:file) == filename }&.
153
- fetch(:requirement)
154
-
155
- lower_bound_req =
156
- if original_req && !unlock_requirement?
157
- original_req
158
- else
159
- ">= #{lower_bound_version}"
160
- end
161
-
162
- unless latest_allowable_version &&
163
- version_class.correct?(latest_allowable_version) &&
164
- version_class.new(latest_allowable_version) >=
165
- version_class.new(lower_bound_version)
166
- return lower_bound_req
167
- end
168
-
169
- lower_bound_req + ", <= #{latest_allowable_version}"
170
- end
171
-
172
- def lower_bound_version
173
- @lower_bound_version ||=
174
- if version_from_lockfile
175
- version_from_lockfile
176
- else
177
- version_from_requirement =
178
- dependency.requirements.map { |r| r.fetch(:requirement) }.
179
- compact.
180
- flat_map { |req_str| requirement_class.new(req_str) }.
181
- flat_map(&:requirements).
182
- reject { |req_array| req_array.first.start_with?("<") }.
183
- map(&:last).
184
- max&.to_s
185
-
186
- version_from_requirement || 0
187
- end
188
- end
189
-
190
- def version_from_lockfile
191
- return unless lockfile
192
-
193
- TomlRB.parse(lockfile.content).
194
- fetch("projects", []).
195
- find { |p| p["name"] == dependency.name }&.
196
- fetch("version", nil)&.
197
- sub(/^v?/, "")
198
- end
199
-
200
- def version_class
201
- Utils.version_class_for_package_manager(dependency.package_manager)
202
- end
203
-
204
- def requirement_class
205
- Utils.requirement_class_for_package_manager(
206
- dependency.package_manager
207
- )
208
- end
209
-
210
- def manifest
211
- @manifest ||= dependency_files.find { |f| f.name == "Gopkg.toml" }
212
- end
213
-
214
- def lockfile
215
- @lockfile ||= dependency_files.find { |f| f.name == "Gopkg.lock" }
216
- end
217
- end
218
- end
219
- end
220
- end
221
- end