{"id":20713872,"url":"https://github.com/diffplug/cache-horizon","last_synced_at":"2026-04-18T20:02:29.441Z","repository":{"id":57718785,"uuid":"259547804","full_name":"diffplug/cache-horizon","owner":"diffplug","description":"Gradle build cache for a group of tasks","archived":false,"fork":false,"pushed_at":"2020-04-28T17:33:10.000Z","size":63,"stargazers_count":0,"open_issues_count":1,"forks_count":0,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-01-17T21:31:22.438Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/diffplug.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2020-04-28T06:11:06.000Z","updated_at":"2020-04-28T17:33:13.000Z","dependencies_parsed_at":"2022-09-26T21:40:31.107Z","dependency_job_id":null,"html_url":"https://github.com/diffplug/cache-horizon","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/diffplug%2Fcache-horizon","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/diffplug%2Fcache-horizon/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/diffplug%2Fcache-horizon/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/diffplug%2Fcache-horizon/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/diffplug","download_url":"https://codeload.github.com/diffplug/cache-horizon/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":242988120,"owners_count":20217535,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-17T02:27:51.344Z","updated_at":"2026-04-18T20:02:29.390Z","avatar_url":"https://github.com/diffplug.png","language":"Java","readme":"# Cache Horizon:\u003cbr\u003eUse gradle build cache for a group of tasks\n\n\u003c!---freshmark shields\noutput = [\n    link(shield('Gradle plugin', 'plugins.gradle.org', 'com.diffplug.cache-horizon', 'blue'), 'https://plugins.gradle.org/plugin/com.diffplug.cache-horizon'),\n    link(shield('Maven central', 'mavencentral', 'available', 'blue'), 'https://search.maven.org/artifact/com.diffplug/cache-horizon'),\n    link(shield('Apache 2.0', 'license', 'apache-2.0', 'blue'), 'https://tldrlegal.com/license/apache-license-2.0-(apache-2.0)'),\n    '',\n    link(shield('Changelog', 'changelog', versionLast, 'brightgreen'), 'CHANGELOG.md'),\n    link(shield('Javadoc', 'javadoc', 'yes', 'brightgreen'), 'https://javadoc.io/doc/com.diffplug/cache-horizon/{{versionLast}}/index.html'),\n    link(shield('Live chat', 'gitter', 'chat', 'brightgreen'), 'https://gitter.im/diffplug/cache-horizon'),\n    link(image('JitCI', 'https://jitci.com/gh/diffplug/cache-horizon/svg'), 'https://jitci.com/gh/diffplug/cache-horizon')\n    ].join('\\n');\n--\u003e\n[![Gradle plugin](https://img.shields.io/badge/plugins.gradle.org-com.diffplug.cache--horizon-blue.svg)](https://plugins.gradle.org/plugin/com.diffplug.cache-horizon)\n[![Maven central](https://img.shields.io/badge/mavencentral-available-blue.svg)](https://search.maven.org/artifact/com.diffplug/cache-horizon)\n[![Apache 2.0](https://img.shields.io/badge/license-apache--2.0-blue.svg)](https://tldrlegal.com/license/apache-license-2.0-(apache-2.0))\n\n[![Changelog](https://img.shields.io/badge/changelog-first--ever-brightgreen.svg)](CHANGELOG.md)\n[![Javadoc](https://img.shields.io/badge/javadoc-yes-brightgreen.svg)](https://javadoc.io/doc/com.diffplug/cache-horizon/first-ever/index.html)\n[![Live chat](https://img.shields.io/badge/gitter-chat-brightgreen.svg)](https://gitter.im/diffplug/cache-horizon)\n[![JitCI](https://jitci.com/gh/diffplug/cache-horizon/svg)](https://jitci.com/gh/diffplug/cache-horizon)\n\u003c!---freshmark /shields --\u003e\n\n\u003c!---freshmark javadoc\noutput = prefixDelimiterReplace(input, 'https://javadoc.io/static/com.diffplug.gradle/image-grinder/', '/', versionLast);\n--\u003e\n\n## The problem\n\nTake the following task trees:\n\n```\n[install node] -\u003e [npm install] -+-\u003e [npm run compileSass      ] + -\u003e [npm run concatMinify]\n                                 +-\u003e [npm run compileTypescript] +\n\n[start docker] -\u003e [run command in docker] -\u003e [stop docker]\n```\n\n- the **group** of tasks can easily be defined as `f(inputs) = output_files`\n- but individually they can't, because some steps modify the environment\n    - you can't cache `start docker` ...\n- if you could somehow cache the **group**, then you could avoid not just a task, but an entire toolchain\n    - ...but you can easily cache `f(dockerfile, input_files) -\u003e output_files`\n\n## A solution\n\n```gradle\nplugins {\n    id 'com.diffplug.cache-horizon'\n}\n\ncacheHorizon {\n    add 'nodeInstall', 'npmInstall', 'compileSass', 'compileTypescript'\n    inputsAndOutputs {\n        inputs.property('nodeVersion', nodeTask.nodeVersion)\n        inputs.file('package-lock.json').withPathSensitivity(PathSensitivity.RELATIVE)\n        inputs.dir('src/main/typescript').withPathSensitivity(PathSensitivity.RELATIVE)\n        outputs.file('build/index.js')\n    }\n}\n```\n\nThis will add two tasks with the following dependency arrangement\n\n```\n                        +------------------------------+\ncacheHorizonIsCached -\u003e | nodeInstall, npmInstall, ... | -\u003e cacheHorizon\n                        +------------------------------+\n```\n\nWhen `cacheHorizonIsCached` executes, it looks forward to check if `cacheHorizon` is able to be restored from cache.  If it is, then it disables `nodeInstall`, `npmInstall`, etc.  When `cacheHorizon` eventually runs, it will just restore `index.js` from cache, avoiding all the intermediate work.\n\n**DANGER** no outside task should depend on anything within the horizon (e.g. `test` dependsOn `compileTypescript` is bad, it should instead depend on `cacheHorizon`).  It is fine if tasks within the horizon depend on anything outside the horizon (e.g. `compileTypescript` dependsOn `lintTypescript` is fine).\n\n## Multiple cache horizons in one project\n\nUsually you only need one `cacheHorizon` per project.  But if you want more, you can do this:\n\n```gradle\ncacheHorizon {\n    named 'dockerHorizon', {\n        add 'dockerStart', 'dockerRun', 'dockerStop'\n        inputsAndOutputs { ... }\n    }\n```\n\nNow you'll have `dockerHorizon` and `dockerHorizonIsCached` tasks.\n\n## Limitations 🔴This project has not been implemented🔴\n\nWe started to implement it, got stuck, and found an easier way around.  We're publishing what we did in case it helps you get to the finish line.  See [this issue](https://github.com/diffplug/cache-horizon/issues/1) for the latest on our progress.  If somebody builds something else which solves this problem we'll link out from there.\n\nCache horizon uses Gradle's internal API, so there will be compatibility delays (e.g. when Gradle N comes out, it might be a little while until `cache-horizon` has been tested and fixed for the new version).\n\n\u003c!---freshmark /javadoc --\u003e\n\n## Acknowledgements\n\n* Maintained by [DiffPlug](https://www.diffplug.com/).\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdiffplug%2Fcache-horizon","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdiffplug%2Fcache-horizon","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdiffplug%2Fcache-horizon/lists"}