From 390bb707c4d42af642c4f72ade92b7bcdfde63f7 Mon Sep 17 00:00:00 2001 From: Sebastiaan Huber Date: Fri, 28 Jan 2022 23:10:21 +0100 Subject: [PATCH] Devops: adopt PEP 621 and move build spec to `pyproject.toml` Following PEP 621 it is now possible to fully define the build procedure of your package in `pyproject.toml`. Since this PEP is now well supported, and for example `pip` can use it, we migrate to it since it provides a bunch of benefits: * No longer need the deprecated `setup.py` to install the package. * Version number is now dynamically fetched from the package. So the utility script to make sure the `setup.json` specifies the same version can be removed. * The `MANIFEST.in` is no longer necessary. The `flit` build tool will automatically include anything. The `pyproject.toml` has a tool section for `flit` that excludes the `tests` and `docs` folders. --- .pre-commit-config.yaml | 15 ---- MANIFEST.in | 6 -- pyproject.toml | 129 ++++++++++++++++++++++++++++++- setup.json | 111 -------------------------- setup.py | 35 --------- utils/__init__.py | 2 - utils/validate_version_number.py | 53 ------------- 7 files changed, 126 insertions(+), 225 deletions(-) delete mode 100644 MANIFEST.in delete mode 100644 setup.json delete mode 100644 setup.py delete mode 100644 utils/__init__.py delete mode 100644 utils/validate_version_number.py diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 5bdf9af98..da1caf8aa 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -50,18 +50,3 @@ repos: - id: pylint language: system exclude: *exclude_files - -- repo: local - hooks: - - id: version-number - name: Check consistency in version number - entry: python ./utils/validate_version_number.py - args: ['version'] - language: system - files: >- - (?x)^( - setup.json| - aiida_quantumespresso/__init__.py| - ./utils/validate_version_number.py| - )$ - pass_filenames: false diff --git a/MANIFEST.in b/MANIFEST.in deleted file mode 100644 index 20d3a53ee..000000000 --- a/MANIFEST.in +++ /dev/null @@ -1,6 +0,0 @@ -include setup.json -include LICENSE.txt -include aiida_quantumespresso/utils/protocols/*.json -include aiida_quantumespresso/calculations/helpers/*.xml -recursive-include aiida_quantumespresso/parsers/parse_xml *.xsd -recursive-include aiida_quantumespresso/workflows/protocols *.yaml diff --git a/pyproject.toml b/pyproject.toml index bf170596e..f75d9708c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,130 @@ [build-system] -requires = ['setuptools>=40.8.0', 'wheel', 'reentry~=1.3', 'fastentrypoints~=0.12'] -build-backend = 'setuptools.build_meta:__legacy__' +requires = ['flit_core >=3.4,<4'] +build-backend = 'flit_core.buildapi' + +[project] +name = 'aiida-quantumespresso' +dynamic = ['version'] +description = 'The official AiiDA plugin for Quantum ESPRESSO' +authors = [{name = 'The AiiDA team', email = 'developers@aiida.net'}] +readme = 'README.md' +license = {file = 'LICENSE.txt'} +classifiers = [ + 'Development Status :: 5 - Production/Stable', + 'Framework :: AiiDA', + 'License :: OSI Approved :: MIT License', + 'Programming Language :: Python', + 'Programming Language :: Python :: 3.6', + 'Programming Language :: Python :: 3.7', + 'Programming Language :: Python :: 3.8', + 'Programming Language :: Python :: 3.9', +] +keywords = ['aiida', 'workflows'] +requires-python = '>=3.6' +dependencies = [ + 'psycopg2-binary<2.9', + 'aiida_core[atomic_tools]~=1.4,>=1.4.4', + 'aiida-pseudo~=0.6.1', + 'jsonschema', + 'packaging', + 'qe-tools~=2.0rc1', + 'xmlschema~=1.2,>=1.2.5', + 'numpy', + 'importlib_resources' +] + +[project.urls] +Home = 'https://github.com/aiidateam/aiida-quantumespresso' +Source = 'https://github.com/aiidateam/aiida-quantumespresso' +Documentation = 'https://aiida-quantumespresso.readthedocs.io' + +[project.optional-dependencies] +docs = [ + 'Sphinx', + 'docutils', + 'sphinx-copybutton~=0.3.0', + 'sphinx-book-theme~=0.1.0', + 'sphinx-click~=2.7.1' +] +pre-commit = [ + 'pre-commit~=2.2', + 'pylint~=2.6.0' +] +tests = [ + 'pgtest~=1.3', + 'pytest~=6.0', + 'pytest-regressions~=1.0' +] +tcod = [ + 'aiida-tcod' +] + +[project.scripts] +aiida-quantumespresso = 'aiida_quantumespresso.cli:cmd_root' + +[project.entry-points.'aiida.calculations'] +'quantumespresso.cp' = 'aiida_quantumespresso.calculations.cp:CpCalculation' +'quantumespresso.create_kpoints_from_distance' = 'aiida_quantumespresso.calculations.functions.create_kpoints_from_distance:create_kpoints_from_distance' +'quantumespresso.dos' = 'aiida_quantumespresso.calculations.dos:DosCalculation' +'quantumespresso.epw' = 'aiida_quantumespresso.calculations.epw:EpwCalculation' +'quantumespresso.matdyn' = 'aiida_quantumespresso.calculations.matdyn:MatdynCalculation' +'quantumespresso.namelists' = 'aiida_quantumespresso.calculations.namelists:NamelistsCalculation' +'quantumespresso.neb' = 'aiida_quantumespresso.calculations.neb:NebCalculation' +'quantumespresso.ph' = 'aiida_quantumespresso.calculations.ph:PhCalculation' +'quantumespresso.pp' = 'aiida_quantumespresso.calculations.pp:PpCalculation' +'quantumespresso.projwfc' = 'aiida_quantumespresso.calculations.projwfc:ProjwfcCalculation' +'quantumespresso.pw' = 'aiida_quantumespresso.calculations.pw:PwCalculation' +'quantumespresso.pw2gw' = 'aiida_quantumespresso.calculations.pw2gw:Pw2gwCalculation' +'quantumespresso.pw2wannier90' = 'aiida_quantumespresso.calculations.pw2wannier90:Pw2wannier90Calculation' +'quantumespresso.pwimmigrant' = 'aiida_quantumespresso.calculations.pwimmigrant:PwimmigrantCalculation' +'quantumespresso.q2r' = 'aiida_quantumespresso.calculations.q2r:Q2rCalculation' +'quantumespresso.seekpath_structure_analysis' = 'aiida_quantumespresso.calculations.functions.seekpath_structure_analysis:seekpath_structure_analysis' + +[project.entry-points.'aiida.data'] +'quantumespresso.force_constants' = 'aiida_quantumespresso.data.force_constants:ForceConstantsData' + +[project.entry-points.'aiida.parsers'] +'quantumespresso.cp' = 'aiida_quantumespresso.parsers.cp:CpParser' +'quantumespresso.dos' = 'aiida_quantumespresso.parsers.dos:DosParser' +'quantumespresso.matdyn' = 'aiida_quantumespresso.parsers.matdyn:MatdynParser' +'quantumespresso.neb' = 'aiida_quantumespresso.parsers.neb:NebParser' +'quantumespresso.ph' = 'aiida_quantumespresso.parsers.ph:PhParser' +'quantumespresso.pp' = 'aiida_quantumespresso.parsers.pp:PpParser' +'quantumespresso.projwfc' = 'aiida_quantumespresso.parsers.projwfc:ProjwfcParser' +'quantumespresso.pw' = 'aiida_quantumespresso.parsers.pw:PwParser' +'quantumespresso.pw2gw' = 'aiida_quantumespresso.parsers.pw2gw:Pw2gwParser' +'quantumespresso.q2r' = 'aiida_quantumespresso.parsers.q2r:Q2rParser' +'quantumespresso.pw2wannier90' = 'aiida_quantumespresso.parsers.pw2wannier90:Pw2wannier90Parser' + +[project.entry-points.'aiida.tools.calculations'] +'quantumespresso.pw' = 'aiida_quantumespresso.tools.calculations.pw:PwCalculationTools' + +[project.entry-points.'aiida.tools.data.orbitals'] +'spinorbithydrogen' = 'aiida_quantumespresso.tools.data.orbital.spinorbithydrogen:SpinorbitHydrogenOrbital' +'noncollinearhydrogen' = 'aiida_quantumespresso.tools.data.orbital.noncollinearhydrogen:NoncollinearHydrogenOrbital' + +[project.entry-points.'aiida.tools.dbexporters.tcod_plugins'] +'quantumespresso.cp' = 'aiida_quantumespresso.tools.dbexporters.tcod_plugins.cp:CpTcodtranslator' +'quantumespresso.pw' = 'aiida_quantumespresso.tools.dbexporters.tcod_plugins.pw:PwTcodtranslator' + +[project.entry-points.'aiida.workflows'] +'quantumespresso.ph.base' = 'aiida_quantumespresso.workflows.ph.base:PhBaseWorkChain' +'quantumespresso.pw.base' = 'aiida_quantumespresso.workflows.pw.base:PwBaseWorkChain' +'quantumespresso.pw.relax' = 'aiida_quantumespresso.workflows.pw.relax:PwRelaxWorkChain' +'quantumespresso.pw.bands' = 'aiida_quantumespresso.workflows.pw.bands:PwBandsWorkChain' +'quantumespresso.pw.band_structure' = 'aiida_quantumespresso.workflows.pw.band_structure:PwBandStructureWorkChain' +'quantumespresso.q2r.base' = 'aiida_quantumespresso.workflows.q2r.base:Q2rBaseWorkChain' +'quantumespresso.matdyn.base' = 'aiida_quantumespresso.workflows.matdyn.base:MatdynBaseWorkChain' +'quantumespresso.pdos' = 'aiida_quantumespresso.workflows.pdos:PdosWorkChain' + +[tool.flit.module] +name = 'aiida_quantumespresso' + +[tool.flit.sdist] +exclude = [ + 'docs/', + 'tests/', +] [tool.pylint.format] max-line-length = 120 @@ -76,5 +200,4 @@ whitelist_externals = make commands = clean: make clean make - """ diff --git a/setup.json b/setup.json deleted file mode 100644 index a56d7bfa4..000000000 --- a/setup.json +++ /dev/null @@ -1,111 +0,0 @@ -{ - "author": "The AiiDA team", - "author_email": "developers@aiida.net", - "classifiers": [ - "Framework :: AiiDA", - "License :: OSI Approved :: MIT License", - "Programming Language :: Python :: 3.6", - "Programming Language :: Python :: 3.7", - "Programming Language :: Python :: 3.8", - "Programming Language :: Python :: 3.9", - "Development Status :: 5 - Production/Stable" - ], - "description": "The official AiiDA plugin for Quantum ESPRESSO", - "entry_points": { - "aiida.calculations": [ - "quantumespresso.cp = aiida_quantumespresso.calculations.cp:CpCalculation", - "quantumespresso.create_kpoints_from_distance = aiida_quantumespresso.calculations.functions.create_kpoints_from_distance:create_kpoints_from_distance", - "quantumespresso.dos = aiida_quantumespresso.calculations.dos:DosCalculation", - "quantumespresso.epw = aiida_quantumespresso.calculations.epw:EpwCalculation", - "quantumespresso.matdyn = aiida_quantumespresso.calculations.matdyn:MatdynCalculation", - "quantumespresso.namelists = aiida_quantumespresso.calculations.namelists:NamelistsCalculation", - "quantumespresso.neb = aiida_quantumespresso.calculations.neb:NebCalculation", - "quantumespresso.ph = aiida_quantumespresso.calculations.ph:PhCalculation", - "quantumespresso.pp = aiida_quantumespresso.calculations.pp:PpCalculation", - "quantumespresso.projwfc = aiida_quantumespresso.calculations.projwfc:ProjwfcCalculation", - "quantumespresso.pw = aiida_quantumespresso.calculations.pw:PwCalculation", - "quantumespresso.pw2gw = aiida_quantumespresso.calculations.pw2gw:Pw2gwCalculation", - "quantumespresso.pw2wannier90 = aiida_quantumespresso.calculations.pw2wannier90:Pw2wannier90Calculation", - "quantumespresso.pwimmigrant = aiida_quantumespresso.calculations.pwimmigrant:PwimmigrantCalculation", - "quantumespresso.q2r = aiida_quantumespresso.calculations.q2r:Q2rCalculation", - "quantumespresso.seekpath_structure_analysis = aiida_quantumespresso.calculations.functions.seekpath_structure_analysis:seekpath_structure_analysis" - ], - "aiida.data": [ - "quantumespresso.force_constants = aiida_quantumespresso.data.force_constants:ForceConstantsData" - ], - "aiida.parsers": [ - "quantumespresso.cp = aiida_quantumespresso.parsers.cp:CpParser", - "quantumespresso.dos = aiida_quantumespresso.parsers.dos:DosParser", - "quantumespresso.matdyn = aiida_quantumespresso.parsers.matdyn:MatdynParser", - "quantumespresso.neb = aiida_quantumespresso.parsers.neb:NebParser", - "quantumespresso.ph = aiida_quantumespresso.parsers.ph:PhParser", - "quantumespresso.pp = aiida_quantumespresso.parsers.pp:PpParser", - "quantumespresso.projwfc = aiida_quantumespresso.parsers.projwfc:ProjwfcParser", - "quantumespresso.pw = aiida_quantumespresso.parsers.pw:PwParser", - "quantumespresso.pw2gw = aiida_quantumespresso.parsers.pw2gw:Pw2gwParser", - "quantumespresso.q2r = aiida_quantumespresso.parsers.q2r:Q2rParser", - "quantumespresso.pw2wannier90 = aiida_quantumespresso.parsers.pw2wannier90:Pw2wannier90Parser" - ], - "aiida.tools.calculations": [ - "quantumespresso.pw = aiida_quantumespresso.tools.calculations.pw:PwCalculationTools" - ], - "aiida.tools.data.orbitals": [ - "spinorbithydrogen = aiida_quantumespresso.tools.data.orbital.spinorbithydrogen:SpinorbitHydrogenOrbital", - "noncollinearhydrogen = aiida_quantumespresso.tools.data.orbital.noncollinearhydrogen:NoncollinearHydrogenOrbital" - ], - "aiida.tools.dbexporters.tcod_plugins": [ - "quantumespresso.cp = aiida_quantumespresso.tools.dbexporters.tcod_plugins.cp:CpTcodtranslator", - "quantumespresso.pw = aiida_quantumespresso.tools.dbexporters.tcod_plugins.pw:PwTcodtranslator" - ], - "aiida.workflows": [ - "quantumespresso.ph.base = aiida_quantumespresso.workflows.ph.base:PhBaseWorkChain", - "quantumespresso.pw.base = aiida_quantumespresso.workflows.pw.base:PwBaseWorkChain", - "quantumespresso.pw.relax = aiida_quantumespresso.workflows.pw.relax:PwRelaxWorkChain", - "quantumespresso.pw.bands = aiida_quantumespresso.workflows.pw.bands:PwBandsWorkChain", - "quantumespresso.pw.band_structure = aiida_quantumespresso.workflows.pw.band_structure:PwBandStructureWorkChain", - "quantumespresso.q2r.base = aiida_quantumespresso.workflows.q2r.base:Q2rBaseWorkChain", - "quantumespresso.matdyn.base = aiida_quantumespresso.workflows.matdyn.base:MatdynBaseWorkChain", - "quantumespresso.pdos = aiida_quantumespresso.workflows.pdos:PdosWorkChain" - ], - "console_scripts": [ - "aiida-quantumespresso = aiida_quantumespresso.cli:cmd_root" - ] - }, - "extras_require": { - "pre-commit": [ - "pre-commit~=2.2", - "pylint~=2.6.0" - ], - "tests": [ - "pgtest~=1.3", - "pytest~=6.0", - "pytest-regressions~=2.3" - ], - "tcod": [ - "aiida-tcod" - ], - "docs": [ - "Sphinx", - "docutils", - "sphinx-copybutton~=0.3.0", - "sphinx-book-theme~=0.1.0", - "sphinx-click~=2.7.1" - ] - }, - "install_requires": [ - "psycopg2-binary<2.9", - "aiida_core[atomic_tools]~=1.4,>=1.4.4", - "aiida-pseudo~=0.6.1", - "jsonschema", - "packaging", - "qe-tools~=2.0rc1", - "xmlschema~=1.2,>=1.2.5", - "numpy", - "importlib_resources" - ], - "license": "MIT License", - "name": "aiida_quantumespresso", - "python_requires": ">=3.6", - "url": "https://github.com/aiidateam/aiida-quantumespresso", - "version": "3.5.1" -} diff --git a/setup.py b/setup.py deleted file mode 100644 index 74d0c73af..000000000 --- a/setup.py +++ /dev/null @@ -1,35 +0,0 @@ -# -*- coding: utf-8 -*- -"""Setup for the `aiida-quantumespresso` plugin which provides an interface to Quantum ESPRESSO for `aiida-core`.""" -try: - import fastentrypoints # pylint: disable=unused-import -except ImportError: - # This should only occur when building the package, i.e. for `python setup.py sdist/bdist_wheel` - pass - - -def setup_package(): - """Set up the package.""" - import json - from setuptools import setup, find_packages - - filename_setup_json = 'setup.json' - filename_description = 'README.md' - - with open(filename_setup_json, 'r') as handle: - setup_json = json.load(handle) - - with open(filename_description, 'r') as handle: - description = handle.read() - - setup( - include_package_data=True, - packages=find_packages(), - reentry_register=True, - long_description=description, - long_description_content_type='text/markdown', - **setup_json - ) - - -if __name__ == '__main__': - setup_package() diff --git a/utils/__init__.py b/utils/__init__.py deleted file mode 100644 index 8576f79c8..000000000 --- a/utils/__init__.py +++ /dev/null @@ -1,2 +0,0 @@ -# -*- coding: utf-8 -*- -"""Module of utilities for the development process.""" diff --git a/utils/validate_version_number.py b/utils/validate_version_number.py deleted file mode 100644 index 6b958c7aa..000000000 --- a/utils/validate_version_number.py +++ /dev/null @@ -1,53 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- -"""Pre-commit script to ensure that version numbers in `setup.json` and `aiida_quantumespresso/__init__.py` match.""" -import os -import json -import sys - -import click - -FILEPATH_SCRIPT = os.path.split(os.path.realpath(__file__))[0] -FILEPATH_ROOT = os.path.join(FILEPATH_SCRIPT, os.pardir) -FILENAME_SETUP_JSON = 'setup.json' -FILEPATH_SETUP_JSON = os.path.join(FILEPATH_ROOT, FILENAME_SETUP_JSON) - - -def get_setup_json(): - """Return the `setup.json` as a python dictionary.""" - with open(FILEPATH_SETUP_JSON, 'r') as handle: - setup_json = json.load(handle) - - return setup_json - - -@click.group() -def cli(): - """Define the main CLI group.""" - - -@cli.command('version') -def validate_version(): - """Check that version numbers in `setup.json` and `aiida_quantumespresso/__init__.py` match.""" - sys.path.insert(0, FILEPATH_ROOT) - import aiida_quantumespresso # pylint: disable=wrong-import-position - version = aiida_quantumespresso.__version__ - - setup_content = get_setup_json() - - if version != setup_content['version']: - click.echo('Version number mismatch detected:') - click.echo(f"Version number in '{FILENAME_SETUP_JSON}': {setup_content['version']}") - click.echo(f"Version number in 'aiida_quantumespresso/__init__.py': {version}") - click.echo(f"Updating version in '{FILENAME_SETUP_JSON}' to: {version}") - - setup_content['version'] = version - with open(FILEPATH_SETUP_JSON, 'w') as handle: - # Write with indentation of two spaces and explicitly define separators to not have spaces at end of lines - json.dump(setup_content, handle, indent=4, separators=(',', ': ')) - - sys.exit(1) - - -if __name__ == '__main__': - cli() # pylint: disable=no-value-for-parameter