Cannot copy file to build directory with a custom task that depends on the "build" task

Hello
I’m trying to do that after the build task, some.bat file is copied to the build directory with this code:

tasks.register<Copy>("copyMainBat") {
    from("src/main/runners/some.bat")
    into(layout.buildDirectory.get())
}

tasks.build {
    dependsOn("copyMainBat")
}

But it’s not working:

If i do

tasks.processResources{
    dependsOn("copyMainBat")
}

instead of

tasks.build {
    dependsOn("copyMainBat")
}

or

into(layout.buildDirectory.get().dir("bin"))

instead of

into(layout.buildDirectory.get())

it’s working fine but why can’t i just copy file to build directory with build task depending on custom task? I just don’t understand how processResources and jar tasks prevent copying directly into build dir

By the way, this working fine as well:

tasks.build {
    inputs.file("some.bat")
        .withPropertyName("inputBatFile")
    outputs.dir(layout.buildDirectory.get())
        .withPropertyName("outputDir")

    doLast {
        copy {
            from("src/main/runners/some.bat")
            into(layout.buildDirectory.get())
        }
    }
}

but this is not good practice, is it?

Let’s start with: do not use .get() needlessly, that destroys the whole concept of having lazily evaluated properties.

The source of your error is, that by using a Copy task with destination directory layout.buildDirectory, that whole directory is the output of the task, which is pretty bad for various reasons and then also causes the error you got because you have overlapping outputs of tasks and that is also always pretty bad for various reasons.

Your last snippet is indeed almost good, just not fully.
You should usually not add actions to a lifecycle task.
And you still define the whole build directory as task output and thus still have overlapping outputs.

Instead, you should create an “untyped” task, there define the input file and output file (not directory) and use the copy { ... } closure. So something like:

tasks.register("copyMainBat") {
    val inputFile = file("src/main/runners/some.bat")
    val outputDir = layout.buildDirectory

    inputs.file(inputFile).withPropertyName("inputBatFile")
    outputs.file(outputDir.file(inputFile.name)).withPropertyName("outputFile")

    doLast {
        copy {
            from(inputFile)
            into(outputDir)
        }
    }
}
1 Like