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

doFirst and doLast in statically compiled languages gets only Task, not actual task type #14127

Open
Vampire opened this issue Aug 13, 2020 · 3 comments
Labels
a:feature A new functionality in:kotlin-dsl

Comments

@Vampire
Copy link
Contributor

Vampire commented Aug 13, 2020

With Gradle 6.5.1, I tried this:

fun deleteExternalsFile(task: PackageJsonDukatTask, file: String) {
    task
            .outputs
            .files
            .asFileTree
            .matching { include("**/$file") }
            .forEach { it.delete() }
}

tasks.withType(PackageJsonDukatTask::class) {
    doLast {
        addJsModuleAnnotation("core.module_@actions_core.kt", "@actions/core")
        addJsModuleAnnotation("io.module_@actions_io.kt", "@actions/io")
        deleteExternalsFile(this, "domain.domain.module_node.kt")
    }
}

This did not compile, as this is only of type Task in doLast.
Of course I can either use this@withType or make the method parameter Task in this case as I only use Task properties,
but that's not the point.
doLast closure should know the type of the task it is called for.

@Vampire Vampire added a:feature A new functionality from:contributor labels Aug 13, 2020
@eskatos eskatos changed the title doLast in Kotlin DSL gets only Task, not actual type doFirst and doLast in statically compiled languages gets only Task, not actual task type Jan 12, 2023
@eskatos
Copy link
Member

eskatos commented Jan 12, 2023

This is the function signatures in Task:

interface Task {
    Task doFirst(Action<? super Task> action);
    Task doLast(Action<? super Task> action);
}

A plugin implemented in Java would have the same problem

project.getTasks().withType(JavaCompile.class).configureEach((JavaCompile javaCompile) ->
    javaCompile.doFirst((Task task) -> { })    
);

Adding Kotlin extensions such as follows doesn't help because the original functions have precedence:

fun <T : Task> T.doFirst(action: T.() -> Unit) {
    doFirst(action as Action<in Task>)
}

At first sight I don't see a simple way to solve this without changing Task radically. Any idea?

@Vampire
Copy link
Contributor Author

Vampire commented Jan 12, 2023

Right now also not really besides adding a type parameter to Task and requiring all task classes to set it to itself or something like that which is probably what you meant with radical change and is probably quite an ugly change and might also make problems when extending tasks.

@eskatos
Copy link
Member

eskatos commented Jan 13, 2023

That's what I had in mind yes. It would be breaking the task api for everyone 🤷

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
a:feature A new functionality in:kotlin-dsl
Projects
None yet
Development

No branches or pull requests

6 participants