diff --git a/.github/workflows/python-package.yml b/.github/workflows/python-package.yml index baa7376..abc229c 100644 --- a/.github/workflows/python-package.yml +++ b/.github/workflows/python-package.yml @@ -10,23 +10,53 @@ on: branches: [ main ] jobs: - build: - - runs-on: ubuntu-latest + tests: + name: ${{ matrix.name }} + runs-on: ${{ matrix.os }} strategy: + fail-fast: false matrix: - python-version: ['3.8', '3.9', '3.10'] + include: + + - name: Python 3.12 with Coverage + os: ubuntu-latest + python: '3.12' + toxenv: py312-test-cov + + - name: Python 3.12 + os: ubuntu-latest + python: '3.12' + toxenv: py312-test + + - name: Python 3.10 + os: ubuntu-latest + python: '3.10' + toxenv: py310-test + + - name: Python 3.9 + os: ubuntu-latest + python: 3.9 + toxenv: py39-test + + - name: Python 3.8 + os: ubuntu-latest + python: 3.8 + toxenv: py38-test steps: - - uses: actions/checkout@v2 - - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v2 + - name: Checkout code + uses: actions/checkout@v4 with: - python-version: ${{ matrix.python-version }} + fetch-depth: 0 + + - name: Set up Python ${{ matrix.python }} + uses: actions/setup-python@v5 + with: + python-version: ${{ matrix.python }} - name: Install dependencies run: | - python -m pip install --upgrade pip - python -m pip install flake8 pytest wheel + python -m pip install --upgrade tox + pip install flake8 pytest-cov wheel tox if [ -f requirements.txt ]; then pip install -r requirements.txt; fi - name: Lint with flake8 run: | @@ -34,6 +64,35 @@ jobs: 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 - - name: Test with pytest + - name: Run Tests run: | - pytest + tox ${{ matrix.toxargs }} -e ${{ matrix.toxenv }} -- ${{ matrix.toxposargs }} + - name: Upload coverage to artifacts + if: ${{ contains(matrix.toxenv,'-cov') }} + uses: actions/upload-artifact@v4 + with: + name: coverage_${{ matrix.toxenv }}.xml + path: coverage.xml + if-no-files-found: error + + upload-coverage-report: + needs: ['tests'] + permissions: + contents: none + runs-on: ubuntu-latest + name: Upload Coverage + steps: + - name: Download coverage artifacts + uses: actions/download-artifact@v4 + with: + path: coverage + pattern: coverage_* + merge-multiple: true + - name: Upload to Codecov + if: ${{ hashFiles('coverage/') != ''}} + uses: codecov/codecov-action@v4 + with: + token: ${{ secrets.CODECOV_TOKEN }} + directory: coverage + fail_ci_if_error: true # optional (default = false) + verbose: true diff --git a/.github/workflows/python-publish.yml b/.github/workflows/python-publish.yml index 61cb2d7..78a3c1d 100644 --- a/.github/workflows/python-publish.yml +++ b/.github/workflows/python-publish.yml @@ -1,31 +1,45 @@ + # This workflows will upload a Python Package using Twine when a release is created # For more information see: https://help.github.com/en/actions/language-and-framework-guides/using-python-with-github-actions#publishing-to-package-registries name: Upload to PYPI - -on: - release: - types: [created] +on: push jobs: - deploy: - + release-build: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 - name: Set up Python - uses: actions/setup-python@v2 + uses: actions/setup-python@v5 with: python-version: '3.x' - name: Install dependencies run: | - python -m pip install --upgrade pip - pip install setuptools wheel twine build - - name: Build and publish - env: - TWINE_USERNAME: ${{ secrets.PYPI_USERNAME }} - TWINE_PASSWORD: ${{ secrets.PYPI_PASSWORD }} - run: | - python -m build . - twine upload dist/* + python3 -m pip install build + - name: Build a binary wheel and source tarball + run: python3 -m build + - name: Upload artifacts + uses: actions/upload-artifact@v4 + with: + name: release-dists + path: dist/ + + pypi-publish: + name: Publish Package to PyPI + runs-on: ubuntu-latest + if: startsWith(github.ref, 'refs/tags/') + needs: + - release-build + permissions: + id-token: write + + steps: + - name: Retrieve release distributions + uses: actions/download-artifact@v4 + with: + name: release-dists + path: dist/ + - name: Publish release distributions to PyPI + uses: pypa/gh-action-pypi-publish@release/v1 diff --git a/.gitignore b/.gitignore index 7f9a5ec..57a1d23 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,8 @@ build/* *__pycache__* *.egg-info/* .tox/* +/coverage.xml +/.tox/ +/.coverage* +/goodman_focus/version.py +.DS_Store diff --git a/.readthedocs.yml b/.readthedocs.yml index 7194400..015b57a 100644 --- a/.readthedocs.yml +++ b/.readthedocs.yml @@ -1,6 +1,5 @@ version: 2 - build: os: ubuntu-lts-latest tools: diff --git a/README.md b/README.md index 85e847d..2faf47b 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ # Goodman Focus Finder ![Goodman Focus](https://github.com/soar-telescope/goodman_focus/workflows/Goodman%20Focus/badge.svg) -[![Coverage Status](https://coveralls.io/repos/github/soar-telescope/goodman_focus/badge.svg?branch=master)](https://coveralls.io/github/soar-telescope/goodman_focus?branch=master) +[![codecov](https://codecov.io/gh/soar-telescope/goodman_focus/graph/badge.svg?token=2ZK2DAMMYE)](https://codecov.io/gh/soar-telescope/goodman_focus) [![Documentation Status](https://readthedocs.org/projects/goodman-focus/badge/?version=latest)](https://goodman-focus.readthedocs.io/en/latest/?badge=latest) [![pypi](https://img.shields.io/pypi/v/goodman_focus.svg?style=flat)](https://pypi.org/project/goodman-focus/) @@ -17,4 +17,4 @@ All the documentation is maintained in https://soardocs.readthedocs.io/projects/ # Found a problem? Please [Open an Issue](https://github.com/soar-telescope/goodman_focus/issues) on -GitHub. \ No newline at end of file +GitHub. diff --git a/docs/conf.py b/docs/conf.py index 8da09ec..f3a7200 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -16,7 +16,8 @@ # import sys # sys.path.insert(0, os.path.abspath('.')) -__version__ = __import__('goodman_focus').__version__ +from importlib.metadata import version +__version__ = version('goodman_focus') # -- Project information ----------------------------------------------------- @@ -43,8 +44,8 @@ extensions = [ 'sphinx.ext.autodoc', 'sphinx.ext.intersphinx', - 'sphinxcontrib.napoleon', 'matplotlib.sphinxext.plot_directive', + 'sphinx.ext.napoleon' ] # Add any paths that contain templates here, relative to this directory. @@ -170,4 +171,4 @@ # -- Options for intersphinx extension --------------------------------------- # Example configuration for intersphinx: refer to the Python standard library. -intersphinx_mapping = {'https://docs.python.org/': None} +intersphinx_mapping = {'python': ('https://docs.python.org/3', None)} diff --git a/environment.yml b/environment.yml index 1fe13fe..1dc0de4 100644 --- a/environment.yml +++ b/environment.yml @@ -1,6 +1,6 @@ name: goodman_focus dependencies: - - python=3.8 + - python=3.12 - astropy - matplotlib - numpy diff --git a/goodman_focus/__init__.py b/goodman_focus/__init__.py index 4acafca..4cde93f 100644 --- a/goodman_focus/__init__.py +++ b/goodman_focus/__init__.py @@ -1,3 +1,6 @@ -from .version import __version__ # noqa: F401 +from importlib.metadata import version + from .goodman_focus import GoodmanFocus # noqa: F401 from .goodman_focus import run_goodman_focus # noqa: F401 + +__version__ = version('goodman_focus') diff --git a/goodman_focus/version.py b/goodman_focus/version.py deleted file mode 100644 index 907a758..0000000 --- a/goodman_focus/version.py +++ /dev/null @@ -1,2 +0,0 @@ -# This is an automatic generated file please do not edit -__version__ = '2.0.3' \ No newline at end of file diff --git a/pyproject.toml b/pyproject.toml index 21f01d0..60ed105 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,7 +1,72 @@ [build-system] +requires = ["setuptools>=64", "setuptools_scm>=8"] +build-backend = "setuptools.build_meta" -requires = ["setuptools", - "setuptools_scm", - "wheel"] +[project] +name = "goodman_focus" +dynamic = ["version"] +description = "Finds best focus for Goodman HTS based on a series of images obtained with different focus values" +readme = "README.md" +requires-python = ">=3.8" +license = {file = "LICENSE"} +keywords = [ + "soar", + "pipelines", + "astronomy", + "images", + "spectroscopy", + "focus" +] -build-backend = 'setuptools.build_meta' \ No newline at end of file +authors = [ + {name = "Simón Torres", email = "simon.torres@noirlab.edu"} +] +maintainers = [ + {name = "Simón Torres", email = "simon.torres@noirlab.edu"} +] + +classifiers = [ + 'Development Status :: 5 - Production/Stable', + 'Environment :: Console', + 'Intended Audience :: Developers', + 'Intended Audience :: Education', + 'Intended Audience :: Science/Research', + 'License :: OSI Approved :: BSD License', + 'Programming Language :: Python :: 3.8', + 'Programming Language :: Python :: 3.9', + 'Programming Language :: Python :: 3.10', + 'Programming Language :: Python :: 3.11', + 'Programming Language :: Python :: 3.12', + 'Natural Language :: English', + 'Operating System :: POSIX :: Linux', + 'Operating System :: POSIX :: Other', + 'Operating System :: MacOS :: MacOS X', + 'Topic :: Scientific/Engineering :: Astronomy', + 'Topic :: Scientific/Engineering :: Information Analysis', + 'Topic :: Software Development :: Libraries :: Python Modules', +] + +dependencies = [ + "astropy", + "ccdproc", + "matplotlib", + "numpy", + "packaging", + "pandas", + "scipy", +] + +[project.urls] +"Homepage" = "https://soardocs.readthedocs.io/projects/goodmanfocus/en/latest/" +"Bug Reports" = "https://github.com/soar-telescope/goodman_focus/issues" +"Source" = "https://github.com/soar-telescope/goodman_focus" + +[project.scripts] +goodman-focus = "goodman_focus:run_goodman_focus" + +[tool.setuptools] +[tool.setuptools.packages.find] +where = ["goodman_focus"] + +[tool.setuptools_scm] +version_file = "goodman_focus/version.py" diff --git a/setup.cfg b/setup.cfg index a9767fe..16d06c1 100644 --- a/setup.cfg +++ b/setup.cfg @@ -11,25 +11,3 @@ build_dir = docs/_build [upload_docs] upload_dir = docs/_build/html show_response = 1 - -[metadata] -package_name = goodman_focus -description = Finds best focus for Goodman HTS based on a series of images obtained with different focus values -long_description = Standalone app to get the best focus. -author = Simon Torres -author_email = simon.torres@noirlab.edu -license = BSD-3-Clause -# url = -edit_on_github = False -github_project = soar-telescope/goodman_focus -install_requires = - astropy - matplotlib - numpy - pandas - scipy - ccdproc - sphinx - -# version should be PEP440 compatible (http://www.python.org/dev/peps/pep-0440) -version = 2.0.3 diff --git a/setup.py b/setup.py index 8d7cf28..6068493 100644 --- a/setup.py +++ b/setup.py @@ -1,93 +1,3 @@ -import os - -from codecs import open from setuptools import setup -try: - from ConfigParser import ConfigParser -except ImportError: - from configparser import ConfigParser - -CONF = ConfigParser() - -HERE = os.path.abspath(os.path.dirname(__file__)) - - -def create_version_py(packagename, version, source_dir='.'): - package_dir = os.path.join(source_dir, packagename) - version_py = os.path.join(package_dir, 'version.py') - - version_str = "# This is an automatic generated file please do not edit\n" \ - "__version__ = '{:s}'".format(version) - - with open(version_py, 'w') as f: - f.write(version_str) - - -# read content from README.md -with open(os.path.join(HERE, 'README.md')) as f: - long_description = f.read() - -CONF.read([os.path.join(os.path.dirname(__file__), 'setup.cfg')]) - -metadata = dict(CONF.items('metadata')) - -PACKAGENAME = metadata['package_name'] - -VERSION = metadata['version'] - -LICENSE = metadata['license'] - -DESCRIPTION = metadata['description'] - -LONG_DESCRIPTION = long_description - -LONG_DESCRIPTION_CONTENT_TYPE = 'text/markdown' - -AUTHOR = metadata['author'] - -AUTHOR_EMAIL = metadata['author_email'] - -INSTALL_REQUIRES = metadata['install_requires'].split() - -# freezes version information in version.py -create_version_py(PACKAGENAME, VERSION) - - -setup( - name=metadata['package_name'], - - version=VERSION, - - description=DESCRIPTION, - - long_description=LONG_DESCRIPTION, - - long_description_content_type=LONG_DESCRIPTION_CONTENT_TYPE, - - # The project's main homepage. - url='https://github.com/soar-telescope/goodman_focus', - - # Author details - author=u'Simon Torres R., ', - - author_email='storres@ctio.noao.edu', - - # Choose your license - license=LICENSE, - - packages=['goodman_focus'], - - package_dir={'goodman_focus': 'goodman_focus'}, - - python_requires=">=3.6", - - install_requires=INSTALL_REQUIRES, - - entry_points={ - 'console_scripts': [ - 'goodman-focus=goodman_focus:run_goodman_focus', - ] - } - -) +setup() diff --git a/tox.ini b/tox.ini index 3688b58..7865b06 100644 --- a/tox.ini +++ b/tox.ini @@ -1,103 +1,19 @@ [tox] -envlist = - py{36,37,38}-test{,-alldeps,-devdeps}{,-cov} - py{36,37,38}-test-numpy{116,117,118} - py{36,37,38}-test-astropy{30,40,lts} - py{36,37,38}-test-external - build_docs - linkcheck - codestyle -requires = - setuptools >= 30.3.0 - pip >= 19.3.1 -isolated_build = true -indexserver = - NIGHTLY = https://pypi.anaconda.org/scipy-wheels-nightly/simple +env_list = + py{38, 39, 310, 311, 312}-test{,-cov} +minversion = 4.4.12 [testenv] -# Suppress display of matplotlib plots generated during docs build -setenv = - MPLBACKEND=agg - # Disable the accelerate linear algebra library when running on macos as - # latest numpy versions do not work with it - NPY_BLAS_ORDER= - NPY_LAPACK_ORDER= +description = run the tests with pytest +package = wheel +wheel_build_env = .pkg -# Pass through the following environment variables which may be needed for the CI -passenv = HOME,WINDIR,LC_ALL,LC_CTYPE,CC,CI,TRAVIS - -# Run the tests in a temporary directory to make sure that we don't import -# this package from the source tree -changedir = .tmp/{envname} - -# tox environments are constructed with so-called 'factors' (or terms) -# separated by hyphens, e.g. test-devdeps-cov. Lines below starting with factor: -# will only take effect if that factor is included in the environment name. To -# see a list of example environments that can be run, along with a description, -# run: -# -# tox -l -v -# -description = - run tests - alldeps: with all optional dependencies - devdeps: with the latest developer version of key dependencies - oldestdeps: with the oldest supported version of key dependencies - cov: and test coverage - numpy116: with numpy 1.16.* - numpy117: with numpy 1.17.* - numpy118: with numpy 1.18.* - astropy30: with astropy 3.0.* - astropy40: with astropy 4.0.* - astropylts: with the latest astropy LTS - external: with outside packages as dependencies - -# The following provides some specific pinnings for key packages deps = + pytest>=6 + cov: pytest-cov - numpy116: numpy==1.16.* - numpy117: numpy==1.17.* - numpy118: numpy==1.18.* - - astropy30: astropy==3.0.* - astropy40: astropy==4.0.* - astropylts: astropy==4.0.* - - devdeps: :NIGHTLY:numpy - devdeps: git+https://github.com/astropy/astropy.git#egg=astropy - - external: asdf - external: git+https://github.com/spacetelescope/jwst@stable - -# The following indicates which extras_require from setup.cfg will be installed -extras = - test - alldeps: all - -commands = - pip freeze - !cov: pytest --pyargs specutils {toxinidir}/docs {posargs} - cov: pytest --pyargs specutils {toxinidir}/docs --cov specutils --cov-config={toxinidir}/setup.cfg {posargs} - -[testenv:build_docs] -changedir = docs -description = invoke sphinx-build to build the HTML docs -extras = docs commands = - pip freeze - sphinx-build -W -b html . _build/html - -[testenv:linkcheck] -changedir = docs -description = check the links in the HTML docs -extras = docs -commands = - pip freeze - sphinx-build -W -b linkcheck . _build/html - -[testenv:codestyle] -skip_install = true -changedir = . -description = check code style, e.g. with flake8 -deps = flake8 -commands = flake8 specutils --count --max-line-length=100 --select=E101,W191,W291,W292,W293,W391,E111,E112,E113,E502,E722,E901,E902 + pytest {tty:--color=yes} {posargs} + cov: pytest {tty:--color=yes} --cov goodman_focus {posargs} + cov: coverage xml -o '{toxinidir}/coverage.xml' + html: coverage html -d .coverage_html