diff --git a/.circleci/config.yml b/.circleci/config.yml index bbe972b7..084adebc 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -34,16 +34,14 @@ jobs: executor: name: python-docker version: <> - steps: - checkout - run: name: Install System Dependencies command: sudo apt-get update && sudo apt-get install -y libsndfile1 - - python/install-packages: - pkg-manager: pip - # app-dir: ~/project/package-directory/ # If you're requirements.txt isn't in the root directory. - pip-dependency-file: requirements_dev.txt + - run: + name: install dependencies + command: pip install ".[tests]" - run: name: Run tests command: pytest @@ -57,18 +55,15 @@ jobs: executor: name: python-docker version: <> - steps: - checkout - - python/install-packages: - pkg-manager: pip - # app-dir: ~/project/package-directory/ # If you're requirements.txt isn't in the root directory. - pip-dependency-file: requirements_dev.txt + - run: + name: install dependencies + command: pip install ".[tests]" - run: name: Ruff command: ruff check - test_documentation_build: parameters: version: @@ -78,20 +73,15 @@ jobs: executor: name: python-docker version: <> - steps: - checkout # - run: # name: Install System Dependencies # command: sudo apt-get update && sudo apt-get install -y libsndfile1 texlive-latex-extra dvipng - - python/install-packages: - pkg-manager: pip - # app-dir: ~/project/package-directory/ # If you're requirements.txt isn't in the root directory. - pip-dependency-file: requirements_dev.txt - run: name: Sphinx command: | - pip install -e . + pip install ".[docs]" cd docs/ make html SPHINXOPTS="-W" @@ -104,20 +94,42 @@ jobs: executor: name: python-docker version: <> + steps: + - checkout + # - run: + # name: Install System Dependencies + # command: sudo apt-get update && sudo apt-get install -y libsndfile1 + - run: + name: install dependencies + command: pip install ".[deploy]" + - run: + name: deploy + command: | # create whl, install twine and publish to Test PyPI + python -m build + twine check dist/* + run_pypi_publish: + parameters: + version: + description: "version tag" + default: "latest" + type: string + executor: + name: python-docker + version: <> steps: - checkout - run: name: Install System Dependencies command: sudo apt-get update && sudo apt-get install -y libsndfile1 - - python/install-packages: - pkg-manager: pip - # app-dir: ~/project/package-directory/ # If you're requirements.txt isn't in the root directory. - pip-dependency-file: requirements_dev.txt + - run: + name: install dependencies + command: pip install ".[deploy]" - run: name: deploy command: | # create whl, install twine and publish to Test PyPI - python setup.py sdist bdist_wheel + python -m build + twine check dist/* twine upload dist/* # Invoke jobs via workflows @@ -130,11 +142,11 @@ workflows: matrix: parameters: version: - - "3.9" - - "3.10" - - "3.11" - - "3.12" - - "3.13" + - "3.9" + - "3.10" + - "3.11" + - "3.12" + - "3.13" - ruff: matrix: @@ -144,7 +156,6 @@ workflows: requires: - build_and_test - - test_documentation_build: matrix: parameters: @@ -153,8 +164,15 @@ workflows: requires: - build_and_test + - test_pypi_publish: + matrix: + parameters: + version: + - "3.9" + requires: + - build_and_test -test_and_publish: + test_and_publish: # Test and publish on new git version tags # This requires its own workflow to successfully trigger the test and build jobs: @@ -162,11 +180,11 @@ test_and_publish: matrix: parameters: version: - - "3.9" - - "3.10" - - "3.11" - - "3.12" - - "3.13" + - "3.9" + - "3.10" + - "3.11" + - "3.12" + - "3.13" filters: branches: @@ -203,7 +221,7 @@ test_and_publish: tags: only: /^v[0-9]+(\.[0-9]+)*$/ - - test_pypi_publish: + - run_pypi_publish: matrix: parameters: version: diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md index 258e2c54..ec24ede8 100644 --- a/.github/ISSUE_TEMPLATE.md +++ b/.github/ISSUE_TEMPLATE.md @@ -3,7 +3,7 @@ * pyrato version: * Python version: * Operating System: -* Did you install pyfar via pip: +* Did you install pyrato via pip: ## Description diff --git a/.github/workflows/has_label.yml b/.github/workflows/has_label.yml new file mode 100644 index 00000000..1750854a --- /dev/null +++ b/.github/workflows/has_label.yml @@ -0,0 +1,27 @@ +name: pull_request label + +on: + pull_request: + types: + - opened + - labeled + - unlabeled + - synchronize + +jobs: + check-labels: + runs-on: ubuntu-latest + steps: + - name: pull_request label + run: | + echo "Checking for label on pull request..." + PR_DATA=$(gh api repos/${{ github.repository }}/pulls/${{ github.event.pull_request.number }}) + LABEL_NAMES=$(echo "$PR_DATA" | jq -r '.labels[].name') + echo "Labels: $LABEL_NAMES" + + if [ -z "$LABEL_NAMES" ]; then + echo "Error: No label found on this pull request. Please add a label." + exit 1 + fi + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/has_version_milestone.yml b/.github/workflows/has_version_milestone.yml new file mode 100644 index 00000000..1a2bf74a --- /dev/null +++ b/.github/workflows/has_version_milestone.yml @@ -0,0 +1,29 @@ +name: pull_request version milestone + +on: + pull_request: + types: + - opened + - labeled + - unlabeled + - synchronize + +jobs: + check-labels: + runs-on: ubuntu-latest + steps: + - name: pull_request version milestone + run: | + echo "Checking for version milestone on pull request..." + PR_DATA=$(gh api repos/${{ github.repository }}/pulls/${{ github.event.pull_request.number }}) + MILESTONE_NAME=$(echo "$PR_DATA" | jq -r '.milestone.title') + echo "Milestone: $MILESTONE_NAME" + + REGEX="^v[0-9]+\.[0-9]+\.[0-9]+$" + MATCHES=$(echo "$MILESTONE_NAME" | grep -E "$REGEX") + if [ -z "$MATCHES" ]; then + echo "Error: No version milestone found on this pull request. Please add a milestone in the format vX.Y.Z." + exit 1 + fi + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.readthedocs.yml b/.readthedocs.yml index 9a269eb2..c701d00b 100644 --- a/.readthedocs.yml +++ b/.readthedocs.yml @@ -8,9 +8,9 @@ version: 2 build: os: ubuntu-22.04 tools: - python: "3.10" + python: "3.12" apt_packages: - - libsndfile1 + - libsndfile1 # Build documentation in the docs/ directory with Sphinx sphinx: @@ -23,4 +23,5 @@ formats: # Optionally set the version of Python and requirements required to build your docs python: install: - - requirements: requirements_dev.txt + - method: pip + path: ".[docs]" diff --git a/CONTRIBUTING.rst b/CONTRIBUTING.rst index 908891f3..23d425f2 100644 --- a/CONTRIBUTING.rst +++ b/CONTRIBUTING.rst @@ -46,9 +46,7 @@ Ready to contribute? Here's how to set up `pyrato` for local development using t $ conda create --name pyrato python $ conda activate pyrato - $ conda install pip - $ pip install -e . - $ pip install -r requirements_dev.txt + $ pip install -e ".[dev]" 4. Create a branch for local development. Indicate the intention of your branch in its respective name (i.e. `feature/branch-name` or `bugfix/branch-name`):: diff --git a/README.md b/README.md index 648e22d6..cb21e69e 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,9 @@ -


+ + [![PyPI version](https://badge.fury.io/py/pyrato.svg)](https://badge.fury.io/py/pyrato) [![Documentation Status](https://readthedocs.org/projects/pyrato/badge/?version=stable)](https://pyrato.readthedocs.io/en/stable/?badge=stable) [![CircleCI](https://circleci.com/gh/pyfar/pyrato.svg?style=shield)](https://circleci.com/gh/pyfar/pyrato) @@ -26,6 +27,7 @@ Use pip to install pyrato If the installation fails, please check out the [help section](https://pyfar-gallery.readthedocs.io/en/latest/help). -## Contributing +Contributing +============ Check out the [contributing guidelines](https://pyfar.readthedocs.io/en/stable/contributing.html) if you want to become part of pyfar. diff --git a/docs/api_reference.rst b/docs/api_reference.rst index 7e754fd8..6786912f 100644 --- a/docs/api_reference.rst +++ b/docs/api_reference.rst @@ -1,7 +1,7 @@ .. _api_reference: API Reference -================== +============= The following gives detailed information about all pyrato functions sorted according to their modules. diff --git a/docs/conf.py b/docs/conf.py index 1833f2b1..eaa3b220 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -10,6 +10,7 @@ import sys import urllib3 import shutil +import numpy as np sys.path.insert(0, os.path.abspath('..')) import pyrato # noqa @@ -54,9 +55,9 @@ master_doc = 'index' # General information about the project. -project = u'pyrato' -copyright = u"2021-2023, Marco Berzborn; 2023, The pyfar developers" -author = u"The pyfar developers" +project = 'pyrato' +copyright = "2021-2023, Marco Berzborn; 2023, The pyfar developers" +author = "The pyfar developers" # The version info for the project you're documenting, acts as replacement # for |version| and |release|, also used in various other places throughout @@ -94,7 +95,6 @@ 'numpy': ('https://numpy.org/doc/stable/', None), 'scipy': ('https://docs.scipy.org/doc/scipy/', None), 'matplotlib': ('https://matplotlib.org/stable/', None), - 'spharpy': ('https://spharpy.readthedocs.io/en/stable/', None), 'pyfar': ('https://pyfar.readthedocs.io/en/stable/', None), } @@ -111,13 +111,15 @@ # -- HTML theme options # https://pydata-sphinx-theme.readthedocs.io/en/stable/user_guide/layout.html html_sidebars = { - "pyrato": [] + "pyrato": [] } + html_theme_options = { "navbar_start": ["navbar-logo"], "navbar_end": ["navbar-icon-links", "theme-switcher"], "navbar_align": "content", - "header_links_before_dropdown": 8, + "header_links_before_dropdown": None, # will be automatically set later based on headers.rst + "header_dropdown_text": "Packages", # Change dropdown name from "More" to "Packages" "icon_links": [ { "name": "GitHub", @@ -152,16 +154,44 @@ '_static/header.rst', 'resources/logos/pyfar_logos_fixed_size_pyrato.png', ] -c = urllib3.PoolManager() -for file in folders_in: - url = link + file - filename = file - os.makedirs(os.path.dirname(filename), exist_ok=True) - with c.request('GET', url, preload_content=False) as res, open(filename, 'wb') as out_file: - shutil.copyfileobj(res, out_file) - -# replace pyfar hard link to internal link + +def download_files_from_gallery(link, folders_in): + c = urllib3.PoolManager() + for file in folders_in: + url = link + file + filename = file + os.makedirs(os.path.dirname(filename), exist_ok=True) + with c.request('GET', url, preload_content=False) as res: + if res.status == 200: + with open(filename, 'wb') as out_file: + shutil.copyfileobj(res, out_file) + +download_files_from_gallery(link, folders_in) +# if logo does not exist, use pyfar logo +if not os.path.exists(html_logo): + download_files_from_gallery( + link, ['resources/logos/pyfar_logos_fixed_size_pyfar.png']) + shutil.copyfile( + 'resources/logos/pyfar_logos_fixed_size_pyfar.png', html_logo) + +# replace pyrato hard link to internal link with open("_static/header.rst", "rt") as fin: with open("header.rst", "wt") as fout: - for line in fin: - fout.write(line.replace(f'https://{project}.readthedocs.io', project)) + lines = [line.replace(f'https://{project}.readthedocs.io', project) for line in fin] + contains_project = any(project in line for line in lines) + + fout.writelines(lines) + + # add project to the list of projects if not in header + if not contains_project: + fout.write(f' {project} <{project}>\n') + + # count the number of gallery headings + count_gallery_headings = np.sum( + ['https://pyfar-gallery.readthedocs.io' in line for line in lines]) + + +# set dropdown header after gallery headings +html_theme_options['header_links_before_dropdown'] = count_gallery_headings+1 + + diff --git a/pyproject.toml b/pyproject.toml index a388e4d6..c15d9541 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,10 +1,86 @@ +[project] +name = "pyrato" +version = "0.4.0" +description = "Collection of functions commonly used in room acoustics." +readme = "README.md" +license = {file = "LICENSE"} +requires-python = ">=3.9" +authors = [ + { name = "The pyfar developers", email = "info@pyfar.org" }, +] +keywords = [ + "acoustics", + "pyfar", +] +classifiers = [ + "Development Status :: 4 - Beta", + "Intended Audience :: Science/Research", + "License :: OSI Approved :: MIT License", + "Natural Language :: English", + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", + +] +dependencies = [ + 'pyfar>=0.5.0', + 'numpy>=1.14.0', + 'scipy>=1.5.0', + 'matplotlib', +] + +[project.optional-dependencies] +deploy = [ + "twine", + "wheel", + "build", + "setuptools", + "bump-my-version", + ] +tests = [ + "pytest", + "pytest-cov", + "watchdog", + "ruff==0.8.3", + "coverage", + +] +docs = [ + "sphinx", + "autodocsumm>=0.2.14", + "pydata-sphinx-theme", + "sphinx_mdinclude", + "sphinx-design", + "sphinx-favicon", + "sphinx-reredirects", +] +dev = ["pyrato[deploy,tests,docs]"] + +[project.urls] +Tracker = "https://github.com/pyfar/pyrato/issues" +Documentation = "https://pyrato.readthedocs.io/" +Download = "https://pypi.org/project/pyrato/" +Homepage = "https://pyfar.org/" +Source = "https://github.com/pyfar/pyrato" +Changelog = "https://github.com/pyfar/pyrato/blob/main/HISTORY.rst" + +[build-system] +requires = ["setuptools>=61.0", "wheel"] +build-backend = "setuptools.build_meta" + +[tool.setuptools.packages] +find = {} # Scan the project directory with the default parameters + + [tool.ruff] exclude = [ ".git", "docs", "examples/", "tests/test_data", - "setup.py", ] line-length = 79 lint.ignore = [ diff --git a/pytest.ini b/pytest.ini deleted file mode 100644 index 445c908c..00000000 --- a/pytest.ini +++ /dev/null @@ -1,4 +0,0 @@ -# pytest.ini -[pytest] -norecursedirs = private -testpaths = tests diff --git a/requirements_dev.txt b/requirements_dev.txt deleted file mode 100644 index 68c7e3db..00000000 --- a/requirements_dev.txt +++ /dev/null @@ -1,23 +0,0 @@ -pip -bump2version -wheel -watchdog -ruff==0.4.1 -coverage -Sphinx<8 -twine - -pytest -pytest-runner -pytest-cov - -numpy>=1.14.0 -scipy>=1.5.0 -matplotlib -autodocsumm -pydata-sphinx-theme -sphinx-design -sphinx-favicon -sphinx-reredirects -pyfar>=0.5.0 -sphinx_mdinclude diff --git a/setup.cfg b/setup.cfg deleted file mode 100644 index 56162471..00000000 --- a/setup.cfg +++ /dev/null @@ -1,17 +0,0 @@ -[bumpversion] -current_version = 0.4.0 -commit = True -tag = True - -[bumpversion:file:setup.py] -search = version='{current_version}' -replace = version='{new_version}' - -[bumpversion:file:pyrato/__init__.py] -search = __version__ = '{current_version}' -replace = __version__ = '{new_version}' - -[bdist_wheel] -universal = 1 -[aliases] -test = pytest diff --git a/setup.py b/setup.py deleted file mode 100644 index b62a5c79..00000000 --- a/setup.py +++ /dev/null @@ -1,74 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- - -"""The setup script.""" - -from setuptools import setup, find_packages - -with open('README.md') as readme_file: - readme = readme_file.read() - -with open('HISTORY.rst') as history_file: - history = history_file.read() - -requirements = [ - 'pyfar>=0.5.0', - 'numpy>=1.14.0', - 'scipy>=1.5.0', - 'matplotlib'] - -setup_requirements = [ - 'pytest-runner', -] - -test_requirements = [ - 'pytest', - 'bump2version', - 'wheel', - 'watchdog', - 'ruff', - 'coverage', - 'Sphinx<8', - 'twine' - 'pydata-sphinx-theme', - 'sphinx_mdinclude', -] - -setup( - author="The pyfar developers", - author_email='info@pyfar.org', - classifiers=[ - 'Development Status :: 4 - Beta', - 'Intended Audience :: Science/Research', - 'License :: OSI Approved :: MIT License', - 'Natural Language :: English', - 'Programming Language :: Python :: 3', - 'Programming Language :: Python :: 3.9', - 'Programming Language :: Python :: 3.10', - 'Programming Language :: Python :: 3.11', - 'Programming Language :: Python :: 3.12', - 'Programming Language :: Python :: 3.13', - ], - description="Collection of functions commonly used in room acoustics", - install_requires=requirements, - license="MIT license", - long_description_content_type='text/markdown', - long_description=readme, - include_package_data=True, - keywords='pyrato', - name='pyrato', - packages=find_packages(), - setup_requires=setup_requirements, - test_suite='tests', - tests_require=test_requirements, - url='https://github.com/pyfar/pyrato', - download_url="https://pypi.org/project/pyrato/", - project_urls={ - "Bug Tracker": "https://github.com/pyfar/pyrato/issues", - "Documentation": "https://pyrato.readthedocs.io/", - "Source Code": "https://github.com/pyfar/pyrato", - }, - version='0.4.0', - zip_safe=False, - python_requires='>=3.9', -)