Add a script to generate Python bundled provides
See https://src.fedoraproject.org/rpms/python-setuptools/pull-request/40 Strictly speaking, this is not an RPM generator, but: - it generates provides - it is tighly coupled with pythondistdeps.py Usage: 1. Run `$ /usr/lib/rpm/pythonbundles.py .../vendored.txt` 2. Copy the output into the spec as a macro definition: %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.15 } 3. Use the macro to expand the provides 4. Verify the macro contents in %check: %check ... %{_rpmconfigdir}/pythonbundles.py src/_vendor/vendored.txt --compare-with '%{bundled}'
This commit is contained in:
parent
e78c420523
commit
48c0de39d9
10 changed files with 368 additions and 3 deletions
90
pythonbundles.py
Normal file
90
pythonbundles.py
Normal file
|
|
@ -0,0 +1,90 @@
|
|||
#!/usr/bin/python3 -B
|
||||
# (imports pythondistdeps from /usr/lib/rpm, hence -B)
|
||||
#
|
||||
# This program is free software.
|
||||
#
|
||||
# It is placed in the public domain or under the CC0-1.0-Universal license,
|
||||
# whichever is more permissive.
|
||||
#
|
||||
# Alternatively, it may be redistributed and/or modified under the terms of
|
||||
# the LGPL version 2.1 (or later) or GPL version 2 (or later).
|
||||
#
|
||||
# Use this script to generate bundled provides, e.g.:
|
||||
# ./pythonbundles.py setuptools-47.1.1/pkg_resources/_vendor/vendored.txt
|
||||
|
||||
import pathlib
|
||||
import sys
|
||||
|
||||
# inject parse_version import to pythondistdeps
|
||||
# not the nicest API, but :/
|
||||
from pkg_resources import parse_version
|
||||
import pythondistdeps
|
||||
pythondistdeps.parse_version = parse_version
|
||||
|
||||
|
||||
def generate_bundled_provides(path, namespace):
|
||||
provides = set()
|
||||
|
||||
for line in path.read_text().splitlines():
|
||||
line, _, comment = line.partition('#')
|
||||
if comment.startswith('egg='):
|
||||
# not a real comment
|
||||
# e.g. git+https://github.com/monty/spam.git@master#egg=spam&...
|
||||
egg, *_ = comment.strip().partition(' ')
|
||||
egg, *_ = egg.strip().partition('&')
|
||||
name = pythondistdeps.normalize_name(egg[4:])
|
||||
provides.add(f'Provides: bundled({namespace}({name}))')
|
||||
continue
|
||||
line = line.strip()
|
||||
if line:
|
||||
name, _, version = line.partition('==')
|
||||
name = pythondistdeps.normalize_name(name)
|
||||
bundled_name = f"bundled({namespace}({name}))"
|
||||
python_provide = pythondistdeps.convert(bundled_name, '==', version)
|
||||
provides.add(f'Provides: {python_provide}')
|
||||
|
||||
return provides
|
||||
|
||||
|
||||
def compare(expected, given):
|
||||
stripped = (l.strip() for l in given)
|
||||
no_comments = set(l for l in stripped if not l.startswith('#'))
|
||||
no_comments.discard('')
|
||||
if expected == no_comments:
|
||||
return True
|
||||
extra_expected = expected - no_comments
|
||||
extra_given = no_comments - expected
|
||||
if extra_expected:
|
||||
print('Missing expected provides:', file=sys.stderr)
|
||||
for provide in sorted(extra_expected):
|
||||
print(f' - {provide}', file=sys.stderr)
|
||||
if extra_given:
|
||||
print('Redundant unexpected provides:', file=sys.stderr)
|
||||
for provide in sorted(extra_given):
|
||||
print(f' + {provide}', file=sys.stderr)
|
||||
return False
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
import argparse
|
||||
|
||||
parser = argparse.ArgumentParser(prog=sys.argv[0],
|
||||
formatter_class=argparse.ArgumentDefaultsHelpFormatter)
|
||||
parser.add_argument('vendored', metavar='VENDORED.TXT',
|
||||
help='Upstream information about vendored libraries')
|
||||
parser.add_argument('-c', '--compare-with', action='store',
|
||||
help='A string value to compare with and verify')
|
||||
parser.add_argument('-n', '--namespace', action='store',
|
||||
help='What namespace of provides will used', default='python3dist')
|
||||
args = parser.parse_args()
|
||||
|
||||
provides = generate_bundled_provides(pathlib.Path(args.vendored), args.namespace)
|
||||
|
||||
if args.compare_with:
|
||||
given = args.compare_with.splitlines()
|
||||
same = compare(provides, given)
|
||||
if not same:
|
||||
sys.exit(1)
|
||||
else:
|
||||
for provide in sorted(provides):
|
||||
print(provide)
|
||||
Loading…
Add table
Add a link
Reference in a new issue