gitforge-cli 0.1.0__tar.gz

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.
@@ -0,0 +1,22 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 shazeus
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
22
+
@@ -0,0 +1,130 @@
1
+ Metadata-Version: 2.4
2
+ Name: gitforge-cli
3
+ Version: 0.1.0
4
+ Summary: A practical Git workflow automation tool for branches, snapshots, releases, and repository hygiene.
5
+ Author-email: shazeus <efeborazan07@gmail.com>
6
+ License-Expression: MIT
7
+ Project-URL: Homepage, https://github.com/shazeus/gitforge-cli
8
+ Project-URL: Repository, https://github.com/shazeus/gitforge-cli
9
+ Project-URL: Issues, https://github.com/shazeus/gitforge-cli/issues
10
+ Keywords: git,cli,workflow,automation,release,changelog
11
+ Classifier: Development Status :: 4 - Beta
12
+ Classifier: Environment :: Console
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: Operating System :: OS Independent
15
+ Classifier: Programming Language :: Python :: 3
16
+ Classifier: Programming Language :: Python :: 3.9
17
+ Classifier: Programming Language :: Python :: 3.10
18
+ Classifier: Programming Language :: Python :: 3.11
19
+ Classifier: Programming Language :: Python :: 3.12
20
+ Classifier: Programming Language :: Python :: 3.13
21
+ Classifier: Topic :: Software Development :: Version Control :: Git
22
+ Classifier: Topic :: Utilities
23
+ Requires-Python: >=3.9
24
+ Description-Content-Type: text/markdown
25
+ License-File: LICENSE
26
+ Requires-Dist: click>=8.1
27
+ Requires-Dist: rich>=13.7
28
+ Provides-Extra: dev
29
+ Requires-Dist: pytest>=8.0; extra == "dev"
30
+ Dynamic: license-file
31
+
32
+ <p align="center">
33
+ <h1 align="center">GitForge</h1>
34
+ <p align="center">Practical Git workflow automation for branches, snapshots, releases, and repository hygiene.</p>
35
+ <p align="center">
36
+ <a href="https://pypi.org/project/gitforge-cli/"><img alt="PyPI" src="https://img.shields.io/pypi/v/gitforge-cli.svg"></a>
37
+ <a href="https://pypi.org/project/gitforge-cli/"><img alt="Python" src="https://img.shields.io/pypi/pyversions/gitforge-cli.svg"></a>
38
+ <a href="https://github.com/shazeus/gitforge-cli/blob/main/LICENSE"><img alt="License" src="https://img.shields.io/github/license/shazeus/gitforge-cli.svg"></a>
39
+ <a href="https://github.com/shazeus/gitforge-cli/stargazers"><img alt="Stars" src="https://img.shields.io/github/stars/shazeus/gitforge-cli.svg?style=social"></a>
40
+ </p>
41
+ </p>
42
+
43
+ ---
44
+
45
+ GitForge is a terminal-first Git workflow assistant for developers who want repeatable branch naming, safer commits, fast repository health checks, release tags, changelogs, branch cleanup, and ref comparisons without memorizing a pile of shell snippets. It uses the real Git executable, prints clean Rich tables, and keeps every operation explicit so it fits normal local and CI workflows.
46
+
47
+ - **Repository health checks** - inspect branch, upstream, dirty state, remotes, conflicts, and local Git identity.
48
+ - **Branch automation** - turn ticket titles into consistent branch names and optionally switch to them.
49
+ - **Snapshot commits** - stage tracked or all files, commit with guardrails, and optionally push.
50
+ - **Release tagging** - create annotated semantic-version tags with dirty-tree protection.
51
+ - **Changelog generation** - group commit history into Markdown or JSON output.
52
+ - **Cleanup and compare tools** - remove merged branches safely and summarize ref differences.
53
+
54
+ ## Installation
55
+
56
+ ```bash
57
+ pip install gitforge-cli
58
+ ```
59
+
60
+ The installed console command is:
61
+
62
+ ```bash
63
+ gitforge --help
64
+ ```
65
+
66
+ ## Usage
67
+
68
+ Inspect a repository:
69
+
70
+ ```bash
71
+ gitforge status --repo .
72
+ gitforge doctor --repo .
73
+ ```
74
+
75
+ Create a workflow branch:
76
+
77
+ ```bash
78
+ gitforge branch "Add OAuth callback validation" --ticket AUTH-42 --prefix feature
79
+ ```
80
+
81
+ Commit a snapshot:
82
+
83
+ ```bash
84
+ gitforge snapshot -m "Implement OAuth callback validation"
85
+ ```
86
+
87
+ Generate a changelog:
88
+
89
+ ```bash
90
+ gitforge changelog --since v0.1.0 --output CHANGELOG.md
91
+ ```
92
+
93
+ Create a release tag:
94
+
95
+ ```bash
96
+ gitforge release 1.2.0 --push
97
+ ```
98
+
99
+ ## Commands
100
+
101
+ | Command | Description | Example |
102
+ | --- | --- | --- |
103
+ | `gitforge status` | Show branch, upstream, dirty state, remote, and last tag. | `gitforge status --json` |
104
+ | `gitforge doctor` | Check Git availability, repo state, identity, remote, upstream, and conflicts. | `gitforge doctor` |
105
+ | `gitforge branch <title>` | Create a normalized branch name from a ticket/title. | `gitforge branch "Fix login" --ticket WEB-7` |
106
+ | `gitforge snapshot` | Stage changes and commit with safety checks. | `gitforge snapshot -m "Fix login"` |
107
+ | `gitforge sync` | Fetch, pull with rebase or merge, and optionally push. | `gitforge sync --autostash` |
108
+ | `gitforge release <version>` | Create an annotated release tag. | `gitforge release 1.0.0` |
109
+ | `gitforge changelog` | Render commit history as grouped Markdown or JSON. | `gitforge changelog --max-count 25` |
110
+ | `gitforge compare <base> [head]` | Compare two refs by unique commits and changed files. | `gitforge compare main HEAD` |
111
+ | `gitforge cleanup` | List or delete merged local branches. | `gitforge cleanup --apply` |
112
+ | `gitforge ignore` | Append built-in `.gitignore` templates. | `gitforge ignore python macos` |
113
+
114
+ ## Configuration
115
+
116
+ GitForge intentionally uses standard Git configuration instead of its own config file.
117
+
118
+ ```bash
119
+ git config user.name "Your Name"
120
+ git config user.email "you@example.com"
121
+ git remote add origin git@github.com:you/project.git
122
+ git branch --set-upstream-to origin/main main
123
+ ```
124
+
125
+ Most commands accept `--repo` so they can operate on another checkout without changing directories.
126
+
127
+ ## License
128
+
129
+ MIT License. See [LICENSE](LICENSE).
130
+
@@ -0,0 +1,99 @@
1
+ <p align="center">
2
+ <h1 align="center">GitForge</h1>
3
+ <p align="center">Practical Git workflow automation for branches, snapshots, releases, and repository hygiene.</p>
4
+ <p align="center">
5
+ <a href="https://pypi.org/project/gitforge-cli/"><img alt="PyPI" src="https://img.shields.io/pypi/v/gitforge-cli.svg"></a>
6
+ <a href="https://pypi.org/project/gitforge-cli/"><img alt="Python" src="https://img.shields.io/pypi/pyversions/gitforge-cli.svg"></a>
7
+ <a href="https://github.com/shazeus/gitforge-cli/blob/main/LICENSE"><img alt="License" src="https://img.shields.io/github/license/shazeus/gitforge-cli.svg"></a>
8
+ <a href="https://github.com/shazeus/gitforge-cli/stargazers"><img alt="Stars" src="https://img.shields.io/github/stars/shazeus/gitforge-cli.svg?style=social"></a>
9
+ </p>
10
+ </p>
11
+
12
+ ---
13
+
14
+ GitForge is a terminal-first Git workflow assistant for developers who want repeatable branch naming, safer commits, fast repository health checks, release tags, changelogs, branch cleanup, and ref comparisons without memorizing a pile of shell snippets. It uses the real Git executable, prints clean Rich tables, and keeps every operation explicit so it fits normal local and CI workflows.
15
+
16
+ - **Repository health checks** - inspect branch, upstream, dirty state, remotes, conflicts, and local Git identity.
17
+ - **Branch automation** - turn ticket titles into consistent branch names and optionally switch to them.
18
+ - **Snapshot commits** - stage tracked or all files, commit with guardrails, and optionally push.
19
+ - **Release tagging** - create annotated semantic-version tags with dirty-tree protection.
20
+ - **Changelog generation** - group commit history into Markdown or JSON output.
21
+ - **Cleanup and compare tools** - remove merged branches safely and summarize ref differences.
22
+
23
+ ## Installation
24
+
25
+ ```bash
26
+ pip install gitforge-cli
27
+ ```
28
+
29
+ The installed console command is:
30
+
31
+ ```bash
32
+ gitforge --help
33
+ ```
34
+
35
+ ## Usage
36
+
37
+ Inspect a repository:
38
+
39
+ ```bash
40
+ gitforge status --repo .
41
+ gitforge doctor --repo .
42
+ ```
43
+
44
+ Create a workflow branch:
45
+
46
+ ```bash
47
+ gitforge branch "Add OAuth callback validation" --ticket AUTH-42 --prefix feature
48
+ ```
49
+
50
+ Commit a snapshot:
51
+
52
+ ```bash
53
+ gitforge snapshot -m "Implement OAuth callback validation"
54
+ ```
55
+
56
+ Generate a changelog:
57
+
58
+ ```bash
59
+ gitforge changelog --since v0.1.0 --output CHANGELOG.md
60
+ ```
61
+
62
+ Create a release tag:
63
+
64
+ ```bash
65
+ gitforge release 1.2.0 --push
66
+ ```
67
+
68
+ ## Commands
69
+
70
+ | Command | Description | Example |
71
+ | --- | --- | --- |
72
+ | `gitforge status` | Show branch, upstream, dirty state, remote, and last tag. | `gitforge status --json` |
73
+ | `gitforge doctor` | Check Git availability, repo state, identity, remote, upstream, and conflicts. | `gitforge doctor` |
74
+ | `gitforge branch <title>` | Create a normalized branch name from a ticket/title. | `gitforge branch "Fix login" --ticket WEB-7` |
75
+ | `gitforge snapshot` | Stage changes and commit with safety checks. | `gitforge snapshot -m "Fix login"` |
76
+ | `gitforge sync` | Fetch, pull with rebase or merge, and optionally push. | `gitforge sync --autostash` |
77
+ | `gitforge release <version>` | Create an annotated release tag. | `gitforge release 1.0.0` |
78
+ | `gitforge changelog` | Render commit history as grouped Markdown or JSON. | `gitforge changelog --max-count 25` |
79
+ | `gitforge compare <base> [head]` | Compare two refs by unique commits and changed files. | `gitforge compare main HEAD` |
80
+ | `gitforge cleanup` | List or delete merged local branches. | `gitforge cleanup --apply` |
81
+ | `gitforge ignore` | Append built-in `.gitignore` templates. | `gitforge ignore python macos` |
82
+
83
+ ## Configuration
84
+
85
+ GitForge intentionally uses standard Git configuration instead of its own config file.
86
+
87
+ ```bash
88
+ git config user.name "Your Name"
89
+ git config user.email "you@example.com"
90
+ git remote add origin git@github.com:you/project.git
91
+ git branch --set-upstream-to origin/main main
92
+ ```
93
+
94
+ Most commands accept `--repo` so they can operate on another checkout without changing directories.
95
+
96
+ ## License
97
+
98
+ MIT License. See [LICENSE](LICENSE).
99
+
@@ -0,0 +1,4 @@
1
+ """GitForge package metadata."""
2
+
3
+ __version__ = "0.1.0"
4
+
@@ -0,0 +1,8 @@
1
+ """Run GitForge with ``python -m gitforge``."""
2
+
3
+ from .cli import main
4
+
5
+
6
+ if __name__ == "__main__":
7
+ main()
8
+
@@ -0,0 +1,101 @@
1
+ """Changelog extraction and rendering."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from dataclasses import asdict, dataclass
6
+ from pathlib import Path
7
+
8
+ from .git import git_text
9
+
10
+
11
+ @dataclass(frozen=True)
12
+ class CommitEntry:
13
+ """A Git commit prepared for display."""
14
+
15
+ full_hash: str
16
+ short_hash: str
17
+ subject: str
18
+ author: str
19
+ date: str
20
+ group: str
21
+
22
+ def as_dict(self) -> dict[str, str]:
23
+ return asdict(self)
24
+
25
+
26
+ GROUP_LABELS = {
27
+ "feat": "Features",
28
+ "fix": "Fixes",
29
+ "docs": "Documentation",
30
+ "test": "Tests",
31
+ "perf": "Performance",
32
+ "refactor": "Refactors",
33
+ "build": "Build",
34
+ "ci": "CI",
35
+ "other": "Other",
36
+ }
37
+
38
+
39
+ def classify_subject(subject: str) -> str:
40
+ """Classify a commit using conventional-commit style prefixes."""
41
+
42
+ prefix = subject.split(":", 1)[0].lower()
43
+ prefix = prefix.split("(", 1)[0]
44
+ return prefix if prefix in GROUP_LABELS else "other"
45
+
46
+
47
+ def load_commits(
48
+ repo: str | Path,
49
+ *,
50
+ rev_range: str | None = None,
51
+ max_count: int = 100,
52
+ ) -> list[CommitEntry]:
53
+ """Load commits from git log."""
54
+
55
+ pretty = "%H%x1f%h%x1f%s%x1f%an%x1f%ad%x1e"
56
+ args = ["log", f"--max-count={max_count}", "--date=short", f"--pretty=format:{pretty}"]
57
+ if rev_range:
58
+ args.insert(1, rev_range)
59
+ output = git_text(args, repo)
60
+ commits: list[CommitEntry] = []
61
+ for record in output.split("\x1e"):
62
+ record = record.strip()
63
+ if not record:
64
+ continue
65
+ parts = record.split("\x1f")
66
+ if len(parts) != 5:
67
+ continue
68
+ full_hash, short_hash, subject, author, date = parts
69
+ commits.append(
70
+ CommitEntry(
71
+ full_hash=full_hash,
72
+ short_hash=short_hash,
73
+ subject=subject,
74
+ author=author,
75
+ date=date,
76
+ group=classify_subject(subject),
77
+ )
78
+ )
79
+ return commits
80
+
81
+
82
+ def render_markdown(commits: list[CommitEntry], title: str = "Changelog") -> str:
83
+ """Render commits as grouped Markdown."""
84
+
85
+ if not commits:
86
+ return f"## {title}\n\nNo commits found for the selected range.\n"
87
+
88
+ lines = [f"## {title}", ""]
89
+ for group, label in GROUP_LABELS.items():
90
+ group_commits = [commit for commit in commits if commit.group == group]
91
+ if not group_commits:
92
+ continue
93
+ lines.append(f"### {label}")
94
+ for commit in group_commits:
95
+ lines.append(
96
+ f"- `{commit.short_hash}` {commit.subject} "
97
+ f"({commit.author}, {commit.date})"
98
+ )
99
+ lines.append("")
100
+ return "\n".join(lines).rstrip() + "\n"
101
+