How do I express optional resource?

I have a task that produces a file.
If the file was created (the task called explicitly) I want it to end up in the project resources (be put into the jar). And if the task was not called explicitly, do nothing (no file in the jar)

When I add this task’s output dir to sourceSets the task is being called all the time

Would something like this work for you?

The createFile task here generates a file. Then we can configure the build task to depend on copyFile so that when we run build, it will copy that generated file into the resources directory if the file exists. There’s probably a more optimal set up than this, but maybe it’ll help.

def createFile = tasks.register('createFile') {
    doLast {
        file('testFile').createNewFile()
    }
}

def copyFile = tasks.register('copyFile') {
    doLast {
        copy {
            from file('testFile')
            into "${buildDir}/resources/main"
        }
    }
}

tasks.named('build').configure {
    dependsOn copyFile
}

Actually it looks like this works as well, and is probably the better way to do it. You can also configure processResources to additionally copy your generated file into resources.

tasks.named('processResources').configure {
    from 'testFile'
}

Thanks, @TriumphantToad. I’ll try

The first variant @TriumphantToad described is actually very bad, tasks should never have overlapping outputs or write into output directories of other tasks / modify outputs of other tasks, or you majorly disturb up-to-date checks and task output caches and might even get unpredictable behavior.

The second variant is a bit better, but still problematic.
Because if the task is not run, but the file is there from a previous run, it will include that stale version of the file.
And it might even fail if the fiel is not there, I’m not sure.
Besides that, other pieces needing the resources will not include the file.

You probably need to do the sourceSets adding that you initially mentioned, depending on the contents of gradle.startParameter.taskNames or similar. But be aware that task names in there don’t have to be complete, but can be abbreviated.

1 Like