dependabot-bundler 0.333.0 → 0.334.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.
- checksums.yaml +4 -4
- data/lib/dependabot/bundler/file_updater/git_pin_replacer.rb +27 -6
- data/lib/dependabot/bundler/file_updater/git_source_remover.rb +14 -2
- data/lib/dependabot/bundler/file_updater/lockfile_updater.rb +85 -26
- data/lib/dependabot/bundler/file_updater/requirement_replacer.rb +74 -10
- data/lib/dependabot/bundler/file_updater.rb +48 -19
- data/lib/dependabot/bundler/metadata_finder.rb +50 -22
- data/lib/dependabot/bundler/requirement.rb +3 -2
- data/lib/dependabot/bundler/update_checker/file_preparer.rb +69 -19
- data/lib/dependabot/bundler/update_checker/force_updater.rb +1 -1
- data/lib/dependabot/bundler/update_checker/latest_version_finder/dependency_source.rb +47 -11
- data/lib/dependabot/bundler/update_checker/requirements_updater.rb +77 -29
- data/lib/dependabot/bundler/update_checker.rb +1 -1
- metadata +4 -4
@@ -1,18 +1,38 @@
|
|
1
|
-
# typed:
|
1
|
+
# typed: strict
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
4
|
require "parser/current"
|
5
|
+
require "sorbet-runtime"
|
6
|
+
|
5
7
|
require "dependabot/bundler/file_updater"
|
6
8
|
|
7
9
|
module Dependabot
|
8
10
|
module Bundler
|
9
11
|
class FileUpdater
|
10
12
|
class RequirementReplacer
|
13
|
+
extend T::Sig
|
14
|
+
|
15
|
+
sig { returns(Dependabot::Dependency) }
|
11
16
|
attr_reader :dependency
|
17
|
+
|
18
|
+
sig { returns(Symbol) }
|
12
19
|
attr_reader :file_type
|
20
|
+
|
21
|
+
sig { returns(String) }
|
13
22
|
attr_reader :updated_requirement
|
23
|
+
|
24
|
+
sig { returns(T.nilable(String)) }
|
14
25
|
attr_reader :previous_requirement
|
15
26
|
|
27
|
+
sig do
|
28
|
+
params(
|
29
|
+
dependency: Dependabot::Dependency,
|
30
|
+
file_type: Symbol,
|
31
|
+
updated_requirement: String,
|
32
|
+
previous_requirement: T.nilable(String),
|
33
|
+
insert_if_bare: T::Boolean
|
34
|
+
).void
|
35
|
+
end
|
16
36
|
def initialize(dependency:, file_type:, updated_requirement:,
|
17
37
|
previous_requirement: nil, insert_if_bare: false)
|
18
38
|
@dependency = dependency
|
@@ -22,7 +42,10 @@ module Dependabot
|
|
22
42
|
@insert_if_bare = insert_if_bare
|
23
43
|
end
|
24
44
|
|
45
|
+
sig { params(content: T.nilable(String)).returns(String) }
|
25
46
|
def rewrite(content)
|
47
|
+
return "" unless content
|
48
|
+
|
26
49
|
buffer = Parser::Source::Buffer.new("(gemfile_content)")
|
27
50
|
buffer.source = content
|
28
51
|
ast = Parser::CurrentRuby.new.parse(buffer)
|
@@ -39,10 +62,12 @@ module Dependabot
|
|
39
62
|
|
40
63
|
private
|
41
64
|
|
65
|
+
sig { returns(T::Boolean) }
|
42
66
|
def insert_if_bare?
|
43
67
|
@insert_if_bare
|
44
68
|
end
|
45
69
|
|
70
|
+
sig { params(content: String, updated_content: String).returns(String) }
|
46
71
|
def update_comment_spacing_if_required(content, updated_content)
|
47
72
|
return updated_content unless previous_requirement
|
48
73
|
|
@@ -53,43 +78,62 @@ module Dependabot
|
|
53
78
|
updated_line_index =
|
54
79
|
updated_lines.length
|
55
80
|
.times.find { |i| content.lines[i] != updated_content.lines[i] }
|
56
|
-
|
81
|
+
return updated_content unless updated_line_index
|
82
|
+
|
83
|
+
updated_line = T.must(updated_lines[updated_line_index])
|
57
84
|
|
58
85
|
updated_line =
|
59
86
|
if length_change.positive?
|
60
87
|
updated_line.sub(/(?<=\s)\s{#{length_change}}#/, "#")
|
61
88
|
elsif length_change.negative?
|
62
89
|
updated_line.sub(/(?<=\s{2})#/, (" " * length_change.abs) + "#")
|
90
|
+
else
|
91
|
+
updated_line
|
63
92
|
end
|
64
93
|
|
65
94
|
updated_lines[updated_line_index] = updated_line
|
66
95
|
updated_lines.join
|
67
96
|
end
|
68
97
|
|
98
|
+
sig { returns(Integer) }
|
69
99
|
def length_change
|
70
|
-
return
|
100
|
+
return 0 unless previous_requirement
|
101
|
+
|
102
|
+
prev_req = T.must(previous_requirement)
|
103
|
+
return updated_requirement.length - prev_req.length unless prev_req.start_with?("=")
|
71
104
|
|
72
105
|
updated_requirement.length -
|
73
|
-
|
106
|
+
prev_req.gsub(/^=/, "").strip.length
|
74
107
|
end
|
75
108
|
|
76
109
|
class Rewriter < Parser::TreeRewriter
|
110
|
+
extend T::Sig
|
111
|
+
|
77
112
|
# TODO: Ideally we wouldn't have to ignore all of these, but
|
78
113
|
# implementing each one will be tricky.
|
79
|
-
SKIPPED_TYPES = %i(send lvar dstr begin if case splat const or).freeze
|
80
|
-
|
114
|
+
SKIPPED_TYPES = T.let(%i(send lvar dstr begin if case splat const or).freeze, T::Array[Symbol])
|
115
|
+
|
116
|
+
sig do
|
117
|
+
params(
|
118
|
+
dependency: Dependabot::Dependency,
|
119
|
+
file_type: Symbol,
|
120
|
+
updated_requirement: String,
|
121
|
+
insert_if_bare: T::Boolean
|
122
|
+
).void
|
123
|
+
end
|
81
124
|
def initialize(dependency:, file_type:, updated_requirement:,
|
82
125
|
insert_if_bare:)
|
83
|
-
@dependency
|
84
|
-
@file_type
|
85
|
-
@updated_requirement = updated_requirement
|
86
|
-
@insert_if_bare
|
126
|
+
@dependency = T.let(dependency, Dependabot::Dependency)
|
127
|
+
@file_type = T.let(file_type, Symbol)
|
128
|
+
@updated_requirement = T.let(updated_requirement, String)
|
129
|
+
@insert_if_bare = T.let(insert_if_bare, T::Boolean)
|
87
130
|
|
88
131
|
return if %i(gemfile gemspec).include?(file_type)
|
89
132
|
|
90
133
|
raise "File type must be :gemfile or :gemspec. Got #{file_type}."
|
91
134
|
end
|
92
135
|
|
136
|
+
sig { params(node: T.untyped).void }
|
93
137
|
def on_send(node)
|
94
138
|
return unless declares_targeted_gem?(node)
|
95
139
|
|
@@ -117,14 +161,21 @@ module Dependabot
|
|
117
161
|
|
118
162
|
private
|
119
163
|
|
164
|
+
sig { returns(Dependabot::Dependency) }
|
120
165
|
attr_reader :dependency
|
166
|
+
|
167
|
+
sig { returns(Symbol) }
|
121
168
|
attr_reader :file_type
|
169
|
+
|
170
|
+
sig { returns(String) }
|
122
171
|
attr_reader :updated_requirement
|
123
172
|
|
173
|
+
sig { returns(T::Boolean) }
|
124
174
|
def insert_if_bare?
|
125
175
|
@insert_if_bare
|
126
176
|
end
|
127
177
|
|
178
|
+
sig { returns(T::Array[Symbol]) }
|
128
179
|
def declaration_methods
|
129
180
|
return %i(gem) if file_type == :gemfile
|
130
181
|
|
@@ -132,12 +183,14 @@ module Dependabot
|
|
132
183
|
add_development_dependency)
|
133
184
|
end
|
134
185
|
|
186
|
+
sig { params(node: T.untyped).returns(T::Boolean) }
|
135
187
|
def declares_targeted_gem?(node)
|
136
188
|
return false unless declaration_methods.include?(node.children[1])
|
137
189
|
|
138
190
|
node.children[2].children.first == dependency.name
|
139
191
|
end
|
140
192
|
|
193
|
+
sig { params(requirement_nodes: T::Array[T.untyped]).returns([String, String]) }
|
141
194
|
def extract_quote_characters_from(requirement_nodes)
|
142
195
|
return ['"', '"'] if requirement_nodes.none?
|
143
196
|
|
@@ -155,6 +208,7 @@ module Dependabot
|
|
155
208
|
end
|
156
209
|
end
|
157
210
|
|
211
|
+
sig { params(requirement_nodes: T::Array[T.untyped]).returns(T::Boolean) }
|
158
212
|
def space_after_specifier?(requirement_nodes)
|
159
213
|
return true if requirement_nodes.none?
|
160
214
|
|
@@ -174,6 +228,7 @@ module Dependabot
|
|
174
228
|
|
175
229
|
EQUALITY_OPERATOR = /(?<![<>!])=/
|
176
230
|
|
231
|
+
sig { params(requirement_nodes: T::Array[T.untyped]).returns(T::Boolean) }
|
177
232
|
def use_equality_operator?(requirement_nodes)
|
178
233
|
return true if requirement_nodes.none?
|
179
234
|
|
@@ -188,6 +243,13 @@ module Dependabot
|
|
188
243
|
req_string.match?(EQUALITY_OPERATOR)
|
189
244
|
end
|
190
245
|
|
246
|
+
sig do
|
247
|
+
params(
|
248
|
+
quote_characters: [String, String],
|
249
|
+
space_after_specifier: T::Boolean,
|
250
|
+
use_equality_operator: T::Boolean
|
251
|
+
).returns(String)
|
252
|
+
end
|
191
253
|
def new_requirement_string(quote_characters:,
|
192
254
|
space_after_specifier:,
|
193
255
|
use_equality_operator:)
|
@@ -204,6 +266,7 @@ module Dependabot
|
|
204
266
|
new_requirement_string
|
205
267
|
end
|
206
268
|
|
269
|
+
sig { params(req: String, use_equality_operator: T::Boolean).returns(String) }
|
207
270
|
def serialized_req(req, use_equality_operator)
|
208
271
|
tmp_req = req
|
209
272
|
|
@@ -215,6 +278,7 @@ module Dependabot
|
|
215
278
|
tmp_req.strip
|
216
279
|
end
|
217
280
|
|
281
|
+
sig { params(nodes: T::Array[T.untyped]).returns(T.untyped) }
|
218
282
|
def range_for(nodes)
|
219
283
|
nodes.first.loc.begin.begin.join(nodes.last.loc.expression)
|
220
284
|
end
|
@@ -1,6 +1,8 @@
|
|
1
|
-
# typed:
|
1
|
+
# typed: strong
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
|
+
require "sorbet-runtime"
|
5
|
+
|
4
6
|
require "dependabot/file_updaters"
|
5
7
|
require "dependabot/file_updaters/base"
|
6
8
|
require "dependabot/bundler/native_helpers"
|
@@ -10,10 +12,13 @@ require "dependabot/file_updaters/vendor_updater"
|
|
10
12
|
module Dependabot
|
11
13
|
module Bundler
|
12
14
|
class FileUpdater < Dependabot::FileUpdaters::Base
|
15
|
+
extend T::Sig
|
16
|
+
|
13
17
|
require_relative "file_updater/gemfile_updater"
|
14
18
|
require_relative "file_updater/gemspec_updater"
|
15
19
|
require_relative "file_updater/lockfile_updater"
|
16
20
|
|
21
|
+
sig { override.returns(T::Array[Regexp]) }
|
17
22
|
def self.updated_files_regex
|
18
23
|
[
|
19
24
|
# Matches Gemfile, Gemfile.lock, gems.rb, gems.locked, .gemspec files, and anything in vendor directory
|
@@ -25,20 +30,21 @@ module Dependabot
|
|
25
30
|
|
26
31
|
# rubocop:disable Metrics/PerceivedComplexity
|
27
32
|
# rubocop:disable Metrics/AbcSize
|
33
|
+
sig { override.returns(T::Array[Dependabot::DependencyFile]) }
|
28
34
|
def updated_dependency_files
|
29
35
|
updated_files = T.let([], T::Array[Dependabot::DependencyFile])
|
30
36
|
|
31
|
-
if gemfile && file_changed?(gemfile)
|
37
|
+
if gemfile && file_changed?(T.must(gemfile))
|
32
38
|
updated_files <<
|
33
39
|
updated_file(
|
34
|
-
file: gemfile,
|
35
|
-
content: updated_gemfile_content(gemfile)
|
40
|
+
file: T.must(gemfile),
|
41
|
+
content: updated_gemfile_content(T.must(gemfile))
|
36
42
|
)
|
37
43
|
end
|
38
44
|
|
39
45
|
if lockfile && dependencies.any?(&:appears_in_lockfile?)
|
40
46
|
updated_files <<
|
41
|
-
updated_file(file: lockfile, content: updated_lockfile_content)
|
47
|
+
updated_file(file: T.must(lockfile), content: updated_lockfile_content)
|
42
48
|
end
|
43
49
|
|
44
50
|
top_level_gemspecs.each do |file|
|
@@ -59,7 +65,7 @@ module Dependabot
|
|
59
65
|
|
60
66
|
base_dir = T.must(updated_files.first).directory
|
61
67
|
vendor_updater
|
62
|
-
.
|
68
|
+
.updated_files(base_directory: base_dir)
|
63
69
|
.each do |file|
|
64
70
|
updated_files << file
|
65
71
|
end
|
@@ -72,10 +78,9 @@ module Dependabot
|
|
72
78
|
private
|
73
79
|
|
74
80
|
# Dynamically fetch the vendor cache folder from bundler
|
81
|
+
sig { returns(T.nilable(String)) }
|
75
82
|
def vendor_cache_dir
|
76
|
-
|
77
|
-
|
78
|
-
@vendor_cache_dir =
|
83
|
+
@vendor_cache_dir = T.let(
|
79
84
|
NativeHelpers.run_bundler_subprocess(
|
80
85
|
bundler_version: bundler_version,
|
81
86
|
function: "vendor_cache_dir",
|
@@ -83,9 +88,12 @@ module Dependabot
|
|
83
88
|
args: {
|
84
89
|
dir: repo_contents_path
|
85
90
|
}
|
86
|
-
)
|
91
|
+
),
|
92
|
+
T.nilable(String)
|
93
|
+
)
|
87
94
|
end
|
88
95
|
|
96
|
+
sig { returns(Dependabot::FileUpdaters::VendorUpdater) }
|
89
97
|
def vendor_updater
|
90
98
|
Dependabot::FileUpdaters::VendorUpdater.new(
|
91
99
|
repo_contents_path: repo_contents_path,
|
@@ -93,6 +101,7 @@ module Dependabot
|
|
93
101
|
)
|
94
102
|
end
|
95
103
|
|
104
|
+
sig { override.void }
|
96
105
|
def check_required_files
|
97
106
|
file_names = dependency_files.map(&:name)
|
98
107
|
|
@@ -104,24 +113,32 @@ module Dependabot
|
|
104
113
|
raise "A gemspec or Gemfile must be provided!"
|
105
114
|
end
|
106
115
|
|
116
|
+
sig { params(updated_files: T::Array[Dependabot::DependencyFile]).void }
|
107
117
|
def check_updated_files(updated_files)
|
108
118
|
return if updated_files.reject { |f| dependency_files.include?(f) }.any?
|
109
119
|
|
110
120
|
raise "No files have changed!"
|
111
121
|
end
|
112
122
|
|
123
|
+
sig { returns(T.nilable(Dependabot::DependencyFile)) }
|
113
124
|
def gemfile
|
114
|
-
@gemfile ||=
|
115
|
-
|
125
|
+
@gemfile ||= T.let(
|
126
|
+
get_original_file("Gemfile") || get_original_file("gems.rb"),
|
127
|
+
T.nilable(Dependabot::DependencyFile)
|
128
|
+
)
|
116
129
|
end
|
117
130
|
|
131
|
+
sig { returns(T.nilable(Dependabot::DependencyFile)) }
|
118
132
|
def lockfile
|
119
|
-
@lockfile ||=
|
120
|
-
|
133
|
+
@lockfile ||= T.let(
|
134
|
+
get_original_file("Gemfile.lock") || get_original_file("gems.locked"),
|
135
|
+
T.nilable(Dependabot::DependencyFile)
|
136
|
+
)
|
121
137
|
end
|
122
138
|
|
139
|
+
sig { returns(T::Array[Dependabot::DependencyFile]) }
|
123
140
|
def evaled_gemfiles
|
124
|
-
@evaled_gemfiles ||=
|
141
|
+
@evaled_gemfiles ||= T.let(
|
125
142
|
dependency_files
|
126
143
|
.reject { |f| f.name.end_with?(".gemspec") }
|
127
144
|
.reject { |f| f.name.end_with?(".specification") }
|
@@ -129,9 +146,12 @@ module Dependabot
|
|
129
146
|
.reject { |f| f.name == "Gemfile" }
|
130
147
|
.reject { |f| f.name == "gems.rb" }
|
131
148
|
.reject { |f| f.name == "gems.locked" }
|
132
|
-
.reject(&:support_file?)
|
149
|
+
.reject(&:support_file?),
|
150
|
+
T.nilable(T::Array[Dependabot::DependencyFile])
|
151
|
+
)
|
133
152
|
end
|
134
153
|
|
154
|
+
sig { params(file: Dependabot::DependencyFile).returns(String) }
|
135
155
|
def updated_gemfile_content(file)
|
136
156
|
GemfileUpdater.new(
|
137
157
|
dependencies: dependencies,
|
@@ -139,6 +159,7 @@ module Dependabot
|
|
139
159
|
).updated_gemfile_content
|
140
160
|
end
|
141
161
|
|
162
|
+
sig { params(gemspec: Dependabot::DependencyFile).returns(String) }
|
142
163
|
def updated_gemspec_content(gemspec)
|
143
164
|
GemspecUpdater.new(
|
144
165
|
dependencies: dependencies,
|
@@ -146,24 +167,32 @@ module Dependabot
|
|
146
167
|
).updated_gemspec_content
|
147
168
|
end
|
148
169
|
|
170
|
+
sig { returns(String) }
|
149
171
|
def updated_lockfile_content
|
150
|
-
@updated_lockfile_content ||=
|
172
|
+
@updated_lockfile_content ||= T.let(
|
151
173
|
LockfileUpdater.new(
|
152
174
|
dependencies: dependencies,
|
153
175
|
dependency_files: dependency_files,
|
154
176
|
repo_contents_path: repo_contents_path,
|
155
177
|
credentials: credentials,
|
156
178
|
options: options
|
157
|
-
).updated_lockfile_content
|
179
|
+
).updated_lockfile_content,
|
180
|
+
T.nilable(String)
|
181
|
+
)
|
158
182
|
end
|
159
183
|
|
184
|
+
sig { returns(T::Array[Dependabot::DependencyFile]) }
|
160
185
|
def top_level_gemspecs
|
161
186
|
dependency_files
|
162
187
|
.select { |file| file.name.end_with?(".gemspec") }
|
163
188
|
end
|
164
189
|
|
190
|
+
sig { returns(String) }
|
165
191
|
def bundler_version
|
166
|
-
@bundler_version ||=
|
192
|
+
@bundler_version ||= T.let(
|
193
|
+
Helpers.bundler_version(lockfile),
|
194
|
+
T.nilable(String)
|
195
|
+
)
|
167
196
|
end
|
168
197
|
end
|
169
198
|
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
# typed:
|
1
|
+
# typed: strict
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
4
|
require "excon"
|
@@ -9,7 +9,9 @@ require "dependabot/registry_client"
|
|
9
9
|
module Dependabot
|
10
10
|
module Bundler
|
11
11
|
class MetadataFinder < Dependabot::MetadataFinders::Base
|
12
|
-
|
12
|
+
extend T::Sig
|
13
|
+
|
14
|
+
SOURCE_KEYS = T.let(%w(
|
13
15
|
source_code_uri
|
14
16
|
homepage_uri
|
15
17
|
wiki_uri
|
@@ -18,8 +20,22 @@ module Dependabot
|
|
18
20
|
changelog_uri
|
19
21
|
mailing_list_uri
|
20
22
|
download_uri
|
21
|
-
).freeze
|
23
|
+
).freeze, T::Array[String])
|
24
|
+
|
25
|
+
sig do
|
26
|
+
params(
|
27
|
+
dependency: Dependabot::Dependency,
|
28
|
+
credentials: T::Array[Dependabot::Credential]
|
29
|
+
).void
|
30
|
+
end
|
31
|
+
def initialize(dependency:, credentials:)
|
32
|
+
super
|
33
|
+
@rubygems_marshalled_gemspec_response = T.let(nil, T.nilable(String))
|
34
|
+
@rubygems_api_response = T.let(nil, T.nilable(T::Hash[String, T.untyped]))
|
35
|
+
@base_url = T.let(nil, T.nilable(String))
|
36
|
+
end
|
22
37
|
|
38
|
+
sig { override.returns(T.nilable(String)) }
|
23
39
|
def homepage_url
|
24
40
|
return super unless %w(default rubygems).include?(new_source_type)
|
25
41
|
return super unless rubygems_api_response["homepage_uri"]
|
@@ -29,6 +45,7 @@ module Dependabot
|
|
29
45
|
|
30
46
|
private
|
31
47
|
|
48
|
+
sig { override.returns(T.nilable(Dependabot::Source)) }
|
32
49
|
def look_up_source
|
33
50
|
case new_source_type
|
34
51
|
when "git" then find_source_from_git_url
|
@@ -37,6 +54,7 @@ module Dependabot
|
|
37
54
|
end
|
38
55
|
end
|
39
56
|
|
57
|
+
sig { override.returns(T.nilable(String)) }
|
40
58
|
def suggested_changelog_url
|
41
59
|
case new_source_type
|
42
60
|
when "default"
|
@@ -50,10 +68,12 @@ module Dependabot
|
|
50
68
|
end
|
51
69
|
end
|
52
70
|
|
71
|
+
sig { returns(String) }
|
53
72
|
def new_source_type
|
54
|
-
dependency.source_type
|
73
|
+
T.must(dependency.source_type)
|
55
74
|
end
|
56
75
|
|
76
|
+
sig { returns(T.nilable(Dependabot::Source)) }
|
57
77
|
def find_source_from_rubygems
|
58
78
|
api_source = find_source_from_rubygems_api_response
|
59
79
|
return api_source if api_source || new_source_type == "default"
|
@@ -61,15 +81,16 @@ module Dependabot
|
|
61
81
|
find_source_from_gemspec_download
|
62
82
|
end
|
63
83
|
|
84
|
+
sig { returns(T.nilable(Dependabot::Source)) }
|
64
85
|
def find_source_from_rubygems_api_response
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
.find { |url| Source.from_url(url) }
|
86
|
+
api_response = rubygems_api_response
|
87
|
+
source_url = SOURCE_KEYS.filter_map { |key| api_response[key] }
|
88
|
+
.find { |url| Source.from_url(url) }
|
69
89
|
|
70
90
|
Source.from_url(source_url)
|
71
91
|
end
|
72
92
|
|
93
|
+
sig { returns(T.nilable(Dependabot::Source)) }
|
73
94
|
def find_source_from_git_url
|
74
95
|
info = dependency.requirements.filter_map { |r| r[:source] }.first
|
75
96
|
|
@@ -77,12 +98,13 @@ module Dependabot
|
|
77
98
|
Source.from_url(url)
|
78
99
|
end
|
79
100
|
|
101
|
+
sig { returns(T.nilable(Dependabot::Source)) }
|
80
102
|
def find_source_from_gemspec_download
|
81
103
|
github_urls = []
|
82
104
|
return unless rubygems_marshalled_gemspec_response
|
83
105
|
|
84
|
-
rubygems_marshalled_gemspec_response.gsub("\x06;", "\n")
|
85
|
-
|
106
|
+
T.must(rubygems_marshalled_gemspec_response).gsub("\x06;", "\n")
|
107
|
+
.scan(Source::SOURCE_REGEX) do
|
86
108
|
github_urls << Regexp.last_match.to_s
|
87
109
|
end
|
88
110
|
|
@@ -95,12 +117,13 @@ module Dependabot
|
|
95
117
|
Source.from_url(source_url)
|
96
118
|
end
|
97
119
|
|
120
|
+
sig { returns(T.nilable(String)) }
|
98
121
|
def changelog_url_from_gemspec_download
|
99
122
|
github_urls = []
|
100
123
|
return unless rubygems_marshalled_gemspec_response
|
101
124
|
|
102
|
-
rubygems_marshalled_gemspec_response.gsub("\x06;", "\n")
|
103
|
-
|
125
|
+
T.must(rubygems_marshalled_gemspec_response).gsub("\x06;", "\n")
|
126
|
+
.scan(Dependabot::Source::SOURCE_REGEX) do
|
104
127
|
github_urls << (Regexp.last_match.to_s +
|
105
128
|
T.must(T.must(Regexp.last_match).post_match.split("\n").first))
|
106
129
|
end
|
@@ -115,8 +138,9 @@ module Dependabot
|
|
115
138
|
|
116
139
|
# NOTE: This response MUST NOT be unmarshalled
|
117
140
|
# (as calling Marshal.load is unsafe)
|
141
|
+
sig { returns(T.nilable(String)) }
|
118
142
|
def rubygems_marshalled_gemspec_response
|
119
|
-
return @rubygems_marshalled_gemspec_response if
|
143
|
+
return @rubygems_marshalled_gemspec_response if @rubygems_marshalled_gemspec_response
|
120
144
|
|
121
145
|
gemspec_uri =
|
122
146
|
"#{registry_url}quick/Marshal.4.8/" \
|
@@ -136,8 +160,9 @@ module Dependabot
|
|
136
160
|
@rubygems_marshalled_gemspec_response = nil
|
137
161
|
end
|
138
162
|
|
163
|
+
sig { returns(T::Hash[String, T.untyped]) }
|
139
164
|
def rubygems_api_response
|
140
|
-
return @rubygems_api_response if
|
165
|
+
return @rubygems_api_response if @rubygems_api_response
|
141
166
|
|
142
167
|
response =
|
143
168
|
Dependabot::RegistryClient.get(
|
@@ -155,16 +180,18 @@ module Dependabot
|
|
155
180
|
@rubygems_api_response = {}
|
156
181
|
end
|
157
182
|
|
183
|
+
sig { params(listing: T::Hash[String, T.untyped]).returns(T::Hash[String, T.untyped]) }
|
158
184
|
def append_slash_to_source_code_uri(listing)
|
159
185
|
# We have to do this so that `Source.from_url(...)` doesn't prune the
|
160
186
|
# last line off of the directory.
|
161
|
-
return listing unless listing
|
162
|
-
return listing if listing.fetch("source_code_uri").end_with?("/")
|
187
|
+
return listing unless listing.fetch("source_code_uri", nil)
|
188
|
+
return listing if T.cast(listing.fetch("source_code_uri"), String).end_with?("/")
|
163
189
|
|
164
|
-
listing["source_code_uri"] = listing["source_code_uri"] + "/"
|
190
|
+
listing["source_code_uri"] = T.cast(listing["source_code_uri"], String) + "/"
|
165
191
|
listing
|
166
192
|
end
|
167
193
|
|
194
|
+
sig { params(response_body: String).returns(String) }
|
168
195
|
def augment_private_response_if_appropriate(response_body)
|
169
196
|
return response_body if new_source_type == "default"
|
170
197
|
|
@@ -173,10 +200,8 @@ module Dependabot
|
|
173
200
|
|
174
201
|
digest = parsed_body.values_at("version", "authors", "info").hash
|
175
202
|
|
176
|
-
source_url = parsed_body
|
177
|
-
|
178
|
-
.compact
|
179
|
-
.find { |url| Source.from_url(url) }
|
203
|
+
source_url = SOURCE_KEYS.filter_map { |key| parsed_body[key] }
|
204
|
+
.find { |url| Source.from_url(url) }
|
180
205
|
return response_body if source_url
|
181
206
|
|
182
207
|
rubygems_response =
|
@@ -190,6 +215,7 @@ module Dependabot
|
|
190
215
|
response_body
|
191
216
|
end
|
192
217
|
|
218
|
+
sig { returns(String) }
|
193
219
|
def registry_url
|
194
220
|
return base_url if new_source_type == "default"
|
195
221
|
|
@@ -197,8 +223,9 @@ module Dependabot
|
|
197
223
|
info[:url] || info.fetch("url")
|
198
224
|
end
|
199
225
|
|
226
|
+
sig { returns(String) }
|
200
227
|
def base_url
|
201
|
-
return @base_url if
|
228
|
+
return @base_url if @base_url
|
202
229
|
|
203
230
|
credential = credentials.find do |cred|
|
204
231
|
cred["type"] == "rubygems_server" && cred.replaces_base?
|
@@ -207,6 +234,7 @@ module Dependabot
|
|
207
234
|
@base_url = "https://#{host}#{'/' unless host&.end_with?('/')}"
|
208
235
|
end
|
209
236
|
|
237
|
+
sig { returns(T::Hash[String, String]) }
|
210
238
|
def registry_auth_headers
|
211
239
|
return {} unless new_source_type == "rubygems"
|
212
240
|
|
@@ -1,4 +1,4 @@
|
|
1
|
-
# typed:
|
1
|
+
# typed: strict
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
4
|
require "sorbet-runtime"
|
@@ -26,9 +26,10 @@ module Dependabot
|
|
26
26
|
|
27
27
|
# Patches Gem::Requirement to make it accept requirement strings like
|
28
28
|
# "~> 4.2.5, >= 4.2.5.1" without first needing to split them.
|
29
|
+
sig { params(requirements: T.nilable(T.any(String, T::Array[String]))).void }
|
29
30
|
def initialize(*requirements)
|
30
31
|
requirements = requirements.flatten.flat_map do |req_string|
|
31
|
-
req_string.split(",").map(&:strip)
|
32
|
+
T.must(req_string).split(",").map(&:strip)
|
32
33
|
end
|
33
34
|
|
34
35
|
super(requirements)
|