diff --git a/.github/workflows/checks.yml b/.github/workflows/checks.yml index a9a66d2a0a..0719ec8b42 100644 --- a/.github/workflows/checks.yml +++ b/.github/workflows/checks.yml @@ -18,15 +18,15 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v2 + uses: actions/checkout@v6 - name: Initialize CodeQL - uses: github/codeql-action/init@v2 + uses: github/codeql-action/init@v4 with: languages: python - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v2 + uses: github/codeql-action/analyze@v4 tests-linux: name: Unit Tests (Linux) @@ -34,14 +34,14 @@ jobs: strategy: matrix: - python-version: ['3.8', '3.9', '3.10'] + python-version: ['3.9', '3.10', '3.11', '3.12', '3.13', '3.14'] steps: - name: Checkout repository - uses: actions/checkout@v2 + uses: actions/checkout@v6 - name: Setup Python ${{ matrix.python-version }} - uses: actions/setup-python@v2.3.1 + uses: actions/setup-python@v6.2.0 with: python-version: ${{ matrix.python-version }} @@ -50,7 +50,7 @@ jobs: echo "Installing pip + wheel..." python -m pip install --upgrade pip wheel echo "Installing python dependencies..." - python -m pip install -r requirements.txt + python -m pip install . - name: Test env: @@ -63,14 +63,14 @@ jobs: strategy: matrix: - python-version: ['3.8', '3.9', '3.10'] + python-version: ['3.9', '3.10', '3.11', '3.12', '3.13', '3.14'] steps: - name: Checkout repository - uses: actions/checkout@v2 + uses: actions/checkout@v6 - name: Setup Python ${{ matrix.python-version }} - uses: actions/setup-python@v2.3.1 + uses: actions/setup-python@v6.2.0 with: python-version: ${{ matrix.python-version }} @@ -80,7 +80,7 @@ jobs: echo "Installing pip + wheel..." python -m pip install --upgrade pip wheel echo "Installing dependencies..." - python -m pip install -r requirements.txt + python -m pip install . - name: Test env: diff --git a/Makefile b/Makefile index 05808f2f99..6af1e7bac6 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,8 @@ version := $(shell python id2xml/run.py --version | awk '{print $$2}' ) +pyversion := $(shell python -c "import sys; print(str(sys.version_info.major) + str(sys.version_info.minor))" ) + testfiles= \ draft-baba-iot-problems-03.txt \ draft-ietf-6man-rfc2460bis-11.txt \ @@ -32,7 +34,7 @@ diffiles = $(addsuffix .diff, $(basename $(resfiles))) tests = $(addsuffix .test, $(basename $(resfiles))) pyfiles = $(wildcard id2xml/*.py) -all: install upload +all: install upload man %.1: id2xml/run.py id2xml/__init__.py Makefile id2xml -h | sed -e 's/^ -/\n -/' \ @@ -40,18 +42,15 @@ all: install upload | txt2man -s1 -r'RFC Format Tools' -t $< > $@ -%.1.gz: %.1 +man: %.1 gzip < $< > $@ pyflakes: pyflakes id2xml -install: id2xml/id2xml.1.gz - python setup.py -q install - -env/bin/id2xml: $(pyfiles) setup.py - python setup.py -q install +install: $(pyfiles) pyproject.toml + python -m pip install .[test] # ------------------------------------------------------------------------ @@ -62,7 +61,7 @@ env/bin/id2xml: $(pyfiles) setup.py # ------------------------------------------------------------------------ # test -test: env/bin/id2xml clean $(resfiles) $(xml3files) $(diffiles) $(tests) +test: id2xml clean $(resfiles) $(xml3files) $(diffiles) $(tests) .PHONY: clean clean: @@ -114,17 +113,17 @@ test/out/%.v3.xml: test/in/%.txt $(pyfiles) # ------------------------------------------------------------------------ -dist/id2xml-$(version).tar.gz: MANIFEST.in setup.py $(pyfiles) - python setup.py -q sdist +dist/id2xml-$(version).tar.gz: MANIFEST.in pyproject.toml $(pyfiles) + python -m build --sdist -dist/id2xml-$(version)-py27-none-any.whl: MANIFEST.in setup.py $(pyfiles) - python setup.py -q bdist_wheel --python-tag py27 +dist/id2xml-$(version)-py$(pyversion)-none-any.whl: MANIFEST.in pyproject.toml $(pyfiles) + python -m build --wheel dist/%.asc: dist/% gpg --detach-sign -a $< sdist: dist/id2xml-$(version).tar.gz dist/id2xml-$(version).tar.gz.asc -bdist_wheel: dist/id2xml-$(version)-py27-none-any.whl dist/id2xml-$(version)-py27-none-any.whl.asc +bdist_wheel: dist/id2xml-$(version)-py$(pyversion)-none-any.whl dist/id2xml-$(version)-py$(pyversion)-none-any.whl.asc dist: test sdist # bdist_wheel diff --git a/bin/mkrelease b/bin/mkrelease index b89c04413d..010c157d88 100755 --- a/bin/mkrelease +++ b/bin/mkrelease @@ -181,7 +181,7 @@ changes=$( sed -n "/^$PROJ ($VER)/,/^ -- /p" changelog ) note "$changes" note "Upgrading the python library modules before checking migrations and running tests ..." -$do pip install --upgrade -r requirements.txt +$do pip install --upgrade . note "Running the tests suite ..." $do make test diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000000..385b8008ba --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,66 @@ +# ------------------------------------------------------- +# Copyright The IETF Trust 2011-2026, All Rights Reserved +# ------------------------------------------------------- +[build-system] +requires = ["setuptools", "wheel"] +build-backend = "setuptools.build_meta" + +[project] +name = "id2xml" +version = "1.5.2" +authors = [ + {name = "Henrik Levkowetz", email = "henrik@levkowetz.com"}, +] + +description = "Convert text-format RFCs and Internet-Drafts to .xml format" +keywords = ["ietf", "rfc", "text", "internet-draft", "xml"] +readme = "README.rst" +license = "BSD-3-Clause" +license-files = ["LICENSE"] +requires-python = ">=3.9" +classifiers = [ + 'Intended Audience :: Other Audience', + 'Topic :: Text Processing', + 'Topic :: Text Processing :: Markup :: XML', + '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', + 'Programming Language :: Python :: 3.14', +] + +dependencies = [ + "lxml", + "pathlib2", + "six", + "xml2rfc>=2.8.2", + "decorator", +] + +[project.urls] +homepage = "https://github.com/ietf-tools/id2xml" +source = "https://github.com/ietf-tools/id2xml" +issues = "https://github.com/ietf-tools/id2xml/issues" +releasenotes = "https://github.com/ietf-tools/id2xml/releases" + +[project.optional-dependencies] +test = [ + "coverage", + "pycodestyle", + "pyflakes", + "tox", +] +dev = [ + "twine", +] + +[project.scripts] +id2xml = "id2xml.run:run" + +[tool.setuptools] +packages = ["id2xml"] +include-package-data = true + +[tool.setuptools.package-data] +id2xml = ["data/*", "debug.py", "utils.py", "run.py"] diff --git a/requirements.txt b/requirements.txt deleted file mode 100644 index 34223a3179..0000000000 --- a/requirements.txt +++ /dev/null @@ -1,5 +0,0 @@ -lxml -pathlib2 -six -xml2rfc>=2.8.2 -decorator diff --git a/setup.py b/setup.py deleted file mode 100644 index bf3801aeee..0000000000 --- a/setup.py +++ /dev/null @@ -1,167 +0,0 @@ -#!/usr/bin/env python -# -------------------------------------------------- -# Copyright The IETF Trust 2011, All Rights Reserved -# -------------------------------------------------- - -import re - -from setuptools import setup, find_packages -from codecs import open -from os import path - - -here = path.abspath(path.dirname(__file__)) - -# Get the long description from the README file -with open(path.join(here, 'README.rst'), encoding='utf-8') as file: - long_description = file.read() - -# Get the requirements from the local requirements.txt file -with open(path.join(here, 'requirements.txt'), encoding='utf-8') as file: - requirements = file.read().splitlines() - -# Get the requirements from the local requirements.txt file -with open(path.join(here, 'MANIFEST.in'), encoding='utf-8') as file: - extra_files = [ l.split()[1] for l in file.read().splitlines() if l ] - -def parse(changelog): - ver_line = "^([a-z0-9+-]+) \(([^)]+)\)(.*?) *$" - sig_line = "^ -- ([^<]+) <([^>]+)> (.*?) *$" - # - entries = [] - if type(changelog) == type(''): - changelog = open(changelog) - for line in changelog: - if re.match(ver_line, line): - package, version, rest = re.match(ver_line, line).groups() - entry = {} - entry["package"] = package - entry["version"] = version - entry["logentry"] = "" - elif re.match(sig_line, line): - author, email, date = re.match(sig_line, line).groups() - entry["author"] = author - entry["email"] = email - entry["datetime"] = date - entry["date"] = " ".join(date.split()[:3]) - entries += [ entry ] - else: - entry["logentry"] += line - changelog.close() - entry["logentry"] = entry["logentry"].strip() - return entries - -changelog_entry_template = """ -Version %(version)s (%(date)s) ------------------------------------------------- - -%(logentry)s""" - -long_description += """ -Changelog -========= -""" + "\n".join([ changelog_entry_template % entry for entry in parse("changelog")[:2] ]) - - - -import id2xml - -setup( - name='id2xml', - - # Versions should comply with PEP440. For a discussion on single-sourcing - # the version across setup.py and the project code, see - # https://packaging.python.org/en/latest/single_source_version.html - version=id2xml.__version__, - - description="Convert text-format RFCs and Internet-Drafts to .xml format", - long_description=long_description, - - # The project's main homepage. - url='https://tools.ietf.org/tools/ietfdb/browser/branch/elft/id2xml/', - - # Author details - author='Henrik Levkowetz', - author_email='henrik@levkowetz.com', - - # Choose your license - license='Simplified BSD', - - # See https://pypi.python.org/pypi?%3Aaction=list_classifiers - classifiers=[ - # How mature is this project? Common values are - # 3 - Alpha - # 4 - Beta - # 5 - Production/Stable - 'Development Status :: 5 - Production/Stable', - - # Indicate who your project is intended for - 'Intended Audience :: Other Audience', - 'Topic :: Text Processing', - 'Topic :: Text Processing :: Markup :: XML', - - # Pick your license as you wish (should match "license" above) - 'License :: OSI Approved :: BSD License', - - # Specify the Python versions you support here. In particular, ensure - # that you indicate whether you support Python 2, Python 3 or both. - 'Programming Language :: Python :: 2.7', - #'Programming Language :: Python :: 3', - #'Programming Language :: Python :: 3.3', - #'Programming Language :: Python :: 3.4', - 'Programming Language :: Python :: 3.5', - 'Programming Language :: Python :: 3.6', - 'Programming Language :: Python :: 3.7', - ], - - # What does your project relate to? - keywords='Internet-Draft text to xml conversion', - - # You can just specify the packages manually here if your project is - # simple. Or you can use find_packages(). - packages=find_packages(exclude=['contrib', 'docs', 'tests']), - - # Alternatively, if you want to distribute just a my_module.py, uncomment - # this: - #py_modules=["debug"], - - # List run-time dependencies here. These will be installed by pip when - # your project is installed. For an analysis of "install_requires" vs pip's - # requirements files see: - # https://packaging.python.org/en/latest/requirements.html - install_requires=requirements, - - # List additional groups of dependencies here (e.g. development - # dependencies). You can install these using the following syntax, - # for example: - # $ pip install -e .[dev,test] - extras_require={ - 'dev': ['twine',], - #'test': ['coverage'], - }, - - # If there are data files included in your packages that need to be - # installed, specify them here. If using Python 2.6 or less, then these - # have to be included in MANIFEST.in as well. - package_data={ - 'id2xml': ['data/*', 'id2xml.1.gz', 'debug.py', 'utils.py', 'run.py' ], - }, - - # Although 'package_data' is the preferred approach, in some case you may - # need to place data files outside of your packages. See: - # http://docs.python.org/3.4/distutils/setupscript.html#installing-additional-files # noqa - # In this case, 'data_file' will be installed into '/my_data' - # data_files=[('/usr/local/share/man/man1', ['id2xml/id2xml.1.gz',])], - - # To provide executable scripts, use entry points in preference to the - # "scripts" keyword. Entry points provide cross-platform support and allow - # pip to create the appropriate form of executable for the target platform. - entry_points={ - 'console_scripts': [ - 'id2xml=id2xml.run:run', - ], - }, - - # We're reading schema files from a package directory. - zip_safe = False, -)