Skip to content
Merged
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
4 changes: 2 additions & 2 deletions oss-licenses-plugin/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,8 @@ gradlePlugin {
dependencies {
implementation(gradleApi())
implementation(localGroovy())
implementation("com.android.tools.build:gradle:7.1.0")
implementation("com.android.tools.build:gradle-api:7.1.0")
implementation("com.android.tools.build:gradle:8.2.0")
implementation("com.android.tools.build:gradle-api:8.2.0")
implementation("com.google.protobuf:protobuf-java:3.19.1")
testImplementation("junit:junit:4.13.2")
testImplementation("org.mockito:mockito-core:4.1.0")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,44 +17,26 @@
package com.google.android.gms.oss.licenses.plugin

import org.gradle.api.DefaultTask
import org.gradle.api.file.DirectoryProperty
import org.gradle.api.tasks.InputDirectory
import org.gradle.api.tasks.Optional
import org.gradle.api.tasks.TaskAction
import org.gradle.work.DisableCachingByDefault

/**
* Task to clean up the generated dependency.json, third_party_licenses and
* third_party_license_metadata files.
* Task to clean up the generated files.
*/
class LicensesCleanUpTask extends DefaultTask {

protected File dependenciesJson

protected File dependencyDir

protected File licensesFile

protected File metadataFile

protected File licensesDir
@DisableCachingByDefault(because = "Local deletion operation")
abstract class LicensesCleanUpTask extends DefaultTask {
@Optional
@InputDirectory
abstract DirectoryProperty getGeneratedDirectory()

@TaskAction
void action() {
if (dependenciesJson.exists()) {
dependenciesJson.delete()
}

if (dependencyDir.isDirectory() && dependencyDir.list().length == 0) {
dependencyDir.delete()
}

if (licensesFile.exists()) {
licensesFile.delete()
}

if (metadataFile.exists()) {
metadataFile.delete()
}

if (licensesDir.isDirectory() && licensesDir.list().length == 0) {
licensesDir.delete()
File directoryToDelete = getGeneratedDirectory().get().asFile
if (directoryToDelete.exists()) {
directoryToDelete.deleteDir()
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,10 @@ package com.google.android.gms.oss.licenses.plugin
import groovy.json.JsonSlurper
import groovy.xml.XmlSlurper
import org.gradle.api.DefaultTask
import org.gradle.api.file.DirectoryProperty
import org.gradle.api.file.RegularFileProperty
import org.gradle.api.tasks.InputFile
import org.gradle.api.tasks.Internal
import org.gradle.api.tasks.OutputDirectory
import org.gradle.api.tasks.OutputFile
import org.gradle.api.tasks.TaskAction
Expand Down Expand Up @@ -62,19 +64,17 @@ abstract class LicensesTask extends DefaultTask {
abstract RegularFileProperty getDependenciesJson()

@OutputDirectory
File rawResourceDir
abstract DirectoryProperty getGeneratedDirectory()

@OutputFile
@Internal // represented by getGeneratedDirectory()
File licenses

@OutputFile
@Internal // represented by getGeneratedDirectory()
File licensesMetadata

@TaskAction
void action() {
initOutputDir()
initLicenseFile()
initLicensesMetadata()

File dependenciesJsonFile = dependenciesJson.asFile.get()
def artifactInfoSet = loadDependenciesJson(dependenciesJsonFile)
Expand Down Expand Up @@ -126,21 +126,15 @@ abstract class LicensesTask extends DefaultTask {
}

protected void initOutputDir() {
File rawResourceDir = new File(getGeneratedDirectory().get().asFile, "raw")
if (!rawResourceDir.exists()) {
rawResourceDir.mkdirs()
}
}

protected void initLicenseFile() {
if (licenses == null) {
logger.error("License file is undefined")
}
licenses = new File(rawResourceDir, "third_party_licenses")
licenses.newWriter().withWriter { w ->
w << ''
}
}

protected void initLicensesMetadata() {
licensesMetadata = new File(rawResourceDir, "third_party_license_metadata")
licensesMetadata.newWriter().withWriter { w ->
w << ''
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,80 +17,57 @@
package com.google.android.gms.oss.licenses.plugin

import com.android.build.api.artifact.SingleArtifact
import com.android.build.gradle.api.BaseVariant
import com.android.build.api.variant.ApplicationAndroidComponentsExtension
import com.android.build.api.variant.ApplicationVariant
import com.android.build.gradle.AppPlugin
import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.api.Task
import org.gradle.api.file.Directory
import org.gradle.api.provider.Provider
import org.gradle.api.tasks.TaskProvider
import org.slf4j.LoggerFactory

class OssLicensesPlugin implements Plugin<Project> {

private static final logger = LoggerFactory.getLogger(DependencyTask.class)

void apply(Project project) {
def variantTolicenseTaskMap = new HashMap<String, LicensesTask>()
project.androidComponents {
onVariants(selector().all(), { variant ->
def baseDir = new File(project.buildDir,
"generated/third_party_licenses/${variant.name}")
def dependenciesJson = new File(baseDir, "dependencies.json")

String dependencyTaskName = "${variant.name}OssDependencyTask"
TaskProvider<DependencyTask> dependencyTask = project.tasks.register(
dependencyTaskName,
DependencyTask.class) {
it.dependenciesJson.set(dependenciesJson)
it.libraryDependenciesReport.set(variant.artifacts.get(SingleArtifact.METADATA_LIBRARY_DEPENDENCIES_REPORT.INSTANCE))
project.plugins.configureEach { plugin ->
if (plugin instanceof AppPlugin) {
def androidComponents = project.extensions.getByType(ApplicationAndroidComponentsExtension)
androidComponents.onVariants(androidComponents.selector().all()) { variant ->
configureLicenceTasks(project, variant)
}
logger.debug("Registered task $dependencyTaskName")

def resourceBaseDir = new File(baseDir, "/res")
def rawResourceDir = new File(resourceBaseDir, "/raw")
def licensesFile = new File(rawResourceDir, "third_party_licenses")
def licensesMetadataFile = new File(rawResourceDir,
"third_party_license_metadata")

def licenseTask = project.tasks.register(
"${variant.name}OssLicensesTask",
LicensesTask.class) {
markNotCompatibleWithConfigurationCache(it)
it.dependenciesJson.set(dependencyTask.flatMap { it.dependenciesJson })
it.rawResourceDir = rawResourceDir
it.licenses = licensesFile
it.licensesMetadata = licensesMetadataFile
}.get()
logger.debug("Created task ${licenseTask.name}")
}
}
}

variantTolicenseTaskMap[variant.name] = licenseTask
private static void configureLicenceTasks(Project project, ApplicationVariant variant) {
Provider<Directory> baseDir = project.layout.buildDirectory.dir("generated/third_party_licenses/${variant.name}")
def dependenciesJson = baseDir.map { it.file("dependencies.json") }
TaskProvider<DependencyTask> dependencyTask = project.tasks.register(
"${variant.name}OssDependencyTask",
DependencyTask.class) {
it.dependenciesJson.set(dependenciesJson)
it.libraryDependenciesReport.set(variant.artifacts.get(SingleArtifact.METADATA_LIBRARY_DEPENDENCIES_REPORT.INSTANCE))
}
project.logger.debug("Registered task ${dependencyTask.name}")

String cleanupTaskName = "${variant.name}OssLicensesCleanUp"
TaskProvider<LicensesCleanUpTask> cleanupTask = project.tasks.register(
cleanupTaskName,
LicensesCleanUpTask.class) {
it.dependenciesJson = dependenciesJson
it.dependencyDir = baseDir
it.licensesFile = licensesFile
it.metadataFile = licensesMetadataFile
it.licensesDir = rawResourceDir
}
logger.debug("Registered task $cleanupTaskName")
TaskProvider<LicensesTask> licenseTask = project.tasks.register(
"${variant.name}OssLicensesTask",
LicensesTask.class) {
markNotCompatibleWithConfigurationCache(it)
it.dependenciesJson.set(dependencyTask.flatMap { it.dependenciesJson })
}
project.logger.debug("Registered task ${licenseTask.name}")
variant.sources.resources.addGeneratedSourceDirectory(licenseTask, LicensesTask::getGeneratedDirectory)

project.tasks.named("clean").configure {
it.dependsOn(cleanupTask)
}
})
TaskProvider<LicensesCleanUpTask> cleanupTask = project.tasks.register(
"${variant.name}OssLicensesCleanUp",
LicensesCleanUpTask.class) {
it.generatedDirectory.set(baseDir)
}
project.logger.debug("Registered task ${cleanupTask.name}")

// TODO: Switch to new Variant API when API is ready and before
// BaseVariant is removed in 8.0
project.android.applicationVariants.all { BaseVariant variant ->
def licenseTask = variantTolicenseTaskMap[variant.name]
if (licenseTask == null) {
return
}
def generatedResFolder = project.files(licenseTask.rawResourceDir.parentFile).builtBy(licenseTask)
variant.registerGeneratedResFolders(generatedResFolder)
project.tasks.named("clean").configure {
it.dependsOn(cleanupTask)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ class EndToEndTest {
}
android {
compileSdkVersion = "android-31"
namespace = "com.example.app"
}
dependencies {
implementation("com.google.android.gms:play-services-oss-licenses:17.0.0")
Expand All @@ -40,14 +41,14 @@ class EndToEndTest {
)
val result = GradleRunner.create()
.withProjectDir(projectDir)
.withGradleVersion("7.6")
.withGradleVersion("8.2")
.withArguments("releaseOssLicensesTask", "-s")
.withPluginClasspath().build()
Assert.assertEquals(result.task(":collectReleaseDependencies")!!.outcome, TaskOutcome.SUCCESS)
Assert.assertEquals(result.task(":releaseOssDependencyTask")!!.outcome, TaskOutcome.SUCCESS)
Assert.assertEquals(result.task(":releaseOssLicensesTask")!!.outcome, TaskOutcome.SUCCESS)
val metadata =
File(projectDir, "build/generated/third_party_licenses/release/res/raw/third_party_license_metadata")
File(projectDir, "build/generated/resources/releaseOssLicensesTask/raw/third_party_license_metadata")
Assert.assertTrue(metadata.readText().contains("play-services-oss-licenses"))
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
package com.google.android.gms.oss.licenses.plugin;

import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;

import java.io.File;
import java.io.IOException;
Expand All @@ -37,31 +38,28 @@ public class LicensesCleanUpTaskTest {
public void testAction() throws IOException {
File testDir = temporaryFolder.newFolder();

File dependencyDir = new File(testDir, "dependency");
dependencyDir.mkdir();

// Set up a generated directory with normal expected contents
File generatedDir = new File(testDir, "generated");
File dependencyDir = new File(generatedDir, "dependency");
assertTrue(dependencyDir.mkdirs());
File dependencyFile = new File(dependencyDir, "dependency.json");
assertTrue(dependencyFile.createNewFile());

File licensesDir = new File(testDir, "raw");
licensesDir.mkdir();

File licensesFile = new File(licensesDir, "third_party_licenses");
File metadataFile = new File(licensesDir, "third_party_license_metadata");
File licensesDir = new File(generatedDir, "res/raw");
assertTrue(licensesDir.mkdirs());
assertTrue(new File(licensesDir, "third_party_licenses").createNewFile());
assertTrue(new File(licensesDir, "third_party_license_metadata").createNewFile());

// Create a licenses clean up task
Project project = ProjectBuilder.builder().withProjectDir(testDir).build();
LicensesCleanUpTask task =
project.getTasks().create("licensesCleanUp", LicensesCleanUpTask.class);
task.dependencyDir = dependencyDir;
task.dependenciesJson = dependencyFile;
task.licensesDir = licensesDir;
task.licensesFile = licensesFile;
task.metadataFile = metadataFile;
task.getGeneratedDirectory().set(generatedDir);

// Run the task action
task.action();
assertFalse(task.dependenciesJson.exists());
assertFalse(task.dependencyDir.exists());
assertFalse(task.licensesFile.exists());
assertFalse(task.metadataFile.exists());
assertFalse(task.licensesDir.exists());

// Ensure the directory is deleted
assertFalse(generatedDir.exists());
}
}
Loading