@@ -474,66 +474,80 @@ configure(allprojects - project(':platform')) {
474474 }
475475}
476476
477- task resolveSourceArtifacts {
478- group = ' verification'
479- description = ' Resolves source artifacts for all configurations so they can be included in dependency verification metadata'
480- doLast {
481- def componentIds = new HashSet ()
482- def unresolvedConfigs = 0
483-
484- def collectComponentIds = { configs , String label ->
485- configs. matching { it. canBeResolved }. each { config ->
486- try {
487- config. incoming. resolutionResult. allComponents. each { component ->
488- componentIds. add(component. id)
489- }
490- } catch (Exception e) {
491- unresolvedConfigs++
492- logger. info(" Could not resolve ${ label} '${ config.name} ': ${ e.message} " )
477+ ext. collectExternalComponentIds = {
478+ ->
479+ def componentIds = new HashSet ()
480+ def unresolvedConfigs = 0
481+
482+ def collectComponentIds = { configs , String label ->
483+ configs. matching { it. canBeResolved }. each { config ->
484+ try {
485+ config. incoming. resolutionResult. allComponents. each { component ->
486+ componentIds. add(component. id)
493487 }
488+ } catch (Exception e) {
489+ unresolvedConfigs++
490+ logger. info(" Could not resolve ${ label} '${ config.name} ': ${ e.message} " )
494491 }
495492 }
493+ }
496494
497- allprojects. each { proj ->
498- collectComponentIds(proj. configurations, " ${ proj.path} config" )
499- collectComponentIds(proj. buildscript. configurations, " ${ proj.path} buildscript config" )
500- }
495+ allprojects. each { proj ->
496+ collectComponentIds(proj. configurations, " ${ proj.path} config" )
497+ collectComponentIds(proj. buildscript. configurations, " ${ proj.path} buildscript config" )
498+ }
501499
502- if (unresolvedConfigs > 0 ) {
503- logger. warn(" ${ unresolvedConfigs} configurations could not be resolved (run with --info for details)" )
504- }
500+ if (unresolvedConfigs > 0 ) {
501+ logger. warn(" ${ unresolvedConfigs} configurations could not be resolved (run with --info for details)" )
502+ }
505503
506- def externalIds = componentIds. findAll { it instanceof org.gradle.api.artifacts.component.ModuleComponentIdentifier }
507- logger . lifecycle( " Resolving sources for ${ externalIds.size() } external dependencies... " )
504+ return componentIds. findAll { it instanceof org.gradle.api.artifacts.component.ModuleComponentIdentifier }
505+ }
508506
509- // Populated by resolveSources across both project and buildscript repository calls
510- def resolvedComponentIds = new HashSet ()
511- def resolveSources = { depHandler , componentIdsToResolve , String label ->
512- def sizeBefore = resolvedComponentIds. size()
513- def result = depHandler. createArtifactResolutionQuery()
514- .forComponents(componentIdsToResolve)
515- .withArtifacts(JvmLibrary , SourcesArtifact )
516- .execute()
517- result. resolvedComponents. each { component ->
518- component. getArtifacts(SourcesArtifact ). each { source ->
519- if (source instanceof ResolvedArtifactResult ) {
520- source. file // access .file to trigger download and register with verification metadata
521- resolvedComponentIds. add(component. id)
522- } else {
523- logger. warn(" Could not download sources for ${ component.id} : ${ source} " )
524- }
507+ // Retries buildscript repositories (which include the Gradle Plugin Portal) for any
508+ // components whose sources did not resolve against the project repositories.
509+ ext. forEachResolvedSourceArtifact = { Collection externalIds , Closure action ->
510+ def resolvedComponentIds = new HashSet ()
511+
512+ def resolveSources = { depHandler , componentIdsToResolve , String label ->
513+ def sizeBefore = resolvedComponentIds. size()
514+ def result = depHandler. createArtifactResolutionQuery()
515+ .forComponents(componentIdsToResolve)
516+ .withArtifacts(JvmLibrary , SourcesArtifact )
517+ .execute()
518+ result. resolvedComponents. each { component ->
519+ component. getArtifacts(SourcesArtifact ). each { source ->
520+ if (source instanceof ResolvedArtifactResult ) {
521+ action(component. id, source)
522+ resolvedComponentIds. add(component. id)
523+ } else {
524+ logger. info(" Could not resolve sources for ${ component.id} : ${ source} " )
525525 }
526526 }
527- def count = resolvedComponentIds. size() - sizeBefore
528- logger. lifecycle(" Resolved sources for ${ count} components from ${ label} " )
529527 }
528+ def count = resolvedComponentIds. size() - sizeBefore
529+ logger. lifecycle(" Resolved sources for ${ count} components from ${ label} " )
530+ }
530531
531- resolveSources(dependencies, externalIds, " project repositories" )
532+ resolveSources(dependencies, externalIds, " project repositories" )
532533
533- // Retry unresolved sources using buildscript repositories (includes Gradle Plugin Portal)
534- def unresolvedIds = externalIds. findAll { ! resolvedComponentIds. contains(it) }
535- if (! unresolvedIds. isEmpty()) {
536- resolveSources(buildscript. dependencies, unresolvedIds, " buildscript repositories" )
534+ def unresolvedIds = externalIds. findAll { ! resolvedComponentIds. contains(it) }
535+ if (! unresolvedIds. isEmpty()) {
536+ resolveSources(buildscript. dependencies, unresolvedIds, " buildscript repositories" )
537+ }
538+
539+ return resolvedComponentIds
540+ }
541+
542+ task resolveSourceArtifacts {
543+ group = ' verification'
544+ description = ' Resolves source artifacts for all configurations so they can be included in dependency verification metadata'
545+ doLast {
546+ def externalIds = collectExternalComponentIds()
547+ logger. lifecycle(" Resolving sources for ${ externalIds.size()} external dependencies..." )
548+
549+ def resolvedComponentIds = forEachResolvedSourceArtifact(externalIds) { id , source ->
550+ source. file // access .file to trigger download and register with verification metadata
537551 }
538552
539553 def finalUnresolved = externalIds. size() - resolvedComponentIds. size()
@@ -544,6 +558,50 @@ task resolveSourceArtifacts {
544558 }
545559}
546560
561+ task verifySourceArtifacts {
562+ group = ' verification'
563+ description = ' Fails the build if gradle/verification-metadata.xml is missing source artifact entries for any resolvable dependency'
564+ doLast {
565+ def metadataFile = rootProject. file(' gradle/verification-metadata.xml' )
566+ def slurper = new groovy.xml.XmlSlurper ()
567+ slurper. setFeature(' http://xml.org/sax/features/namespaces' , false )
568+ def metadata = slurper. parse(metadataFile)
569+
570+ def componentsWithRecordedSources = new HashSet ()
571+ metadata. components. component. each { comp ->
572+ def group = comp. @group. text()
573+ def name = comp. @name. text()
574+ def version = comp. @version. text()
575+ def expected = " ${ name} -${ version} -sources.jar" . toString()
576+ if (comp. artifact. any { it. @name. text() == expected }) {
577+ componentsWithRecordedSources. add(" ${ group} :${ name} :${ version} " . toString())
578+ }
579+ }
580+
581+ def externalIds = collectExternalComponentIds()
582+ def missing = new TreeSet ()
583+ forEachResolvedSourceArtifact(externalIds) { id , source ->
584+ def key = " ${ id.group} :${ id.module} :${ id.version} " . toString()
585+ if (! componentsWithRecordedSources. contains(key)) {
586+ missing. add(key)
587+ }
588+ }
589+
590+ if (! missing. isEmpty()) {
591+ def list = missing. collect { " - ${ it} " }. join(' \n ' )
592+ throw new GradleException (
593+ " gradle/verification-metadata.xml is missing source artifact entries for ${ missing.size()} " +
594+ " ${ missing.size() == 1 ? 'dependency' : 'dependencies'} :\n " +
595+ " ${ list} \n\n " +
596+ " Regenerate the metadata by running:\n " +
597+ " ./gradlew --write-verification-metadata sha256 resolveSourceArtifacts\n " +
598+ " and commit the updated gradle/verification-metadata.xml." )
599+ }
600+
601+ logger. lifecycle(" verification-metadata.xml contains source entries for all resolvable external components." )
602+ }
603+ }
604+
547605task deploy () {}
548606
549607task checkMavenCoordinateCollisions {
0 commit comments