diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 000000000..88363add0 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,6 @@ +version: 2 +updates: + - package-ecosystem: "pip" + directory: "/requirements" + schedule: + interval: "daily" diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 000000000..f29d06272 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,113 @@ +name: GitHub CI +on: + pull_request: + push: + tags: + - "*" + branches: + - main + +jobs: + + style: + name: Code style + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: Set up Python + uses: actions/setup-python@v2 + with: + python-version: 3.7 + - name: Install dependencies + run: | + python -m pip install --upgrade pip tox + - name: Test with tox + run: tox -e style + + + tests: + name: Test baked project + runs-on: ${{ matrix.os }} + strategy: + matrix: + os: [windows-latest, ubuntu-latest] + python-version: ["3.7", "3.8", "3.9", "3.10"] + build-system: ["flit", "setuptools"] + fail-fast: false + + steps: + - uses: actions/checkout@v2 + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v2 + with: + python-version: ${{ matrix.python-version }} + + - name: Install dependencies + run: python -m pip install --upgrade pip ${{ matrix.build-system }} tox tox-gh-actions + + # Runs only the tox environment specified in tox.ini [gh-actions] + - name: Test with tox-gh-actions + run: tox + + # Baked project actions are tested only for Linux-base OS + - name: Install and configure act for Linux-based OS + if: matrix.os == 'ubuntu-latest' + run: | + sudo apt-get install build-essential gcc + /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" + test -d ~/.linuxbrew && eval "$(~/.linuxbrew/bin/brew shellenv)" + test -d /home/linuxbrew/.linuxbrew && eval "$(/home/linuxbrew/.linuxbrew/bin/brew shellenv)" + test -r ~/.bash_profile && echo "eval \"\$($(brew --prefix)/bin/brew shellenv)\"" >> ~/.bash_profile + brew install act + echo "-P ubuntu-latest=ghcr.io/catthehacker/ubuntu:act-latest" >> ~/.actrc + + - name: Test flit baked project + if: matrix.os == 'ubuntu-latest' && matrix.build-system == 'flit' + run: | + # Change to baked project directory + cd output/test_bake_project_with_build_s0/cookies/bake00/pyproduct-library + # Initialize it as git repository (pre-commit needs it) + git config --global user.email "you@example.com" + git config --global user.name "Your Name" + git init && git add . && git commit -m "Init Python package" + # TODO: Only filter out errors from tox command + # act -j tests docs > act_output.log || true > act_output.log; grep -c ERROR act_output.log && cat act_output.log + tox + # Check package builds properly + python -m pip install -r requirements/requirements_build.txt + flit build + python -m twine check dist/* + + - name: Test poetry baked project + if: matrix.os == 'ubuntu-latest' && matrix.build-system == 'poetry' + run: | + # Change to baked project directory + cd output/test_bake_project_with_build_s1/cookies/bake00/pyproduct-library + # Initialize it as git repository (pre-commit needs it) + git config --global user.email "you@example.com" + git config --global user.name "Your Name" + git init && git add . && git commit -m "Init Python package" + # TODO: Only filter out errors from tox command + # act -j tests docs > act_output.log || true > act_output.log; grep -c ERROR act_output.log && cat act_output.log + tox + # Check package builds properly + poetry run python -m pip install -r requirements/requirements_build.txt + poetry build + poetry run python -m twine check dist/* + + - name: Test setuptools baked project + if: matrix.os == 'ubuntu-latest' && matrix.build-system == 'setuptools' + run: | + # Change to baked project directory + cd output/test_bake_project_with_build_s2/cookies/bake00/pyproduct-library + # Initialize it as git repository (pre-commit needs it) + git config --global user.email "you@example.com" + git config --global user.name "Your Name" + git init && git add . && git commit -m "Init Python package" + # TODO: Only filter out errors from tox command + # act -j tests docs > act_output.log || true > act_output.log; grep -c ERROR act_output.log && cat act_output.log + tox + # Check package builds properly + python -m pip install -r requirements/requirements_build.txt + python -m build + python -m twine check dist/* diff --git a/.gitignore b/.gitignore index 131895535..7d5839d3e 100644 --- a/.gitignore +++ b/.gitignore @@ -156,3 +156,6 @@ cython_debug/ #.idea/ # End of https://www.toptal.com/developers/gitignore/api/python + +# Ignore baked output cookies from debugging +output/ diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 000000000..6bd904043 --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,39 @@ +repos: + +- repo: https://github.com/psf/black + rev: 22.1.0 + hooks: + - id: black + exclude: "^({{cookiecutter.project_name_slug}}/)" + args: ["tests", "hooks"] + +- repo: https://github.com/pycqa/isort + rev: 5.10.1 + hooks: + - id: isort + args: [ + "--profile", "black", + "--force-sort-within-sections", + "--line-length", "100", + "--section-default", "THIRDPARTY", "hooks", "tests" + ] + +- repo: https://gitlab.com/PyCQA/flake8 + rev: 4.0.1 + hooks: + - id: flake8 + args: ["tests", "hooks"] + exclude: "^({{cookiecutter.project_name_slug}}/)" + +- repo: https://github.com/codespell-project/codespell + rev: v2.1.0 + hooks: + - id: codespell + +- repo: https://github.com/pycqa/pydocstyle + rev: 6.1.1 + hooks: + - id: pydocstyle + additional_dependencies: [toml] + args: ["--match-dir='^(hooks)'"] + exclude: "^({{cookiecutter.project_name_slug}}/)|(tests/)" diff --git a/LICENSE b/LICENSE new file mode 100644 index 000000000..ea581cdfa --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2022 ANSYS, Inc. All rights reserved. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md deleted file mode 100644 index 593f2313c..000000000 --- a/README.md +++ /dev/null @@ -1 +0,0 @@ -# PyAnsys library as cookiecutter template diff --git a/README.rst b/README.rst new file mode 100644 index 000000000..5efacf998 --- /dev/null +++ b/README.rst @@ -0,0 +1,68 @@ +PyAnsys library as cookiecutter template +======================================== + +This repository holds a `cookiecutter`_ template for +creating a Python library. The process is fully interactive and the rendered +project is compliant with the `PyAnsys Developer's guide`_. + + +Requirements +------------ + +Before creating your library, you will need to install `cookiecutter`_ via: + +.. code:: bash + + python -m pip install cookiecutter + + +How to use +---------- + +Once you have installed `cookiecutter`_, you can create a new Python library by +calling this template using: + +.. code:: bash + + cookiecutter gh:pyansys/pyansys-template + +Previous command will ask you to introduce different data regarding your new +Python project. Some of these are already pre-defined but you can always change +their value: + +- **product_name**: the name of Ansys product (i.e. Product). +- **product_name_slug**: product sanitized name (i.e. product). +- **library_name**: the name of the product library (i.e. Library). +- **library_name_slug**: library named sanitized (i.e. library). +- **project_name_slug**: the project's directory name (i.e. pyproduct-library). +- **pkg_name**: the name of the Python package/library (i.e. ansys-product-library). +- **version**: the version of the package/library (i.e. 0.1.dev0). +- **short_description**: a short description of the purpose/goal of the project. +- **repository_url**: link to the repository where the source code will be hosted. +- **requires_python**: choose the minimum required Python version among 3.7, 3.8, 3.9 or 3.10. +- **build_system**: choose the build system among flit, poetry or setuptools. +- **max_linelength**: maximum number of characters per line in the source code (i.e. 100). + + +How to contribute +----------------- + +For developers, the requirements can be installed via: + +.. code:: bash + + python -m pip install -r requirements/requirements_dev.txt + +The coding style checks and unit tests are executed via `tox`_. Simply execute: + +.. code:: bash + + tox + +and all the environments (style and tests) will be checked. + + +.. LINKS AND REFERENCES +.. _cookiecutter: https://cookiecutter.readthedocs.io/en/latest/ +.. _PyAnsys Developer's guide: https://dev.docs.pyansys.com/ +.. _tox: https://tox.wiki/ diff --git a/cookiecutter.json b/cookiecutter.json new file mode 100644 index 000000000..631462f00 --- /dev/null +++ b/cookiecutter.json @@ -0,0 +1,14 @@ +{ + "product_name": "product", + "product_name_slug": "{{ cookiecutter.product_name | lower | slugify }}", + "library_name": "library", + "library_name_slug": "{{ cookiecutter.library_name | lower | slugify }}", + "project_name_slug": "py{{ cookiecutter.product_name_slug }}-{{ cookiecutter.library_name_slug }}", + "pkg_name": "ansys-{{ cookiecutter.product_name_slug }}-{{ cookiecutter.library_name_slug }}", + "version": "0.1.dev0", + "short_description": "A Python wrapper for Ansys {{ cookiecutter.product_name }} {{ cookiecutter.library_name }}", + "repository_url": "https://github.com/pyansys/{{ cookiecutter.project_name_slug }}", + "requires_python": ["3.7", "3.8", "3.9", "3.10"], + "build_system": ["flit", "poetry", "setuptools"], + "max_linelength": "100" +} diff --git a/hooks/post_gen_project.py b/hooks/post_gen_project.py new file mode 100644 index 000000000..d1f42fed1 --- /dev/null +++ b/hooks/post_gen_project.py @@ -0,0 +1,75 @@ +"""Post-processing script for cleaning the raw rendered project.""" +import os +from pathlib import Path + +import isort + +ALLOWED_BUILD_SYSTEMS = ["flit", "poetry", "setuptools"] +"""A list of all allowed build systems by the template.""" + + +def remove_tool_files(tool_name, basedir): + """ + Remove files matching given glob expression within desired base directory. + + Parameters + ---------- + tool_name: str + Name of the tool used as build system. + basedir: Path + Base directory path. + + """ + for filepath in basedir.glob(f"**/*_{tool_name}*"): + filepath.unlink() + + +def rename_tool_files(tool_name, basedir): + """Rename tool filenames within desired base directory. + + Parameters + ---------- + tool_name: str + Name of the tool used as build system. + basedir: Path + Base directory path. + + """ + for original_filepath in basedir.glob(f"**/*_{tool_name}*"): + new_filename = original_filepath.name.replace(f"_{tool_name}", "") + original_filepath.rename(Path(original_filepath.parent, new_filename)) + + +def main(): + """Entry point of the script.""" + # Get baked project location path + project_path = Path(os.getcwd()) + + # Get the desired build system + build_system = "{{ cookiecutter.build_system }}" + # TODO: warn user if using setup.py + # if build_system == "setuptools": + # raise Warning("Please, consider to update to pyproject.toml.") + + # Remove non-desired build system files + for tool in ALLOWED_BUILD_SYSTEMS: + if tool != build_system: + remove_tool_files(tool, project_path) + + # Rename any files including tool name suffix + rename_tool_files(build_system, project_path) + + # Apply isort with desired config + isort_config = isort.settings.Config( + line_length=100, + profile="black", + ) + filepaths_list = [ + project_path / "doc/source/conf.py", + ] + for filepath in filepaths_list: + isort.api.sort_file(filepath, isort_config) + + +if __name__ == "__main__": + main() diff --git a/hooks/pre_gen_project.py b/hooks/pre_gen_project.py new file mode 100644 index 000000000..8ff9416f2 --- /dev/null +++ b/hooks/pre_gen_project.py @@ -0,0 +1,29 @@ +"""Pre-processing script for cleaning the raw rendered project.""" +import subprocess +import sys + + +def install_package(package): + """ + Installs desired package in current Python environment. + + Parameters + ---------- + package: str + Name of the package. + + """ + subprocess.check_call( + [sys.executable, "-m", "pip", "install", "--ignore-installed", package] + ) + + +def main(): + """Entry point of the script.""" + packages_list = ["isort"] + for package in packages_list: + install_package(package) + + +if __name__ == "__main__": + main() diff --git a/requirements/requirements_dev.txt b/requirements/requirements_dev.txt new file mode 100644 index 000000000..f09a528f1 --- /dev/null +++ b/requirements/requirements_dev.txt @@ -0,0 +1,2 @@ +cookiecutter==1.7.3 +tox==3.24.5 diff --git a/requirements/requirements_tests.txt b/requirements/requirements_tests.txt new file mode 100644 index 000000000..725d1821e --- /dev/null +++ b/requirements/requirements_tests.txt @@ -0,0 +1,2 @@ +pytest +pytest-cookies diff --git a/tests/test_template.py b/tests/test_template.py new file mode 100644 index 000000000..612a58299 --- /dev/null +++ b/tests/test_template.py @@ -0,0 +1,69 @@ +import pytest + +PRODUCT_NAME = "Product" +PRODUCT_NAME_SLUG = PRODUCT_NAME.lower().replace(" ", "-").replace("_", "-") +LIBRARY_NAME = "Library" +LIBRARY_NAME_SLUG = LIBRARY_NAME.lower().replace(" ", "-").replace("_", "-") +PROJECT_NAME_SLUG = f"py{PRODUCT_NAME_SLUG}-{LIBRARY_NAME_SLUG}" +PKG_NAME = f"ansys-{PRODUCT_NAME_SLUG}-{LIBRARY_NAME_SLUG}" +VERSION = "0.1.dev0" +SHORT_DESCRIPTION = f"A Python wrapper for Ansys {PRODUCT_NAME} {LIBRARY_NAME}" +REPOSITORY_URL = f"https://github.com/pyansys/{PROJECT_NAME_SLUG}" +REQUIRES_PYTHON = "3.7" +MAX_LINELENGTH = "100" + + +@pytest.mark.parametrize("tool", ["flit", "poetry", "setuptools"]) +def test_bake_project_with_build_system(cookies, tool): + result = cookies.bake( + extra_context={ + "product_name": PRODUCT_NAME, + "product_name_slug": PRODUCT_NAME_SLUG, + "library_name": LIBRARY_NAME, + "library_name_slug": LIBRARY_NAME_SLUG, + "project_name_slug": PROJECT_NAME_SLUG, + "pkg_name": PKG_NAME, + "version": VERSION, + "short_description": SHORT_DESCRIPTION, + "repository_url": REPOSITORY_URL, + "requires_python": REQUIRES_PYTHON, + "build_system": tool, + "max_linelength": MAX_LINELENGTH, + } + ) + + assert result.exit_code == 0, result.exception + assert result.exception is None + assert result.project_path.name == PROJECT_NAME_SLUG + assert result.project_path.is_dir() + + files = [ + ".github/workflows/ci_cd.yml", + ".gitignore", + ".flake8", + ".pre-commit-config.yaml", + "LICENSE", + "README.rst", + "requirements/requirements_tests.txt", + "requirements/requirements_doc.txt", + "requirements/requirements_build.txt", + "pyproject.toml" if tool != "setuptools" else "setup.py", + "tox.ini", + ] + + dirs = [ + ".github", + ".github/workflows", + "doc", + "doc/source", + "requirements", + "src", + "src/ansys/" + PRODUCT_NAME_SLUG, + "src/ansys/" + PRODUCT_NAME_SLUG + "/" + LIBRARY_NAME_SLUG, + "tests", + ] + + for path in files: + assert (result.project_path / path).is_file() + for path in dirs: + assert (result.project_path / path).is_dir() diff --git a/tox.ini b/tox.ini new file mode 100644 index 000000000..a1686133d --- /dev/null +++ b/tox.ini @@ -0,0 +1,37 @@ +[tox] +description = Default environments to be executed when calling tox +envlist = + style,{py37,py38,py39,py310}-{keep-output} +skipsdist = true + +[gh-actions] +python = + 3.7: py37-keep-output + 3.8: py38-keep-output + 3.9: py39-keep-output + 3.10: py310-keep-output + +[testenv] +description = Generic environment configuration +basepython = + py37: python3.7 + py38: python3.8 + py39: python3.9 + py310: python3.10 + {style}: python3 +setenv = + PYTHONUNBUFFERED = yes + keep-output: PYTEST_MARKERS = --keep-baked-projects --basetemp=output +deps = + -r{toxinidir}/requirements/requirements_tests.txt +commands = + pytest {env:PYTEST_MARKERS:} {posargs: tests -vv} + +[testenv:style] +description = Checks if code style applies +skip_install = true +deps = + pre-commit +commands = + pre-commit install + pre-commit run --all-files --show-diff-on-failure diff --git a/{{cookiecutter.project_name_slug}}/.flake8 b/{{cookiecutter.project_name_slug}}/.flake8 new file mode 100644 index 000000000..072126e50 --- /dev/null +++ b/{{cookiecutter.project_name_slug}}/.flake8 @@ -0,0 +1,7 @@ +[flake8] +exclude = venv, __init__.py, doc/_build, .venv +select = W191, W291, W293, W391, E115, E117, E122, E124, E125, E225, E231, E301, E303, E501, F401, F403 +count = True +max-complexity = 10 +max-line-length = {{ cookiecutter.max_linelength }} +statistics = True diff --git a/{{cookiecutter.project_name_slug}}/.github/workflows/ci_cd.yml b/{{cookiecutter.project_name_slug}}/.github/workflows/ci_cd.yml new file mode 100644 index 000000000..9b9a15ef0 --- /dev/null +++ b/{{cookiecutter.project_name_slug}}/.github/workflows/ci_cd.yml @@ -0,0 +1,84 @@ +name: GitHub CI +on: + pull_request: + push: + tags: + - "*" + branches: + - main + +jobs: + + style: + name: Code style + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: Set up Python + uses: actions/setup-python@v2 + with: + python-version: {{ cookiecutter.requires_python }} + - name: Install dependencies + run: | + python -m pip install --upgrade pip {{ cookiecutter.build_system }} tox + - name: Test with tox + run: tox -e style + + + tests: + name: Tests and coverage + runs-on: {{ '${{ matrix.os }}' }} + strategy: + matrix: + os: [windows-latest, ubuntu-latest] + python-version: ["3.7", "3.8", "3.9", "3.10"] + fail-fast: false + steps: + - uses: actions/checkout@v2 + - name: Set up Python {{ '${{ matrix.python-version }}' }} + uses: actions/setup-python@v2 + with: + python-version: {{ '${{ matrix.python-version }}' }} + - name: Install dependencies + run: | + python -m pip install --upgrade pip {{ cookiecutter.build_system }} tox tox-gh-actions + - name: Test with tox + # Only the tox environment specified in the tox.ini gh-actions is run + run: tox + + + docs: + name: Documentation + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: Set up Python + uses: actions/setup-python@v2 + with: + python-version: 3.7 + - name: Install dependencies + run: | + python -m pip install --upgrade pip {{ cookiecutter.build_system }} tox + - name: Test with tox + run: tox -e doc + + + build: + name: Build library + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: Set up Python + uses: actions/setup-python@v2 + with: + python-version: 3.7 + - name: Install dependencies + run: | + python -m pip install --upgrade pip {{ cookiecutter.build_system }} + python -m pip install -r requirements/requirements_build.txt + {% if cookiecutter.build_system in ["flit", "poetry"] -%} + {{ cookiecutter.build_system }} build + {% elif cookiecutter.build_system == "setuptools" -%} + python -m build + {% endif -%} + python -m twine check dist/* diff --git a/{{cookiecutter.project_name_slug}}/.gitignore b/{{cookiecutter.project_name_slug}}/.gitignore new file mode 100644 index 000000000..131895535 --- /dev/null +++ b/{{cookiecutter.project_name_slug}}/.gitignore @@ -0,0 +1,158 @@ +# Created by https://www.toptal.com/developers/gitignore/api/python +# Edit at https://www.toptal.com/developers/gitignore?templates=python + +### Python ### +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +share/python-wheels/ +*.egg-info/ +.installed.cfg +*.egg +MANIFEST + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.nox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*.cover +*.py,cover +.hypothesis/ +.pytest_cache/ +cover/ + +# Translations +*.mo +*.pot + +# Django stuff: +*.log +local_settings.py +db.sqlite3 +db.sqlite3-journal + +# Flask stuff: +instance/ +.webassets-cache + +# Scrapy stuff: +.scrapy + +# Sphinx documentation +docs/_build/ + +# PyBuilder +.pybuilder/ +target/ + +# Jupyter Notebook +.ipynb_checkpoints + +# IPython +profile_default/ +ipython_config.py + +# pyenv +# For a library or package, you might want to ignore these files since the code is +# intended to run in multiple environments; otherwise, check them in: +# .python-version + +# pipenv +# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. +# However, in case of collaboration, if having platform-specific dependencies or dependencies +# having no cross-platform support, pipenv may install dependencies that don't work, or not +# install all needed dependencies. +#Pipfile.lock + +# poetry +# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control. +# This is especially recommended for binary packages to ensure reproducibility, and is more +# commonly ignored for libraries. +# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control +#poetry.lock + +# PEP 582; used by e.g. github.com/David-OConnor/pyflow +__pypackages__/ + +# Celery stuff +celerybeat-schedule +celerybeat.pid + +# SageMath parsed files +*.sage.py + +# Environments +.env +.venv +env/ +venv/ +ENV/ +env.bak/ +venv.bak/ + +# Spyder project settings +.spyderproject +.spyproject + +# Rope project settings +.ropeproject + +# mkdocs documentation +/site + +# mypy +.mypy_cache/ +.dmypy.json +dmypy.json + +# Pyre type checker +.pyre/ + +# pytype static type analyzer +.pytype/ + +# Cython debug symbols +cython_debug/ + +# PyCharm +# JetBrains specific template is maintainted in a separate JetBrains.gitignore that can +# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore +# and can be added to the global gitignore or merged into this file. For a more nuclear +# option (not recommended) you can uncomment the following to ignore the entire idea folder. +#.idea/ + +# End of https://www.toptal.com/developers/gitignore/api/python diff --git a/{{cookiecutter.project_name_slug}}/.pre-commit-config.yaml b/{{cookiecutter.project_name_slug}}/.pre-commit-config.yaml new file mode 100644 index 000000000..05df9ea77 --- /dev/null +++ b/{{cookiecutter.project_name_slug}}/.pre-commit-config.yaml @@ -0,0 +1,37 @@ +repos: + +- repo: https://github.com/psf/black + rev: 22.1.0 + hooks: + - id: black + args: ["src", "tests"] + +- repo: https://github.com/pycqa/isort + rev: 5.10.1 + hooks: + - id: isort + args: [ + "--profile", "black", + "--force-sort-within-sections", + "--line-length", "{{ cookiecutter.max_linelength }}", + "--section-default", "THIRDPARTY", "src", "tests" + ] + +- repo: https://gitlab.com/PyCQA/flake8 + rev: 4.0.1 + hooks: + - id: flake8 + args: ["src", "tests"] + +- repo: https://github.com/codespell-project/codespell + rev: v2.1.0 + hooks: + - id: codespell + +- repo: https://github.com/pycqa/pydocstyle + rev: 6.1.1 + hooks: + - id: pydocstyle + additional_dependencies: [toml] + args: ["--match-dir='^(src)'"] + exclude: "^(tests/)" diff --git a/{{cookiecutter.project_name_slug}}/LICENSE b/{{cookiecutter.project_name_slug}}/LICENSE new file mode 100644 index 000000000..cc26aa180 --- /dev/null +++ b/{{cookiecutter.project_name_slug}}/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) {% now 'utc', '%Y' %} ANSYS, Inc. All rights reserved. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/{{cookiecutter.project_name_slug}}/README.rst b/{{cookiecutter.project_name_slug}}/README.rst new file mode 100644 index 000000000..4775a2058 --- /dev/null +++ b/{{cookiecutter.project_name_slug}}/README.rst @@ -0,0 +1,184 @@ +Py{{ cookiecutter.product_name }} {{ cookiecutter.library_name }} +{{ '=' * (cookiecutter.project_name_slug | length) }} + +{{ cookiecutter.short_description }} + + +How to install +-------------- + +At least two installation modes are provided: user and developer. + +For users +^^^^^^^^^ + +In order to install Py{{ cookiecutter.product_name }} {{ cookiecutter.library_name }}, make sure you +have the required build system tool. To do so, run: + +.. code:: bash + + python -m pip install -U pip {{ cookiecutter.build_system }} + +Then, you can simply execute: + +{% if cookiecutter.build_system in ["flit", "setuptools"] -%} + +.. code:: bash + + python -m pip install {{ cookiecutter.pkg_name }} + +{% elif cookiecutter.build_system == "poetry" -%} + +.. code:: bash + + poetry run python -m pip install {{ cookiecutter.pkg_name }} + +{% endif -%} + + +For developers +^^^^^^^^^^^^^^ + +Installing Py{{ cookiecutter.product_name }} {{ cookiecutter.library_name }} in developer mode allows +you to modify the source and enhance it. + +Before contributing to the project, please refer to the `PyAnsys Developer's guide`_. You will +need to follow these steps: + +1. Start by cloning this repository: + + .. code:: bash + + git clone {{ cookiecutter.repository_url }} + +2. Create a fresh-clean Python environment and activate it: + + .. code:: bash + + python -m venv .venv && source venv .venv + +3. Make sure you have the latest required build system and testing/CI tools: + + .. code:: bash + + python -m pip install -U pip {{ cookiecutter.build_system }} tox + +4. Install the project in editable mode: + + {% if cookiecutter.build_system in ["flit", "setuptools"] -%} + + .. code:: bash + + python -m pip install --editable {{ cookiecutter.pkg_name }} + + {% elif cookiecutter.build_system == "poetry" -%} + + .. code:: bash + + poetry run python -m pip install {{ cookiecutter.pkg_name }} + + {% endif -%} + +5. Finally, verify your development installation by running: + + .. code:: bash + + tox + + +How to testing +-------------- + +This project takes advantage of `tox`_. This tool allows to automate common +development tasks (similar to Makefile) but it is oriented towards Python +development. + +Using tox +^^^^^^^^^ + +As Makefile has rules, `tox`_ has environments. In fact, the tool creates its +own virtual environment so anything being tested is isolated from the project in +order to guarantee project's integrity. The following environments commands are provided: + +- **tox -e style**: will check for coding style quality. +- **tox -e py3X**: being X the minor version of your Python environment. Checks for unit tests. +- **tox -e py3X-coverage**: checks for unit testing and code coverage. +- **tox -e doc**: checs for documentation building process. + + +Raw testing +^^^^^^^^^^^ + +If required, you can always call the style commands (`black`_, `isort`_, +`flake8`_...) or unit testing ones (`pytest`_) from the command line. However, +this does not guarantee that your project is being tested in an isolated +environment, which is the reason why tools like `tox`_ exist. + + +A note on pre-commit +^^^^^^^^^^^^^^^^^^^^ + +The style checks take advantage of `pre-commit`_. Developers are not forced but +encouraged to install this tool via: + +.. code:: bash + + python -m pip install pre-commit && pre-commit install + + +Documentation +------------- + +For building documentation, you can either run the usual rules provided in the +`Sphinx`_ Makefile, such us: + +.. code:: bash + + make -C doc/ html && your_browser_name doc/html/index.html + +However, the recommended way of checking documentation integrity is using: + +.. code:: bash + + tox -e doc && your_browser_name .tox/doc_out/html/index.html + + +Distributing +------------ + +If you would like to create either source or wheel files, start by installing +the building requirements: + +.. code:: bash + + python -m pip install -r requirements/requirements_build.txt + +Then, you can execute: + +{% if cookiecutter.build_system in ["flit", "poetry"] -%} + + .. code:: bash + + {{ cookiecutter.build_system }} build + python -m twine check dist/* + +{% elif cookiecutter.build_system == "setuptools" -%} + + .. code:: bash + + python -m pip install -r requirements/requirements_build.txt + python -m build + python -m twine check dist/* + +{% endif -%} + + +.. LINKS AND REFERENCES +.. _black: https://github.com/psf/black +.. _flake8: https://flake8.pycqa.org/en/latest/ +.. _isort: https://github.com/PyCQA/isort +.. _PyAnsys Developer's guide: https://dev.docs.pyansys.com/ +.. _pre-commit: https://pre-commit.com/ +.. _pytest: https://docs.pytest.org/en/stable/ +.. _Sphinx: https://www.sphinx-doc.org/en/master/ +.. _tox: https://tox.wiki/ diff --git a/{{cookiecutter.project_name_slug}}/doc/Makefile b/{{cookiecutter.project_name_slug}}/doc/Makefile new file mode 100755 index 000000000..59714b1ae --- /dev/null +++ b/{{cookiecutter.project_name_slug}}/doc/Makefile @@ -0,0 +1,24 @@ +# Minimal makefile for Sphinx documentation +# + +# You can set these variables from the command line. +SPHINXOPTS = +SPHINXBUILD = sphinx-build +SOURCEDIR = source +BUILDDIR = build + +# Put it first so that "make" without argument is like "make help". +help: + @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) + +.PHONY: help Makefile + +# Catch-all target: route all unknown targets to Sphinx using the new +# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) + + +# Customized clean due to examples gallery +clean: + rm -rf build diff --git a/{{cookiecutter.project_name_slug}}/doc/make.bat b/{{cookiecutter.project_name_slug}}/doc/make.bat new file mode 100644 index 000000000..6247f7e23 --- /dev/null +++ b/{{cookiecutter.project_name_slug}}/doc/make.bat @@ -0,0 +1,35 @@ +@ECHO OFF + +pushd %~dp0 + +REM Command file for Sphinx documentation + +if "%SPHINXBUILD%" == "" ( + set SPHINXBUILD=sphinx-build +) +set SOURCEDIR=source +set BUILDDIR=build + +if "%1" == "" goto help + +%SPHINXBUILD% >NUL 2>NUL +if errorlevel 9009 ( + echo. + echo.The 'sphinx-build' command was not found. Make sure you have Sphinx + echo.installed, then set the SPHINXBUILD environment variable to point + echo.to the full path of the 'sphinx-build' executable. Alternatively you + echo.may add the Sphinx directory to PATH. + echo. + echo.If you don't have Sphinx installed, grab it from + echo.http://sphinx-doc.org/ + exit /b 1 +) + +%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% +goto end + +:help +%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% + +:end +popd diff --git a/{{cookiecutter.project_name_slug}}/doc/source/_static/README.md b/{{cookiecutter.project_name_slug}}/doc/source/_static/README.md new file mode 100644 index 000000000..ff7796e46 --- /dev/null +++ b/{{cookiecutter.project_name_slug}}/doc/source/_static/README.md @@ -0,0 +1 @@ +Static files will be found here (like images and other assets). diff --git a/{{cookiecutter.project_name_slug}}/doc/source/_templates/README.md b/{{cookiecutter.project_name_slug}}/doc/source/_templates/README.md new file mode 100644 index 000000000..86a233caa --- /dev/null +++ b/{{cookiecutter.project_name_slug}}/doc/source/_templates/README.md @@ -0,0 +1 @@ +## Contains templates for the documentation build diff --git a/{{cookiecutter.project_name_slug}}/doc/source/_templates/sidebar-nav-bs.html b/{{cookiecutter.project_name_slug}}/doc/source/_templates/sidebar-nav-bs.html new file mode 100644 index 000000000..89de016a1 --- /dev/null +++ b/{{cookiecutter.project_name_slug}}/doc/source/_templates/sidebar-nav-bs.html @@ -0,0 +1,12 @@ + diff --git a/{{cookiecutter.project_name_slug}}/doc/source/conf.py b/{{cookiecutter.project_name_slug}}/doc/source/conf.py new file mode 100755 index 000000000..c523464aa --- /dev/null +++ b/{{cookiecutter.project_name_slug}}/doc/source/conf.py @@ -0,0 +1,76 @@ +"""Sphinx documentation configuration file.""" +from datetime import datetime + +from ansys.{{cookiecutter.product_name_slug}}.{{cookiecutter.library_name_slug}} import __version__ +from pyansys_sphinx_theme import pyansys_logo_black + +# Project information +project = "{{ cookiecutter.pkg_name }}" +copyright = f"(c) {datetime.now().year} ANSYS, Inc. All rights reserved" +author = "ANSYS, Inc." +release = version = __version__ + +# use the default pyansys logo +html_logo = pyansys_logo_black +html_theme = "pyansys_sphinx_theme" + +# specify the location of your github repo +html_theme_options = { + "github_url": "{{ cookiecutter.repository_url }}", + "show_prev_next": False, +} + +# Sphinx extensions +extensions = [ + "sphinx.ext.autodoc", + "sphinx.ext.autosummary", + "numpydoc", + "sphinx.ext.intersphinx", + "sphinx_copybutton", +] + +# Intersphinx mapping +intersphinx_mapping = { + "python": ("https://docs.python.org/dev", None), + # kept here as an example + # "scipy": ("https://docs.scipy.org/doc/scipy/reference", None), + # "numpy": ("https://numpy.org/devdocs", None), + # "matplotlib": ("https://matplotlib.org/stable", None), + # "pandas": ("https://pandas.pydata.org/pandas-docs/stable", None), + # "pyvista": ("https://docs.pyvista.org/", None), +} + +# numpydoc configuration +numpydoc_show_class_members = False +numpydoc_xref_param_type = True + +# Consider enabling numpydoc validation. See: +# https://numpydoc.readthedocs.io/en/latest/validation.html# +numpydoc_validate = True +numpydoc_validation_checks = { + "GL06", # Found unknown section + "GL07", # Sections are in the wrong order. + "GL08", # The object does not have a docstring + "GL09", # Deprecation warning should precede extended summary + "GL10", # reST directives {directives} must be followed by two colons + "SS01", # No summary found + "SS02", # Summary does not start with a capital letter + # "SS03", # Summary does not end with a period + "SS04", # Summary contains heading whitespaces + # "SS05", # Summary must start with infinitive verb, not third person + "RT02", # The first line of the Returns section should contain only the + # type, unless multiple values are being returned" +} + + +# static path +html_static_path = ["_static"] + +# Add any paths that contain templates here, relative to this directory. +templates_path = ["_templates"] + +# The suffix(es) of source filenames. +source_suffix = ".rst" + +# The master toctree document. +master_doc = "index" diff --git a/{{cookiecutter.project_name_slug}}/doc/source/index.rst b/{{cookiecutter.project_name_slug}}/doc/source/index.rst new file mode 100644 index 000000000..d2824a5f6 --- /dev/null +++ b/{{cookiecutter.project_name_slug}}/doc/source/index.rst @@ -0,0 +1,6 @@ +.. + Just reuse the root readme to avoid duplicating the documentation. + Provide any documentation specific to your online documentation + here. + +.. include:: ../../README.rst diff --git a/{{cookiecutter.project_name_slug}}/pyproject_flit.toml b/{{cookiecutter.project_name_slug}}/pyproject_flit.toml new file mode 100644 index 000000000..c2d20871b --- /dev/null +++ b/{{cookiecutter.project_name_slug}}/pyproject_flit.toml @@ -0,0 +1,34 @@ +[build-system] +requires = ["flit_core >=3.2,<4"] +build-backend = "flit_core.buildapi" + +[project] +# Check https://flit.readthedocs.io/en/latest/pyproject_toml.html for all available sections +name = "{{ cookiecutter.pkg_name }}" +version = "{{ cookiecutter.version }}" +description = "{{ cookiecutter.short_description }}" +readme = "README.rst" +requires-python = ">={{ cookiecutter.requires_python }}" +license = {file = "LICENSE"} +authors = [ + {name = "ANSYS, Inc.", email = "pyansys.support@ansys.com"}, +] +maintainers = [ + {name = "PyAnsys developers", email = "pyansys.maintainers@ansys.com"}, +] + +classifiers = [ + "Development Status :: 4 - Beta", + "Programming Language :: Python :: 3", + "License :: OSI Approved :: MIT License", + "Operating System :: OS Independent", +] +dependencies = [ + "importlib-metadata >=4.0", +] + +[tool.flit.module] +name = "ansys.{{ cookiecutter.product_name_slug }}.{{cookiecutter.library_name_slug }}" + +[project.urls] +Source = "{{ cookiecutter.repository_url }}" diff --git a/{{cookiecutter.project_name_slug}}/pyproject_poetry.toml b/{{cookiecutter.project_name_slug}}/pyproject_poetry.toml new file mode 100644 index 000000000..e9fc46ddc --- /dev/null +++ b/{{cookiecutter.project_name_slug}}/pyproject_poetry.toml @@ -0,0 +1,27 @@ +[build-system] +requires = ["poetry-core>=1.0.0"] +build-backend = "poetry.core.masonry.api" + +[tool.poetry] +# Check https://python-poetry.org/docs/pyproject/ for all available sections +name = "{{ cookiecutter.pkg_name }}" +version = "{{ cookiecutter.version }}" +description = "{{ cookiecutter.short_description }}" +license = "MIT" +authors = ["ANSYS, Inc. "] +maintainers = ["PyAnsys developers "] +readme = "README.rst" +repository = "{{ cookiecutter.repository_url }}" +classifiers = [ + "Development Status :: 4 - Beta", + "Programming Language :: Python :: 3", + "License :: OSI Approved :: MIT License", + "Operating System :: OS Independent", +] +packages = [ + { include = "ansys", from = "src" }, +] + +[tool.poetry.dependencies] +python = ">={{ cookiecutter.requires_python }},<4.0" +importlib-metadata = {version = "^4.0", python = "<3.8"} diff --git a/{{cookiecutter.project_name_slug}}/requirements/requirements_build.txt b/{{cookiecutter.project_name_slug}}/requirements/requirements_build.txt new file mode 100644 index 000000000..a18c98ac9 --- /dev/null +++ b/{{cookiecutter.project_name_slug}}/requirements/requirements_build.txt @@ -0,0 +1,2 @@ +build>=0.7.0 +twine>=3.8 diff --git a/{{cookiecutter.project_name_slug}}/requirements/requirements_doc.txt b/{{cookiecutter.project_name_slug}}/requirements/requirements_doc.txt new file mode 100644 index 000000000..04fdab5c6 --- /dev/null +++ b/{{cookiecutter.project_name_slug}}/requirements/requirements_doc.txt @@ -0,0 +1,4 @@ +Sphinx>=4.4 +numpydoc>=1.2 +pyansys_sphinx_theme>=0.2 +Sphinx-copybutton>=0.4 diff --git a/{{cookiecutter.project_name_slug}}/requirements/requirements_tests.txt b/{{cookiecutter.project_name_slug}}/requirements/requirements_tests.txt new file mode 100644 index 000000000..fee6c2ece --- /dev/null +++ b/{{cookiecutter.project_name_slug}}/requirements/requirements_tests.txt @@ -0,0 +1,2 @@ +pytest>=7.0 +pytest-cov>=3.0 diff --git a/{{cookiecutter.project_name_slug}}/setup_setuptools.py b/{{cookiecutter.project_name_slug}}/setup_setuptools.py new file mode 100644 index 000000000..e6999895b --- /dev/null +++ b/{{cookiecutter.project_name_slug}}/setup_setuptools.py @@ -0,0 +1,22 @@ +"""Installation file for ansys-mapdl-core.""" + +from setuptools import find_namespace_packages, setup + +setup( + name="{{ cookiecutter.pkg_name }}", + packages=find_namespace_packages(where="src", include="ansys*"), + package_dir={"": "src"}, + version="{{ cookiecutter.version }}", + description="{{ cookiecutter.short_description }}", + long_description=open("README.rst").read(), + license="MIT", + classifiers=[ + "Development Status :: 4 - Beta", + "Programming Language :: Python :: 3", + "License :: OSI Approved :: MIT License", + "Operating System :: OS Independent", + ], + url="{{ cookiecutter.repository_url }}", + python_requires=">={{ cookiecutter.requires_python }}", + install_requires=["importlib-metadata >=4.0"], +) diff --git a/{{cookiecutter.project_name_slug}}/src/ansys/{{cookiecutter.product_name_slug}}/{{cookiecutter.library_name_slug}}/__init__.py b/{{cookiecutter.project_name_slug}}/src/ansys/{{cookiecutter.product_name_slug}}/{{cookiecutter.library_name_slug}}/__init__.py new file mode 100644 index 000000000..8077f3cc4 --- /dev/null +++ b/{{cookiecutter.project_name_slug}}/src/ansys/{{cookiecutter.product_name_slug}}/{{cookiecutter.library_name_slug}}/__init__.py @@ -0,0 +1,12 @@ +""" +{{ cookiecutter.product_name }}. + +{{ cookiecutter.library_name }} +""" + +try: + import importlib.metadata as importlib_metadata +except ModuleNotFoundError: + import importlib_metadata + +__version__ = importlib_metadata.version(__name__.replace(".", "-")) diff --git a/{{cookiecutter.project_name_slug}}/tests/test_metadata.py b/{{cookiecutter.project_name_slug}}/tests/test_metadata.py new file mode 100644 index 000000000..cb605aacc --- /dev/null +++ b/{{cookiecutter.project_name_slug}}/tests/test_metadata.py @@ -0,0 +1,5 @@ +from ansys.{{cookiecutter.product_name_slug}} import {{ cookiecutter.library_name_slug }} + + +def test_pkg_version(): + assert {{ cookiecutter.library_name_slug }}.__version__ == "{{ cookiecutter.version }}" diff --git a/{{cookiecutter.project_name_slug}}/tox_flit.ini b/{{cookiecutter.project_name_slug}}/tox_flit.ini new file mode 100644 index 000000000..e5918c4df --- /dev/null +++ b/{{cookiecutter.project_name_slug}}/tox_flit.ini @@ -0,0 +1,46 @@ +[tox] +description = Default tox environments list +envlist = + style,{py37,py38,py39,py310}-{coverage},doc +isolated_build = True +isolated_build_env = build + +[gh-actions] +description = The tox environment to be executed in gh-actions for a given python version +python = + 3.7: style,py37-coverage,doc + 3.8: style,py38-coverage,doc + 3.9: style,py39-coverage,doc + 3.10: style,py310-coverage,doc + +[testenv] +description = Checks for project unit tests and coverage (if desired) +basepython = + py37: python3.7 + py38: python3.8 + py39: python3.9 + py310: python3.10 + {style,reformat,doc,build}: python3 +setenv = + PYTHONUNBUFFERED = yes + coverage: PYTEST_EXTRA_ARGS = --cov +deps = + -r{toxinidir}/requirements/requirements_tests.txt +commands = + pytest {env:PYTEST_MARKERS:} {env:PYTEST_EXTRA_ARGS:} {posargs:-vv} + +[testenv:style] +description = Checks project code style +skip_install = true +deps = + pre-commit +commands = + pre-commit install + pre-commit run --all-files --show-diff-on-failure + +[testenv:doc] +description = Check if documentation generates properly +deps = + -r{toxinidir}/requirements/requirements_doc.txt +commands = + sphinx-build -d "{toxworkdir}/doc_doctree" doc/source "{toxworkdir}/doc_out" --color -vW -bhtml diff --git a/{{cookiecutter.project_name_slug}}/tox_poetry.ini b/{{cookiecutter.project_name_slug}}/tox_poetry.ini new file mode 100644 index 000000000..97cfbdba1 --- /dev/null +++ b/{{cookiecutter.project_name_slug}}/tox_poetry.ini @@ -0,0 +1,50 @@ +[tox] +description = Default tox environments list +envlist = + style,{py37,py38,py39,py310}-{coverage},doc +isolated_build = true + +[gh-actions] +description = The tox environment to be executed in gh-actions for a given python version +python = + 3.7: style,py37-coverage,doc + 3.8: style,py38-coverage,doc + 3.9: style,py39-coverage,doc + 3.10: style,py310-coverage,doc + +[testenv] +description = Checks for project unit tests and coverage (if desired) +basepython = + py37: python3.7 + py38: python3.8 + py39: python3.9 + py310: python3.10 + {style,reformat,doc}: python3 +skip_install = true +whitelist_externals = + poetry +setenv = + PYTHONUNBUFFERED = yes + coverage: PYTEST_EXTRA_ARGS = --cov +deps = + -r{toxinidir}/requirements/requirements_tests.txt +commands = + poetry install + poetry run pytest {env:PYTEST_MARKERS:} {env:PYTEST_EXTRA_ARGS:} {posargs:-vv} + +[testenv:style] +description = Checks project code style +skip_install = true +deps = + pre-commit +commands = + pre-commit install + pre-commit run --all-files --show-diff-on-failure + +[testenv:doc] +description = Check if documentation generates properly +deps = + -r{toxinidir}/requirements/requirements_doc.txt +commands = + poetry install + poetry run sphinx-build -d "{toxworkdir}/doc_doctree" doc/source "{toxworkdir}/doc_out" --color -vW -bhtml diff --git a/{{cookiecutter.project_name_slug}}/tox_setuptools.ini b/{{cookiecutter.project_name_slug}}/tox_setuptools.ini new file mode 100644 index 000000000..bd640a7ba --- /dev/null +++ b/{{cookiecutter.project_name_slug}}/tox_setuptools.ini @@ -0,0 +1,44 @@ +[tox] +description = Default tox environments list +envlist = + style,{py37,py38,py39,py310}-{coverage},doc + +[gh-actions] +description = The tox environment to be executed in gh-actions for a given python version +python = + 3.7: style,py37-coverage,doc + 3.8: style,py38-coverage,doc + 3.9: style,py39-coverage,doc + 3.10: style,py310-coverage,doc + +[testenv] +description = Checks for project unit tests and coverage (if desired) +basepython = + py37: python3.7 + py38: python3.8 + py39: python3.9 + py310: python3.10 + {style,reformat,doc}: python3 +setenv = + PYTHONUNBUFFERED = yes + coverage: PYTEST_EXTRA_ARGS = --cov +deps = + -r{toxinidir}/requirements/requirements_tests.txt +commands = + pytest {env:PYTEST_MARKERS:} {env:PYTEST_EXTRA_ARGS:} {posargs:-vv} + +[testenv:style] +description = Checks project code style +skip_install = true +deps = + pre-commit +commands = + pre-commit install + pre-commit run --all-files --show-diff-on-failure + +[testenv:doc] +description = Check if documentation generates properly +deps = + -r{toxinidir}/requirements/requirements_doc.txt +commands = + sphinx-build -d "{toxworkdir}/doc_doctree" doc/source "{toxworkdir}/doc_out" --color -vW -bhtml