Skip to main content

Turn git commits into content, automatically.

Project description

CommitDev CLI

The client side of CommitDev: a small Python package that lets a tagged git commit message (e.g. [post][linkedin] Added JWT auth) trigger content generation, without that tag ever ending up in your permanent git history.

What this package does

When you write a commit like:

git commit -m "[draft][linkedin][tone=technical] Added JWT authentication"

Two things happen automatically, before the commit is even finalized:

  1. The tags get stripped from the message. What actually gets saved to your repo is just Added JWT authentication — clean, no brackets.
  2. CommitDev gets told what the tags were. The tags (draft, linkedin, tone=technical) and the commit's SHA get sent to the CommitDev API, so it knows what kind of draft to generate for that commit once it later sees the (now tag-free) push on GitHub.

This only works on text that matches CommitDev's known tag vocabulary (post, draft, linkedin, tone=..., etc.) — unrelated bracketed text developers already use, like [JIRA-456] or [WIP], is left untouched.

How it works (the mechanism)

Git hooks are small scripts that git runs automatically at certain points in the commit process. This package installs two of them:

  • commit-msg — runs before the commit object exists, with the message you just typed. This is the only point where the message can still be edited, so this is where tag-stripping happens.
  • post-commit — runs right after the commit exists, so this is the only point where the final commit SHA is known. This is where the tags + SHA get reported to CommitDev.

Because these are real git hooks (not a separate command you have to remember to type), they fire no matter how you commit — terminal, VS Code, or any other git client.

The two files actually installed into .git/hooks/ aren't the Python logic itself — they're tiny shell shims:

#!/bin/sh
exec commitdev hook commit-msg "$@"

This calls back into whichever commitdev is on your PATH, so the hook always runs in the right Python environment, regardless of which python3 git happens to find. It also means the same shim works unmodified on Windows, since Git for Windows runs hooks through its bundled sh.

A fire-and-forget design choice: the API call in post-commit has a short timeout and silently swallows any network error. A slow or unreachable CommitDev server should never block or break a developer's commit.

Package layout

commitdev/
├── main.py            entry point — wires up `login`, `logout`, `whoami`, `init`,
│                      and the hidden `hook` commands the installed shims call
├── installer.py       `commitdev init` — writes the two shims into .git/hooks/
├── config.py          reads/writes ~/.commitdev/config.json (the saved auth token)
├── commands/auth.py   `login` / `logout` / `whoami` — GitHub Device Flow auth
└── hooks/
    ├── commit_msg.py  strips known tags from the commit message
    └── post_commit.py reports tags + SHA to the CommitDev API
tests/
└── test_hooks.py      automated tests for the above

What's still a placeholder

This package is the client half only — there's no real CommitDev backend yet, so two things are intentionally stubbed and marked TODO in the code:

  • GITHUB_CLIENT_ID in commands/auth.py — needs a real GitHub OAuth App (with Device Flow enabled) before commitdev login can fully work.
  • The API URLs (api.commitdev.com/...) — needs a real server before the login exchange and the post-commit report actually go anywhere.

Everything else — hook installation, tag stripping, and the local fire-and-forget reporting logic — works today, independent of the backend.

Install

pip install -e .

This installs the package and adds a commitdev command to your terminal.

Manual test (no backend needed)

This exercises everything except the actual network calls, since there's no live server yet.

# 1. Make a throwaway test repo — don't use a real project for this
mkdir test-repo && cd test-repo
git init

# 2. Install the hooks into it
commitdev init
# -> should print "commit-msg: installed." and "post-commit: installed."

# 3. Make a tagged commit
git commit --allow-empty -m "[draft][linkedin] testing this out"

# 4. Check what actually got saved
git log -1
# -> message should read "testing this out", no brackets

# 5. Confirm tags were captured for reporting
cat .git/commitdev_pending.json
# -> {"tags": ["draft", "linkedin"]}   (gets deleted after post-commit runs)

# 6. Confirm unrelated brackets are left alone
git commit --allow-empty -m "[JIRA-456] Fix login bug"
git log -1
# -> message is unchanged, [JIRA-456] still there

# 7. Confirm a re-run of init doesn't duplicate anything
commitdev init
# -> should print "already installed" for both hooks

Automated tests

pip install -e ".[dev]"
pytest

tests/test_hooks.py covers, against the real package code in a real throwaway git repo:

  • commitdev init installs both hooks, correctly, and is safe to re-run
  • known tags are stripped from the message; unrelated bracketed text isn't
  • commits with no tags are left completely untouched, no extra files created
  • post-commit never throws or blocks a commit when no one is logged in

These were also verified manually before being checked in.

Try the real auth flow

This part needs network access and a real GitHub OAuth App client ID (currently a placeholder), so it won't fully complete yet — but you can confirm the flow starts correctly:

commitdev login
# -> should print a GitHub URL + a one-time code, and open your browser

Recognized commit tags

[post] [draft] [regenerate] [schedule] · [linkedin] [x] [devto] [hashnode] · [tone=...] [length=...] · [feature] [bugfix] [refactor] [performance] [security] [docs] [test]

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

commitdev-0.1.0.tar.gz (11.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

commitdev-0.1.0-py3-none-any.whl (10.7 kB view details)

Uploaded Python 3

File details

Details for the file commitdev-0.1.0.tar.gz.

File metadata

  • Download URL: commitdev-0.1.0.tar.gz
  • Upload date:
  • Size: 11.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.6

File hashes

Hashes for commitdev-0.1.0.tar.gz
Algorithm Hash digest
SHA256 06e9e60997eb2a62d76617d427c6dd6e355c2c0e844cb5f60ab348d85750741f
MD5 b475ae7c8f05b65929cb10ade02d91ab
BLAKE2b-256 12cdf942f82753eb8a7e352872770358b25636c62354adbb03c50afc5e63b0f9

See more details on using hashes here.

File details

Details for the file commitdev-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: commitdev-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 10.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.6

File hashes

Hashes for commitdev-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 0380c05691149b8b6736c51050023f38cb6e9d512a875e22317faf9dba431693
MD5 3c83397a02298519fe8fafe7b78adc38
BLAKE2b-256 40184325d91989e892c46ae6b37bd314ceab934f4e6b36b312d62dcf1513de41

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page