Skip to content

Commit

Permalink
Refactor the run script and pre-commit hooks to reduce duplication
Browse files Browse the repository at this point in the history
  • Loading branch information
pronovic committed Oct 24, 2022
1 parent ee8d579 commit ffca2da
Show file tree
Hide file tree
Showing 41 changed files with 1,026 additions and 736 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/test-suite.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# vim: set ft=yaml ts=2 sw=2:
# vim: set ft=yaml ts=2 sw=2 expandtab:
name: Test Suite
on:
push:
Expand All @@ -14,7 +14,7 @@ concurrency:
cancel-in-progress: true
jobs:
build-and-test:
uses: pronovic/gha-shared-workflows/.github/workflows/poetry-build-and-test.yml@v1
uses: pronovic/gha-shared-workflows/.github/workflows/poetry-build-and-test.yml@v2
secrets: inherit
with:
matrix-os-version: "[ 'ubuntu-latest', 'macos-latest' ]"
Expand Down
32 changes: 2 additions & 30 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,35 +3,7 @@ repos:
- repo: local
hooks:
- id: system
name: Tab Characters
entry: sh utils/check-tabs.sh
pass_filenames: false
language: system
- repo: local
hooks:
- id: system
name: Black
entry: poetry run black .
pass_filenames: false
language: system
- repo: local
hooks:
- id: system
name: isort
entry: poetry run isort .
pass_filenames: false
language: system
- repo: local
hooks:
- id: system
name: MyPy
entry: poetry run mypy
pass_filenames: false
language: system
- repo: local
hooks:
- id: system
name: Pylint
entry: poetry run pylint -j 0 src/vplan tests
name: Code Style Checks
entry: ./run checks
pass_filenames: false
language: system
9 changes: 9 additions & 0 deletions .run/commands/black.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# vim: set ft=bash ts=3 sw=3 expandtab:
# Run the black code formatter

command_black() {
echo "Running black formatter..."
poetry_run black "$@" .
echo "done"
}

23 changes: 23 additions & 0 deletions .run/commands/checktabs.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# vim: set ft=bash ts=3 sw=3 expandtab:
# Check for tab characters in the source tree

command_checktabs() {
echo "Checking for tab characters..."

local result

cd "$REPO_DIR" # we need to be in the root of the repo for 'git ls-files' to do what we need

result=$(grep -l "$(printf '\t')" $(git ls-files | grep -v -x -F --file=".tabignore"))
if [ $? == 0 ]; then
echo "❌ Some files contain tab characters"
echo "${result}"
exit 1
fi

echo "✅ No tab characters found"
echo "done"

cd - >/dev/null
}

10 changes: 10 additions & 0 deletions .run/commands/disablekeyring.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# vim: set ft=bash ts=3 sw=3 expandtab:
# Disable the Python keyring

# This prevents Poetry v1.2.0 from using the Python keyring, which sometimes fails or hangs on Linux.
# See: https://github.com/python-poetry/poetry/issues/2692#issuecomment-1235683370

command_disablekeyring() {
export PYTHON_KEYRING_BACKEND="keyring.backends.null.Keyring"
}

28 changes: 28 additions & 0 deletions .run/commands/dos2unix.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# vim: set ft=bash ts=3 sw=3 expandtab:
# Convert a file from DOS line endings to UNIX line endings

# See: https://stackoverflow.com/a/53657266

command_dos2unix() {
cat << EOF > "$WORKING_DIR/dos2unix.py"
import sys
DOS = b"\r\n"
UNIX = b"\n"
path = sys.argv[1]
with open(path, "rb") as f:
content = f.read()
content = content.replace(DOS, UNIX)
with open(path, "wb") as f:
f.write(content)
sys.exit(0)
EOF

poetry_run python "$WORKING_DIR/dos2unix.py" "$1"
}

9 changes: 9 additions & 0 deletions .run/commands/enablekeyring.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# vim: set ft=bash ts=3 sw=3 expandtab:
# Enable the Python keyring

# We need to unset this for cases where the keyring is required, like publishing

command_enablekeyring() {
unset PYTHON_KEYRING_BACKEND
}

9 changes: 9 additions & 0 deletions .run/commands/isort.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# vim: set ft=bash ts=3 sw=3 expandtab:
# Run the isort import formatter

command_isort() {
echo "Running isort formatter..."
poetry_run isort --color "$@" .
echo "done"
}

11 changes: 11 additions & 0 deletions .run/commands/latestcode.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# vim: set ft=bash ts=3 sw=3 expandtab:
# Make sure that the latest code is installed

command_latestcode() {
poetry install --only-root >/dev/null
if [ $? != 0 ]; then
echo "*** Failed to install the latest code"
exit 1
fi
}

11 changes: 11 additions & 0 deletions .run/commands/mypy.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# vim: set ft=bash ts=3 sw=3 expandtab:
# Run the MyPy code checker

# We generate relative paths in the output to make integration with Pycharm work better

command_mypy() {
echo "Running mypy checks..."
poetry_run mypy --hide-absolute-path "$@"
echo "done"
}

19 changes: 19 additions & 0 deletions .run/commands/poetrybuild.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# vim: set ft=bash ts=3 sw=3 expandtab:
# Build release artifacts into the dist/ directory

command_poetrybuild() {
echo "Building release artifacts..."

rm -f dist/*

poetry version

poetry build
if [ $? != 0 ]; then
echo "*** Build failed"
exit 1
fi

echo "done"
}

9 changes: 9 additions & 0 deletions .run/commands/precommit.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# vim: set ft=bash ts=3 sw=3 expandtab:
# Install pre-commit hooks

command_precommit() {
echo -n "Installing pre-commit hooks..."
poetry_run pre-commit install >/dev/null
echo "done"
}

28 changes: 28 additions & 0 deletions .run/commands/publishpypi.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# vim: set ft=bash ts=3 sw=3 expandtab:
# Publish the current tagged code to PyPI and push to GitHub

# Before doing this, you must retrieve and configure a local API token
# For instance: poetry config pypi-token.pypi token --local
# See: https://python-poetry.org/docs/repositories/#configuring-credentials

command_publishpypi() {
run_command enablekeyring # or we can't get the token from the keyring

poetry build
if [ $? != 0 ]; then
echo "*** Build step failed."
exit 1
fi

poetry publish
if [ $? != 0 ]; then
echo "*** Publish step failed."
exit 1
fi

git push --follow-tags
if [ $? != 0 ]; then
exit 1
fi
}

30 changes: 30 additions & 0 deletions .run/commands/pylint.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# vim: set ft=bash ts=3 sw=3 expandtab:
# Run the Pylint code checker

# We generate relative paths in the output to make integration with Pycharm work better

command_pylint() {
echo "Running pylint checks..."

local OPTIND OPTARG option tests template

tests="tests"
template="{path}:{line}:{column} - {C} - ({symbol}) - {msg}"

while getopts "t" option; do
case $option in
t)
tests="" # -t means to ignore the tests
;;
?)
echo "invalid option -$OPTARG"
exit 1
;;
esac
done

shift $((OPTIND -1)) # pop off the options consumed by getopts

poetry_run pylint --msg-template="$template" -j 0 "$@" $(ls -d src/*) $tests
echo "done"
}
44 changes: 44 additions & 0 deletions .run/commands/pytest.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# vim: set ft=bash ts=3 sw=3 expandtab:
# Run the pytest unit tests, optionally with coverage

command_pytest() {
local OPTIND OPTARG option coverage html color

coverage="no"
html="no"

while getopts ":ch" option; do
case $option in
c)
coverage="yes"
;;
h)
html="yes"
;;
?)
echo "invalid option -$OPTARG"
exit 1
;;
esac
done

shift $((OPTIND -1)) # pop off the options consumed by getopts

color=""
if [ "$GITHUB_ACTIONS" == "true" ] && [ "$RUNNER_OS" == "Windows" ]; then
color="--color no" # color messes up the terminal on Windows in GHA
fi

if [ $coverage == "yes" ]; then
poetry_run coverage run -m pytest --testdox --force-testdox $color tests
poetry_run coverage report
if [ $html == "yes" ]; then
# Use 'start' on Windows, and 'open' on MacOS and Debian (post-bullseye)
poetry_run coverage html -d .htmlcov
$(which start || which open) .htmlcov/index.html 2>/dev/null
fi
else
poetry_run pytest --testdox --force-testdox $color tests
fi
}

48 changes: 48 additions & 0 deletions .run/commands/requirements.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# vim: set ft=bash ts=3 sw=3 expandtab:
# Generate a requirements.txt file in the docs directory, for use by readthedocs.io

# Unfortunately, we can't just rely on Poetry here. Poetry wants to generate a
# file that includes our project's lowest compatible version of Python, but
# readthedocs.io can only build with older versions (v3.7 as of this writing,
# even though it's years out of date). So, we need to modify the generated
# result to make readthedocs.io happy.
#
# The "solution" is to replace whatever lowest python version Poetry generated
# with "3.7", and hope for the best. That seems to have been working so far,
# but we may eventually run into a dependency that simply doesn't exist for
# Python 3.7.

command_requirements() {
echo -n "Generating docs/requirements.txt..."

local replacement

poetry self add --quiet poetry-plugin-export
if [ $? != 0 ]; then
echo ""
echo "*** Failed to install Poetry plugin: poetry-plugin-export"
exit 1
fi

poetry export --format=requirements.txt --without-hashes --with dev --output=docs/requirements.txt
if [ $? != 0 ]; then
echo ""
echo "*** Failed to export docs/requirements.txt"
exit 1
fi

replacement='s|python_version >= "3\.[0-9][0-9]*"|python_version >= "3.7"|g'
sed --version 2>&1 | grep -iq "GNU sed"
if [ $? = 0 ]; then
# GNU sed accepts a bare -i and assumes no backup file
sed -i "$replacement" docs/requirements.txt
else
# BSD sed requires you to set an empty backup file extension
sed -i "" "$replacement" docs/requirements.txt
fi

run_command dos2unix docs/requirements.txt

echo "done"
}

31 changes: 31 additions & 0 deletions .run/commands/sphinx.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# vim: set ft=bash ts=3 sw=3 expandtab:
# Build the Sphinx documentation for readthedocs.io

command_sphinx() {
local OPTIND OPTARG option open

open="no"

while getopts ":o" option; do
case $option in
o)
open="yes"
;;
?)
echo "invalid option -$OPTARG"
exit 1
;;
esac
done

cd docs

poetry_run sphinx-build -N -E -a -b html -d _build/doctrees . _build/html 2>&1 | grep -v -F --file=.sphinxignore
if [ $open == "yes" ]; then
# Use 'start' on Windows, and 'open' on MacOS and Debian (post-bullseye)
$(which start || which open) _build/html/index.html 2>/dev/null
fi

cd - >/dev/null
}

Loading

0 comments on commit ffca2da

Please sign in to comment.