This repository demonstrates a small persistent cache layer around a Task build.
Task still owns source checksums and up-to-date decisions. The task-cache
helper only handles the generated files that Task declares for the build.
- Go
- Task (
taskonPATH, orTASK_BIN=/path/to/task)
task buildBuilds bin/helloworld through the cache helper.
scripts/test-cache-behavior.shRuns the full expected behavior flow and asserts each cache state.
The build task declares:
- sources:
go.*and*.go - generated output:
bin/helloworld - command:
bin/task-cache --task build -- go build -o bin/helloworld .
The build task depends on the internal task-cache task, so Task first builds
the helper binary at bin/task-cache.
When task build runs:
- Task calculates its native checksum for the
buildtask. - Task writes that checksum under
.task/checksum/build. - Task runs
bin/task-cache --task build -- go build -o bin/helloworld .. - The helper reads
Taskfile.ymland discovers thebuild.generatesentries. - The helper reads
.task/checksum/buildand uses it as the persistent archive key. - The helper looks for
.cache/build/<task-checksum>.tar.xz.
If the archive exists, the helper restores the generated outputs from the archive and verifies that every declared generated file exists.
If the archive does not exist, the helper runs the build command after --,
verifies the generated files, and saves them into
.cache/build/<task-checksum>.tar.xz.
Archives store the generated path exactly as Task declares it. For the current build task, the archive entry is:
bin/helloworld
On restore, the helper extracts into the repository root, recreates parent directories when needed, and writes the file back to the same relative path:
bin/helloworld
There is no separate staging output directory. The restored file appears where a normal build would have created it.
scripts/test-cache-behavior.sh is the executable description of the expected
cache behavior.
It does the following:
- Resolves the Task binary from
TASK_BIN,task, or$HOME/go/bin/task. - Copies
main.goto a temporary file and restores it on exit. - Removes
.task,.cache, andbinto start from a clean local state. - Runs the first build and expects:
- no matching archive for the current Task checksum
- the Go build command to run
- one new
.cache/build/*.tar.xzarchive
- Runs the second build and expects Task's native up-to-date behavior:
Task "build" is up to date- still only one archive
- Changes
main.gofromHello, World!toHello from cache test!. - Runs the third build and expects:
- a new Task checksum
- no matching archive for that checksum
- a second archive
- Runs
./bin/helloworldand verifies the modified output. - Restores the original
main.goand removesbin/helloworld. - Runs the fourth build and expects:
- the original Task checksum to match the first archive
- generated outputs to be restored from
.cache/build/<checksum>.tar.xz - no build command needed for
bin/helloworld
- Runs
./bin/helloworldand verifies the restoredHello, World!output. - Runs one final build and expects Task's native up-to-date behavior again.
The important scenario is step 10: the source returns to a previously seen checksum while the generated binary is missing locally. The helper restores the binary from the persistent archive into the normal generated output path.
The flow uses three local directories:
.task/checksum/build: Task's native checksum state.cache/build/: persistenttar.xzarchives keyed by Task checksumbin/: generated helper and application binaries
These are build artifacts and can be removed to reset the local cache behavior.