Run task only if build cache exists

I have a use case where a build takes up to 30 min. The build artifacts can be used to speed up next build when working in a GUI tool, so when a developer opens the tool to work with the product, it would be helpful if an existing build cache can be restored. If a build cache does not exist, a build should not be started.

This can kind of be handled by raising an exception when executing, but this gives an ugly error message.
I would like to check if a build cache exists for a task before executing the task or to exit execute gracefully without creating a cache.

Current draft below. The double invocation would not be needed if the first ‘deleteFiles’ task could evaluate if a cache exists for the genFiles task.

project.tasks.create('genFiles', GenerateFiles).configure {
    description = "Generate files"

    dependsOn('deleteFiles')
}
project.tasks.create('restoreCache', GenerateFiles).configure {
    description = "Restore cache of generated files"

    onlyIf { project.tasks.genFiles.getState().upToDate }
    dependsOn('genFiles')
    // TODO delete files if up to date, separate task needed?
    //dependsOn('deleteFiles')
}
project.afterEvaluate {
    project.tasks.create('deleteFiles') {
        onlyIf { !ext.unpackCacheOnly.get() || project.tasks.genFiles.getState().upToDate }

        doLast {
            // Remove all output files/folders
            // This is required to cache builds after output files are modified i.e. in a GUI generation (rebuild will not be cached otherwise)
            TaskOutputs taskOutputs = project.tasks.genFiles.outputs
            def str = ' Cleaned'
            taskOutputs.getFiles().each { File f ->
                str += ' ' + f
                project.delete(f)
                if (!f.parentFile.exists()) {
                    f.parentFile.mkdirs()
                }
            }
            log.info str
        }
    }

}
//////////////////////////////////////////////////////////////////////////////////////

@TaskAction
void execute(IncrementalTaskInputs inputs) {
if (project.extensions.ext.unpackCacheOnly.get()){
// We need to throw to exit with error (to not cache)
throw new GradleException(‘No cache exists, exiting (ignore message about failure)’)
}
rest of build…

The solution I used
Users are confused about the failure, using ANSI escape to at least show the message clearly

            def genCacheCheckTask = project.tasks.register('genCacheCheck', GenerateTask) {
            group = Extension.name
            description = "Try to restore cache to temp dir, to find if it exists"

            unpackCacheOnly = true
            testOutputDir = "tmp/tmpUnpackCache/"
        }
        def delGenCacheCheckTask = project.tasks.register('preGenCacheCheck', DeleteTask) {
            deleteTask = genCacheCheckTask
        }
        genCacheCheckTask.configure {
            dependsOn(delGenCacheCheckTask)
        }


        def genCacheTask = project.tasks.register('genCache', GenerateTask) {
            group = Extension.name
            description = "Extract existing cache"

            dependsOn { genCacheCheckTask }

            unpackCacheOnly = true
        }
        def delGenCacheTask = project.tasks.register('preGenCache', DeleteTask) {
            deleteTask = genCacheTask
        }
        genCacheTask.configure {
            dependsOn(delGenCacheTask)
        }
/**
 * Color output using ANSI escape
 */
def color = { color, text ->
    def colors = [black: 30, red: 31, green: 32, yellow: 33, blue: 34, magenta: 35, cyan: 36, white: 37]
    return new String((char) 27) + "[${colors[color]}m${text}" + new String((char) 27) + "[0m"
}
/*
 * The action performed when at least one file has been updated
 */
@TaskAction
void execute(IncrementalTaskInputs inputs) {
    if (unpackCacheOnly){
        log.warn("${color 'green', 'No cache exists, exiting (ignore message about failure)'}")
        // We need to throw to exit with error (to not cache)
        throw new GradleException('No cache exists, exiting (ignore message about failure)')
    }