# Run task only if build cache exists

**URL:** https://discuss.gradle.org/t/run-task-only-if-build-cache-exists/33407
**Category:** Help/Discuss
**Created:** [October 3, 2019, 1:56pm UTC](https://discuss.gradle.org/t/run-task-only-if-build-cache-exists/33407 "2019-10-03T13:56:32Z")
**Posts on this page:** 2
**Page:** 1

<div class="post-metadata">

### Author: ![gerhardol](https://sea1.discourse-cdn.com/gradle/user_avatar/discuss.gradle.org/gerhardol/32/8004_2.png) [@gerhardol](https://discuss.gradle.org/u/gerhardol)
#### Post date: [October 3, 2019, 1:56pm UTC](https://discuss.gradle.org/t/run-task-only-if-build-cache-exists/33407/1 "2019-10-03T13:56:33Z")

</div>

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…

---

<div class="post-metadata">

### Author: ![gerhardol](https://sea1.discourse-cdn.com/gradle/user_avatar/discuss.gradle.org/gerhardol/32/8004_2.png) [@gerhardol](https://discuss.gradle.org/u/gerhardol)
#### Post date: [October 10, 2019, 7:27am UTC](https://discuss.gradle.org/t/run-task-only-if-build-cache-exists/33407/2 "2019-10-10T07:27:14Z")

</div>

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)')
    }
```
