git2svn 0.4.0__tar.gz → 0.4.1__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.
- git2svn-0.4.1/.githooks/pre-commit +34 -0
- git2svn-0.4.1/.github/dependabot.yml +41 -0
- git2svn-0.4.1/.github/workflows/ci.yml +88 -0
- git2svn-0.4.1/.github/workflows/release.yml +189 -0
- git2svn-0.4.1/.gitignore +13 -0
- git2svn-0.4.1/.pre-commit-config.yaml +9 -0
- git2svn-0.4.1/CONTRIBUTING.md +90 -0
- {git2svn-0.4.0 → git2svn-0.4.1}/PKG-INFO +2 -1
- git2svn-0.4.1/docs/arc42/README.md +229 -0
- git2svn-0.4.1/docs/arc42/adrs.md +75 -0
- git2svn-0.4.1/docs/arc42/concepts.md +56 -0
- git2svn-0.4.1/docs/req42.md +108 -0
- git2svn-0.4.1/docs/user-guide/README.md +64 -0
- git2svn-0.4.1/docs/user-guide/commands.md +169 -0
- git2svn-0.4.1/docs/user-guide/integration-workflow.md +159 -0
- git2svn-0.4.1/docs/user-guide/troubleshooting.md +55 -0
- {git2svn-0.4.0 → git2svn-0.4.1}/git2svn/__init__.py +4 -1
- git2svn-0.4.1/git2svn/_version.py +24 -0
- {git2svn-0.4.0 → git2svn-0.4.1}/git2svn/cli.py +9 -4
- {git2svn-0.4.0 → git2svn-0.4.1}/git2svn.egg-info/PKG-INFO +2 -1
- git2svn-0.4.1/git2svn.egg-info/SOURCES.txt +38 -0
- {git2svn-0.4.0 → git2svn-0.4.1}/git2svn.egg-info/requires.txt +1 -0
- git2svn-0.4.1/git2svn.egg-info/scm_file_list.json +34 -0
- git2svn-0.4.1/git2svn.py +14 -0
- {git2svn-0.4.0 → git2svn-0.4.1}/pyproject.toml +9 -2
- git2svn-0.4.0/git2svn.egg-info/SOURCES.txt +0 -20
- {git2svn-0.4.0 → git2svn-0.4.1}/LICENSE.md +0 -0
- {git2svn-0.4.0 → git2svn-0.4.1}/README.md +0 -0
- {git2svn-0.4.0 → git2svn-0.4.1}/git2svn/__main__.py +0 -0
- {git2svn-0.4.0 → git2svn-0.4.1}/git2svn/core.py +0 -0
- {git2svn-0.4.0 → git2svn-0.4.1}/git2svn/eol.py +0 -0
- {git2svn-0.4.0 → git2svn-0.4.1}/git2svn/git.py +0 -0
- {git2svn-0.4.0 → git2svn-0.4.1}/git2svn/patcher.py +0 -0
- {git2svn-0.4.0 → git2svn-0.4.1}/git2svn/state.py +0 -0
- {git2svn-0.4.0 → git2svn-0.4.1}/git2svn/svn.py +0 -0
- {git2svn-0.4.0 → git2svn-0.4.1}/git2svn.egg-info/dependency_links.txt +0 -0
- {git2svn-0.4.0 → git2svn-0.4.1}/git2svn.egg-info/entry_points.txt +0 -0
- {git2svn-0.4.0 → git2svn-0.4.1}/git2svn.egg-info/top_level.txt +0 -0
- {git2svn-0.4.0 → git2svn-0.4.1}/setup.cfg +0 -0
- {git2svn-0.4.0 → git2svn-0.4.1}/tests/test_e2e.py +0 -0
- {git2svn-0.4.0 → git2svn-0.4.1}/tests/test_git2svn.py +0 -0
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Git pre-commit hook to enforce code formatting and linting via ruff
|
|
3
|
+
|
|
4
|
+
set -e
|
|
5
|
+
|
|
6
|
+
# Check if currently on 'trunk' branch and ensure no merge commits are being created
|
|
7
|
+
CURRENT_BRANCH=$(git symbolic-ref --short HEAD 2>/dev/null || true)
|
|
8
|
+
if [ "$CURRENT_BRANCH" = "trunk" ]; then
|
|
9
|
+
if [ -f .git/MERGE_HEAD ]; then
|
|
10
|
+
echo "[git2svn pre-commit hook] ERROR: Merge commits are not permitted on 'trunk'." >&2
|
|
11
|
+
echo "[git2svn pre-commit hook] git2svn replay requires a strictly linear history." >&2
|
|
12
|
+
echo "[git2svn pre-commit hook] Please rebase your feature branch and use fast-forward: 'git merge --ff-only <branch>'" >&2
|
|
13
|
+
exit 1
|
|
14
|
+
fi
|
|
15
|
+
fi
|
|
16
|
+
|
|
17
|
+
# Check if ruff is available
|
|
18
|
+
if command -v ruff >/dev/null 2>&1; then
|
|
19
|
+
RUFF_CMD="ruff"
|
|
20
|
+
elif python3 -m ruff --version >/dev/null 2>&1; then
|
|
21
|
+
RUFF_CMD="python3 -m ruff"
|
|
22
|
+
else
|
|
23
|
+
echo "[git2svn pre-commit hook] WARNING: 'ruff' not found in PATH or python environment. Skipping formatting checks."
|
|
24
|
+
exit 0
|
|
25
|
+
fi
|
|
26
|
+
|
|
27
|
+
echo "[git2svn pre-commit hook] Checking code formatting..."
|
|
28
|
+
$RUFF_CMD format --check .
|
|
29
|
+
|
|
30
|
+
echo "[git2svn pre-commit hook] Checking code linting..."
|
|
31
|
+
$RUFF_CMD check .
|
|
32
|
+
|
|
33
|
+
echo "[git2svn pre-commit hook] All checks passed!"
|
|
34
|
+
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
version: 2
|
|
2
|
+
updates:
|
|
3
|
+
# Maintain Python dev dependencies in pyproject.toml
|
|
4
|
+
- package-ecosystem: "pip"
|
|
5
|
+
directory: "/"
|
|
6
|
+
schedule:
|
|
7
|
+
interval: "weekly"
|
|
8
|
+
day: "monday"
|
|
9
|
+
time: "08:00"
|
|
10
|
+
timezone: "Europe/Zurich"
|
|
11
|
+
open-pull-requests-limit: 5
|
|
12
|
+
labels:
|
|
13
|
+
- "dependencies"
|
|
14
|
+
- "python"
|
|
15
|
+
groups:
|
|
16
|
+
pip-minor-patch:
|
|
17
|
+
patterns:
|
|
18
|
+
- "*"
|
|
19
|
+
update-types:
|
|
20
|
+
- "minor"
|
|
21
|
+
- "patch"
|
|
22
|
+
|
|
23
|
+
# Maintain GitHub Actions dependencies
|
|
24
|
+
- package-ecosystem: "github-actions"
|
|
25
|
+
directory: "/"
|
|
26
|
+
schedule:
|
|
27
|
+
interval: "weekly"
|
|
28
|
+
day: "monday"
|
|
29
|
+
time: "08:00"
|
|
30
|
+
timezone: "Europe/Zurich"
|
|
31
|
+
open-pull-requests-limit: 5
|
|
32
|
+
labels:
|
|
33
|
+
- "dependencies"
|
|
34
|
+
- "github-actions"
|
|
35
|
+
groups:
|
|
36
|
+
actions-minor-patch:
|
|
37
|
+
patterns:
|
|
38
|
+
- "*"
|
|
39
|
+
update-types:
|
|
40
|
+
- "minor"
|
|
41
|
+
- "patch"
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [ "main" ]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [ "main" ]
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
lint-and-format:
|
|
11
|
+
name: Lint & Format (Ruff)
|
|
12
|
+
runs-on: ubuntu-latest
|
|
13
|
+
steps:
|
|
14
|
+
- name: Check out repository
|
|
15
|
+
uses: actions/checkout@v7
|
|
16
|
+
|
|
17
|
+
- name: Set up Python
|
|
18
|
+
uses: actions/setup-python@v7
|
|
19
|
+
with:
|
|
20
|
+
python-version: "3.12"
|
|
21
|
+
|
|
22
|
+
- name: Install Ruff
|
|
23
|
+
run: pip install ruff
|
|
24
|
+
|
|
25
|
+
- name: Run Ruff Lint Checks
|
|
26
|
+
run: ruff check .
|
|
27
|
+
|
|
28
|
+
- name: Verify Formatting with Ruff
|
|
29
|
+
run: ruff format --check .
|
|
30
|
+
|
|
31
|
+
test:
|
|
32
|
+
name: Test on Python ${{ matrix.python-version }} (${{ matrix.os }})
|
|
33
|
+
runs-on: ${{ matrix.os }}
|
|
34
|
+
strategy:
|
|
35
|
+
fail-fast: false
|
|
36
|
+
matrix:
|
|
37
|
+
os: [ubuntu-latest, windows-latest, macos-latest]
|
|
38
|
+
python-version: ["3.11", "3.12", "3.13"]
|
|
39
|
+
|
|
40
|
+
steps:
|
|
41
|
+
- name: Check out repository
|
|
42
|
+
uses: actions/checkout@v7
|
|
43
|
+
|
|
44
|
+
- name: Set up Python ${{ matrix.python-version }}
|
|
45
|
+
uses: actions/setup-python@v7
|
|
46
|
+
with:
|
|
47
|
+
python-version: ${{ matrix.python-version }}
|
|
48
|
+
|
|
49
|
+
- name: Install Subversion (Linux)
|
|
50
|
+
if: runner.os == 'Linux'
|
|
51
|
+
run: |
|
|
52
|
+
sudo apt-get update
|
|
53
|
+
sudo apt-get install -y subversion git
|
|
54
|
+
|
|
55
|
+
- name: Install Subversion (macOS)
|
|
56
|
+
if: runner.os == 'macOS'
|
|
57
|
+
run: |
|
|
58
|
+
brew install subversion git
|
|
59
|
+
|
|
60
|
+
- name: Install Subversion (Windows)
|
|
61
|
+
if: runner.os == 'Windows'
|
|
62
|
+
run: |
|
|
63
|
+
choco install tortoisesvn -y --params:"/NoRestart"
|
|
64
|
+
# Add TortoiseSVN CLI tools to PATH if present
|
|
65
|
+
echo "C:\Program Files\TortoiseSVN\bin" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
|
|
66
|
+
|
|
67
|
+
- name: Install Dependencies
|
|
68
|
+
run: pip install -e .[dev]
|
|
69
|
+
|
|
70
|
+
- name: Run Unit & Integration Tests (with Coverage)
|
|
71
|
+
if: runner.os == 'Linux' && matrix.python-version == '3.12'
|
|
72
|
+
run: |
|
|
73
|
+
coverage run -m unittest discover tests
|
|
74
|
+
coverage xml
|
|
75
|
+
|
|
76
|
+
- name: Run Unit & Integration Tests
|
|
77
|
+
if: runner.os != 'Linux' || matrix.python-version != '3.12'
|
|
78
|
+
run: python -m unittest discover tests
|
|
79
|
+
|
|
80
|
+
- name: Upload Coverage to Codecov
|
|
81
|
+
if: runner.os == 'Linux' && matrix.python-version == '3.12'
|
|
82
|
+
uses: codecov/codecov-action@v7
|
|
83
|
+
with:
|
|
84
|
+
token: ${{ secrets.CODECOV_TOKEN }}
|
|
85
|
+
files: coverage.xml
|
|
86
|
+
flags: unittests
|
|
87
|
+
fail_ci_if_error: false
|
|
88
|
+
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
name: Release Pipeline
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
tags:
|
|
6
|
+
- 'v*'
|
|
7
|
+
workflow_dispatch:
|
|
8
|
+
inputs:
|
|
9
|
+
bump:
|
|
10
|
+
description: 'Semantic Version Bump'
|
|
11
|
+
required: true
|
|
12
|
+
default: 'patch'
|
|
13
|
+
type: choice
|
|
14
|
+
options:
|
|
15
|
+
- patch
|
|
16
|
+
- minor
|
|
17
|
+
- major
|
|
18
|
+
- custom
|
|
19
|
+
custom_version:
|
|
20
|
+
description: 'Custom Version (only if "custom" selected above, e.g. v0.3.1)'
|
|
21
|
+
required: false
|
|
22
|
+
default: ''
|
|
23
|
+
|
|
24
|
+
permissions:
|
|
25
|
+
contents: write
|
|
26
|
+
id-token: write # Required for PyPI Trusted Publishing (OIDC)
|
|
27
|
+
|
|
28
|
+
jobs:
|
|
29
|
+
tag-release:
|
|
30
|
+
runs-on: ubuntu-latest
|
|
31
|
+
outputs:
|
|
32
|
+
tag: ${{ steps.resolve_tag.outputs.tag }}
|
|
33
|
+
steps:
|
|
34
|
+
- name: Checkout Code
|
|
35
|
+
uses: actions/checkout@v4
|
|
36
|
+
with:
|
|
37
|
+
fetch-depth: 0
|
|
38
|
+
|
|
39
|
+
- name: Resolve Release Tag
|
|
40
|
+
id: resolve_tag
|
|
41
|
+
shell: bash
|
|
42
|
+
run: |
|
|
43
|
+
if [ "${{ github.event_name }}" = "push" ]; then
|
|
44
|
+
TAG="${{ github.ref_name }}"
|
|
45
|
+
echo "Triggered by tag push: $TAG"
|
|
46
|
+
else
|
|
47
|
+
# Triggered via workflow_dispatch button -> compute next semver
|
|
48
|
+
LATEST_TAG=$(git tag --sort=-v:refname | grep -E '^v?[0-9]+\.[0-9]+\.[0-9]+$' | head -n 1 || true)
|
|
49
|
+
if [ -z "$LATEST_TAG" ]; then
|
|
50
|
+
LATEST_TAG="v0.3.0"
|
|
51
|
+
fi
|
|
52
|
+
echo "Latest stable tag: $LATEST_TAG"
|
|
53
|
+
|
|
54
|
+
RAW_VER="${LATEST_TAG#v}"
|
|
55
|
+
IFS='.' read -r MAJOR MINOR PATCH <<< "$RAW_VER"
|
|
56
|
+
|
|
57
|
+
BUMP="${{ github.event.inputs.bump }}"
|
|
58
|
+
CUSTOM="${{ github.event.inputs.custom_version }}"
|
|
59
|
+
|
|
60
|
+
if [ "$BUMP" = "patch" ]; then
|
|
61
|
+
TAG="v${MAJOR}.${MINOR}.$((PATCH + 1))"
|
|
62
|
+
elif [ "$BUMP" = "minor" ]; then
|
|
63
|
+
TAG="v${MAJOR}.$((MINOR + 1)).0"
|
|
64
|
+
elif [ "$BUMP" = "major" ]; then
|
|
65
|
+
TAG="v$((MAJOR + 1)).0.0"
|
|
66
|
+
elif [ "$BUMP" = "custom" ]; then
|
|
67
|
+
if [ -z "$CUSTOM" ]; then
|
|
68
|
+
echo "Error: custom_version cannot be empty when bump=custom" >&2
|
|
69
|
+
exit 1
|
|
70
|
+
fi
|
|
71
|
+
if [[ ! "$CUSTOM" =~ ^v ]]; then
|
|
72
|
+
TAG="v${CUSTOM}"
|
|
73
|
+
else
|
|
74
|
+
TAG="${CUSTOM}"
|
|
75
|
+
fi
|
|
76
|
+
fi
|
|
77
|
+
|
|
78
|
+
echo "Computed new tag: $TAG"
|
|
79
|
+
git config user.name "github-actions[bot]"
|
|
80
|
+
git config user.email "github-actions[bot]@users.noreply.github.com"
|
|
81
|
+
git tag -a "$TAG" -m "Release $TAG"
|
|
82
|
+
git push origin "$TAG"
|
|
83
|
+
fi
|
|
84
|
+
|
|
85
|
+
echo "tag=$TAG" >> "$GITHUB_OUTPUT"
|
|
86
|
+
|
|
87
|
+
build-and-publish:
|
|
88
|
+
needs: tag-release
|
|
89
|
+
runs-on: ubuntu-latest
|
|
90
|
+
steps:
|
|
91
|
+
- name: Checkout Code
|
|
92
|
+
uses: actions/checkout@v4
|
|
93
|
+
with:
|
|
94
|
+
fetch-depth: 0
|
|
95
|
+
ref: ${{ needs.tag-release.outputs.tag }}
|
|
96
|
+
|
|
97
|
+
- name: Fetch All Tags
|
|
98
|
+
run: |
|
|
99
|
+
git fetch --tags --force
|
|
100
|
+
|
|
101
|
+
- name: Set up Python
|
|
102
|
+
uses: actions/setup-python@v5
|
|
103
|
+
with:
|
|
104
|
+
python-version: '3.12'
|
|
105
|
+
|
|
106
|
+
- name: Install Build Tools
|
|
107
|
+
run: |
|
|
108
|
+
pip install build setuptools-scm
|
|
109
|
+
|
|
110
|
+
- name: Build Wheel & Sdist
|
|
111
|
+
env:
|
|
112
|
+
TAG: ${{ needs.tag-release.outputs.tag }}
|
|
113
|
+
run: |
|
|
114
|
+
export SETUPTOOLS_SCM_PRETEND_VERSION="${TAG#v}"
|
|
115
|
+
echo "Building package for release version: $SETUPTOOLS_SCM_PRETEND_VERSION"
|
|
116
|
+
python -m build
|
|
117
|
+
|
|
118
|
+
- name: Create GitHub Release
|
|
119
|
+
env:
|
|
120
|
+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
121
|
+
TAG: ${{ needs.tag-release.outputs.tag }}
|
|
122
|
+
run: |
|
|
123
|
+
EXTRA_FLAGS=()
|
|
124
|
+
if [[ "$TAG" =~ (alpha|beta|rc|dev) ]]; then
|
|
125
|
+
EXTRA_FLAGS+=(--prerelease)
|
|
126
|
+
fi
|
|
127
|
+
|
|
128
|
+
START_TAG=$(git tag --sort=-v:refname | grep -E '^v?[0-9]+\.[0-9]+\.[0-9]+$' | grep -v "^${TAG}$" | head -n 1 || true)
|
|
129
|
+
if [ -z "$START_TAG" ]; then
|
|
130
|
+
START_TAG=$(git describe --tags --abbrev=0 "${TAG}^" 2>/dev/null || true)
|
|
131
|
+
fi
|
|
132
|
+
|
|
133
|
+
RANGE="${START_TAG}..${TAG}"
|
|
134
|
+
if [ -z "$START_TAG" ]; then
|
|
135
|
+
RANGE="${TAG}"
|
|
136
|
+
fi
|
|
137
|
+
|
|
138
|
+
REPO_URL="https://github.com/${{ github.repository }}"
|
|
139
|
+
NOTES_FILE="/tmp/release_notes.md"
|
|
140
|
+
echo "## What's Changed" > "$NOTES_FILE"
|
|
141
|
+
echo "" >> "$NOTES_FILE"
|
|
142
|
+
|
|
143
|
+
FEATS=$(git log "$RANGE" --grep="^feat" --pretty=format:"* %s ([%h]($REPO_URL/commit/%H))" || true)
|
|
144
|
+
FIXES=$(git log "$RANGE" --grep="^fix" --pretty=format:"* %s ([%h]($REPO_URL/commit/%H))" || true)
|
|
145
|
+
MAINT=$(git log "$RANGE" --grep="^chore" --grep="^perf" --grep="^refactor" --grep="^docs" --pretty=format:"* %s ([%h]($REPO_URL/commit/%H))" || true)
|
|
146
|
+
|
|
147
|
+
HAS_CONTENT=false
|
|
148
|
+
if [ -n "$FEATS" ]; then
|
|
149
|
+
echo "### 🚀 Features" >> "$NOTES_FILE"
|
|
150
|
+
echo "$FEATS" >> "$NOTES_FILE"
|
|
151
|
+
echo "" >> "$NOTES_FILE"
|
|
152
|
+
HAS_CONTENT=true
|
|
153
|
+
fi
|
|
154
|
+
|
|
155
|
+
if [ -n "$FIXES" ]; then
|
|
156
|
+
echo "### 🐛 Bug Fixes" >> "$NOTES_FILE"
|
|
157
|
+
echo "$FIXES" >> "$NOTES_FILE"
|
|
158
|
+
echo "" >> "$NOTES_FILE"
|
|
159
|
+
HAS_CONTENT=true
|
|
160
|
+
fi
|
|
161
|
+
|
|
162
|
+
if [ -n "$MAINT" ]; then
|
|
163
|
+
echo "### 🧰 Maintenance & Documentation" >> "$NOTES_FILE"
|
|
164
|
+
echo "$MAINT" >> "$NOTES_FILE"
|
|
165
|
+
echo "" >> "$NOTES_FILE"
|
|
166
|
+
HAS_CONTENT=true
|
|
167
|
+
fi
|
|
168
|
+
|
|
169
|
+
if [ "$HAS_CONTENT" = false ]; then
|
|
170
|
+
git log "$RANGE" --pretty=format:"* %s ([%h]($REPO_URL/commit/%H))" >> "$NOTES_FILE" || true
|
|
171
|
+
echo "" >> "$NOTES_FILE"
|
|
172
|
+
fi
|
|
173
|
+
|
|
174
|
+
if [ -n "$START_TAG" ]; then
|
|
175
|
+
echo "**Full Changelog**: $REPO_URL/compare/${START_TAG}...${TAG}" >> "$NOTES_FILE"
|
|
176
|
+
fi
|
|
177
|
+
|
|
178
|
+
gh release create "$TAG" dist/* \
|
|
179
|
+
--title "$TAG" \
|
|
180
|
+
--notes-file "$NOTES_FILE" \
|
|
181
|
+
"${EXTRA_FLAGS[@]}"
|
|
182
|
+
|
|
183
|
+
- name: Publish to PyPI
|
|
184
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
185
|
+
continue-on-error: true # Allows pipeline to succeed even before PyPI Trusted Publishing is registered
|
|
186
|
+
with:
|
|
187
|
+
packages-dir: dist/
|
|
188
|
+
skip-existing: true
|
|
189
|
+
print-hash: true
|
git2svn-0.4.1/.gitignore
ADDED
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
# Contributing to git2svn
|
|
2
|
+
|
|
3
|
+
Thank you for contributing to `git2svn`! This document outlines our development workflow, coding standards, and contribution guidelines.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## 1. Development Environment Setup
|
|
8
|
+
|
|
9
|
+
`git2svn` is built entirely on the Python 3 standard library with zero runtime dependencies. Only development tooling (Ruff) is required.
|
|
10
|
+
|
|
11
|
+
### 1.1 Requirements
|
|
12
|
+
* Python `>= 3.11`
|
|
13
|
+
* `git` CLI (standard installation)
|
|
14
|
+
* `svn` CLI (Apache Subversion command-line client)
|
|
15
|
+
* `ruff` for code formatting and linting
|
|
16
|
+
|
|
17
|
+
### 1.2 Installation for Development
|
|
18
|
+
```bash
|
|
19
|
+
# Clone the repository
|
|
20
|
+
git clone https://github.com/your-org/git2svn.git
|
|
21
|
+
cd git2svn
|
|
22
|
+
|
|
23
|
+
# Optional: create a virtual environment
|
|
24
|
+
python3 -m venv .venv
|
|
25
|
+
source .venv/bin/activate
|
|
26
|
+
|
|
27
|
+
# Install dev dependencies (ruff)
|
|
28
|
+
pip install -e ".[dev]"
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
---
|
|
32
|
+
|
|
33
|
+
## 2. Coding Standards & Conventions
|
|
34
|
+
|
|
35
|
+
### 2.1 Commit Messages
|
|
36
|
+
All commit messages **must** strictly adhere to the [Conventional Commits](https://www.conventionalcommits.org/) specification:
|
|
37
|
+
```text
|
|
38
|
+
<type>(<optional scope>): <description>
|
|
39
|
+
|
|
40
|
+
[optional body]
|
|
41
|
+
|
|
42
|
+
[optional footer(s)]
|
|
43
|
+
```
|
|
44
|
+
* **Allowed Types:** `feat`, `fix`, `docs`, `style`, `refactor`, `perf`, `test`, `build`, `ci`, `chore`.
|
|
45
|
+
* **Example:** `feat(patch): replace patch with git apply and add EOL normalization`
|
|
46
|
+
|
|
47
|
+
### 2.2 Code Formatting & Linting
|
|
48
|
+
We use [Ruff](https://astral.sh/ruff) configured in `pyproject.toml` (target Python 3.11+, line length 120):
|
|
49
|
+
```bash
|
|
50
|
+
# Check code for lint errors and auto-fix what's safe
|
|
51
|
+
ruff check --fix .
|
|
52
|
+
|
|
53
|
+
# Format code
|
|
54
|
+
ruff format .
|
|
55
|
+
|
|
56
|
+
# Check formatting without modifying
|
|
57
|
+
ruff format --check .
|
|
58
|
+
```
|
|
59
|
+
All code must pass `ruff check .` and `ruff format --check .` with zero errors or warnings before committing.
|
|
60
|
+
|
|
61
|
+
### 2.3 Documentation-as-Code
|
|
62
|
+
* All architecture documentation resides in [`docs/arc42.md`](docs/arc42.md) following the [arc42 template](https://arc42.org/).
|
|
63
|
+
* All requirements documentation resides in [`docs/req42.md`](docs/req42.md) following the [req42 framework](https://req42.de/).
|
|
64
|
+
* CLI workflows and command guides reside in [`docs/user-guide.md`](docs/user-guide.md).
|
|
65
|
+
* Diagrams are embedded directly using **Mermaid.js** code blocks (`mermaid`).
|
|
66
|
+
|
|
67
|
+
---
|
|
68
|
+
|
|
69
|
+
## 3. Testing Guidelines
|
|
70
|
+
|
|
71
|
+
### 3.1 Running Tests
|
|
72
|
+
Run the test suite using Python's built-in `unittest` runner:
|
|
73
|
+
```bash
|
|
74
|
+
python3 -m unittest discover tests
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
### 3.2 Writing Tests
|
|
78
|
+
* Any new feature or bugfix must include corresponding automated tests in `tests/`.
|
|
79
|
+
* Mock external network or real SVN servers where appropriate, but use real temporary Git repositories and directory structures (`tempfile.TemporaryDirectory`) for unit and integration testing.
|
|
80
|
+
* When adding newline/patch logic, test both `\r\n` (CRLF) and `\n` (LF) scenarios to prevent regressions with SVN `E135000` mixed line endings.
|
|
81
|
+
|
|
82
|
+
---
|
|
83
|
+
|
|
84
|
+
## 4. Pull Request Process
|
|
85
|
+
|
|
86
|
+
1. Create a feature branch off `main` (e.g. `feat/my-new-option`).
|
|
87
|
+
2. Make your changes adhering to conventional commits.
|
|
88
|
+
3. Run `ruff check .`, `ruff format --check .`, and `python3 -m unittest discover tests`.
|
|
89
|
+
4. Ensure documentation in `docs/` and `README.md` is updated if CLI syntax or architecture changed.
|
|
90
|
+
5. Open a Pull Request with a clear description of the problem solved.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: git2svn
|
|
3
|
-
Version: 0.4.
|
|
3
|
+
Version: 0.4.1
|
|
4
4
|
Summary: CLI utility to synchronize changes from a local Git repository to a local SVN working copy
|
|
5
5
|
Author: Simon
|
|
6
6
|
License: Apache-2.0
|
|
@@ -27,6 +27,7 @@ License-File: LICENSE.md
|
|
|
27
27
|
Provides-Extra: dev
|
|
28
28
|
Requires-Dist: coverage>=7.0.0; extra == "dev"
|
|
29
29
|
Requires-Dist: ruff>=0.8.0; extra == "dev"
|
|
30
|
+
Requires-Dist: setuptools-scm>=8.0; extra == "dev"
|
|
30
31
|
Dynamic: license-file
|
|
31
32
|
|
|
32
33
|
# Git-to-SVN Synchronization CLI (`git2svn`)
|