This message was deleted.
# plugin-development
s
This message was deleted.
c
Not sure how to do this for any generic SourceSet; the below works for Java:
Copy code
val javaExtension = the<JavaPluginExtension>()
    javaExtension.sourceSets.forEach { sourceSet ->
        sourceSet.compileJavaTaskName
    }
Seems like there’s a bunch of accessors exposed there:
Copy code
String getClassesTaskName();

    String getProcessResourcesTaskName();

    String getCompileJavaTaskName();

    String getCompileTaskName(String var1);

    String getJavadocTaskName();

    String getJarTaskName();

    String getJavadocJarTaskName();

    String getSourcesJarTaskName();

    String getTaskName(@Nullable String var1, @Nullable String var2);
It looks like there’s a pattern -
compile
+
language
.
Copy code
@Override
    public String getCompileTaskName(String language) {
        return getTaskName("compile", language);
    }

    @Override
    public String getCompileJavaTaskName() {
        return getCompileTaskName("java");
    }
Perhaps grabbing the
destinationDirectory
from all org.gradle.api.tasks.compile.AbstractCompile tasks is more precise.
Copy code
/**
 * The base class for all JVM-based language compilation tasks.
 */
@DisableCachingByDefault(because = "Abstract super-class, not to be instantiated directly")
public abstract class AbstractCompile extends SourceTask {
fyi, SourceSet. getCompileTaskName is used for cpp, swift as well (from Gradle sources).
v
There is not necessarily the task that compiles the sources, there can be multiple. But you should also not really do what you try to. Use the output of the source set as input for your byte code enhancement and you should also get automatically the necessary task dependencies. Almost all cases where you want to set a manual
dependsOn
where not a lifecycle task is on the left side is a coffee smell actually.
s
@Vampire That's not unreasonable and I tried that originally. But it leads to other problems / difficulties. At the moment this actually uses a do-last action to avoid up-to-date issues. Using an actual task (iiuc) also means a new output directory which means lots of other tasks (jar, test, etc) need to get reconfigured
v
Ah, yeah, if you do the manipulation in-place, a
doLast
action is better of course.
But you then of course have to add code for any JVM language that could contribute. Java, Kotlin, Groovy, Scala, ..., any other that already exists or might be added in the future.
s
Enhancing is the same regardless
Is that what you mean?
If you mean in terms of accessing the "compilation task", you are absolutely correct. Making that SourceSet and compilation-task connection is the thing I am struggling with
@Chris Lee Sure, those methods "work" as I stated initially. The problem is knowing ahead of time what the language is. Once you know the language, sure, call
getCompileTaskName(String language)
Now imagine you are writing a general use plugin - you do not know the language - it might be one of any
v
Or multiple
Maybe you can somehow just get all task dependencies and just attach your enhancement to all dependency tasks, just doing nothing if you don't find
.class
files in the output
s
Can a SourceSet really have multiple compilation tasks?
v
Of course, one per language
s
I know you can mix groovy and java sources, for example. But they are compiled once iiuc
Ah, right... SourceDirectorySet
v
Groovy is a special case as Groovy supports joint compilation
Not sure if you have one or two tasks there
But for all other languages at least it should be one task per language
s
So taking a step back, do you see a better way to accomplish this? Enhancing bytecode after compilation...
c
perhaps create an instrumentation task from each
AbstractCompile
task, hooking output to input?
v
To enhance it in the file in-place? No, a
doLast
action is imho optimal in that case so that caching, up-to-dateness and so on are properly affected too. If it does not have to be in-place the question is where it is needed. If you need it everywhere the classes are used it might be indeed the best solution. If you for example only need it in the test task, then you could add on out-of-place enhancement task and use that result for the test task for example.
s
Using a task is not really feasible. It forces you to use a different "classes output dir"
@Vampire No, unfortunately the enhanced classes need to completely replace the non-enhanced versions
Its really a "post compile" step in the truest sense
v
Then the
doLast
is most probably indeed the way to go.
c
seems that way
s
Yes, that seems to be the consensus. But that's what I am doing now and it has its own pitfalls which is what I initially asked about
I have to find the task(s) to which to apply the doLast (with some filtering, etc)
c
s/b
AbstractComile
instances with the filtering.
s
Not sure what s/b means here
v
Are you sure all language plugins will extend it?
s
and its not that kind of filtering
c
tasks.withType<AbstractCompile>().configureEach
s
@Chris Lee Again, its not filtering at the compilation level
c
that gets you all the compile tasks to which add the doLast to.
v
If all language plugins extend it
s
Right, its not all compile tasks
c
correct. filter as needed.
v
I still think you should maybe try to get all dependency tasks of the source set and just enhance all of them, no matter what type they are and just do nothing if no class files are found.
Or you need to support languages explicitly by getting their compile tasks and if someone uses another language they are lost and need to wait for you to support it
s
That may be the best option for now
Its fairly reasonable
Ok, thanks @Vampire and @Chris Lee
👍 1
I'll just go with the "discrete language" support approach for now
👌 1