ubuntu-dev-tools/reverse-depends

171 lines
6.3 KiB
Plaintext
Raw Permalink Normal View History

2011-11-09 23:44:22 +02:00
#!/usr/bin/python
#
2011-11-12 13:12:15 +02:00
# Copyright (C) 2011, Stefano Rivera <stefanor@ubuntu.com>
2011-11-09 23:44:22 +02:00
#
# Permission to use, copy, modify, and/or distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
# copyright notice and this permission notice appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
import optparse
2011-11-11 23:13:01 +02:00
import sys
2011-11-09 23:44:22 +02:00
from distro_info import DistroDataOutdated
2011-11-09 23:44:22 +02:00
from ubuntutools.logger import Logger
from ubuntutools.misc import (system_distribution, vendor_to_distroinfo,
codename_to_distribution)
2011-11-11 23:38:01 +02:00
from ubuntutools.rdepends import query_rdepends, RDependsException
2011-11-09 23:44:22 +02:00
2011-11-09 23:44:22 +02:00
def main():
system_distro_info = vendor_to_distroinfo(system_distribution())()
try:
default_release = system_distro_info.devel()
except DistroDataOutdated, e:
Logger.warn(e)
default_release = 'unstable'
2011-11-15 12:58:04 +02:00
parser = optparse.OptionParser('%prog [options] package',
2011-11-12 12:53:32 +02:00
description="List reverse-dependencies of package. "
2011-11-11 23:47:14 +02:00
"If the package name is prefixed with src: then the "
2011-11-12 12:53:32 +02:00
"reverse-dependencies of all the binary packages that "
2011-11-11 23:47:14 +02:00
"the specified source package builds will be listed.")
2011-11-09 23:44:22 +02:00
parser.add_option('-r', '--release', metavar='RELEASE',
default=default_release,
help='Query dependencies in RELEASE. '
'Default: %s' % default_release)
2011-11-09 23:44:22 +02:00
parser.add_option('-R', '--without-recommends',
action='store_false', dest='recommends', default=True,
help='Only consider Depends relationships, '
2011-11-12 12:53:32 +02:00
'not Recommends')
2011-11-09 23:44:22 +02:00
parser.add_option('-s', '--with-suggests',
action='store_true', dest='suggests', default=False,
2011-11-12 12:53:32 +02:00
help='Also consider Suggests relationships')
2011-11-09 23:44:22 +02:00
parser.add_option('-b', '--build-depends',
action='store_const', dest='arch', const='source',
help='Query build dependencies (synonym for '
2011-11-12 12:53:32 +02:00
'--arch=source)')
parser.add_option('-a', '--arch', metavar='ARCH', default='any',
2011-11-12 12:53:32 +02:00
help='Query dependencies in ARCH. '
'Default: any')
parser.add_option('-c', '--component', metavar='COMPONENT',
action='append',
help='Only consider reverse-dependencies in COMPONENT. '
2011-11-12 12:53:32 +02:00
'Can be specified multiple times. Default: all')
parser.add_option('-l', '--list',
action='store_true', default=False,
help='Display a simple, machine-readable list')
2011-11-09 23:44:22 +02:00
parser.add_option('-u', '--service-url', metavar='URL',
dest='server', default=None,
2011-11-12 12:53:32 +02:00
help='Reverse Dependencies webservice URL. '
'Default: UbuntuWire')
2011-11-09 23:44:22 +02:00
options, args = parser.parse_args()
if len(args) != 1:
parser.error("One (and only one) package must be specified")
package = args[0]
opts = {}
2011-11-09 23:44:22 +02:00
if options.server is not None:
opts['server'] = options.server
# Convert unstable/testing aliases to codenames:
distribution = codename_to_distribution(options.release)
if not distribution:
parser.error('Unknown release codename %s' % options.release)
distro_info = vendor_to_distroinfo(distribution)()
try:
options.release = distro_info.codename(options.release,
default=options.release)
except DistroDataOutdated:
# We already printed a warning
pass
2011-11-11 23:13:01 +02:00
try:
data = query_rdepends(package, options.release, options.arch, **opts)
2011-11-11 23:38:01 +02:00
except RDependsException, e:
Logger.error(str(e))
sys.exit(1)
if options.arch == 'source':
fields = ['Reverse-Build-Depends', 'Reverse-Build-Depends-Indep']
else:
fields = ['Reverse-Depends']
if options.recommends:
fields.append('Reverse-Recommends')
if options.suggests:
fields.append('Reverse-Suggests')
for field in data.keys():
if field not in fields:
del data[field]
if options.component:
for field, rdeps in data.items():
filtered = [rdep for rdep in rdeps
if rdep['Component'] in options.component]
if not filtered:
del data[field]
else:
data[field] = filtered
if options.list:
display_consise(data)
else:
display_verbose(data)
def display_verbose(data):
if not data:
print "No reverse dependencies found"
return
all_archs = set()
# This isn't accurate, but we make up for it by displaying what we found
for rdeps in data.itervalues():
for rdep in rdeps:
if 'Architectures' in rdep:
all_archs.update(rdep['Architectures'])
for field, rdeps in data.iteritems():
print field
print '=' * len(field)
2011-11-11 23:32:20 +02:00
rdeps.sort(key=lambda x: x['Package'])
for rdep in rdeps:
line = '* %s' % rdep['Package']
if all_archs and set(rdep['Architectures']) != all_archs:
line += ' [%s]' % ' '.join(sorted(rdep['Architectures']))
if 'Dependency' in rdep:
if len(line) < 30:
line += ' ' * (30 - len(line))
line += ' (for %s)' % rdep['Dependency']
print line
print
if all_archs:
print ("Packages without architectures listed are "
"reverse-dependencies in: %s"
% ', '.join(sorted(list(all_archs))))
def display_consise(data):
result = set()
for rdeps in data.itervalues():
for rdep in rdeps:
result.add(rdep['Package'])
print u'\n'.join(sorted(list(result)))
2011-11-09 23:44:22 +02:00
2011-11-09 23:44:22 +02:00
if __name__ == '__main__':
main()