dboss-cli 0.1.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
dboss/__init__.py ADDED
File without changes
dboss/cli.py ADDED
@@ -0,0 +1,63 @@
1
+ import sys
2
+
3
+ import click
4
+
5
+ from dboss.git_utils import GitError, commit as commit_fn, get_staged_diff
6
+ from dboss.ollama_client import OllamaError, generate, strip_code_fences
7
+ from dboss.prompts import build_commit_prompt
8
+
9
+
10
+ @click.group()
11
+ def main():
12
+ """dboss — git commit message generator."""
13
+ sys.stdout.reconfigure(encoding="utf-8", errors="replace")
14
+ sys.stderr.reconfigure(encoding="utf-8", errors="replace")
15
+
16
+
17
+ @main.command()
18
+ def hello():
19
+ """Smoke test: verify the CLI is installed correctly."""
20
+ click.echo("hello from dboss")
21
+
22
+
23
+ @main.command()
24
+ def commit():
25
+ """Generate a commit message for staged changes and commit."""
26
+ try:
27
+ diff = get_staged_diff()
28
+ except GitError as e:
29
+ raise click.ClickException(str(e))
30
+
31
+ if not diff:
32
+ click.echo("No staged changes.")
33
+ return
34
+
35
+ prompt = build_commit_prompt(diff)
36
+
37
+ while True:
38
+ try:
39
+ message = generate(prompt)
40
+ except OllamaError as e:
41
+ raise click.ClickException(str(e))
42
+
43
+ message = strip_code_fences(message)
44
+ click.echo(f"\nSuggested commit message:\n\n {message}\n")
45
+ choice = click.prompt(
46
+ "[y] accept [r] regenerate [n] cancel",
47
+ type=click.Choice(["y", "r", "n"]),
48
+ default="y",
49
+ show_choices=False,
50
+ )
51
+
52
+ if choice == "y":
53
+ try:
54
+ commit_fn(message)
55
+ except GitError as e:
56
+ raise click.ClickException(str(e))
57
+ click.echo("Commit created.")
58
+ break
59
+ elif choice == "r":
60
+ continue
61
+ else:
62
+ click.echo("Cancelled.")
63
+ break
dboss/git_utils.py ADDED
@@ -0,0 +1,41 @@
1
+ import subprocess
2
+
3
+
4
+ class GitError(Exception):
5
+ pass
6
+
7
+
8
+ def get_staged_diff() -> str:
9
+ try:
10
+ subprocess.run(
11
+ ["git", "rev-parse", "--git-dir"],
12
+ capture_output=True,
13
+ check=True,
14
+ )
15
+ except FileNotFoundError:
16
+ raise GitError("git komutu bulunamadı. Git kurulu mu?")
17
+ except subprocess.CalledProcessError:
18
+ raise GitError("Bu dizin bir git reposu değil.")
19
+
20
+ try:
21
+ result = subprocess.run(
22
+ ["git", "diff", "--staged"],
23
+ capture_output=True,
24
+ encoding="utf-8",
25
+ check=True,
26
+ )
27
+ return result.stdout
28
+ except subprocess.CalledProcessError as e:
29
+ raise GitError(f"git diff başarısız: {e.stderr.strip()}")
30
+
31
+
32
+ def commit(message: str) -> None:
33
+ try:
34
+ subprocess.run(
35
+ ["git", "commit", "-m", message],
36
+ capture_output=True,
37
+ encoding="utf-8",
38
+ check=True,
39
+ )
40
+ except subprocess.CalledProcessError as e:
41
+ raise GitError(f"git commit başarısız: {e.stderr.strip()}")
dboss/ollama_client.py ADDED
@@ -0,0 +1,37 @@
1
+ import os
2
+ import re
3
+
4
+ import requests
5
+
6
+ OLLAMA_BASE_URL = "http://localhost:11434"
7
+ DEFAULT_MODEL = os.environ.get("DBOSS_MODEL", "qwen2.5-coder:3b")
8
+
9
+
10
+ def strip_code_fences(text: str) -> str:
11
+ # Remove opening fence line: ```plaintext, ```bash, ``` etc.
12
+ text = re.sub(r"^```[^\n]*\n", "", text)
13
+ # Remove closing fence line
14
+ text = re.sub(r"\n```\s*$", "", text)
15
+ return text.strip()
16
+
17
+
18
+ class OllamaError(Exception):
19
+ pass
20
+
21
+
22
+ def generate(prompt: str, model: str = DEFAULT_MODEL) -> str:
23
+ url = f"{OLLAMA_BASE_URL}/api/generate"
24
+ payload = {"model": model, "prompt": prompt, "stream": False}
25
+ try:
26
+ resp = requests.post(url, json=payload, timeout=120)
27
+ except requests.exceptions.ConnectionError:
28
+ raise OllamaError(
29
+ "Ollama'ya bağlanılamadı. `ollama serve` çalışıyor mu? (localhost:11434)"
30
+ )
31
+ if resp.status_code == 404:
32
+ raise OllamaError(
33
+ f"Model bulunamadı: {model!r}. `ollama pull {model}` çalıştır."
34
+ )
35
+ if not resp.ok:
36
+ raise OllamaError(f"Ollama HTTP {resp.status_code}: {resp.text[:200]}")
37
+ return resp.json()["response"]
dboss/prompts.py ADDED
@@ -0,0 +1,17 @@
1
+ def build_commit_prompt(diff: str) -> str:
2
+ return (
3
+ "You are a commit message generator.\n"
4
+ "Rules:\n"
5
+ "- Use Conventional Commits format: feat:, fix:, docs:, refactor:, test:, chore:, etc.\n"
6
+ "- Write in English.\n"
7
+ "- Return ONLY the commit message. No explanation, no markdown, no quotes.\n"
8
+ "- Do NOT wrap the message in code fences or backticks.\n"
9
+ "- Do NOT add a language tag like 'plaintext'. Output raw text only.\n"
10
+ "- The first (summary) line must not exceed 72 characters.\n"
11
+ "- If needed, add a blank line after the summary, then a body.\n"
12
+ "- Output EXACTLY ONE commit message. Do NOT produce a list of multiple commit messages.\n"
13
+ "- Do NOT invent changes that are not in the diff. Only describe what the diff actually shows.\n"
14
+ "- Keep it to a single summary line, optionally followed by a blank line and a short body.\n\n"
15
+ "Git diff to summarize:\n\n"
16
+ f"{diff}"
17
+ )
@@ -0,0 +1,9 @@
1
+ Metadata-Version: 2.4
2
+ Name: dboss-cli
3
+ Version: 0.1.0
4
+ Requires-Python: >=3.12
5
+ Requires-Dist: click
6
+ Requires-Dist: requests
7
+ Provides-Extra: dev
8
+ Requires-Dist: pytest; extra == 'dev'
9
+ Requires-Dist: pytest-mock; extra == 'dev'
@@ -0,0 +1,9 @@
1
+ dboss/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
+ dboss/cli.py,sha256=z4_DrvkGI0dzdT-3jsDtjzCh_0BYpalxPHIcM4xfHlU,1681
3
+ dboss/git_utils.py,sha256=6hq--3J28wR6boIAFS2lLE7RZ21ojJzSRrXYrOjOPjc,1086
4
+ dboss/ollama_client.py,sha256=cu17K92rDhjXDCXzCkkjcbVfa4cVSZahkTyT3terX_Y,1146
5
+ dboss/prompts.py,sha256=ob4PuYWpYQEDJWrZOH1g4ztJWxeVjOtFLxRvLU2gbn8,1001
6
+ dboss_cli-0.1.0.dist-info/METADATA,sha256=QdSBS-1WlXj9ZaMCl6bIdW775KOqzgbsn0lcHfeB_mQ,223
7
+ dboss_cli-0.1.0.dist-info/WHEEL,sha256=mffPy8wBnZQn2VnJUU5jE99KsxaSfiyMHV9Yt0aLVxs,87
8
+ dboss_cli-0.1.0.dist-info/entry_points.txt,sha256=hWTF230W7GXohliNjWiUF2AvNcLBYr_TWR6Ec3tzVeI,41
9
+ dboss_cli-0.1.0.dist-info/RECORD,,
@@ -0,0 +1,4 @@
1
+ Wheel-Version: 1.0
2
+ Generator: hatchling 1.30.1
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ dboss = dboss.cli:main