From f38d5b56b82c5d5a323fef221f58b101d40cb9b2 Mon Sep 17 00:00:00 2001 From: Mark Dickinson Date: Tue, 16 Jul 2024 16:43:50 +0100 Subject: [PATCH] Modernize package configuration --- setup.cfg => .flake8 | 0 .gitattributes | 2 - .gitignore | 3 - apptools/__init__.py | 16 --- docs/source/conf.py | 5 +- etstool.py | 1 - pyproject.toml | 53 ++++++- setup.py | 334 ------------------------------------------- 8 files changed, 55 insertions(+), 359 deletions(-) rename setup.cfg => .flake8 (100%) delete mode 100644 .gitattributes delete mode 100644 setup.py diff --git a/setup.cfg b/.flake8 similarity index 100% rename from setup.cfg rename to .flake8 diff --git a/.gitattributes b/.gitattributes deleted file mode 100644 index 106077607..000000000 --- a/.gitattributes +++ /dev/null @@ -1,2 +0,0 @@ -# For archives, substitute the commit hash in the setup.py file. -/setup.py export-subst \ No newline at end of file diff --git a/.gitignore b/.gitignore index 68ed4c3a0..aac25a01c 100644 --- a/.gitignore +++ b/.gitignore @@ -16,6 +16,3 @@ docs/build/ *.egg-info/ build/ dist/ - -# Auto-generated by setup.py -apptools/version.py diff --git a/apptools/__init__.py b/apptools/__init__.py index 812ad102f..e69de29bb 100644 --- a/apptools/__init__.py +++ b/apptools/__init__.py @@ -1,16 +0,0 @@ -# (C) Copyright 2005-2024 Enthought, Inc., Austin, TX -# All rights reserved. -# -# This software is provided without warranty under the terms of the BSD -# license included in LICENSE.txt and may be redistributed only under -# the conditions described in the aforementioned license. The license -# is also available online at http://www.enthought.com/licenses/BSD.txt -# -# Thanks for using Enthought open source! - -try: - from apptools.version import version as __version__ -except ImportError: - # If we get here, we're using a source tree that hasn't been created via - # the setup script. - __version__ = "unknown" diff --git a/docs/source/conf.py b/docs/source/conf.py index 6f24177ed..d9255924c 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -22,7 +22,8 @@ # All configuration values have a default value; values that are commented out # serve to show the default value. -import apptools +import importlib.metadata + import enthought_sphinx_theme # General configuration @@ -53,7 +54,7 @@ # The default replacements for |version| and |release|, also used in various # other places throughout the built documents. -version = release = apptools.__version__ +version = release = importlib.metadata.version("apptools") # There are two options for replacing |today|: either, you set today to some # non-false value, then it is used: diff --git a/etstool.py b/etstool.py index 6988d7e77..6699f412c 100644 --- a/etstool.py +++ b/etstool.py @@ -307,7 +307,6 @@ def flake8(edm, runtime, environment): "apptools", "docs", "etstool.py", - "setup.py", "examples", "integrationtests", ] diff --git a/pyproject.toml b/pyproject.toml index 7e01ab27f..2886de6f3 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,3 +1,54 @@ [build-system] -requires = ['setuptools', 'wheel'] +requires = ['setuptools'] build-backend = 'setuptools.build_meta' + +[project] +name = 'apptools' +version = '5.4.0' +description = 'application tools' +readme = 'README.rst' +requires-python = '>= 3.8' +license = { file = 'LICENSE.txt' } +authors = [{ name = 'Enthought', email = 'info@enthought.com' }] +dependencies = ['traits >= 6.2.0'] +classifiers = [ + 'Development Status :: 5 - Production/Stable', + 'Intended Audience :: Developers', + 'Intended Audience :: Science/Research', + 'License :: OSI Approved :: BSD License', + 'Operating System :: MacOS', + 'Operating System :: Microsoft :: Windows', + 'Operating System :: OS Independent', + 'Operating System :: POSIX', + 'Operating System :: Unix', + 'Programming Language :: Python', + 'Topic :: Scientific/Engineering', + 'Topic :: Software Development', + 'Topic :: Software Development :: Libraries', +] + +[project.optional-dependencies] +docs = ['enthought_sphinx_theme', 'sphinx'] +gui = ['pyface', 'traitsui'] +# PyTables is currently incompatible with NumPy 2.0 +# https://github.com/enthought/apptools/issues/345 +h5 = ['numpy < 2.0', 'pandas', 'tables'] +persistence = ['numpy < 2.0'] +preferences = ['configobj'] +test = ["importlib-resources>=1.1.0; python_version<'3.9'"] + + +[project.urls] +documentation = 'https://docs.enthought.com/apptools' +repository = 'https://github.com/enthought/apptools' +issues = 'https://github.com/enthought/apptools/issues' + +[tool.setuptools.packages.find] +include = ['apptools*'] + +[tool.setuptools.package-data] +apptools = [ + 'logger/plugin/*.ini', + 'logger/plugin/view/images/*.png', + 'preferences/tests/*.ini', +] diff --git a/setup.py b/setup.py deleted file mode 100644 index 1a87519df..000000000 --- a/setup.py +++ /dev/null @@ -1,334 +0,0 @@ -# (C) Copyright 2008-2024 Enthought, Inc., Austin, TX -# All rights reserved. -# -# This software is provided without warranty under the terms of the BSD -# license included in LICENSE.txt and may be redistributed only under -# the conditions described in the aforementioned license. The license -# is also available online at http://www.enthought.com/licenses/BSD.txt -# -# Thanks for using Enthought open source! - -import os -import runpy -import subprocess - -from setuptools import setup, find_packages - -# Version information; update this by hand when making a new bugfix or feature -# release. The actual package version is autogenerated from this information -# together with information from the version control system, and then injected -# into the package source. -MAJOR = 5 -MINOR = 4 -MICRO = 0 -PRERELEASE = "" -IS_RELEASED = False - -# If this file is part of a Git export (for example created with "git archive", -# or downloaded from GitHub), ARCHIVE_COMMIT_HASH gives the full hash of the -# commit that was exported. -ARCHIVE_COMMIT_HASH = "$Format:%H$" - -# Templates for version strings. -RELEASED_VERSION = "{major}.{minor}.{micro}{prerelease}" -UNRELEASED_VERSION = "{major}.{minor}.{micro}{prerelease}.dev{dev}" - -# Paths to the autogenerated version file and the Git directory. -HERE = os.path.abspath(os.path.dirname(__file__)) -VERSION_FILE = os.path.join(HERE, "apptools", "version.py") -GIT_DIRECTORY = os.path.join(HERE, ".git") - -# Template for the autogenerated version file. -VERSION_FILE_TEMPLATE = '''\ -# (C) Copyright 2008-2024 Enthought, Inc., Austin, TX -# All rights reserved. -# -# This software is provided without warranty under the terms of the BSD -# license included in LICENSE.txt and may be redistributed only under -# the conditions described in the aforementioned license. The license -# is also available online at http://www.enthought.com/licenses/BSD.txt -# -# Thanks for using Enthought open source! - -""" -Version information for this Apptools distribution. - -This file is autogenerated by the Apptools setup.py script. -""" - -#: The full version of the package, including a development suffix -#: for unreleased versions of the package. -version = "{version}" - -#: The Git revision from which this release was made. -git_revision = "{git_revision}" - -#: Flag whether this is a final release -is_released = {is_released} -''' - -# Git executable to use to get revision information. -GIT = "git" - - -def _git_output(args): - """ - Call Git with the given arguments and return the output as (Unicode) text. - """ - return subprocess.check_output([GIT] + args).decode("utf-8") - - -def _git_info(commit="HEAD"): - """ - Get information about the given commit from Git. - - Parameters - ---------- - commit : str, optional - Commit to provide information for. Defaults to "HEAD". - - Returns - ------- - git_count : int - Number of revisions from this commit to the initial commit. - git_revision : unicode - Commit hash for HEAD. - - Raises - ------ - EnvironmentError - If Git is not available. - subprocess.CalledProcessError - If Git is available, but the version command fails (most likely - because there's no Git repository here). - """ - count_args = ["rev-list", "--count", "--first-parent", commit] - git_count = int(_git_output(count_args)) - - revision_args = ["rev-list", "--max-count", "1", commit] - git_revision = _git_output(revision_args).rstrip() - - return git_count, git_revision - - -def write_version_file(version, git_revision): - """ - Write version information to the version file. - - Overwrites any existing version file. - - Parameters - ---------- - version : unicode - Package version. - git_revision : unicode - The full commit hash for the current Git revision. - """ - with open(VERSION_FILE, "w", encoding="ascii") as version_file: - version_file.write( - VERSION_FILE_TEMPLATE.format( - version=version, - git_revision=git_revision, - is_released=IS_RELEASED, - ) - ) - - -def read_version_file(): - """ - Read version information from the version file, if it exists. - - Returns - ------- - version : unicode - The full version, including any development suffix. - git_revision : unicode - The full commit hash for the current Git revision. - - Raises - ------ - EnvironmentError - If the version file does not exist. - """ - version_info = runpy.run_path(VERSION_FILE) - return (version_info["version"], version_info["git_revision"]) - - -def git_version(): - """ - Construct version information from local variables and Git. - - Returns - ------- - version : unicode - Package version. - git_revision : unicode - The full commit hash for the current Git revision. - - Raises - ------ - EnvironmentError - If Git is not available. - subprocess.CalledProcessError - If Git is available, but the version command fails (most likely - because there's no Git repository here). - """ - git_count, git_revision = _git_info() - version_template = RELEASED_VERSION if IS_RELEASED else UNRELEASED_VERSION - version = version_template.format( - major=MAJOR, - minor=MINOR, - micro=MICRO, - prerelease=PRERELEASE, - dev=git_count, - ) - return version, git_revision - - -def archive_version(): - """ - Construct version information for an archive. - - Returns - ------- - version : str - Package version. - git_revision : str - The full commit hash for the current Git revision. - - Raises - ------ - ValueError - If this does not appear to be an archive. - """ - if "$" in ARCHIVE_COMMIT_HASH: - raise ValueError("This does not appear to be an archive.") - - version_template = RELEASED_VERSION if IS_RELEASED else UNRELEASED_VERSION - version = version_template.format( - major=MAJOR, - minor=MINOR, - micro=MICRO, - prerelease=PRERELEASE, - dev="-unknown", - ) - return version, ARCHIVE_COMMIT_HASH - - -def resolve_version(): - """ - Process version information and write a version file if necessary. - - Returns the current version information. - - Returns - ------- - version : unicode - Package version. - git_revision : unicode - The full commit hash for the current Git revision. - """ - if os.path.isdir(GIT_DIRECTORY): - # This is a local clone; compute version information and write - # it to the version file, overwriting any existing information. - version = git_version() - print("Computed package version: {}".format(version)) - print("Writing version to version file {}.".format(VERSION_FILE)) - write_version_file(*version) - elif "$" not in ARCHIVE_COMMIT_HASH: - # This is a source archive. - version = archive_version() - print("Archive package version: {}".format(version)) - print("Writing version to version file {}.".format(VERSION_FILE)) - write_version_file(*version) - elif os.path.isfile(VERSION_FILE): - # This is a source distribution. Read the version information. - print("Reading version file {}".format(VERSION_FILE)) - version = read_version_file() - print("Package version from version file: {}".format(version)) - else: - # This is a source archive for an unreleased version. - raise RuntimeError( - "Unable to determine package version. No local Git clone " - "detected, and no version file found at {}." - "Please use a source dist or a git clone.".format(VERSION_FILE) - ) - - return version - - -def get_long_description(): - """ Read long description from README.txt. """ - with open("README.rst", "r", encoding="utf-8") as readme: - return readme.read() - - -if __name__ == "__main__": - version, git_revision = resolve_version() - - setup( - name='apptools', - version=version, - author='Enthought, Inc.', - author_email='info@enthought.com', - maintainer='ETS Developers', - maintainer_email='enthought-dev@enthought.com', - url='https://docs.enthought.com/apptools', - download_url=('https://www.github.com/enthought/apptools'), - classifiers=[ - c.strip() for c in """\ - Development Status :: 5 - Production/Stable - Intended Audience :: Developers - Intended Audience :: Science/Research - License :: OSI Approved :: BSD License - Operating System :: MacOS - Operating System :: Microsoft :: Windows - Operating System :: OS Independent - Operating System :: POSIX - Operating System :: Unix - Programming Language :: Python - Topic :: Scientific/Engineering - Topic :: Software Development - Topic :: Software Development :: Libraries - """.splitlines() if len(c.strip()) > 0], - description='application tools', - long_description=get_long_description(), - long_description_content_type="text/x-rst", - include_package_data=True, - package_data={ - 'apptools': [ - 'logger/plugin/*.ini', - 'logger/plugin/view/images/*.png', - 'preferences/tests/*.ini' - ] - }, - install_requires=['traits>=6.2.0'], - extras_require={ - "docs": ["enthought-sphinx-theme", "sphinx"], - "test": [ - "importlib-resources>=1.1.0; python_version<'3.9'", - ], - "gui": [ - "pyface", - "traitsui", - ], - "h5": [ - # PyTables is currently incompatible with NumPy 2.0 - # xref: enthought/apptools#345 - "numpy < 2.0", - "pandas", - "tables", - ], - "persistence": [ - "numpy < 2.0", - ], - "preferences": [ - "configobj", - ], - }, - license='BSD', - packages=find_packages(), - platforms=["Windows", "Linux", "Mac OS-X", "Unix", "Solaris"], - zip_safe=False, - python_requires=">=3.8", - )