From f352400599e4a4c14e1a18997a15a153781beee3 Mon Sep 17 00:00:00 2001 From: Thierry Vignaud Date: Wed, 24 Sep 2014 15:22:28 +0200 Subject: readd back pythoneggs.py --- Makefile.am | 3 +- pythoneggs.py | 183 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 185 insertions(+), 1 deletion(-) create mode 100755 pythoneggs.py diff --git a/Makefile.am b/Makefile.am index 49b83fd..d573bff 100644 --- a/Makefile.am +++ b/Makefile.am @@ -41,7 +41,8 @@ pkg_scripts = \ perl.req \ perl.req-from-meta \ php.prov \ - php.req + php.req \ + pythoneggs.py pkg_gscripts = \ find-provides \ diff --git a/pythoneggs.py b/pythoneggs.py new file mode 100755 index 0000000..178610f --- /dev/null +++ b/pythoneggs.py @@ -0,0 +1,183 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# +# Copyright 2010 Per Øyvind Karlsen +# +# This program is free software. It may be redistributed and/or modified under +# the terms of the LGPL version 2.1 (or later). +# +# RPM5 python (egg) dependency generator. +# + +from getopt import getopt +from os.path import basename, dirname, isdir, sep, splitext +from sys import argv, stdin, version +from pkg_resources import Distribution, FileMetadata, PathMetadata +from distutils.sysconfig import get_python_lib + + +opts, args = getopt(argv[1:], 'hPRSCOE', + ['help', 'provides', 'requires', 'suggests', 'conflicts', 'obsoletes', 'extras']) + +Provides = False +Requires = False +Suggests = False +Conflicts = False +Obsoletes = False +Extras = False + +for o, a in opts: + if o in ('-h', '--help'): + print '-h, --help\tPrint help' + print '-P, --provides\tPrint Provides' + print '-R, --requires\tPrint Requires' + print '-S, --suggests\tPrint Suggests' + print '-C, --conflicts\tPrint Conflicts' + print '-O, --obsoletes\tPrint Obsoletes (unused)' + print '-E, --extras\tPrint Extras ' + exit(1) + elif o in ('-P', '--provides'): + Provides = True + elif o in ('-R', '--requires'): + Requires = True + elif o in ('-S', '--suggests'): + Suggests = True + elif o in ('-C', '--conflicts'): + Conflicts = True + elif o in ('-O', '--obsoletes'): + Obsoletes = True + elif o in ('-E', '--extras'): + Extras = True + +if Requires: + py_abi = True +else: + py_abi = False +py_deps = {} +if args: + files = args +else: + files = stdin.readlines() +for f in files: + f = f.strip() + lower = f.lower() + name = 'python(abi)' + # add dependency based on path, versioned if within versioned python directory + if py_abi and (lower.endswith('.py') or lower.endswith('.pyc') or lower.endswith('.pyo')): + if not name in py_deps: + py_deps[name] = [] + purelib = get_python_lib(standard_lib=1, plat_specific=0).split(version[:3])[0] + platlib = get_python_lib(standard_lib=1, plat_specific=1).split(version[:3])[0] + for lib in (purelib, platlib): + if lib in f: + spec = ('==',f.split(lib)[1].split(sep)[0]) + if not spec in py_deps[name]: + py_deps[name].append(spec) + # Determine provide, requires, conflicts & suggests based on egg metadata + if lower.endswith('.egg') or \ + lower.endswith('.egg-info') or \ + lower.endswith('.egg-link'): + dist_name = basename(f) + if isdir(f): + path_item = dirname(f) + metadata = PathMetadata(path_item, f) + else: + path_item = f + metadata = FileMetadata(f) + dist = Distribution.from_location(path_item, dist_name, metadata) + if not dist.py_version: + continue + py_major = dist.py_version[:1] + if Provides: + # If egg metadata says package name is python, we provide python(abi) + if dist.key == 'python': + name = 'python(abi)' + if not name in py_deps: + py_deps[name] = [] + py_deps[name].append(('==', dist.py_version)) + name = 'pythonegg(%s)(%s)' % (py_major, dist.key) + if not name in py_deps: + py_deps[name] = [] + if dist.version: + spec = ('==', dist.version) + if not spec in py_deps[name]: + py_deps[name].append(spec) + if Requires or (Suggests and dist.extras): + name = 'python(abi)' + # If egg metadata says package name is python, we don't add dependency on python(abi) + if dist.key == 'python': + py_abi = False + if name in py_deps: + py_deps.pop(name) + elif py_abi and dist.py_version: + if not name in py_deps: + py_deps[name] = [] + spec = ('==', dist.py_version) + if not spec in py_deps[name]: + py_deps[name].append(spec) + deps = dist.requires() + if Suggests: + depsextras = dist.requires(extras=dist.extras) + if not Requires: + for dep in reversed(depsextras): + if dep in deps: + depsextras.remove(dep) + deps = depsextras + # add requires/suggests based on egg metadata + for dep in deps: + name = 'pythonegg(%s)(%s)' % (py_major, dep.key) + for spec in dep.specs: + if spec[0] != '!=': + if not name in py_deps: + py_deps[name] = [] + if not spec in py_deps[name]: + py_deps[name].append(spec) + if not dep.specs: + py_deps[name] = [] + # Unused, for automatic sub-package generation based on 'extras' from egg metadata + # TODO: implement in rpm later, or...? + if Extras: + deps = dist.requires() + extras = dist.extras + print extras + for extra in extras: + print '%%package\textras-%s' % extra + print 'Summary:\t%s extra for %s python egg' % (extra, dist.key) + print 'Group:\t\tDevelopment/Python' + depsextras = dist.requires(extras=[extra]) + for dep in reversed(depsextras): + if dep in deps: + depsextras.remove(dep) + deps = depsextras + for dep in deps: + for spec in dep.specs: + if spec[0] == '!=': + print 'Conflicts:\t%s %s %s' % (dep.key, '==', spec[1]) + else: + print 'Requires:\t%s %s %s' % (dep.key, spec[0], spec[1]) + print '%%description\t%s' % extra + print '%s extra for %s python egg' % (extra, dist.key) + print '%%files\t\textras-%s\n' % extra + if Conflicts: + # Should we really add conflicts for extras? + # Creating a meta package per extra with suggests on, which has + # the requires/conflicts in stead might be a better solution... + for dep in dist.requires(extras=dist.extras): + name = dep.key + for spec in dep.specs: + if spec[0] == '!=': + if not name in py_deps: + py_deps[name] = [] + spec = ('==', spec[1]) + if not spec in py_deps[name]: + py_deps[name].append(spec) +names = py_deps.keys() +names.sort() +for name in names: + if py_deps[name]: + # Print out versioned provides, requires, suggests, conflicts + for spec in py_deps[name]: + print '%s %s %s' % (name, spec[0], spec[1]) + else: + # Print out unversioned provides, requires, suggests, conflicts + print name -- cgit v1.2.1