RPM Package Manager, CVS Repository http://rpm5.org/cvs/ ____________________________________________________________________________
Server: rpm5.org Name: Per Øyvind Karlsen Root: /v/rpm/cvs Email: pkarl...@rpm5.org Module: rpm Date: 25-Jan-2011 22:56:58 Branch: rpm-5_3 Handle: 2011012521565800 Added files: (Branch: rpm-5_3) rpm/scripts pythoneggs.py Log: add pythonegg() dependency extractor Summary: Revision Changes Path 1.2.2.2 +180 -0 rpm/scripts/pythoneggs.py ____________________________________________________________________________ patch -p0 <<'@@ .' Index: rpm/scripts/pythoneggs.py ============================================================================ $ cvs diff -u -r0 -r1.2.2.2 pythoneggs.py --- /dev/null 2011-01-25 22:55:01.000000000 +0100 +++ pythoneggs.py 2011-01-25 22:56:58.712436077 +0100 @@ -0,0 +1,180 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# +# Copyright 2010 Per Ãyvind Karlsen <peroyv...@mandriva.org> +# +# 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 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)' % 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)' % 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 @@ . ______________________________________________________________________ RPM Package Manager http://rpm5.org CVS Sources Repository rpm-cvs@rpm5.org