From 3c777e01013121130b968e879ce56c191821d25d Mon Sep 17 00:00:00 2001 From: classabbyamp Date: Sat, 7 Dec 2024 12:27:22 -0500 Subject: [PATCH 01/13] common: move handling of rdeps, shlib-provides, shlib-requires files to XBPS_STATEDIR. There's no need for them to pollute PKGDESTDIR. Keep INSTALL.msg/REMOVE.msg handling as-is for now because it's a little more complex. Keep the pkglints for these files because xbps still ignores them. --- common/hooks/do-pkg/00-gen-pkg.sh | 12 +++++----- .../post-install/06-strip-and-debug-pkgs.sh | 2 +- .../hooks/post-install/98-shlib-provides.sh | 4 ++-- .../hooks/pre-pkg/04-generate-runtime-deps.sh | 4 ++-- .../pre-pkg/05-generate-32bit-runtime-deps.sh | 22 +++++++++---------- common/hooks/pre-pkg/99-pkglint.sh | 4 ++-- common/hooks/pre-pkg/999-collected-rdeps.sh | 4 ++-- common/xbps-src/shutils/show.sh | 6 ++--- 8 files changed, 29 insertions(+), 29 deletions(-) diff --git a/common/hooks/do-pkg/00-gen-pkg.sh b/common/hooks/do-pkg/00-gen-pkg.sh index e61f0532bd71f6..af3938eac04972 100644 --- a/common/hooks/do-pkg/00-gen-pkg.sh +++ b/common/hooks/do-pkg/00-gen-pkg.sh @@ -34,14 +34,14 @@ genpkg() { cd $pkgdir _preserve=${preserve:+-p} - if [ -s ${PKGDESTDIR}/rdeps ]; then - _deps="$(<${PKGDESTDIR}/rdeps)" + if [ -s ${XBPS_STATEDIR}/${pkgname}-rdeps ]; then + _deps="$(<${XBPS_STATEDIR}/${pkgname}-rdeps)" fi - if [ -s ${PKGDESTDIR}/shlib-provides ]; then - _shprovides="$(<${PKGDESTDIR}/shlib-provides)" + if [ -s ${XBPS_STATEDIR}/${pkgname}-shlib-provides ]; then + _shprovides="$(<${XBPS_STATEDIR}/${pkgname}-shlib-provides)" fi - if [ -s ${PKGDESTDIR}/shlib-requires ]; then - _shrequires="$(<${PKGDESTDIR}/shlib-requires)" + if [ -s ${XBPS_STATEDIR}/${pkgname}-shlib-requires ]; then + _shrequires="$(<${XBPS_STATEDIR}/${pkgname}-shlib-requires)" fi if [ -s ${XBPS_STATEDIR}/gitrev ]; then _gitrevs="$(<${XBPS_STATEDIR}/gitrev)" diff --git a/common/hooks/post-install/06-strip-and-debug-pkgs.sh b/common/hooks/post-install/06-strip-and-debug-pkgs.sh index b6bd52320dc8d1..ebe3166f09c039 100644 --- a/common/hooks/post-install/06-strip-and-debug-pkgs.sh +++ b/common/hooks/post-install/06-strip-and-debug-pkgs.sh @@ -51,7 +51,7 @@ create_debug_pkg() { msg_red "$pkgver: failed to create debug pkg\n" return 1 fi - printf "${pkgver} " >> ${_destdir}/rdeps + printf "${pkgver} " >> ${XBPS_STATEDIR}/${pkgname}-dbg-rdeps rmdir --ignore-fail-on-non-empty "${PKGDESTDIR}/usr/lib" 2>/dev/null return 0 } diff --git a/common/hooks/post-install/98-shlib-provides.sh b/common/hooks/post-install/98-shlib-provides.sh index a2ccff794b2e66..bcb015d6733739 100644 --- a/common/hooks/post-install/98-shlib-provides.sh +++ b/common/hooks/post-install/98-shlib-provides.sh @@ -50,8 +50,8 @@ collect_sonames() { echo "$f" >> ${_tmpfile} done if [ -s "${_tmpfile}" ]; then - tr '\n' ' ' < "${_tmpfile}" > ${_destdir}/shlib-provides - echo >> ${_destdir}/shlib-provides + tr '\n' ' ' < "${_tmpfile}" > "${XBPS_STATEDIR}/${pkgname}-shlib-provides" + echo >> "${XBPS_STATEDIR}/${pkgname}-shlib-provides" if [ "$_mainpkg" ]; then cp "${_tmpfile}" "${_shlib_dir}/${pkgname}.soname" fi diff --git a/common/hooks/pre-pkg/04-generate-runtime-deps.sh b/common/hooks/pre-pkg/04-generate-runtime-deps.sh index 78c4be2e63d51b..658257b19483c2 100644 --- a/common/hooks/pre-pkg/04-generate-runtime-deps.sh +++ b/common/hooks/pre-pkg/04-generate-runtime-deps.sh @@ -41,7 +41,7 @@ store_pkgdestdir_rundeps() { _curdep="${_curdep}>=0" fi printf "%s " "${_curdep}" - done > "${PKGDESTDIR}/rdeps" + done > "${XBPS_STATEDIR}/${pkgname}-rdeps" fi } @@ -149,6 +149,6 @@ hook() { store_pkgdestdir_rundeps if [ -n "${sorequires}" ]; then - echo "${sorequires}" | xargs -n1 | sort | xargs > ${PKGDESTDIR}/shlib-requires + echo "${sorequires}" | xargs -n1 | sort | xargs > ${XBPS_STATEDIR}/${pkgname}-shlib-requires fi } diff --git a/common/hooks/pre-pkg/05-generate-32bit-runtime-deps.sh b/common/hooks/pre-pkg/05-generate-32bit-runtime-deps.sh index 3685f762315b0c..a2c79d34770866 100644 --- a/common/hooks/pre-pkg/05-generate-32bit-runtime-deps.sh +++ b/common/hooks/pre-pkg/05-generate-32bit-runtime-deps.sh @@ -19,13 +19,13 @@ hook() { # 32bit dependencies. trap - ERR - : > ${destdir32}/rdeps + : > ${XBPS_STATEDIR}/${pkgname}-32bit-rdeps - if [ -s "$PKGDESTDIR/rdeps" ]; then + if [ -s "${XBPS_STATEDIR}/${pkgname}-rdeps" ]; then if [ -n "$lib32depends" ]; then _deps="${lib32depends}" else - _deps="$(<${PKGDESTDIR}/rdeps)" + _deps="$(<${XBPS_STATEDIR}/${pkgname}-rdeps)" fi for f in ${_deps}; do unset found pkgn pkgv _shprovides @@ -43,7 +43,7 @@ hook() { # If dependency is a development pkg switch it to 32bit. if [[ $pkgn == *-devel ]]; then echo " RDEP: $f -> ${pkgn}-32bit${pkgv} (development)" - printf "${pkgn}-32bit${pkgv} " >> ${destdir32}/rdeps + printf "${pkgn}-32bit${pkgv} " >> ${XBPS_STATEDIR}/${pkgname}-32bit-rdeps continue fi # If dependency does not have "shlib-provides" do not @@ -60,20 +60,20 @@ hook() { _shprovides="$($XBPS_QUERY_CMD -R --property=shlib-provides "$pkgn")" if [ -n "${_shprovides}" ]; then echo " RDEP: $f -> ${pkgn}-32bit${pkgv} (shlib-provides)" - printf "${pkgn}-32bit${pkgv} " >> ${destdir32}/rdeps + printf "${pkgn}-32bit${pkgv} " >> ${XBPS_STATEDIR}/${pkgname}-32bit-rdeps else echo " RDEP: $f -> ${pkgn}${pkgv} (no shlib-provides)" - printf "${pkgn}${pkgv} " >> ${destdir32}/rdeps + printf "${pkgn}${pkgv} " >> ${XBPS_STATEDIR}/${pkgname}-32bit-rdeps fi else - if [ -s ${XBPS_DESTDIR}/${pkgn}-${version}/shlib-provides ]; then + if [ -s "${XBPS_STATEDIR}/${pkgn}-shlib-provides" ]; then # Dependency is a subpkg; check if it provides any shlib # and convert to 32bit if true. echo " RDEP: $f -> ${pkgn}-32bit${pkgv} (subpkg, shlib-provides)" - printf "${pkgn}-32bit${pkgv} " >> ${destdir32}/rdeps + printf "${pkgn}-32bit${pkgv} " >> ${XBPS_STATEDIR}/${pkgname}-32bit-rdeps else echo " RDEP: $f -> ${pkgn}${pkgv} (subpkg, no shlib-provides)" - printf "${pkgn}${pkgv} " >> ${destdir32}/rdeps + printf "${pkgn}${pkgv} " >> ${XBPS_STATEDIR}/${pkgname}-32bit-rdeps fi fi done @@ -81,7 +81,7 @@ hook() { # If it's a development pkg add a dependency to the 64bit pkg. if [[ $pkgn == *-devel ]]; then echo " RDEP: ${pkgver}" - printf "${pkgver} " >> ${destdir32}/rdeps + printf "${pkgver} " >> ${XBPS_STATEDIR}/${pkgname}-32bit-rdeps fi - printf "\n" >> ${destdir32}/rdeps + printf "\n" >> ${XBPS_STATEDIR}/${pkgname}-32bit-rdeps } diff --git a/common/hooks/pre-pkg/99-pkglint.sh b/common/hooks/pre-pkg/99-pkglint.sh index 90cb07da3f4aff..2922c1a36f526a 100644 --- a/common/hooks/pre-pkg/99-pkglint.sh +++ b/common/hooks/pre-pkg/99-pkglint.sh @@ -170,11 +170,11 @@ hook() { fi # Check for missing shlibs and SONAME bumps. - if [ ! -s "${PKGDESTDIR}/shlib-provides" ]; then + if [ ! -s "${XBPS_STATEDIR}/${pkgname}-shlib-provides" ]; then return 0 fi - for filename in $(<${PKGDESTDIR}/shlib-provides); do + for filename in $(<"${XBPS_STATEDIR}/${pkgname}-shlib-provides"); do rev=${filename#*.so.} libname=${filename%.so*} _shlib=$(echo "$libname"|sed -E 's|\+|\\+|g') diff --git a/common/hooks/pre-pkg/999-collected-rdeps.sh b/common/hooks/pre-pkg/999-collected-rdeps.sh index 67f4a6261e8ab6..e22b0c5c0f5cdb 100644 --- a/common/hooks/pre-pkg/999-collected-rdeps.sh +++ b/common/hooks/pre-pkg/999-collected-rdeps.sh @@ -1,7 +1,7 @@ # This hook displays resolved dependencies for a pkg. hook() { - if [ -e $PKGDESTDIR/rdeps ]; then - echo " $(cat $PKGDESTDIR/rdeps)" + if [ -e "${XBPS_STATEDIR}/${pkgname}-rdeps" ]; then + echo " $(cat "${XBPS_STATEDIR}/${pkgname}-rdeps")" fi } diff --git a/common/xbps-src/shutils/show.sh b/common/xbps-src/shutils/show.sh index 5e9e8a186bb13d..39d46b623bfdef 100644 --- a/common/xbps-src/shutils/show.sh +++ b/common/xbps-src/shutils/show.sh @@ -62,7 +62,7 @@ show_pkg_var() { } show_pkg_deps() { - [ -f "${PKGDESTDIR}/rdeps" ] && cat ${PKGDESTDIR}/rdeps + [ -f "${XBPS_STATEDIR}/${pkgname}-rdeps" ] && cat "${XBPS_STATEDIR}/${pkgname}-rdeps" } show_pkg_files() { @@ -155,9 +155,9 @@ show_pkg_build_options() { } show_pkg_shlib_provides() { - [ -f "${PKGDESTDIR}/shlib-provides" ] && cat ${PKGDESTDIR}/shlib-provides + [ -f "${XBPS_STATEDIR}/${pkgname}-shlib-provides" ] && cat "${XBPS_STATEDIR}/${pkgname}-shlib-provides" } show_pkg_shlib_requires() { - [ -f "${PKGDESTDIR}/shlib-requires" ] && cat ${PKGDESTDIR}/shlib-requires + [ -f "${XBPS_STATEDIR}/${pkgname}-shlib-requires" ] && cat "${XBPS_STATEDIR}/${pkgname}-shlib-requires" } From 847ed330e501b70a093bc81f9e8eb1a1955c6c6e Mon Sep 17 00:00:00 2001 From: classabbyamp Date: Mon, 2 Dec 2024 09:41:02 -0500 Subject: [PATCH 02/13] New package: python3-flit_core-bootstrap-3.9.0 dependency of python3-{installer,packaging}-bootstrap --- srcpkgs/python3-flit_core-bootstrap/template | 30 ++++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 srcpkgs/python3-flit_core-bootstrap/template diff --git a/srcpkgs/python3-flit_core-bootstrap/template b/srcpkgs/python3-flit_core-bootstrap/template new file mode 100644 index 00000000000000..77870bdfd1d215 --- /dev/null +++ b/srcpkgs/python3-flit_core-bootstrap/template @@ -0,0 +1,30 @@ +# Template file for 'python3-flit_core-bootstrap' +pkgname=python3-flit_core-bootstrap +version=3.9.0 +revision=1 +# This package is required by python3-build and python3-installer, used by the +# python3-pep517 style; so using that style here would create a cycle +hostmakedepends="python3" +depends="python3" +short_desc="Simplified packaging of Python modules (for xbps-src use)" +maintainer="Andrew J. Hesford " +license="BSD-3-Clause" +homepage="https://flit.pypa.io/" +changelog="https://flit.pypa.io/en/stable/history.html" +distfiles="${PYPI_SITE}/f/flit_core/flit_core-${version}.tar.gz" +checksum=72ad266176c4a3fcfab5f2930d76896059851240570ce9a98733b658cb786eba +make_check=no # bootstrap +repository=bootstrap +nopyprovides=yes +noverifypydeps=yes + +do_build() { + python3 -m flit_core.wheel +} + +do_install() { + python3 bootstrap_install.py --install-root "${DESTDIR}" \ + --installdir "/${py3_sitelib}-bootstrap" \ + "dist/flit_core-${version}-py3-none-any.whl" + vlicense LICENSE +} From 8c6a90724662ccfad2d338668cb14c833962887c Mon Sep 17 00:00:00 2001 From: classabbyamp Date: Mon, 2 Dec 2024 09:41:46 -0500 Subject: [PATCH 03/13] New package: python3-installer-bootstrap-0.7.0 dependency of python3-packaging-bootstrap --- srcpkgs/python3-installer-bootstrap/template | 41 ++++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 srcpkgs/python3-installer-bootstrap/template diff --git a/srcpkgs/python3-installer-bootstrap/template b/srcpkgs/python3-installer-bootstrap/template new file mode 100644 index 00000000000000..111be0e431c00c --- /dev/null +++ b/srcpkgs/python3-installer-bootstrap/template @@ -0,0 +1,41 @@ +# Template file for 'python3-installer-bootstrap' +pkgname=python3-installer-bootstrap +version=0.7.0 +revision=1 +# This package is used by the python3-pep517 build style; using that style here +# would create a build cycle +build_style=python3-module +hostmakedepends="python3-flit_core-bootstrap" +depends="python3" +short_desc="Low-level library for installing from a Python wheel (for xbps-src use)" +maintainer="Andrew J. Hesford " +license="MIT" +homepage="https://installer.readthedocs.io/" +distfiles="${PYPI_SITE}/i/installer/installer-${version}.tar.gz" +checksum=a26d3e3116289bb08216e0d0f7d925fcef0b0194eedfa0c944bcaaa106c4b631 +make_check=no # bootstrap +repository=bootstrap +nopyprovides=yes +noverifypydeps=yes + +do_build() { + local pypath="/${py3_sitelib}-bootstrap" + if [ -n "${PYTHONPATH}" ]; then + pypath="${pypath}:${PYTHONPATH}" + fi + + PYTHONPATH="${pypath}" python3 -m flit_core.wheel +} + +do_install() { + local pypath="./src:/${py3_sitelib}-bootstrap" + if [ -n "${PYTHONPATH}" ]; then + pypath="${pypath}:${PYTHONPATH}" + fi + + PYTHONPATH="${pypath}" python3 -m installer --destdir "${DESTDIR}" \ + "dist/installer-${version}-py3-none-any.whl" + mv "${DESTDIR}/${py3_sitelib}" "${DESTDIR}/${py3_sitelib}-bootstrap" + + vlicense LICENSE +} From 5d3f2abf6fde6fff12384750b93815b5dd3ab677 Mon Sep 17 00:00:00 2001 From: classabbyamp Date: Mon, 2 Dec 2024 09:42:00 -0500 Subject: [PATCH 04/13] New package: python3-packaging-bootstrap-24.1 needed for verifying python module dependencies --- srcpkgs/python3-packaging-bootstrap/template | 40 ++++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 srcpkgs/python3-packaging-bootstrap/template diff --git a/srcpkgs/python3-packaging-bootstrap/template b/srcpkgs/python3-packaging-bootstrap/template new file mode 100644 index 00000000000000..192fff3734b0a5 --- /dev/null +++ b/srcpkgs/python3-packaging-bootstrap/template @@ -0,0 +1,40 @@ +# Template file for 'python3-packaging-bootstrap' +pkgname=python3-packaging-bootstrap +version=24.1 +revision=1 +# This package is required by python3-build, used by the python3-pep517 style; +# using that style here would create a cycle +build_style=python3-module +hostmakedepends="python3-flit_core-bootstrap python3-installer-bootstrap" +depends="python3" +short_desc="Core utilities for Python 3 packages (for xbps-src use)" +maintainer="Andrew J. Hesford " +license="Apache-2.0, BSD-2-Clause" +homepage="https://github.com/pypa/packaging" +distfiles="${PYPI_SITE}/p/packaging/packaging-${version}.tar.gz" +checksum=026ed72c8ed3fcce5bf8950572258698927fd1dbda10a5e981cdf0ac37f4f002 +make_check=no # provides no tests, bootstrap +repository=bootstrap +nopyprovides=yes +noverifypydeps=yes + +do_build() { + local pypath="/${py3_sitelib}-bootstrap" + if [ -n "${PYTHONPATH}" ]; then + pypath="${pypath}:${PYTHONPATH}" + fi + + PYTHONPATH="${pypath}" python3 -m flit_core.wheel +} + +do_install() { + local pypath="/${py3_sitelib}-bootstrap" + if [ -n "${PYTHONPATH}" ]; then + pypath="${pypath}:${PYTHONPATH}" + fi + + PYTHONPATH="${pypath}" python3 -m installer --destdir "${DESTDIR}" \ + "dist/packaging-${version}-py3-none-any.whl" + mv "${DESTDIR}/${py3_sitelib}" "${DESTDIR}/${py3_sitelib}-bootstrap" + vlicense LICENSE +} From ee14287993aa4c33aefc496ec8e219742c671bf9 Mon Sep 17 00:00:00 2001 From: classabbyamp Date: Mon, 2 Dec 2024 09:42:26 -0500 Subject: [PATCH 05/13] common/environment/build-style/python3-*.sh: add python3-packaging-bootstrap ...if verifying python dependencies. needed for python module dependency verification hook --- common/environment/build-style/python3-module.sh | 3 +++ common/environment/build-style/python3-pep517.sh | 5 ++++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/common/environment/build-style/python3-module.sh b/common/environment/build-style/python3-module.sh index 638f6be9373a47..8ab040aaf58a68 100644 --- a/common/environment/build-style/python3-module.sh +++ b/common/environment/build-style/python3-module.sh @@ -1,3 +1,6 @@ lib32disabled=yes +if [ -z "$nopyprovides" ] || [ -z "$noverifypydeps" ]; then + hostmakedepends+=" python3-packaging-bootstrap" +fi makedepends+=" python3" build_helper+=" python3" diff --git a/common/environment/build-style/python3-pep517.sh b/common/environment/build-style/python3-pep517.sh index f4faf980f5080d..b56773720aee72 100644 --- a/common/environment/build-style/python3-pep517.sh +++ b/common/environment/build-style/python3-pep517.sh @@ -1,3 +1,6 @@ -hostmakedepends+=" python3-build python3-installer" lib32disabled=yes +hostmakedepends+=" python3-build python3-installer" +if [ -z "$nopyprovides" ] || [ -z "$noverifypydeps" ]; then + hostmakedepends+=" python3-packaging-bootstrap" +fi build_helper+=" python3" From e107fba29e133132da1efb25eb93c7380e4cde0a Mon Sep 17 00:00:00 2001 From: classabbyamp Date: Tue, 3 Dec 2024 14:52:46 -0500 Subject: [PATCH 06/13] xbps-src: adjust help for -s it's now used for python dependency verification too --- xbps-src | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/xbps-src b/xbps-src index 00e955fe8168b7..c17270b62ee4b5 100755 --- a/xbps-src +++ b/xbps-src @@ -244,7 +244,7 @@ $(print_cross_targets) This alternative repository will also be used to resolve dependencies with highest priority order than others. --s Make vsed warnings errors. +-s Make some warnings into errors. -t Create a temporary masterdir to not pollute the current one. Note that the existing masterdir must be fully populated with binary-bootstrap first. From f15101b2f8268a5eae36a6908f59ee5de1ed46d1 Mon Sep 17 00:00:00 2001 From: classabbyamp Date: Tue, 3 Dec 2024 15:20:07 -0500 Subject: [PATCH 07/13] common/hooks/post-install/04-create-xbps-metadata-scripts: handle ... python bootstrap several bootstrap python3 modules put packages in ${py3_sitelib}-bootstrap to prevent conflicts and keep them out of the normal PYTHONPATH. this allows the pycompile_module hook to work for those modules --- common/hooks/post-install/04-create-xbps-metadata-scripts.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/hooks/post-install/04-create-xbps-metadata-scripts.sh b/common/hooks/post-install/04-create-xbps-metadata-scripts.sh index 70152bad55f4fc..cf7868b1067360 100644 --- a/common/hooks/post-install/04-create-xbps-metadata-scripts.sh +++ b/common/hooks/post-install/04-create-xbps-metadata-scripts.sh @@ -274,7 +274,7 @@ _EOF if [ -d ${PKGDESTDIR}/usr/lib/python* ]; then pycompile_version="$(find ${PKGDESTDIR}/usr/lib/python* -prune -type d | grep -o '[[:digit:]]\.[[:digit:]]\+$')" if [ -z "${pycompile_module}" ]; then - pycompile_module="$(find ${PKGDESTDIR}/usr/lib/python*/site-packages -mindepth 1 -maxdepth 1 '!' -name '*.egg-info' '!' -name '*.dist-info' '!' -name '*.so' '!' -name '*.pth' -printf '%f ')" + pycompile_module="$(find ${PKGDESTDIR}/usr/lib/python*/site-packages* -mindepth 1 -maxdepth 1 '!' -name '*.egg-info' '!' -name '*.dist-info' '!' -name '*.so' '!' -name '*.pth' -printf '%f ')" fi fi From 07076706d140d30c31695ef99d155ab723ceaed1 Mon Sep 17 00:00:00 2001 From: classabbyamp Date: Tue, 3 Dec 2024 15:31:24 -0500 Subject: [PATCH 08/13] common/environment/setup-subpkg/subpkg: add vars for python dep verif --- Manual.md | 7 +++++++ common/environment/setup-subpkg/subpkg.sh | 6 ++++++ 2 files changed, 13 insertions(+) diff --git a/Manual.md b/Manual.md index c39509f5c7f61b..9d1fabe07d8a18 100644 --- a/Manual.md +++ b/Manual.md @@ -1639,6 +1639,13 @@ written in Python) or just single Python file ones that live in `/usr/bin`. If `python_version` is set to `ignore`, python-containing shebangs will not be rewritten. Use this only if a package should not be using a system version of python. +- `python_extras`: Python module extras to consider when verifying Python module dependencies. +Can be used to ensure additional dependency sets are checked. Example: `python_extras="all"`. + +- `nopyprovides`: if set, don't create `provides` entries for Python modules in the package. + +- `nopyverifydeps`: if set, don't verify Python module dependencies. + Also, a set of useful variables are defined to use in the templates: | Variable | Value | diff --git a/common/environment/setup-subpkg/subpkg.sh b/common/environment/setup-subpkg/subpkg.sh index 6edab5d882e114..379ade740faca5 100644 --- a/common/environment/setup-subpkg/subpkg.sh +++ b/common/environment/setup-subpkg/subpkg.sh @@ -11,6 +11,9 @@ unset -v nostrip nostrip_files # hooks/post-install/14-fix-permissions unset -v nocheckperms nofixperms +# hooks/pre-pkg/04-generate-provides +unset -v nopyprovides + # hooks/pre-pkg/04-generate-runtime-deps unset -v noverifyrdeps skiprdeps allow_unknown_shlibs shlib_requires @@ -20,6 +23,9 @@ unset -v lib32depends lib32disabled lib32files lib32mode lib32symlinks # hooks/pre-pkg/06-shlib-provides unset -v noshlibprovides shlib_provides +# hooks/pre-pkg/06-verify-python-deps +unset -v noverifypydeps python_extras + # xbps-triggers: system-accounts unset -v system_accounts system_groups From a2fcd04aab95a28a086ea1126a0e84c7984509b6 Mon Sep 17 00:00:00 2001 From: classabbyamp Date: Tue, 3 Dec 2024 15:38:14 -0500 Subject: [PATCH 09/13] common/hooks: use file for managing provides this will allow provides to be generated from things like package contents and saved into the file for package generation. --- common/hooks/do-pkg/00-gen-pkg.sh | 4 +++- common/hooks/pre-pkg/04-generate-provides.sh | 16 ++++++++++++++++ 2 files changed, 19 insertions(+), 1 deletion(-) create mode 100644 common/hooks/pre-pkg/04-generate-provides.sh diff --git a/common/hooks/do-pkg/00-gen-pkg.sh b/common/hooks/do-pkg/00-gen-pkg.sh index af3938eac04972..e37a733603df32 100644 --- a/common/hooks/do-pkg/00-gen-pkg.sh +++ b/common/hooks/do-pkg/00-gen-pkg.sh @@ -37,6 +37,9 @@ genpkg() { if [ -s ${XBPS_STATEDIR}/${pkgname}-rdeps ]; then _deps="$(<${XBPS_STATEDIR}/${pkgname}-rdeps)" fi + if [ -s ${XBPS_STATEDIR}/${pkgname}-provides ]; then + _provides="$(<${XBPS_STATEDIR}/${pkgname}-provides)" + fi if [ -s ${XBPS_STATEDIR}/${pkgname}-shlib-provides ]; then _shprovides="$(<${XBPS_STATEDIR}/${pkgname}-shlib-provides)" fi @@ -48,7 +51,6 @@ genpkg() { fi # Stripping whitespaces - local _provides="$(echo $provides)" local _conflicts="$(echo $conflicts)" local _replaces="$(echo $replaces)" local _reverts="$(echo $reverts)" diff --git a/common/hooks/pre-pkg/04-generate-provides.sh b/common/hooks/pre-pkg/04-generate-provides.sh new file mode 100644 index 00000000000000..f74d1f80543c47 --- /dev/null +++ b/common/hooks/pre-pkg/04-generate-provides.sh @@ -0,0 +1,16 @@ +# vim: set ts=4 sw=4 et: +# +# This hook executes the following tasks: +# - Generates provides file with provides entries for xbps-create(1) + +hook() { + local -a _provides=() + + # include explicit values from the template + read -r -a _provides <<< "$provides" + + if [ "${#_provides[@]}" -gt 0 ]; then + echo " ${_provides[*]}" + echo "${_provides[*]}" > "${PKGDESTDIR}/provides" + fi +} From c73eaf5cdad662a516280709d2a3f722d91b7d5c Mon Sep 17 00:00:00 2001 From: classabbyamp Date: Tue, 3 Dec 2024 15:42:51 -0500 Subject: [PATCH 10/13] common/scripts/parse-py-metadata.py: add script to parse python module metadata this script uses python3-packaging-bootstrap to extract information about python modules, including their names and dependencies for use by xbps-src hooks --- common/scripts/parse-py-metadata.py | 203 ++++++++++++++++++++++++++++ 1 file changed, 203 insertions(+) create mode 100644 common/scripts/parse-py-metadata.py diff --git a/common/scripts/parse-py-metadata.py b/common/scripts/parse-py-metadata.py new file mode 100644 index 00000000000000..150d476a4ceccc --- /dev/null +++ b/common/scripts/parse-py-metadata.py @@ -0,0 +1,203 @@ +#!/usr/bin/python3 + +# vim: set ts=4 sw=4 et: +""" +Usage: + +./parse-py-metadata.py -S "$DESTDIR/$py3_sitelib" provides -v "$version" + + extract the names of top-level packages from: + - $DESTDIR/$py3_sitelib/*.dist-info/METADATA + - $DESTDIR/$py3_sitelib/*.egg-info/PKG-INFO + +./parse-py-metadata.py -S "$DESTDIR/$py3_sitelib" [-s] [-C] depends -e "extra1 extra2 ..." + -D "$XBPS_STATEDIR/$pkgname-rdeps" -V <( xbps-query -R -p provides -s "py3:" ) + + check that the dependencies of a package match what's listed in the python + package metadata, using the virtual package provides entries generated by + `parse-py-metadata.py provides`. + +This script requires python3-packaging-bootstrap to be installed in the chroot +to run (which should be taken care of by the python3-module and python3-pep517 +build styles). +""" + +import argparse +from pathlib import Path +from sys import stderr +from typing import TYPE_CHECKING + +if TYPE_CHECKING: + from packaging.metadata import Metadata + from packaging.requirements import Requirement + from packaging.utils import canonicalize_name + + +def msg_err(msg: str, *, nocolor: bool = False, strict: bool = False): + if nocolor: + print(msg, flush=True) + else: + color = "31" if strict else "33" + print(f"\033[1m\033[{color}m{msg}\033[m", file=stderr, flush=True) + + +def vpkgname(val: "str | Requirement", *, version: str | None = None) -> str: + sfx = "" + if version is not None: + sfx = f"-{version}" + if isinstance(val, Requirement): + name = val.name + else: + name = val + return f"py3:{canonicalize_name(name)}{sfx}" + + +def getpkgname(pkgver: str) -> str: + return pkgver.rpartition("-")[0] + + +def getpkgversion(pkgver: str) -> str: + return pkgver.rpartition("-")[2] + + +def getpkgdepname(pkgdep: str) -> str: + if "<" in pkgdep: + return pkgdep.partition("<")[0] + elif ">" in pkgdep: + return pkgdep.partition(">")[0] + else: + return pkgdep.rpartition("-")[0] + + +def match_markers(req: "Requirement", extras: set[str]) -> bool: + # unconditional requirement + if req.marker is None: + return True + + # check the requirement for each extra we want and without any extras + if extras: + return req.marker.evaluate() and any(req.marker.evaluate({"extra": e}) for e in extras) + + return req.marker.evaluate() + + +def find_metadata_files(sitepkgs: Path) -> list[Path]: + metafiles = list(sitepkgs.glob("*.dist-info/METADATA")) + metafiles.extend(sitepkgs.glob("*.egg-info/PKG-INFO")) + return metafiles + + +def parse_provides(args): + out = set() + + for metafile in find_metadata_files(args.sitepkgs): + with metafile.open() as f: + raw = f.read() + + meta = Metadata.from_email(raw, validate=False) + + out.add(vpkgname(meta.name, version=getpkgversion(args.pkgver))) + if meta.provides_dist is not None: + out.update(map(lambda n: vpkgname(n, version=getpkgversion(args.pkgver)), meta.provides_dist)) + # deprecated but may be used + if meta.provides is not None: + out.update(map(lambda n: vpkgname(n, version=getpkgversion(args.pkgver)), meta.provides)) + + print("\n".join(out), flush=True) + + +def parse_depends(args): + depends = dict() + vpkgs = dict() + extras = set(args.extras.split()) + + with args.vpkgs.open() as f: + for ln in f.readlines(): + if not ln.strip(): + continue + pkgver, _, rest = ln.partition(":") + vpkgvers, _, _ = rest.strip().partition("(") + pkg = getpkgname(pkgver) + vpkg = map(getpkgname, vpkgvers.split()) + for v in vpkg: + vpkgs[v] = pkg + + if args.rdeps.exists(): + with args.rdeps.open() as f: + rdeps = list(map(getpkgdepname, f.read().split())) + else: + rdeps = [] + + for metafile in find_metadata_files(args.sitepkgs): + with metafile.open() as f: + raw = f.read() + + meta = Metadata.from_email(raw, validate=False) + + if meta.requires_dist is not None: + depends.update(map(lambda p: (vpkgname(p), None), + filter(lambda r: match_markers(r, extras), meta.requires_dist))) + # deprecated but may be used + if meta.requires is not None: + depends.update(map(lambda p: (vpkgname(p), None), meta.requires)) + + err = False + unknown = False + missing = [] + for k in depends.keys(): + if k in vpkgs.keys(): + pkgname = vpkgs[k] + if pkgname in rdeps: + print(f" PYTHON: {k} <-> {pkgname}", flush=True) + else: + msg_err(f" PYTHON: {k} <-> {pkgname} NOT IN depends PLEASE FIX!", + nocolor=args.nocolor, strict=args.strict) + missing.append(pkgname) + err = True + else: + msg_err(f" PYTHON: {k} <-> UNKNOWN PKG PLEASE FIX!", + nocolor=args.nocolor, strict=args.strict) + unknown = True + err = True + + if missing or unknown: + msg_err(f"=> {args.pkgver}: missing dependencies detected!", + nocolor=args.nocolor, strict=args.strict) + if missing: + msg_err(f"=> {args.pkgver}: please add these packages to depends: {' '.join(sorted(missing))}", + nocolor=args.nocolor, strict=args.strict) + + if err and args.strict: + exit(1) + + +if __name__ == "__main__": + parser = argparse.ArgumentParser() + parser.add_argument("-S", dest="sitepkgs", type=Path) + parser.add_argument("-v", dest="pkgver") + parser.add_argument("-s", dest="strict", action="store_true") + parser.add_argument("-C", dest="nocolor", action="store_true") + subparsers = parser.add_subparsers() + + prov_parser = subparsers.add_parser("provides") + prov_parser.set_defaults(func=parse_provides) + + deps_parser = subparsers.add_parser("depends") + deps_parser.add_argument("-e", dest="extras", default="") + deps_parser.add_argument("-V", dest="vpkgs", type=Path) + deps_parser.add_argument("-D", dest="rdeps", type=Path) + deps_parser.set_defaults(func=parse_depends) + + args = parser.parse_args() + + try: + from packaging.metadata import Metadata + from packaging.requirements import Requirement + from packaging.utils import canonicalize_name + except ImportError: + msg_err(f"=> WARNING: {args.pkgver}: missing packaging module!\n" + f"=> WARNING: {args.pkgver}: please add python3-packaging-bootstrap to hostmakedepends to run this check", + nocolor=args.nocolor) + exit(0) + + args.func(args) From 171dcee06b3a4e69d899ec8add96eb5f27577820 Mon Sep 17 00:00:00 2001 From: classabbyamp Date: Tue, 3 Dec 2024 16:20:39 -0500 Subject: [PATCH 11/13] common/hooks/pre-pkg/04-generate-provides: generate provides for python modules --- common/hooks/pre-pkg/04-generate-provides.sh | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/common/hooks/pre-pkg/04-generate-provides.sh b/common/hooks/pre-pkg/04-generate-provides.sh index f74d1f80543c47..f9c1a68e134c78 100644 --- a/common/hooks/pre-pkg/04-generate-provides.sh +++ b/common/hooks/pre-pkg/04-generate-provides.sh @@ -3,14 +3,27 @@ # This hook executes the following tasks: # - Generates provides file with provides entries for xbps-create(1) +generate_python_provides() { + local py3_bin="${XBPS_MASTERDIR}/usr/bin/python3" + + if [ -z "$nopyprovides" ] && [ -d "${PKGDESTDIR}/${py3_sitelib}" ] && [ -x "${py3_bin}" ]; then + PYTHONPATH="${XBPS_MASTERDIR}/${py3_sitelib}-bootstrap" "${py3_bin}" \ + "${XBPS_COMMONDIR}"/scripts/parse-py-metadata.py \ + -S "${PKGDESTDIR}/${py3_sitelib}" -v "${pkgver}" provides + fi +} + hook() { local -a _provides=() # include explicit values from the template read -r -a _provides <<< "$provides" + # get the canonical python package names for each python module + mapfile -t _provides -O "${#_provides[@]}" < <( generate_python_provides ) + if [ "${#_provides[@]}" -gt 0 ]; then echo " ${_provides[*]}" - echo "${_provides[*]}" > "${PKGDESTDIR}/provides" + echo "${_provides[*]}" > "${XBPS_STATEDIR}/${pkgname}-provides" fi } From e3bb2b24d63a60a0fa860dbc88f9d4cf3d9cd647 Mon Sep 17 00:00:00 2001 From: classabbyamp Date: Tue, 3 Dec 2024 16:21:08 -0500 Subject: [PATCH 12/13] common/hooks/pre-pkg/06-verify-python-deps: add hook compares rdeps and Python module metadata to find missing dependencies for python packages. this uses virtual packages to map python canonical package names to void packages. --- common/hooks/pre-pkg/06-verify-python-deps.sh | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 common/hooks/pre-pkg/06-verify-python-deps.sh diff --git a/common/hooks/pre-pkg/06-verify-python-deps.sh b/common/hooks/pre-pkg/06-verify-python-deps.sh new file mode 100644 index 00000000000000..a47e5bbbf107d3 --- /dev/null +++ b/common/hooks/pre-pkg/06-verify-python-deps.sh @@ -0,0 +1,17 @@ +# vim: set ts=4 sw=4 et: +# +# This hook executes the following tasks: +# - Verifies python module dependencies from dist-info's METADATA and egg-info's PKG-INFO + +hook() { + local py3_bin="${XBPS_MASTERDIR}/usr/bin/python3" + + if [ -z "$nopyprovides" ] && [ -d "${PKGDESTDIR}/${py3_sitelib}" ] && [ -x "${py3_bin}" ]; then + PYTHONPATH="${XBPS_MASTERDIR}/${py3_sitelib}-bootstrap" "${py3_bin}" \ + "${XBPS_COMMONDIR}"/scripts/parse-py-metadata.py \ + ${NOCOLORS:+-C} ${XBPS_STRICT:+-s} -S "${PKGDESTDIR}/${py3_sitelib}" -v "${pkgver}" \ + depends -e "${python_extras}" \ + -V <( $XBPS_QUERY_XCMD -R -p provides -s "py3:" ) -D "${XBPS_STATEDIR}/${pkgname}-rdeps" \ + || msg_error "$pkgver: failed to verify python module dependencies\n" + fi +} From 11134aa9a9f5d416106e88ff6abf755888621afc Mon Sep 17 00:00:00 2001 From: classabbyamp Date: Tue, 3 Dec 2024 18:58:57 -0500 Subject: [PATCH 13/13] REVERTME: switch xtools branch --- common/travis/fetch-xtools.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/travis/fetch-xtools.sh b/common/travis/fetch-xtools.sh index 0dd9e6c532c06c..a185684e38bf42 100755 --- a/common/travis/fetch-xtools.sh +++ b/common/travis/fetch-xtools.sh @@ -4,7 +4,7 @@ TAR=tar command -v bsdtar >/dev/null && TAR=bsdtar -URL="https://github.com/leahneukirchen/xtools/archive/master.tar.gz" +URL="https://github.com/classabbyamp/xtools/archive/pyprovides.tar.gz" FILE="xtools.tar.gz" mkdir -p /tmp/bin