diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..96c89ce --- /dev/null +++ b/.gitattributes @@ -0,0 +1,3 @@ +# Ignore all Git auto CR/LF line endings conversions +* -text +pyproject.toml export-subst diff --git a/.github/workflows/pypi-release.yml b/.github/workflows/pypi-release.yml new file mode 100644 index 0000000..1cc17da --- /dev/null +++ b/.github/workflows/pypi-release.yml @@ -0,0 +1,87 @@ +name: Create library release archives, create a GH release and publish PyPI wheel and sdist on tag in main branch + + +# This is executed automatically on a tag in the main branch + +# Summary of the steps: +# - build wheels and sdist +# - upload wheels and sdist to PyPI +# - create gh-release and upload wheels and dists there +# TODO: smoke test wheels and sdist +# TODO: add changelog to release text body + +# WARNING: this is designed only for packages building as pure Python wheels + +on: + workflow_dispatch: + push: + tags: + - "v*.*.*" + +jobs: + build-pypi-distribs: + name: Build and publish library to PyPI + runs-on: ubuntu-24.04 + + steps: + - uses: actions/checkout@v4 + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: 3.12 + + - name: Install pypa/build and twine + run: python -m pip install --user --upgrade build twine pkginfo flot + + - name: Build a binary wheel and a source tarball + run: python -m flot --pyproject pyproject.toml --wheel --sdist + + - name: Validate wheel and sdist for Pypi + run: python -m twine check dist/* + + - name: Upload built archives + uses: actions/upload-artifact@v4 + with: + name: pypi_archives + path: dist/* + + + create-gh-release: + name: Create GH release + needs: + - build-pypi-distribs + runs-on: ubuntu-24.04 + + steps: + - name: Download built archives + uses: actions/download-artifact@v4 + with: + name: pypi_archives + path: dist + + - name: Create GH release + uses: softprops/action-gh-release@v2 + with: + draft: true + files: dist/* + + + create-pypi-release: + name: Create PyPI release + needs: + - create-gh-release + runs-on: ubuntu-24.04 + environment: pypi-publish + permissions: + id-token: write + + steps: + - name: Download built archives + uses: actions/download-artifact@v4 + with: + name: pypi_archives + path: dist + + - name: Publish to PyPI + if: startsWith(github.ref, 'refs/tags') + uses: pypa/gh-action-pypi-publish@release/v1 \ No newline at end of file diff --git a/.github/workflows/tests-docs-ci.yml b/.github/workflows/tests-docs-ci.yml new file mode 100644 index 0000000..8c973da --- /dev/null +++ b/.github/workflows/tests-docs-ci.yml @@ -0,0 +1,30 @@ +name: CI Tests and Documentation + +on: [push, pull_request] + +jobs: + build: + runs-on: ubuntu-24.04 + + strategy: + max-parallel: 4 + matrix: + python-version: [3.13] + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v5 + with: + python-version: ${{ matrix.python-version }} + + - name: Install Dependencies + run: make dev + + - name: Check documentation build + run: make docs + + - name: Check code, docs style and run tests + run: make test diff --git a/.gitignore b/.gitignore index 4b3cf8e..68a909e 100644 --- a/.gitignore +++ b/.gitignore @@ -1,11 +1,76 @@ -/build/ -/dist/ -__pycache__/ -/docs/_build/ -/.coverage -/.pytest_cache -/.tox -.idea/ -venv/ -*.pyc -.python-version +# Python compiled files +*.py[cod] + +# virtualenv and other misc bits +/src/*.egg-info +*.egg-info +/dist +/build +/bin +/lib +/scripts +/Scripts +/Lib +/pip-selfcheck.json +/tmp +/venv +.Python +/include +/Include +/local +*/local/* +/local/ +/share/ +/tcl/ +/.eggs/ + +# Installer logs +pip-log.txt + +# Unit test / coverage reports +.cache +.coverage +.coverage.* +nosetests.xml +htmlcov + +# Translations +*.mo + +# IDEs +.project +.pydevproject +.idea +org.eclipse.core.resources.prefs +.vscode +.vs + +# Sphinx +docs/_build +docs/bin +docs/build +docs/include +docs/Lib +doc/pyvenv.cfg +pyvenv.cfg + +# Various junk and temp files +.DS_Store +*~ +.*.sw[po] +.build +.ve +*.bak +/.cache/ + +# pyenv +/.python-version +/man/ +/.pytest_cache/ +lib64 +tcl + +# Ignore Jupyter Notebook related temp files +.ipynb_checkpoints/ +/.ruff_cache/ +.env diff --git a/.readthedocs.yml b/.readthedocs.yml new file mode 100644 index 0000000..021e6a4 --- /dev/null +++ b/.readthedocs.yml @@ -0,0 +1,29 @@ +# .readthedocs.yml +# Read the Docs configuration file +# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details + +# Required +version: 2 + +# Build in latest ubuntu/python +build: + os: ubuntu-24.04 + tools: + python: "3.13" + +# Build PDF & ePub +formats: + - epub + - pdf + +# Where the Sphinx conf.py file is located +sphinx: + configuration: docs/conf.py + +# Setting the python version and doc build requirements +python: + install: + - method: pip + path: . + extra_requirements: + - test diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 3d63aa3..bede207 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -1,15 +1,49 @@ -Changelog -========= +CHANGELOG +=============== -Next Release ----------------- +v0.7.3 +------- +- Support named pyproject.toml files properly so multiple + wheels can be created from specific pyproject.toml files +- Add standard CI tests, style and doc checks, release scripts -v0.7.2 - 2023-12-29 -v0.7.1 - 2023-12-26 -v0.6.2 - 2023-12-23 -v0.6.1 - 2023-12-23 -v0.6.0 - 2023-12-23 ----------------------- -Initial releases based on a fork of flit. +Version 0.7.2 +-------------- + +- Improve logging messages. +- Do not double include files in sdist that are selected in includes, extra and metadata files. + + +Version 0.7.1 +-------------- + +- Simplify how includes and excludes are processed. +- Make builds reproducible. +- Add support to run arbitrarry Python scripts at the start of a wheel or sdist build. +- Improve documentation, including a release checklist. + + +Version 0.6.2 +-------------- + +- First working version. + + +Version 0.6.1 +-------------- + +- Improve documentation. + + +Version 0.6.0 +-------------- + +- Work in progress. + + +Version 0.5 +----------- + +- Initial release forked from flit. diff --git a/Makefile b/Makefile index 54032a1..0a08e9a 100644 --- a/Makefile +++ b/Makefile @@ -4,7 +4,7 @@ # See https://github.com/nexB/flot/ for support and sources # Python version can be specified with `$ PYTHON_EXE=python3.x make conf` -PYTHON_EXE?=python3 +PYTHON_EXE?=python3.13 VENV=venv ACTIVATE?=. ${VENV}/bin/activate; diff --git a/docs/_static/theme_overrides.css b/docs/_static/theme_overrides.css new file mode 100644 index 0000000..5863ccf --- /dev/null +++ b/docs/_static/theme_overrides.css @@ -0,0 +1,26 @@ +/* this is the container for the pages */ +.wy-nav-content { + max-width: 100%; + padding: 0px 40px 0px 0px; + margin-top: 0px; +} + +.wy-nav-content-wrap { + border-right: solid 1px; +} + +div.rst-content { + max-width: 1300px; + border: 0; + padding: 10px 80px 10px 80px; + margin-left: 50px; +} + +@media (max-width: 768px) { + div.rst-content { + max-width: 1300px; + border: 0; + padding: 0px 10px 10px 10px; + margin-left: 0px; + } +} diff --git a/docs/history.rst b/docs/history.rst index d5a0c4b..dad35bc 100644 --- a/docs/history.rst +++ b/docs/history.rst @@ -1,41 +1,4 @@ Release history =============== -Version 0.7.2 --------------- - -- Improve logging messages. -- Do not double include files in sdist that are selected in includes, extra and metadata files. - - -Version 0.7.1 --------------- - -- Simplify how includes and excludes are processed. -- Make builds reproducible. -- Add support to run arbitrarry Python scripts at the start of a wheel or sdist build. -- Improve documentation, including a release checklist. - - -Version 0.6.2 --------------- - -- First working version. - - -Version 0.6.1 --------------- - -- Improve documentation. - - -Version 0.6.0 --------------- - -- Work in progress. - - -Version 0.5 ------------ - -- Initial release forked from flit. +.. include:: ../CHANGELOG.rst diff --git a/flot/__init__.py b/flot/__init__.py index ce90cd6..c546d19 100644 --- a/flot/__init__.py +++ b/flot/__init__.py @@ -99,21 +99,17 @@ def main(argv=None): build_wheel = True if build_sdist: - sdn = sdist.make_sdist( + sdist.make_sdist( pyproject_file=args.pyproject, output_dir=args.output_dir, ) if build_wheel: - with unpacked_tarball(sdn) as tmpdir: - sdist_dir = Path(tmpdir) - wheel.make_wheel( - pyproject_file=sdist_dir / "pyproject.toml", - output_dir=args.output_dir, - wheel_tag=args.wheel_tag, - ) - print("using wheel tag:", args.wheel_tag) - print("from unpacked sdist:", tmpdir) - + wheel.make_wheel( + pyproject_file=args.pyproject, + output_dir=args.output_dir, + wheel_tag=args.wheel_tag, + ) + print("using wheel tag:", args.wheel_tag) else: wheel.make_wheel( pyproject_file=args.pyproject, diff --git a/flot/versionno.py b/flot/versionno.py index 416514a..b688713 100644 --- a/flot/versionno.py +++ b/flot/versionno.py @@ -6,6 +6,7 @@ # Regex from packaging, via PEP 440 """Normalize version number according to PEP 440""" + import logging import os import re diff --git a/flot/wheel.py b/flot/wheel.py index 9e67631..d6e2ee1 100644 --- a/flot/wheel.py +++ b/flot/wheel.py @@ -261,7 +261,7 @@ def write_metadata(self): if rel_meta.name in existing_metadata_files: raise Exception( f"Duplicated metadata file: {rel_meta} " - f"already exists at: {existing_metadata_files[rel_meta.name ]}" + f"already exists at: {existing_metadata_files[rel_meta.name]}" ) if rel_meta.name in WELL_KNOWN_WHEEL_METADATA_FILES: diff --git a/pyproject.toml b/pyproject.toml index 916e9ef..190fcb9 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -2,7 +2,6 @@ requires = ["flot"] build-backend = "flot.buildapi" - [project] name = "flot" version = "0.7.3" @@ -17,7 +16,7 @@ maintainers = [ dependencies = [ "tomli; python_version < '3.11'", ] -requires-python = ">=3.8" +requires-python = ">=3.10" readme = "README.rst" license = {text = "BSD-3-Clause AND BSD-2-clause"} classifiers = ["Intended Audience :: Developers", @@ -40,9 +39,6 @@ test = [ "bump-my-version", "tox", "twine", -] - -doc = [ "sphinx", "sphinxcontrib_github_alt", "sphinx-rtd-theme" @@ -85,7 +81,6 @@ files = [ [tool.black] line-length = 100 include = '\.pyi?$' -skip_gitignore = true # 'extend-exclude' excludes files or directories in addition to the defaults extend-exclude = ''' ( @@ -106,16 +101,35 @@ skip = "docs,venv,tmp,build,dist,tests/data" [tool.pytest.ini_options] norecursedirs = [ ".git", + "bin", "dist", "build", + "_build", + "etc", + "local", + "ci", "docs", "man", "share", + "samples", ".cache", ".settings", + "Include", + "include", + "Lib", + "lib", + "lib64", + "Lib64", + "Scripts", + "thirdparty", "tmp", "venv", + ".venv", "tests/data", + "*/tests/test_data", + ".eggs", + "src/*/data", + "tests/*/data" ] python_files = "*.py" @@ -128,3 +142,79 @@ addopts = [ "--strict-markers", "--doctest-modules", ] + +[tool.ruff] +line-length = 100 +extend-exclude = [] +target-version = "py310" +include = [ + "pyproject.toml", + "src/**/*.py", + "etc/**/*.py", + "test/**/*.py", + "tests/**/*.py", + "doc/**/*.py", + "docs/**/*.py", + "*.py", + "." + +] +# ignore test data and testfiles: they should never be linted nor formatted +exclude = [ +# main style + "**/tests/data/**/*", +# scancode-toolkit + "**/tests/*/data/**/*", +# dejacode, purldb + "**/tests/testfiles/**/*", +# vulnerablecode, fetchcode + "**/tests/*/test_data/**/*", + "**/tests/test_data/**/*", +# django migrations + "**/migrations/**/*" +] + +[tool.ruff.lint] +# Rules: https://docs.astral.sh/ruff/rules/ +select = [ +# "E", # pycodestyle +# "W", # pycodestyle warnings + "D", # pydocstyle +# "F", # Pyflakes +# "UP", # pyupgrade +# "S", # flake8-bandit + "I", # isort +# "C9", # McCabe complexity +] +ignore = ["D1", "D200", "D202", "D203", "D205", "D212", "D400", "D415", "I001"] + + +[tool.ruff.lint.isort] +force-single-line = true +lines-after-imports = 1 +default-section = "first-party" +known-first-party = ["src", "tests", "etc/scripts/**/*.py"] +known-third-party = ["click", "pytest"] + +sections = { django = ["django"] } +section-order = [ + "future", + "standard-library", + "django", + "third-party", + "first-party", + "local-folder", +] + +[tool.ruff.lint.mccabe] +max-complexity = 10 + +[tool.ruff.lint.per-file-ignores] +# Place paths of files to be ignored by ruff here +"tests/*" = ["S101"] +"test_*.py" = ["S101"] + + +[tool.doc8] +ignore-path = ["docs/build", "doc/build", "docs/_build", "doc/_build"] +max-line-length=100