Replace setuptools and setup.py with hatch and pyproject.toml

This commit is contained in:
Chris Mayo 2022-09-05 19:24:01 +01:00
parent 86243c00a1
commit 47d1015e00
22 changed files with 266 additions and 373 deletions

View file

@ -1 +0,0 @@
ref-names: $Format:%D$

1
.gitattributes vendored
View file

@ -1,4 +1,3 @@
.git_archival.txt export-subst
.gitattributes export-ignore .gitattributes export-ignore
.gitignore export-ignore .gitignore export-ignore
/doc/web export-ignore /doc/web export-ignore

View file

@ -13,7 +13,7 @@ jobs:
with: with:
repository: linkchecker/linkchecker repository: linkchecker/linkchecker
ref: master ref: master
# Needed for setuptools_scm to extract LinkChecker version from tag # Needed for hatch-vcs to extract LinkChecker version from tag
# https://github.com/actions/checkout/issues/249 # https://github.com/actions/checkout/issues/249
fetch-depth: 0 fetch-depth: 0
@ -26,8 +26,8 @@ jobs:
- name: Install Python packages - name: Install Python packages
run: > run: >
pip3 install dnspython beautifulsoup4 requests \ pip3 install dnspython beautifulsoup4 requests \
sphinx sphinx_epytext sphinx_rtd_theme sphinx-sitemap \ hatch hatch-vcs sphinx sphinx_epytext sphinx_rtd_theme \
sphinx-intl setuptools_scm sphinx-sitemap sphinx-intl
- name: Prepare git environment - name: Prepare git environment
run: | run: |
@ -36,15 +36,11 @@ jobs:
git checkout -b man-updates git checkout -b man-updates
git remote add local ${{ github.server_url }}/${{ github.repository }} git remote add local ${{ github.server_url }}/${{ github.repository }}
- name: Create application version number
run: >
python3 setup.py build
- name: Build man pages - name: Build man pages
run: | run: |
make -C doc locale hatch -e doc run locale
git commit -a -m "Update doc translation catalogs" git commit -a -m "Update doc translation catalogs"
make -C doc man hatch -e doc run man
git commit -a -m "Update man pages" git commit -a -m "Update man pages"
- name: Build application translations catalogs - name: Build application translations catalogs

View file

@ -50,7 +50,7 @@ jobs:
uses: actions/cache@v2 uses: actions/cache@v2
with: with:
path: ~/.cache/pip path: ~/.cache/pip
key: ${{ runner.os }}-pip-${{ matrix.python-version }}-${{ hashFiles('tox.ini', 'setup.py') }} key: ${{ runner.os }}-pip-${{ matrix.python-version }}-${{ hashFiles('tox.ini', 'pyproject.toml') }}
restore-keys: | restore-keys: |
${{ runner.os }}-pip-${{ matrix.python-version }}- ${{ runner.os }}-pip-${{ matrix.python-version }}-
${{ runner.os }}-pip- ${{ runner.os }}-pip-
@ -58,7 +58,7 @@ jobs:
- name: Install Python dependencies - name: Install Python dependencies
run: | run: |
python -m pip install -U pip python -m pip install -U pip
python -m pip install -U setuptools wheel python -m pip install -U hatchling hatch-vcs polib
python -m pip install -U tox coveralls python -m pip install -U tox coveralls
- name: Wait for ClamAV to be ready - name: Wait for ClamAV to be ready
@ -102,16 +102,15 @@ jobs:
- name: Install Python packages - name: Install Python packages
run: | run: |
pip install -r requirements.txt Sphinx sphinx-epytext sphinx-intl \ pip install -U -r requirements.txt hatch hatch-vcs Sphinx \
sphinx-rtd-theme sphinx-sitemap sphinx-epytext sphinx-intl sphinx-rtd-theme sphinx-sitemap
- name: Build - name: Build
run: | run: |
python3 setup.py build egg_info hatch -e doc run code
make -C doc code hatch -e doc run html
make -C doc html hatch -e doc run locale
make -C doc locale hatch -e doc run man
make -C doc man
make -C doc check make -C doc check
lint: lint:
@ -145,7 +144,7 @@ jobs:
- name: Install dependencies - name: Install dependencies
run: | run: |
python -m pip install -U pip python -m pip install -U pip
python -m pip install -U setuptools wheel python -m pip install -U hatchling hatch-vcs polib
python -m pip install -U tox python -m pip install -U tox
- name: Run ${{ matrix.toxenv }} - name: Run ${{ matrix.toxenv }}

View file

@ -15,7 +15,7 @@ jobs:
steps: steps:
- uses: actions/checkout@v2 - uses: actions/checkout@v2
# Needed for setuptools_scm to extract LinkChecker version from tag # Needed for hatch-vcs to extract LinkChecker version from tag
# https://github.com/actions/checkout/issues/249 # https://github.com/actions/checkout/issues/249
with: with:
fetch-depth: 0 fetch-depth: 0
@ -30,13 +30,13 @@ jobs:
- name: Install Python packages - name: Install Python packages
run: > run: >
pip install dnspython beautifulsoup4 requests \ pip install dnspython beautifulsoup4 requests \
sphinx sphinx_epytext sphinx_rtd_theme sphinx-sitemap hatch hatch-vcs sphinx sphinx_epytext sphinx_rtd_theme \
sphinx-sitemap
- name: Build - name: Build
run: | run: |
python3 setup.py build egg_info hatch -e doc run code
make -C doc code hatch -e doc run html
make -C doc html
- name: Publish - name: Publish
uses: peaceiris/actions-gh-pages@068dc23d9710f1ba62e86896f84735d869951305 uses: peaceiris/actions-gh-pages@068dc23d9710f1ba62e86896f84735d869951305

View file

@ -12,7 +12,7 @@ jobs:
steps: steps:
- uses: actions/checkout@v2 - uses: actions/checkout@v2
# Needed for setuptools_scm to extract LinkChecker version from tag # Needed for hatch-vcs to extract LinkChecker version from tag
# https://github.com/actions/checkout/issues/249 # https://github.com/actions/checkout/issues/249
with: with:
fetch-depth: 0 fetch-depth: 0
@ -25,7 +25,7 @@ jobs:
- name: Install Python packages - name: Install Python packages
run: > run: >
pip3 install polib setuptools_scm twine wheel pip3 install -U hatchling hatch-vcs polib twine
- name: Set SOURCE_DATE_EPOCH - name: Set SOURCE_DATE_EPOCH
run: > run: >
@ -33,7 +33,7 @@ jobs:
- name: Create distribution files - name: Create distribution files
run: > run: >
python3 setup.py sdist bdist_wheel python3 -m hatchling build
- name: Check distribution files - name: Check distribution files
run: > run: >

1
.gitignore vendored
View file

@ -45,3 +45,4 @@ coverage.xml
doc/html doc/html
doc/src/_build doc/src/_build
doc/src/code/linkcheck doc/src/code/linkcheck
linkcheck/_release.py

View file

@ -11,7 +11,6 @@ include pyoxidizer.bzl
include .project include .project
include .pydevproject include .pydevproject
include .yamllint include .yamllint
include _release_date
include linkcheck/data/linkcheckerrc include linkcheck/data/linkcheckerrc
recursive-include cgi-bin \ recursive-include cgi-bin \
@ -46,6 +45,8 @@ recursive-include doc \
*.yml \ *.yml \
Makefile \ Makefile \
linkcheckerrc_* linkcheckerrc_*
recursive-include linkcheck \
*.mo
recursive-include po \ recursive-include po \
*.po \ *.po \
*.pot \ *.pot \
@ -77,6 +78,8 @@ recursive-include tests \
*.xml \ *.xml \
*.zip \ *.zip \
Bookmarks Bookmarks
recursive-include tools \
*.py
recursive-include windows \ recursive-include windows \
*.bat \ *.bat \
*.cer \ *.cer \

View file

@ -4,7 +4,7 @@ LOCALES:=en de
all: html man all: html man
code: clean code: clean
PYTHONPATH=.. sphinx-autogen src/code/index.rst python3 -m sphinx.ext.autosummary.generate src/code/index.rst
html: html:
make -C src html make -C src html

View file

@ -2,6 +2,11 @@
Changes: Changes:
- PyXDG is no longer used - PyXDG is no longer used
- setuptools and setup.py replaced with hatchling and pyproject.toml
- The application version is derived from git tags using hatch-vcs
- Documentation build is run using hatch
- Binary translation catalogs are compiled using polib during distribution
package building and are now included in sdist packages
10.1.0 (released 22.12.2021) 10.1.0 (released 22.12.2021)

View file

@ -19,10 +19,10 @@ sphinx_sitemap
Configuration Configuration
------------- -------------
Before building either man pages or HTML, generate ``PKG-INFO`` Before building either man pages or HTML, the package metadata needs to be
containing copyright, author and version with: created to derive copyright, author and version values. Running Sphinx in a
hatch environment manages this for us.
``linkchecker $ ./setup.py build``
Man Pages Man Pages
--------- ---------
@ -31,7 +31,7 @@ Source files are in doc/src/man.
The pages can be built with: The pages can be built with:
``linkchecker/doc $ make man`` ``linkchecker $ hatch -e doc run man``
The files are saved in doc/man. The files are saved in doc/man.
@ -46,11 +46,11 @@ HTML
``doc/src/code/index.rst`` gives an overview of the LinkChecker code, optionally a navigable ``doc/src/code/index.rst`` gives an overview of the LinkChecker code, optionally a navigable
copy of the LinkChecker source can be created with: copy of the LinkChecker source can be created with:
``linkchecker/doc $ make code`` ``linkchecker $ hatch -e doc run code``
Build the HTML files with: Build the HTML files with:
``linkchecker/doc $ make html`` ``linkchecker $ hatch -e doc run html``
The files are saved in doc/html. The files are saved in doc/html.

View file

@ -3,13 +3,10 @@ Installation
If you are upgrading from older versions of LinkChecker you should If you are upgrading from older versions of LinkChecker you should
also read the upgrading documentation stored in upgrading.txt. also read the upgrading documentation stored in upgrading.txt.
When installing from source, for application translations to be installed Installing a LinkChecker release uses pre-built distribution packages. Building
polib_ needs to be installed before LinkChecker. After LinkChecker installation the distribution packages requires hatchling_ and hatch-vcs_, and for application
polib_ can be removed. translations to be compiled polib_ needs to be installed. After the sdist/wheel
has been built polib_ can be removed. pip-run_ may be useful for this.
Installing from the GitHub release assets requires setuptools-scm-git-archive_.
pip-run_ may be useful for both of these cases.
There are several steps to resolve problems with detecting the character There are several steps to resolve problems with detecting the character
encoding of checked HTML pages: encoding of checked HTML pages:
@ -34,7 +31,9 @@ used.
.. _polib: https://pypi.org/project/polib/ .. _polib: https://pypi.org/project/polib/
.. _setuptools-scm-git-archive: https://pypi.org/project/setuptools-scm-git-archive/ .. _hatchling: https://pypi.org/project/hatchling/
.. _hatch-vcs: https://pypi.org/project/hatch-vcs/
.. _venv: https://docs.python.org/3/library/venv.html#creating-virtual-environments .. _venv: https://docs.python.org/3/library/venv.html#creating-virtual-environments
@ -42,12 +41,18 @@ Setup with pip
------------------ ------------------
pip_ can be used to install LinkChecker on the local system. pip_ can be used to install LinkChecker on the local system.
If you want application translations, first: To install the latest release from PyPI:
``pip3 install linkchecker``
Alternatively you can install the latest source from the LinkChecker GitHub repository.
First, if you want application translations:
``pip3 install polib`` ``pip3 install polib``
Then this command will install LinkChecker from the latest source: Then:
``pip3 install git+https://github.com/linkchecker/linkchecker.git`` ``pip3 install git+https://github.com/linkchecker/linkchecker.git``
N.B. git archive's cannot be used.
.. _pip: https://pypi.org/project/pip/ .. _pip: https://pypi.org/project/pip/
Setup for Windows Setup for Windows
@ -73,64 +78,59 @@ Manual setup for Unix systems
----------------------------- -----------------------------
First, install the required software. First, install the required software.
1. Python >= 3.7 from https://www.python.org/ 1. Python hatchling package from https://pypi.org/project/hatchling/
Be sure to also have installed the included distutils module. 2. Python hatch-vcs package from https://pypi.org/project/hatch-vcs/
On most distributions, the distutils module is included in
an extra ``python-dev`` package.
2. Python Requests package from https://pypi.org/project/requests/ 3. Python Requests package from https://pypi.org/project/requests/
3. Python Beautiful Soup package from https://pypi.org/project/beautifulsoup4/ 4. Python Beautiful Soup package from https://pypi.org/project/beautifulsoup4/
4. *Optional, installation time only, for translations:* 5. Python dnspython package from https://pypi.org/project/dnspython/
6. *Optional, build time only, for translations:*
polib Python module from https://pypi.org/project/polib/ polib Python module from https://pypi.org/project/polib/
5. *Optional, for bash-completion:* 7. *Optional, for bash-completion:*
argcomplete Python module from https://pypi.org/project/argcomplete/ argcomplete Python module from https://pypi.org/project/argcomplete/
6. *Optional, for displaying country codes:* 8. *Optional, for displaying country codes:*
GeoIP from https://pypi.org/project/GeoIP/ GeoIP from https://pypi.org/project/GeoIP/
7. *Optional, used for Virus checking:* 9. *Optional, used for Virus checking:*
ClamAv from https://www.clamav.net/ ClamAv from https://www.clamav.net/
8. *Optional, to run the WSGI web interface:* 10. *Optional, to run the WSGI web interface:*
Apache from https://httpd.apache.org/ Apache from https://httpd.apache.org/
mod_wsgi from https://pypi.org/project/mod-wsgi/ mod_wsgi from https://pypi.org/project/mod-wsgi/
Note for developers: if you want to regenerate the po/linkchecker.pot template Note for developers: if you want to regenerate the po/linkchecker.pot template
from the source files, you will need xgettext with Python support. This is from the source files, you will need xgettext with Python support. This is
available in gettext >= 0.12. available in gettext >= 0.12.
Now install the application. Clone the LinkChecker repository:
1. Compile Python modules ``git clone https://github.com/linkchecker/linkchecker.git``
Run ``python setup.py sdist --manifest-only`` to create the MANIFEST
file.
Run ``python setup.py build`` to compile the Python files.
For help about the setup.py script options, run
``python setup.py --help``.
2. ``cd linkchecker``
a) Installation as root
Build the distribution wheel:
Run ``sudo python setup.py install`` to install LinkChecker.
``hatchling build``
b) Installation as a normal user
Now install the application from the wheel:
Run ``python setup.py install --home $HOME``. Note that you have
to adjust your PATH and PYTHONPATH environment variables, eg. by ``pip install --no-index --user dist/LinkChecker-<version>-py3-none-any.whl``
adding the commands ``export PYTHONPATH=$HOME/lib/python`` and
``export PATH=$PATH:$HOME/bin`` to your shell configuration Note that you may have to adjust your PATH and PYTHONPATH environment variables,
file. eg. by adding the commands ``export PYTHONPATH=$HOME/lib/python`` and
``export PATH=$PATH:$HOME/bin`` to your shell configuration file.
For more information look at the `Modifying Python's search path`_
documentation. For more information look at the `Modifying Python's search path`_
documentation.
.. _Modifying Python's search path:
https://docs.python.org/3/install/#inst-search-path .. _Modifying Python's search path:
https://docs.python.org/3/install/#inst-search-path
After installation After installation

View file

@ -1,8 +1,8 @@
# You can set these variables from the command line, and also # You can set these variables from the command line, and also
# from the environment for the first two. # from the environment for the first two.
SPHINXOPTS ?= SPHINXOPTS ?=
SPHINXBUILD ?= sphinx-build SPHINXBUILD ?= python3 -m sphinx.cmd.build
SPHINXINTL ?= sphinx-intl SPHINXINTL ?= python3 -m sphinx_intl.commands
SOURCEDIR = . SOURCEDIR = .
BUILDDIR = _build BUILDDIR = _build
LANGUAGE = en LANGUAGE = en

View file

@ -1,7 +1,3 @@
import os
import sys
sys.path.insert(0, os.path.abspath('../..'))
# -- Project information ----------------------------------------------------- # -- Project information -----------------------------------------------------
import linkcheck.configuration import linkcheck.configuration

View file

@ -42,7 +42,7 @@ These two steps can be performed with:
Create man pages: Create man pages:
``linkchecker/doc $ make man`` ``linkchecker/doc $ hatch -e doc run man``
After updating the source files all steps need to be repeated, if translations After updating the source files all steps need to be repeated, if translations
alone have been changed in the .po file only the last step is needed. alone have been changed in the .po file only the last step is needed.

View file

@ -4,6 +4,10 @@ Migrating from 10.1 to 10.x
--------------------------- ---------------------------
Python 3.7 or newer is required. Python 3.7 or newer is required.
Compiled application translations are now also included in the sdist package.
No need to install polib before installing any distribution package. It is
still required for building distribution packages that include translations.
Migrating from 10.0 to 10.1 Migrating from 10.0 to 10.1
--------------------------- ---------------------------
If installing from source and application translations are needed the Python If installing from source and application translations are needed the Python

View file

@ -1,20 +0,0 @@
python setup.py install --root=$RPM_BUILD_ROOT --record=INSTALLED_FILES
# 'brp-compress' compresses the manpages without distutils knowing.
# The sed scripts append ".gz", ".bz2" or ".xz" suffixes to the affected
# manpage filenames.
RPM_MANDIR=usr/share/man
RPM_LOCALMANDIR=usr/local/share/man
if [ -n "$( ls $RPM_BUILD_ROOT/$RPM_MANDIR/man*/*.bz2 2>/dev/null )" \
-o -n "$( ls $RPM_BUILD_ROOT/$RPM_LOCALMANDIR/man*/*.bz2 2>/dev/null )" ]; then
# add .bz2 suffix
sed -i -e 's@man/man\([[:digit:]]\)/\(.\+\.[[:digit:]]\)$@man/man\1/\2.bz2@g' INSTALLED_FILES
elif [ -n "$( ls $RPM_BUILD_ROOT/$RPM_MANDIR/man*/*.xz 2>/dev/null )" \
-o -n "$( ls $RPM_BUILD_ROOT/$RPM_LOCALMANDIR/man*/*.xz 2>/dev/null )" ]; then
# add .xz suffix
sed -i -e 's@man/man\([[:digit:]]\)/\(.\+\.[[:digit:]]\)$@man/man\1/\2.xz@g' INSTALLED_FILES
elif [ -n "$( ls $RPM_BUILD_ROOT/$RPM_MANDIR/man*/*.gz 2>/dev/null )" \
-o -n "$( ls $RPM_BUILD_ROOT/$RPM_LOCALMANDIR/man*/*.gz 2>/dev/null )" ]; then
# add .gz suffix
sed -i -e 's@man/man\([[:digit:]]\)/\(.\+\.[[:digit:]]\)$@man/man\1/\2.gz@g' INSTALLED_FILES
fi

View file

@ -23,7 +23,6 @@ import re
import urllib.parse import urllib.parse
import shutil import shutil
import socket import socket
from datetime import date
try: try:
from importlib.metadata import distribution from importlib.metadata import distribution
@ -37,10 +36,11 @@ from . import confparse
linkchecker_distribution = distribution(COMMAND_NAME) linkchecker_distribution = distribution(COMMAND_NAME)
Version = linkchecker_distribution.metadata["Version"] Version = linkchecker_distribution.metadata["Version"]
try: try:
ReleaseDate = date.fromisoformat( from .. import _release
linkchecker_distribution.read_text("RELEASE_DATE")) except ImportError:
except (TypeError, ValueError):
ReleaseDate = "unknown" ReleaseDate = "unknown"
else:
ReleaseDate = _release.__release_date__
AppName = linkchecker_distribution.metadata["Name"] AppName = linkchecker_distribution.metadata["Name"]
App = AppName + " " + Version App = AppName + " " + Version
Author = linkchecker_distribution.metadata["Author"] Author = linkchecker_distribution.metadata["Author"]
@ -49,7 +49,7 @@ Copyright = "Copyright (C) 2000-2016 Bastian Kleineidam, 2010-2022 " + Author
HtmlCopyright = ("Copyright &copy; 2000-2016 Bastian&nbsp;Kleineidam, 2010-2022 " HtmlCopyright = ("Copyright &copy; 2000-2016 Bastian&nbsp;Kleineidam, 2010-2022 "
+ HtmlAuthor) + HtmlAuthor)
HtmlAppInfo = App + ", " + HtmlCopyright HtmlAppInfo = App + ", " + HtmlCopyright
Url = linkchecker_distribution.metadata["Home-page"] Url = linkchecker_distribution.metadata["Project-URL"].split(", ")[1]
SupportUrl = "https://github.com/linkchecker/linkchecker/issues" SupportUrl = "https://github.com/linkchecker/linkchecker/issues"
UserAgent = "Mozilla/5.0 (compatible; %s/%s; +%s)" % (AppName, Version, Url) UserAgent = "Mozilla/5.0 (compatible; %s/%s; +%s)" % (AppName, Version, Url)
Freeware = ( Freeware = (

99
pyproject.toml Normal file
View file

@ -0,0 +1,99 @@
[project]
name = "LinkChecker"
dynamic = ["version"]
description = "check links in web documents or full websites"
readme = "README.rst"
keywords = ["link", "url", "site", "checking", "crawling", "verification", "validation"]
authors = [{name = "LinkChecker Authors"}]
maintainers = [{name = "LinkChecker Authors"}]
classifiers = [
"Topic :: Internet :: WWW/HTTP :: Site Management :: Link Checking",
"Development Status :: 5 - Production/Stable",
"License :: OSI Approved :: GNU General Public License v2 or later (GPLv2+)",
"Programming Language :: Python",
"Programming Language :: Python :: 3.7",
"Programming Language :: Python :: 3.8",
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
]
requires-python = ">=3.7"
dependencies = [
"importlib_metadata;python_version<'3.8'",
"requests >= 2.4",
"dnspython >= 2.0",
"beautifulsoup4 >= 4.8.1",
]
[build-system]
requires = [
"hatchling>=1.8.0",
"hatch-vcs",
]
build-backend = "hatchling.build"
[project.urls]
Homepage = "https://linkchecker.github.io/linkchecker/"
"Bug Tracker" = "https://github.com/linkchecker/linkchecker/issues"
Repository = "https://github.com/linkchecker/linkchecker"
Changelog = "https://github.com/linkchecker/linkchecker/blob/master/doc/changelog.txt"
[project.scripts]
linkchecker = "linkcheck.command.linkchecker:linkchecker"
[tool.hatch.build]
artifacts = [
"linkcheck/_release.py",
"linkcheck/data/locale",
]
[tool.hatch.build.targets.sdist]
strict-naming = false
[tool.hatch.build.targets.sdist.hooks.custom]
path = "tools/hatch_build.py"
[tool.hatch.build.targets.wheel]
only-include = ["linkcheck"]
strict-naming = false
[tool.hatch.build.targets.wheel.shared-data]
"doc/man/en/linkchecker.1" = "share/man/man1/linkchecker.1"
"doc/man/en/linkcheckerrc.5" = "share/man/man5/linkcheckerrc.5"
"doc/man/de/linkchecker.1" = "share/man/de/man1/linkchecker.1"
"doc/man/de/linkcheckerrc.5" = "share/man/de/man5/linkcheckerrc.5"
"cgi-bin/lconline/leer.html.en" = "share/linkchecker/examples/cgi-bin/lconline/leer.html.en"
"cgi-bin/lconline/leer.html.de" = "share/linkchecker/examples/cgi-bin/lconline/leer.html.de"
"cgi-bin/lconline/index.html" = "share/linkchecker/examples/cgi-bin/lconline/index.html"
"cgi-bin/lconline/lc_cgi.html.en" = "share/linkchecker/examples/cgi-bin/lconline/lc_cgi.html.en"
"cgi-bin/lconline/lc_cgi.html.de" = "share/linkchecker/examples/cgi-bin/lconline/lc_cgi.html.de"
"cgi-bin/lconline/check.js" = "share/linkchecker/examples/cgi-bin/lconline/check.js"
"cgi-bin/lc.wsgi" = "share/linkchecker/examples/cgi-bin/lc.wsgi"
"config/linkchecker.apache2.conf" = "share/linkchecker/examples/config/linkchecker.apache2.conf"
"config/linkchecker-completion" = "share/linkchecker/examples/config/linkchecker-completion"
"doc/examples/check_failures.sh" = "share/linkchecker/examples/check_failures.sh"
"doc/examples/check_for_x_errors.sh" = "share/linkchecker/examples/check_for_x_errors.sh"
"doc/examples/check_urls.sh" = "share/linkchecker/examples/check_urls.sh"
[tool.hatch.version]
source = "vcs"
[tool.hatch.version.raw-options]
local_scheme = "node-and-timestamp"
version_scheme = "post-release"
[tool.hatch.envs.doc]
dependencies = [
"sphinx",
"sphinx_epytext",
"sphinx_intl",
"sphinx_rtd_theme",
"sphinx-sitemap",
]
[tool.hatch.envs.doc.scripts]
code = "make -C doc code"
html = "make -C doc html"
locale = "make -C doc locale"
man = "make -C doc man"

View file

@ -1,19 +1,3 @@
[global]
;command_packages = distcmds
[bdist_rpm]
release = 1
packager = Bastian Kleineidam <bastian.kleineidam@web.de>
doc_files = doc/examples/
cgi-bin/lconline/
provides = linkchecker
group = Applications/Internet
install_script = install-rpm.sh
python = python
[bdist_wheel]
universal = 0
[check-manifest] [check-manifest]
ignore = ignore =
*.rej *.rej
@ -36,7 +20,6 @@ per-file-ignores =
# In several files imports intentionally cause: # In several files imports intentionally cause:
# E402: module level import not at top of file # E402: module level import not at top of file
# F401: module imported but unused # F401: module imported but unused
setup.py: E402
doc/src/conf.py: E402,F821 doc/src/conf.py: E402,F821
linkcheck/__init__.py: E402,F401 linkcheck/__init__.py: E402,F401
linkcheck/checker/httpurl.py: E402 linkcheck/checker/httpurl.py: E402

236
setup.py
View file

@ -1,236 +0,0 @@
#!/usr/bin/python3
# Copyright (C) 2000-2014 Bastian Kleineidam
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
"""
Setup file for the distuils module.
It includes the following features:
- records the release date
- automatic generation of .mo locale files
- automatic permission setting on POSIX systems for installed files
"""
import sys
if sys.version_info < (3, 7, 0, "final", 0):
raise SystemExit("This program requires Python 3.7 or later.")
import os
import stat
import subprocess
from pathlib import Path
# import Distutils stuff
from setuptools import find_packages, setup
from distutils.command.build import build
from distutils.command.install_data import install_data
from setuptools.command.egg_info import egg_info
from setuptools.command.sdist import sdist
try:
import polib
except ImportError:
COMPILE_TRANSLATIONS = False
else:
COMPILE_TRANSLATIONS = True
# the application name
AppName = "LinkChecker"
Description = "check links in web documents or full websites"
RELEASE_DATE_FILE = "_release_date"
def get_long_description():
"""Try to read long description from README.rst."""
try:
return Path("README.rst").read_text()
except Exception:
return Description
def get_release_date(for_sdist=False):
"""Return release date as a string from the most recent commit."""
release_date = "unknown"
cp = None
try:
# need git >= 2.25.0 for %cs
cp = subprocess.run(["git", "log", "-n 1", "HEAD", "--format=%cI"],
capture_output=True, text=True)
except FileNotFoundError:
pass
if cp and cp.stdout:
release_date = cp.stdout.split("T")[0]
elif not for_sdist:
try:
release_date = Path(RELEASE_DATE_FILE).read_text()
except FileNotFoundError:
pass
return release_date
class MySdist(sdist):
def run(self):
Path(RELEASE_DATE_FILE).write_text(get_release_date(for_sdist=True))
super().run()
class MyBuild(build):
"""Custom build with translation compilation"""
def run(self):
if COMPILE_TRANSLATIONS:
for po in Path("po").glob("*.po"):
mo = Path(
self.build_lib, "linkcheck", "data", "locale",
po.stem, "LC_MESSAGES", AppName.lower()
).with_suffix(".mo")
pofile = polib.pofile(str(po))
mo.parent.mkdir(exist_ok=True, parents=True)
pofile.save_as_mofile(str(mo))
else:
print(
"warning: polib package not found: translations not compiled",
file=sys.stderr)
super().run()
class MyEggInfo(egg_info):
def run(self):
"""Add release date to metadata."""
super().run()
self.write_file(
"release date",
os.path.join(self.egg_info, "RELEASE_DATE"),
get_release_date()
)
class MyInstallData(install_data):
"""Fix file permissions."""
def run(self):
"""Adjust permissions on POSIX systems."""
super().run()
self.fix_permissions()
def fix_permissions(self):
"""Set correct read permissions on POSIX systems. Might also
be possible by setting umask?"""
if os.name == "posix" and not self.dry_run:
# Make the data files we just installed world-readable,
# and the directories world-executable as well.
for path in self.get_outputs():
mode = os.stat(path)[stat.ST_MODE]
if stat.S_ISDIR(mode):
mode |= 0o11
mode |= 0o44
os.chmod(path, mode)
# scripts
myname = "LinkChecker Authors"
myemail = ""
data_files = [
(
"share/linkchecker/examples",
[
"cgi-bin/lconline/leer.html.en",
"cgi-bin/lconline/leer.html.de",
"cgi-bin/lconline/index.html",
"cgi-bin/lconline/lc_cgi.html.en",
"cgi-bin/lconline/lc_cgi.html.de",
"cgi-bin/lconline/check.js",
"cgi-bin/lc.wsgi",
"config/linkchecker.apache2.conf",
],
),
]
if os.name == "posix":
data_files.append(("share/man/man1", ["doc/man/en/linkchecker.1"]))
data_files.append(("share/man/man5", ["doc/man/en/linkcheckerrc.5"]))
data_files.append(("share/man/de/man1", ["doc/man/de/linkchecker.1"]))
data_files.append(("share/man/de/man5", ["doc/man/de/linkcheckerrc.5"]))
data_files.append(
(
"share/linkchecker/examples",
[
"config/linkchecker-completion",
"doc/examples/check_failures.sh",
"doc/examples/check_for_x_errors.sh",
"doc/examples/check_urls.sh",
],
)
)
setup(
name=AppName,
use_scm_version={
"local_scheme": "node-and-timestamp",
"version_scheme": "post-release",
},
description=Description,
keywords="link,url,site,checking,crawling,verification,validation",
author=myname,
author_email=myemail,
maintainer=myname,
maintainer_email=myemail,
url="https://linkchecker.github.io/linkchecker/",
license="GPL",
long_description=get_long_description(),
long_description_content_type="text/x-rst",
cmdclass={
"sdist": MySdist,
"build": MyBuild,
"egg_info": MyEggInfo,
"install_data": MyInstallData,
},
packages=find_packages(include=["linkcheck", "linkcheck.*"]),
entry_points={
"console_scripts": [
"linkchecker = linkcheck.command.linkchecker:linkchecker"
]
},
data_files=data_files,
include_package_data=True,
classifiers=[
"Topic :: Internet :: WWW/HTTP :: Site Management :: Link Checking",
"Development Status :: 5 - Production/Stable",
"License :: OSI Approved :: GNU General Public License (GPL)",
"Programming Language :: Python",
"Programming Language :: Python :: 3.7",
"Programming Language :: Python :: 3.8",
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
],
options={},
# Requirements, usable with setuptools or the new Python packaging module.
python_requires=">= 3.7",
setup_requires=["setuptools_scm"],
install_requires=[
"importlib_metadata;python_version<'3.8'",
"requests >= 2.4",
"dnspython >= 2.0",
"beautifulsoup4 >= 4.8.1",
],
# Commented out since they are untested and not officially supported.
# See also doc/install.txt for more detailed dependency documentation.
# extra_requires = {
# "IP country info": ['GeoIP'], # https://pypi.org/project/GeoIP/
# "Bash completion": ['argcomplete'], # https://pypi.org/project/argcomplete/
# "Memory debugging": ['meliae'], # https://pypi.org/project/meliae/
# }
)

65
tools/hatch_build.py Normal file
View file

@ -0,0 +1,65 @@
# Copyright (C) 2022 Chris Mayo
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
from pathlib import Path
import shutil
import subprocess
from hatchling.builders.hooks.plugin.interface import BuildHookInterface
try:
import polib
except ImportError:
COMPILE_TRANSLATIONS = False
else:
COMPILE_TRANSLATIONS = True
LOCALE_DIR = ("linkcheck", "data", "locale")
RELEASE_PY = ("linkcheck", "_release.py")
class CustomBuildHook(BuildHookInterface):
def clean(self, versions):
Path(*RELEASE_PY).unlink(missing_ok=True)
shutil.rmtree(str(Path(*LOCALE_DIR)), ignore_errors=True)
def initialize(self, version, build_data):
cp = None
committer_date = "unknown"
try:
cp = subprocess.run(["git", "log", "-n 1", "HEAD", "--format=%cs"],
capture_output=True, text=True)
except FileNotFoundError:
pass
else:
if cp and cp.stdout:
committer_date = cp.stdout.strip()
Path(*RELEASE_PY).write_text(
f"__release_date__ = \"{committer_date}\"\n")
if COMPILE_TRANSLATIONS:
for po in Path("po").glob("*.po"):
mo = Path(
*LOCALE_DIR,
po.stem, "LC_MESSAGES", "linkchecker",
).with_suffix(".mo")
pofile = polib.pofile(str(po))
mo.parent.mkdir(exist_ok=True, parents=True)
pofile.save_as_mofile(str(mo))
else:
self.app.display_warning(
"polib package not found: translations not compiled")