@@ -92,7 +92,7 @@ def super_pom
9292 { url : central_repo_url , id : "central" }
9393 end
9494
95- sig { params ( entry : Nokogiri ::XML ::Element ) . returns ( T ::Hash [ Symbol , T . nilable ( String ) ] ) }
95+ sig { params ( entry : Nokogiri ::XML ::Node ) . returns ( T ::Hash [ Symbol , T . nilable ( String ) ] ) }
9696 def serialize_mvn_repo ( entry )
9797 {
9898 url : entry . at_css ( "url" ) . content . strip ,
@@ -130,22 +130,101 @@ def serialize_urls(entry, pom)
130130 . returns ( T ::Array [ T ::Hash [ Symbol , T . untyped ] ] )
131131 end
132132 def gather_repository_urls ( pom :, exclude_inherited : false )
133- repos_in_pom =
134- Nokogiri ::XML ( pom . content )
135- . css ( REPOSITORY_SELECTOR )
136- . map { |node | serialize_mvn_repo ( node ) }
137- . reject { |entry | contains_property? ( entry [ :url ] ) && !evaluate_properties? }
138- . select { |entry | entry [ :url ] . start_with? ( "http" ) }
139- . map { |entry | serialize_urls ( entry , pom ) }
140-
141- return repos_in_pom if exclude_inherited
142-
143- urls_in_pom = repos_in_pom . map { |repo | repo [ :url ] }
144- unless ( parent = parent_pom ( pom , urls_in_pom ) )
145- return repos_in_pom
133+ repos = repositories_from_pom ( pom )
134+ return repos if exclude_inherited
135+
136+ parent = parent_with_repositories ( pom , repos )
137+ return repos unless parent
138+
139+ repos + gather_repository_urls ( pom : parent )
140+ end
141+
142+ sig do
143+ params (
144+ pom : Dependabot ::DependencyFile
145+ ) . returns (
146+ T ::Array [ T ::Hash [ Symbol , T . untyped ] ]
147+ )
148+ end
149+ def repositories_from_pom ( pom )
150+ doc = Nokogiri ::XML ( pom . content )
151+ doc . remove_namespaces!
152+
153+ repository_nodes ( doc )
154+ . filter_map { |node | build_repo_entry ( node , pom ) }
155+ end
156+
157+ sig do
158+ params (
159+ node : Nokogiri ::XML ::Node ,
160+ pom : Dependabot ::DependencyFile
161+ ) . returns ( T . nilable ( T ::Hash [ Symbol , T . untyped ] ) )
162+ end
163+ def build_repo_entry ( node , pom )
164+ url = node . at_css ( "url" ) &.text &.strip . to_s
165+ return if url . empty?
166+
167+ entry = serialize_mvn_repo ( node )
168+
169+ return if property_blocked? ( entry )
170+ return unless http_url? ( entry )
171+
172+ serialize_urls ( entry , pom )
173+ end
174+
175+ sig { params ( entry : T ::Hash [ Symbol , T . nilable ( String ) ] ) . returns ( T ::Boolean ) }
176+ def property_blocked? ( entry )
177+ contains_property? ( T . must ( entry . fetch ( :url ) ) ) && !evaluate_properties?
178+ end
179+
180+ sig { params ( entry : T ::Hash [ Symbol , T . untyped ] ) . returns ( T ::Boolean ) }
181+ def http_url? ( entry )
182+ entry . fetch ( :url ) &.start_with? ( "http" )
183+ end
184+
185+ sig do
186+ params (
187+ pom : Dependabot ::DependencyFile ,
188+ repos : T ::Array [ T ::Hash [ Symbol , T . untyped ] ]
189+ ) . returns ( T . nilable ( Dependabot ::DependencyFile ) )
190+ end
191+ def parent_with_repositories ( pom , repos )
192+ urls = repos . map { |r | r [ :url ] }
193+ parent_pom ( pom , urls )
194+ end
195+
196+ # Returns the repository XML nodes that should be considered when resolving artifacts.
197+ #
198+ # Selection rules:
199+ # - Always includes repositories declared at the project level.
200+ # - Repositories declared inside <profiles> are included only when the enclosing
201+ # <profile> has <activation><activeByDefault>true</activeByDefault></activation>.
202+ #
203+ # @example With active profile
204+ # <profile>
205+ # <activation><activeByDefault>true</activeByDefault></activation>
206+ # <repositories>...</repositories>
207+ # </profile>
208+ #
209+ sig { params ( doc : Nokogiri ::XML ::Document ) . returns ( T ::Array [ Nokogiri ::XML ::Node ] ) }
210+ def repository_nodes ( doc )
211+ doc . css ( REPOSITORY_SELECTOR ) . select do |repo_node |
212+ profile = repo_node . ancestors ( "profile" ) . first
213+
214+ # Not in a profile => always include
215+ next true unless profile
216+
217+ # In a profile => only include when activeByDefault=true
218+ active_by_default_profile? ( profile )
146219 end
220+ end
221+
222+ sig { params ( profile : Nokogiri ::XML ::Element ) . returns ( T ::Boolean ) }
223+ def active_by_default_profile? ( profile )
224+ node = profile . at_xpath ( "./activation/activeByDefault" )
225+ return false unless node
147226
148- repos_in_pom + gather_repository_urls ( pom : parent )
227+ node . text . strip . casecmp? ( "true" )
149228 end
150229
151230 sig { returns ( T ::Boolean ) }
0 commit comments