#40 Proof of concept: Validate bundled provides in %check with a Python script
Closed 3 years ago by churchyard. Opened 3 years ago by churchyard.
rpms/ churchyard/python-setuptools check_vendored_python  into  master

file added
+49
@@ -0,0 +1,49 @@ 

+ import pathlib

+ import sys

+ 

+ try:

+     SOURCES = pathlib.Path(sys.argv[1])

+ except IndexError:

+     sys.exit(

+         "Requires directory with prepped sources as argument, e.g. setuptools-47.1.1"

+     )

+ VENDOR_FILE = SOURCES / "pkg_resources/_vendor/vendored.txt"

+ 

+ 

+ def convert_version(version):

+     for pre in "a", "b", "rc", "dev":

+         if pre in version:

+             version, rel, relnum = version.partition(pre)

+             break

+     else:

+         rel = relnum = ""

+ 

+     while version.endswith(".0"):

+         version = version[:-2]

+ 

+     if rel == "dev":

+         return f"{version}~~{rel}{relnum}"

+     if rel:

+         return f"{version}~{rel}{relnum}"

+     return version

+ 

+ 

+ provides = set()

+ 

+ for line in VENDOR_FILE.read_text().splitlines():

+     line, *_ = line.partition("#")

+     line = line.strip()

+     if line:

+         name, _, version = line.partition("==")

+         version = convert_version(version)

+         provides.add(f"Provides: bundled(python3dist({name})) = {version}")

+ 

+ # When used standalone, we print, when with argument, we assert

+ if len(sys.argv) == 2:

+     for provide in sorted(provides):

+         print(provide)

+ else:

+     expected = set(sys.argv[2].splitlines())

+     expected.discard("")

+     if provides != expected:

+         sys.exit(f"{provides} != {expected}")

file modified
+15 -10
@@ -45,6 +45,17 @@ 

  BuildRequires:  python3-rpm-generators

  %endif # without bootstrap

  

+ # Virtual provides for the packages bundled by setuptools.

+ # You can find the versions in setuptools/setuptools/_vendor/vendored.txt

+ # Use this source to generate the list:

+ Source9:        bundled_provides.py

+ %global bundled %{expand:

+ Provides: bundled(python3dist(appdirs)) = 1.4.3

+ Provides: bundled(python3dist(packaging)) = 16.8

+ Provides: bundled(python3dist(pyparsing)) = 2.2.1

+ Provides: bundled(python3dist(six)) = 1.10

+ }

+ 

  %description

  Setuptools is a collection of enhancements to the Python distutils that allow

  you to more easily build and distribute Python packages, especially ones that
@@ -53,15 +64,6 @@ 

  This package also contains the runtime components of setuptools, necessary to

  execute the software that requires pkg_resources.

  

- # Virtual provides for the packages bundled by setuptools.

- # You can find the versions in setuptools/setuptools/_vendor/vendored.txt

- %global bundled %{expand:

- Provides: bundled(python3dist(packaging)) = 16.8

- Provides: bundled(python3dist(pyparsing)) = 2.2.1

- Provides: bundled(python3dist(six)) = 1.10.0

- Provides: bundled(python3dist(appdirs)) = 1.4.3

- }

- 

  %package -n python3-setuptools

  Summary:        Easily build and distribute Python 3 packages

  Conflicts:      python-setuptools < %{version}-%{release}
@@ -142,8 +144,11 @@ 

  %endif

  

  

- %if %{with tests}

  %check

+ # Assert the bundled provides are up to date

+ %{python3} %{SOURCE9} . '%{bundled}'

+ 

+ %if %{with tests}

  # --ignore=pavement.py:

  #   pavement.py is only used by upstream to do releases and vendoring, we don't ship it

  PYTHONDONTWRITEBYTECODE=1 PYTHONPATH=$(pwd) pytest-%{python3_version} \

We repeatadly forget to update the list of bundled provides.

This is a proof of concept of validating the provides in %check
with a Python script.

If we like he idea, we can make the script more general,
package it to python-rpm-macros and reuse it in setuptools, pip, pipenv...

As for the code, I have no notes, it looks good. If we were to ship it fedora-wide, I'd appreciate using argparse, but for now it's fine.

Why I like this approach more:

  • the vendor.txt "parsing" is more robust already and can be extended easily in the future
  • the code in spec (a macro that has the actual provides) is more understandable by beginners over a Lua table
  • the script can be used to actually generate the provides section

Why I like this approach more:

the vendor.txt "parsing" is more robust already and can be extended easily in the future
the code in spec (a macro that has the actual provides) is more understandable by beginners over a Lua table
the script can be used to actually generate the provides section

Oh right, automatically generating is a big plus for the future too. +1

Added it to my balance sheet here: https://src.fedoraproject.org/rpms/python-setuptools/pull-request/39#comment-47966

Pull-Request has been closed by churchyard

3 years ago