Skip to content

Commit 4345faa

Browse files
committedOct 4, 2023
Merge branch 'sh'
2 parents 91f63cd + c2472e9 commit 4345faa

13 files changed

+200
-93
lines changed
 

‎.github/dependabot.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,4 @@ updates:
33
- package-ecosystem: "github-actions"
44
directory: "/"
55
schedule:
6-
interval: "weekly"
6+
interval: "weekly"

‎.github/workflows/cygwin-test.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ jobs:
4040
4141
- name: Prepare this repo for tests
4242
run: |
43-
TRAVIS=yes ./init-tests-after-clone.sh
43+
./init-tests-after-clone.sh
4444
4545
- name: Set git user identity and command aliases for the tests
4646
run: |

‎.github/workflows/lint.yml

+4
Original file line numberDiff line numberDiff line change
@@ -14,3 +14,7 @@ jobs:
1414
python-version: "3.x"
1515

1616
- uses: pre-commit/action@v3.0.0
17+
with:
18+
extra_args: --all-files --hook-stage manual
19+
env:
20+
SKIP: black-format

‎.github/workflows/pythonpackage.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ jobs:
3737

3838
- name: Prepare this repo for tests
3939
run: |
40-
TRAVIS=yes ./init-tests-after-clone.sh
40+
./init-tests-after-clone.sh
4141
4242
- name: Set git user identity and command aliases for the tests
4343
run: |

‎.pre-commit-config.yaml

+37-15
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,39 @@
11
repos:
2-
- repo: https://github.com/PyCQA/flake8
3-
rev: 6.1.0
4-
hooks:
5-
- id: flake8
6-
additional_dependencies:
7-
- flake8-bugbear==23.9.16
8-
- flake8-comprehensions==3.14.0
9-
- flake8-typing-imports==1.14.0
10-
exclude: ^doc|^git/ext/
2+
- repo: https://github.com/psf/black-pre-commit-mirror
3+
rev: 23.9.1
4+
hooks:
5+
- id: black
6+
alias: black-check
7+
name: black (check)
8+
args: [--check, --diff]
9+
exclude: ^git/ext/
10+
stages: [manual]
1111

12-
- repo: https://github.com/pre-commit/pre-commit-hooks
13-
rev: v4.4.0
14-
hooks:
15-
- id: check-merge-conflict
16-
- id: check-toml
17-
- id: check-yaml
12+
- id: black
13+
alias: black-format
14+
name: black (format)
15+
exclude: ^git/ext/
16+
17+
- repo: https://github.com/PyCQA/flake8
18+
rev: 6.1.0
19+
hooks:
20+
- id: flake8
21+
additional_dependencies:
22+
- flake8-bugbear==23.9.16
23+
- flake8-comprehensions==3.14.0
24+
- flake8-typing-imports==1.14.0
25+
exclude: ^doc|^git/ext/
26+
27+
- repo: https://github.com/shellcheck-py/shellcheck-py
28+
rev: v0.9.0.5
29+
hooks:
30+
- id: shellcheck
31+
args: [--color]
32+
exclude: ^git/ext/
33+
34+
- repo: https://github.com/pre-commit/pre-commit-hooks
35+
rev: v4.4.0
36+
hooks:
37+
- id: check-toml
38+
- id: check-yaml
39+
- id: check-merge-conflict

‎Makefile

+5-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
1-
.PHONY: all clean release force_release
1+
.PHONY: all lint clean release force_release
22

33
all:
4-
@grep -Ee '^[a-z].*:' Makefile | cut -d: -f1 | grep -vF all
4+
@awk -F: '/^[[:alpha:]].*:/ && !/^all:/ {print $$1}' Makefile
5+
6+
lint:
7+
SKIP=black-format pre-commit run --all-files --hook-stage manual
58

69
clean:
710
rm -rf build/ dist/ .eggs/ .tox/

‎README.md

+28-14
Original file line numberDiff line numberDiff line change
@@ -76,17 +76,20 @@ To clone the [the GitHub repository](https://github.com/gitpython-developers/Git
7676
```bash
7777
git clone https://github.com/gitpython-developers/GitPython
7878
cd GitPython
79-
git fetch --tags
8079
./init-tests-after-clone.sh
8180
```
8281

82+
On Windows, `./init-tests-after-clone.sh` can be run in a Git Bash shell.
83+
8384
If you are cloning [your own fork](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/working-with-forks/about-forks), then replace the above `git clone` command with one that gives the URL of your fork. Or use this [`gh`](https://cli.github.com/) command (assuming you have `gh` and your fork is called `GitPython`):
8485

8586
```bash
8687
gh repo clone GitPython
8788
```
8889

89-
Having cloned the repo, create and activate your [virtual environment](https://docs.python.org/3/tutorial/venv.html). Then make an [editable install](https://pip.pypa.io/en/stable/topics/local-project-installs/#editable-installs):
90+
Having cloned the repo, create and activate your [virtual environment](https://docs.python.org/3/tutorial/venv.html).
91+
92+
Then make an [editable install](https://pip.pypa.io/en/stable/topics/local-project-installs/#editable-installs):
9093

9194
```bash
9295
pip install -e ".[test]"
@@ -114,9 +117,9 @@ See [Issue #525](https://github.com/gitpython-developers/GitPython/issues/525).
114117

115118
### RUNNING TESTS
116119

117-
_Important_: Right after cloning this repository, please be sure to have
118-
executed `git fetch --tags` followed by the `./init-tests-after-clone.sh`
119-
script in the repository root. Otherwise you will encounter test failures.
120+
_Important_: Right after cloning this repository, please be sure to have executed
121+
the `./init-tests-after-clone.sh` script in the repository root. Otherwise
122+
you will encounter test failures.
120123

121124
On _Windows_, make sure you have `git-daemon` in your PATH. For MINGW-git, the `git-daemon.exe`
122125
exists in `Git\mingw64\libexec\git-core\`.
@@ -143,30 +146,41 @@ To test, run:
143146
pytest
144147
```
145148

146-
To lint, run:
149+
To lint, and apply automatic code formatting, run:
147150

148151
```bash
149152
pre-commit run --all-files
150153
```
151154

155+
- Linting without modifying code can be done with: `make lint`
156+
- Auto-formatting without other lint checks can be done with: `black .`
157+
152158
To typecheck, run:
153159

154160
```bash
155161
mypy -p git
156162
```
157163

158-
For automatic code formatting, run:
164+
#### CI (and tox)
159165

160-
```bash
161-
black .
162-
```
166+
The same linting, and running tests on all the different supported Python versions, will be performed:
167+
168+
- Upon submitting a pull request.
169+
- On each push, *if* you have a fork with GitHub Actions enabled.
170+
- Locally, if you run [`tox`](https://tox.wiki/) (this skips any Python versions you don't have installed).
171+
172+
#### Configuration files
173+
174+
Specific tools:
163175

164-
Configuration for flake8 is in the `./.flake8` file.
176+
- Configurations for `mypy`, `pytest`, `coverage.py`, and `black` are in `./pyproject.toml`.
177+
- Configuration for `flake8` is in the `./.flake8` file.
165178

166-
Configurations for `mypy`, `pytest`, `coverage.py`, and `black` are in `./pyproject.toml`.
179+
Orchestration tools:
167180

168-
The same linting and testing will also be performed against different supported python versions
169-
upon submitting a pull request (or on each push if you have a fork with a "main" branch and actions enabled).
181+
- Configuration for `pre-commit` is in the `./.pre-commit-config.yaml` file.
182+
- Configuration for `tox` is in `./tox.ini`.
183+
- Configuration for GitHub Actions (CI) is in files inside `./.github/workflows/`.
170184

171185
### Contributions
172186

‎build-release.sh

+8-7
Original file line numberDiff line numberDiff line change
@@ -6,21 +6,22 @@
66
set -eEu
77

88
function release_with() {
9-
$1 -m build --sdist --wheel
9+
"$1" -m build --sdist --wheel
1010
}
1111

12-
if test -n "${VIRTUAL_ENV:-}"; then
12+
function suggest_venv() {
13+
local venv_cmd='python -m venv env && source env/bin/activate'
14+
printf "HELP: To avoid this error, use a virtual-env with '%s' instead.\n" "$venv_cmd"
15+
}
16+
17+
if test -n "${VIRTUAL_ENV-}"; then
1318
deps=(build twine) # Install twine along with build, as we need it later.
1419
echo "Virtual environment detected. Adding packages: ${deps[*]}"
1520
pip install --quiet --upgrade "${deps[@]}"
1621
echo 'Starting the build.'
1722
release_with python
1823
else
19-
function suggest_venv() {
20-
venv_cmd='python -m venv env && source env/bin/activate'
21-
printf "HELP: To avoid this error, use a virtual-env with '%s' instead.\n" "$venv_cmd"
22-
}
2324
trap suggest_venv ERR # This keeps the original exit (error) code.
2425
echo 'Starting the build.'
25-
release_with python3 # Outside a venv, use python3.
26+
release_with python3 # Outside a venv, use python3.
2627
fi

‎check-version.sh

+18-8
Original file line numberDiff line numberDiff line change
@@ -10,29 +10,39 @@ trap 'echo "$0: Check failed. Stopping." >&2' ERR
1010
readonly version_path='VERSION'
1111
readonly changes_path='doc/source/changes.rst'
1212

13+
function check_status() {
14+
git status -s "$@"
15+
test -z "$(git status -s "$@")"
16+
}
17+
18+
function get_latest_tag() {
19+
local config_opts
20+
printf -v config_opts ' -c versionsort.suffix=-%s' alpha beta pre rc RC
21+
# shellcheck disable=SC2086 # Deliberately word-splitting the arguments.
22+
git $config_opts tag -l '[0-9]*' --sort=-v:refname | head -n1
23+
}
24+
1325
echo 'Checking current directory.'
1426
test "$(cd -- "$(dirname -- "$0")" && pwd)" = "$(pwd)" # Ugly, but portable.
1527

1628
echo "Checking that $version_path and $changes_path exist and have no uncommitted changes."
1729
test -f "$version_path"
1830
test -f "$changes_path"
19-
git status -s -- "$version_path" "$changes_path"
20-
test -z "$(git status -s -- "$version_path" "$changes_path")"
31+
check_status -- "$version_path" "$changes_path"
2132

2233
# This section can be commented out, if absolutely necessary.
2334
echo 'Checking that ALL changes are committed.'
24-
git status -s --ignore-submodules
25-
test -z "$(git status -s --ignore-submodules)"
35+
check_status --ignore-submodules
2636

27-
version_version="$(cat "$version_path")"
37+
version_version="$(<"$version_path")"
2838
changes_version="$(awk '/^[0-9]/ {print $0; exit}' "$changes_path")"
29-
config_opts="$(printf ' -c versionsort.suffix=-%s' alpha beta pre rc RC)"
30-
latest_tag="$(git $config_opts tag -l '[0-9]*' --sort=-v:refname | head -n1)"
39+
latest_tag="$(get_latest_tag)"
3140
head_sha="$(git rev-parse HEAD)"
3241
latest_tag_sha="$(git rev-parse "${latest_tag}^{commit}")"
3342

3443
# Display a table of all the current version, tag, and HEAD commit information.
35-
echo $'\nThe VERSION must be the same in all locations, and so must the HEAD and tag SHA'
44+
echo
45+
echo 'The VERSION must be the same in all locations, and so must the HEAD and tag SHA'
3646
printf '%-14s = %s\n' 'VERSION file' "$version_version" \
3747
'changes.rst' "$changes_version" \
3848
'Latest tag' "$latest_tag" \

‎doc/Makefile

+22-21
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,15 @@
22
#
33

44
# You can set these variables from the command line.
5+
BUILDDIR = build
56
SPHINXOPTS = -W
67
SPHINXBUILD = sphinx-build
78
PAPER =
89

910
# Internal variables.
1011
PAPEROPT_a4 = -D latex_paper_size=a4
1112
PAPEROPT_letter = -D latex_paper_size=letter
12-
ALLSPHINXOPTS = -d build/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) source
13+
ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) source
1314

1415
.PHONY: help clean html web pickle htmlhelp latex changes linkcheck
1516

@@ -24,52 +25,52 @@ help:
2425
@echo " linkcheck to check all external links for integrity"
2526

2627
clean:
27-
-rm -rf build/*
28+
-rm -rf $(BUILDDIR)/*
2829

2930
html:
30-
mkdir -p build/html build/doctrees
31-
$(SPHINXBUILD) -b html $(ALLSPHINXOPTS) build/html
31+
mkdir -p $(BUILDDIR)/html $(BUILDDIR)/doctrees
32+
$(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
3233
@echo
33-
@echo "Build finished. The HTML pages are in build/html."
34+
@echo "Build finished. The HTML pages are in $(BUILDDIR)/html."
3435

3536
pickle:
36-
mkdir -p build/pickle build/doctrees
37-
$(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) build/pickle
37+
mkdir -p $(BUILDDIR)/pickle $(BUILDDIR)/doctrees
38+
$(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle
3839
@echo
3940
@echo "Build finished; now you can process the pickle files."
4041

4142
web: pickle
4243

4344
json:
44-
mkdir -p build/json build/doctrees
45-
$(SPHINXBUILD) -b json $(ALLSPHINXOPTS) build/json
45+
mkdir -p $(BUILDDIR)/json $(BUILDDIR)/doctrees
46+
$(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json
4647
@echo
4748
@echo "Build finished; now you can process the JSON files."
4849

4950
htmlhelp:
50-
mkdir -p build/htmlhelp build/doctrees
51-
$(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) build/htmlhelp
51+
mkdir -p $(BUILDDIR)/htmlhelp $(BUILDDIR)/doctrees
52+
$(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp
5253
@echo
5354
@echo "Build finished; now you can run HTML Help Workshop with the" \
54-
".hhp project file in build/htmlhelp."
55+
".hhp project file in $(BUILDDIR)/htmlhelp."
5556

5657
latex:
57-
mkdir -p build/latex build/doctrees
58-
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) build/latex
58+
mkdir -p $(BUILDDIR)/latex $(BUILDDIR)/doctrees
59+
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
5960
@echo
60-
@echo "Build finished; the LaTeX files are in build/latex."
61+
@echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex."
6162
@echo "Run \`make all-pdf' or \`make all-ps' in that directory to" \
6263
"run these through (pdf)latex."
6364

6465
changes:
65-
mkdir -p build/changes build/doctrees
66-
$(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) build/changes
66+
mkdir -p $(BUILDDIR)/changes $(BUILDDIR)/doctrees
67+
$(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes
6768
@echo
68-
@echo "The overview file is in build/changes."
69+
@echo "The overview file is in $(BUILDDIR)/changes."
6970

7071
linkcheck:
71-
mkdir -p build/linkcheck build/doctrees
72-
$(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) build/linkcheck
72+
mkdir -p $(BUILDDIR)/linkcheck $(BUILDDIR)/doctrees
73+
$(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck
7374
@echo
7475
@echo "Link check complete; look for any errors in the above output " \
75-
"or in build/linkcheck/output.txt."
76+
"or in $(BUILDDIR)/linkcheck/output.txt."

‎init-tests-after-clone.sh

+64-9
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,73 @@
1-
#!/usr/bin/env bash
1+
#!/bin/sh
22

3-
set -e
3+
set -eu
44

5-
if [[ -z "$TRAVIS" ]]; then
6-
read -rp "This operation will destroy locally modified files. Continue ? [N/y]: " answer
7-
if [[ ! $answer =~ [yY] ]]; then
8-
exit 2
9-
fi
5+
fallback_repo_for_tags='https://github.com/gitpython-developers/GitPython.git'
6+
7+
ci() {
8+
# For now, check just these, as a false positive could lead to data loss.
9+
test -n "${TRAVIS-}" || test -n "${GITHUB_ACTIONS-}"
10+
}
11+
12+
no_version_tags() {
13+
test -z "$(git tag -l '[0-9]*' 'v[0-9]*')"
14+
}
15+
16+
warn() {
17+
if test -n "${GITHUB_ACTIONS-}"; then
18+
printf '::warning ::%s\n' "$*" >&2 # Annotate workflow.
19+
else
20+
printf '%s\n' "$@" >&2
21+
fi
22+
}
23+
24+
if ! ci; then
25+
printf 'This operation will destroy locally modified files. Continue ? [N/y]: ' >&2
26+
read -r answer
27+
case "$answer" in
28+
[yY])
29+
;;
30+
*)
31+
exit 2 ;;
32+
esac
1033
fi
1134

35+
# Stop if we have run this. (You can delete __testing_point__ to let it rerun.)
36+
# This also keeps track of where we are, so we can get back here.
1237
git tag __testing_point__
13-
git checkout master || git checkout -b master
38+
39+
# The tests need a branch called master.
40+
git checkout master -- || git checkout -b master
41+
42+
# The tests need a reflog history on the master branch.
1443
git reset --hard HEAD~1
1544
git reset --hard HEAD~1
1645
git reset --hard HEAD~1
46+
47+
# Point the master branch where we started, so we test the correct code.
1748
git reset --hard __testing_point__
18-
git submodule update --init --recursive
49+
50+
# The tests need submodules. (On CI, they would already have been checked out.)
51+
if ! ci; then
52+
git submodule update --init --recursive
53+
fi
54+
55+
# The tests need some version tags. Try to get them even in forks. This fetches
56+
# other objects too. So, locally, we always do it, for a consistent experience.
57+
if ! ci || no_version_tags; then
58+
git fetch --all --tags
59+
fi
60+
61+
# If we still have no version tags, try to get them from the original repo.
62+
if no_version_tags; then
63+
warn 'No local or remote version tags found. Trying fallback remote:' \
64+
"$fallback_repo_for_tags"
65+
66+
# git fetch supports * but not [], and --no-tags means no *other* tags, so...
67+
printf 'refs/tags/%d*:refs/tags/%d*\n' 0 0 1 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8 9 9 |
68+
xargs git fetch --no-tags "$fallback_repo_for_tags"
69+
70+
if no_version_tags; then
71+
warn 'No version tags found anywhere. Some tests will fail.'
72+
fi
73+
fi

‎test/test_git.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ def tearDown(self):
4343
def _assert_logged_for_popen(self, log_watcher, name, value):
4444
re_name = re.escape(name)
4545
re_value = re.escape(str(value))
46-
re_line = re.compile(fr"DEBUG:git.cmd:Popen\(.*\b{re_name}={re_value}[,)]")
46+
re_line = re.compile(rf"DEBUG:git.cmd:Popen\(.*\b{re_name}={re_value}[,)]")
4747
match_attempts = [re_line.match(message) for message in log_watcher.output]
4848
self.assertTrue(any(match_attempts), repr(log_watcher.output))
4949

‎tox.ini

+10-13
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[tox]
22
requires = tox>=4
3-
env_list = py{37,38,39,310,311,312}, lint, mypy, black
3+
env_list = py{37,38,39,310,311,312}, lint, mypy, html
44

55
[testenv]
66
description = Run unit tests
@@ -11,25 +11,22 @@ commands = pytest --color=yes {posargs}
1111

1212
[testenv:lint]
1313
description = Lint via pre-commit
14-
base_python = py39
15-
commands = pre-commit run --all-files
14+
base_python = py{39,310,311,312,38,37}
15+
set_env =
16+
SKIP = black-format
17+
commands = pre-commit run --all-files --hook-stage manual
1618

1719
[testenv:mypy]
1820
description = Typecheck with mypy
19-
base_python = py39
21+
base_python = py{39,310,311,312,38,37}
2022
commands = mypy -p git
2123
ignore_outcome = true
2224

23-
[testenv:black]
24-
description = Check style with black
25-
base_python = py39
26-
commands = black --check --diff .
27-
28-
# Run "tox -e html" for this. It is deliberately excluded from env_list, as
29-
# unlike the other environments, this one writes outside the .tox/ directory.
3025
[testenv:html]
3126
description = Build HTML documentation
32-
base_python = py39
27+
base_python = py{39,310,311,312,38,37}
3328
deps = -r doc/requirements.txt
3429
allowlist_externals = make
35-
commands = make -C doc html
30+
commands =
31+
make BUILDDIR={env_tmp_dir}/doc/build -C doc clean
32+
make BUILDDIR={env_tmp_dir}/doc/build -C doc html

0 commit comments

Comments
 (0)
Please sign in to comment.