dependabot-core 0.94.13 → 0.95.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- metadata +13 -337
- data/CHANGELOG.md +0 -7079
- data/LICENSE +0 -39
- data/README.md +0 -114
- data/helpers/test/run.rb +0 -18
- data/helpers/utils/git-credential-store-immutable +0 -10
- data/lib/dependabot/clients/bitbucket.rb +0 -105
- data/lib/dependabot/clients/github_with_retries.rb +0 -121
- data/lib/dependabot/clients/gitlab.rb +0 -72
- data/lib/dependabot/dependency.rb +0 -115
- data/lib/dependabot/dependency_file.rb +0 -60
- data/lib/dependabot/errors.rb +0 -179
- data/lib/dependabot/file_fetchers/README.md +0 -65
- data/lib/dependabot/file_fetchers/base.rb +0 -368
- data/lib/dependabot/file_fetchers.rb +0 -18
- data/lib/dependabot/file_parsers/README.md +0 -45
- data/lib/dependabot/file_parsers/base/dependency_set.rb +0 -77
- data/lib/dependabot/file_parsers/base.rb +0 -31
- data/lib/dependabot/file_parsers.rb +0 -18
- data/lib/dependabot/file_updaters/README.md +0 -58
- data/lib/dependabot/file_updaters/base.rb +0 -52
- data/lib/dependabot/file_updaters.rb +0 -18
- data/lib/dependabot/git_commit_checker.rb +0 -412
- data/lib/dependabot/metadata_finders/README.md +0 -53
- data/lib/dependabot/metadata_finders/base/changelog_finder.rb +0 -321
- data/lib/dependabot/metadata_finders/base/changelog_pruner.rb +0 -177
- data/lib/dependabot/metadata_finders/base/commits_finder.rb +0 -221
- data/lib/dependabot/metadata_finders/base/release_finder.rb +0 -255
- data/lib/dependabot/metadata_finders/base.rb +0 -117
- data/lib/dependabot/metadata_finders.rb +0 -18
- data/lib/dependabot/pull_request_creator/branch_namer.rb +0 -170
- data/lib/dependabot/pull_request_creator/commit_signer.rb +0 -63
- data/lib/dependabot/pull_request_creator/github.rb +0 -277
- data/lib/dependabot/pull_request_creator/gitlab.rb +0 -136
- data/lib/dependabot/pull_request_creator/labeler.rb +0 -373
- data/lib/dependabot/pull_request_creator/message_builder.rb +0 -906
- data/lib/dependabot/pull_request_creator.rb +0 -153
- data/lib/dependabot/pull_request_updater/github.rb +0 -165
- data/lib/dependabot/pull_request_updater.rb +0 -43
- data/lib/dependabot/shared_helpers.rb +0 -224
- data/lib/dependabot/source.rb +0 -120
- data/lib/dependabot/update_checkers/README.md +0 -67
- data/lib/dependabot/update_checkers/base.rb +0 -220
- data/lib/dependabot/update_checkers.rb +0 -18
- data/lib/dependabot/utils.rb +0 -33
- data/lib/dependabot/version.rb +0 -5
- data/lib/dependabot.rb +0 -4
- data/lib/rubygems_version_patch.rb +0 -14
@@ -1,53 +0,0 @@
|
|
1
|
-
# Metadata finders
|
2
|
-
|
3
|
-
Metadata finders look up metadata about a dependency, such as its GitHub URL.
|
4
|
-
|
5
|
-
There is a `Dependabot::MetadataFinders` class for each language Dependabot
|
6
|
-
supports.
|
7
|
-
|
8
|
-
## Public API
|
9
|
-
|
10
|
-
Each `Dependabot::MetadataFinders` class exposes the following methods:
|
11
|
-
|
12
|
-
| Method | Description |
|
13
|
-
|-----------------------|---------------------------------------------------------------------------------------------|
|
14
|
-
| `#source_url` | A link to the source data for the dependency. |
|
15
|
-
| `#homepage_url` | A link to the homepage for the dependency. |
|
16
|
-
| `#commits_url` | A link to a commit diff between the previous version of the dependency and the new version. |
|
17
|
-
| `#commits` | A list of commits between the previous version of the dependency and the new version. |
|
18
|
-
| `#changelog_url` | A link to the changelog for the dependency. |
|
19
|
-
| `#changelog_text` | The relevant text from the changelog. |
|
20
|
-
| `#release_url` | A link to the release notes for this version of the dependency. |
|
21
|
-
| `#release_text` | The relevant text from the release notes |
|
22
|
-
| `#upgrade_guide_url` | A link to the upgrade guide for this upgrade (if it exists). |
|
23
|
-
| `#upgrade_guide_text` | The text of the upgrade guide for this upgrade (if it exists). |
|
24
|
-
|
25
|
-
An integration might look as follows:
|
26
|
-
|
27
|
-
```ruby
|
28
|
-
require 'dependabot/metadata_finders'
|
29
|
-
|
30
|
-
dependency = update_checker.updated_dependency
|
31
|
-
|
32
|
-
metadata_finder_class = Dependabot::MetadataFinders::Ruby::Bundler
|
33
|
-
metadata_finder = metadata_finder_class.new(
|
34
|
-
dependency: dependency,
|
35
|
-
credentials: credentials
|
36
|
-
)
|
37
|
-
|
38
|
-
puts "Changelog for #{dependency.name} is at #{metadata_finder.changelog_url}"
|
39
|
-
```
|
40
|
-
|
41
|
-
## Writing a metadata finder for a new language
|
42
|
-
|
43
|
-
All new metadata finders should inherit from `Dependabot::MetadataFinders::Base`
|
44
|
-
and implement the following methods:
|
45
|
-
|
46
|
-
| Method | Description |
|
47
|
-
|------------------------|-------------------------|
|
48
|
-
| `#look_up_source` | Private method that returns a `Dependabot::Source` object. Generally the source details are extracted from a source code URL provided by the language's dependency registry, but sometimes it's already know from parsing the dependency file. |
|
49
|
-
|
50
|
-
To ensure the above are implemented, you should include
|
51
|
-
`it_behaves_like "a dependency metadata finder"` in your specs for the new
|
52
|
-
metadata finder.
|
53
|
-
|
@@ -1,321 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require "excon"
|
4
|
-
|
5
|
-
require "dependabot/clients/github_with_retries"
|
6
|
-
require "dependabot/clients/gitlab"
|
7
|
-
require "dependabot/clients/bitbucket"
|
8
|
-
require "dependabot/shared_helpers"
|
9
|
-
require "dependabot/metadata_finders/base"
|
10
|
-
|
11
|
-
module Dependabot
|
12
|
-
module MetadataFinders
|
13
|
-
class Base
|
14
|
-
class ChangelogFinder
|
15
|
-
require_relative "changelog_pruner"
|
16
|
-
require_relative "commits_finder"
|
17
|
-
|
18
|
-
# Earlier entries are preferred
|
19
|
-
CHANGELOG_NAMES = %w(changelog history news changes release).freeze
|
20
|
-
|
21
|
-
attr_reader :source, :dependency, :credentials
|
22
|
-
|
23
|
-
def initialize(source:, dependency:, credentials:)
|
24
|
-
@source = source
|
25
|
-
@dependency = dependency
|
26
|
-
@credentials = credentials
|
27
|
-
end
|
28
|
-
|
29
|
-
def changelog_url
|
30
|
-
changelog&.html_url
|
31
|
-
end
|
32
|
-
|
33
|
-
def changelog_text
|
34
|
-
return unless full_changelog_text
|
35
|
-
|
36
|
-
ChangelogPruner.new(
|
37
|
-
dependency: dependency,
|
38
|
-
changelog_text: full_changelog_text
|
39
|
-
).pruned_text
|
40
|
-
end
|
41
|
-
|
42
|
-
def upgrade_guide_url
|
43
|
-
upgrade_guide&.html_url
|
44
|
-
end
|
45
|
-
|
46
|
-
def upgrade_guide_text
|
47
|
-
return unless upgrade_guide
|
48
|
-
|
49
|
-
@upgrade_guide_text ||= fetch_file_text(upgrade_guide)
|
50
|
-
end
|
51
|
-
|
52
|
-
private
|
53
|
-
|
54
|
-
# rubocop:disable Metrics/CyclomaticComplexity
|
55
|
-
# rubocop:disable Metrics/PerceivedComplexity
|
56
|
-
def changelog
|
57
|
-
return unless source
|
58
|
-
|
59
|
-
# Changelog won't be relevant for a git commit bump
|
60
|
-
return if git_source? && !ref_changed?
|
61
|
-
|
62
|
-
# If there is a changelog, and it includes the new version, return it
|
63
|
-
if new_version && default_branch_changelog &&
|
64
|
-
fetch_file_text(default_branch_changelog)&.include?(new_version)
|
65
|
-
return default_branch_changelog
|
66
|
-
end
|
67
|
-
|
68
|
-
# Otherwise, look for a changelog at the tag for this version
|
69
|
-
if new_version && relevant_tag_changelog &&
|
70
|
-
fetch_file_text(relevant_tag_changelog)&.include?(new_version)
|
71
|
-
return relevant_tag_changelog
|
72
|
-
end
|
73
|
-
|
74
|
-
# Fall back to the changelog (or nil) from the default branch
|
75
|
-
default_branch_changelog
|
76
|
-
end
|
77
|
-
# rubocop:enable Metrics/CyclomaticComplexity
|
78
|
-
# rubocop:enable Metrics/PerceivedComplexity
|
79
|
-
|
80
|
-
def default_branch_changelog
|
81
|
-
return unless source
|
82
|
-
|
83
|
-
@default_branch_changelog ||= changelog_from_ref(nil)
|
84
|
-
end
|
85
|
-
|
86
|
-
def relevant_tag_changelog
|
87
|
-
return unless source
|
88
|
-
return unless tag_for_new_version
|
89
|
-
|
90
|
-
@relevant_tag_changelog ||= changelog_from_ref(tag_for_new_version)
|
91
|
-
end
|
92
|
-
|
93
|
-
def changelog_from_ref(ref)
|
94
|
-
files =
|
95
|
-
dependency_file_list(ref).
|
96
|
-
select { |f| f.type == "file" }.
|
97
|
-
reject { |f| f.name.end_with?(".sh") }.
|
98
|
-
reject { |f| f.size > 1_000_000 }
|
99
|
-
|
100
|
-
CHANGELOG_NAMES.each do |name|
|
101
|
-
candidates = files.select { |f| f.name =~ /#{name}/i }
|
102
|
-
file = candidates.first if candidates.one?
|
103
|
-
file ||=
|
104
|
-
candidates.find do |f|
|
105
|
-
candidates -= [f] && next if fetch_file_text(f).nil?
|
106
|
-
ChangelogPruner.new(
|
107
|
-
dependency: dependency,
|
108
|
-
changelog_text: fetch_file_text(f)
|
109
|
-
).includes_new_version?
|
110
|
-
end
|
111
|
-
file ||= candidates.max_by(&:size)
|
112
|
-
return file if file
|
113
|
-
end
|
114
|
-
|
115
|
-
nil
|
116
|
-
end
|
117
|
-
|
118
|
-
def tag_for_new_version
|
119
|
-
@tag_for_new_version ||=
|
120
|
-
CommitsFinder.new(
|
121
|
-
dependency: dependency,
|
122
|
-
source: source,
|
123
|
-
credentials: credentials
|
124
|
-
).new_tag
|
125
|
-
end
|
126
|
-
|
127
|
-
def full_changelog_text
|
128
|
-
return unless changelog
|
129
|
-
|
130
|
-
fetch_file_text(changelog)
|
131
|
-
end
|
132
|
-
|
133
|
-
def fetch_file_text(file)
|
134
|
-
@file_text ||= {}
|
135
|
-
|
136
|
-
unless @file_text.key?(file.download_url)
|
137
|
-
@file_text[file.download_url] =
|
138
|
-
case source.provider
|
139
|
-
when "github" then fetch_github_file(file)
|
140
|
-
when "gitlab" then fetch_gitlab_file(file)
|
141
|
-
when "bitbucket" then fetch_bitbucket_file(file)
|
142
|
-
else raise "Unsupported provider '#{source.provider}"
|
143
|
-
end
|
144
|
-
end
|
145
|
-
|
146
|
-
return unless @file_text[file.download_url].valid_encoding?
|
147
|
-
|
148
|
-
@file_text[file.download_url].
|
149
|
-
force_encoding("UTF-8").
|
150
|
-
encode.sub(/\n*\z/, "")
|
151
|
-
end
|
152
|
-
|
153
|
-
def fetch_github_file(file)
|
154
|
-
# Hitting the download URL directly causes encoding problems
|
155
|
-
raw_content = github_client.get(file.url).content
|
156
|
-
Base64.decode64(raw_content).force_encoding("UTF-8").encode
|
157
|
-
end
|
158
|
-
|
159
|
-
def fetch_gitlab_file(file)
|
160
|
-
Excon.get(
|
161
|
-
file.download_url,
|
162
|
-
idempotent: true,
|
163
|
-
**SharedHelpers.excon_defaults
|
164
|
-
).body
|
165
|
-
end
|
166
|
-
|
167
|
-
def fetch_bitbucket_file(file)
|
168
|
-
bitbucket_client.get(file.download_url).body
|
169
|
-
end
|
170
|
-
|
171
|
-
def upgrade_guide
|
172
|
-
return unless source
|
173
|
-
|
174
|
-
# Upgrade guide usually won't be relevant for bumping anything other
|
175
|
-
# than the major version
|
176
|
-
return unless major_version_upgrade?
|
177
|
-
|
178
|
-
dependency_file_list.
|
179
|
-
select { |f| f.type == "file" }.
|
180
|
-
select { |f| f.name.casecmp("upgrade.md").zero? }.
|
181
|
-
reject { |f| f.size > 1_000_000 }.
|
182
|
-
max_by(&:size)
|
183
|
-
end
|
184
|
-
|
185
|
-
def dependency_file_list(ref = nil)
|
186
|
-
@dependency_file_list ||= {}
|
187
|
-
@dependency_file_list[ref] ||= fetch_dependency_file_list(ref)
|
188
|
-
end
|
189
|
-
|
190
|
-
def fetch_dependency_file_list(ref)
|
191
|
-
case source.provider
|
192
|
-
when "github" then fetch_github_file_list(ref)
|
193
|
-
when "bitbucket" then fetch_bitbucket_file_list
|
194
|
-
when "gitlab" then fetch_gitlab_file_list
|
195
|
-
when "azure" then [] # TODO: Fetch files from Azure
|
196
|
-
else raise "Unexpected repo provider '#{source.provider}'"
|
197
|
-
end
|
198
|
-
end
|
199
|
-
|
200
|
-
def fetch_github_file_list(ref)
|
201
|
-
files = []
|
202
|
-
|
203
|
-
if source.directory
|
204
|
-
opts = { path: source.directory, ref: ref }.compact
|
205
|
-
tmp_files = github_client.contents(source.repo, opts)
|
206
|
-
files += tmp_files if tmp_files.is_a?(Array)
|
207
|
-
end
|
208
|
-
|
209
|
-
opts = { ref: ref }.compact
|
210
|
-
files += github_client.contents(source.repo, opts)
|
211
|
-
|
212
|
-
files.uniq.each do |f|
|
213
|
-
next unless %w(doc docs).include?(f.name) && f.type == "dir"
|
214
|
-
|
215
|
-
opts = { path: f.path, ref: ref }.compact
|
216
|
-
files += github_client.contents(source.repo, opts)
|
217
|
-
end
|
218
|
-
|
219
|
-
files
|
220
|
-
rescue Octokit::NotFound
|
221
|
-
[]
|
222
|
-
end
|
223
|
-
|
224
|
-
def fetch_bitbucket_file_list
|
225
|
-
branch = default_bitbucket_branch
|
226
|
-
bitbucket_client.fetch_repo_contents(source.repo).map do |file|
|
227
|
-
OpenStruct.new(
|
228
|
-
name: file.fetch("path").split("/").last,
|
229
|
-
type: file.fetch("type") == "commit_file" ? "file" : file["type"],
|
230
|
-
size: file.fetch("size", 0),
|
231
|
-
html_url: "#{source.url}/src/#{branch}/#{file['path']}",
|
232
|
-
download_url: "#{source.url}/raw/#{branch}/#{file['path']}"
|
233
|
-
)
|
234
|
-
end
|
235
|
-
rescue Dependabot::Clients::Bitbucket::NotFound,
|
236
|
-
Dependabot::Clients::Bitbucket::Unauthorized,
|
237
|
-
Dependabot::Clients::Bitbucket::Forbidden
|
238
|
-
[]
|
239
|
-
end
|
240
|
-
|
241
|
-
def fetch_gitlab_file_list
|
242
|
-
gitlab_client.repo_tree(source.repo).map do |file|
|
243
|
-
OpenStruct.new(
|
244
|
-
name: file.name,
|
245
|
-
type: file.type == "blob" ? "file" : file.type,
|
246
|
-
size: 0, # GitLab doesn't return file size
|
247
|
-
html_url: "#{source.url}/blob/master/#{file.path}",
|
248
|
-
download_url: "#{source.url}/raw/master/#{file.path}"
|
249
|
-
)
|
250
|
-
end
|
251
|
-
rescue Gitlab::Error::NotFound
|
252
|
-
[]
|
253
|
-
end
|
254
|
-
|
255
|
-
def new_version
|
256
|
-
@new_version ||= git_source? ? new_ref : dependency.version
|
257
|
-
@new_version&.gsub(/^v/, "")
|
258
|
-
end
|
259
|
-
|
260
|
-
def previous_ref
|
261
|
-
dependency.previous_requirements.map do |r|
|
262
|
-
r.dig(:source, "ref") || r.dig(:source, :ref)
|
263
|
-
end.compact.first
|
264
|
-
end
|
265
|
-
|
266
|
-
def new_ref
|
267
|
-
dependency.requirements.map do |r|
|
268
|
-
r.dig(:source, "ref") || r.dig(:source, :ref)
|
269
|
-
end.compact.first
|
270
|
-
end
|
271
|
-
|
272
|
-
def ref_changed?
|
273
|
-
previous_ref && new_ref && previous_ref != new_ref
|
274
|
-
end
|
275
|
-
|
276
|
-
# TODO: Refactor me so that Composer doesn't need to be special cased
|
277
|
-
def git_source?
|
278
|
-
# Special case Composer, which uses git as a source but handles tags
|
279
|
-
# internally
|
280
|
-
return false if dependency.package_manager == "composer"
|
281
|
-
|
282
|
-
requirements = dependency.requirements
|
283
|
-
sources = requirements.map { |r| r.fetch(:source) }.uniq.compact
|
284
|
-
return false if sources.empty?
|
285
|
-
raise "Multiple sources! #{sources.join(', ')}" if sources.count > 1
|
286
|
-
|
287
|
-
source_type = sources.first[:type] || sources.first.fetch("type")
|
288
|
-
source_type == "git"
|
289
|
-
end
|
290
|
-
|
291
|
-
def major_version_upgrade?
|
292
|
-
return false unless dependency.version&.match?(/^\d/)
|
293
|
-
return false unless dependency.previous_version&.match?(/^\d/)
|
294
|
-
|
295
|
-
dependency.version.split(".").first.to_i -
|
296
|
-
dependency.previous_version.split(".").first.to_i >= 1
|
297
|
-
end
|
298
|
-
|
299
|
-
def gitlab_client
|
300
|
-
@gitlab_client ||= Dependabot::Clients::Gitlab.
|
301
|
-
for_gitlab_dot_com(credentials: credentials)
|
302
|
-
end
|
303
|
-
|
304
|
-
def github_client
|
305
|
-
@github_client ||= Dependabot::Clients::GithubWithRetries.
|
306
|
-
for_github_dot_com(credentials: credentials)
|
307
|
-
end
|
308
|
-
|
309
|
-
def bitbucket_client
|
310
|
-
@bitbucket_client ||= Dependabot::Clients::Bitbucket.
|
311
|
-
for_bitbucket_dot_org(credentials: credentials)
|
312
|
-
end
|
313
|
-
|
314
|
-
def default_bitbucket_branch
|
315
|
-
@default_bitbucket_branch ||=
|
316
|
-
bitbucket_client.fetch_default_branch(source.repo)
|
317
|
-
end
|
318
|
-
end
|
319
|
-
end
|
320
|
-
end
|
321
|
-
end
|
@@ -1,177 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require "dependabot/metadata_finders/base"
|
4
|
-
|
5
|
-
module Dependabot
|
6
|
-
module MetadataFinders
|
7
|
-
class Base
|
8
|
-
class ChangelogPruner
|
9
|
-
attr_reader :dependency, :changelog_text
|
10
|
-
|
11
|
-
def initialize(dependency:, changelog_text:)
|
12
|
-
@dependency = dependency
|
13
|
-
@changelog_text = changelog_text
|
14
|
-
end
|
15
|
-
|
16
|
-
def includes_new_version?
|
17
|
-
!new_version_changelog_line.nil?
|
18
|
-
end
|
19
|
-
|
20
|
-
# rubocop:disable Metrics/PerceivedComplexity
|
21
|
-
# rubocop:disable Metrics/CyclomaticComplexity
|
22
|
-
def pruned_text
|
23
|
-
changelog_lines = changelog_text.split("\n")
|
24
|
-
|
25
|
-
slice_range =
|
26
|
-
if old_version_changelog_line && new_version_changelog_line
|
27
|
-
if old_version_changelog_line < new_version_changelog_line
|
28
|
-
Range.new(old_version_changelog_line, -1)
|
29
|
-
else
|
30
|
-
Range.new(new_version_changelog_line,
|
31
|
-
old_version_changelog_line - 1)
|
32
|
-
end
|
33
|
-
elsif old_version_changelog_line
|
34
|
-
return if old_version_changelog_line.zero?
|
35
|
-
|
36
|
-
# Assumes changelog is in descending order
|
37
|
-
Range.new(0, old_version_changelog_line - 1)
|
38
|
-
elsif new_version_changelog_line
|
39
|
-
# Assumes changelog is in descending order
|
40
|
-
Range.new(new_version_changelog_line, -1)
|
41
|
-
else
|
42
|
-
return unless changelog_contains_relevant_versions?
|
43
|
-
|
44
|
-
# If the changelog contains any relevant versions, return it in
|
45
|
-
# full. We could do better here by fully parsing the changelog
|
46
|
-
Range.new(0, -1)
|
47
|
-
end
|
48
|
-
|
49
|
-
changelog_lines.slice(slice_range).join("\n").sub(/\n*\z/, "")
|
50
|
-
end
|
51
|
-
# rubocop:enable Metrics/PerceivedComplexity
|
52
|
-
# rubocop:enable Metrics/CyclomaticComplexity
|
53
|
-
|
54
|
-
private
|
55
|
-
|
56
|
-
def old_version_changelog_line
|
57
|
-
old_version = git_source? ? previous_ref : dependency.previous_version
|
58
|
-
return nil unless old_version
|
59
|
-
|
60
|
-
changelog_line_for_version(old_version)
|
61
|
-
end
|
62
|
-
|
63
|
-
def new_version_changelog_line
|
64
|
-
return nil unless new_version
|
65
|
-
|
66
|
-
changelog_line_for_version(new_version)
|
67
|
-
end
|
68
|
-
|
69
|
-
# rubocop:disable Metrics/CyclomaticComplexity
|
70
|
-
# rubocop:disable Metrics/PerceivedComplexity
|
71
|
-
def changelog_line_for_version(version)
|
72
|
-
raise "No changelog text" unless changelog_text
|
73
|
-
return nil unless version
|
74
|
-
|
75
|
-
version = version.gsub(/^v/, "")
|
76
|
-
escaped_version = Regexp.escape(version)
|
77
|
-
|
78
|
-
changelog_lines = changelog_text.split("\n")
|
79
|
-
|
80
|
-
changelog_lines.find_index.with_index do |line, index|
|
81
|
-
next false unless line.match?(/(?<!\.)#{escaped_version}(?![.\-])/)
|
82
|
-
next false if line.match?(/#{escaped_version}\.\./)
|
83
|
-
next true if line.start_with?("#", "!", "==")
|
84
|
-
next true if line.match?(/^v?#{escaped_version}:?/)
|
85
|
-
next true if line.match?(/^[\+\*\-] (version )?#{escaped_version}/i)
|
86
|
-
next true if line.match?(/^\d{4}-\d{2}-\d{2}/)
|
87
|
-
next true if changelog_lines[index + 1]&.match?(/^[=\-\+]{3,}\s*$/)
|
88
|
-
|
89
|
-
false
|
90
|
-
end
|
91
|
-
end
|
92
|
-
# rubocop:enable Metrics/CyclomaticComplexity
|
93
|
-
# rubocop:enable Metrics/PerceivedComplexity
|
94
|
-
|
95
|
-
def changelog_contains_relevant_versions?
|
96
|
-
# Assume the changelog is relevant if we can't parse the new version
|
97
|
-
return true unless version_class.correct?(dependency.version)
|
98
|
-
|
99
|
-
# Assume the changelog is relevant if it mentions the new version
|
100
|
-
# anywhere
|
101
|
-
return true if changelog_text.include?(dependency.version)
|
102
|
-
|
103
|
-
# Otherwise check if any intermediate versions are included in headers
|
104
|
-
versions_in_changelog_headers.any? do |version|
|
105
|
-
next false unless version <= version_class.new(dependency.version)
|
106
|
-
next true unless dependency.previous_version
|
107
|
-
next true unless version_class.correct?(dependency.previous_version)
|
108
|
-
|
109
|
-
version > version_class.new(dependency.previous_version)
|
110
|
-
end
|
111
|
-
end
|
112
|
-
|
113
|
-
def versions_in_changelog_headers
|
114
|
-
changelog_lines = changelog_text.split("\n")
|
115
|
-
header_lines =
|
116
|
-
changelog_lines.select.with_index do |line, index|
|
117
|
-
next true if line.start_with?("#", "!")
|
118
|
-
next true if line.match?(/^v?\d\.\d/)
|
119
|
-
next true if changelog_lines[index + 1]&.match?(/^[=-]+\s*$/)
|
120
|
-
|
121
|
-
false
|
122
|
-
end
|
123
|
-
|
124
|
-
versions = []
|
125
|
-
header_lines.each do |line|
|
126
|
-
cleaned_line = line.gsub(/^[^0-9]*/, "").gsub(/[\s,:].*/, "")
|
127
|
-
next if cleaned_line.empty? || !version_class.correct?(cleaned_line)
|
128
|
-
|
129
|
-
versions << version_class.new(cleaned_line)
|
130
|
-
end
|
131
|
-
|
132
|
-
versions
|
133
|
-
end
|
134
|
-
|
135
|
-
def new_version
|
136
|
-
@new_version ||= git_source? ? new_ref : dependency.version
|
137
|
-
@new_version&.gsub(/^v/, "")
|
138
|
-
end
|
139
|
-
|
140
|
-
def previous_ref
|
141
|
-
dependency.previous_requirements.map do |r|
|
142
|
-
r.dig(:source, "ref") || r.dig(:source, :ref)
|
143
|
-
end.compact.first
|
144
|
-
end
|
145
|
-
|
146
|
-
def new_ref
|
147
|
-
dependency.requirements.map do |r|
|
148
|
-
r.dig(:source, "ref") || r.dig(:source, :ref)
|
149
|
-
end.compact.first
|
150
|
-
end
|
151
|
-
|
152
|
-
def ref_changed?
|
153
|
-
previous_ref && new_ref && previous_ref != new_ref
|
154
|
-
end
|
155
|
-
|
156
|
-
# TODO: Refactor me so that Composer doesn't need to be special cased
|
157
|
-
def git_source?
|
158
|
-
# Special case Composer, which uses git as a source but handles tags
|
159
|
-
# internally
|
160
|
-
return false if dependency.package_manager == "composer"
|
161
|
-
|
162
|
-
requirements = dependency.requirements
|
163
|
-
sources = requirements.map { |r| r.fetch(:source) }.uniq.compact
|
164
|
-
return false if sources.empty?
|
165
|
-
raise "Multiple sources! #{sources.join(', ')}" if sources.count > 1
|
166
|
-
|
167
|
-
source_type = sources.first[:type] || sources.first.fetch("type")
|
168
|
-
source_type == "git"
|
169
|
-
end
|
170
|
-
|
171
|
-
def version_class
|
172
|
-
Utils.version_class_for_package_manager(dependency.package_manager)
|
173
|
-
end
|
174
|
-
end
|
175
|
-
end
|
176
|
-
end
|
177
|
-
end
|