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
1 change: 1 addition & 0 deletions oss-licenses-plugin/gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,4 @@ systemProp.com.google.protobuf.use_unsafe_pre22_gencode=true

org.gradle.configuration-cache=true
org.gradle.caching=true
org.gradle.jvmargs=-Xmx2048m -XX:MaxMetaspaceSize=1024m
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 @@ -16,13 +16,24 @@

package com.google.android.gms.oss.licenses.plugin

import org.gradle.api.tasks.InputFile
import org.gradle.api.tasks.Optional
import org.gradle.api.tasks.PathSensitive
import org.gradle.api.tasks.PathSensitivity
import java.io.Serializable

/**
* Data class to hold the resolved physical files for a single dependency.
*/
class ArtifactFiles implements Serializable {
@InputFile
@PathSensitive(PathSensitivity.NONE)
@Optional
File pomFile

@InputFile
@PathSensitive(PathSensitivity.NONE)
@Optional
File libraryFile

ArtifactFiles(File pomFile, File libraryFile) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,12 @@ import groovy.json.JsonBuilder
import groovy.json.JsonGenerator
import org.gradle.api.DefaultTask
import org.gradle.api.file.RegularFileProperty
import org.gradle.api.tasks.CacheableTask
import org.gradle.api.tasks.InputFile
import org.gradle.api.tasks.Optional
import org.gradle.api.tasks.OutputFile
import org.gradle.api.tasks.PathSensitive
import org.gradle.api.tasks.PathSensitivity
import org.gradle.api.tasks.TaskAction
import org.slf4j.LoggerFactory

Expand All @@ -37,14 +41,16 @@ import static com.android.tools.build.libraries.metadata.Library.LibraryOneofCas
* If the protobuf is not present (e.g. debug variants) it writes a single
* dependency on the {@link DependencyUtil#ABSENT_ARTIFACT}.
*/
@CacheableTask
abstract class DependencyTask extends DefaultTask {
private static final logger = LoggerFactory.getLogger(DependencyTask.class)

@OutputFile
abstract RegularFileProperty getDependenciesJson()

@InputFile
@org.gradle.api.tasks.Optional
@PathSensitive(PathSensitivity.NONE)
@Optional
abstract RegularFileProperty getLibraryDependenciesReport()

@TaskAction
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,14 @@ 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.CacheableTask
import org.gradle.api.tasks.InputFile
import org.gradle.api.tasks.Internal
import org.gradle.api.tasks.Nested
import org.gradle.api.tasks.OutputDirectory
import org.gradle.api.tasks.OutputFile
import org.gradle.api.tasks.PathSensitive
import org.gradle.api.tasks.PathSensitivity
import org.gradle.api.tasks.TaskAction
import org.slf4j.LoggerFactory

Expand All @@ -38,6 +42,7 @@ import java.util.zip.ZipFile
* mappings (POMs and Library artifacts) are provided as lazy input properties,
* making the task a pure function of its inputs.
*/
@CacheableTask
abstract class LicensesTask extends DefaultTask {
private static final String UTF_8 = "UTF-8"
private static final byte[] LINE_SEPARATOR = System
Expand Down Expand Up @@ -66,10 +71,11 @@ abstract class LicensesTask extends DefaultTask {
* A map of GAV coordinates (group:name:version) to their resolved POM and Library files.
* Populated by OssLicensesPlugin during configuration.
*/
@org.gradle.api.tasks.Input
@Nested
abstract org.gradle.api.provider.MapProperty<String, ArtifactFiles> getArtifactFiles()

@InputFile
@PathSensitive(PathSensitivity.NONE)
abstract RegularFileProperty getDependenciesJson()

@OutputDirectory
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,12 @@ abstract class EndToEndTest(private val agpVersion: String, private val gradleVe
private lateinit var projectDir: File

private fun createRunner(vararg arguments: String): GradleRunner {
return createRunnerWithDir(projectDir, *arguments)
}

private fun createRunnerWithDir(dir: File, vararg arguments: String): GradleRunner {
return GradleRunner.create()
.withProjectDir(projectDir)
.withProjectDir(dir)
.withGradleVersion(gradleVersion)
.forwardOutput()
// Isolate TestKit per AGP version subclass to allow parallel execution
Expand All @@ -49,7 +53,11 @@ abstract class EndToEndTest(private val agpVersion: String, private val gradleVe
@Before
fun setup() {
projectDir = tempDirectory.newFolder("basic")
File(projectDir, "build.gradle").writeText(
setupProject(projectDir)
}

private fun setupProject(dir: File) {
File(dir, "build.gradle").writeText(
"""
plugins {
id("com.android.application") version "$agpVersion"
Expand All @@ -68,13 +76,13 @@ abstract class EndToEndTest(private val agpVersion: String, private val gradleVe
}
""".trimIndent()
)
File(projectDir, "gradle.properties").writeText(
File(dir, "gradle.properties").writeText(
"""
android.useAndroidX=true
com.google.protobuf.use_unsafe_pre22_gencode=true
""".trimIndent()
)
File(projectDir, "settings.gradle").writeText(
File(dir, "settings.gradle").writeText(
"""
pluginManagement {
repositories {
Expand Down Expand Up @@ -192,16 +200,72 @@ abstract class EndToEndTest(private val agpVersion: String, private val gradleVe
// Gson 2.8.9 specifically uses the Apache 2.0 license URL.
Assert.assertTrue(content.contains("apache.org/licenses/LICENSE-2.0"))
}

@Test
fun testRelocatability() {
val cacheDir = tempDirectory.newFolder("cache")
val dir1 = tempDirectory.newFolder("dir1")
val dir2 = tempDirectory.newFolder("dir2")

// Helper to populate a directory with the test project
fun populate(dir: File) {
// ONLY copy the source files, NEVER the build outputs or local cache state
projectDir.listFiles()?.forEach { file ->
if (file.name != "build" && file.name != ".gradle") {
file.copyRecursively(File(dir, file.name), overwrite = true)
}
}

// Update the settings.gradle to point to the correct repo path in the new location
File(dir, "settings.gradle").writeText(
"""
pluginManagement {
repositories {
maven {
url = uri("${System.getProperty("repo_path")}")
}
google()
mavenCentral()
}
}

buildCache {
local {
directory = '${cacheDir.absolutePath.replace("\\", "/")}'
}
}
""".trimIndent()
)
}
populate(dir1)
populate(dir2)

// 1. Run in dir1 to prime the cache
val result1 = createRunnerWithDir(dir1, "releaseOssLicensesTask", "--build-cache").build()
Assert.assertEquals(TaskOutcome.SUCCESS, result1.task(":releaseOssLicensesTask")?.outcome)

// 2. Run in dir2 (different absolute path) and expect FROM-CACHE
val result2 = createRunnerWithDir(dir2, "releaseOssLicensesTask", "--build-cache").build()

Assert.assertEquals(
"LicensesTask should be relocatable",
TaskOutcome.FROM_CACHE,
result2.task(":releaseOssLicensesTask")?.outcome
)
Assert.assertEquals(
"DependencyTask should be relocatable",
TaskOutcome.FROM_CACHE,
result2.task(":releaseOssDependencyTask")?.outcome
)
}
}

class EndToEndTest_AGP74_G75 : EndToEndTest("7.4.2", "7.5")
class EndToEndTest_AGP80_G80 : EndToEndTest("8.0.0", "8.0")
class EndToEndTest_AGP82_G82 : EndToEndTest("8.2.0", "8.2")
class EndToEndTest_AGP87_G89 : EndToEndTest("8.7.0", "8.9")
class EndToEndTest_AGP810_G811 : EndToEndTest("8.10.0", "8.11.1")
class EndToEndTest_AGP812_G814 : EndToEndTest("8.12.2", "8.14")
class EndToEndTest_AGP90_G90 : EndToEndTest("9.0.0-alpha03", "9.0.0")
class EndToEndTest_AGP91_G931 : EndToEndTest("9.1.0-alpha05", "9.3.1")
class EndToEndTest_AGP74_G75 : EndToEndTest("7.4.2", "7.5.1")
class EndToEndTest_AGP80_G80 : EndToEndTest("8.0.2", "8.0.2")
class EndToEndTest_AGP87_G89 : EndToEndTest("8.7.3", "8.9")
class EndToEndTest_AGP812_G814 : EndToEndTest("8.12.2", "8.14.1")
class EndToEndTest_AGP_STABLE_90_G90 : EndToEndTest("9.0.1", "9.1.0")
class EndToEndTest_AGP_ALPHA_92_G94 : EndToEndTest("9.2.0-alpha02", "9.4.0")

private fun expectedDependenciesJson(builtInKotlinEnabled: Boolean, agpVersion: String) = """[
{
Expand Down Expand Up @@ -382,7 +446,7 @@ private fun expectedDependenciesJson(builtInKotlinEnabled: Boolean, agpVersion:
{
"group": "org.jetbrains.kotlin",
"name": "kotlin-stdlib",
"version": "${if (agpVersion.startsWith("9.1")) "2.2.10" else "2.2.0"}"""" else ""}
"version": "${if (agpVersion.startsWith("9"))"2.2.10" else "2.2.0"}"""" else ""}
}
]"""

Expand Down
Loading