dependabot-npm_and_yarn 0.309.0 → 0.310.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/npm_and_yarn/file_parser/pnpm_lock.rb +60 -19
- data/lib/dependabot/npm_and_yarn/file_parser/yarn_lock.rb +37 -16
- data/lib/dependabot/npm_and_yarn/file_updater/bun_lockfile_updater.rb +60 -19
- data/lib/dependabot/npm_and_yarn/file_updater/package_json_preparer.rb +16 -4
- data/lib/dependabot/npm_and_yarn/file_updater/yarn_lockfile_updater.rb +211 -60
- data/lib/dependabot/npm_and_yarn/file_updater.rb +1 -1
- data/lib/dependabot/npm_and_yarn/metadata_finder.rb +56 -15
- data/lib/dependabot/npm_and_yarn/native_helpers.rb +8 -1
- data/lib/dependabot/npm_and_yarn/package/registry_finder.rb +1 -1
- data/lib/dependabot/npm_and_yarn/requirement.rb +23 -9
- data/lib/dependabot/npm_and_yarn/update_checker/conflicting_dependency_resolver.rb +36 -9
- data/lib/dependabot/npm_and_yarn/update_checker/dependency_files_builder.rb +82 -24
- data/lib/dependabot/npm_and_yarn/update_checker/library_detector.rb +35 -5
- data/lib/dependabot/npm_and_yarn/update_checker/requirements_updater.rb +61 -24
- data/lib/dependabot/npm_and_yarn/update_checker/vulnerability_auditor.rb +60 -7
- data/lib/dependabot/npm_and_yarn/update_checker.rb +3 -3
- metadata +5 -5
@@ -1,8 +1,9 @@
|
|
1
|
-
# typed:
|
1
|
+
# typed: strict
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
4
|
require "excon"
|
5
5
|
require "time"
|
6
|
+
require "sorbet-runtime"
|
6
7
|
|
7
8
|
require "dependabot/metadata_finders"
|
8
9
|
require "dependabot/metadata_finders/base"
|
@@ -13,6 +14,9 @@ require "dependabot/npm_and_yarn/version"
|
|
13
14
|
module Dependabot
|
14
15
|
module NpmAndYarn
|
15
16
|
class MetadataFinder < Dependabot::MetadataFinders::Base
|
17
|
+
extend T::Sig
|
18
|
+
|
19
|
+
sig { override.returns(T.nilable(String)) }
|
16
20
|
def homepage_url
|
17
21
|
# Attempt to use version_listing first, as fetching the entire listing
|
18
22
|
# array can be slow (if it's large)
|
@@ -22,10 +26,11 @@ module Dependabot
|
|
22
26
|
listing&.last&.fetch("homepage", nil) || super
|
23
27
|
end
|
24
28
|
|
29
|
+
sig { override.returns(T.nilable(String)) }
|
25
30
|
def maintainer_changes
|
26
31
|
return unless npm_releaser
|
27
32
|
return unless npm_listing.dig("time", dependency.version)
|
28
|
-
return if previous_releasers
|
33
|
+
return if previous_releasers&.include?(npm_releaser)
|
29
34
|
|
30
35
|
"This version was pushed to npm by " \
|
31
36
|
"[#{npm_releaser}](https://www.npmjs.com/~#{npm_releaser}), a new " \
|
@@ -34,10 +39,11 @@ module Dependabot
|
|
34
39
|
|
35
40
|
private
|
36
41
|
|
42
|
+
sig { override.returns(T.nilable(Dependabot::Source)) }
|
37
43
|
def look_up_source
|
38
44
|
return find_source_from_registry if new_source.nil?
|
39
45
|
|
40
|
-
source_type = new_source[:type
|
46
|
+
source_type = new_source&.[](:type) || new_source&.fetch("type")
|
41
47
|
|
42
48
|
case source_type
|
43
49
|
when "git" then find_source_from_git_url
|
@@ -46,12 +52,14 @@ module Dependabot
|
|
46
52
|
end
|
47
53
|
end
|
48
54
|
|
55
|
+
sig { returns(T.nilable(String)) }
|
49
56
|
def npm_releaser
|
50
57
|
all_version_listings
|
51
58
|
.find { |v, _| v == dependency.version }
|
52
59
|
&.last&.fetch("_npmUser", nil)&.fetch("name", nil)
|
53
60
|
end
|
54
61
|
|
62
|
+
sig { returns(T.nilable(T::Array[String])) }
|
55
63
|
def previous_releasers
|
56
64
|
times = npm_listing.fetch("time")
|
57
65
|
|
@@ -68,6 +76,7 @@ module Dependabot
|
|
68
76
|
.filter_map { |_, d| d.fetch("_npmUser", nil)&.fetch("name", nil) }
|
69
77
|
end
|
70
78
|
|
79
|
+
sig { returns(T.nilable(Dependabot::Source)) }
|
71
80
|
def find_source_from_registry
|
72
81
|
# Attempt to use version_listing first, as fetching the entire listing
|
73
82
|
# array can be slow (if it's large)
|
@@ -92,6 +101,7 @@ module Dependabot
|
|
92
101
|
potential_sources.first
|
93
102
|
end
|
94
103
|
|
104
|
+
sig { returns(T.nilable(T::Hash[T.any(String, Symbol), T.untyped])) }
|
95
105
|
def new_source
|
96
106
|
sources = dependency.requirements
|
97
107
|
.map { |r| r.fetch(:source) }.uniq.compact
|
@@ -100,6 +110,12 @@ module Dependabot
|
|
100
110
|
sources.first
|
101
111
|
end
|
102
112
|
|
113
|
+
sig do
|
114
|
+
params(
|
115
|
+
details: T.nilable(T.any(String, T::Hash[String, T.untyped]))
|
116
|
+
)
|
117
|
+
.returns(T.nilable(Dependabot::Source))
|
118
|
+
end
|
103
119
|
def get_source(details)
|
104
120
|
potential_url = get_url(details)
|
105
121
|
return unless potential_url
|
@@ -111,6 +127,12 @@ module Dependabot
|
|
111
127
|
potential_source
|
112
128
|
end
|
113
129
|
|
130
|
+
sig do
|
131
|
+
params(
|
132
|
+
details: T.nilable(T.any(String, T::Hash[String, T.untyped]))
|
133
|
+
)
|
134
|
+
.returns(T.nilable(String))
|
135
|
+
end
|
114
136
|
def get_url(details)
|
115
137
|
url =
|
116
138
|
case details
|
@@ -122,6 +144,12 @@ module Dependabot
|
|
122
144
|
"https://github.com/" + url
|
123
145
|
end
|
124
146
|
|
147
|
+
sig do
|
148
|
+
params(
|
149
|
+
details: T.nilable(T.any(String, T::Hash[String, T.untyped]))
|
150
|
+
)
|
151
|
+
.returns(T.nilable(String))
|
152
|
+
end
|
125
153
|
def get_directory(details)
|
126
154
|
# Only return a directory if it is explicitly specified
|
127
155
|
return unless details.is_a?(Hash)
|
@@ -129,22 +157,27 @@ module Dependabot
|
|
129
157
|
details.fetch("directory", nil)
|
130
158
|
end
|
131
159
|
|
160
|
+
sig { returns(T.nilable(Dependabot::Source)) }
|
132
161
|
def find_source_from_git_url
|
133
|
-
url = new_source[:url
|
162
|
+
url = new_source&.[](:url) || new_source&.fetch("url")
|
134
163
|
Source.from_url(url)
|
135
164
|
end
|
136
165
|
|
166
|
+
sig { returns(T::Hash[String, T.untyped]) }
|
137
167
|
def latest_version_listing
|
138
|
-
return @latest_version_listing if defined?(@latest_version_listing)
|
168
|
+
return @latest_version_listing if defined?(@latest_version_listing) && @latest_version_listing
|
169
|
+
|
170
|
+
@latest_version_listing = T.let({}, T.nilable(T::Hash[String, T.untyped]))
|
139
171
|
|
140
172
|
response = Dependabot::RegistryClient.get(url: "#{dependency_url}/latest", headers: registry_auth_headers)
|
141
|
-
|
173
|
+
@latest_version_listing = JSON.parse(response.body) if response.status == 200
|
142
174
|
|
143
|
-
@latest_version_listing
|
175
|
+
@latest_version_listing
|
144
176
|
rescue JSON::ParserError, Excon::Error::Timeout
|
145
|
-
@latest_version_listing
|
177
|
+
@latest_version_listing
|
146
178
|
end
|
147
179
|
|
180
|
+
sig { returns(T::Array[[String, T::Hash[String, T.untyped]]]) }
|
148
181
|
def all_version_listings
|
149
182
|
return [] if npm_listing["versions"].nil?
|
150
183
|
|
@@ -154,28 +187,32 @@ module Dependabot
|
|
154
187
|
.reverse
|
155
188
|
end
|
156
189
|
|
190
|
+
sig { returns(T::Hash[String, T.untyped]) }
|
157
191
|
def npm_listing
|
158
|
-
return @npm_listing
|
192
|
+
return @npm_listing if defined?(@npm_listing) && @npm_listing
|
193
|
+
|
194
|
+
@npm_listing = T.let({}, T.nilable(T::Hash[String, T.untyped]))
|
159
195
|
|
160
196
|
response = Dependabot::RegistryClient.get(url: dependency_url, headers: registry_auth_headers)
|
161
|
-
return @npm_listing
|
197
|
+
return T.must(@npm_listing) if response.status >= 500
|
162
198
|
|
163
199
|
begin
|
164
200
|
@npm_listing = JSON.parse(response.body)
|
165
201
|
rescue JSON::ParserError
|
166
202
|
raise unless non_standard_registry?
|
167
|
-
|
168
|
-
@npm_listing = {}
|
169
203
|
end
|
204
|
+
|
205
|
+
@npm_listing
|
170
206
|
rescue Excon::Error::Timeout
|
171
|
-
@npm_listing
|
207
|
+
@npm_listing
|
172
208
|
end
|
173
209
|
|
210
|
+
sig { returns(String) }
|
174
211
|
def dependency_url
|
175
212
|
registry_url =
|
176
213
|
if new_source.nil? then "https://registry.npmjs.org"
|
177
214
|
else
|
178
|
-
new_source
|
215
|
+
new_source&.fetch(:url)
|
179
216
|
end
|
180
217
|
|
181
218
|
# NPM registries expect slashes to be escaped
|
@@ -183,19 +220,22 @@ module Dependabot
|
|
183
220
|
"#{registry_url}/#{escaped_dependency_name}"
|
184
221
|
end
|
185
222
|
|
223
|
+
sig { returns(T::Hash[String, String]) }
|
186
224
|
def registry_auth_headers
|
187
225
|
return {} unless auth_token
|
188
226
|
|
189
227
|
{ "Authorization" => "Bearer #{auth_token}" }
|
190
228
|
end
|
191
229
|
|
230
|
+
sig { returns(String) }
|
192
231
|
def dependency_registry
|
193
232
|
if new_source.nil? then "registry.npmjs.org"
|
194
233
|
else
|
195
|
-
new_source
|
234
|
+
new_source&.fetch(:url)&.gsub("https://", "")&.gsub("http://", "")
|
196
235
|
end
|
197
236
|
end
|
198
237
|
|
238
|
+
sig { returns(T.nilable(String)) }
|
199
239
|
def auth_token
|
200
240
|
credentials
|
201
241
|
.select { |cred| cred["type"] == "npm_registry" }
|
@@ -203,6 +243,7 @@ module Dependabot
|
|
203
243
|
&.fetch("token", nil)
|
204
244
|
end
|
205
245
|
|
246
|
+
sig { returns(T::Boolean) }
|
206
247
|
def non_standard_registry?
|
207
248
|
dependency_registry != "registry.npmjs.org"
|
208
249
|
end
|
@@ -1,13 +1,19 @@
|
|
1
|
-
# typed:
|
1
|
+
# typed: strong
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
|
+
require "sorbet-runtime"
|
5
|
+
|
4
6
|
module Dependabot
|
5
7
|
module NpmAndYarn
|
6
8
|
module NativeHelpers
|
9
|
+
extend T::Sig
|
10
|
+
|
11
|
+
sig { returns(String) }
|
7
12
|
def self.helper_path
|
8
13
|
"node #{File.join(native_helpers_root, 'run.js')}"
|
9
14
|
end
|
10
15
|
|
16
|
+
sig { returns(String) }
|
11
17
|
def self.native_helpers_root
|
12
18
|
helpers_root = ENV.fetch("DEPENDABOT_NATIVE_HELPERS_PATH", nil)
|
13
19
|
return File.join(helpers_root, "npm_and_yarn") unless helpers_root.nil?
|
@@ -15,6 +21,7 @@ module Dependabot
|
|
15
21
|
File.join(__dir__, "../../../helpers")
|
16
22
|
end
|
17
23
|
|
24
|
+
sig { params(dependency_names: T::Array[String]).returns(String) }
|
18
25
|
def self.run_npm8_subdependency_update_command(dependency_names)
|
19
26
|
# NOTE: npm options
|
20
27
|
# - `--force` ignores checks for platform (os, cpu) and engines
|
@@ -84,7 +84,7 @@ module Dependabot
|
|
84
84
|
end
|
85
85
|
end
|
86
86
|
|
87
|
-
sig { params(dependency_name: String).returns(
|
87
|
+
sig { params(dependency_name: String).returns(String) }
|
88
88
|
def registry_from_rc(dependency_name)
|
89
89
|
explicit_registry_from_rc(dependency_name) || global_registry
|
90
90
|
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
# typed:
|
1
|
+
# typed: strict
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
4
|
require "sorbet-runtime"
|
@@ -12,16 +12,22 @@ module Dependabot
|
|
12
12
|
class Requirement < Dependabot::Requirement
|
13
13
|
extend T::Sig
|
14
14
|
|
15
|
-
AND_SEPARATOR = /(?<=[a-zA-Z0-9*])\s+(?:&+\s+)?(?!\s*[|-])
|
16
|
-
OR_SEPARATOR = /(?<=[a-zA-Z0-9*])\s
|
15
|
+
AND_SEPARATOR = T.let(/(?<=[a-zA-Z0-9*])\s+(?:&+\s+)?(?!\s*[|-])/, Regexp)
|
16
|
+
OR_SEPARATOR = T.let(/(?<=[a-zA-Z0-9*])\s*\|+/, Regexp)
|
17
17
|
|
18
18
|
# Override the version pattern to allow a 'v' prefix
|
19
19
|
quoted = OPS.keys.map { |k| Regexp.quote(k) }.join("|")
|
20
20
|
version_pattern = "v?#{NpmAndYarn::Version::VERSION_PATTERN}"
|
21
21
|
|
22
|
-
PATTERN_RAW = "\\s*(#{quoted})?\\s*(#{version_pattern})\\s*".freeze
|
23
|
-
PATTERN = /\A#{PATTERN_RAW}\z
|
22
|
+
PATTERN_RAW = T.let("\\s*(#{quoted})?\\s*(#{version_pattern})\\s*".freeze, String)
|
23
|
+
PATTERN = T.let(/\A#{PATTERN_RAW}\z/, Regexp)
|
24
24
|
|
25
|
+
sig do
|
26
|
+
params(
|
27
|
+
obj: T.any(String, Gem::Version)
|
28
|
+
)
|
29
|
+
.returns(T::Array[T.any(String, T.nilable(NpmAndYarn::Version))])
|
30
|
+
end
|
25
31
|
def self.parse(obj)
|
26
32
|
return ["=", nil] if obj.is_a?(String) && Version::VERSION_TAGS.include?(obj.strip)
|
27
33
|
return ["=", NpmAndYarn::Version.new(obj.to_s)] if obj.is_a?(Gem::Version)
|
@@ -52,16 +58,18 @@ module Dependabot
|
|
52
58
|
end
|
53
59
|
end
|
54
60
|
|
61
|
+
sig { params(requirements: T.nilable(T.any(String, T::Array[String]))).void }
|
55
62
|
def initialize(*requirements)
|
56
63
|
requirements = requirements.flatten
|
57
|
-
.flat_map { |req_string| req_string.split(",").map(&:strip) }
|
64
|
+
.flat_map { |req_string| T.must(req_string).split(",").map(&:strip) }
|
58
65
|
.flat_map { |req_string| convert_js_constraint_to_ruby_constraint(req_string) }
|
59
66
|
|
60
|
-
super
|
67
|
+
super
|
61
68
|
end
|
62
69
|
|
63
70
|
private
|
64
71
|
|
72
|
+
sig { params(req_string: String).returns(T.any(String, T::Array[String])) }
|
65
73
|
def convert_js_constraint_to_ruby_constraint(req_string)
|
66
74
|
return req_string if req_string.match?(/^([A-Za-uw-z]|v[^\d])/)
|
67
75
|
|
@@ -79,6 +87,7 @@ module Dependabot
|
|
79
87
|
end
|
80
88
|
end
|
81
89
|
|
90
|
+
sig { params(req_string: String).returns(String) }
|
82
91
|
def convert_tilde_req(req_string)
|
83
92
|
version = req_string.gsub(/^~\>?[\s=]*/, "")
|
84
93
|
parts = version.split(".")
|
@@ -86,8 +95,11 @@ module Dependabot
|
|
86
95
|
"~> #{parts.join('.')}"
|
87
96
|
end
|
88
97
|
|
98
|
+
sig { params(req_string: String).returns(T::Array[String]) }
|
89
99
|
def convert_hyphen_req(req_string)
|
90
|
-
|
100
|
+
parts = req_string.split(/\s+-\s+/)
|
101
|
+
lower_bound = T.must(parts[0])
|
102
|
+
upper_bound = T.must(parts[1])
|
91
103
|
lower_bound_parts = lower_bound.split(".")
|
92
104
|
lower_bound_parts.fill("0", lower_bound_parts.length...3)
|
93
105
|
|
@@ -105,6 +117,7 @@ module Dependabot
|
|
105
117
|
[">= #{lower_bound_parts.join('.')}", upper_bound_range]
|
106
118
|
end
|
107
119
|
|
120
|
+
sig { params(req_string: String).returns(String) }
|
108
121
|
def ruby_range(req_string)
|
109
122
|
parts = req_string.split(".")
|
110
123
|
# If we have three or more parts then this is an exact match
|
@@ -115,13 +128,14 @@ module Dependabot
|
|
115
128
|
"~> #{parts.join('.')}"
|
116
129
|
end
|
117
130
|
|
131
|
+
sig { params(req_string: String).returns(T::Array[String]) }
|
118
132
|
def convert_caret_req(req_string)
|
119
133
|
version = req_string.gsub(/^\^[\s=]*/, "")
|
120
134
|
parts = version.split(".")
|
121
135
|
parts.fill("x", parts.length...3)
|
122
136
|
first_non_zero = parts.find { |d| d != "0" }
|
123
137
|
first_non_zero_index =
|
124
|
-
first_non_zero ? parts.index(first_non_zero) : parts.count - 1
|
138
|
+
first_non_zero ? T.must(parts.index(first_non_zero)) : parts.count - 1
|
125
139
|
# If the requirement has a blank minor or patch version increment the
|
126
140
|
# previous index value with 1
|
127
141
|
first_non_zero_index -= 1 if first_non_zero == "x"
|
@@ -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/dependency"
|
5
7
|
require "dependabot/errors"
|
6
8
|
require "dependabot/logger"
|
@@ -15,6 +17,15 @@ module Dependabot
|
|
15
17
|
module NpmAndYarn
|
16
18
|
class UpdateChecker < Dependabot::UpdateCheckers::Base
|
17
19
|
class ConflictingDependencyResolver
|
20
|
+
extend T::Sig
|
21
|
+
|
22
|
+
sig do
|
23
|
+
params(
|
24
|
+
dependency_files: T::Array[Dependabot::DependencyFile],
|
25
|
+
credentials: T::Array[Dependabot::Credential]
|
26
|
+
)
|
27
|
+
.void
|
28
|
+
end
|
18
29
|
def initialize(dependency_files:, credentials:)
|
19
30
|
@dependency_files = dependency_files
|
20
31
|
@credentials = credentials
|
@@ -30,6 +41,13 @@ module Dependabot
|
|
30
41
|
# * name [String] the blocking dependencies name
|
31
42
|
# * version [String] the version of the blocking dependency
|
32
43
|
# * requirement [String] the requirement on the target_dependency
|
44
|
+
sig do
|
45
|
+
params(
|
46
|
+
dependency: Dependabot::Dependency,
|
47
|
+
target_version: T.nilable(T.any(String, Dependabot::Version))
|
48
|
+
)
|
49
|
+
.returns(T::Array[T::Hash[String, String]])
|
50
|
+
end
|
33
51
|
def conflicting_dependencies(dependency:, target_version:)
|
34
52
|
SharedHelpers.in_a_temporary_directory do
|
35
53
|
dependency_files_builder = DependencyFilesBuilder.new(
|
@@ -46,16 +64,22 @@ module Dependabot
|
|
46
64
|
# parser doesn't deal with at the moment.
|
47
65
|
if dependency_files_builder.package_locks.any? ||
|
48
66
|
dependency_files_builder.shrinkwraps.any?
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
67
|
+
T.cast(
|
68
|
+
SharedHelpers.run_helper_subprocess(
|
69
|
+
command: NativeHelpers.helper_path,
|
70
|
+
function: "npm:findConflictingDependencies",
|
71
|
+
args: [Dir.pwd, dependency.name, target_version.to_s]
|
72
|
+
),
|
73
|
+
T::Array[T::Hash[String, String]]
|
53
74
|
)
|
54
75
|
else
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
76
|
+
T.cast(
|
77
|
+
SharedHelpers.run_helper_subprocess(
|
78
|
+
command: NativeHelpers.helper_path,
|
79
|
+
function: "yarn:findConflictingDependencies",
|
80
|
+
args: [Dir.pwd, dependency.name, target_version.to_s]
|
81
|
+
),
|
82
|
+
T::Array[T::Hash[String, String]]
|
59
83
|
)
|
60
84
|
end
|
61
85
|
end
|
@@ -65,7 +89,10 @@ module Dependabot
|
|
65
89
|
|
66
90
|
private
|
67
91
|
|
92
|
+
sig { returns(T::Array[Dependabot::DependencyFile]) }
|
68
93
|
attr_reader :dependency_files
|
94
|
+
|
95
|
+
sig { returns(T::Array[Dependabot::Credential]) }
|
69
96
|
attr_reader :credentials
|
70
97
|
end
|
71
98
|
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/npm_and_yarn/file_updater/npmrc_builder"
|
5
7
|
require "dependabot/npm_and_yarn/file_updater/package_json_preparer"
|
6
8
|
|
@@ -8,12 +10,23 @@ module Dependabot
|
|
8
10
|
module NpmAndYarn
|
9
11
|
class UpdateChecker
|
10
12
|
class DependencyFilesBuilder
|
13
|
+
extend T::Sig
|
14
|
+
|
15
|
+
sig do
|
16
|
+
params(
|
17
|
+
dependency: Dependabot::Dependency,
|
18
|
+
dependency_files: T::Array[Dependabot::DependencyFile],
|
19
|
+
credentials: T::Array[Dependabot::Credential]
|
20
|
+
)
|
21
|
+
.void
|
22
|
+
end
|
11
23
|
def initialize(dependency:, dependency_files:, credentials:)
|
12
24
|
@dependency = dependency
|
13
25
|
@dependency_files = dependency_files
|
14
26
|
@credentials = credentials
|
15
27
|
end
|
16
28
|
|
29
|
+
sig { void }
|
17
30
|
def write_temporary_dependency_files
|
18
31
|
write_lockfiles
|
19
32
|
|
@@ -31,74 +44,108 @@ module Dependabot
|
|
31
44
|
end
|
32
45
|
end
|
33
46
|
|
47
|
+
sig { returns(T::Array[Dependabot::DependencyFile]) }
|
34
48
|
def package_locks
|
35
|
-
@package_locks ||=
|
49
|
+
@package_locks ||= T.let(
|
36
50
|
dependency_files
|
37
|
-
.select { |f| f.name.end_with?("package-lock.json") }
|
51
|
+
.select { |f| f.name.end_with?("package-lock.json") },
|
52
|
+
T.nilable(T::Array[Dependabot::DependencyFile])
|
53
|
+
)
|
38
54
|
end
|
39
55
|
|
56
|
+
sig { returns(T::Array[Dependabot::DependencyFile]) }
|
40
57
|
def yarn_locks
|
41
|
-
@yarn_locks ||=
|
58
|
+
@yarn_locks ||= T.let(
|
42
59
|
dependency_files
|
43
|
-
.select { |f| f.name.end_with?("yarn.lock") }
|
60
|
+
.select { |f| f.name.end_with?("yarn.lock") },
|
61
|
+
T.nilable(T::Array[Dependabot::DependencyFile])
|
62
|
+
)
|
44
63
|
end
|
45
64
|
|
65
|
+
sig { returns(T::Array[Dependabot::DependencyFile]) }
|
46
66
|
def pnpm_locks
|
47
|
-
@pnpm_locks ||=
|
67
|
+
@pnpm_locks ||= T.let(
|
48
68
|
dependency_files
|
49
|
-
.select { |f| f.name.end_with?("pnpm-lock.yaml") }
|
69
|
+
.select { |f| f.name.end_with?("pnpm-lock.yaml") },
|
70
|
+
T.nilable(T::Array[Dependabot::DependencyFile])
|
71
|
+
)
|
50
72
|
end
|
51
73
|
|
74
|
+
sig { returns(T::Array[Dependabot::DependencyFile]) }
|
52
75
|
def bun_locks
|
53
|
-
@bun_locks ||=
|
76
|
+
@bun_locks ||= T.let(
|
54
77
|
dependency_files
|
55
|
-
.select { |f| f.name.end_with?("bun.lock") }
|
78
|
+
.select { |f| f.name.end_with?("bun.lock") },
|
79
|
+
T.nilable(T::Array[Dependabot::DependencyFile])
|
80
|
+
)
|
56
81
|
end
|
57
82
|
|
83
|
+
sig { returns(T.nilable(Dependabot::DependencyFile)) }
|
58
84
|
def root_yarn_lock
|
59
|
-
@root_yarn_lock ||=
|
85
|
+
@root_yarn_lock ||= T.let(
|
60
86
|
dependency_files
|
61
|
-
.find { |f| f.name == "yarn.lock" }
|
87
|
+
.find { |f| f.name == "yarn.lock" },
|
88
|
+
T.nilable(Dependabot::DependencyFile)
|
89
|
+
)
|
62
90
|
end
|
63
91
|
|
92
|
+
sig { returns(T.nilable(Dependabot::DependencyFile)) }
|
64
93
|
def root_pnpm_lock
|
65
|
-
@root_pnpm_lock ||=
|
94
|
+
@root_pnpm_lock ||= T.let(
|
66
95
|
dependency_files
|
67
|
-
.find { |f| f.name == "pnpm-lock.yaml" }
|
96
|
+
.find { |f| f.name == "pnpm-lock.yaml" },
|
97
|
+
T.nilable(Dependabot::DependencyFile)
|
98
|
+
)
|
68
99
|
end
|
69
100
|
|
101
|
+
sig { returns(T.nilable(Dependabot::DependencyFile)) }
|
70
102
|
def root_bun_lock
|
71
|
-
@root_bun_lock ||=
|
103
|
+
@root_bun_lock ||= T.let(
|
72
104
|
dependency_files
|
73
|
-
.find { |f| f.name == "bun.lock" }
|
105
|
+
.find { |f| f.name == "bun.lock" },
|
106
|
+
T.nilable(Dependabot::DependencyFile)
|
107
|
+
)
|
74
108
|
end
|
75
109
|
|
110
|
+
sig { returns(T::Array[Dependabot::DependencyFile]) }
|
76
111
|
def shrinkwraps
|
77
|
-
@shrinkwraps ||=
|
112
|
+
@shrinkwraps ||= T.let(
|
78
113
|
dependency_files
|
79
|
-
.select { |f| f.name.end_with?("npm-shrinkwrap.json") }
|
114
|
+
.select { |f| f.name.end_with?("npm-shrinkwrap.json") },
|
115
|
+
T.nilable(T::Array[Dependabot::DependencyFile])
|
116
|
+
)
|
80
117
|
end
|
81
118
|
|
119
|
+
sig { returns(T::Array[Dependabot::DependencyFile]) }
|
82
120
|
def lockfiles
|
83
121
|
[*package_locks, *shrinkwraps, *yarn_locks, *pnpm_locks, *bun_locks]
|
84
122
|
end
|
85
123
|
|
124
|
+
sig { returns(T::Array[Dependabot::DependencyFile]) }
|
86
125
|
def package_files
|
87
|
-
@package_files ||=
|
126
|
+
@package_files ||= T.let(
|
88
127
|
dependency_files
|
89
|
-
.select { |f| f.name.end_with?("package.json") }
|
128
|
+
.select { |f| f.name.end_with?("package.json") },
|
129
|
+
T.nilable(T::Array[Dependabot::DependencyFile])
|
130
|
+
)
|
90
131
|
end
|
91
132
|
|
92
133
|
private
|
93
134
|
|
135
|
+
sig { returns(Dependabot::Dependency) }
|
94
136
|
attr_reader :dependency
|
137
|
+
|
138
|
+
sig { returns(T::Array[Dependabot::DependencyFile]) }
|
95
139
|
attr_reader :dependency_files
|
140
|
+
|
141
|
+
sig { returns(T::Array[Dependabot::Credential]) }
|
96
142
|
attr_reader :credentials
|
97
143
|
|
144
|
+
sig { void }
|
98
145
|
def write_lockfiles
|
99
146
|
yarn_locks.each do |f|
|
100
147
|
FileUtils.mkdir_p(Pathname.new(f.name).dirname)
|
101
|
-
File.write(f.name, prepared_yarn_lockfile_content(f.content))
|
148
|
+
File.write(f.name, prepared_yarn_lockfile_content(T.must(f.content)))
|
102
149
|
end
|
103
150
|
|
104
151
|
[*package_locks, *shrinkwraps, *pnpm_locks, *bun_locks].each do |f|
|
@@ -107,13 +154,16 @@ module Dependabot
|
|
107
154
|
end
|
108
155
|
end
|
109
156
|
|
157
|
+
# rubocop:disable Metrics/PerceivedComplexity
|
158
|
+
sig { returns(T::Boolean) }
|
110
159
|
def yarnrc_specifies_private_reg?
|
111
160
|
return false unless yarnrc_file
|
112
161
|
|
113
162
|
regex = Package::RegistryFinder::YARN_GLOBAL_REGISTRY_REGEX
|
114
163
|
yarnrc_global_registry =
|
115
|
-
yarnrc_file
|
116
|
-
|
164
|
+
yarnrc_file&.content
|
165
|
+
&.lines
|
166
|
+
&.find { |line| line.match?(regex) }
|
117
167
|
&.match(regex)
|
118
168
|
&.named_captures
|
119
169
|
&.fetch("registry")
|
@@ -124,20 +174,24 @@ module Dependabot
|
|
124
174
|
r.include?(T.must(URI(yarnrc_global_registry).host))
|
125
175
|
end
|
126
176
|
end
|
177
|
+
# rubocop:enable Metrics/PerceivedComplexity
|
127
178
|
|
128
179
|
# Duplicated in NpmLockfileUpdater
|
129
180
|
# Remove the dependency we want to update from the lockfile and let
|
130
181
|
# yarn find the latest resolvable version and fix the lockfile
|
182
|
+
sig { params(content: String).returns(String) }
|
131
183
|
def prepared_yarn_lockfile_content(content)
|
132
184
|
content.gsub(/^#{Regexp.quote(dependency.name)}\@.*?\n\n/m, "")
|
133
185
|
end
|
134
186
|
|
187
|
+
sig { params(file: Dependabot::DependencyFile).returns(String) }
|
135
188
|
def prepared_package_json_content(file)
|
136
189
|
NpmAndYarn::FileUpdater::PackageJsonPreparer.new(
|
137
|
-
package_json_content: file.content
|
190
|
+
package_json_content: T.must(file.content)
|
138
191
|
).prepared_content
|
139
192
|
end
|
140
193
|
|
194
|
+
sig { returns(String) }
|
141
195
|
def npmrc_content
|
142
196
|
NpmAndYarn::FileUpdater::NpmrcBuilder.new(
|
143
197
|
credentials: credentials,
|
@@ -145,10 +199,12 @@ module Dependabot
|
|
145
199
|
).npmrc_content
|
146
200
|
end
|
147
201
|
|
202
|
+
sig { returns(T.nilable(Dependabot::DependencyFile)) }
|
148
203
|
def yarnrc_file
|
149
204
|
dependency_files.find { |f| f.name == ".yarnrc" }
|
150
205
|
end
|
151
206
|
|
207
|
+
sig { returns(String) }
|
152
208
|
def yarnrc_content
|
153
209
|
NpmAndYarn::FileUpdater::NpmrcBuilder.new(
|
154
210
|
credentials: credentials,
|
@@ -156,12 +212,14 @@ module Dependabot
|
|
156
212
|
).yarnrc_content
|
157
213
|
end
|
158
214
|
|
215
|
+
sig { returns(T.nilable(Dependabot::DependencyFile)) }
|
159
216
|
def yarnrc_yml_file
|
160
217
|
dependency_files.find { |f| f.name.end_with?(".yarnrc.yml") }
|
161
218
|
end
|
162
219
|
|
220
|
+
sig { returns(T.nilable(String)) }
|
163
221
|
def yarnrc_yml_content
|
164
|
-
yarnrc_yml_file
|
222
|
+
yarnrc_yml_file&.content
|
165
223
|
end
|
166
224
|
end
|
167
225
|
end
|