Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix build cache in combination with Android product flavors causes issues #1088

Merged
merged 1 commit into from
Feb 16, 2025
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
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@ import org.gradle.api.provider.Provider
import org.gradle.api.tasks.CacheableTask
import org.gradle.api.tasks.Input
import org.gradle.api.tasks.Internal
import org.gradle.api.tasks.Optional
import org.gradle.api.tasks.OutputFile
import org.gradle.api.tasks.TaskAction
import org.slf4j.LoggerFactory
import java.io.File

@CacheableTask
abstract class AboutLibrariesCollectorTask : DefaultTask() {
Expand All @@ -32,15 +32,26 @@ abstract class AboutLibrariesCollectorTask : DefaultTask() {
@Internal
protected lateinit var collectedDependencies: CollectedContainer

@Optional
@Input
open var variant: Provider<String?> = project.provider { null }

@OutputFile
val dependencyCache: Provider<RegularFile> = project.layout.buildDirectory.file("generated/aboutLibraries/dependency_cache.json")
val dependencyCache: Provider<RegularFile> = project.provider {
val variant = variant.orNull
if (variant == null) {
project.layout.buildDirectory.file("generated/aboutLibraries/dependency_cache.json").orNull
} else {
project.layout.buildDirectory.file("generated/aboutLibraries/$variant/dependency_cache.json").orNull
}
}

/**
* Collect the dependencies via the available configurations for the current project
*/
fun configure() {
project.evaluationDependsOnChildren()
collectedDependencies = DependencyCollector(includePlatform, filterVariants).collect(project)
collectedDependencies = DependencyCollector(includePlatform, filterVariants + (variant.orNull?.let { arrayOf(it) } ?: emptyArray())).collect(project)
}

@TaskAction
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.mikepenz.aboutlibraries.plugin

import com.mikepenz.aboutlibraries.plugin.util.experimentalCache
import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.api.file.Directory
Expand Down Expand Up @@ -53,37 +54,27 @@ class AboutLibrariesPlugin : Plugin<Project> {
project.tasks.register("exportLibraryDefinitions", AboutLibrariesTask::class.java) {
it.description = "Writes the relevant meta data for the AboutLibraries plugin to display dependencies"
it.group = "Build"
it.variant = project.providers.gradleProperty("aboutLibraries.exportVariant")
.orElse(project.providers.gradleProperty("exportVariant"))
it.variant = project.providers.gradleProperty("aboutLibraries.exportVariant").orElse(project.providers.gradleProperty("exportVariant"))

val projectDirectory = project.layout.projectDirectory
val buildDirectory = project.layout.buildDirectory

val exportPath: Provider<Directory> = project.providers.gradleProperty("aboutLibraries.exportPath")
.map { path -> projectDirectory.dir(path) }
.orElse(
project.providers.gradleProperty("exportPath").map { path -> projectDirectory.dir(path) }
).orElse(
buildDirectory.dir("generated/aboutLibraries/")
)
val exportPath: Provider<Directory> = project.providers.gradleProperty("aboutLibraries.exportPath").map { path -> projectDirectory.dir(path) }.orElse(
project.providers.gradleProperty("exportPath").map { path -> projectDirectory.dir(path) }).orElse(
buildDirectory.dir("generated/aboutLibraries/")
)
it.resultDirectory.set(exportPath)

it.dependsOn(collectTask)
}

val extension = project.extensions.findByType(AboutLibrariesExtension::class.java)!!
if (extension.registerAndroidTasks) {
AboutLibrariesPluginAndroidExtension.apply(project, collectTask)
AboutLibrariesPluginAndroidExtension.apply(project)
}
}
}

private val Project.experimentalCache: Provider<Boolean>
get() = providers.gradleProperty("org.gradle.unsafe.configuration-cache").map { it == "true" }
.orElse(
providers.gradleProperty("org.gradle.configuration-cache").map { it == "true" }
)

companion object {
private val LOGGER = LoggerFactory.getLogger(AboutLibrariesPlugin::class.java)
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,27 +1,27 @@
package com.mikepenz.aboutlibraries.plugin

import com.mikepenz.aboutlibraries.plugin.util.experimentalCache
import org.gradle.api.Project
import org.gradle.api.tasks.TaskProvider
import org.slf4j.LoggerFactory
import java.util.*
import java.util.Locale

/**
* Android specific extension for the [AboutLibrariesPlugin]
*/
object AboutLibrariesPluginAndroidExtension {
private val LOGGER = LoggerFactory.getLogger(AboutLibrariesPluginAndroidExtension::class.java)

fun apply(project: Project, collectTask: TaskProvider<AboutLibrariesCollectorTask>) {
fun apply(project: Project) {
try {
val app = project.extensions.findByType(com.android.build.gradle.AppExtension::class.java)
if (app != null) {
app.applicationVariants.configureEach {
createAboutLibrariesAndroidTasks(project, it, collectTask)
createAboutLibrariesAndroidTasks(project, it)
}
} else {
val lib = project.extensions.findByType(com.android.build.gradle.LibraryExtension::class.java)
lib?.libraryVariants?.configureEach {
createAboutLibrariesAndroidTasks(project, it, collectTask)
createAboutLibrariesAndroidTasks(project, it)
}
}
} catch (t: Throwable) {
Expand All @@ -30,15 +30,24 @@ object AboutLibrariesPluginAndroidExtension {
}

@Suppress("DEPRECATION")
private fun createAboutLibrariesAndroidTasks(project: Project, v: Any, collectTask: TaskProvider<*>) {
private fun createAboutLibrariesAndroidTasks(project: Project, v: Any) {
val variant = (v as? com.android.build.gradle.api.BaseVariant) ?: return

// task to output library names with ids for further actions
val collectTask = project.tasks.register("collectDependencies${variant.name.capitalize(Locale.ENGLISH)}", AboutLibrariesCollectorTask::class.java) {
it.description = "Collects dependencies to be used by the different AboutLibraries tasks"
it.variant = project.provider { variant.name }
if (project.experimentalCache.orNull == true) {
it.configure()
}
}

val resultsResDirectory = project.layout.buildDirectory.dir("generated/aboutLibraries/${variant.name}/res/")
val resultsDirectory = resultsResDirectory.map { it.dir("raw/") }

// task to write the general definitions information
val task = project.tasks.register(
"prepareLibraryDefinitions${variant.name.capitalize(Locale.ENGLISH)}",
AboutLibrariesTask::class.java
"prepareLibraryDefinitions${variant.name.capitalize(Locale.ENGLISH)}", AboutLibrariesTask::class.java
) {
it.description = "Writes the relevant meta data for the AboutLibraries plugin to display dependencies"
it.group = "Build"
Expand All @@ -53,8 +62,7 @@ object AboutLibrariesPluginAndroidExtension {
try {
variant.mergeResourcesProvider.configure { it.dependsOn(task) }
} catch (t: Throwable) {
@Suppress("DEPRECATION")
variant.mergeResources.dependsOn(task)
@Suppress("DEPRECATION") variant.mergeResources.dependsOn(task)
}
} catch (t: Throwable) {
LOGGER.warn("Using deprecated API to register task, as new registerGeneratedResFolders was not supported by the current environment. Consider upgrading your AGP version.")
Expand All @@ -65,8 +73,7 @@ object AboutLibrariesPluginAndroidExtension {

// task to generate libraries, and their license into the build folder (not hooked to the build task)
project.tasks.register(
"generateLibraryDefinitions${variant.name.capitalize(Locale.ENGLISH)}",
AboutLibrariesTask::class.java
"generateLibraryDefinitions${variant.name.capitalize(Locale.ENGLISH)}", AboutLibrariesTask::class.java
) {
it.description = "Manually write meta data for the AboutLibraries plugin"
it.group = "Build"
Expand All @@ -77,8 +84,7 @@ object AboutLibrariesPluginAndroidExtension {

// task to output libraries, and their license in CSV format to the CLI
project.tasks.register(
"exportLibraries${variant.name.capitalize(Locale.ENGLISH)}",
AboutLibrariesExportTask::class.java
"exportLibraries${variant.name.capitalize(Locale.ENGLISH)}", AboutLibrariesExportTask::class.java
) {
it.description = "Writes all libraries and their license in CSV format to the CLI"
it.group = "Help"
Expand All @@ -88,8 +94,7 @@ object AboutLibrariesPluginAndroidExtension {

// task to output libraries, their license in CSV format and source to a given location
project.tasks.register(
"exportComplianceLibraries${variant.name.capitalize(Locale.ENGLISH)}",
AboutLibrariesExportComplianceTask::class.java
"exportComplianceLibraries${variant.name.capitalize(Locale.ENGLISH)}", AboutLibrariesExportComplianceTask::class.java
) {
it.description = "Writes all libraries with their source and their license in CSV format to the configured directory"
it.group = "Help"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,15 @@ abstract class BaseAboutLibrariesTask : DefaultTask() {

@InputFile
@PathSensitive(value = PathSensitivity.RELATIVE)
val dependencyCache: Provider<RegularFile> = project.layout.buildDirectory.file("generated/aboutLibraries/dependency_cache.json")

val dependencyCache: Provider<RegularFile> = project.provider {
val variant = variant.orNull
if (variant == null) {
project.layout.buildDirectory.file("generated/aboutLibraries/dependency_cache.json").orNull
} else {
project.layout.buildDirectory.file("generated/aboutLibraries/$variant/dependency_cache.json").orNull
}
}

@Optional
@PathSensitive(value = PathSensitivity.RELATIVE)
@InputDirectory
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,21 @@ package com.mikepenz.aboutlibraries.plugin.util
import com.mikepenz.aboutlibraries.plugin.mapping.Library
import com.mikepenz.aboutlibraries.plugin.mapping.License
import com.mikepenz.aboutlibraries.plugin.util.parser.PomReader
import org.gradle.api.Project
import org.gradle.api.artifacts.ModuleIdentifier
import org.gradle.api.artifacts.ResolvedArtifact
import org.gradle.api.artifacts.ResolvedDependency
import org.gradle.api.artifacts.ResolvedModuleVersion
import org.gradle.api.artifacts.component.ComponentArtifactIdentifier
import org.gradle.api.artifacts.component.ModuleComponentIdentifier
import org.gradle.api.provider.Provider
import java.io.File
import java.security.MessageDigest

internal val Project.experimentalCache: Provider<Boolean>
get() = providers.gradleProperty("org.gradle.unsafe.configuration-cache").map { it == "true" }.orElse(
providers.gradleProperty("org.gradle.configuration-cache").map { it == "true" })

internal infix fun <T> List<PomReader>?.first(read: PomReader.() -> T?): T? {
this ?: return null
for (reader in this) {
Expand Down
Loading