Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file modified oss-licenses-plugin/gradle/wrapper/gradle-wrapper.jar
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-9.3.1-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-9.4.0-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
Expand Down
7 changes: 2 additions & 5 deletions oss-licenses-plugin/gradlew

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 1 addition & 2 deletions oss-licenses-plugin/gradlew.bat

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ import org.gradle.api.Project
import org.gradle.api.artifacts.Configuration
import org.gradle.api.artifacts.component.ModuleComponentIdentifier
import org.gradle.api.artifacts.result.ResolvedArtifactResult
import org.gradle.api.provider.Provider
import org.gradle.maven.MavenModule
import org.gradle.maven.MavenPomArtifact

Expand All @@ -46,54 +45,52 @@ class DependencyUtil {
*
* @param project The Gradle project used to create the resolution query.
* @param runtimeConfiguration The configuration whose dependencies should be resolved.
* @return A provider for a map of GAV coordinates to their resolved ArtifactFiles.
* @return A map of GAV coordinates to their resolved ArtifactFiles.
*/
static Provider<Map<String, ArtifactFiles>> resolveArtifacts(Project project, Configuration runtimeConfiguration) {
return project.provider {
// We create an ArtifactView to gather the component identifiers and library files.
// We specifically target external Maven dependencies (ModuleComponentIdentifiers).
def runtimeArtifactView = runtimeConfiguration.incoming.artifactView {
it.componentFilter { id -> id instanceof ModuleComponentIdentifier }
}

def artifactsMap = [:]

// 1. Gather library files directly from the view
runtimeArtifactView.artifacts.each { artifact ->
def id = artifact.id.componentIdentifier
if (id instanceof ModuleComponentIdentifier) {
String key = "${id.group}:${id.module}:${id.version}".toString()
artifactsMap[key] = new ArtifactFiles(null, artifact.file)
}
static Map<String, ArtifactFiles> resolveArtifacts(Project project, Configuration runtimeConfiguration) {
// We create an ArtifactView to gather the component identifiers and library files.
// We specifically target external Maven dependencies (ModuleComponentIdentifiers).
def runtimeArtifactView = runtimeConfiguration.incoming.artifactView {
it.componentFilter { id -> id instanceof ModuleComponentIdentifier }
}

def artifactsMap = [:]

// 1. Gather library files directly from the view
runtimeArtifactView.artifacts.each { artifact ->
def id = artifact.id.componentIdentifier
if (id instanceof ModuleComponentIdentifier) {
String key = "${id.group}:${id.module}:${id.version}".toString()
artifactsMap[key] = new ArtifactFiles(null, artifact.file)
}
}

// 2. Fetch corresponding POM files using ArtifactResolutionQuery
def componentIds = runtimeArtifactView.artifacts.collect { it.id.componentIdentifier }
if (!componentIds.isEmpty()) {
def result = project.dependencies.createArtifactResolutionQuery()
.forComponents(componentIds)
.withArtifacts(MavenModule, MavenPomArtifact)
.execute()
// 2. Fetch corresponding POM files using ArtifactResolutionQuery
def componentIds = runtimeArtifactView.artifacts.collect { it.id.componentIdentifier }

if (!componentIds.isEmpty()) {
def result = project.dependencies.createArtifactResolutionQuery()
.forComponents(componentIds)
.withArtifacts(MavenModule, MavenPomArtifact)
.execute()

result.resolvedComponents.each { component ->
component.getArtifacts(MavenPomArtifact).each { artifact ->
if (artifact instanceof ResolvedArtifactResult) {
def id = component.id
String key = "${id.group}:${id.module}:${id.version}".toString()

// Update the existing entry with the POM file
if (artifactsMap.containsKey(key)) {
artifactsMap[key].pomFile = artifact.file
} else {
artifactsMap[key] = new ArtifactFiles(artifact.file, null)
}
result.resolvedComponents.each { component ->
component.getArtifacts(MavenPomArtifact).each { artifact ->
if (artifact instanceof ResolvedArtifactResult) {
def id = component.id
String key = "${id.group}:${id.module}:${id.version}".toString()

// Update the existing entry with the POM file
if (artifactsMap.containsKey(key)) {
artifactsMap[key].pomFile = artifact.file
} else {
artifactsMap[key] = new ArtifactFiles(artifact.file, null)
}
}
}
}

return artifactsMap
}

return artifactsMap
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -58,10 +58,11 @@ class OssLicensesPlugin implements Plugin<Project> {

// Task 1: Dependency Identification
// This task reads the AGP METADATA_LIBRARY_DEPENDENCIES_REPORT protobuf.
def dependenciesJson = baseDir.map { it.file("dependencies.json") }
TaskProvider<DependencyTask> dependencyTask = project.tasks.register(
"${variant.name}OssDependencyTask",
DependencyTask.class) {
it.dependenciesJson.set(baseDir.map { it.file("dependencies.json") })
it.dependenciesJson.set(dependenciesJson)
it.libraryDependenciesReport.set(variant.artifacts.get(SingleArtifact.METADATA_LIBRARY_DEPENDENCIES_REPORT.INSTANCE))
}
project.logger.debug("Registered task ${dependencyTask.name}")
Expand All @@ -72,12 +73,28 @@ class OssLicensesPlugin implements Plugin<Project> {
"${variant.name}OssLicensesTask",
LicensesTask.class) {
it.dependenciesJson.set(dependencyTask.flatMap { it.dependenciesJson })
it.artifactFiles.set(DependencyUtil.resolveArtifacts(project, variant.runtimeConfiguration))

it.artifactFiles.set(project.provider {
DependencyUtil.resolveArtifacts(project, variant.runtimeConfiguration)
})
}
project.logger.debug("Registered task ${licenseTask.name}")

// Register the LicensesTask output as a generated resource folder for AGP.
variant.sources.res.addGeneratedSourceDirectory(licenseTask, LicensesTask::getGeneratedDirectory)

// Task 3: Cleanup
// Ensures generated license files are deleted when running the clean task.
TaskProvider<LicensesCleanUpTask> cleanupTask = project.tasks.register(
"${variant.name}OssLicensesCleanUp",
LicensesCleanUpTask.class) {
it.generatedDirectory.set(baseDir)
}
project.logger.debug("Registered task ${cleanupTask.name}")

project.tasks.named("clean").configure {
it.dependsOn(cleanupTask)
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ public void testComplexDependencyGraphResolution() throws IOException {
runtimeClasspath.resolve();

// Execute resolution logic
Map<String, ArtifactFiles> artifactFiles = DependencyUtil.resolveArtifacts(appProject, runtimeClasspath).get();
Map<String, ArtifactFiles> artifactFiles = DependencyUtil.resolveArtifacts(appProject, runtimeClasspath);

// Assertions
// - Guava resolved to the higher version
Expand Down Expand Up @@ -121,7 +121,7 @@ public void testPomResolution() throws IOException {
Configuration runtimeClasspath = appProject.getConfigurations().getByName("runtimeClasspath");
runtimeClasspath.resolve();

Map<String, ArtifactFiles> artifactFiles = DependencyUtil.resolveArtifacts(appProject, runtimeClasspath).get();
Map<String, ArtifactFiles> artifactFiles = DependencyUtil.resolveArtifacts(appProject, runtimeClasspath);

assertThat(artifactFiles).containsKey("com.google.guava:guava:33.0.0-jre");
assertThat(artifactFiles.get("com.google.guava:guava:33.0.0-jre").getPomFile()).isNotNull();
Expand Down
Loading