cobo: copy boilerplates from configurable git repositories
cobo (short for copy boilerplates) is a command-line tool for fetching boilerplate files from configurable git repositories. It ships with five sources baked in:
gitignore— GitHub'sgithub/gitignoretemplatesgitattributes— communitygitattributes/gitattributestemplateseditorconfig—vinibrsl/editorconfig-templatesmise—mise-cookbooksconfigslicenses— SPDX license texts fromspdx/license-list-data
You can add your own sources via a single TOML config file.
cobo is the successor to micoo, which is now deprecated.
Installation
uv tool install cobo
or
pipx install cobo
or
mise install pipx:cobo
Quick start
Fetch the baked sources once:
cobo update
List boilerplates in a source:
cobo gitignore list
cobo mise list
Dump one to stdout:
cobo mise dump python > mise.local.toml
cobo gitignore dump Python Node > .gitignore
cobo gitattributes dump Python > .gitattributes
cobo editorconfig dump Python > .editorconfig
Configuration
A user config file at ~/.cobo/config.toml can override baked sources or add
new ones.
Suppose you maintain a repo of reusable Dockerfile snippets laid out like this:
example/dockerfiles (https://example.invalid/you/dockerfiles)
└── templates/
├── python.Dockerfile
├── node.Dockerfile
└── rust.Dockerfile
The matching source entry:
[sources.dockerfiles]
description = "My Dockerfile snippets"
url = "https://example.invalid/you/dockerfiles"
branch = "main"
extension = ".Dockerfile"
subpath = "templates"
multi_dump = false
inject_header = true
comment_prefix = "#"
Field semantics:
extension— suffix used to discover boilerplates. A filetemplates/python.Dockerfileis exposed as the namepython.subpath— only scan this subdirectory of the clone (omit to scan the whole repo).branch— branch to track; pin to whatever the upstream default is.multi_dump— whentrue,dumpaccepts multiple names and concatenates them (used bygitignoreandgitattributes).inject_header/comment_prefix— prepend a provenance comment block on dump using the given line prefix.
Once added, the source becomes a first-class subcommand:
cobo dockerfiles list # python, node, rust
cobo dockerfiles dump python # contents of templates/python.Dockerfile
Trust boundary. The config file is a trust boundary:
urlandbranchvalues are passed directly togit. Only add sources you trust.
Branch drift. Baked-in sources pin the upstream default branch (some
main, othersmaster). If an upstream renames its default branch, override thebranchfield in your user config until the baked default is updated.
Disposable cache. Source clones under the cache root (
cobo root/cobo <source> root) are managed bycobo update, which performsfetch+ hard reset +clean -fdx. Any local edits, untracked files, or commits inside those clones are discarded on the next update — never use the cache as a working tree.
Command reference
cobo
├── update (clone/pull all sources)
├── version
├── info
├── list-sources
├── root (cache directory path)
├── config (resolved merged config)
├── config-path (user config file path)
└── <source> (one subcommand per configured source)
├── update
├── list
├── search <term>
├── dump <name>...
├── root (this source's clone path)
└── remote (this source's git URL)
Keeping fragments up to date
cobo can track dumped boilerplates and alert you when upstream templates change — the same Dependabot/Renovate pattern applied to boilerplates.
Record a dump:
cobo gitignore dump Python Node --out .gitignore --lock
--lock writes a cobo.lock file: cobo walks up from the current working
directory for the nearest existing cobo.lock and updates it, or creates one
in the current working directory if none is found. Re-run after
cobo gitignore update to refresh the pin. (--lock requires --out.)
Already have dumped files from before the lockfile? Adopt them from their provenance headers:
cobo lock import .gitignore .editorconfig # reconstruct lock entries from headers
Check for drift:
cobo check # Rich table; exits 0 (clean), 1 (updates available), 2 (no/invalid lock)
cobo check --strict # also exit non-zero when a fragment errored (CI gate)
cobo check --json # machine-readable JSON with outdated_count, error_count, fragments
cobo check --exclude '.github/*' # skip fragments whose path matches a glob
Apply updates:
cobo sync # re-renders outdated fragments and advances cobo.lock
cobo sync --dry-run # shows changes without writing
cobo sync --exclude '.github/*' # leave matching fragments untouched
Commit the updated output files and cobo.lock together.
Hold a fragment back: set update = false in its [[fragment]] block in
cobo.lock; check and sync skip it and show it as "held".
Automate with GitHub Actions: add hasansezertasan/cobo@v0.2.0 to a weekly
workflow — it runs cobo sync and opens a PR when fragments drift. Requires
permissions: contents: write and pull-requests: write. A pre-built Docker
variant (hasansezertasan/cobo/docker@v0.2.0) is also available for faster
cold-starts. Pin to a released tag (or a commit SHA); a moving @v1 major tag
will follow the 1.0 release.
See docs/fragment-updates.md for the full guide: lockfile format, exit-code tables, provenance headers, and a ready-to-paste consuming workflow.
Author
Maintained by Hasan Sezer Taşan.
License
MIT. See LICENSE.
Metadata
Release files for cobo 0.5.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| cobo-0.5.1.tar.gz | 178.6 kB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| cobo-0.5.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 228.9 kB
Release files / cobo-0.5.1.tar.gz
| Download URL | cobo-0.5.1.tar.gz |
|---|---|
| Size | 178.6 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
cb03251ac8dfe921408c171f58fd3d2e2b560d9f10353ca57a99f4967f42fe33
|
|
BLAKE2b-256 checksum How to use checksums |
79b0c445411b1dc6671195078b5ec465ff11abc24434a2a08bf83b7f574a8c39
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.12.21 {"installer":{"name":"uv","version":"0.12.21","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Release files / cobo-0.5.1-py3-none-any.whl
| Download URL | cobo-0.5.1-py3-none-any.whl |
|---|---|
| Size | 50.3 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
3fef18a2f39da0170526d57480b8fd0d2a8afb8b236aa3935330cffdb28df6cd
|
|
BLAKE2b-256 checksum How to use checksums |
0e2c30f39b3774b9255431eb1c613e2640c0679380d1ecaf3853acf1deca4e2d
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.12.21 {"installer":{"name":"uv","version":"0.12.21","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Security for cobo 0.5.1
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.