Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

52 introduce poetry #53

Merged
merged 10 commits into from
Nov 2, 2023
30 changes: 11 additions & 19 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,35 +15,27 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ["3.9", "3.10", "3.11"]
python-version: ["3.11", "3.12"]
os: [ubuntu-latest, windows-latest]
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- name: Set up ${{ matrix.python-version }}
uses: actions/setup-python@v3
uses: actions/setup-python@v4
with:
python-version: ${{ matrix.python-version }}
- name: Install just
uses: extractions/setup-just@v1
- name: Install poetry
uses: abatilo/actions-poetry@v2
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install black flake8 isort mypy pylint pytest
if [ -f requirements-dev.txt ]; then pip install -r requirements-dev.txt; fi
just install
- name: Lint with flake8, mypy, pylint, isort and black
run: |
# stop the build if there are Python syntax errors or undefined names
flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics
# exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide
flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics
# check also with pylint
pylint $(git ls-files '*.py') --ignore=conf.py
# mypy
mypy src
# isort
isort --check-only --recursive --quiet .
# black
black --check .
just lint
- name: Test with pytest
run: |
pytest --cov --cov-report=xml
just cov
- name: Test & publish code coverage
# https://github.com/marketplace/actions/code-climate-coverage-action
uses: paambaati/[email protected]
Expand Down
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ Read [here](https://www.butterfly.com.au/blog/website-development/clean-high-qua
- [Git](https://git-scm.com)
- [Python3](https://docs.python.org/3/)
- [just](https://github.com/casey/just)
- [poetry](https://python-poetry.org/)

## Usage

Expand Down Expand Up @@ -156,7 +157,7 @@ Automatically fix the coding style:

just fix

Update the libraries and the requirements file:
Update dependencies and config files:

just up

Expand Down
102 changes: 66 additions & 36 deletions justfile
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,43 @@ MIN_COVERAGE := '100'
@zen:
python -m this

# just show the help
@help:
echo "# INSTALL\n"
echo "## Install using poetry\n"
echo " poetry install"
echo "If you only want to install the project’s runtime dependencies:\n"
echo " poetry install --only main"
echo "Ensure that the locked dependencies in the poetry.lock file are the only ones present in the environment, removing anything that’s not necessary."
echo " poetry install --sync"
echo
echo "Add dependencies to the current project:\n"
echo " poetry add <dependency>"
echo
echo "Add a development dependency:\n"
echo " poetry add <dependency> --group dev"
echo
echo "## Testing and code quality"
echo
echo "### Type check and quality check of your code\n"
echo " just lint"
echo
echo "### Run tests\n"
echo " just test"
echo
echo "### Run tests with coverage\n"
echo " just cov"
echo
echo "### Perform a complete checkup\n"
echo " just check"
echo
echo "### Run benchmarks\n"
echo " just benchmarks"
echo
echo "### Build documentation\n"
echo " just doc"
echo

# rename project and author
@rename project author:
# replace string "Cleanpython" with {{project}} and "iacopy" with {{author}} in files
Expand Down Expand Up @@ -48,35 +85,28 @@ MIN_COVERAGE := '100'

# first time installation to get the new versions of libraries and check everything is ok
@startup:
echo "Installing requirements to get the new versions of libraries and check everything is ok"
pip install --upgrade pip
pip install -r update-requirements.txt
poetry self update
echo "Get the new versions of libraries and check everything is ok"
just up
poetry install
echo "Complete checkup of code: lint and test coverage"
just check
echo "Creating documentation of current codebase"
just doc
echo "Updating requirements.txt"
pip freeze > requirements-dev.txt
echo "Updating pylintrc"
pylint --generate-rcfile > pylintrc
echo "Done."
echo "Remember to commit the updated requirements.txt and/or pylintrc."
echo "Remember to commit changes."
echo =========================================================================================
echo "You can now run 'just' to get a list of available recipes."
echo "You can now run 'just' to get a list of available recipes, or 'just help' to get more info."

# install stuff: requirements and git hooks (assume virtualenv activated)
# install stuff: dependencies (using poetry) and git hooks
install:
pip install --upgrade pip
pip install -r requirements-dev.txt
poetry install

# get the latest versions of the installed libraries and update requirements.txt
# get the latest versions of the installed libraries
up:
pip install --upgrade pip
pip uninstall -y -r requirements-dev.txt
pip install -r update-requirements.txt
pip freeze > requirements-dev.txt
pylint --generate-rcfile > pylintrc
echo "Remember to commit the updated requirements.txt and/or pylintrc."
poetry update
poetry run pylint --generate-rcfile > pylintrc
@echo "Now you can call `just install`"

# (beta) for VirtualFish: like 'up' but recreate vf virtualenv to remove also old dependencies
vfup projectenv:
Expand All @@ -92,27 +122,27 @@ install-hooks:
# install pre-push hook
echo "just test" > .git/hooks/pre-push&&chmod +x .git/hooks/pre-push

# bootstrap your virtualenv
# bootstrap your virtualenv (deprecated)
setenv VIRTUALENV:
@echo Create virtualenv and use it to install requirements
virtualenv -p python3 {{VIRTUALENVS_DIR}}/{{VIRTUALENV}}
{{VIRTUALENVS_DIR}}/{{VIRTUALENV}}/bin/python -m pip install -r requirements-dev.txt
@echo Now please activate the virtualenv, then call \"just doc\".

@_mypy:
mypy --ignore-missing-imports src
poetry run mypy --ignore-missing-imports src

@_flake8:
flake8 .
poetry run flake8 .

@_pylint:
pylint $(git ls-files '*.py') --ignore conf.py
poetry run pylint $(git ls-files '*.py') --ignore conf.py

@_isort:
isort --check-only --recursive --quiet . || just _fail "Fix imports by calling \'just fix\'."
poetry run isort --check-only --recursive --quiet . || just _fail "Fix imports by calling \'just fix\'."

@_black:
black --check -q . || just _fail "Fix code formatting by calling \'just fix\'."
poetry run black --check -q . || just _fail "Fix code formatting by calling \'just fix\'."

# statically check the codebase (mypy, flake8, pylint, isort)
@lint:
Expand All @@ -129,29 +159,29 @@ setenv VIRTUALENV:

# auto fix imports and pep8 coding style
@fix:
isort .
black .
poetry run isort .
poetry run black .
# Re-check code quality
just lint

# run tests with coverage
@_test-cov:
pytest --cov --cov-report=xml .
poetry run pytest --cov --cov-report=xml .

# run tests only (with no coverage and no lint)
@test:
pytest
poetry run pytest
echo "Tests: OK ✅✅✅✅"

# run tests with coverage.py, create html report and open it
@cov:
just _test-cov
coverage html # create an HTML report
just _open htmlcov/index.html
poetry run coverage html # create an HTML report
just _open-nofail htmlcov/index.html

# check if coverage satisfies requirements
@_check-cov:
coverage report --fail-under {{MIN_COVERAGE}}
poetry run coverage report --fail-under {{MIN_COVERAGE}}
echo "\nTest coverage {{MIN_COVERAGE}}% : OK ✅✅✅✅✅"

# complete checkup: code analysis, tests and coverage
Expand Down Expand Up @@ -191,12 +221,12 @@ setenv VIRTUALENV:

# execute benchmarks tests only, in benchmark mode.
@benchmarks K_SELECTOR="test":
pytest --benchmark-enable --benchmark-only -k {{K_SELECTOR}} .
poetry run pytest --benchmark-enable --benchmark-only -k {{K_SELECTOR}} .

# bootstrap documentation (to test the recipe, `rm -rf docs`, then `just doc`)
@_setup-doc:
echo Setting up documentation...
sphinx-quickstart --no-sep --ext-autodoc --ext-coverage --ext-todo --ext-viewcode --no-makefile --no-batchfile ./{{DOC_DIRNAME}}
poetry run sphinx-quickstart --no-sep --ext-autodoc --ext-coverage --ext-todo --ext-viewcode --no-makefile --no-batchfile ./{{DOC_DIRNAME}}

# uncomment "sys.path.append" line on conf.py and pass "../src" as argument in order to generate the documentation correctly.
# and fix also index.rst (adding "modules" to the toctree, otherwise the build does not work properly)
Expand All @@ -210,10 +240,10 @@ setenv VIRTUALENV:
echo Auto-generate modules documentation...
# Positional args from seconds (if any) are paths you want to exclude from docs
# -f overwrite existing .rst, --private include also "_"-starting attributes.
sphinx-apidoc -f -o ./{{DOC_DIRNAME}}/ ./src
poetry run sphinx-apidoc -f -o ./{{DOC_DIRNAME}}/ ./src

echo Building documentation...
sphinx-build -b html -c ./{{DOC_DIRNAME}} ./{{DOC_DIRNAME}}/ ./{{DOC_DIRNAME}}/build/html -v
poetry run sphinx-build -b html -c ./{{DOC_DIRNAME}} ./{{DOC_DIRNAME}}/ ./{{DOC_DIRNAME}}/build/html -v

# build and open HTML documentation
@doc: _build-doc
Expand Down
34 changes: 34 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
[tool.poetry]
name = "cleanpython"
version = "0.1.0"
description = "Clean code with batteries included."
authors = ["iacopo <[email protected]>"]
license = "MIT"
readme = "README.md"

[tool.poetry.dependencies]
python = "^3.11"
Flask = "^3.0.0" # Just an example

[tool.poetry.group.dev.dependencies]
pytest = "^7.4.3"
pytest-benchmark = "^4.0.0"
pytest-cov = "^4.1.0"
coverage = "^7.3.2"
mypy = "^1.6.1"
pylint = "^3.0.2"
flake8 = "^6.1.0"
isort = "^5.12.0"
black = "^23.10.1"

[tool.poetry.group.docs]
optional = true

[tool.poetry.group.docs.dependencies]
Sphinx = "^7.2.6"
sphinx-sizzle-theme = "^0.1.3"
myst-parser = "^2.0.0"

[build-system]
requires = ["poetry-core"]
build-backend = "poetry.core.masonry.api"
Loading