diff --git a/.gitignore b/.gitignore index 89531ed..45464ab 100644 --- a/.gitignore +++ b/.gitignore @@ -30,3 +30,15 @@ /OWSLib-0.27.2.tar.gz /OWSLib-0.28.0.tar.gz /OWSLib-0.28.1.tar.gz +/OWSLib-0.29.0.tar.gz +/OWSLib-0.29.1.tar.gz +/OWSLib-0.29.2.tar.gz +/OWSLib-0.29.3.tar.gz +/OWSLib-0.30.0.tar.gz +/OWSLib-0.30.0-filtered.tar.zst +/OWSLib-0.31.0-filtered.tar.zst +/OWSLib-0.32.0-filtered.tar.zst +/OWSLib-0.33.0-filtered.tar.zst +/OWSLib-0.34.0-filtered.tar.zst +/OWSLib-0.34.1-filtered.tar.zst +/OWSLib-0.35.0-filtered.tar.zst diff --git a/get_source b/get_source new file mode 100755 index 0000000..085fbb8 --- /dev/null +++ b/get_source @@ -0,0 +1,63 @@ +#!/bin/sh +set -o nounset +set -o errexit + +FORGEURL='https://github.com/geopython/OWSLib' + +print_help() +{ + cat <&2 + print_help "${0}" + exit 1 +elif [ "${1-}" = '-h' ] || [ "${1-}" = '--help' ] +then + print_help "${0}" + exit 0 +fi + +VERSION="${1}" +SOURCE0="${FORGEURL}/archive/${VERSION}/OWSLib-${VERSION}.tar.gz" +TARNAME="$(basename "${SOURCE0}")" +TARDIR="$(basename "${SOURCE0}" '.tar.gz')" +NEWTAR="${TARDIR}-filtered.tar.zst" + +SAVEDIR="${PWD}" +XDIR="$(mktemp -d)" +trap "rm -rf '${XDIR}'" INT TERM EXIT + +cd "${XDIR}" +curl -L -O "${SOURCE0}" +echo "Extracting ${TARNAME}…" 1>&2 +tar -xzf "${TARNAME}" +MTIME="$(stat -c '%Y' "${TARDIR}")" +rm -rvf "${TARDIR}/tests/resources" +echo "Re-compressing as ${NEWTAR}…" 1>&2 +# https://www.gnu.org/software/tar/manual/html_section/Reproducibility.html +# We reset all mtimes to that of the top-level extracted directory; since git +# archives don’t have meaningful per-file mtimes, nothing useful is lost. +TZ=UTC LC_ALL=C tar \ + --create \ + --sort=name \ + --format=posix \ + --numeric-owner --owner=0 --group=0 \ + --mode=go+u,go-w \ + --pax-option='delete=atime,delete=ctime' \ + --clamp-mtime --mtime="@${MTIME}" \ + "${TARDIR}/" | + zstdmt --ultra -22 > "${NEWTAR}" +touch -d @"${MTIME}" "${NEWTAR}" + +cd "${SAVEDIR}" +mv -v "${XDIR}/${NEWTAR}" . diff --git a/python-OWSLib.rpmlintrc b/python-OWSLib.rpmlintrc new file mode 100644 index 0000000..694038d --- /dev/null +++ b/python-OWSLib.rpmlintrc @@ -0,0 +1,7 @@ +# The source cannot be a URL because we have to filter out files before +# uploading to the lookaside cache. +addFilter(r" invalid-url .* OWSLib-.*-filtered\.tar\.zst") +# There is nothing wrong with .tar.zst, but rpmlint does not know that. +addFilter(r" inconsistent-file-extension .*\.tar\.zst") +# Removed without replacement in Fedora 42 +addFilter(r" obsolete-not-provided python-OWSLIB-doc") diff --git a/python-OWSLib.spec b/python-OWSLib.spec index a646079..a44a326 100644 --- a/python-OWSLib.spec +++ b/python-OWSLib.spec @@ -1,28 +1,51 @@ -# Sphinx-generated HTML documentation is not suitable for packaging; see -# https://bugzilla.redhat.com/show_bug.cgi?id=2006555 for discussion. -# -# We can generate PDF documentation as a substitute. -%bcond_without doc_pdf - Name: python-OWSLib -Version: 0.28.1 +Version: 0.35.0 Release: %autorelease -Summary: Client library for OGC web services +Summary: OGC Web Service utility library License: BSD-3-Clause URL: https://geopython.github.io/OWSLib -Source0: https://github.com/geopython/OWSLib/archive/%{version}/OWSLib-%{version}.tar.gz +# A filtered source archive, obtained by (see Source1): +# +# ./get_source %%{version} +# +# is required because tests/resources/ contains XML data files that appear to +# have been pulled from various GIS databases, and the license terms for these +# files are unclear. +# +# The unfiltered base source URL would be: +# +# https://github.com/geopython/OWSLib/archive/%%{version}/OWSLib-%%{version}.tar.gz +# +# We *could* use the PyPI sdist, which does not contain tests/resources/, but +# it also does not contain any tests at all. We can still run some tests +# without the XML files, and we would like to do so. +Source0: OWSLib-%{version}-filtered.tar.zst +Source1: get_source + +BuildSystem: pyproject +BuildOption(install): -l owslib BuildArch: noarch -BuildRequires: python3-devel - -%if %{with doc_pdf} -BuildRequires: make -BuildRequires: python3-sphinx-latex -BuildRequires: latexmk -BuildRequires: pandoc -%endif +# Tests; dependencies are in requirements-dev.txt. +BuildRequires: %{py3_dist pytest} +BuildRequires: %{py3_dist pytest_httpserver} +BuildRequires: %{py3_dist Pillow} +# We don’t have pytest-socket packaged, and we can get by without it. +# - pytest-socket +# We don’t use tox to run the tests. It would run "python3 setup.py develop", +# which is unwanted. +# - tox +# Unwanted linting/coverage dependencies: +# https://docs.fedoraproject.org/en-US/packaging-guidelines/Python/#_linters +# - coverage +# - coveralls +# - flake8 +# - pytest-cov +# These are just for the maintainer to upload to PyPI. +# - build +# - twine %global common_description %{expand: OWSLib is a Python package for client programming with Open Geospatial @@ -42,120 +65,78 @@ Summary: %{summary} %py_provides python3-owslib +# The -doc subpackage was removed for Fedora 42; we can remove this Obsoletes +# after Fedora 44. (EPEL10 never had a -doc subpackage.) +Obsoletes: python-OWSLIB-doc < 0.32.0-1 + %description -n python3-OWSLib %{common_description} -%package doc -Summary: Documentation and examples for OWSLib - -%description doc -%{summary}. - - -%prep -%autosetup -n OWSLib-%{version} - +%prep -a # Don’t analyze/report test coverage -sed -r -i 's/[-]-cov[^[:blank:]]*[[:blank:]][^[[:blank:]]+//g' tox.ini -# Don’t generate linting/coverage dependencies. -# -# We don’t have python3dist(pandoc) packaged, and besides, we don’t actually -# need python3dist(pandoc)—only the pandoc command-line tool, which we have -# manually BR’d. -# -# Don’t generate twine dependency, which is just for the upstream maintainer -# uploading to PyPI. -sed -r -e '/^(flake8|pytest-cov|pandoc|coverage|coveralls|twine)\b/d' \ -%if %{without doc_pdf} - -e '/^(ipykernel|nbconvert|.*sphinx)/d' \ -%endif - requirements-dev.txt | tee requirements-dev-filtered.txt - -# We don’t need shebangs in the examples. The pattern of selecting files -# before modifying them with sed keeps us from unnecessarily discarding the -# original mtimes on unmodified files. -find 'examples' -type f -name '*.py' \ - -exec gawk '/^#!/ { print FILENAME }; { nextfile }' '{}' '+' | - xargs -r sed -r -i '1{/^#!/d}' -# Some of them, but not all of them, were executable. -chmod -v a-x examples/*.py - -# Because at least one notebook requires Internet access, we must continue past -# notebook errors when building documentation. -echo 'nbsphinx_allow_errors = True' >> docs/conf.py +sed -r -i 's/^([[:blank:]]*)(--cov\b)/\1# \2/' tox.ini -%generate_buildrequires -%pyproject_buildrequires requirements-dev-filtered.txt - - -%build -%pyproject_wheel - -%if %{with doc_pdf} -PYTHONPATH="${PWD}" %make_build -C docs latex SPHINXOPTS='%{?_smp_mflags}' -%make_build -C docs/build/latex/en LATEXMKOPTS='-quiet' -%endif - - -%install -%pyproject_install -%pyproject_save_files owslib - - -%check +%check -a # Otherwise, pytest finds the package twice in the Python path and complains. rm -rf owslib -# There is a convenient “online” mark for deselecting tests that require -# Internet access, but we still have to manually deselect doctests that try to -# make network requests. -k="${k-}${k+ and }not wms_geoserver_mass_gis.txt" -k="${k-}${k+ and }not wfs_MapServerWFSFeature.txt" -k="${k-}${k+ and }not wfs_MapServerWFSCapabilities.txt" -k="${k-}${k+ and }not wfs2_storedqueries.txt" -k="${k-}${k+ and }not wfs1_generic.txt" -k="${k-}${k+ and }not wcs_thredds.txt" -k="${k-}${k+ and }not test_wmts_example_informatievlaanderen" +# These require test data files from tests/resources/, which we have removed: +ignore="${ignore-} --ignore-glob=tests/doctests/*.txt" +k="${k-}${k+ and }not test_gm03" +ignore="${ignore-} --ignore=tests/test_iso_parsing.py" +ignore="${ignore-} --ignore=tests/test_ows_interfaces.py" +ignore="${ignore-} --ignore=tests/test_owscontext_atomxml.py" +k="${k-}${k+ and }not test_decode_single_json" +k="${k-}${k+ and }not test_load_parse" +k="${k-}${k+ and }not test_decode_full_json" +k="${k-}${k+ and }not test_load_bulk" +ignore="${ignore-} --ignore=tests/test_remote_metadata.py" +k="${k-}${k+ and }not TestOffline" +ignore="${ignore-} --ignore=tests/test_wfs_generic.py" +ignore="${ignore-} --ignore=tests/test_wms_datageo_130.py" +ignore="${ignore-} --ignore=tests/test_wms_jpl_capabilities.py" +k="${k-}${k+ and }not test_wps_getOperationByName" +k="${k-}${k+ and }not test_wps_checkStatus" +k="${k-}${k+ and }not test_wps_process_representation" +k="${k-}${k+ and }not test_wps_process_properties" +k="${k-}${k+ and }not test_wps_literal_data_input_parsing_references" +k="${k-}${k+ and }not test_wps_response_with_lineage" +ignore="${ignore-} --ignore=tests/test_wps_describeprocess_bbox.py" +ignore="${ignore-} --ignore=tests/test_wps_describeprocess_ceda.py" +ignore="${ignore-} --ignore=tests/test_wps_describeprocess_emu_all.py" +ignore="${ignore-} --ignore=tests/test_wps_describeprocess_usgs.py" +ignore="${ignore-} --ignore=tests/test_wps_execute.py" +ignore="${ignore-} --ignore=tests/test_wps_execute_invalid_request.py" +ignore="${ignore-} --ignore=tests/test_wps_getcapabilities_52n.py" +ignore="${ignore-} --ignore=tests/test_wps_getcapabilities_ceda.py" +ignore="${ignore-} --ignore=tests/test_wps_getcapabilities_usgs.py" +ignore="${ignore-} --ignore-glob=tests/test_wps_request*.py" +ignore="${ignore-} --ignore-glob=tests/test_wps_response*.py" +k="${k-}${k+ and }not test_metadata" +k="${k-}${k+ and }not test_responsibility" +k="${k-}${k+ and }not test_distributor" +k="${k-}${k+ and }not test_online_distribution" +k="${k-}${k+ and }not test_identification" +k="${k-}${k+ and }not test_identification_contact" +k="${k-}${k+ and }not test_identification_date" +k="${k-}${k+ and }not test_identification_extent" +k="${k-}${k+ and }not test_identification_keywords" +k="${k-}${k+ and }not test_get_all_contacts" +k="${k-}${k+ and }not test_aus" +k="${k-}${k+ and }not test_service" +k="${k-}${k+ and }not test_md_featurecataloguedesc" +k="${k-}${k+ and }not test_md_imagedescription" +k="${k-}${k+ and }not test_dq_dataquality" +k="${k-}${k+ and }not test_md_reference_system" +k="${k-}${k+ and }not test_service2" +k="${k-}${k+ and }not test_md_distribution" -# This is a trivial error where the representation of the expected TypeError -# has changed over time: -# Differences (unified diff with -expected +actual): -# @@ -1,3 +1,6 @@ -# Traceback (most recent call last): -# -... -# -TypeError: get_namespace() ... -# + File "/usr/lib64/python3.10/doctest.py", line 1346, in __run -# + exec(compile(example.source, filename, "single", -# + File "", line 1, in -# + ns.get_namespace() -# +TypeError: Namespaces.get_namespace() missing 1 required positional argument: 'key' -k="${k-}${k+ and }not namespaces.txt" - -# Unknown problem—check if it is fixed in a later version: -k="${k-}${k+ and } not (TestOffline and test_wfs_110_remotemd_parse_all)" -k="${k-}${k+ and } not (TestOffline and test_wfs_110_remotemd_parse_single)" -k="${k-}${k+ and } not (TestOffline and test_wfs_200_remotemd_parse_all)" -k="${k-}${k+ and } not (TestOffline and test_wfs_200_remotemd_parse_single)" -k="${k-}${k+ and } not (TestOffline and test_wms_130_remotemd_parse_all)" -k="${k-}${k+ and } not (TestOffline and test_wms_130_remotemd_parse_single)" - -%pytest -m 'not online' -k "${k-}" +%pytest -m 'not online' -k "${k-}" ${ignore-} -v -rs %files -n python3-OWSLib -f %{pyproject_files} -# pyproject_files handles LICENSE; verify with “rpm -qL -p …” -%doc AUTHORS.rst -%doc CHANGES.rst -%doc README.rst - - -%files doc -%license LICENSE -%doc examples -%if %{with doc_pdf} -%doc docs/build/latex/en/OWSLib.pdf -%endif +%doc README.md %changelog diff --git a/sources b/sources index 6ddf3e6..da0ff49 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -SHA512 (OWSLib-0.28.1.tar.gz) = bd62a5e371e64e0e256cc83d2f044294c20965f6b107b0dd9074ac752971620f01af4c7fc9a82e43dc81e71a6a36696b75403012841c28925b017d9c47b2d4a5 +SHA512 (OWSLib-0.35.0-filtered.tar.zst) = be1eb52fa09049b720c1ebd476363e01c6442c9905c9adf0d35ccc11f39b228b9f3e64ed882a7c04987f2f38f9c8500a61aeef61e48a41602098ff22df0ed526