Dariusz Kuc
07/27/2021, 5:23 PMcompileKotlin
in JVM builds and compile${Variant}Kotlin
for 🤖 ). What is somewhat weird is that for JVM builds my task gets included when running build
goal but on Android it is not....
If I explicitly run my task on Android project it does get finalized correctly. So just wondering what would be the cause of the difference in behavior between JVM and Android buildsDariusz Kuc
07/27/2021, 5:25 PMfinalizeBy
-> https://github.com/dariuszkuc/graphql-kotlin/blob/android_build/plugins/graphql-ko[…]n/com/expediagroup/graphql/plugin/gradle/GraphQLGradlePlugin.ktDariusz Kuc
07/27/2021, 5:27 PMcompileKotlin dependsOn myTask
vs current myTask finalizedBy compileKotlin
) but I thought that was considered a bad practice?Vampire
07/27/2021, 9:19 PMdependsOn
if you can instead use an implicit task dependency, yes.
But using a finalizedBy
instead is just wrong and thus worse.
compileKotlin dependsOn myTask
means if compileKotlin
needs to run, first myTask
has to have been run before it.
myTask finalizedBy compileKotlin
means whenever myTask
is run, run compileKotlin
automatically after it.
But the latter does not mean, that if you run compileKotlin
, that myTask
is run before.
But either way, if you do it like that, I guess you generate the sources into the same directory where the versioned sources are present, which is another bad practice.
Or you manually add the output directory of myTask
to the source directories, which also is bad practice.
Instead you should register the myTask
as source directory, then its output will be considered source for all means like building a sources jar, requesting all sources, compilation and so on and at the same time you have the implicit task dependency for all tasks that need the sources and not only the compile task.Vampire
07/27/2021, 9:20 PMval mySourceGeneratingTask by tasks.registering(...) {
...
}
val generate by tasks.registering {
dependsOn(mySourceGeneratingTask)
}
sourceSets {
main {
java {
srcDir(mySourceGeneratingTask)
}
}
}
The generate task is fully optional, but I like to have a lifecycle task that depends on all tasks that generate something.Dariusz Kuc
07/27/2021, 9:23 PMsrcDir
-> https://github.com/dariuszkuc/graphql-kotlin/blob/android_build/plugins/graphql-ko[…]n/com/expediagroup/graphql/plugin/gradle/GraphQLGradlePlugin.ktDariusz Kuc
07/27/2021, 9:23 PMmain.java.srcDir
Dariusz Kuc
07/27/2021, 9:24 PMDariusz Kuc
07/27/2021, 9:25 PMOr you manually add the output directory ofyeah I'm adding output directoryto the source directories, which also is bad practice.myTask
Dariusz Kuc
07/27/2021, 9:37 PMsrcDir
and that works like a charm for JVM build (without explicit dependsOn/finalizeBy), I'll check what I need to do for AndroidVampire
07/27/2021, 9:57 PMoutputDirectory
DirectoryProperty
property should also be enough already.
I didn't check, but I guess outputDirectory
is annotated with @OutputDirectory
, this way it also carries the implicit task dependency.
So even with what you had before it should have been fine without dependsOn
or finalizedBy
and for Android there is hopefully also a place to add the source.
But I'm not familiar with Android builds, sorry.Dariusz Kuc
07/27/2021, 10:04 PMDariusz Kuc
07/27/2021, 10:14 PMDariusz Kuc
07/28/2021, 4:31 AMsourceSets
are stored -> on default JVM build its a project property vs android extension property
val baseExtension = project.extensions.findByType(BaseExtension::class.java)
println("Android source sets: ${baseExtension?.sourceSets?.names}")
val androidMainSourceSet = baseExtension?.sourceSets?.findByName("main")?.java
androidMainSourceSet?.srcDir(task.outputDirectory)
println("Android main source set: $androidMainSourceSet")
Running it I see that my task source is added but it still doesn't run during the build
Android source sets: [androidTest, androidTestDebug, androidTestRelease, debug, main, release, test, testDebug, testRelease]
Android main source set: com.android.build.gradle.internal.api.DefaultAndroidSourceDirectorySet@1b4062a2, type=com.android.build.gradle.internal.api.artifact.SourceArtifactType$JAVA_SOURCES@9aa5534, source=[src/main/java, task ':app:graphqlGenerateClient' property 'outputDirectory']
Wondering whether this is because of kotlin-android
plugin is applied eagerly (supposedly getting fix in next release).Vampire
07/28/2021, 7:45 AM@Override
@NonNull
public Set<File> getSrcDirs() {
return fileResolver.resolveFiles(source.toArray()).getFiles();
}
So at this time the implicit task dependencies are eradicated. I guess you indeed need explicit dependsOn
for Android and need to complain to Google about this fact.ephemient
07/28/2021, 8:50 AMVampire
07/28/2021, 9:33 AMsrcDir
is not enough.
So probably what ephemient said. 🙂Dariusz Kuc
07/28/2021, 1:58 PMregisterJavaGeneratingTask
but it was throwing me an exception as I'm trying to configure it from my task configuration
i.e.
val baseExtension = project.extensions.findByType(BaseExtension::class.java)!!
val androidMainSourceSet = baseExtension.sourceSets.findByName("main")?.java
androidMainSourceSet?.srcDir(task.outputDirectory)
val variants = when (androidExtension) {
is LibraryExtension -> if (isTestSource) findTestVariants(androidExtension) else androidExtension.libraryVariants
is AppExtension -> if (isTestSource) findTestVariants(androidExtension) else androidExtension.applicationVariants
else -> throw RuntimeException(
"Unsupported configuration - unable to determine appropriate compile Kotlin task. graphql-kotlin plugin only supports default JVM builds, Android libraries and applications"
)
}
variants.forEach { variant ->
variant.registerJavaGeneratingTask(task, task.outputDirectory.asFile.get()). // throws exception
variant.addJavaSourceFoldersToModel(task.outputDirectory.asFile.get())
}
DefaultTaskContainer#NamedDomainObjectProvider.configure(Action) on task set cannot be executed in the current context.
was trying to add sources directly to the variant sources (e.g. debug) as well but that didn't make any differenceDariusz Kuc
07/28/2021, 2:14 PMdependsOn
on my task that will always execute my task (even though end user might not have configured it)....Dariusz Kuc
07/28/2021, 2:15 PMVampire
07/28/2021, 2:16 PMcompile
task needs a dependency on your task, then add it.
If your task is unconfigured and thus has no inputs, it will be skipped if you have annotated your properties properly.Vampire
07/28/2021, 2:17 PMVampire
07/28/2021, 2:17 PMDariusz Kuc
07/28/2021, 2:22 PMIf your task is unconfigured and thus has no inputs, it will be skipped if you have annotated your properties properly.I use conventions to setup some defaults so unsure if that makes any difference
Vampire
07/28/2021, 2:38 PMVampire
07/28/2021, 2:39 PMDariusz Kuc
07/28/2021, 2:45 PMDariusz Kuc
07/28/2021, 2:46 PMDariusz Kuc
07/28/2021, 2:58 PMVampire
07/28/2021, 2:59 PMephemient
07/29/2021, 2:36 PMtask.outputDirectoty.asFile.get()
,
val outputDir = File(buildDir, "generated/source/...")
taskProvider.configure { outputDirectory.set(outputDir) }
variant.registerJavaGeneratingTask(taskProvider, outputDir)
wouldn't need any trickinessVampire
07/29/2021, 2:38 PMbuildDir
, but the lazy layout.buildDirectory
variant 🙂Vampire
07/29/2021, 2:40 PMregisterJavaGeneratingTask
which again does not accept lazy values 😞Dariusz Kuc
07/29/2021, 3:26 PMDariusz Kuc
07/29/2021, 3:28 PM