dependabot-core 0.84.1 → 0.85.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,127 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "dependabot/file_parsers/java/maven"
4
- require "dependabot/update_checkers/java/maven"
5
- require "dependabot/update_checkers/java/maven/requirements_updater"
6
- require "dependabot/file_updaters/java/maven/declaration_finder"
7
-
8
- module Dependabot
9
- module UpdateCheckers
10
- module Java
11
- class Maven
12
- class PropertyUpdater
13
- require_relative "version_finder"
14
-
15
- def initialize(dependency:, dependency_files:, credentials:,
16
- target_version_details:, ignored_versions:)
17
- @dependency = dependency
18
- @dependency_files = dependency_files
19
- @credentials = credentials
20
- @ignored_versions = ignored_versions
21
- @target_version = target_version_details&.fetch(:version)
22
- @source_url = target_version_details&.fetch(:source_url)
23
- end
24
-
25
- def update_possible?
26
- return false unless target_version
27
-
28
- @update_possible ||=
29
- dependencies_using_property.all? do |dep|
30
- versions = VersionFinder.new(
31
- dependency: dep,
32
- dependency_files: dependency_files,
33
- credentials: credentials,
34
- ignored_versions: ignored_versions
35
- ).versions.map { |v| v.fetch(:version) }
36
-
37
- versions.include?(target_version) || versions.none?
38
- end
39
- end
40
-
41
- def updated_dependencies
42
- raise "Update not possible!" unless update_possible?
43
-
44
- @updated_dependencies ||=
45
- dependencies_using_property.map do |dep|
46
- Dependency.new(
47
- name: dep.name,
48
- version: updated_version(dep),
49
- requirements: updated_requirements(dep),
50
- previous_version: dep.version,
51
- previous_requirements: dep.requirements,
52
- package_manager: dep.package_manager
53
- )
54
- end
55
- end
56
-
57
- private
58
-
59
- attr_reader :dependency, :dependency_files, :target_version,
60
- :source_url, :credentials, :ignored_versions
61
-
62
- def dependencies_using_property
63
- @dependencies_using_property ||=
64
- FileParsers::Java::Maven.new(
65
- dependency_files: dependency_files,
66
- source: nil
67
- ).parse.select do |dep|
68
- dep.requirements.any? do |r|
69
- next unless r.dig(:metadata, :property_name) == property_name
70
-
71
- r.dig(:metadata, :property_source) == property_source
72
- end
73
- end
74
- end
75
-
76
- def property_name
77
- @property_name ||= dependency.requirements.
78
- find { |r| r.dig(:metadata, :property_name) }&.
79
- dig(:metadata, :property_name)
80
-
81
- raise "No requirement with a property name!" unless @property_name
82
-
83
- @property_name
84
- end
85
-
86
- def property_source
87
- @property_source ||=
88
- dependency.requirements.
89
- find { |r| r.dig(:metadata, :property_name) == property_name }&.
90
- dig(:metadata, :property_source)
91
- end
92
-
93
- def version_string(dep)
94
- declaring_requirement =
95
- dep.requirements.
96
- find { |r| r.dig(:metadata, :property_name) == property_name }
97
-
98
- FileUpdaters::Java::Maven::DeclarationFinder.new(
99
- dependency: dep,
100
- declaring_requirement: declaring_requirement,
101
- dependency_files: dependency_files
102
- ).declaration_nodes.first.at_css("version")&.content
103
- end
104
-
105
- def pom
106
- dependency_files.find { |f| f.name == "pom.xml" }
107
- end
108
-
109
- def updated_version(dep)
110
- version_string(dep).gsub("${#{property_name}}", target_version.to_s)
111
- end
112
-
113
- def updated_requirements(dep)
114
- @updated_requirements ||= {}
115
- @updated_requirements[dep.name] ||=
116
- RequirementsUpdater.new(
117
- requirements: dep.requirements,
118
- latest_version: updated_version(dep),
119
- source_url: source_url,
120
- properties_to_update: [property_name]
121
- ).updated_requirements
122
- end
123
- end
124
- end
125
- end
126
- end
127
- end
@@ -1,92 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- #######################################################
4
- # For more details on Maven version constraints, see: #
5
- # https://maven.apache.org/pom.html#Dependencies #
6
- #######################################################
7
-
8
- require "dependabot/update_checkers/java/maven"
9
- require "dependabot/utils/java/version"
10
- require "dependabot/utils/java/requirement"
11
-
12
- module Dependabot
13
- module UpdateCheckers
14
- module Java
15
- class Maven
16
- class RequirementsUpdater
17
- def initialize(requirements:, latest_version:, source_url:,
18
- properties_to_update:)
19
- @requirements = requirements
20
- @source_url = source_url
21
- @properties_to_update = properties_to_update
22
- return unless latest_version
23
-
24
- @latest_version = version_class.new(latest_version)
25
- end
26
-
27
- def updated_requirements
28
- return requirements unless latest_version
29
-
30
- # Note: Order is important here. The FileUpdater needs the updated
31
- # requirement at index `i` to correspond to the previous requirement
32
- # at the same index.
33
- requirements.map do |req|
34
- next req if req.fetch(:requirement).nil?
35
- next req if req.fetch(:requirement).include?(",")
36
-
37
- property_name = req.dig(:metadata, :property_name)
38
- if property_name && !properties_to_update.include?(property_name)
39
- next req
40
- end
41
-
42
- new_req = update_requirement(req[:requirement])
43
- req.merge(requirement: new_req, source: updated_source)
44
- end
45
- end
46
-
47
- private
48
-
49
- attr_reader :requirements, :latest_version, :source_url,
50
- :properties_to_update
51
-
52
- def update_requirement(req_string)
53
- if req_string.include?(".+")
54
- update_dynamic_requirement(req_string)
55
- else
56
- # Since range requirements are excluded this must be exact
57
- update_exact_requirement(req_string)
58
- end
59
- end
60
-
61
- def update_exact_requirement(req_string)
62
- old_version = requirement_class.new(req_string).
63
- requirements.first.last
64
- req_string.gsub(old_version.to_s, latest_version.to_s)
65
- end
66
-
67
- # This is really only a Gradle thing, but Gradle relies on this
68
- # RequirementsUpdater too
69
- def update_dynamic_requirement(req_string)
70
- precision = req_string.split(".").take_while { |s| s != "+" }.count
71
-
72
- version_parts = latest_version.segments.first(precision)
73
-
74
- version_parts.join(".") + ".+"
75
- end
76
-
77
- def version_class
78
- Utils::Java::Version
79
- end
80
-
81
- def requirement_class
82
- Utils::Java::Requirement
83
- end
84
-
85
- def updated_source
86
- { type: "maven_repo", url: source_url }
87
- end
88
- end
89
- end
90
- end
91
- end
92
- end
@@ -1,225 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "nokogiri"
4
- require "dependabot/shared_helpers"
5
- require "dependabot/file_parsers/java/maven/repositories_finder"
6
- require "dependabot/update_checkers/java/maven"
7
- require "dependabot/utils/java/version"
8
- require "dependabot/utils/java/requirement"
9
-
10
- module Dependabot
11
- module UpdateCheckers
12
- module Java
13
- class Maven
14
- class VersionFinder
15
- TYPE_SUFFICES = %w(jre android java).freeze
16
-
17
- def initialize(dependency:, dependency_files:, credentials:,
18
- ignored_versions:)
19
- @dependency = dependency
20
- @dependency_files = dependency_files
21
- @credentials = credentials
22
- @ignored_versions = ignored_versions
23
- @forbidden_urls = []
24
- end
25
-
26
- def latest_version_details
27
- possible_versions = versions
28
-
29
- unless wants_prerelease?
30
- possible_versions =
31
- possible_versions.
32
- reject { |v| v.fetch(:version).prerelease? }
33
- end
34
-
35
- unless wants_date_based_version?
36
- possible_versions =
37
- possible_versions.
38
- reject { |v| v.fetch(:version) > version_class.new(1900) }
39
- end
40
-
41
- possible_versions =
42
- possible_versions.
43
- select { |v| matches_dependency_version_type?(v.fetch(:version)) }
44
-
45
- ignored_versions.each do |req|
46
- ignore_req = Utils::Java::Requirement.new(req.split(","))
47
- possible_versions =
48
- possible_versions.
49
- reject { |v| ignore_req.satisfied_by?(v.fetch(:version)) }
50
- end
51
-
52
- possible_versions.reverse.find { |v| released?(v.fetch(:version)) }
53
- end
54
-
55
- def versions
56
- version_details =
57
- repositories.map do |repository_details|
58
- url = repository_details.fetch("url")
59
- dependency_metadata(repository_details).
60
- css("versions > version").
61
- select { |node| version_class.correct?(node.content) }.
62
- map { |node| version_class.new(node.content) }.
63
- map { |version| { version: version, source_url: url } }
64
- end.flatten
65
-
66
- if version_details.none? && forbidden_urls.any?
67
- raise PrivateSourceAuthenticationFailure, forbidden_urls.first
68
- end
69
-
70
- version_details.sort_by { |details| details.fetch(:version) }
71
- end
72
-
73
- private
74
-
75
- attr_reader :dependency, :dependency_files, :credentials,
76
- :ignored_versions, :forbidden_urls
77
-
78
- def wants_prerelease?
79
- return false unless dependency.version
80
- return false unless version_class.correct?(dependency.version)
81
-
82
- version_class.new(dependency.version).prerelease?
83
- end
84
-
85
- def wants_date_based_version?
86
- return false unless dependency.version
87
- return false unless version_class.correct?(dependency.version)
88
-
89
- version_class.new(dependency.version) >= version_class.new(100)
90
- end
91
-
92
- def released?(version)
93
- repositories.any? do |repository_details|
94
- url = repository_details.fetch("url")
95
- response = Excon.get(
96
- dependency_files_url(url, version),
97
- user: repository_details.fetch("username"),
98
- password: repository_details.fetch("password"),
99
- idempotent: true,
100
- **SharedHelpers.excon_defaults
101
- )
102
-
103
- artifact_id = dependency.name.split(":").last
104
- type = dependency.requirements.first.
105
- dig(:metadata, :packaging_type)
106
- response.body.include?("#{artifact_id}-#{version}.#{type}")
107
- rescue Excon::Error::Socket, Excon::Error::Timeout
108
- false
109
- end
110
- end
111
-
112
- def dependency_metadata(repository_details)
113
- @dependency_metadata ||= {}
114
- @dependency_metadata[repository_details.hash] ||=
115
- begin
116
- response = Excon.get(
117
- dependency_metadata_url(repository_details.fetch("url")),
118
- user: repository_details.fetch("username"),
119
- password: repository_details.fetch("password"),
120
- idempotent: true,
121
- **SharedHelpers.excon_defaults
122
- )
123
- check_response(response, repository_details.fetch("url"))
124
- Nokogiri::XML(response.body)
125
- rescue Excon::Error::Socket, Excon::Error::Timeout
126
- central =
127
- FileParsers::Java::Maven::RepositoriesFinder::CENTRAL_REPO_URL
128
- raise if repository_details.fetch("url") == central
129
-
130
- Nokogiri::XML("")
131
- end
132
- end
133
-
134
- def check_response(response, repository_url)
135
- central =
136
- FileParsers::Java::Maven::RepositoriesFinder::CENTRAL_REPO_URL
137
-
138
- return unless [401, 403].include?(response.status)
139
- return if @forbidden_urls.include?(repository_url)
140
- return if repository_url == central
141
-
142
- @forbidden_urls << repository_url
143
- end
144
-
145
- def repositories
146
- return @repositories if @repositories
147
-
148
- details = pom_repository_details + credentials_repository_details
149
-
150
- @repositories =
151
- details.reject do |repo|
152
- next if repo["password"]
153
-
154
- # Reject this entry if an identical one with a password exists
155
- details.any? { |r| r["url"] == repo["url"] && r["password"] }
156
- end
157
- end
158
-
159
- def pom_repository_details
160
- @pom_repository_details ||=
161
- FileParsers::Java::Maven::RepositoriesFinder.
162
- new(dependency_files: dependency_files).
163
- repository_urls(pom: pom).
164
- map do |url|
165
- { "url" => url, "username" => nil, "password" => nil }
166
- end
167
- end
168
-
169
- def credentials_repository_details
170
- credentials.
171
- select { |cred| cred["type"] == "maven_repository" }.
172
- map do |cred|
173
- {
174
- "url" => cred.fetch("url").gsub(%r{/+$}, ""),
175
- "username" => cred.fetch("username", nil),
176
- "password" => cred.fetch("password", nil)
177
- }
178
- end
179
- end
180
-
181
- def matches_dependency_version_type?(comparison_version)
182
- return true unless dependency.version
183
-
184
- current_type =
185
- TYPE_SUFFICES.
186
- find { |t| dependency.version.split(/[.\-]/).include?(t) }
187
-
188
- version_type =
189
- TYPE_SUFFICES.
190
- find { |t| comparison_version.to_s.split(/[.\-]/).include?(t) }
191
-
192
- current_type == version_type
193
- end
194
-
195
- def pom
196
- filename = dependency.requirements.first.fetch(:file)
197
- dependency_files.find { |f| f.name == filename }
198
- end
199
-
200
- def dependency_metadata_url(repository_url)
201
- group_id, artifact_id = dependency.name.split(":")
202
-
203
- "#{repository_url}/"\
204
- "#{group_id.tr('.', '/')}/"\
205
- "#{artifact_id}/"\
206
- "maven-metadata.xml"
207
- end
208
-
209
- def dependency_files_url(repository_url, version)
210
- group_id, artifact_id = dependency.name.split(":")
211
-
212
- "#{repository_url}/"\
213
- "#{group_id.tr('.', '/')}/"\
214
- "#{artifact_id}/"\
215
- "#{version}/"
216
- end
217
-
218
- def version_class
219
- Utils::Java::Version
220
- end
221
- end
222
- end
223
- end
224
- end
225
- end
@@ -1,110 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "dependabot/utils/java/version"
4
-
5
- module Dependabot
6
- module Utils
7
- module Java
8
- class Requirement < Gem::Requirement
9
- quoted = OPS.keys.map { |k| Regexp.quote k }.join("|")
10
- PATTERN_RAW =
11
- "\\s*(#{quoted})?\\s*(#{Utils::Java::Version::VERSION_PATTERN})\\s*"
12
- PATTERN = /\A#{PATTERN_RAW}\z/.freeze
13
-
14
- def self.parse(obj)
15
- if obj.is_a?(Gem::Version)
16
- return ["=", Utils::Java::Version.new(obj.to_s)]
17
- end
18
-
19
- unless (matches = PATTERN.match(obj.to_s))
20
- msg = "Illformed requirement [#{obj.inspect}]"
21
- raise BadRequirementError, msg
22
- end
23
-
24
- return DefaultRequirement if matches[1] == ">=" && matches[2] == "0"
25
-
26
- [matches[1] || "=", Utils::Java::Version.new(matches[2])]
27
- end
28
-
29
- def self.requirements_array(requirement_string)
30
- split_java_requirement(requirement_string).map do |str|
31
- new(str)
32
- end
33
- end
34
-
35
- def initialize(*requirements)
36
- requirements = requirements.flatten.flat_map do |req_string|
37
- convert_java_constraint_to_ruby_constraint(req_string)
38
- end
39
-
40
- super(requirements)
41
- end
42
-
43
- def satisfied_by?(version)
44
- version = Utils::Java::Version.new(version.to_s)
45
- super
46
- end
47
-
48
- private
49
-
50
- def self.split_java_requirement(req_string)
51
- req_string.split(/(?<=\]|\)),/).flat_map do |str|
52
- next str if str.start_with?("(", "[")
53
-
54
- exacts, *rest = str.split(/,(?=\[|\()/)
55
- [*exacts.split(","), *rest]
56
- end
57
- end
58
- private_class_method :split_java_requirement
59
-
60
- def convert_java_constraint_to_ruby_constraint(req_string)
61
- return unless req_string
62
-
63
- if self.class.send(:split_java_requirement, req_string).count > 1
64
- raise "Can't convert multiple Java reqs to a single Ruby one"
65
- end
66
-
67
- if req_string&.include?(",")
68
- return convert_java_range_to_ruby_range(req_string)
69
- end
70
-
71
- convert_java_equals_req_to_ruby(req_string)
72
- end
73
-
74
- def convert_java_range_to_ruby_range(req_string)
75
- lower_b, upper_b = req_string.split(",").map(&:strip)
76
-
77
- lower_b =
78
- if ["(", "["].include?(lower_b) then nil
79
- elsif lower_b.start_with?("(") then "> #{lower_b.sub(/\(\s*/, '')}"
80
- else ">= #{lower_b.sub(/\[\s*/, '').strip}"
81
- end
82
-
83
- upper_b =
84
- if [")", "]"].include?(upper_b) then nil
85
- elsif upper_b.end_with?(")") then "< #{upper_b.sub(/\s*\)/, '')}"
86
- else "<= #{upper_b.sub(/\s*\]/, '').strip}"
87
- end
88
-
89
- [lower_b, upper_b].compact
90
- end
91
-
92
- def convert_java_equals_req_to_ruby(req_string)
93
- return convert_wildcard_req(req_string) if req_string&.include?("+")
94
-
95
- # If a soft requirement is being used, treat it as an equality matcher
96
- return req_string unless req_string&.start_with?("[")
97
-
98
- req_string.gsub(/[\[\]\(\)]/, "")
99
- end
100
-
101
- def convert_wildcard_req(req_string)
102
- version = req_string.gsub(/(?:\.|^)\+/, "")
103
- return ">= 0" if version.empty?
104
-
105
- "~> #{version}.0"
106
- end
107
- end
108
- end
109
- end
110
- end