dependabot-maven 0.316.0 → 0.318.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/maven/file_parser/maven_dependency_parser.rb +126 -0
- data/lib/dependabot/maven/file_parser.rb +95 -3
- data/lib/dependabot/maven/file_updater/declaration_finder.rb +1 -1
- data/lib/dependabot/maven/file_updater.rb +63 -6
- data/lib/dependabot/maven/native_helpers.rb +41 -0
- data/lib/dependabot/maven/package/package_details_fetcher.rb +2 -1
- metadata +6 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7dddaacd9f55be6eed5e719f3e4fb005d0e09a1cbcaedaa434a74c3802e8ba4f
|
4
|
+
data.tar.gz: f7080365f342e6ecfdc094718c5bb186d2e228b014bb7e824db1648814320302
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a4f0f5efb938e2ae503c50e562be4169afaa47a5a058757938f69395dacc3c46693488daaf9db2e6151bdbf0d03c7dd879be15de5f8840aa4dd15abf04913e15
|
7
|
+
data.tar.gz: 6308ea5cb891f6f7bed9f9095381bdaceacd75ef3fef890b7d2fcdce0b5ac3b84f800924b0ff718f4fcc8cb35bcdc5c85592a99606c7af35bf77ec598bf5fb0c
|
@@ -0,0 +1,126 @@
|
|
1
|
+
# typed: strict
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require "sorbet-runtime"
|
5
|
+
|
6
|
+
require "dependabot/maven/file_parser"
|
7
|
+
require "dependabot/maven/native_helpers"
|
8
|
+
|
9
|
+
module Dependabot
|
10
|
+
module Maven
|
11
|
+
class FileParser
|
12
|
+
class MavenDependencyParser
|
13
|
+
extend T::Sig
|
14
|
+
require "dependabot/file_parsers/base/dependency_set"
|
15
|
+
|
16
|
+
DEPENDENCY_OUTPUT_FILE = "dependency-tree-output.json"
|
17
|
+
|
18
|
+
sig do
|
19
|
+
params(dependency_files: T::Array[Dependabot::DependencyFile])
|
20
|
+
.returns(Dependabot::FileParsers::Base::DependencySet)
|
21
|
+
end
|
22
|
+
def self.build_dependency_set(dependency_files)
|
23
|
+
dependency_set = Dependabot::FileParsers::Base::DependencySet.new
|
24
|
+
|
25
|
+
# Copy only pom.xml files to a temporary directory to
|
26
|
+
# output the dependency tree without building the project
|
27
|
+
SharedHelpers.in_a_temporary_directory do |temp_path|
|
28
|
+
# Create a directory structure that maintains relative relationships
|
29
|
+
project_directory = create_directory_structure(dependency_files, temp_path.to_s)
|
30
|
+
|
31
|
+
dependency_files.each do |pom|
|
32
|
+
pom_path = File.join(project_directory, pom.name)
|
33
|
+
pom_dir = File.dirname(pom_path)
|
34
|
+
FileUtils.mkdir_p(pom_dir)
|
35
|
+
File.write(pom_path, pom.content)
|
36
|
+
end
|
37
|
+
|
38
|
+
Dir.chdir(project_directory) do
|
39
|
+
NativeHelpers.run_mvn_dependency_tree_plugin(DEPENDENCY_OUTPUT_FILE)
|
40
|
+
end
|
41
|
+
|
42
|
+
# mvn CLI outputs dependency tree for each pom.xml file, collect them
|
43
|
+
# add into single dependency set
|
44
|
+
dependency_files.each do |pom|
|
45
|
+
pom_path = File.join(project_directory, pom.name)
|
46
|
+
pom_dir = File.dirname(pom_path)
|
47
|
+
output_file = File.join(pom_dir, DEPENDENCY_OUTPUT_FILE)
|
48
|
+
|
49
|
+
# If we run updater from sub-module, parent file might be included in dependency files,
|
50
|
+
# but mvn CLI will not generate dependency tree for it unless we start from the parent.
|
51
|
+
# In that case we can just skip it and focus only on current file and it's sub-modules.
|
52
|
+
unless File.exist?(output_file)
|
53
|
+
Dependabot.logger.warn("Dependency tree output file not found: #{output_file}")
|
54
|
+
next
|
55
|
+
end
|
56
|
+
|
57
|
+
dependency_tree = JSON.parse(File.read(output_file))
|
58
|
+
extract_dependencies_from_tree(pom, dependency_set, dependency_tree)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
dependency_set
|
63
|
+
end
|
64
|
+
|
65
|
+
sig do
|
66
|
+
params(pom: Dependabot::DependencyFile,
|
67
|
+
dependency_set: Dependabot::FileParsers::Base::DependencySet,
|
68
|
+
dependency_tree: T::Hash[String, T.untyped]).void
|
69
|
+
end
|
70
|
+
def self.extract_dependencies_from_tree(pom, dependency_set, dependency_tree)
|
71
|
+
traverse_tree = T.let(-> {}, T.proc.params(node: T::Hash[String, T.untyped]).void)
|
72
|
+
traverse_tree = lambda do |node|
|
73
|
+
artifact_id = node["artifactId"]
|
74
|
+
group_id = node["groupId"]
|
75
|
+
version = node["version"]
|
76
|
+
type = node["type"]
|
77
|
+
classifier = node["classifier"].to_s.empty? ? nil : node["classifier"]
|
78
|
+
scope = node["scope"]
|
79
|
+
|
80
|
+
groups = scope == "test" ? ["test"] : []
|
81
|
+
dependency_set << Dependabot::Dependency.new(
|
82
|
+
name: "#{group_id}:#{artifact_id}",
|
83
|
+
version: version,
|
84
|
+
package_manager: "maven",
|
85
|
+
requirements: [{
|
86
|
+
requirement: version,
|
87
|
+
file: nil,
|
88
|
+
groups: groups,
|
89
|
+
source: nil,
|
90
|
+
metadata: {
|
91
|
+
packaging_type: type,
|
92
|
+
classifier: classifier,
|
93
|
+
pom_file: pom.name
|
94
|
+
}
|
95
|
+
}]
|
96
|
+
)
|
97
|
+
|
98
|
+
node["children"]&.each(&traverse_tree)
|
99
|
+
end
|
100
|
+
|
101
|
+
traverse_tree.call(dependency_tree)
|
102
|
+
end
|
103
|
+
|
104
|
+
sig do
|
105
|
+
params(dependency_files: T::Array[Dependabot::DependencyFile], temp_path: String)
|
106
|
+
.returns(String)
|
107
|
+
end
|
108
|
+
def self.create_directory_structure(dependency_files, temp_path)
|
109
|
+
# Find the topmost directory level by finding the minimum number of "../" sequences
|
110
|
+
relative_top_depth = dependency_files.map do |pom|
|
111
|
+
Pathname.new(pom.name).cleanpath.to_s.scan("../").length
|
112
|
+
end.max || 0
|
113
|
+
|
114
|
+
# Create the base directory structure with the required depth
|
115
|
+
base_depth_path = (0...relative_top_depth).reduce(temp_path) do |path, i|
|
116
|
+
File.join(path, "l#{i}")
|
117
|
+
end
|
118
|
+
|
119
|
+
FileUtils.mkdir_p(base_depth_path)
|
120
|
+
|
121
|
+
base_depth_path
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
@@ -3,6 +3,7 @@
|
|
3
3
|
|
4
4
|
require "nokogiri"
|
5
5
|
require "sorbet-runtime"
|
6
|
+
require "open3"
|
6
7
|
|
7
8
|
require "dependabot/dependency"
|
8
9
|
require "dependabot/file_parsers"
|
@@ -16,9 +17,11 @@ require "dependabot/errors"
|
|
16
17
|
# - http://maven.apache.org/pom.html
|
17
18
|
module Dependabot
|
18
19
|
module Maven
|
20
|
+
# rubocop:disable Metrics/ClassLength
|
19
21
|
class FileParser < Dependabot::FileParsers::Base
|
20
22
|
extend T::Sig
|
21
23
|
require "dependabot/file_parsers/base/dependency_set"
|
24
|
+
require_relative "file_parser/maven_dependency_parser"
|
22
25
|
require_relative "file_parser/property_value_finder"
|
23
26
|
|
24
27
|
# The following "dependencies" are candidates for updating:
|
@@ -41,9 +44,30 @@ module Dependabot
|
|
41
44
|
sig { override.returns(T::Array[Dependabot::Dependency]) }
|
42
45
|
def parse
|
43
46
|
dependency_set = DependencySet.new
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
+
|
48
|
+
dependencies = []
|
49
|
+
if Dependabot::Experiments.enabled?(:maven_transitive_dependencies)
|
50
|
+
dependency_set += MavenDependencyParser.build_dependency_set(pomfiles)
|
51
|
+
|
52
|
+
pomfiles.each { |pom| dependency_set += pomfile_dependencies(pom) }
|
53
|
+
extensionfiles.each { |extension| dependency_set += extensionfile_dependencies(extension) }
|
54
|
+
|
55
|
+
dependency_set.dependencies.each do |dep|
|
56
|
+
requirements = merge_requirements(dep.requirements)
|
57
|
+
dependencies << Dependabot::Dependency.new(
|
58
|
+
name: dep.name,
|
59
|
+
version: dep.version,
|
60
|
+
package_manager: "maven",
|
61
|
+
requirements: requirements
|
62
|
+
)
|
63
|
+
end
|
64
|
+
else
|
65
|
+
pomfiles.each { |pom| dependency_set += pomfile_dependencies(pom) }
|
66
|
+
extensionfiles.each { |extension| dependency_set += extensionfile_dependencies(extension) }
|
67
|
+
dependencies = dependency_set.dependencies
|
68
|
+
end
|
69
|
+
|
70
|
+
dependencies
|
47
71
|
end
|
48
72
|
|
49
73
|
sig { returns(Ecosystem) }
|
@@ -386,7 +410,75 @@ module Dependabot
|
|
386
410
|
def check_required_files
|
387
411
|
raise "No pom.xml!" unless get_original_file("pom.xml")
|
388
412
|
end
|
413
|
+
|
414
|
+
# Merge dependency scan requirements with file parsing requirements.
|
415
|
+
# Since dependency scan evaluates properties, we need to combine results with XML parsing,
|
416
|
+
# so we know when certain requirement not a literal value and can differentiate transitive dependencies
|
417
|
+
# from direct dependencies.
|
418
|
+
sig do
|
419
|
+
params(requirements: T::Array[T::Hash[Symbol, T.untyped]]).returns(T::Array[T::Hash[Symbol, T.untyped]])
|
420
|
+
end
|
421
|
+
def merge_requirements(requirements)
|
422
|
+
return requirements if requirements.length <= 1
|
423
|
+
|
424
|
+
merged = []
|
425
|
+
used_indices = Set.new
|
426
|
+
requirements.each_with_index do |dep_scan_req, i|
|
427
|
+
next if used_indices.include?(i) || dep_scan_req.dig(:metadata, :pom_file).nil?
|
428
|
+
|
429
|
+
# Look for another requirement where pom_file matches property_source
|
430
|
+
match_index = requirements.find_index.with_index do |parsing_req, j|
|
431
|
+
j > i &&
|
432
|
+
!used_indices.include?(j) &&
|
433
|
+
dep_scan_req.dig(:metadata, :pom_file) == parsing_req.fetch(:file)
|
434
|
+
end
|
435
|
+
|
436
|
+
if match_index
|
437
|
+
parsing_req = T.must(requirements[match_index])
|
438
|
+
|
439
|
+
# Merge the two requirements
|
440
|
+
# We prefer file and requirement properties from parsed requirements,
|
441
|
+
# because they include correct file and not evaluated property value.
|
442
|
+
merged_req = {
|
443
|
+
requirement: parsing_req[:requirement],
|
444
|
+
file: parsing_req[:file],
|
445
|
+
groups: [*dep_scan_req[:groups], *parsing_req[:groups]].uniq.compact,
|
446
|
+
source: dep_scan_req[:source],
|
447
|
+
metadata: merge_metadata(dep_scan_req[:metadata], parsing_req[:metadata])
|
448
|
+
}
|
449
|
+
|
450
|
+
merged << merged_req
|
451
|
+
used_indices.add(i)
|
452
|
+
used_indices.add(match_index)
|
453
|
+
else
|
454
|
+
# No match found, keep the requirement as is
|
455
|
+
merged << dep_scan_req
|
456
|
+
used_indices.add(i)
|
457
|
+
end
|
458
|
+
end
|
459
|
+
|
460
|
+
merged
|
461
|
+
end
|
462
|
+
|
463
|
+
# Merge metadata from two requirements, combining all keys
|
464
|
+
sig do
|
465
|
+
params(metadata1: T::Hash[Symbol, T.untyped],
|
466
|
+
metadata2: T::Hash[Symbol, T.untyped]).returns(T::Hash[Symbol, T.untyped])
|
467
|
+
end
|
468
|
+
def merge_metadata(metadata1, metadata2)
|
469
|
+
metadata1.merge(metadata2) do |_key, old_value, new_value|
|
470
|
+
case [old_value, new_value]
|
471
|
+
in [nil, new_value] then new_value
|
472
|
+
in [old_value, nil] then old_value
|
473
|
+
in [old_value, new_value] if old_value == new_value then old_value
|
474
|
+
else
|
475
|
+
# If values differ, combine them
|
476
|
+
[*old_value, *new_value].uniq
|
477
|
+
end
|
478
|
+
end
|
479
|
+
end
|
389
480
|
end
|
481
|
+
# rubocop:enable Metrics/ClassLength
|
390
482
|
end
|
391
483
|
end
|
392
484
|
|
@@ -61,7 +61,7 @@ module Dependabot
|
|
61
61
|
|
62
62
|
sig { returns(Dependabot::DependencyFile) }
|
63
63
|
def declaring_pom
|
64
|
-
filename = declaring_requirement.fetch(:file)
|
64
|
+
filename = declaring_requirement.fetch(:file) || declaring_requirement.dig(:metadata, :pom_file)
|
65
65
|
declaring_pom = dependency_files.find { |f| f.name == filename }
|
66
66
|
return declaring_pom if declaring_pom
|
67
67
|
|
@@ -74,13 +74,14 @@ module Dependabot
|
|
74
74
|
raise "Bad req match" unless new_req[:file] == T.must(old_req)[:file]
|
75
75
|
next if new_req[:requirement] == T.must(old_req)[:requirement]
|
76
76
|
|
77
|
+
file_name = T.let(new_req.fetch(:file) || new_req.dig(:metadata, :pom_file), String)
|
77
78
|
if new_req.dig(:metadata, :property_name)
|
78
79
|
files = update_pomfiles_for_property_change(files, new_req)
|
79
|
-
pom = files.find { |f| f.name ==
|
80
|
+
pom = files.find { |f| f.name == file_name }
|
80
81
|
files[T.must(files.index(pom))] =
|
81
82
|
remove_property_suffix_in_pom(dependency, T.must(pom), T.must(old_req))
|
82
83
|
else
|
83
|
-
file = files.find { |f| f.name ==
|
84
|
+
file = files.find { |f| f.name == file_name }
|
84
85
|
files[T.must(files.index(file))] =
|
85
86
|
update_version_in_file(dependency, T.must(file), T.must(old_req), new_req)
|
86
87
|
end
|
@@ -119,11 +120,20 @@ module Dependabot
|
|
119
120
|
end
|
120
121
|
def update_version_in_file(dependency, file, previous_req, requirement)
|
121
122
|
updated_content = T.must(file.content)
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
123
|
+
original_file_declarations = original_file_declarations(dependency, previous_req)
|
124
|
+
|
125
|
+
if original_file_declarations.any?
|
126
|
+
# If the file already has a declaration for this dependency, we
|
127
|
+
# update the existing declaration with the new version.
|
128
|
+
original_file_declarations.each do |old_dec|
|
129
|
+
updated_content = updated_content.gsub(old_dec) do
|
130
|
+
updated_file_declaration(old_dec, previous_req, requirement)
|
131
|
+
end
|
126
132
|
end
|
133
|
+
else
|
134
|
+
# If the file does not have a declaration for this dependency, we
|
135
|
+
# add a new declaration for it.
|
136
|
+
updated_content = add_new_declaration(updated_content, dependency, requirement)
|
127
137
|
end
|
128
138
|
|
129
139
|
raise "Expected content to change!" if updated_content == file.content
|
@@ -131,6 +141,53 @@ module Dependabot
|
|
131
141
|
updated_file(file: file, content: updated_content)
|
132
142
|
end
|
133
143
|
|
144
|
+
sig do
|
145
|
+
params(
|
146
|
+
content: String,
|
147
|
+
dependency: Dependabot::Dependency,
|
148
|
+
requirement: T::Hash[Symbol, T.untyped]
|
149
|
+
).returns(String)
|
150
|
+
end
|
151
|
+
def add_new_declaration(content, dependency, requirement) # rubocop:disable Metrics/AbcSize
|
152
|
+
doc = Nokogiri::XML(content) { |config| config.default_xml.noblanks }
|
153
|
+
doc.remove_namespaces!
|
154
|
+
|
155
|
+
project = doc.at_xpath("//project")
|
156
|
+
raise "<project> element not found in the XML content" unless project
|
157
|
+
|
158
|
+
dependency_management = project.at_xpath("dependencyManagement")
|
159
|
+
unless dependency_management
|
160
|
+
dependency_management = Nokogiri::XML::Node.new("dependencyManagement", doc)
|
161
|
+
dependencies = Nokogiri::XML::Node.new("dependencies", doc)
|
162
|
+
dependency_management.add_child(dependencies)
|
163
|
+
project.add_child(dependency_management)
|
164
|
+
end
|
165
|
+
|
166
|
+
dependencies = dependency_management.at_xpath("dependencies")
|
167
|
+
unless dependencies
|
168
|
+
dependencies = Nokogiri::XML::Node.new("dependencies", doc)
|
169
|
+
dependency_management.add_child(dependencies)
|
170
|
+
end
|
171
|
+
|
172
|
+
dependency_node = Nokogiri::XML::Node.new("dependency", doc)
|
173
|
+
|
174
|
+
group_id = Nokogiri::XML::Node.new("groupId", doc)
|
175
|
+
group_id.content = dependency.name.split(":").first
|
176
|
+
dependency_node.add_child(group_id)
|
177
|
+
|
178
|
+
artifact_id = Nokogiri::XML::Node.new("artifactId", doc)
|
179
|
+
artifact_id.content = dependency.name.split(":").last
|
180
|
+
dependency_node.add_child(artifact_id)
|
181
|
+
|
182
|
+
version = Nokogiri::XML::Node.new("version", doc)
|
183
|
+
version.content = requirement.fetch(:requirement)
|
184
|
+
dependency_node.add_child(version)
|
185
|
+
|
186
|
+
dependencies.add_child(dependency_node)
|
187
|
+
|
188
|
+
doc.to_xml
|
189
|
+
end
|
190
|
+
|
134
191
|
sig do
|
135
192
|
params(
|
136
193
|
dep: Dependabot::Dependency,
|
@@ -0,0 +1,41 @@
|
|
1
|
+
# typed: strong
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require "shellwords"
|
5
|
+
require "sorbet-runtime"
|
6
|
+
|
7
|
+
module Dependabot
|
8
|
+
module Maven
|
9
|
+
module NativeHelpers
|
10
|
+
extend T::Sig
|
11
|
+
|
12
|
+
sig do
|
13
|
+
params(file_name: String).void
|
14
|
+
end
|
15
|
+
def self.run_mvn_dependency_tree_plugin(file_name)
|
16
|
+
proxy_url = URI.parse(ENV.fetch("HTTPS_PROXY"))
|
17
|
+
stdout, _, status = Open3.capture3(
|
18
|
+
{ "PROXY_HOST" => proxy_url.host },
|
19
|
+
"mvn",
|
20
|
+
"dependency:tree",
|
21
|
+
"-DoutputFile=#{file_name}",
|
22
|
+
"-DoutputType=json",
|
23
|
+
"-e"
|
24
|
+
)
|
25
|
+
Dependabot.logger.info("mvn dependency:tree output: STDOUT:#{stdout}")
|
26
|
+
handle_tool_error(stdout) unless status.success?
|
27
|
+
end
|
28
|
+
|
29
|
+
sig { params(output: String).void }
|
30
|
+
def self.handle_tool_error(output)
|
31
|
+
if (match = output.match(
|
32
|
+
%r{Could not transfer artifact (?<artifact>[^ ]+) from/to (?<repository_name>[^ ]+) \((?<repository_url>[^ ]+)\): status code: (?<status_code>[0-9]+)} # rubocop:disable Layout/LineLength
|
33
|
+
)) && (match[:status_code] == ("403") || match[:status_code] == ("401"))
|
34
|
+
raise Dependabot::PrivateSourceAuthenticationFailure, match[:repository_url]
|
35
|
+
end
|
36
|
+
|
37
|
+
raise DependabotError, "mvn CLI failed with an unhandled error"
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -356,7 +356,8 @@ module Dependabot
|
|
356
356
|
# Returns the POM file for the dependency, if it exists.
|
357
357
|
sig { returns(T.nilable(Dependabot::DependencyFile)) }
|
358
358
|
def pom
|
359
|
-
filename = dependency.requirements.first&.fetch(:file)
|
359
|
+
filename = dependency.requirements.first&.fetch(:file) ||
|
360
|
+
dependency.requirements.first&.dig(:metadata, :pom_file)
|
360
361
|
dependency_files.find { |f| f.name == filename }
|
361
362
|
end
|
362
363
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: dependabot-maven
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.318.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Dependabot
|
@@ -15,14 +15,14 @@ dependencies:
|
|
15
15
|
requirements:
|
16
16
|
- - '='
|
17
17
|
- !ruby/object:Gem::Version
|
18
|
-
version: 0.
|
18
|
+
version: 0.318.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.318.0
|
26
26
|
- !ruby/object:Gem::Dependency
|
27
27
|
name: debug
|
28
28
|
requirement: !ruby/object:Gem::Requirement
|
@@ -244,6 +244,7 @@ files:
|
|
244
244
|
- lib/dependabot/maven.rb
|
245
245
|
- lib/dependabot/maven/file_fetcher.rb
|
246
246
|
- lib/dependabot/maven/file_parser.rb
|
247
|
+
- lib/dependabot/maven/file_parser/maven_dependency_parser.rb
|
247
248
|
- lib/dependabot/maven/file_parser/pom_fetcher.rb
|
248
249
|
- lib/dependabot/maven/file_parser/property_value_finder.rb
|
249
250
|
- lib/dependabot/maven/file_parser/repositories_finder.rb
|
@@ -252,6 +253,7 @@ files:
|
|
252
253
|
- lib/dependabot/maven/file_updater/property_value_updater.rb
|
253
254
|
- lib/dependabot/maven/language.rb
|
254
255
|
- lib/dependabot/maven/metadata_finder.rb
|
256
|
+
- lib/dependabot/maven/native_helpers.rb
|
255
257
|
- lib/dependabot/maven/package/package_details_fetcher.rb
|
256
258
|
- lib/dependabot/maven/package_manager.rb
|
257
259
|
- lib/dependabot/maven/requirement.rb
|
@@ -268,7 +270,7 @@ licenses:
|
|
268
270
|
- MIT
|
269
271
|
metadata:
|
270
272
|
bug_tracker_uri: https://github.com/dependabot/dependabot-core/issues
|
271
|
-
changelog_uri: https://github.com/dependabot/dependabot-core/releases/tag/v0.
|
273
|
+
changelog_uri: https://github.com/dependabot/dependabot-core/releases/tag/v0.318.0
|
272
274
|
rdoc_options: []
|
273
275
|
require_paths:
|
274
276
|
- lib
|