From 499661631dae6a904d8f97852ec3dade81116dc2 Mon Sep 17 00:00:00 2001 From: Olaf Haag <83961384+Olaf-Wolf3D@users.noreply.github.com> Date: Tue, 14 May 2024 02:30:29 +0300 Subject: [PATCH] chore: update project settings and ci workflow * update authors * use hatch 1.10 internal envs for tests and linting, replace black with ruff formatter * ci: update test workflow to use new hatch envs, more Python versions * docs: update contributing guide with improved setup instructions * ci: fix linting target python version mismatch * ci: upgrade to artifact v4, upload only latest Python results --- .github/workflows/test.yml | 16 +-- .pre-commit-config.yaml | 13 +-- CONTRIBUTING.md | 12 +-- pyproject.toml | 212 +++++++++++++++++-------------------- 4 files changed, 117 insertions(+), 136 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 5eb19c6..85e3e50 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -29,7 +29,7 @@ jobs: fail-fast: false matrix: os: [ubuntu-latest] - python-version: ['3.11'] + python-version: ['3.12', '3.11', '3.10'] steps: - uses: actions/checkout@v3 @@ -43,7 +43,7 @@ jobs: run: pip install --upgrade hatch - name: Run tests - run: hatch run test:cov + run: hatch test --python ${{ matrix.python-version }} --cover - name: Prepare artifact run: | @@ -52,14 +52,16 @@ jobs: cp -r tests/.coverage artifact/.coverage - name: Upload performance & coverage report artifact - uses: actions/upload-artifact@v3 + # Only upload the artifact for the first (most recent supported) Python version in the matrix. + if: strategy.job-index == 0 + uses: actions/upload-artifact@v4 with: - name: coverage-profiling + name: coverage-profiling-${{ matrix.os }}-Py${{ matrix.python-version }} path: artifact if-no-files-found: error - - name: Run linting - run: hatch run lint:style + - name: Run static analysis + run: hatch fmt --check - name: Run type-checking - run: hatch run lint:typing + run: hatch run types:check diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 1b9550b..f440013 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -22,18 +22,11 @@ repos: # Code style and formatting - repo: https://github.com/astral-sh/ruff-pre-commit # Ruff version. - rev: v0.4.3 + rev: v0.4.4 hooks: - id: ruff - args: [--fix, --exit-non-zero-on-fix] - - - repo: https://github.com/psf/black - rev: 24.4.2 - hooks: - - id: black - args: [ - --line-length, "120", - ] + args: [ --fix, --exit-non-zero-on-fix ] + - id: ruff-format - repo: https://github.com/HunterMcGushion/docstr_coverage rev: v2.3.0 diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index a392aba..d1c3c15 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -43,10 +43,10 @@ The [`good first issue` label](https://github.com/readyplayerme/meshops/issues?q It's best to use a separate Python _environment_ for development to avoid conflicts with other Python projects and keep your system Python clean. In this section we'll provide instructions on how to set up such an environment for the project. We use [hatch](https://hatch.pypa.io/) as the Python package build backend and Python project manager. -We recommend to install it as it will provide you with a project-specific development environment. However, using hatch is not a necessity, but more of a convenience. +We recommend to install it as it will provide you with a project-specific development environment, including the required Python version as a virtual environment. However, using hatch is not a necessity, but more of a convenience. 1. You can read [hatch's installation instructions](https://hatch.pypa.io/latest/install/) for information on how to install it on your system. -Since version 1.8.0, hatch is available as pre-built binaries and can install the required Python version as a virtual environment. +You should get at least hatch **v1.10.0**. 2. Prepare the environment for development. Once you have setup hatch, navigate to the cloned repository, and execute: @@ -55,8 +55,8 @@ Since version 1.8.0, hatch is available as pre-built binaries and can install th hatch env create ``` - This will create yet a new environment within a `.venv` folder of the project and install the development dependencies into it. - An IDE like [Visual Studio Code](https://code.visualstudio.com/) will automatically detect this environment and suggest to you to use it as the Python interpreter for this repository. + This will create a new virtual environment for development and install the development dependencies into it. + An IDE like [Visual Studio Code](https://code.visualstudio.com/) can [detect hatch environments](https://hatch.pypa.io/latest/how-to/integrate/vscode/) for you to use it as the Python interpreter for this repository. It also installs [pre-commit](https://pre-commit.com/) hooks into the repository, which will run linting and formatting checks before you commit your changes. Alternatively, you can get the new environment path and add it to your IDE as a Python interpreter for this repository with: @@ -68,7 +68,7 @@ Since version 1.8.0, hatch is available as pre-built binaries and can install th If you decided against using hatch, we still recommend installing the pre-commit hooks. ```powershell - pre-commit install -t pre-commit -t commit-msg -t pre-push + pre-commit install --overwrite -t pre-commit -t commit-msg -t pre-push ``` ### Branch Off & Make Your Changes @@ -79,7 +79,7 @@ Since version 1.8.0, hatch is available as pre-built binaries and can install th 2. Write or update tests for your changes. -3. Run tests with `hatch run test` and or run linting & formatting and tests with `hatch run all` locally. +3. Run tests with `hatch test --cover` and or run linting & formatting and tests with `hatch fmt` locally, as well as `hatch run types:check` for static type checking. ### Commit your update diff --git a/pyproject.toml b/pyproject.toml index c6314b9..092ed48 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -9,14 +9,24 @@ description = "This package provides means to help with mesh processing and some readme = "README.md" requires-python = ">=3.10" license = "MIT" -keywords = ["ready player me", "gltf", "3D", "mesh", "texture", "texture mapping", "uv mapping", "uv", "uv seam", "uv border",] +keywords = [ + "ready player me", + "gltf", + "3D", + "mesh", + "texture", + "texture mapping", + "uv mapping", + "uv", + "uv seam", + "uv border", +] authors = [ { name = "Ready Player Me", email = "info@readyplayer.me" }, -] -maintainers = [ - { name = "Daniel-Ionut Rancea", email = "daniel-ionut.rancea@readyplayer.me" }, { name = "Olaf Haag", email = "olaf@readyplayer.me" }, + { name = "Daniel-Ionut Rancea" }, ] +maintainers = [{ name = "Olaf Haag", email = "olaf@readyplayer.me" }] classifiers = [ "Development Status :: 2 - Pre-Alpha", "License :: OSI Approved :: MIT License", @@ -25,30 +35,12 @@ classifiers = [ "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", "Topic :: Multimedia :: Graphics", - "Topic :: Multimedia :: Graphics :: 3D Modeling" -] -dependencies = [ - "trimesh[recommend]>=4.0.1", - "pillow", - "scipy", + "Topic :: Multimedia :: Graphics :: 3D Modeling", ] +dependencies = ["trimesh[recommend]>=4.0.1", "pillow", "scipy"] [project.optional-dependencies] -test = [ - "pytest", - "pytest-xdist", - "coverage[toml]>=6.5", - "pyinstrument", -] -lint = [ - "black==24.4.2", - "mypy==1.10.0", - "ruff==0.4.3", -] -dev = [ - "readyplayerme.meshops[test, lint]", - "pre-commit", -] +dev = ["pre-commit"] [project.urls] Documentation = "https://github.com/readyplayerme/meshops#readme" @@ -62,74 +54,59 @@ path = "src/readyplayerme/meshops/__about__.py" packages = ["src/readyplayerme"] [tool.hatch.envs.default] +installer = "uv" description = "Python virtual environment in project dir to quickly get up and running in an IDE like VSCode." type = "virtual" -path = ".venv" -features = [ - "dev", -] -post-install-commands = [ - "install-precommit", -] +features = ["dev"] +post-install-commands = ["install-precommit"] [tool.hatch.envs.default.scripts] install-precommit = "pre-commit install --overwrite -t pre-commit -t commit-msg -t pre-push" -test = "pytest {args:tests}" -test-cov = "coverage run -m pytest {args:tests}" -cov-report = [ - "- coverage combine", - "coverage report", - "coverage html -d ./tests/.coverage", -] -cov = [ - "test-cov", - "cov-report", -] -typing = "mypy --install-types --non-interactive {args:src/readyplayerme/meshops tests}" -style = [ - "ruff check {args:.}", - "black --check --diff {args:.}", -] -fmt = [ - "black {args:.}", - "ruff --fix {args:.}", - "style", -] -all = [ - "style", - "typing", - "cov", -] -[tool.hatch.envs.lint] -description = "Python virtual environment to be used in CI to run linting and type checking." -# Note: This still inherits the path from the default env, so it will use the same venv. -features = [ - "lint", -] -post-install-commands = [] +[tool.hatch.envs.hatch-test] +extra-dependencies = ["pyinstrument"] +randomize = true +parallel = true +retries = 2 +retry-delay = 1 -[tool.hatch.envs.test] -description = "Python virtual environment to be used in CI to run tests." -# Note: This still inherits the path from the default env, so it will use the same venv. -features = [ - "test", -] +[[tool.hatch.envs.hatch-test.matrix]] +python = ["3.12", "3.11", "3.10"] + +[tool.hatch.envs.hatch-test.scripts] +run = "pytest{env:HATCH_TEST_ARGS:} {args}" +run-cov = "coverage run -m pytest{env:HATCH_TEST_ARGS:} {args}" +cov-combine = "coverage combine" +cov-html = "coverage html -d ./tests/.coverage" +cov-report = ["coverage report", "cov-html"] + +[tool.hatch.envs.hatch-test.extra-scripts] +pip = "{env:HATCH_UV} pip {args}" + +[tool.hatch.envs.hatch-static-analysis] +dependencies = ["ruff==0.4.4"] +# Disable the hatch's default config and use the one from the project. +config-path = "none" + +[tool.hatch.envs.types] +extra-dependencies = ["mypy==1.10.0", "pytest"] +installer = "uv" post-install-commands = [] -[[tool.hatch.envs.all.matrix]] -python = ["3.10", "3.11"] +[tool.hatch.envs.types.scripts] +check = "mypy --install-types --non-interactive {args:src/readyplayerme/meshops tests}" -[tool.pytest.ini_options] -#addopts="-n auto" +# Workaround for mypy using pip instead of uv, to avoid "pip not found" error. +[[tool.hatch.envs.types.matrix]] +tool = ["uv"] -[tool.black] -target-version = ["py310", "py311"] -line-length = 120 -skip-string-normalization = false +[tool.hatch.envs.types.overrides] +matrix.tool.installer = { value = "{matrix:tool}" } +matrix.tool.scripts = [ + { key = "pip", value = "{env:HATCH_UV} pip {args}", if = ["uv"] }, +] [tool.ruff] -target-version = "py311" line-length = 120 builtins = ["_"] @@ -173,13 +150,28 @@ ignore = [ # Allow boolean positional values in function calls, like `dict.get(... True)` "FBT003", # Allow try-except-pass & try-except-continue - "S110", "S112", + "S110", + "S112", # Ignore complexity - "C901", "PLR0911", "PLR0912", "PLR0913", "PLR0915", + "C901", + "PLR0911", + "PLR0912", + "PLR0913", + "PLR0915", # Exclude self, cls, args, kwargs from annotation, allow dynamically typed expressions (typing.Any) in type annotations - "ANN101", "ANN102", "ANN002", "ANN003", "ANN401", + "ANN101", + "ANN102", + "ANN002", + "ANN003", + "ANN401", # Don't require documentation for every function parameter and magic methods. - "D417", "D102", "D105", "D107", "D100" + "D417", + "D102", + "D105", + "D107", + "D100", + # hatch recommends to ignore implicitly concatenated strings on a single line to avoid conflicts with the formatter. + "ISC001", ] unfixable = [ # Don't touch unused imports @@ -187,27 +179,27 @@ unfixable = [ ] # Exclude a variety of commonly ignored directories. exclude = [ - ".bzr", - ".direnv", - ".eggs", - ".git", - ".git-rewrite", - ".hg", - ".mypy_cache", - ".nox", - ".pants.d", - ".pytype", - ".ruff_cache", - ".svn", - ".tox", - ".venv", - "__pypackages__", - "_build", - "buck-out", - "build", - "dist", - "node_modules", - "venv", + ".bzr", + ".direnv", + ".eggs", + ".git", + ".git-rewrite", + ".hg", + ".mypy_cache", + ".nox", + ".pants.d", + ".pytype", + ".ruff_cache", + ".svn", + ".tox", + ".venv", + "__pypackages__", + "_build", + "buck-out", + "build", + "dist", + "node_modules", + "venv", ] [tool.ruff.lint.isort] @@ -271,17 +263,11 @@ ignore_missing_imports = true source_pkgs = ["readyplayerme", "readyplayerme.meshops"] branch = true parallel = true -omit = [ - "src/readyplayerme/*/__about__.py", -] +omit = ["src/readyplayerme/*/__about__.py"] [tool.coverage.paths] coverage_debugging = ["src/readyplayerme", "*/meshops/src/readyplayerme"] [tool.coverage.report] include_namespace_packages = true -exclude_lines = [ - "no cov", - "if __name__ == .__main__.:", - "if TYPE_CHECKING:", -] +exclude_lines = ["no cov", "if __name__ == .__main__.:", "if TYPE_CHECKING:"]