Skip to content

Commit 4266942

Browse files
committed
first commit
0 parents  commit 4266942

File tree

13 files changed

+3201
-0
lines changed

13 files changed

+3201
-0
lines changed

.github/workflows/ci.yml

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
name: CI
2+
3+
on:
4+
push:
5+
branches: [main, master, develop]
6+
pull_request:
7+
branches: [main, master]
8+
9+
jobs:
10+
test:
11+
name: Python ${{ matrix.python-version }} on ${{ matrix.os }}
12+
runs-on: ${{ matrix.os }}
13+
strategy:
14+
fail-fast: false
15+
matrix:
16+
os: [ubuntu-latest, macos-latest, windows-latest]
17+
python-version: ["3.8", "3.9", "3.10", "3.11", "3.12"]
18+
19+
steps:
20+
- uses: actions/checkout@v4
21+
22+
- name: Set up Python ${{ matrix.python-version }}
23+
uses: actions/setup-python@v5
24+
with:
25+
python-version: ${{ matrix.python-version }}
26+
27+
- name: Install package (editable)
28+
run: pip install -e .
29+
30+
- name: Smoke test — import
31+
run: python -c "import git_diff; print('Version:', git_diff.__version__)"
32+
33+
- name: Smoke test — CLI version
34+
run: git-diff --version
35+
36+
- name: Smoke test — CLI help
37+
run: git-diff --help
38+
39+
- name: Functional test — git data collection
40+
run: |
41+
python -c "
42+
from git_diff.git_data import get_repo_root, collect_all_data, parse_diff
43+
root = get_repo_root('.')
44+
print('Root:', root)
45+
46+
# Test parse_diff
47+
sample = '''diff --git a/hello.py b/hello.py
48+
index abc..def 100644
49+
--- a/hello.py
50+
+++ b/hello.py
51+
@@ -1,3 +1,4 @@
52+
def hello():
53+
- print('hello')
54+
+ print('hello world')
55+
+ return True
56+
'''.replace(' ', '')
57+
result = parse_diff(sample)
58+
assert result['total_files'] == 1
59+
assert result['total_additions'] == 2
60+
assert result['total_deletions'] == 1
61+
print('parse_diff: OK')
62+
63+
# Collect full data from this repo
64+
data = collect_all_data(root)
65+
assert 'repo' in data
66+
assert 'commits' in data
67+
print('Repo:', data['repo']['name'])
68+
print('Commits:', len(data['commits']))
69+
print('Files:', len(data['file_tree']))
70+
print('All tests passed!')
71+
"
72+
73+
- name: Test server imports
74+
run: |
75+
python -c "
76+
from git_diff.server import find_free_port, GitDiffHandler
77+
port = find_free_port()
78+
print('Free port found:', port)
79+
assert 7433 <= port <= 7500
80+
print('Server imports: OK')
81+
"

.github/workflows/publish.yml

Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
name: Publish to PyPI
2+
3+
on:
4+
# Trigger manually from GitHub Actions tab (optionally bump version)
5+
workflow_dispatch:
6+
inputs:
7+
version:
8+
description: "New version to publish (e.g. 0.2.0). Leave blank to use current."
9+
required: false
10+
default: ""
11+
dry_run:
12+
description: "Dry run — build but don't publish"
13+
required: false
14+
type: boolean
15+
default: false
16+
17+
# Auto-publish when a GitHub Release is created
18+
release:
19+
types: [published]
20+
21+
permissions:
22+
contents: write
23+
id-token: write # Required for OIDC trusted publisher (no API token needed!)
24+
25+
jobs:
26+
# ──────────────────────────────────────────────────────────────────
27+
# 1. Build wheel + sdist
28+
# ──────────────────────────────────────────────────────────────────
29+
build:
30+
name: Build distribution packages
31+
runs-on: ubuntu-latest
32+
33+
outputs:
34+
version: ${{ steps.get_version.outputs.version }}
35+
36+
steps:
37+
- name: Checkout code
38+
uses: actions/checkout@v4
39+
with:
40+
fetch-depth: 0
41+
42+
- name: Set up Python 3.12
43+
uses: actions/setup-python@v5
44+
with:
45+
python-version: "3.12"
46+
47+
- name: Bump version (manual trigger with version input)
48+
if: github.event_name == 'workflow_dispatch' && github.event.inputs.version != ''
49+
env:
50+
NEW_VERSION: ${{ github.event.inputs.version }}
51+
run: |
52+
echo "Bumping version to $NEW_VERSION"
53+
sed -i "s/^version = .*/version = \"$NEW_VERSION\"/" pyproject.toml
54+
sed -i "s/__version__ = .*/__version__ = \"$NEW_VERSION\"/" git_diff/__init__.py
55+
git config user.name "github-actions[bot]"
56+
git config user.email "github-actions[bot]@users.noreply.github.com"
57+
git add pyproject.toml git_diff/__init__.py
58+
git commit -m "chore: release v$NEW_VERSION [skip ci]"
59+
git tag "v$NEW_VERSION"
60+
git push origin HEAD --tags
61+
62+
- name: Get version
63+
id: get_version
64+
run: |
65+
VERSION=$(python -c "import tomllib; print(tomllib.load(open('pyproject.toml','rb'))['project']['version'])" 2>/dev/null || \
66+
python -c "import tomli; print(tomli.load(open('pyproject.toml','rb'))['project']['version'])" 2>/dev/null || \
67+
grep '^version' pyproject.toml | head -1 | sed 's/version = "\(.*\)"/\1/')
68+
echo "version=$VERSION" >> $GITHUB_OUTPUT
69+
echo "Building version: $VERSION"
70+
71+
- name: Install build tools
72+
run: python -m pip install --upgrade pip hatchling build
73+
74+
- name: Build wheel and sdist
75+
run: python -m build
76+
77+
- name: Verify build
78+
run: |
79+
ls -lh dist/
80+
python -m pip install dist/*.whl
81+
git-diff --version
82+
python -c "import git_diff; print('Import OK:', git_diff.__version__)"
83+
84+
- name: Upload artifacts
85+
uses: actions/upload-artifact@v4
86+
with:
87+
name: dist-packages
88+
path: dist/
89+
retention-days: 7
90+
91+
# ──────────────────────────────────────────────────────────────────
92+
# 2. Publish to PyPI (skipped on dry run)
93+
# ──────────────────────────────────────────────────────────────────
94+
publish:
95+
name: Publish to PyPI
96+
needs: build
97+
runs-on: ubuntu-latest
98+
if: ${{ github.event.inputs.dry_run != 'true' }}
99+
100+
environment:
101+
name: pypi
102+
url: https://pypi.org/p/git-diff
103+
104+
permissions:
105+
id-token: write # OIDC — no username/password/token needed
106+
107+
steps:
108+
- name: Download artifacts
109+
uses: actions/download-artifact@v4
110+
with:
111+
name: dist-packages
112+
path: dist/
113+
114+
- name: Publish to PyPI via trusted publisher
115+
uses: pypa/gh-action-pypi-publish@release/v1
116+
# Zero config needed when using OIDC trusted publisher
117+
# No username, no password, no API token — just works ✅

.gitignore

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
# Python
2+
__pycache__/
3+
*.py[cod]
4+
*.pyo
5+
*.pyd
6+
*.so
7+
*.egg
8+
*.egg-info/
9+
dist/
10+
build/
11+
.eggs/
12+
.installed.cfg
13+
lib/
14+
lib64/
15+
16+
# Virtual environments
17+
.venv/
18+
venv/
19+
env/
20+
ENV/
21+
.env
22+
23+
# Testing
24+
.pytest_cache/
25+
.coverage
26+
htmlcov/
27+
.tox/
28+
.mypy_cache/
29+
.ruff_cache/
30+
31+
# IDEs
32+
.idea/
33+
.vscode/
34+
*.swp
35+
*.swo
36+
.DS_Store
37+
Thumbs.db
38+
39+
# Logs
40+
*.log

CHANGELOG.md

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
# Changelog
2+
3+
All notable changes to `git-diff` are documented here.
4+
5+
The format follows [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
6+
This project uses [Semantic Versioning](https://semver.org/).
7+
8+
---
9+
10+
## [0.1.0] — 2024-01-01
11+
12+
### 🎉 Initial release
13+
14+
#### Added
15+
- **GitHub-style diff viewer** with line numbers, `+`/`-` highlights, hunk headers
16+
- **3 themes**: Dark (GitHub dark), Light (GitHub light), AMOLED (true black)
17+
- **Repository overview** with stats cards (commits, contributors, branches, tags, size)
18+
- **Commit activity heatmap** (GitHub-calendar style, last 90 days)
19+
- **Language breakdown** with color bar chart by file extension
20+
- **Commit history** — browse up to 500 commits, click any for full diff
21+
- **Compare any two refs** — branch vs branch, SHA vs SHA, tag vs tag, any mix
22+
- **Working tree changes** — staged and unstaged diffs clearly separated
23+
- **File browser** — browse all tracked files with syntax-highlighted view
24+
- **File history** — commits that touched a specific file
25+
- **Blame view** — line-level authorship with commit hash and date
26+
- **Contributors panel** — ranked by commits with visual progress bars
27+
- **Branches & tags panel** — local/remote branches, annotated tags
28+
- **Stash viewer** — list and diff all stash entries
29+
- **Keyboard shortcuts**`Esc`, `Ctrl+R`, `Ctrl+K`, `Ctrl+\`
30+
- **REST API** — all data accessible via `/api/*` endpoints
31+
- **Zero runtime dependencies** — pure Python stdlib only
32+
- **Cross-platform** — macOS, Linux, Windows
33+
- **Python 3.8–3.13** support
34+
- **PyPI Trusted Publisher** (OIDC) workflow — no API token needed
35+
- **CI** — tests on 3 OS × 5 Python versions

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2024 Ankit Chaubey
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.

0 commit comments

Comments
 (0)