dependabot-core 0.87.15 → 0.88.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (33) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +4 -0
  3. data/lib/dependabot/file_fetchers.rb +0 -2
  4. data/lib/dependabot/file_parsers.rb +0 -2
  5. data/lib/dependabot/file_updaters.rb +0 -2
  6. data/lib/dependabot/metadata_finders.rb +0 -2
  7. data/lib/dependabot/pull_request_creator/message_builder.rb +1 -1
  8. data/lib/dependabot/update_checkers.rb +0 -2
  9. data/lib/dependabot/update_checkers/php/composer/version_resolver.rb +3 -2
  10. data/lib/dependabot/utils.rb +0 -4
  11. data/lib/dependabot/version.rb +1 -1
  12. metadata +1 -22
  13. data/helpers/elixir/bin/check_update.exs +0 -92
  14. data/helpers/elixir/bin/do_update.exs +0 -39
  15. data/helpers/elixir/bin/parse_deps.exs +0 -103
  16. data/helpers/elixir/bin/run.exs +0 -76
  17. data/helpers/elixir/mix.exs +0 -21
  18. data/helpers/elixir/mix.lock +0 -3
  19. data/lib/dependabot/file_fetchers/elixir/hex.rb +0 -78
  20. data/lib/dependabot/file_parsers/elixir/hex.rb +0 -134
  21. data/lib/dependabot/file_updaters/elixir/hex.rb +0 -71
  22. data/lib/dependabot/file_updaters/elixir/hex/lockfile_updater.rb +0 -147
  23. data/lib/dependabot/file_updaters/elixir/hex/mixfile_git_pin_updater.rb +0 -53
  24. data/lib/dependabot/file_updaters/elixir/hex/mixfile_requirement_updater.rb +0 -74
  25. data/lib/dependabot/file_updaters/elixir/hex/mixfile_sanitizer.rb +0 -28
  26. data/lib/dependabot/file_updaters/elixir/hex/mixfile_updater.rb +0 -98
  27. data/lib/dependabot/metadata_finders/elixir/hex.rb +0 -69
  28. data/lib/dependabot/update_checkers/elixir/hex.rb +0 -274
  29. data/lib/dependabot/update_checkers/elixir/hex/file_preparer.rb +0 -193
  30. data/lib/dependabot/update_checkers/elixir/hex/requirements_updater.rb +0 -177
  31. data/lib/dependabot/update_checkers/elixir/hex/version_resolver.rb +0 -175
  32. data/lib/dependabot/utils/elixir/requirement.rb +0 -54
  33. data/lib/dependabot/utils/elixir/version.rb +0 -66
@@ -1,53 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "dependabot/file_updaters/elixir/hex"
4
- require "dependabot/shared_helpers"
5
-
6
- module Dependabot
7
- module FileUpdaters
8
- module Elixir
9
- class Hex
10
- class MixfileGitPinUpdater
11
- def initialize(dependency_name:, mixfile_content:,
12
- previous_pin:, updated_pin:)
13
- @dependency_name = dependency_name
14
- @mixfile_content = mixfile_content
15
- @previous_pin = previous_pin
16
- @updated_pin = updated_pin
17
- end
18
-
19
- def updated_content
20
- updated_content = update_pin(mixfile_content)
21
-
22
- if content_should_change? && mixfile_content == updated_content
23
- raise "Expected content to change!"
24
- end
25
-
26
- updated_content
27
- end
28
-
29
- private
30
-
31
- attr_reader :dependency_name, :mixfile_content,
32
- :previous_pin, :updated_pin
33
-
34
- def update_pin(content)
35
- requirement_line_regex =
36
- /
37
- \{\s*:#{Regexp.escape(dependency_name)},[^\}]*
38
- (?:ref|tag):\s+["']#{Regexp.escape(previous_pin)}["']
39
- /mx
40
-
41
- content.gsub(requirement_line_regex) do |requirement_line|
42
- requirement_line.gsub(previous_pin, updated_pin)
43
- end
44
- end
45
-
46
- def content_should_change?
47
- previous_pin == updated_pin
48
- end
49
- end
50
- end
51
- end
52
- end
53
- end
@@ -1,74 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "dependabot/file_updaters/elixir/hex"
4
- require "dependabot/shared_helpers"
5
-
6
- module Dependabot
7
- module FileUpdaters
8
- module Elixir
9
- class Hex
10
- class MixfileRequirementUpdater
11
- def initialize(dependency_name:, mixfile_content:,
12
- previous_requirement:, updated_requirement:,
13
- insert_if_bare: false)
14
- @dependency_name = dependency_name
15
- @mixfile_content = mixfile_content
16
- @previous_requirement = previous_requirement
17
- @updated_requirement = updated_requirement
18
- @insert_if_bare = insert_if_bare
19
- end
20
-
21
- def updated_content
22
- updated_content = update_requirement(mixfile_content)
23
-
24
- if content_should_change? && mixfile_content == updated_content
25
- raise "Expected content to change!"
26
- end
27
-
28
- updated_content
29
- end
30
-
31
- private
32
-
33
- attr_reader :dependency_name, :mixfile_content,
34
- :previous_requirement, :updated_requirement
35
-
36
- def insert_if_bare?
37
- !@insert_if_bare.nil?
38
- end
39
-
40
- def update_requirement(content)
41
- return content if previous_requirement.nil? && !insert_if_bare?
42
-
43
- requirement_line_regex =
44
- if previous_requirement
45
- /
46
- :#{Regexp.escape(dependency_name)}\s*,.*
47
- #{Regexp.escape(previous_requirement)}
48
- /x
49
- else
50
- /:#{Regexp.escape(dependency_name)}(,|\s|\})/
51
- end
52
-
53
- content.gsub(requirement_line_regex) do |requirement_line|
54
- if previous_requirement
55
- requirement_line.gsub(previous_requirement, updated_requirement)
56
- else
57
- requirement_line.gsub(
58
- ":#{dependency_name}",
59
- ":#{dependency_name}, \"#{updated_requirement}\""
60
- )
61
- end
62
- end
63
- end
64
-
65
- def content_should_change?
66
- return false if previous_requirement == updated_requirement
67
-
68
- previous_requirement || insert_if_bare?
69
- end
70
- end
71
- end
72
- end
73
- end
74
- end
@@ -1,28 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "dependabot/file_updaters/elixir/hex"
4
- require "dependabot/shared_helpers"
5
-
6
- module Dependabot
7
- module FileUpdaters
8
- module Elixir
9
- class Hex
10
- class MixfileSanitizer
11
- def initialize(mixfile_content:)
12
- @mixfile_content = mixfile_content
13
- end
14
-
15
- def sanitized_content
16
- mixfile_content.
17
- gsub(/File\.read!\(.*?\)/, '"0.0.1"').
18
- gsub(/File\.read\(.*?\)/, '{:ok, "0.0.1"}')
19
- end
20
-
21
- private
22
-
23
- attr_reader :mixfile_content
24
- end
25
- end
26
- end
27
- end
28
- end
@@ -1,98 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "dependabot/file_updaters/elixir/hex"
4
- require "dependabot/file_updaters/elixir/hex/mixfile_requirement_updater"
5
- require "dependabot/file_updaters/elixir/hex/mixfile_git_pin_updater"
6
-
7
- module Dependabot
8
- module FileUpdaters
9
- module Elixir
10
- class Hex
11
- class MixfileUpdater
12
- def initialize(mixfile:, dependencies:)
13
- @mixfile = mixfile
14
- @dependencies = dependencies
15
- end
16
-
17
- def updated_mixfile_content
18
- dependencies.
19
- select { |dep| requirement_changed?(mixfile, dep) }.
20
- reduce(mixfile.content.dup) do |content, dep|
21
- updated_content = content
22
-
23
- updated_content = update_requirement(
24
- content: updated_content,
25
- filename: mixfile.name,
26
- dependency: dep
27
- )
28
-
29
- updated_content = update_git_pin(
30
- content: updated_content,
31
- filename: mixfile.name,
32
- dependency: dep
33
- )
34
-
35
- if content == updated_content
36
- raise "Expected content to change!"
37
- end
38
-
39
- updated_content
40
- end
41
- end
42
-
43
- private
44
-
45
- attr_reader :mixfile, :dependencies
46
-
47
- def requirement_changed?(file, dependency)
48
- changed_requirements =
49
- dependency.requirements - dependency.previous_requirements
50
-
51
- changed_requirements.any? { |f| f[:file] == file.name }
52
- end
53
-
54
- def update_requirement(content:, filename:, dependency:)
55
- updated_req =
56
- dependency.requirements.find { |r| r[:file] == filename }.
57
- fetch(:requirement)
58
-
59
- old_req =
60
- dependency.previous_requirements.
61
- find { |r| r[:file] == filename }.
62
- fetch(:requirement)
63
-
64
- return content unless old_req
65
-
66
- MixfileRequirementUpdater.new(
67
- dependency_name: dependency.name,
68
- mixfile_content: content,
69
- previous_requirement: old_req,
70
- updated_requirement: updated_req
71
- ).updated_content
72
- end
73
-
74
- def update_git_pin(content:, filename:, dependency:)
75
- updated_pin =
76
- dependency.requirements.find { |r| r[:file] == filename }&.
77
- dig(:source, :ref)
78
-
79
- old_pin =
80
- dependency.previous_requirements.
81
- find { |r| r[:file] == filename }&.
82
- dig(:source, :ref)
83
-
84
- return content unless old_pin
85
- return content if old_pin == updated_pin
86
-
87
- MixfileGitPinUpdater.new(
88
- dependency_name: dependency.name,
89
- mixfile_content: content,
90
- previous_pin: old_pin,
91
- updated_pin: updated_pin
92
- ).updated_content
93
- end
94
- end
95
- end
96
- end
97
- end
98
- end
@@ -1,69 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "excon"
4
- require "dependabot/metadata_finders/base"
5
- require "dependabot/shared_helpers"
6
-
7
- module Dependabot
8
- module MetadataFinders
9
- module Elixir
10
- class Hex < Dependabot::MetadataFinders::Base
11
- SOURCE_KEYS = %w(
12
- GitHub Github github
13
- GitLab Gitlab gitlab
14
- BitBucket Bitbucket bitbucket
15
- Source source
16
- ).freeze
17
-
18
- private
19
-
20
- def look_up_source
21
- case new_source_type
22
- when "default" then find_source_from_hex_listing
23
- when "git" then find_source_from_git_url
24
- else raise "Unexpected source type: #{new_source_type}"
25
- end
26
- end
27
-
28
- def new_source_type
29
- sources =
30
- dependency.requirements.map { |r| r.fetch(:source) }.uniq.compact
31
-
32
- return "default" if sources.empty?
33
- raise "Multiple sources! #{sources.join(', ')}" if sources.count > 1
34
-
35
- sources.first[:type] || sources.first.fetch("type")
36
- end
37
-
38
- def find_source_from_hex_listing
39
- potential_source_urls =
40
- SOURCE_KEYS.
41
- map { |key| hex_listing.dig("meta", "links", key) }.
42
- compact
43
-
44
- source_url = potential_source_urls.find { |url| Source.from_url(url) }
45
- Source.from_url(source_url)
46
- end
47
-
48
- def find_source_from_git_url
49
- info = dependency.requirements.map { |r| r[:source] }.compact.first
50
-
51
- url = info[:url] || info.fetch("url")
52
- Source.from_url(url)
53
- end
54
-
55
- def hex_listing
56
- return @hex_listing unless @hex_listing.nil?
57
-
58
- response = Excon.get(
59
- "https://hex.pm/api/packages/#{dependency.name}",
60
- idempotent: true,
61
- **SharedHelpers.excon_defaults
62
- )
63
-
64
- @hex_listing = JSON.parse(response.body)
65
- end
66
- end
67
- end
68
- end
69
- end
@@ -1,274 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "excon"
4
- require "dependabot/git_commit_checker"
5
- require "dependabot/update_checkers/base"
6
- require "dependabot/shared_helpers"
7
-
8
- require "json"
9
-
10
- module Dependabot
11
- module UpdateCheckers
12
- module Elixir
13
- class Hex < Dependabot::UpdateCheckers::Base
14
- require_relative "hex/file_preparer"
15
- require_relative "hex/requirements_updater"
16
- require_relative "hex/version_resolver"
17
-
18
- def latest_version
19
- @latest_version ||=
20
- if git_dependency?
21
- latest_version_for_git_dependency
22
- else
23
- latest_release_from_hex_registry || latest_resolvable_version
24
- end
25
- end
26
-
27
- def latest_resolvable_version
28
- @latest_resolvable_version ||=
29
- if git_dependency?
30
- latest_resolvable_version_for_git_dependency
31
- else
32
- fetch_latest_resolvable_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
- fetch_latest_resolvable_version(unlock_requirement: false)
42
- end
43
- end
44
-
45
- def updated_requirements
46
- RequirementsUpdater.new(
47
- requirements: dependency.requirements,
48
- updated_source: updated_source,
49
- latest_resolvable_version: latest_resolvable_version&.to_s
50
- ).updated_requirements
51
- end
52
-
53
- private
54
-
55
- def latest_version_resolvable_with_full_unlock?
56
- # Full unlock checks aren't implemented for Elixir (yet)
57
- false
58
- end
59
-
60
- def updated_dependencies_after_full_unlock
61
- raise NotImplementedError
62
- end
63
-
64
- def latest_version_for_git_dependency
65
- latest_git_version_sha
66
- end
67
-
68
- def latest_resolvable_version_for_git_dependency
69
- # If the gem isn't pinned, the latest version is just the latest
70
- # commit for the specified branch.
71
- unless git_commit_checker.pinned?
72
- return latest_resolvable_commit_with_unchanged_git_source
73
- end
74
-
75
- # If the dependency is pinned to a tag that looks like a version then
76
- # we want to update that tag. The latest version will then be the SHA
77
- # of the latest tag that looks like a version.
78
- if git_commit_checker.pinned_ref_looks_like_version? &&
79
- latest_git_tag_is_resolvable?
80
- new_tag = git_commit_checker.local_tag_for_latest_version
81
- return new_tag.fetch(:commit_sha)
82
- end
83
-
84
- # If the dependency is pinned then there's nothing we can do.
85
- dependency.version
86
- end
87
-
88
- def latest_resolvable_commit_with_unchanged_git_source
89
- fetch_latest_resolvable_version(unlock_requirement: false)
90
- rescue SharedHelpers::HelperSubprocessFailed,
91
- Dependabot::DependencyFileNotResolvable => error
92
- # Resolution may fail, as Elixir updates straight to the tip of the
93
- # branch. Just return `nil` if it does (so no update).
94
- return if error.message.include?("resolution failed")
95
-
96
- raise error
97
- end
98
-
99
- def git_dependency?
100
- git_commit_checker.git_dependency?
101
- end
102
-
103
- def latest_git_version_sha
104
- # If the gem isn't pinned, the latest version is just the latest
105
- # commit for the specified branch.
106
- unless git_commit_checker.pinned?
107
- return git_commit_checker.head_commit_for_current_branch
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. The latest version will then be the SHA
112
- # of the latest tag that looks like a version.
113
- if git_commit_checker.pinned_ref_looks_like_version?
114
- latest_tag = git_commit_checker.local_tag_for_latest_version
115
- return latest_tag&.fetch(:commit_sha) || dependency.version
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
- dependency.version
121
- end
122
-
123
- def latest_git_tag_is_resolvable?
124
- return @git_tag_resolvable if @latest_git_tag_is_resolvable_checked
125
-
126
- @latest_git_tag_is_resolvable_checked = true
127
-
128
- return false if git_commit_checker.local_tag_for_latest_version.nil?
129
-
130
- replacement_tag = git_commit_checker.local_tag_for_latest_version
131
-
132
- prepared_files = FilePreparer.new(
133
- dependency: dependency,
134
- dependency_files: dependency_files,
135
- replacement_git_pin: replacement_tag.fetch(:tag)
136
- ).prepared_dependency_files
137
-
138
- resolver_result = VersionResolver.new(
139
- dependency: dependency,
140
- prepared_dependency_files: prepared_files,
141
- original_dependency_files: dependency_files,
142
- credentials: credentials
143
- ).latest_resolvable_version
144
-
145
- @git_tag_resolvable = !resolver_result.nil?
146
- rescue SharedHelpers::HelperSubprocessFailed,
147
- Dependabot::DependencyFileNotResolvable => error
148
- raise error unless error.message.include?("resolution failed")
149
-
150
- @git_tag_resolvable = false
151
- end
152
-
153
- def updated_source
154
- # Never need to update source, unless a git_dependency
155
- return dependency_source_details unless git_dependency?
156
-
157
- # Update the git tag if updating a pinned version
158
- if git_commit_checker.pinned_ref_looks_like_version? &&
159
- latest_git_tag_is_resolvable?
160
- new_tag = git_commit_checker.local_tag_for_latest_version
161
- return dependency_source_details.merge(ref: new_tag.fetch(:tag))
162
- end
163
-
164
- # Otherwise return the original source
165
- dependency_source_details
166
- end
167
-
168
- def dependency_source_details
169
- sources =
170
- dependency.requirements.map { |r| r.fetch(:source) }.uniq.compact
171
-
172
- raise "Multiple sources! #{sources.join(', ')}" if sources.count > 1
173
-
174
- sources.first
175
- end
176
-
177
- def fetch_latest_resolvable_version(unlock_requirement:)
178
- @latest_resolvable_version_hash ||= {}
179
- @latest_resolvable_version_hash[unlock_requirement] ||=
180
- version_resolver(unlock_requirement: unlock_requirement).
181
- latest_resolvable_version
182
- end
183
-
184
- def version_resolver(unlock_requirement:)
185
- @version_resolver ||= {}
186
- @version_resolver[unlock_requirement] ||=
187
- begin
188
- prepared_dependency_files = prepared_dependency_files(
189
- unlock_requirement: unlock_requirement,
190
- latest_allowable_version: latest_release_from_hex_registry
191
- )
192
-
193
- VersionResolver.new(
194
- dependency: dependency,
195
- prepared_dependency_files: prepared_dependency_files,
196
- original_dependency_files: dependency_files,
197
- credentials: credentials
198
- )
199
- end
200
- end
201
-
202
- def prepared_dependency_files(unlock_requirement:,
203
- latest_allowable_version: nil)
204
- FilePreparer.new(
205
- dependency: dependency,
206
- dependency_files: dependency_files,
207
- unlock_requirement: unlock_requirement,
208
- latest_allowable_version: latest_allowable_version
209
- ).prepared_dependency_files
210
- end
211
-
212
- def latest_release_from_hex_registry
213
- @latest_release_from_hex_registry ||=
214
- begin
215
- versions = hex_registry_response&.fetch("releases", []) || []
216
- versions =
217
- versions.
218
- select { |release| version_class.correct?(release["version"]) }.
219
- map { |release| version_class.new(release["version"]) }
220
-
221
- versions.reject!(&:prerelease?) unless wants_prerelease?
222
- versions.reject! do |v|
223
- ignore_reqs.any? { |r| r.satisfied_by?(v) }
224
- end
225
- versions.max
226
- end
227
- end
228
-
229
- def hex_registry_response
230
- return @hex_registry_response if @hex_registry_requested
231
-
232
- @hex_registry_requested = true
233
-
234
- response = Excon.get(
235
- dependency_url,
236
- idempotent: true,
237
- **SharedHelpers.excon_defaults
238
- )
239
-
240
- return unless response.status == 200
241
-
242
- @hex_registry_response = JSON.parse(response.body)
243
- rescue Excon::Error::Socket, Excon::Error::Timeout
244
- nil
245
- end
246
-
247
- def wants_prerelease?
248
- current_version = dependency.version
249
- if current_version &&
250
- version_class.correct?(current_version) &&
251
- version_class.new(current_version).prerelease?
252
- return true
253
- end
254
-
255
- dependency.requirements.any? do |req|
256
- req[:requirement]&.match?(/\d-[A-Za-z0-9]/)
257
- end
258
- end
259
-
260
- def dependency_url
261
- "https://hex.pm/api/packages/#{dependency.name}"
262
- end
263
-
264
- def git_commit_checker
265
- @git_commit_checker ||=
266
- GitCommitChecker.new(
267
- dependency: dependency,
268
- credentials: credentials
269
- )
270
- end
271
- end
272
- end
273
- end
274
- end