Status Update
Comments
vi...@google.com <vi...@google.com>
je...@google.com <je...@google.com>
cm...@google.com <cm...@google.com> #2
Thanks for the use case, I'm looking in to improving these. We won't remove these without a good replacement being stable first.
eg...@gmail.com <eg...@gmail.com> #3
zh...@gmail.com <zh...@gmail.com> #4
As AGP 7.0 is approaching soon (gradle-api
module:
Use case:
- For static analysis tools, we have
https://github.com/gradle/gradle/blob/master/subprojects/code-quality/src/main/groovy/org/gradle/api/plugins/quality/internal/AbstractCodeQualityPlugin.java out of the box to create a static analysis task per Java source set. - Althought we can use the same mechanism for Android, since Android is modeling the source structure through
AndroidSourceSet
, it is more natural to configure the static analysis tool perAndroidSourceDirectorySet
. AndroidSourceSet
gives more modular static analysis tasks configurations, which is in general improving the cacheability and reducing the build time for incremental changes.- This applies not only for Checkstyle, but also for other popular static analysis tool like Detekt and ktlint.
re...@gmail.com <re...@gmail.com> #5
Same here, i need to modify sourceSet according to current sourceSet value in my plugin. but i can't do it now
re...@gmail.com <re...@gmail.com> #6
I have noticed that DefaultAndroidSourceDirectorySet has marked deprecated method for include and exclude method
Our team has made an java file overlay plugin to fast overwrite some single class or java file for quick local build and development. which used the include
and exclude
file to implement adding single file to source sets. the logic as below.
if exclude
and include
method and getSrcDirs
been removed, the plugin will be broken.
our project is very huge to do a full compile, this plugin helps our team a lot.
Hope those method will not be removed.
@Deprecated("To be removed in 8.0")
override fun exclude(excludeSpec: Spec<FileTreeElement>): PatternFilterable {
filter.exclude(excludeSpec)
return this
}
@Deprecated("To be removed in 8.0")
override fun exclude(excludeSpec: Closure<*>): PatternFilterable {
filter.exclude(excludeSpec)
return this
}
val android = project.extensions.getByName("android") as? BaseAppModuleExtension
android?.sourceSets {
named("main") { androidSourceSet ->
val javaConfig = (androidSourceSet.java as com.android.build.gradle.internal.api.DefaultAndroidSourceDirectorySet)
val sourceFilesCache = mutableSetOf<String>()
javaConfig.srcDirs.forEach { srcDir ->
project.files(srcDir).asFileTree.matching(javaConfig.filter)
.forEach { sourceFile ->
sourceFilesCache.add(sourceFile.toRelativeString(srcDir))
}
}
javaConfig.filter.includes.clear()
externalSourceFilesConfiguration.javaSrcDirs.forEach { baseDir ->
val externalSrcDir = if (baseDir.startsWith("/")) outerSrcDir + baseDir.trimStart('/') else outerSrcDir + baseDir
project.fileTree(externalSrcDir).matching {
it.include(externalSourceFilesConfiguration.javaSourceFiles)
}.forEach { sourceFile ->
sourceFilesCache.add(
sourceFile.toRelativeString(
project.file(
externalSrcDir
)
)
)
}
javaConfig.srcDirs(externalSrcDir)
}
sourceFilesCache.forEach { sourceFile ->
javaConfig.filter.include(sourceFile)
}
}
}
xa...@google.com <xa...@google.com> #7
Getting access to the sources should be done with
Please take a look at this APIs to see whether it fits all your need.
Using include/exclude during config time based on things, is not something that's going to work with config cache. I would strongly suggest to find a different way?
Chris, can we make sure to close this for 8.1?
ma...@gmail.com <ma...@gmail.com> #8
Unfortunately, Components.sources
doesn't expose the same information as android.sourceSets.configureEach
did. If you iterate through android.sourceSet
you'll get distinct directories for each variant, for example for a project with [free|paid]
flavours and [debug|release]
build types you'll get src/main/kotlin
, src/debug/kotlin
, src/paidDebug/kotlin
which don't overlap with each other.
Maybe I'm wrong, but here's my attempt to reproduce the same scenario:
fun Project.repro() {
val android = project.extensions.findByName("androidComponents") as? AndroidComponentsExtension<*, *, *> ?: return
android.onVariants { variant ->
val emptyFileTree = files().asFileTree
val allVariantKotlinFiles = sequenceOf(
variant.sources,
variant.unitTest?.sources,
(variant as? HasAndroidTest)?.androidTest?.sources,
(variant as? HasTestFixtures)?.testFixtures?.sources,
)
.mapNotNull { sources -> listOfNotNull(sources?.kotlin?.all?.orNull, sources?.java?.all?.orNull).flatten() }
.flatten()
.map { sourcesRoot -> project.fileTree(sourcesRoot) { it.include("**/*.kt") } }
.fold(emptyFileTree) { merged, tree -> merged + tree }
tasks.register("runCodeStyleAgainst${variant.name.capitalize()}", SourceTask::class.java) { sourceTask ->
sourceTask.source(allVariantKotlinFiles)
}
}
}
but the issue is: these are not distinct anymore. runCodeStyleAgainstFreeDebug
and runCodeStyleAgainstPaidDebug
will both attempt to run over files from src/main/debug
, which isn't the most performant way and effectively will break things (i.e. if autoformating option is enabled).
Is there any other option to list all distinct sourceSets for the project, the same way the old API allows to? Am I missing something?
xa...@google.com <xa...@google.com> #9
For what you are doing, the best way would be to have a single task that gather all the sources from all the variant (it seems like there's no reason to have a separate task for each variant).
We are aware that there may be cases where you want to process an individual source folder. However, the existing DSL is still not the place to do this due to timing issue between different plugins. Gradle's Property
API is the solution for this, and our variant API uses this, and therefore you need an API that exposes it too. This is on our todo list but no ETA right now.
ma...@gmail.com <ma...@gmail.com> #10
Thanks for the answer 🙏
(it seems like there's no reason to have a separate task for each variant).
The motivation here was to not run the task against all project files if they didn't change. Currently, if I modify i.e. flavor-specific tests files, I don't need/want to check all other files. (I'm aware of incremental tasks, but I assume it's not applicable to all use-cases. For example, some of the teams don't use remote cache, so they can't leverage incremental compilation when checking out a new remote branch)
However, the existing DSL is still not the place to do this due to timing issue between different plugins.
Do I understand correctly that you'll eventually add a dedicated API to iterate over all source sets? If so, then that's completely fine 👍
I understood #7 as a statement the only possible way to iterate over source sets will be the Component#sources
property, and this was the only reason why I wanted to mention it doesn't really work yet (I tested latest 8.1 alpha).
Description
AGP: 4.1.0
I want to configure Checkstyle tool for all java sources. With older plugin version I was able to call
Deprecation warning suggests I should use
com.android.build.api.dsl.AndroidSourceSet
class instead, which doesn't exposesrcDirs
anymore. If there is another way accessing it it would be nice to have a deprecation warning on thesrcDirs
property tooExpected result: I'm able to access
java
srcDirs without Deprecation warningActual Result: I able to obtain all java source directories only with a deprecatior warning