dependabot-maven 0.211.0 → 0.213.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b27a606e758a694d530b58bef9c1135138e041909753e66070b75da20d456e06
4
- data.tar.gz: 1896007d54b0b5be26fbeb1c6cf9d7baf915e4f0653a498895d0cd2c47479870
3
+ metadata.gz: 68711b5b438172e0e075d72ef2cb8b7b86994f612f5e65d4ccd8132a8e46212c
4
+ data.tar.gz: 14ab13cf9c9f09662510ff5ea97d3f37677620d8a96b3d18be5c6b7b3e90bae5
5
5
  SHA512:
6
- metadata.gz: 52453588e68a9277e93d3e47ea0b762b67b598fb500bf1508894ae17b182434fd9dbb3fdbc1c3f475cc4fbde2b553dbdfe28f8b248b173d3489cd839859a746f
7
- data.tar.gz: b47b9fa0958db859be40836138604108f711252bcefad7c62e426e33e370324a4f80b960c8d13cd8c8db27b6745877bbe5cddca5ada52ffa64abe357ca335cca
6
+ metadata.gz: 633b8678f53dbc5caae6a1ca4d226a1651b51c3a6605fc5aed2f8b053912cc37427ee1f16873e588976ccb47987f1e1ad4a7e2df11d09aa5efdf55fd245e1645
7
+ data.tar.gz: 619707ebc8b916e98e73aa3151bcdcc3dd1c8ba0c15f131012ad75432de66d7a15633e39033305ecc5216bee798a24968aaf4ac6560ea77e58d382ac6fd1ee8f
@@ -7,7 +7,7 @@ require "dependabot/file_fetchers/base"
7
7
  module Dependabot
8
8
  module Maven
9
9
  class FileFetcher < Dependabot::FileFetchers::Base
10
- MODULE_SELECTOR = "project > modules > module, "\
10
+ MODULE_SELECTOR = "project > modules > module, " \
11
11
  "profile > modules > module"
12
12
 
13
13
  def self.required_files_in?(filenames)
@@ -0,0 +1,122 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "nokogiri"
4
+
5
+ require "dependabot/dependency_file"
6
+ require "dependabot/maven/file_parser"
7
+ require "dependabot/registry_client"
8
+
9
+ module Dependabot
10
+ module Maven
11
+ class FileParser
12
+ class PomFetcher
13
+ def initialize(dependency_files:)
14
+ @dependency_files = dependency_files
15
+ @poms = {}
16
+ end
17
+
18
+ def internal_dependency_poms
19
+ return @internal_dependency_poms if @internal_dependency_poms
20
+
21
+ @internal_dependency_poms = {}
22
+ dependency_files.each do |pom|
23
+ doc = Nokogiri::XML(pom.content)
24
+ group_id = doc.at_css("project > groupId") ||
25
+ doc.at_css("project > parent > groupId")
26
+ artifact_id = doc.at_css("project > artifactId")
27
+
28
+ next unless group_id && artifact_id
29
+
30
+ dependency_name = [
31
+ group_id.content.strip,
32
+ artifact_id.content.strip
33
+ ].join(":")
34
+
35
+ @internal_dependency_poms[dependency_name] = pom
36
+ end
37
+
38
+ @internal_dependency_poms
39
+ end
40
+
41
+ def fetch_remote_parent_pom(group_id, artifact_id, version, urls_to_try)
42
+ pom_id = "#{group_id}:#{artifact_id}:#{version}"
43
+ return @poms[pom_id] if @poms.key?(pom_id)
44
+
45
+ urls_to_try.each do |base_url|
46
+ url =
47
+ if version.include?("SNAPSHOT")
48
+ fetch_snapshot_pom_url(group_id, artifact_id, version, base_url)
49
+ else
50
+ remote_pom_url(group_id, artifact_id, version, base_url)
51
+ end
52
+ next if url.nil?
53
+
54
+ response = fetch(url)
55
+ next unless response.status == 200
56
+ next unless pom?(response.body)
57
+
58
+ dependency_file = DependencyFile.new(
59
+ name: "remote_pom.xml",
60
+ content: response.body
61
+ )
62
+
63
+ @poms[pom_id] = dependency_file
64
+ return dependency_file
65
+ rescue Excon::Error::Socket, Excon::Error::Timeout,
66
+ Excon::Error::TooManyRedirects, URI::InvalidURIError
67
+ nil
68
+ end
69
+
70
+ # If a parent POM couldn't be found, return `nil`
71
+ nil
72
+ end
73
+
74
+ private
75
+
76
+ def remote_pom_url(group_id, artifact_id, version, base_repo_url)
77
+ "#{base_repo_url}/" \
78
+ "#{group_id.tr('.', '/')}/#{artifact_id}/#{version}/" \
79
+ "#{artifact_id}-#{version}.pom"
80
+ end
81
+
82
+ def remote_pom_snapshot_url(group_id, artifact_id, version, snapshot_version, base_repo_url)
83
+ "#{base_repo_url}/" \
84
+ "#{group_id.tr('.', '/')}/#{artifact_id}/#{version}/" \
85
+ "#{artifact_id}-#{snapshot_version}.pom"
86
+ end
87
+
88
+ def remote_pom_snapshot_metadata_url(group_id, artifact_id, version, base_repo_url)
89
+ "#{base_repo_url}/" \
90
+ "#{group_id.tr('.', '/')}/#{artifact_id}/#{version}/" \
91
+ "maven-metadata.xml"
92
+ end
93
+
94
+ def fetch_snapshot_pom_url(group_id, artifact_id, version, base_url)
95
+ url = remote_pom_snapshot_metadata_url(group_id, artifact_id, version, base_url)
96
+ response = fetch(url)
97
+ return nil unless response.status == 200
98
+
99
+ snapshot = Nokogiri::XML(response.body).
100
+ css("snapshotVersion").
101
+ find { |node| node.at_css("extension").content == "pom" }&.
102
+ at_css("value")&.
103
+ content
104
+ return nil unless snapshot
105
+
106
+ remote_pom_snapshot_url(group_id, artifact_id, version, snapshot, base_url)
107
+ end
108
+
109
+ def fetch(url)
110
+ @maven_responses ||= {}
111
+ @maven_responses[url] ||= Dependabot::RegistryClient.get(url: url, options: { retry_limit: 1 })
112
+ end
113
+
114
+ def pom?(content)
115
+ !Nokogiri::XML(content).at_css("project > artifactId").nil?
116
+ end
117
+
118
+ attr_reader :dependency_files
119
+ end
120
+ end
121
+ end
122
+ end
@@ -14,11 +14,14 @@ module Dependabot
14
14
  class FileParser
15
15
  class PropertyValueFinder
16
16
  require_relative "repositories_finder"
17
+ require_relative "pom_fetcher"
17
18
 
18
- DOT_SEPARATOR_REGEX = %r{\.(?!\d+([.\/_\-]|$)+)}.freeze
19
+ DOT_SEPARATOR_REGEX = %r{\.(?!\d+([.\/_\-]|$)+)}
19
20
 
20
- def initialize(dependency_files:)
21
+ def initialize(dependency_files:, credentials: [])
21
22
  @dependency_files = dependency_files
23
+ @credentials = credentials
24
+ @pom_fetcher = PomFetcher.new(dependency_files: dependency_files)
22
25
  end
23
26
 
24
27
  def property_details(property_name:, callsite_pom:)
@@ -60,29 +63,6 @@ module Dependabot
60
63
 
61
64
  attr_reader :dependency_files
62
65
 
63
- def internal_dependency_poms
64
- return @internal_dependency_poms if @internal_dependency_poms
65
-
66
- @internal_dependency_poms = {}
67
- dependency_files.each do |pom|
68
- doc = Nokogiri::XML(pom.content)
69
- group_id = doc.at_css("project > groupId") ||
70
- doc.at_css("project > parent > groupId")
71
- artifact_id = doc.at_css("project > artifactId")
72
-
73
- next unless group_id && artifact_id
74
-
75
- dependency_name = [
76
- group_id.content.strip,
77
- artifact_id.content.strip
78
- ].join(":")
79
-
80
- @internal_dependency_poms[dependency_name] = pom
81
- end
82
-
83
- @internal_dependency_poms
84
- end
85
-
86
66
  def sanitize_property_name(property_name)
87
67
  property_name.sub(/^pom\./, "").sub(/^project\./, "")
88
68
  end
@@ -100,11 +80,11 @@ module Dependabot
100
80
 
101
81
  name = [group_id, artifact_id].join(":")
102
82
 
103
- return internal_dependency_poms[name] if internal_dependency_poms[name]
83
+ return @pom_fetcher.internal_dependency_poms[name] if @pom_fetcher.internal_dependency_poms[name]
104
84
 
105
85
  return unless version && !version.include?(",")
106
86
 
107
- fetch_remote_parent_pom(group_id, artifact_id, version, pom)
87
+ @pom_fetcher.fetch_remote_parent_pom(group_id, artifact_id, version, parent_repository_urls(pom))
108
88
  end
109
89
  # rubocop:enable Metrics/PerceivedComplexity
110
90
 
@@ -118,44 +98,12 @@ module Dependabot
118
98
  def repositories_finder
119
99
  @repositories_finder ||=
120
100
  RepositoriesFinder.new(
101
+ pom_fetcher: @pom_fetcher,
121
102
  dependency_files: dependency_files,
103
+ credentials: @credentials,
122
104
  evaluate_properties: false
123
105
  )
124
106
  end
125
-
126
- def fetch_remote_parent_pom(group_id, artifact_id, version, pom)
127
- parent_repository_urls(pom).each do |base_url|
128
- url = remote_pom_url(group_id, artifact_id, version, base_url)
129
-
130
- @maven_responses ||= {}
131
- @maven_responses[url] ||= Dependabot::RegistryClient.get(url: url)
132
- next unless @maven_responses[url].status == 200
133
- next unless pom?(@maven_responses[url].body)
134
-
135
- dependency_file = DependencyFile.new(
136
- name: "remote_pom.xml",
137
- content: @maven_responses[url].body
138
- )
139
-
140
- return dependency_file
141
- rescue Excon::Error::Socket, Excon::Error::Timeout,
142
- Excon::Error::TooManyRedirects, URI::InvalidURIError
143
- nil
144
- end
145
-
146
- # If a parent POM couldn't be found, return `nil`
147
- nil
148
- end
149
-
150
- def remote_pom_url(group_id, artifact_id, version, base_repo_url)
151
- "#{base_repo_url}/"\
152
- "#{group_id.tr('.', '/')}/#{artifact_id}/#{version}/"\
153
- "#{artifact_id}-#{version}.pom"
154
- end
155
-
156
- def pom?(content)
157
- !Nokogiri::XML(content).at_css("project > artifactId").nil?
158
- end
159
107
  end
160
108
  end
161
109
  end
@@ -15,48 +15,78 @@ module Dependabot
15
15
  class FileParser
16
16
  class RepositoriesFinder
17
17
  require_relative "property_value_finder"
18
+ require_relative "pom_fetcher"
18
19
  # In theory we should check the artifact type and either look in
19
20
  # <repositories> or <pluginRepositories>. In practice it's unlikely
20
21
  # anyone makes this distinction.
21
- REPOSITORY_SELECTOR = "repositories > repository, "\
22
+ REPOSITORY_SELECTOR = "repositories > repository, " \
22
23
  "pluginRepositories > pluginRepository"
23
24
 
24
- # The Central Repository is included in the Super POM, which is
25
- # always inherited from.
26
- CENTRAL_REPO_URL = "https://repo.maven.apache.org/maven2"
27
-
28
- def initialize(dependency_files:, evaluate_properties: true)
25
+ def initialize(pom_fetcher:, dependency_files: [], credentials: [], evaluate_properties: true)
26
+ @pom_fetcher = pom_fetcher
29
27
  @dependency_files = dependency_files
28
+ @credentials = credentials
30
29
 
31
30
  # We need the option not to evaluate properties so as not to have a
32
31
  # circular dependency between this class and the PropertyValueFinder
33
32
  # class
34
33
  @evaluate_properties = evaluate_properties
34
+ # Aggregates URLs seen in POMs to avoid short term memory loss.
35
+ # For instance a repository in a child POM might apply to the parent too.
36
+ @known_urls = []
37
+ end
38
+
39
+ def central_repo_url
40
+ base = @credentials.find { |cred| cred["type"] == "maven_repository" && cred["replaces-base"] == true }
41
+ base ? base["url"] : "https://repo.maven.apache.org/maven2"
35
42
  end
36
43
 
37
44
  # Collect all repository URLs from this POM and its parents
38
45
  def repository_urls(pom:, exclude_inherited: false)
39
- repo_urls_in_pom =
40
- Nokogiri::XML(pom.content).
41
- css(REPOSITORY_SELECTOR).
42
- map { |node| node.at_css("url").content.strip.gsub(%r{/$}, "") }.
43
- reject { |url| contains_property?(url) && !evaluate_properties? }.
44
- select { |url| url.start_with?("http") }.
45
- map { |url| evaluated_value(url, pom) }
46
+ entries = gather_repository_urls(pom: pom, exclude_inherited: exclude_inherited)
47
+ ids = Set.new
48
+ @known_urls += entries.map do |entry|
49
+ next if entry[:id] && ids.include?(entry[:id])
46
50
 
47
- return repo_urls_in_pom + [CENTRAL_REPO_URL] if exclude_inherited
48
-
49
- unless (parent = parent_pom(pom, repo_urls_in_pom))
50
- return repo_urls_in_pom + [CENTRAL_REPO_URL]
51
+ ids.add(entry[:id]) unless entry[:id].nil?
52
+ entry
51
53
  end
54
+ @known_urls = @known_urls.uniq.compact
52
55
 
53
- repo_urls_in_pom + repository_urls(pom: parent)
56
+ urls = urls_from_credentials + @known_urls.map { |entry| entry[:url] }
57
+ urls += [central_repo_url] unless @known_urls.any? { |entry| entry[:id] == super_pom[:id] }
58
+ urls.uniq
54
59
  end
55
60
 
56
61
  private
57
62
 
58
63
  attr_reader :dependency_files
59
64
 
65
+ # The Central Repository is included in the Super POM, which is
66
+ # always inherited from.
67
+ def super_pom
68
+ { url: central_repo_url, id: "central" }
69
+ end
70
+
71
+ def gather_repository_urls(pom:, exclude_inherited: false)
72
+ repos_in_pom =
73
+ Nokogiri::XML(pom.content).
74
+ css(REPOSITORY_SELECTOR).
75
+ map { |node| { url: node.at_css("url").content.strip, id: node.at_css("id").content.strip } }.
76
+ reject { |entry| contains_property?(entry[:url]) && !evaluate_properties? }.
77
+ select { |entry| entry[:url].start_with?("http") }.
78
+ map { |entry| { url: evaluated_value(entry[:url], pom).gsub(%r{/$}, ""), id: entry[:id] } }
79
+
80
+ return repos_in_pom if exclude_inherited
81
+
82
+ urls_in_pom = repos_in_pom.map { |repo| repo[:url] }
83
+ unless (parent = parent_pom(pom, urls_in_pom))
84
+ return repos_in_pom
85
+ end
86
+
87
+ repos_in_pom + gather_repository_urls(pom: parent)
88
+ end
89
+
60
90
  def evaluate_properties?
61
91
  @evaluate_properties
62
92
  end
@@ -74,72 +104,19 @@ module Dependabot
74
104
 
75
105
  name = [group_id, artifact_id].join(":")
76
106
 
77
- return internal_dependency_poms[name] if internal_dependency_poms[name]
107
+ return @pom_fetcher.internal_dependency_poms[name] if @pom_fetcher.internal_dependency_poms[name]
78
108
 
79
109
  return unless version && !version.include?(",")
80
110
 
81
- fetch_remote_parent_pom(group_id, artifact_id, version, repo_urls)
111
+ urls = urls_from_credentials + repo_urls + [central_repo_url]
112
+ @pom_fetcher.fetch_remote_parent_pom(group_id, artifact_id, version, urls)
82
113
  end
83
114
  # rubocop:enable Metrics/PerceivedComplexity
84
115
 
85
- def internal_dependency_poms
86
- return @internal_dependency_poms if @internal_dependency_poms
87
-
88
- @internal_dependency_poms = {}
89
- dependency_files.each do |pom|
90
- doc = Nokogiri::XML(pom.content)
91
- group_id = doc.at_css("project > groupId") ||
92
- doc.at_css("project > parent > groupId")
93
- artifact_id = doc.at_css("project > artifactId")
94
-
95
- next unless group_id && artifact_id
96
-
97
- dependency_name = [
98
- group_id.content.strip,
99
- artifact_id.content.strip
100
- ].join(":")
101
-
102
- @internal_dependency_poms[dependency_name] = pom
103
- end
104
-
105
- @internal_dependency_poms
106
- end
107
-
108
- def fetch_remote_parent_pom(group_id, artifact_id, version, repo_urls)
109
- (repo_urls + [CENTRAL_REPO_URL]).uniq.each do |base_url|
110
- url = remote_pom_url(group_id, artifact_id, version, base_url)
111
-
112
- @maven_responses ||= {}
113
- @maven_responses[url] ||= Dependabot::RegistryClient.get(
114
- url: url,
115
- # We attempt to find dependencies in private repos before failing over to the CENTRAL_REPO_URL,
116
- # but this can burn a lot of a job's time against slow servers due to our `read_timeout` being 20 seconds.
117
- #
118
- # In order to avoid the overall job timing out, we only make one retry attempt
119
- options: { retry_limit: 1 }
120
- )
121
- next unless @maven_responses[url].status == 200
122
- next unless pom?(@maven_responses[url].body)
123
-
124
- dependency_file = DependencyFile.new(
125
- name: "remote_pom.xml",
126
- content: @maven_responses[url].body
127
- )
128
-
129
- return dependency_file
130
- rescue Excon::Error::Socket, Excon::Error::Timeout,
131
- Excon::Error::TooManyRedirects, URI::InvalidURIError
132
- nil
133
- end
134
-
135
- # If a parent POM couldn't be found, return `nil`
136
- nil
137
- end
138
-
139
- def remote_pom_url(group_id, artifact_id, version, base_repo_url)
140
- "#{base_repo_url}/"\
141
- "#{group_id.tr('.', '/')}/#{artifact_id}/#{version}/"\
142
- "#{artifact_id}-#{version}.pom"
116
+ def urls_from_credentials
117
+ @credentials.
118
+ select { |cred| cred["type"] == "maven_repository" }.
119
+ filter_map { |cred| cred["url"]&.strip&.gsub(%r{/$}, "") }
143
120
  end
144
121
 
145
122
  def contains_property?(value)
@@ -174,16 +151,12 @@ module Dependabot
174
151
  # values from parent POMs)
175
152
  def property_value_finder
176
153
  @property_value_finder ||=
177
- PropertyValueFinder.new(dependency_files: dependency_files)
154
+ PropertyValueFinder.new(dependency_files: dependency_files, credentials: @credentials)
178
155
  end
179
156
 
180
157
  def property_regex
181
158
  Maven::FileParser::PROPERTY_REGEX
182
159
  end
183
-
184
- def pom?(content)
185
- !Nokogiri::XML(content).at_css("project > artifactId").nil?
186
- end
187
160
  end
188
161
  end
189
162
  end
@@ -21,14 +21,14 @@ module Dependabot
21
21
  # - Any dependencies (incl. those in dependencyManagement or plugins)
22
22
  # - Any plugins (incl. those in pluginManagement)
23
23
  # - Any extensions
24
- DEPENDENCY_SELECTOR = "project > parent, "\
25
- "dependencies > dependency, "\
24
+ DEPENDENCY_SELECTOR = "project > parent, " \
25
+ "dependencies > dependency, " \
26
26
  "extensions > extension"
27
27
  PLUGIN_SELECTOR = "plugins > plugin"
28
28
  EXTENSION_SELECTOR = "extensions > extension"
29
29
 
30
30
  # Regex to get the property name from a declaration that uses a property
31
- PROPERTY_REGEX = /\$\{(?<property>.*?)\}/.freeze
31
+ PROPERTY_REGEX = /\$\{(?<property>.*?)\}/
32
32
 
33
33
  def parse
34
34
  dependency_set = DependencySet.new
@@ -267,7 +267,7 @@ module Dependabot
267
267
  # values from parent POMs)
268
268
  def property_value_finder
269
269
  @property_value_finder ||=
270
- PropertyValueFinder.new(dependency_files: dependency_files)
270
+ PropertyValueFinder.new(dependency_files: dependency_files, credentials: credentials)
271
271
  end
272
272
 
273
273
  def pomfiles
@@ -283,7 +283,7 @@ module Dependabot
283
283
 
284
284
  def internal_dependency_names
285
285
  @internal_dependency_names ||=
286
- dependency_files.map do |pom|
286
+ dependency_files.filter_map do |pom|
287
287
  doc = Nokogiri::XML(pom.content)
288
288
  group_id = doc.at_css("project > groupId") ||
289
289
  doc.at_css("project > parent > groupId")
@@ -292,7 +292,7 @@ module Dependabot
292
292
  next unless group_id && artifact_id
293
293
 
294
294
  [group_id.content.strip, artifact_id.content.strip].join(":")
295
- end.compact
295
+ end
296
296
  end
297
297
 
298
298
  def check_required_files
@@ -11,7 +11,7 @@ module Dependabot
11
11
  class DeclarationFinder
12
12
  DECLARATION_REGEX =
13
13
  %r{<parent>.*?</parent>|<dependency>.*?</dependency>|
14
- <plugin>.*?(?:<plugin>.*?</plugin>.*)?</plugin>|<extension>.*?</extension>}mx.freeze
14
+ <plugin>.*?(?:<plugin>.*?</plugin>.*)?</plugin>|<extension>.*?</extension>}mx
15
15
 
16
16
  attr_reader :dependency, :declaring_requirement, :dependency_files
17
17
 
@@ -28,7 +28,7 @@ module Dependabot
28
28
  \s*#{Regexp.quote(node.content)}\s*
29
29
  </#{Regexp.quote(node.name)}>}xm
30
30
  property_text = node.to_s
31
- if pom_to_update.content =~ property_re
31
+ if pom_to_update.content&.match?(property_re)
32
32
  updated_content = pom_to_update.content.sub(
33
33
  property_re,
34
34
  "<#{node.name}>#{updated_value}</#{node.name}>"
@@ -31,7 +31,7 @@ module Dependabot
31
31
  )
32
32
  end
33
33
 
34
- updated_files.select! { |f| f.name.end_with?("pom.xml") || f.name.end_with?("extensions.xml") }
34
+ updated_files.select! { |f| f.name.end_with?("pom.xml", "extensions.xml") }
35
35
  updated_files.reject! { |f| dependency_files.include?(f) }
36
36
 
37
37
  raise "No files changed!" if updated_files.none?
@@ -89,10 +89,9 @@ module Dependabot
89
89
  updated_content = file.content
90
90
 
91
91
  original_file_declarations(dependency, previous_req).each do |old_dec|
92
- updated_content = updated_content.gsub(
93
- old_dec,
92
+ updated_content = updated_content.gsub(old_dec) do
94
93
  updated_file_declaration(old_dec, previous_req, requirement)
95
- )
94
+ end
96
95
  end
97
96
 
98
97
  raise "Expected content to change!" if updated_content == file.content
@@ -12,7 +12,7 @@ require "dependabot/registry_client"
12
12
  module Dependabot
13
13
  module Maven
14
14
  class MetadataFinder < Dependabot::MetadataFinders::Base
15
- DOT_SEPARATOR_REGEX = %r{\.(?!\d+([.\/_\-]|$)+)}.freeze
15
+ DOT_SEPARATOR_REGEX = %r{\.(?!\d+([.\/_\-]|$)+)}
16
16
 
17
17
  private
18
18
 
@@ -131,8 +131,8 @@ module Dependabot
131
131
 
132
132
  return unless artifact_id && group_id && version
133
133
 
134
- url = "#{maven_repo_url}/#{group_id.tr('.', '/')}/#{artifact_id}/"\
135
- "#{version}/"\
134
+ url = "#{maven_repo_url}/#{group_id.tr('.', '/')}/#{artifact_id}/" \
135
+ "#{version}/" \
136
136
  "#{artifact_id}-#{version}.pom"
137
137
 
138
138
  response = Dependabot::RegistryClient.get(
@@ -149,7 +149,7 @@ module Dependabot
149
149
 
150
150
  source&.fetch(:url, nil) ||
151
151
  source&.fetch("url") ||
152
- Maven::FileParser::RepositoriesFinder::CENTRAL_REPO_URL
152
+ Maven::FileParser::RepositoriesFinder.new(credentials: credentials).central_repo_url
153
153
  end
154
154
 
155
155
  def maven_repo_dependency_url
@@ -7,10 +7,9 @@ module Dependabot
7
7
  module Maven
8
8
  class Requirement < Gem::Requirement
9
9
  quoted = OPS.keys.map { |k| Regexp.quote k }.join("|")
10
- OR_SYNTAX = /(?<=\]|\)),/.freeze
11
- PATTERN_RAW =
12
- "\\s*(#{quoted})?\\s*(#{Maven::Version::VERSION_PATTERN})\\s*"
13
- PATTERN = /\A#{PATTERN_RAW}\z/.freeze
10
+ OR_SYNTAX = /(?<=\]|\)),/
11
+ PATTERN_RAW = "\\s*(#{quoted})?\\s*(#{Maven::Version::VERSION_PATTERN})\\s*"
12
+ PATTERN = /\A#{PATTERN_RAW}\z/
14
13
 
15
14
  def self.parse(obj)
16
15
  return ["=", Maven::Version.new(obj.to_s)] if obj.is_a?(Gem::Version)
@@ -57,8 +57,10 @@ module Dependabot
57
57
  version_details =
58
58
  repositories.map do |repository_details|
59
59
  url = repository_details.fetch("url")
60
- dependency_metadata(repository_details).
61
- css("versions > version").
60
+ xml = dependency_metadata(repository_details)
61
+ next [] if xml.blank?
62
+
63
+ break xml.css("versions > version").
62
64
  select { |node| version_class.correct?(node.content) }.
63
65
  map { |node| version_class.new(node.content) }.
64
66
  map { |version| { version: version, source_url: url } }
@@ -166,15 +168,16 @@ module Dependabot
166
168
  headers: repository_details.fetch("auth_headers")
167
169
  )
168
170
  check_response(response, repository_details.fetch("url"))
171
+ return unless response.status < 400
169
172
 
170
173
  Nokogiri::XML(response.body)
171
174
  rescue URI::InvalidURIError
172
- Nokogiri::XML("")
175
+ nil
173
176
  rescue Excon::Error::Socket, Excon::Error::Timeout,
174
177
  Excon::Error::TooManyRedirects
175
178
  raise if central_repo_urls.include?(repository_details["url"])
176
179
 
177
- Nokogiri::XML("")
180
+ nil
178
181
  end
179
182
 
180
183
  def check_response(response, repository_url)
@@ -188,21 +191,25 @@ module Dependabot
188
191
  def repositories
189
192
  return @repositories if defined?(@repositories)
190
193
 
191
- details = pom_repository_details + credentials_repository_details
192
-
193
- @repositories =
194
- details.reject do |repo|
195
- next if repo["auth_headers"]
194
+ @repositories = credentials_repository_details
195
+ pom_repository_details.each do |repo|
196
+ @repositories << repo unless @repositories.any? { |r| r["url"] == repo["url"] }
197
+ end
198
+ @repositories
199
+ end
196
200
 
197
- # Reject this entry if an identical one with non-empty auth_headers exists
198
- details.any? { |r| r["url"] == repo["url"] && r["auth_headers"] != {} }
199
- end
201
+ def repository_finder
202
+ @repository_finder ||=
203
+ Maven::FileParser::RepositoriesFinder.new(
204
+ pom_fetcher: Maven::FileParser::PomFetcher.new(dependency_files: dependency_files),
205
+ dependency_files: dependency_files,
206
+ credentials: credentials
207
+ )
200
208
  end
201
209
 
202
210
  def pom_repository_details
203
211
  @pom_repository_details ||=
204
- Maven::FileParser::RepositoriesFinder.
205
- new(dependency_files: dependency_files).
212
+ repository_finder.
206
213
  repository_urls(pom: pom).
207
214
  map do |url|
208
215
  { "url" => url, "auth_headers" => {} }
@@ -248,10 +255,10 @@ module Dependabot
248
255
  def dependency_metadata_url(repository_url)
249
256
  group_id, artifact_id, _classifier = dependency.name.split(":")
250
257
 
251
- "#{repository_url}/"\
252
- "#{group_id.tr('.', '/')}/"\
253
- "#{artifact_id}/"\
254
- "maven-metadata.xml"
258
+ "#{repository_url}/" \
259
+ "#{group_id.tr('.', '/')}/" \
260
+ "#{artifact_id}/" \
261
+ "maven-metadata.xml"
255
262
  end
256
263
 
257
264
  def dependency_files_url(repository_url, version)
@@ -260,11 +267,11 @@ module Dependabot
260
267
  dig(:metadata, :packaging_type)
261
268
 
262
269
  actual_classifier = classifier.nil? ? "" : "-#{classifier}"
263
- "#{repository_url}/"\
264
- "#{group_id.tr('.', '/')}/"\
265
- "#{artifact_id}/"\
266
- "#{version}/"\
267
- "#{artifact_id}-#{version}#{actual_classifier}.#{type}"
270
+ "#{repository_url}/" \
271
+ "#{group_id.tr('.', '/')}/" \
272
+ "#{artifact_id}/" \
273
+ "#{version}/" \
274
+ "#{artifact_id}-#{version}#{actual_classifier}.#{type}"
268
275
  end
269
276
 
270
277
  def version_class
@@ -272,9 +279,7 @@ module Dependabot
272
279
  end
273
280
 
274
281
  def central_repo_urls
275
- central_url_without_protocol =
276
- Maven::FileParser::RepositoriesFinder::CENTRAL_REPO_URL.
277
- gsub(%r{^.*://}, "")
282
+ central_url_without_protocol = repository_finder.central_repo_url.gsub(%r{^.*://}, "")
278
283
 
279
284
  %w(http:// https://).map { |p| p + central_url_without_protocol }
280
285
  end
@@ -138,7 +138,7 @@ module Dependabot
138
138
  def property_value_finder
139
139
  @property_value_finder ||=
140
140
  Maven::FileParser::PropertyValueFinder.
141
- new(dependency_files: dependency_files)
141
+ new(dependency_files: dependency_files, credentials: credentials)
142
142
  end
143
143
 
144
144
  def version_comes_from_multi_dependency_property?
@@ -47,7 +47,7 @@ module Dependabot
47
47
  end
48
48
 
49
49
  def gitlab_maven_repo?(maven_repo_path)
50
- gitlab_maven_repo_reg = %r{^/api/v4.*/packages/maven/?$}.freeze
50
+ gitlab_maven_repo_reg = %r{^/api/v4.*/packages/maven/?$}
51
51
  maven_repo_path.match?(gitlab_maven_repo_reg)
52
52
  end
53
53
  end
@@ -27,10 +27,10 @@ module Dependabot
27
27
  "sp" => 7
28
28
  }.freeze
29
29
  VERSION_PATTERN =
30
- "[0-9a-zA-Z]+"\
31
- '(?>\.[0-9a-zA-Z]*)*'\
30
+ "[0-9a-zA-Z]+" \
31
+ '(?>\.[0-9a-zA-Z]*)*' \
32
32
  '([_\-\+][0-9A-Za-z_-]*(\.[0-9A-Za-z_-]*)*)?'
33
- ANCHORED_VERSION_PATTERN = /\A\s*(#{VERSION_PATTERN})?\s*\z/.freeze
33
+ ANCHORED_VERSION_PATTERN = /\A\s*(#{VERSION_PATTERN})?\s*\z/
34
34
 
35
35
  def self.correct?(version)
36
36
  return false if version.nil?
@@ -43,6 +43,10 @@ module Dependabot
43
43
  super(version.to_s.tr("_", "-"))
44
44
  end
45
45
 
46
+ def inspect
47
+ "#<#{self.class} #{@version_string}>"
48
+ end
49
+
46
50
  def to_s
47
51
  @version_string
48
52
  end
@@ -117,11 +121,11 @@ module Dependabot
117
121
  end
118
122
 
119
123
  def trim_version(version)
120
- version.split("-").map do |v|
124
+ version.split("-").filter_map do |v|
121
125
  parts = v.split(".")
122
126
  parts = parts[0..-2] while NULL_VALUES.include?(parts&.last)
123
127
  parts&.join(".")
124
- end.compact.reject(&:empty?).join("-")
128
+ end.reject(&:empty?).join("-")
125
129
  end
126
130
 
127
131
  def convert_dates(version, other_version)
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dependabot-maven
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.211.0
4
+ version: 0.213.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dependabot
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-08-23 00:00:00.000000000 Z
11
+ date: 2022-10-31 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: dependabot-common
@@ -16,42 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - '='
18
18
  - !ruby/object:Gem::Version
19
- version: 0.211.0
19
+ version: 0.213.0
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - '='
25
25
  - !ruby/object:Gem::Version
26
- version: 0.211.0
27
- - !ruby/object:Gem::Dependency
28
- name: debase
29
- requirement: !ruby/object:Gem::Requirement
30
- requirements:
31
- - - '='
32
- - !ruby/object:Gem::Version
33
- version: 0.2.3
34
- type: :development
35
- prerelease: false
36
- version_requirements: !ruby/object:Gem::Requirement
37
- requirements:
38
- - - '='
39
- - !ruby/object:Gem::Version
40
- version: 0.2.3
41
- - !ruby/object:Gem::Dependency
42
- name: debase-ruby_core_source
43
- requirement: !ruby/object:Gem::Requirement
44
- requirements:
45
- - - '='
46
- - !ruby/object:Gem::Version
47
- version: 0.10.16
48
- type: :development
49
- prerelease: false
50
- version_requirements: !ruby/object:Gem::Requirement
51
- requirements:
52
- - - '='
53
- - !ruby/object:Gem::Version
54
- version: 0.10.16
26
+ version: 0.213.0
55
27
  - !ruby/object:Gem::Dependency
56
28
  name: debug
57
29
  requirement: !ruby/object:Gem::Requirement
@@ -86,14 +58,14 @@ dependencies:
86
58
  requirements:
87
59
  - - "~>"
88
60
  - !ruby/object:Gem::Version
89
- version: 3.11.1
61
+ version: 3.13.0
90
62
  type: :development
91
63
  prerelease: false
92
64
  version_requirements: !ruby/object:Gem::Requirement
93
65
  requirements:
94
66
  - - "~>"
95
67
  - !ruby/object:Gem::Version
96
- version: 3.11.1
68
+ version: 3.13.0
97
69
  - !ruby/object:Gem::Dependency
98
70
  name: rake
99
71
  requirement: !ruby/object:Gem::Requirement
@@ -142,28 +114,28 @@ dependencies:
142
114
  requirements:
143
115
  - - "~>"
144
116
  - !ruby/object:Gem::Version
145
- version: 1.35.1
117
+ version: 1.37.1
146
118
  type: :development
147
119
  prerelease: false
148
120
  version_requirements: !ruby/object:Gem::Requirement
149
121
  requirements:
150
122
  - - "~>"
151
123
  - !ruby/object:Gem::Version
152
- version: 1.35.1
124
+ version: 1.37.1
153
125
  - !ruby/object:Gem::Dependency
154
- name: ruby-debug-ide
126
+ name: rubocop-performance
155
127
  requirement: !ruby/object:Gem::Requirement
156
128
  requirements:
157
129
  - - "~>"
158
130
  - !ruby/object:Gem::Version
159
- version: 0.7.3
131
+ version: 1.15.0
160
132
  type: :development
161
133
  prerelease: false
162
134
  version_requirements: !ruby/object:Gem::Requirement
163
135
  requirements:
164
136
  - - "~>"
165
137
  - !ruby/object:Gem::Version
166
- version: 0.7.3
138
+ version: 1.15.0
167
139
  - !ruby/object:Gem::Dependency
168
140
  name: simplecov
169
141
  requirement: !ruby/object:Gem::Requirement
@@ -244,6 +216,7 @@ files:
244
216
  - lib/dependabot/maven.rb
245
217
  - lib/dependabot/maven/file_fetcher.rb
246
218
  - lib/dependabot/maven/file_parser.rb
219
+ - lib/dependabot/maven/file_parser/pom_fetcher.rb
247
220
  - lib/dependabot/maven/file_parser/property_value_finder.rb
248
221
  - lib/dependabot/maven/file_parser/repositories_finder.rb
249
222
  - lib/dependabot/maven/file_updater.rb
@@ -269,14 +242,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
269
242
  requirements:
270
243
  - - ">="
271
244
  - !ruby/object:Gem::Version
272
- version: 2.7.0
245
+ version: 3.1.0
273
246
  required_rubygems_version: !ruby/object:Gem::Requirement
274
247
  requirements:
275
248
  - - ">="
276
249
  - !ruby/object:Gem::Version
277
- version: 2.7.0
250
+ version: 3.1.0
278
251
  requirements: []
279
- rubygems_version: 3.1.6
252
+ rubygems_version: 3.3.7
280
253
  signing_key:
281
254
  specification_version: 4
282
255
  summary: Maven support for dependabot