dependabot-core 0.83.2 → 0.84.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.
@@ -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