dependabot-core 0.83.2 → 0.84.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +5 -0
- data/lib/dependabot/file_fetchers.rb +0 -2
- data/lib/dependabot/file_parsers.rb +0 -2
- data/lib/dependabot/file_updaters.rb +0 -2
- data/lib/dependabot/file_updaters/ruby/.DS_Store +0 -0
- data/lib/dependabot/metadata_finders.rb +0 -1
- data/lib/dependabot/metadata_finders/base/release_finder.rb +4 -0
- data/lib/dependabot/update_checkers.rb +0 -2
- data/lib/dependabot/utils.rb +0 -2
- data/lib/dependabot/version.rb +1 -1
- metadata +3 -13
- data/lib/dependabot/file_fetchers/java/gradle.rb +0 -56
- data/lib/dependabot/file_fetchers/java/gradle/settings_file_parser.rb +0 -66
- data/lib/dependabot/file_parsers/java/gradle.rb +0 -236
- data/lib/dependabot/file_parsers/java/gradle/property_value_finder.rb +0 -90
- data/lib/dependabot/file_parsers/java/gradle/repositories_finder.rb +0 -145
- data/lib/dependabot/file_updaters/java/gradle.rb +0 -176
- data/lib/dependabot/file_updaters/java/gradle/dependency_set_updater.rb +0 -66
- data/lib/dependabot/file_updaters/java/gradle/property_value_updater.rb +0 -58
- data/lib/dependabot/update_checkers/java/gradle.rb +0 -148
- data/lib/dependabot/update_checkers/java/gradle/multi_dependency_updater.rb +0 -105
- data/lib/dependabot/update_checkers/java/gradle/version_finder.rb +0 -183
@@ -1,90 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require "dependabot/file_parsers/java/gradle"
|
4
|
-
|
5
|
-
module Dependabot
|
6
|
-
module FileParsers
|
7
|
-
module Java
|
8
|
-
class Gradle
|
9
|
-
class PropertyValueFinder
|
10
|
-
PROPERTY_DECLARATION_REGEX =
|
11
|
-
/(?:^|\s+|ext.)(?<name>[^\s=]+)\s*=\s*['"](?<value>[^\s]+)['"]/.
|
12
|
-
freeze
|
13
|
-
|
14
|
-
def initialize(dependency_files:)
|
15
|
-
@dependency_files = dependency_files
|
16
|
-
end
|
17
|
-
|
18
|
-
def property_details(property_name:, callsite_buildfile:)
|
19
|
-
# If the root project was specified, just look in the top-level
|
20
|
-
# buildfile
|
21
|
-
if property_name.start_with?("rootProject.")
|
22
|
-
property_name = property_name.sub("rootProject.", "")
|
23
|
-
return properties(top_level_buildfile).fetch(property_name, nil)
|
24
|
-
end
|
25
|
-
|
26
|
-
# If this project was specified strip the specifier
|
27
|
-
if property_name.start_with?("project.")
|
28
|
-
property_name = property_name.sub("project.", "")
|
29
|
-
end
|
30
|
-
|
31
|
-
# If a `properties` prefix was specified strip that out, too
|
32
|
-
if property_name.start_with?("properties.")
|
33
|
-
property_name = property_name.sub("properties.", "")
|
34
|
-
end
|
35
|
-
|
36
|
-
# Look for a property in the callsite buildfile. If that fails, look
|
37
|
-
# for the property in the top-level buildfile
|
38
|
-
if properties(callsite_buildfile).fetch(property_name, nil)
|
39
|
-
return properties(callsite_buildfile).fetch(property_name)
|
40
|
-
end
|
41
|
-
|
42
|
-
properties(top_level_buildfile).fetch(property_name, nil)
|
43
|
-
end
|
44
|
-
|
45
|
-
def property_value(property_name:, callsite_buildfile:)
|
46
|
-
property_details(
|
47
|
-
property_name: property_name,
|
48
|
-
callsite_buildfile: callsite_buildfile
|
49
|
-
)&.fetch(:value)
|
50
|
-
end
|
51
|
-
|
52
|
-
private
|
53
|
-
|
54
|
-
attr_reader :dependency_files
|
55
|
-
|
56
|
-
def properties(buildfile)
|
57
|
-
@properties ||= {}
|
58
|
-
return @properties[buildfile.name] if @properties[buildfile.name]
|
59
|
-
|
60
|
-
@properties[buildfile.name] = {}
|
61
|
-
prepared_content(buildfile).scan(PROPERTY_DECLARATION_REGEX) do
|
62
|
-
declaration_string = Regexp.last_match.to_s.strip
|
63
|
-
captures = Regexp.last_match.named_captures
|
64
|
-
name = captures.fetch("name").sub(/^ext\./, "")
|
65
|
-
@properties[buildfile.name][name] = {
|
66
|
-
value: captures.fetch("value"),
|
67
|
-
declaration_string: declaration_string,
|
68
|
-
file: buildfile.name
|
69
|
-
}
|
70
|
-
end
|
71
|
-
|
72
|
-
@properties[buildfile.name]
|
73
|
-
end
|
74
|
-
|
75
|
-
def prepared_content(buildfile)
|
76
|
-
# Remove any comments
|
77
|
-
buildfile.content.
|
78
|
-
gsub(%r{(?<=^|\s)//.*$}, "\n").
|
79
|
-
gsub(%r{(?<=^|\s)/\*.*?\*/}m, "")
|
80
|
-
end
|
81
|
-
|
82
|
-
def top_level_buildfile
|
83
|
-
@top_level_buildfile ||=
|
84
|
-
dependency_files.find { |f| f.name == "build.gradle" }
|
85
|
-
end
|
86
|
-
end
|
87
|
-
end
|
88
|
-
end
|
89
|
-
end
|
90
|
-
end
|
@@ -1,145 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require "dependabot/file_parsers/java/gradle"
|
4
|
-
|
5
|
-
module Dependabot
|
6
|
-
module FileParsers
|
7
|
-
module Java
|
8
|
-
class Gradle
|
9
|
-
class RepositoriesFinder
|
10
|
-
# The Central Repo doesn't have special status for Gradle, but until
|
11
|
-
# we're confident we're selecting repos correctly it's wise to include
|
12
|
-
# it as a default.
|
13
|
-
CENTRAL_REPO_URL = "https://repo.maven.apache.org/maven2"
|
14
|
-
|
15
|
-
REPOSITORIES_BLOCK_START = /(?:^|\s)repositories\s*\{/.freeze
|
16
|
-
MAVEN_REPO_REGEX =
|
17
|
-
/maven\s*\{[^\}]*\surl[\s\(]\s*['"](?<url>[^'"]+)['"]/.freeze
|
18
|
-
|
19
|
-
def initialize(dependency_files:, target_dependency_file:)
|
20
|
-
@dependency_files = dependency_files
|
21
|
-
@target_dependency_file = target_dependency_file
|
22
|
-
raise "No target file!" unless target_dependency_file
|
23
|
-
end
|
24
|
-
|
25
|
-
def repository_urls
|
26
|
-
repository_urls = []
|
27
|
-
repository_urls += inherited_repository_urls
|
28
|
-
repository_urls += own_buildfile_repository_urls
|
29
|
-
repository_urls = repository_urls.uniq
|
30
|
-
|
31
|
-
return repository_urls unless repository_urls.empty?
|
32
|
-
|
33
|
-
[CENTRAL_REPO_URL]
|
34
|
-
end
|
35
|
-
|
36
|
-
private
|
37
|
-
|
38
|
-
attr_reader :dependency_files, :target_dependency_file
|
39
|
-
|
40
|
-
def inherited_repository_urls
|
41
|
-
return [] unless top_level_buildfile
|
42
|
-
|
43
|
-
buildfile_content = comment_free_content(top_level_buildfile)
|
44
|
-
subproject_blocks = []
|
45
|
-
|
46
|
-
buildfile_content.scan(/(?:^|\s)allprojects\s*\{/) do
|
47
|
-
mtch = Regexp.last_match
|
48
|
-
subproject_blocks <<
|
49
|
-
mtch.post_match[0..closing_bracket_index(mtch.post_match)]
|
50
|
-
end
|
51
|
-
|
52
|
-
if top_level_buildfile != target_dependency_file
|
53
|
-
buildfile_content.scan(/(?:^|\s)subprojects\s*\{/) do
|
54
|
-
mtch = Regexp.last_match
|
55
|
-
subproject_blocks <<
|
56
|
-
mtch.post_match[0..closing_bracket_index(mtch.post_match)]
|
57
|
-
end
|
58
|
-
end
|
59
|
-
|
60
|
-
repository_urls_from(subproject_blocks.join("\n"))
|
61
|
-
end
|
62
|
-
|
63
|
-
def own_buildfile_repository_urls
|
64
|
-
buildfile_content = comment_free_content(target_dependency_file)
|
65
|
-
|
66
|
-
buildfile_content.dup.scan(/(?:^|\s)subprojects\s*\{/) do
|
67
|
-
mtch = Regexp.last_match
|
68
|
-
buildfile_content.gsub!(
|
69
|
-
mtch.post_match[0..closing_bracket_index(mtch.post_match)],
|
70
|
-
""
|
71
|
-
)
|
72
|
-
end
|
73
|
-
|
74
|
-
repository_urls_from(buildfile_content)
|
75
|
-
end
|
76
|
-
|
77
|
-
def repository_urls_from(buildfile_content)
|
78
|
-
repository_urls = []
|
79
|
-
|
80
|
-
repository_blocks = []
|
81
|
-
buildfile_content.scan(REPOSITORIES_BLOCK_START) do
|
82
|
-
mtch = Regexp.last_match
|
83
|
-
repository_blocks <<
|
84
|
-
mtch.post_match[0..closing_bracket_index(mtch.post_match)]
|
85
|
-
end
|
86
|
-
|
87
|
-
repository_blocks.each do |block|
|
88
|
-
if block.include?(" google(")
|
89
|
-
repository_urls << "https://maven.google.com/"
|
90
|
-
end
|
91
|
-
|
92
|
-
if block.include?(" mavenCentral(")
|
93
|
-
repository_urls << "https://repo.maven.apache.org/maven2/"
|
94
|
-
end
|
95
|
-
|
96
|
-
if block.include?(" jcenter(")
|
97
|
-
repository_urls << "https://jcenter.bintray.com/"
|
98
|
-
end
|
99
|
-
|
100
|
-
block.scan(MAVEN_REPO_REGEX) do
|
101
|
-
repository_urls << Regexp.last_match.named_captures.fetch("url")
|
102
|
-
end
|
103
|
-
end
|
104
|
-
|
105
|
-
repository_urls.
|
106
|
-
map { |url| url.strip.gsub(%r{/$}, "") }.
|
107
|
-
select { |url| valid_url?(url) }.
|
108
|
-
uniq
|
109
|
-
end
|
110
|
-
|
111
|
-
def closing_bracket_index(string)
|
112
|
-
closes_required = 1
|
113
|
-
|
114
|
-
string.chars.each_with_index do |char, index|
|
115
|
-
closes_required += 1 if char == "{"
|
116
|
-
closes_required -= 1 if char == "}"
|
117
|
-
return index if closes_required.zero?
|
118
|
-
end
|
119
|
-
end
|
120
|
-
|
121
|
-
def valid_url?(url)
|
122
|
-
# Reject non-http URLs because they're probably parsing mistakes
|
123
|
-
return false unless url.start_with?("http")
|
124
|
-
|
125
|
-
URI.parse(url)
|
126
|
-
true
|
127
|
-
rescue URI::InvalidURIError
|
128
|
-
false
|
129
|
-
end
|
130
|
-
|
131
|
-
def comment_free_content(buildfile)
|
132
|
-
buildfile.content.
|
133
|
-
gsub(%r{(?<=^|\s)//.*$}, "\n").
|
134
|
-
gsub(%r{(?<=^|\s)/\*.*?\*/}m, "")
|
135
|
-
end
|
136
|
-
|
137
|
-
def top_level_buildfile
|
138
|
-
@top_level_buildfile ||=
|
139
|
-
dependency_files.find { |f| f.name == "build.gradle" }
|
140
|
-
end
|
141
|
-
end
|
142
|
-
end
|
143
|
-
end
|
144
|
-
end
|
145
|
-
end
|
@@ -1,176 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require "dependabot/file_updaters/base"
|
4
|
-
require "dependabot/file_parsers/java/gradle"
|
5
|
-
|
6
|
-
module Dependabot
|
7
|
-
module FileUpdaters
|
8
|
-
module Java
|
9
|
-
class Gradle < Dependabot::FileUpdaters::Base
|
10
|
-
require_relative "gradle/dependency_set_updater"
|
11
|
-
require_relative "gradle/property_value_updater"
|
12
|
-
|
13
|
-
def self.updated_files_regex
|
14
|
-
[/^build\.gradle$/, %r{/build\.gradle$}]
|
15
|
-
end
|
16
|
-
|
17
|
-
def updated_dependency_files
|
18
|
-
updated_files = buildfiles.dup
|
19
|
-
|
20
|
-
# Loop through each of the changed requirements, applying changes to
|
21
|
-
# all buildfiles for that change. Note that the logic is different
|
22
|
-
# here to other languages because Java has property inheritance across
|
23
|
-
# files (although we're not supporting it for gradle yet).
|
24
|
-
dependencies.each do |dependency|
|
25
|
-
updated_files = update_buildfiles_for_dependency(
|
26
|
-
buildfiles: updated_files,
|
27
|
-
dependency: dependency
|
28
|
-
)
|
29
|
-
end
|
30
|
-
|
31
|
-
updated_files = updated_files.reject { |f| buildfiles.include?(f) }
|
32
|
-
|
33
|
-
raise "No files changed!" if updated_files.none?
|
34
|
-
|
35
|
-
updated_files
|
36
|
-
end
|
37
|
-
|
38
|
-
private
|
39
|
-
|
40
|
-
def check_required_files
|
41
|
-
raise "No build.gradle!" unless get_original_file("build.gradle")
|
42
|
-
end
|
43
|
-
|
44
|
-
def update_buildfiles_for_dependency(buildfiles:, dependency:)
|
45
|
-
files = buildfiles.dup
|
46
|
-
|
47
|
-
# The UpdateChecker ensures the order of requirements is preserved
|
48
|
-
# when updating, so we can zip them together in new/old pairs.
|
49
|
-
reqs = dependency.requirements.zip(dependency.previous_requirements).
|
50
|
-
reject { |new_req, old_req| new_req == old_req }
|
51
|
-
|
52
|
-
# Loop through each changed requirement and update the buildfiles
|
53
|
-
reqs.each do |new_req, old_req|
|
54
|
-
raise "Bad req match" unless new_req[:file] == old_req[:file]
|
55
|
-
next if new_req[:requirement] == old_req[:requirement]
|
56
|
-
|
57
|
-
buildfile = files.find { |f| f.name == new_req.fetch(:file) }
|
58
|
-
|
59
|
-
if new_req.dig(:metadata, :property_name)
|
60
|
-
files = update_files_for_property_change(files, old_req, new_req)
|
61
|
-
elsif new_req.dig(:metadata, :dependency_set)
|
62
|
-
files = update_files_for_dep_set_change(files, old_req, new_req)
|
63
|
-
else
|
64
|
-
files[files.index(buildfile)] =
|
65
|
-
update_version_in_buildfile(
|
66
|
-
dependency,
|
67
|
-
buildfile,
|
68
|
-
old_req,
|
69
|
-
new_req
|
70
|
-
)
|
71
|
-
end
|
72
|
-
end
|
73
|
-
|
74
|
-
files
|
75
|
-
end
|
76
|
-
|
77
|
-
def update_files_for_property_change(buildfiles, old_req, new_req)
|
78
|
-
files = buildfiles.dup
|
79
|
-
property_name = new_req.fetch(:metadata).fetch(:property_name)
|
80
|
-
buildfile = files.find { |f| f.name == new_req.fetch(:file) }
|
81
|
-
|
82
|
-
PropertyValueUpdater.new(dependency_files: files).
|
83
|
-
update_files_for_property_change(
|
84
|
-
property_name: property_name,
|
85
|
-
callsite_buildfile: buildfile,
|
86
|
-
previous_value: old_req.fetch(:requirement),
|
87
|
-
updated_value: new_req.fetch(:requirement)
|
88
|
-
)
|
89
|
-
end
|
90
|
-
|
91
|
-
def update_files_for_dep_set_change(buildfiles, old_req, new_req)
|
92
|
-
files = buildfiles.dup
|
93
|
-
dependency_set = new_req.fetch(:metadata).fetch(:dependency_set)
|
94
|
-
buildfile = files.find { |f| f.name == new_req.fetch(:file) }
|
95
|
-
|
96
|
-
DependencySetUpdater.new(dependency_files: files).
|
97
|
-
update_files_for_dep_set_change(
|
98
|
-
dependency_set: dependency_set,
|
99
|
-
buildfile: buildfile,
|
100
|
-
previous_requirement: old_req.fetch(:requirement),
|
101
|
-
updated_requirement: new_req.fetch(:requirement)
|
102
|
-
)
|
103
|
-
end
|
104
|
-
|
105
|
-
def update_version_in_buildfile(dependency, buildfile, previous_req,
|
106
|
-
requirement)
|
107
|
-
updated_content =
|
108
|
-
buildfile.content.gsub(
|
109
|
-
original_buildfile_declaration(dependency, previous_req),
|
110
|
-
updated_buildfile_declaration(
|
111
|
-
dependency,
|
112
|
-
previous_req,
|
113
|
-
requirement
|
114
|
-
)
|
115
|
-
)
|
116
|
-
|
117
|
-
if updated_content == buildfile.content
|
118
|
-
raise "Expected content to change!"
|
119
|
-
end
|
120
|
-
|
121
|
-
updated_file(file: buildfile, content: updated_content)
|
122
|
-
end
|
123
|
-
|
124
|
-
def original_buildfile_declaration(dependency, requirement)
|
125
|
-
# This implementation is limited to declarations that appear on a
|
126
|
-
# single line.
|
127
|
-
buildfile = buildfiles.find { |f| f.name == requirement.fetch(:file) }
|
128
|
-
buildfile.content.lines.find do |line|
|
129
|
-
line = evaluate_properties(line, buildfile)
|
130
|
-
next false unless line.include?(dependency.name.split(":").first)
|
131
|
-
next false unless line.include?(dependency.name.split(":").last)
|
132
|
-
|
133
|
-
line.include?(requirement.fetch(:requirement))
|
134
|
-
end
|
135
|
-
end
|
136
|
-
|
137
|
-
def evaluate_properties(string, buildfile)
|
138
|
-
result = string.dup
|
139
|
-
|
140
|
-
string.scan(FileParsers::Java::Gradle::PROPERTY_REGEX) do
|
141
|
-
prop_name = Regexp.last_match.named_captures.fetch("property_name")
|
142
|
-
property_value = property_value_finder.property_value(
|
143
|
-
property_name: prop_name,
|
144
|
-
callsite_buildfile: buildfile
|
145
|
-
)
|
146
|
-
next unless property_value
|
147
|
-
|
148
|
-
result.sub!(Regexp.last_match.to_s, property_value)
|
149
|
-
end
|
150
|
-
|
151
|
-
result
|
152
|
-
end
|
153
|
-
|
154
|
-
def property_value_finder
|
155
|
-
@property_value_finder ||=
|
156
|
-
FileParsers::Java::Gradle::PropertyValueFinder.
|
157
|
-
new(dependency_files: dependency_files)
|
158
|
-
end
|
159
|
-
|
160
|
-
def updated_buildfile_declaration(dependency, previous_req, requirement)
|
161
|
-
original_req_string = previous_req.fetch(:requirement)
|
162
|
-
|
163
|
-
original_buildfile_declaration(dependency, previous_req).gsub(
|
164
|
-
original_req_string,
|
165
|
-
requirement.fetch(:requirement)
|
166
|
-
)
|
167
|
-
end
|
168
|
-
|
169
|
-
def buildfiles
|
170
|
-
@buildfiles ||=
|
171
|
-
dependency_files.select { |f| f.name.end_with?("build.gradle") }
|
172
|
-
end
|
173
|
-
end
|
174
|
-
end
|
175
|
-
end
|
176
|
-
end
|
@@ -1,66 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require "dependabot/file_parsers/java/gradle"
|
4
|
-
require "dependabot/file_updaters/java/gradle"
|
5
|
-
|
6
|
-
module Dependabot
|
7
|
-
module FileUpdaters
|
8
|
-
module Java
|
9
|
-
class Gradle
|
10
|
-
class DependencySetUpdater
|
11
|
-
def initialize(dependency_files:)
|
12
|
-
@dependency_files = dependency_files
|
13
|
-
end
|
14
|
-
|
15
|
-
def update_files_for_dep_set_change(dependency_set:,
|
16
|
-
buildfile:,
|
17
|
-
previous_requirement:,
|
18
|
-
updated_requirement:)
|
19
|
-
declaration_string =
|
20
|
-
original_declaration_string(dependency_set, buildfile)
|
21
|
-
|
22
|
-
return dependency_files unless declaration_string
|
23
|
-
|
24
|
-
updated_content = buildfile.content.sub(
|
25
|
-
declaration_string,
|
26
|
-
declaration_string.sub(
|
27
|
-
previous_requirement,
|
28
|
-
updated_requirement
|
29
|
-
)
|
30
|
-
)
|
31
|
-
|
32
|
-
updated_files = dependency_files.dup
|
33
|
-
updated_files[updated_files.index(buildfile)] =
|
34
|
-
update_file(file: buildfile, content: updated_content)
|
35
|
-
|
36
|
-
updated_files
|
37
|
-
end
|
38
|
-
|
39
|
-
private
|
40
|
-
|
41
|
-
attr_reader :dependency_files
|
42
|
-
|
43
|
-
def original_declaration_string(dependency_set, buildfile)
|
44
|
-
regex = FileParsers::Java::Gradle::DEPENDENCY_SET_DECLARATION_REGEX
|
45
|
-
dependency_sets = []
|
46
|
-
buildfile.content.scan(regex) do
|
47
|
-
dependency_sets << Regexp.last_match.to_s
|
48
|
-
end
|
49
|
-
|
50
|
-
dependency_sets.find do |mtch|
|
51
|
-
next unless mtch.include?(dependency_set[:group])
|
52
|
-
|
53
|
-
mtch.include?(dependency_set[:version])
|
54
|
-
end
|
55
|
-
end
|
56
|
-
|
57
|
-
def update_file(file:, content:)
|
58
|
-
updated_file = file.dup
|
59
|
-
updated_file.content = content
|
60
|
-
updated_file
|
61
|
-
end
|
62
|
-
end
|
63
|
-
end
|
64
|
-
end
|
65
|
-
end
|
66
|
-
end
|