A tiny curl-ish vendoring wrapper with S3-compatible object-store caching.
Project description
vendcurl
vendcurl is a tiny curl-ish command for setup scripts and CI bootstrap code. It downloads a URL, validates the resulting file, writes a content-addressed blob into an S3-compatible object store, writes a URL manifest, and prefers that vendored blob on later runs.
It is deliberately boring: SHA-256 does the identity work; archive validators only check structure and obvious archive-path nastiness.
Install with uv
From this source tree:
uv tool install .
From a git repository once you have committed it somewhere:
uv tool install git+https://github.com/you/vendcurl
For local hacking without installing:
uv run vendcurl --help
S3-compatible configuration
You can pass options each time:
vendcurl \
--bucket my-vendor-cache \
--endpoint-url https://s3.eu-west-2.amazonaws.com \
--prefix sandbox-artifacts \
--sha256 0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef \
https://example.test/releases/tool-1.2.3.tar.gz \
vendor/tool-1.2.3.tar.gz
Or use environment variables:
export VENDCURL_BUCKET=my-vendor-cache
export VENDCURL_PREFIX=sandbox-artifacts
export VENDCURL_ENDPOINT_URL=https://s3.eu-west-2.amazonaws.com
export AWS_PROFILE=dev
vendcurl https://example.test/releases/tool-1.2.3.zip vendor/tool.zip
The supported environment variables are:
VENDCURL_BUCKETorS3_BUCKETVENDCURL_PREFIXVENDCURL_ENDPOINT_URL,AWS_ENDPOINT_URL_S3, orS3_ENDPOINT_URLVENDCURL_REGION,AWS_REGION, orAWS_DEFAULT_REGIONVENDCURL_PROFILEorAWS_PROFILEVENDCURL_RETRIESVENDCURL_TIMEOUTVENDCURL_USER_AGENT
Credentials are whatever boto3 can already find: environment variables, profiles, instance metadata, OIDC-derived credentials, and so on.
Behaviour
On the first run, vendcurl:
- Downloads the origin URL.
- Computes SHA-256 while writing the file.
- Checks
--sha256if you supplied it. - Chooses a validator from the filename/content type unless you set
--validator. - Uploads the blob to
s3://$bucket/$prefix/blobs/sha256/<first-two-hex>/<sha256>. - Writes a URL manifest to
s3://$bucket/$prefix/manifests/by-url/<sha256(url)>.json. - Atomically moves the validated file into your requested output path.
On later runs, it reads the URL manifest first, downloads the content-addressed blob from S3, re-checks SHA-256 locally, validates the file again, and only goes back to the origin if the cache entry is missing or stale.
Validators
--validator auto recognizes:
- tar archives:
.tar,.tar.gz,.tgz,.tar.xz,.txz,.tar.bz2,.tbz,.tbz2 - zip archives:
.zip,.whl,.jar - single compressed streams:
.gz,.xz,.bz2
You can force a validator with --validator tar, --validator zip, --validator gzip, --validator xz, --validator bz2, or disable structural checks with --validator none.
By default, tar and zip validation rejects archive member names that look dangerous for later extraction, such as absolute paths, Windows drive paths, and .. traversal. Use --allow-unsafe-archive-paths only for fossilized upstreams that you have inspected and deliberately trust.
Useful modes
Force origin refresh and update the manifest:
vendcurl --refresh https://example.test/tool.tar.gz vendor/tool.tar.gz
Use only the vendored copy, never the origin:
vendcurl --no-origin --sha256 "$digest" https://example.test/tool.tar.gz vendor/tool.tar.gz
Smoke-test a URL without S3:
vendcurl --no-store --validator zip https://example.test/file.zip ./file.zip
Emit machine-readable output:
vendcurl --json https://example.test/file.zip ./file.zip
Development
The unit tests are stdlib-only:
PYTHONPATH=src python -m unittest discover -s tests
If you have uv available:
uv run python -m unittest discover -s tests
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file vendcurl-0.1.0.tar.gz.
File metadata
- Download URL: vendcurl-0.1.0.tar.gz
- Upload date:
- Size: 11.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.9.21 {"installer":{"name":"uv","version":"0.9.21","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Fedora Linux","version":"43","id":"","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
97fb724797c6e46b7894a165975ea7b4306db5ea6bb3dfc6e68e298922e8a778
|
|
| MD5 |
5452ebd3b5654f3543523f789b1adea4
|
|
| BLAKE2b-256 |
2a79017eec86057ee26668a9c4338578234945b92d4fd0e983d58d66d7f51ba0
|
File details
Details for the file vendcurl-0.1.0-py3-none-any.whl.
File metadata
- Download URL: vendcurl-0.1.0-py3-none-any.whl
- Upload date:
- Size: 13.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.9.21 {"installer":{"name":"uv","version":"0.9.21","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Fedora Linux","version":"43","id":"","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0b66a3beace1395a8a624309825ab37455138c8d733f3789e52206ed9b6d6116
|
|
| MD5 |
d45ffa21ce95a1043ed6b7edd2d49433
|
|
| BLAKE2b-256 |
1d6c720067b738972bffec885650be5ee2337ad7b27e51c5b8cf6afece5f9550
|