dependabot-gradle 0.375.0 → 0.376.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
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 927977ff944f07aab10b9338ca71c9540520dc07a97f3db8cf2aa9b27d325d9f
|
|
4
|
+
data.tar.gz: b618b2c6aaeb01de38041a829a0b1f650604df9791889323fe8066388b3e3aeb
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 648c6a0d23f8ae1f8026a10d19e66766a14c29be9e4fe3b46cc6386b0b24e82328e357b9504b40b61612322cddff3ab4ad786beca3a1d5d70dc9e42b321aebaf
|
|
7
|
+
data.tar.gz: 289b073da8a00a76bf0f2b636e8429d76a4472eba85057e4d4630b981b30554a674cbdd23879f3446a78f2a874903089ac00dfdd1f4de44072393245c7ec82e1
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
# typed: strong
|
|
2
2
|
# frozen_string_literal: true
|
|
3
3
|
|
|
4
|
-
require "
|
|
4
|
+
require "fileutils"
|
|
5
5
|
require "shellwords"
|
|
6
|
+
require "sorbet-runtime"
|
|
6
7
|
|
|
7
|
-
require "dependabot/gradle/file_parser"
|
|
8
8
|
require "dependabot/gradle/file_updater"
|
|
9
9
|
|
|
10
10
|
module Dependabot
|
|
@@ -13,6 +13,8 @@ module Dependabot
|
|
|
13
13
|
class LockfileUpdater
|
|
14
14
|
extend T::Sig
|
|
15
15
|
|
|
16
|
+
INIT_SCRIPT_TASK_NAME = T.let("dependabotResolveAll", String)
|
|
17
|
+
|
|
16
18
|
sig { params(dependency_files: T::Array[Dependabot::DependencyFile]).void }
|
|
17
19
|
def initialize(dependency_files:)
|
|
18
20
|
@dependency_files = dependency_files
|
|
@@ -20,67 +22,159 @@ module Dependabot
|
|
|
20
22
|
|
|
21
23
|
sig { params(build_file: Dependabot::DependencyFile).returns(T::Array[Dependabot::DependencyFile]) }
|
|
22
24
|
def update_lockfiles(build_file)
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
end
|
|
25
|
+
root_dir = determine_root_dir(build_file: build_file)
|
|
26
|
+
lockfiles = lockfiles_for_root(root_dir)
|
|
26
27
|
|
|
27
|
-
|
|
28
|
-
return dependency_files unless local_lockfiles.any?
|
|
28
|
+
return dependency_files unless lockfiles.any?
|
|
29
29
|
|
|
30
30
|
updated_files = dependency_files.dup
|
|
31
|
+
|
|
31
32
|
SharedHelpers.in_a_temporary_directory do |temp_dir|
|
|
32
33
|
populate_temp_directory(temp_dir)
|
|
33
|
-
|
|
34
|
-
cwd =
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
# Would prefer to use command line arguments, but they don't work.
|
|
42
|
-
properties_filename = File.join(temp_dir, build_file.directory, "gradle.properties")
|
|
43
|
-
write_properties_file(properties_filename)
|
|
34
|
+
|
|
35
|
+
cwd = File.join(temp_dir, root_dir == "/" ? "" : root_dir.delete_prefix("/"))
|
|
36
|
+
FileUtils.mkdir_p(cwd)
|
|
37
|
+
|
|
38
|
+
write_properties_file(File.join(cwd, "gradle.properties"))
|
|
39
|
+
|
|
40
|
+
init_script_path = File.join(cwd, "dependabot-locking.init.gradle")
|
|
41
|
+
write_init_script(init_script_path)
|
|
44
42
|
|
|
45
43
|
command_parts = [
|
|
46
44
|
"gradle",
|
|
47
|
-
"
|
|
48
|
-
|
|
49
|
-
"--write-locks"
|
|
45
|
+
"--init-script", init_script_path,
|
|
46
|
+
INIT_SCRIPT_TASK_NAME,
|
|
47
|
+
"--write-locks",
|
|
48
|
+
"--no-daemon"
|
|
50
49
|
]
|
|
51
50
|
command = Shellwords.join(command_parts)
|
|
52
51
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
end
|
|
52
|
+
SharedHelpers.run_shell_command(command, cwd: cwd)
|
|
53
|
+
|
|
54
|
+
update_lockfiles_content(temp_dir, lockfiles, updated_files)
|
|
55
|
+
rescue SharedHelpers::HelperSubprocessFailed => e
|
|
56
|
+
Dependabot.logger.error("Failed to update lockfiles: #{e.message}")
|
|
57
|
+
return updated_files
|
|
60
58
|
end
|
|
59
|
+
|
|
61
60
|
updated_files
|
|
62
61
|
end
|
|
63
62
|
|
|
63
|
+
sig { params(build_file: Dependabot::DependencyFile).returns(String) }
|
|
64
|
+
def determine_root_dir(build_file:)
|
|
65
|
+
settings_file = find_settings_file(build_file)
|
|
66
|
+
return normalized_directory_path(settings_file) if settings_file
|
|
67
|
+
|
|
68
|
+
file_path = normalized_file_path(build_file)
|
|
69
|
+
return normalize_path(File.dirname(file_path, 2)) if file_path.end_with?("/gradle/libs.versions.toml")
|
|
70
|
+
|
|
71
|
+
normalized_directory_path(build_file)
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
sig { params(file: Dependabot::DependencyFile).returns(String) }
|
|
75
|
+
def normalized_directory_path(file)
|
|
76
|
+
file_path = normalized_file_path(file)
|
|
77
|
+
dir = File.dirname(file_path)
|
|
78
|
+
dir == "/" ? "/" : normalize_path(dir)
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
sig { params(root_dir: String).returns(T::Array[Dependabot::DependencyFile]) }
|
|
82
|
+
def lockfiles_for_root(root_dir)
|
|
83
|
+
sub_build_roots = sub_build_roots_for(root_dir)
|
|
84
|
+
|
|
85
|
+
dependency_files.select do |file|
|
|
86
|
+
next false unless file.name.end_with?(".lockfile")
|
|
87
|
+
|
|
88
|
+
file_path = normalized_file_path(file)
|
|
89
|
+
next false unless path_under_root?(file_path, root_dir)
|
|
90
|
+
|
|
91
|
+
sub_build_roots.none? { |sub_root| file_path.start_with?("#{sub_root}/") || file_path == sub_root }
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
|
|
64
95
|
sig do
|
|
65
96
|
params(
|
|
66
97
|
temp_dir: T.any(Pathname, String),
|
|
67
|
-
|
|
98
|
+
lockfiles: T::Array[Dependabot::DependencyFile],
|
|
68
99
|
updated_lockfiles: T::Array[Dependabot::DependencyFile]
|
|
69
100
|
).void
|
|
70
101
|
end
|
|
71
|
-
def update_lockfiles_content(temp_dir,
|
|
72
|
-
|
|
73
|
-
|
|
102
|
+
def update_lockfiles_content(temp_dir, lockfiles, updated_lockfiles)
|
|
103
|
+
lockfiles.each do |file|
|
|
104
|
+
# Handle "/" directory as root - File.join treats "/" as absolute path and ignores prior components
|
|
105
|
+
relative_dir = file.directory == "/" ? "" : file.directory
|
|
106
|
+
lockfile_path = File.join(temp_dir, relative_dir, file.name)
|
|
107
|
+
|
|
108
|
+
unless File.exist?(lockfile_path)
|
|
109
|
+
Dependabot.logger.warn(
|
|
110
|
+
"Lockfile #{file.name} was not regenerated by Gradle after a successful lockfile update run. " \
|
|
111
|
+
"Preserving existing lockfile."
|
|
112
|
+
)
|
|
113
|
+
next
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
content = File.read(lockfile_path)
|
|
117
|
+
next if content == file.content
|
|
118
|
+
|
|
74
119
|
tmp_file = file.dup
|
|
75
|
-
tmp_file.content =
|
|
76
|
-
|
|
120
|
+
tmp_file.content = content
|
|
121
|
+
|
|
122
|
+
index = updated_lockfiles.find_index { |f| f.name == file.name }
|
|
123
|
+
if index
|
|
124
|
+
updated_lockfiles[index] = tmp_file
|
|
125
|
+
else
|
|
126
|
+
updated_lockfiles << tmp_file
|
|
127
|
+
end
|
|
128
|
+
end
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
private
|
|
132
|
+
|
|
133
|
+
sig { returns(T::Array[Dependabot::DependencyFile]) }
|
|
134
|
+
attr_reader :dependency_files
|
|
135
|
+
|
|
136
|
+
sig { params(file_path: String, root_dir: String).returns(T::Boolean) }
|
|
137
|
+
def path_under_root?(file_path, root_dir)
|
|
138
|
+
root_dir == "/" || file_path == root_dir || file_path.start_with?("#{root_dir}/")
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
# Find all sub-build roots (settings files deeper than root_dir) so we can
|
|
142
|
+
# exclude lockfiles that belong to an included/composite build.
|
|
143
|
+
sig { params(root_dir: String).returns(T::Array[String]) }
|
|
144
|
+
def sub_build_roots_for(root_dir)
|
|
145
|
+
dependency_files.filter_map do |f|
|
|
146
|
+
basename = File.basename(f.name)
|
|
147
|
+
next unless basename == "settings.gradle" || basename == "settings.gradle.kts"
|
|
148
|
+
|
|
149
|
+
dir = normalized_directory_path(f)
|
|
150
|
+
next if dir == root_dir
|
|
151
|
+
|
|
152
|
+
dir if path_under_root?(dir, root_dir)
|
|
77
153
|
end
|
|
78
154
|
end
|
|
79
155
|
|
|
156
|
+
sig { params(file: Dependabot::DependencyFile).returns(String) }
|
|
157
|
+
def normalized_file_path(file)
|
|
158
|
+
# Handle "/" directory as root - File.join treats "/" as absolute path and ignores prior components
|
|
159
|
+
relative_dir = file.directory == "/" ? "" : file.directory
|
|
160
|
+
path = relative_dir.empty? ? file.name : File.join(relative_dir, file.name)
|
|
161
|
+
normalize_path(path)
|
|
162
|
+
end
|
|
163
|
+
|
|
164
|
+
sig { params(path: String).returns(String) }
|
|
165
|
+
def normalize_path(path)
|
|
166
|
+
normalized = path.squeeze("/")
|
|
167
|
+
normalized = "/#{normalized}" unless normalized.start_with?("/")
|
|
168
|
+
normalized = normalized.sub(%r{/$}, "")
|
|
169
|
+
normalized.empty? ? "/" : normalized
|
|
170
|
+
end
|
|
171
|
+
|
|
80
172
|
sig { params(temp_dir: T.any(Pathname, String)).void }
|
|
81
173
|
def populate_temp_directory(temp_dir)
|
|
82
174
|
@dependency_files.each do |file|
|
|
83
|
-
|
|
175
|
+
# Handle "/" directory as root - File.join treats "/" as absolute path and ignores prior components
|
|
176
|
+
relative_dir = file.directory == "/" ? "" : file.directory
|
|
177
|
+
in_path_name = File.join(temp_dir, relative_dir, file.name)
|
|
84
178
|
FileUtils.mkdir_p(File.dirname(in_path_name))
|
|
85
179
|
File.write(in_path_name, file.content)
|
|
86
180
|
end
|
|
@@ -96,6 +190,7 @@ module Dependabot
|
|
|
96
190
|
https_proxy_host = https_split&.fetch(1, nil)&.gsub("//", "") || "host.docker.internal"
|
|
97
191
|
http_proxy_port = http_split&.fetch(2) || "1080"
|
|
98
192
|
https_proxy_port = https_split&.fetch(2) || "1080"
|
|
193
|
+
|
|
99
194
|
properties_content = "
|
|
100
195
|
systemProp.http.proxyHost=#{http_proxy_host}
|
|
101
196
|
systemProp.http.proxyPort=#{http_proxy_port}
|
|
@@ -104,10 +199,46 @@ systemProp.https.proxyPort=#{https_proxy_port}"
|
|
|
104
199
|
File.write(file_name, properties_content)
|
|
105
200
|
end
|
|
106
201
|
|
|
107
|
-
|
|
202
|
+
sig { params(file_name: String).void }
|
|
203
|
+
def write_init_script(file_name)
|
|
204
|
+
# Resolve all resolvable configurations across all loaded projects so
|
|
205
|
+
# Gradle rewrites every relevant lockfile in one invocation.
|
|
206
|
+
script_content = <<~GRADLE
|
|
207
|
+
allprojects {
|
|
208
|
+
if (tasks.findByName("#{INIT_SCRIPT_TASK_NAME}") == null) {
|
|
209
|
+
tasks.register("#{INIT_SCRIPT_TASK_NAME}") {
|
|
210
|
+
doLast {
|
|
211
|
+
configurations.findAll { it.canBeResolved }.each { it.resolve() }
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
GRADLE
|
|
217
|
+
File.write(file_name, script_content)
|
|
218
|
+
end
|
|
108
219
|
|
|
109
|
-
sig { returns(T
|
|
110
|
-
|
|
220
|
+
sig { params(build_file: Dependabot::DependencyFile).returns(T.nilable(Dependabot::DependencyFile)) }
|
|
221
|
+
def find_settings_file(build_file)
|
|
222
|
+
settings_files = dependency_files.select do |f|
|
|
223
|
+
basename = File.basename(f.name)
|
|
224
|
+
basename == "settings.gradle" || basename == "settings.gradle.kts"
|
|
225
|
+
end
|
|
226
|
+
|
|
227
|
+
return nil if settings_files.empty?
|
|
228
|
+
|
|
229
|
+
build_dir = normalized_directory_path(build_file)
|
|
230
|
+
|
|
231
|
+
ancestor_settings = settings_files.select do |f|
|
|
232
|
+
settings_dir = normalized_directory_path(f)
|
|
233
|
+
path_under_root?(build_dir, settings_dir)
|
|
234
|
+
end
|
|
235
|
+
|
|
236
|
+
return nil if ancestor_settings.empty?
|
|
237
|
+
|
|
238
|
+
ancestor_settings.max_by do |f|
|
|
239
|
+
normalized_directory_path(f).split("/").count { |element| !element.empty? }
|
|
240
|
+
end
|
|
241
|
+
end
|
|
111
242
|
end
|
|
112
243
|
end
|
|
113
244
|
end
|
|
@@ -5,81 +5,22 @@ require "sorbet-runtime"
|
|
|
5
5
|
|
|
6
6
|
require "dependabot/gradle/file_updater"
|
|
7
7
|
require "dependabot/gradle/file_parser/property_value_finder"
|
|
8
|
+
require "dependabot/maven/shared/shared_property_value_updater"
|
|
8
9
|
|
|
9
10
|
module Dependabot
|
|
10
11
|
module Gradle
|
|
11
12
|
class FileUpdater
|
|
12
|
-
class PropertyValueUpdater
|
|
13
|
+
class PropertyValueUpdater < Dependabot::Maven::Shared::SharedPropertyValueUpdater
|
|
13
14
|
extend T::Sig
|
|
14
15
|
|
|
15
|
-
sig { params(dependency_files: T::Array[DependencyFile]).void }
|
|
16
|
-
def initialize(dependency_files:)
|
|
17
|
-
@dependency_files = dependency_files
|
|
18
|
-
@property_value_finder = T.let(nil, T.nilable(Gradle::FileParser::PropertyValueFinder))
|
|
19
|
-
end
|
|
20
|
-
|
|
21
|
-
sig do
|
|
22
|
-
params(
|
|
23
|
-
property_name: String,
|
|
24
|
-
callsite_buildfile: DependencyFile,
|
|
25
|
-
previous_value: String,
|
|
26
|
-
updated_value: String
|
|
27
|
-
)
|
|
28
|
-
.returns(T::Array[DependencyFile])
|
|
29
|
-
end
|
|
30
|
-
def update_files_for_property_change(
|
|
31
|
-
property_name:,
|
|
32
|
-
callsite_buildfile:,
|
|
33
|
-
previous_value:,
|
|
34
|
-
updated_value:
|
|
35
|
-
)
|
|
36
|
-
declaration_details = T.must(
|
|
37
|
-
property_value_finder.property_details(
|
|
38
|
-
property_name: property_name,
|
|
39
|
-
callsite_buildfile: callsite_buildfile
|
|
40
|
-
)
|
|
41
|
-
)
|
|
42
|
-
declaration_string = declaration_details.fetch(:declaration_string)
|
|
43
|
-
filename = declaration_details.fetch(:file)
|
|
44
|
-
|
|
45
|
-
file_to_update = T.must(dependency_files.find { |f| f.name == filename })
|
|
46
|
-
updated_content = T.must(file_to_update.content).sub(
|
|
47
|
-
declaration_string,
|
|
48
|
-
declaration_string.sub(
|
|
49
|
-
previous_value_regex(previous_value),
|
|
50
|
-
updated_value
|
|
51
|
-
)
|
|
52
|
-
)
|
|
53
|
-
|
|
54
|
-
updated_files = dependency_files.dup
|
|
55
|
-
updated_files[T.must(updated_files.index(file_to_update))] =
|
|
56
|
-
update_file(file: file_to_update, content: updated_content)
|
|
57
|
-
|
|
58
|
-
updated_files
|
|
59
|
-
end
|
|
60
|
-
|
|
61
16
|
private
|
|
62
17
|
|
|
63
|
-
sig { returns(
|
|
64
|
-
attr_reader :dependency_files
|
|
65
|
-
|
|
66
|
-
sig { returns(Gradle::FileParser::PropertyValueFinder) }
|
|
18
|
+
sig { override.returns(Gradle::FileParser::PropertyValueFinder) }
|
|
67
19
|
def property_value_finder
|
|
68
|
-
@property_value_finder ||=
|
|
69
|
-
Gradle::FileParser::PropertyValueFinder
|
|
70
|
-
.
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
sig { params(file: DependencyFile, content: String).returns(DependencyFile) }
|
|
74
|
-
def update_file(file:, content:)
|
|
75
|
-
updated_file = file.dup
|
|
76
|
-
updated_file.content = content
|
|
77
|
-
updated_file
|
|
78
|
-
end
|
|
79
|
-
|
|
80
|
-
sig { params(previous_value: String).returns(Regexp) }
|
|
81
|
-
def previous_value_regex(previous_value)
|
|
82
|
-
/(?<=['"])#{Regexp.quote(previous_value)}(?=['"])/
|
|
20
|
+
@property_value_finder ||= T.let(
|
|
21
|
+
Gradle::FileParser::PropertyValueFinder.new(dependency_files: dependency_files),
|
|
22
|
+
T.nilable(Gradle::FileParser::PropertyValueFinder)
|
|
23
|
+
)
|
|
83
24
|
end
|
|
84
25
|
end
|
|
85
26
|
end
|
|
@@ -107,17 +107,34 @@ module Dependabot
|
|
|
107
107
|
replace_updated_files(files, updated_files)
|
|
108
108
|
end
|
|
109
109
|
if Dependabot::Experiments.enabled?(:gradle_lockfile_updater)
|
|
110
|
-
buildfiles_processed
|
|
111
|
-
lockfile_updater = LockfileUpdater.new(dependency_files: files)
|
|
112
|
-
updated_files = lockfile_updater.update_lockfiles(buildfile)
|
|
113
|
-
replace_updated_files(files, updated_files)
|
|
114
|
-
end
|
|
110
|
+
update_lockfiles_for_buildfiles(files, buildfiles_processed)
|
|
115
111
|
end
|
|
116
112
|
|
|
117
113
|
files
|
|
118
114
|
end
|
|
119
115
|
# rubocop:enable Metrics/PerceivedComplexity
|
|
120
116
|
# rubocop:enable Metrics/AbcSize
|
|
117
|
+
|
|
118
|
+
sig do
|
|
119
|
+
params(
|
|
120
|
+
files: T::Array[Dependabot::DependencyFile],
|
|
121
|
+
buildfiles_processed: T::Hash[String, Dependabot::DependencyFile]
|
|
122
|
+
).void
|
|
123
|
+
end
|
|
124
|
+
def update_lockfiles_for_buildfiles(files, buildfiles_processed)
|
|
125
|
+
lockfile_roots_processed = T.let(Set.new, T::Set[String])
|
|
126
|
+
|
|
127
|
+
buildfiles_processed.each_value do |buildfile|
|
|
128
|
+
lockfile_updater = LockfileUpdater.new(dependency_files: files)
|
|
129
|
+
root_dir = lockfile_updater.determine_root_dir(build_file: buildfile)
|
|
130
|
+
next if lockfile_roots_processed.include?(root_dir)
|
|
131
|
+
|
|
132
|
+
lockfile_roots_processed.add(root_dir)
|
|
133
|
+
|
|
134
|
+
updated_files = lockfile_updater.update_lockfiles(buildfile)
|
|
135
|
+
replace_updated_files(files, updated_files)
|
|
136
|
+
end
|
|
137
|
+
end
|
|
121
138
|
sig do
|
|
122
139
|
params(
|
|
123
140
|
files: T::Array[Dependabot::DependencyFile],
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: dependabot-gradle
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.376.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Dependabot
|
|
@@ -15,28 +15,28 @@ dependencies:
|
|
|
15
15
|
requirements:
|
|
16
16
|
- - '='
|
|
17
17
|
- !ruby/object:Gem::Version
|
|
18
|
-
version: 0.
|
|
18
|
+
version: 0.376.0
|
|
19
19
|
type: :runtime
|
|
20
20
|
prerelease: false
|
|
21
21
|
version_requirements: !ruby/object:Gem::Requirement
|
|
22
22
|
requirements:
|
|
23
23
|
- - '='
|
|
24
24
|
- !ruby/object:Gem::Version
|
|
25
|
-
version: 0.
|
|
25
|
+
version: 0.376.0
|
|
26
26
|
- !ruby/object:Gem::Dependency
|
|
27
27
|
name: dependabot-maven
|
|
28
28
|
requirement: !ruby/object:Gem::Requirement
|
|
29
29
|
requirements:
|
|
30
30
|
- - '='
|
|
31
31
|
- !ruby/object:Gem::Version
|
|
32
|
-
version: 0.
|
|
32
|
+
version: 0.376.0
|
|
33
33
|
type: :runtime
|
|
34
34
|
prerelease: false
|
|
35
35
|
version_requirements: !ruby/object:Gem::Requirement
|
|
36
36
|
requirements:
|
|
37
37
|
- - '='
|
|
38
38
|
- !ruby/object:Gem::Version
|
|
39
|
-
version: 0.
|
|
39
|
+
version: 0.376.0
|
|
40
40
|
- !ruby/object:Gem::Dependency
|
|
41
41
|
name: debug
|
|
42
42
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -285,7 +285,7 @@ licenses:
|
|
|
285
285
|
- MIT
|
|
286
286
|
metadata:
|
|
287
287
|
bug_tracker_uri: https://github.com/dependabot/dependabot-core/issues
|
|
288
|
-
changelog_uri: https://github.com/dependabot/dependabot-core/releases/tag/v0.
|
|
288
|
+
changelog_uri: https://github.com/dependabot/dependabot-core/releases/tag/v0.376.0
|
|
289
289
|
rdoc_options: []
|
|
290
290
|
require_paths:
|
|
291
291
|
- lib
|