11# typed: strict
22# frozen_string_literal: true
33
4- require "nokogiri"
54require "sorbet-runtime"
65
7- require "dependabot/file_fetchers/base"
86require "dependabot/gradle/distributions"
97require "dependabot/gradle/file_fetcher"
108require "dependabot/gradle/file_parser/repositories_finder"
11- require "dependabot/maven/utils/auth_headers_finder "
9+ require "dependabot/maven/shared/shared_metadata_finder "
1210require "dependabot/metadata_finders"
13- require "dependabot/metadata_finders/base"
14- require "dependabot/registry_client"
1511
1612module Dependabot
1713 module Gradle
18- class MetadataFinder < Dependabot ::MetadataFinders :: Base
14+ class MetadataFinder < Dependabot ::Maven :: Shared :: SharedMetadataFinder
1915 extend T ::Sig
2016
21- DOT_SEPARATOR_REGEX = %r{\. (?!\d +([.\/ _\- ]|$)+)}
22- PROPERTY_REGEX = /\$ \{ (?<property>.*?)\} /
2317 KOTLIN_PLUGIN_REPO_PREFIX = "org.jetbrains.kotlin"
2418
2519 private
@@ -28,18 +22,7 @@ class MetadataFinder < Dependabot::MetadataFinders::Base
2822 def look_up_source
2923 return distributions_source if Distributions . distribution_requirements? ( dependency . requirements )
3024
31- tmp_source = look_up_source_in_pom ( dependency_pom_file )
32- return tmp_source if tmp_source
33-
34- return unless ( parent = parent_pom_file ( dependency_pom_file ) )
35-
36- tmp_source = look_up_source_in_pom ( parent )
37- return unless tmp_source
38-
39- artifact = dependency . name . split ( ":" ) . last
40- return tmp_source if tmp_source . repo . end_with? ( T . must ( artifact ) )
41-
42- tmp_source if repo_has_subdir_for_dep? ( tmp_source )
25+ super
4326 end
4427
4528 # The Gradle Wrapper does not have its own release notes.
@@ -53,120 +36,35 @@ def distributions_source
5336 )
5437 end
5538
56- sig { params ( tmp_source : Dependabot ::Source ) . returns ( T ::Boolean ) }
57- def repo_has_subdir_for_dep? ( tmp_source )
58- @repo_has_subdir_for_dep ||= T . let ( { } , T . nilable ( T ::Hash [ Dependabot ::Source , T ::Boolean ] ) )
59- return T . must ( @repo_has_subdir_for_dep [ tmp_source ] ) if @repo_has_subdir_for_dep . key? ( tmp_source )
60-
61- artifact = dependency . name . split ( ":" ) . last
62- fetcher =
63- Dependabot ::Gradle ::FileFetcher . new ( source : tmp_source , credentials : credentials )
64-
65- @repo_has_subdir_for_dep [ tmp_source ] =
66- fetcher . send ( :repo_contents , raise_errors : false )
67- . select { |f | f . type == "dir" }
68- . any? { |f | artifact &.end_with? ( f . name ) }
69- rescue Dependabot ::BranchNotFound
70- tmp_source . branch = nil
71- retry
72- rescue Dependabot ::RepoNotFound
73- T . must ( @repo_has_subdir_for_dep ) [ tmp_source ] = false
74- end
75-
76- sig { params ( pom : Nokogiri ::XML ::Document ) . returns ( T . nilable ( Dependabot ::Source ) ) }
77- def look_up_source_in_pom ( pom )
78- potential_source_urls = [
79- pom . at_css ( "project > url" ) &.content ,
80- pom . at_css ( "project > scm > url" ) &.content ,
81- pom . at_css ( "project > issueManagement > url" ) &.content
82- ] . compact
83-
84- source_url = potential_source_urls . find { |url | Source . from_url ( url ) }
85- source_url ||= source_from_anywhere_in_pom ( pom )
86- source_url = substitute_property_in_source_url ( source_url , pom )
87-
88- Source . from_url ( source_url )
89- end
90-
91- sig { params ( source_url : T . nilable ( String ) , pom : Nokogiri ::XML ::Document ) . returns ( T . nilable ( String ) ) }
92- def substitute_property_in_source_url ( source_url , pom )
93- return unless source_url
94- return source_url unless source_url . include? ( "${" )
95-
96- regex = PROPERTY_REGEX
97- property_name = T . must ( source_url . match ( regex ) ) . named_captures [ "property" ]
98- doc = pom . dup
99- doc . remove_namespaces!
100- nm = T . must ( property_name ) . sub ( /^pom\. / , "" ) . sub ( /^project\. / , "" )
101- property_value =
102- loop do
103- candidate_node =
104- doc . at_xpath ( "/project/#{ nm } " ) ||
105- doc . at_xpath ( "/project/properties/#{ nm } " ) ||
106- doc . at_xpath ( "/project/profiles/profile/properties/#{ nm } " )
107- break ( candidate_node . content ) if candidate_node
108- break unless nm . match? ( DOT_SEPARATOR_REGEX )
109-
110- nm = nm . sub ( DOT_SEPARATOR_REGEX , "/" )
111- end
112-
113- source_url . gsub ( "${#{ property_name } }" , property_value )
39+ sig { override . returns ( T . class_of ( Dependabot ::FileFetchers ::Base ) ) }
40+ def file_fetcher_class
41+ Dependabot ::Gradle ::FileFetcher
11442 end
11543
116- sig { params ( pom : T . any ( String , Nokogiri ::XML ::Document ) ) . returns ( T . nilable ( String ) ) }
117- def source_from_anywhere_in_pom ( pom )
118- github_urls = [ ]
119- pom . to_s . scan ( Source ::SOURCE_REGEX ) do
120- github_urls << Regexp . last_match . to_s
121- end
122-
123- github_urls . find do |url |
124- repo = T . must ( Source . from_url ( url ) ) . repo
125- repo . end_with? ( T . must ( dependency . name . split ( ":" ) . last ) )
44+ sig { override . returns ( T . nilable ( String ) ) }
45+ def dependency_artifact_id
46+ if kotlin_plugin? then "#{ KOTLIN_PLUGIN_REPO_PREFIX } .#{ dependency . name } .gradle.plugin"
47+ elsif plugin? then "#{ dependency . name } .gradle.plugin"
48+ else
49+ dependency . name . split ( ":" ) . last
12650 end
12751 end
12852
129- sig { returns ( Nokogiri :: XML :: Document ) }
130- def dependency_pom_file
131- return @dependency_pom_file unless @dependency_pom_file . nil?
132-
133- artifact_id =
134- if kotlin_plugin? then "#{ KOTLIN_PLUGIN_REPO_PREFIX } .#{ dependency . name } .gradle.plugin"
135- elsif plugin? then "#{ dependency . name } .gradle.plugin"
53+ sig { override . returns ( String ) }
54+ def maven_repo_dependency_url
55+ group_id , artifact_id =
56+ if kotlin_plugin?
57+ [ " #{ KOTLIN_PLUGIN_REPO_PREFIX } . #{ dependency . name } " ,
58+ "#{ KOTLIN_PLUGIN_REPO_PREFIX } .#{ dependency . name } .gradle.plugin" ]
59+ elsif plugin? then [ dependency . name , "#{ dependency . name } .gradle.plugin" ]
13660 else
137- dependency . name . split ( ":" ) . last
61+ dependency . name . split ( ":" )
13862 end
13963
140- response = Dependabot ::RegistryClient . get (
141- url : "#{ maven_repo_dependency_url } /#{ dependency . version } /#{ artifact_id } -#{ dependency . version } .pom" ,
142- headers : auth_headers
143- )
144-
145- @dependency_pom_file = T . let ( Nokogiri ::XML ( response . body ) , T . nilable ( Nokogiri ::XML ::Document ) )
146- rescue Excon ::Error ::Timeout
147- @dependency_pom_file ||= T . let ( Nokogiri ::XML ( "" ) , T . nilable ( Nokogiri ::XML ::Document ) )
148- end
149-
150- sig { params ( pom : Nokogiri ::XML ::Document ) . returns ( T . nilable ( Nokogiri ::XML ::Document ) ) }
151- def parent_pom_file ( pom )
152- doc = pom . dup
153- doc . remove_namespaces!
154- group_id = doc . at_xpath ( "/project/parent/groupId" ) &.content &.strip
155- artifact_id =
156- doc . at_xpath ( "/project/parent/artifactId" ) &.content &.strip
157- version = doc . at_xpath ( "/project/parent/version" ) &.content &.strip
158-
159- return unless artifact_id && group_id && version
160-
161- response = Dependabot ::RegistryClient . get (
162- url : "#{ maven_repo_url } /#{ group_id . tr ( '.' , '/' ) } /#{ artifact_id } /#{ version } /#{ artifact_id } -#{ version } .pom" ,
163- headers : auth_headers
164- )
165-
166- Nokogiri ::XML ( response . body )
64+ "#{ maven_repo_url } /#{ group_id &.tr ( '.' , '/' ) } /#{ artifact_id } "
16765 end
16866
169- sig { returns ( String ) }
67+ sig { override . returns ( String ) }
17068 def maven_repo_url
17169 source = dependency . requirements
17270 . find { |r | r . fetch ( :source ) } &.fetch ( :source )
@@ -176,18 +74,9 @@ def maven_repo_url
17674 Gradle ::FileParser ::RepositoriesFinder ::CENTRAL_REPO_URL
17775 end
17876
179- sig { returns ( String ) }
180- def maven_repo_dependency_url
181- group_id , artifact_id =
182- if kotlin_plugin?
183- [ "#{ KOTLIN_PLUGIN_REPO_PREFIX } .#{ dependency . name } " ,
184- "#{ KOTLIN_PLUGIN_REPO_PREFIX } .#{ dependency . name } .gradle.plugin" ]
185- elsif plugin? then [ dependency . name , "#{ dependency . name } .gradle.plugin" ]
186- else
187- dependency . name . split ( ":" )
188- end
189-
190- "#{ maven_repo_url } /#{ group_id &.tr ( '.' , '/' ) } /#{ artifact_id } "
77+ sig { override . returns ( String ) }
78+ def central_repo_url
79+ Gradle ::FileParser ::RepositoriesFinder ::CENTRAL_REPO_URL
19180 end
19281
19382 sig { returns ( T ::Boolean ) }
@@ -199,14 +88,6 @@ def plugin?
19988 def kotlin_plugin?
20089 plugin? && dependency . requirements . any? { |r | r . fetch ( :groups ) . include? "kotlin" }
20190 end
202-
203- sig { returns ( T ::Hash [ String , String ] ) }
204- def auth_headers
205- @auth_headers ||= T . let (
206- Dependabot ::Maven ::Utils ::AuthHeadersFinder . new ( credentials ) . auth_headers ( maven_repo_url ) ,
207- T . nilable ( T ::Hash [ String , String ] )
208- )
209- end
21091 end
21192 end
21293end
0 commit comments