Skip to content
kitsuyuiPublic

About

Run command with caching.

Resources

Code of conduct

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

cmd_cache

Coverage Github All Releases

Run command with caching.

When cache exists, replay by cache. When cache doesn't exist, run command and cache it.

Cache key can be generated with these way:

  • Command
  • File content (relative path and content)
  • Environment variable (name and value)
  • Text

Repeated --file, --env, and --text inputs are treated as dependency sets, so their order does not affect the cache key.

--file values must be relative paths inside the current working directory. Absolute paths and paths that escape the current working directory are rejected.

By default, cmd_cache keeps the newest 1024 complete cache entries in the cache directory and prunes older entries after each run. Set --max-cache-entries=0 to disable pruning.

Cache compatibility

New cache status files include a cmd_cache status v1 header before the exit status. Existing cache entries that contain only a numeric exit status are still accepted for backward compatibility.

Concurrent execution and locking

On Linux and macOS, cmd_cache takes an advisory file lock (flock) before running the wrapped command, so a second process racing on the same cache key waits for the first instead of re-running the command.

Windows does not support this lock. flock is not available there, so cmd_cache prints a running without lock warning to stderr and runs the wrapped command without serialization. If two processes on Windows start concurrently with the same cache key before either has written a cache entry, the wrapped command can run more than once.

If you rely on cmd_cache to prevent duplicate concurrent execution of an expensive command on Windows, serialize the invoking step externally (e.g. in your build system or CI job) rather than relying on cmd_cache's lock.

Environment variable inheritance

The cache key only includes the environment variables listed with --env. However, the wrapped command inherits the entire process environment when it runs — not just the --env variables.

This means variables like PATH, HOME, LANG, and TZ silently affect which binary is resolved and how the command behaves, even though they are not part of the cache key.

If any unlisted environment variable affects the command's output, add it with --env to include it in the cache key:

cmd_cache --env PATH --env LANG -- my-command

Shared cache directories across machines or CI environments with different PATH or locale settings can produce stale replays from a cache hit.

Working directory inheritance

The cache key does not include the current working directory (CWD). The wrapped command inherits the CWD of the cmd_cache process, but this CWD is not factored into the cache key.

This means that CWD-sensitive commands — such as ls, make, go build, or git status — can produce a cache hit across different directories. The first cached result will be replayed regardless of which directory cmd_cache was invoked from.

If the wrapped command's output depends on the CWD, include it explicitly in the cache key:

cmd_cache --text "$PWD" -- ls

This mirrors the --env pattern for environment variables: any implicit dependency on the runtime environment must be declared explicitly to get a correct cache key.

Time-dependent commands

cmd_cache does not expire entries by time. There is no TTL, --max-age, or date-based cache invalidation option. A cache hit is replayed until the command, file dependencies, selected environment variables, or --text inputs produce a different cache key, or until cache pruning removes the entry.

If the wrapped command changes output over time, include the intended time window in the cache key explicitly:

cmd_cache --text "$(date -u +%Y-%m-%d)" -- curl https://example.com/daily.json

Prefer UTC or another explicitly chosen timezone for date keys. Plain date +%Y-%m-%d uses the local timezone, so machines in different timezones can create different daily cache entries while sharing the same cache directory. If the command itself depends on local time or TZ, include that environment variable with --env TZ or encode the chosen timezone in --text.

Usage

Example

$ cmd_cache --file depedingfile.go --env GOPATH -- go build

Options

cmd_cache

Usage:
 cmd_cache [--cache-directory=DIRECTORY] [--max-cache-entries=COUNT] [(--file FILE | --env ENV | --text TEXT)...] -- COMMAND...
 cmd_cache (--help | --version)

Arguments:
 FILE      depending file under the current working directory. (e.g. prog.h)
 ENV       depending environment variable. (e.g. LD_LIBRARY_PATH)
 TEXT      text affecting command.
 COMMAND   real command.

Options:
 -h --help               						 Show this screen.
 -V --version            						 Show version.
 --cache-directory=DIRECTORY    Cache directory [default: .cmd_cache]
 --max-cache-entries=COUNT      Maximum complete cache entries to keep; 0 disables pruning [default: 1024]

Build

$ go get -d ./...
$ go build

Development

Install lefthook and register the hooks once:

$ lefthook install

After that, on every commit the following check runs automatically:

  • pre-commit: shellcheck bin/*.sh, go vet ./...

On every push the full local suite runs:

  • pre-push: shellcheck bin/*.sh, go vet ./..., go test ./...

These hooks bring CI feedback earlier. The CI workflow still runs the full suite (including -race -cover) on every PR and push to main.

LICENSE

Source

The 3-Clause BSD License. See also LICENSE file.

statically linked libraries:

About

Run command with caching.

Resources

Code of conduct

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages