Releases: prostomarkeloff/ohbin
v0.2.2
Fixes
add: move the next-section comment block past a newly appended tool
write_tool only relocated the trailing comment block — the one belonging to the following top-level section, which tomlkit parses into the physically-last tool's innermost body — when overwriting an existing tool. Appending a brand-new tool (the common ohbin add / add-gist path) left that comment stranded above the new entry and dropped the blank-line separator before the next section.
write_tool now detaches it from the current last tool and re-attaches it after the new entry on append as well.
v0.2.1
Fixes
gist: read ohbin.json via raw_url when GitHub truncates inline content
GitHub's gists API truncates the inline content of every file in a gist once any single file exceeds ~1MB. That left the tiny ohbin.json index — sitting next to a multi-MB encrypted blob — coming back empty (truncated: true, content: ""), which broke:
ohbin publish-gist --gist <id>(adding another platform to an existing gist)ohbin add-gist <gist>(resolving a gist into pyproject)
_load_index now falls back to the file's raw_url (which always serves complete bytes) whenever the inline content is truncated or empty.
ohbin 0.2.0
Encrypted private binaries via secret gists
Distribute locally-built private binaries through secret (link-gated) GitHub gists, encrypted — no public release, no committing the binary to a repo. A leaked gist link is useless without the password.
New commands
ohbin publish-gist <bin> --password PW [--platform KEY] [--gist ID]— encrypt a binary for one platform and upload it to a secret gist;--gistappends more platforms to the same gist.ohbin add-gist <url|id> [--password PW]— resolve a published gist intopyproject.toml(pins the immutable raw URL + checksums).run/whichgain--password;--pyproject-fileis now a global flag on every subcommand.
How it works
Each platform's binary is gzip → AES-256-CBC (openssl, -pbkdf2) → base64 so it survives a text-only gist; ohbin decrypts on first run and caches the result. The ciphertext is checksum-verified on download and the decrypted binary afterwards (which also catches a wrong password). Crypto shells out to the system openssl — no new Python dependency.
Notes
- Password precedence:
--password> manifestpasswordfield (no env var); reading it from the manifest warns unlesspassword_committed_ok = true. - Mutating commands (
add/add-gist) write only to./pyproject.tomlor--pyproject-file, never walking up the tree. Every manifest-touching command prints the resolved pyproject realpath. - Requires
opensslon PATH on the consuming machine. POSIX-only at runtime.
Full diff: v0.1.1...v0.2.0
ohbin 0.1.1
Fixes
ohbin addno longer eats the comment block before the next section.
When overwriting an existing[tool.ohbin.tools.<name>](e.g. a version
bump), standalone comments and the blank-line separator that precede the
following section header are now preserved. Previously tomlkit attributed
them to the tool's innermost sub-table and the rebuild-and-replace dropped
them. (#1)
Full test coverage added in tests/test_add.py.
ohbin 0.1.0
Declarative GitHub-release binaries for uv projects. Declare native CLI tools in pyproject.toml; ohbin downloads them on first use, SHA256-verifies against pinned hashes, caches per host, and execs them. One dev-dependency, any number of tools — no per-tool wrapper packages to copy between repos.
Install
[dependency-groups]
dev = ["ohbin"]
[tool.uv.sources]
ohbin = { git = "https://github.com/prostomarkeloff/ohbin.git", tag = "v0.1.0" }Highlights
ohbin add owner/repo— resolves a GitHub release, matches one asset per platform (linux/darwin × x86_64/arm64), pins each SHA256 (APIdigest, else download+hash), and writes[tool.ohbin.tools.*]into your pyproject (comments preserved via tomlkit).ohbin run <tool> -- <args>— download-on-first-use, thenexecv(signals/exit codes forward transparently). Pluswhich/list, and an in-processensure()API.- Resilient — retry-with-backoff on transient network / timeout / 5xx / rate-limit / truncated-stream failures; a clean 404 is never mistaken for a transient error.
- Integrity — every download SHA256-checked before extraction; atomic install under
flock(safe under parallel CI).
Notes
- POSIX only (uses
fcntl.flock). - Requires Python ≥ 3.11.