[yum-commits] repoquery.py
James Antill
james at osuosl.org
Mon Jan 24 05:00:27 UTC 2011
repoquery.py | 203 +++++++++++++++++++++++++++++++++++++++++++++++++++--------
1 file changed, 176 insertions(+), 27 deletions(-)
New commits:
commit 0f01a8c4a770d02b95e215541631ae9c06081f0f
Author: Pierre-Yves <pingou at pingoured.fr>
Date: Sat Jan 15 13:50:23 2011 +0100
Update arguments
- Remove --show-dupes from --help (while the argument still works)
- Remove --tree-* from --help (while the argument still works)
- Implement the --output[text|ascii-tree|dot-tree] (default to 'text') argument
- Implement the --level[all|any int] (default to 'all') argument
The combination of --requires --output=ascii-tree --level=all reproduce the behavior of --tree-requires
same goes for:
--whatrequires --output=ascii-tree vs --tree-whatrequires
--obsoletes --output=ascii-tree vs --tree-obsoletes
--conflicts --output=ascii-tree vs --tree-conflicts
Use the propagation of the dot object to determine if it is a tree or a dot tree
diff --git a/repoquery.py b/repoquery.py
index c14f296..be1fe86 100755
--- a/repoquery.py
+++ b/repoquery.py
@@ -29,6 +29,7 @@ import exceptions
import urlparse
from optparse import OptionParser
+from optparse import SUPPRESS_HELP
import logging
import yum
@@ -75,8 +76,6 @@ querytags = [ 'name', 'version', 'release', 'epoch', 'arch', 'summary',
'relativepath', 'hdrstart', 'hdrend', 'id',
]
-
-
def sec2isodate(timestr):
return time.strftime("%F %T", time.gmtime(int(timestr)))
@@ -126,6 +125,34 @@ class queryError(exceptions.Exception):
return '%s' % to_unicode(self.value)
+class DotPlot(object):
+ def __init__(self):
+
+ print 'digraph packages {',
+ print """
+size="20.69,25.52";
+ratio="fill";
+rankdir="TB";
+orientation=port;
+node[style="filled"];
+outputorder="edgesfirst";
+ranksep="1";
+"""
+
+ def addPackage(self, pkg, deps):
+ # color calculations lifted from rpmgraph
+ h=0.5+(0.6/23*len(deps))
+ s=h+0.1
+ b=1.0
+
+ print '"%s" [color="%s %s %s"];' % (pkg, h, s, b)
+ print '"%s" -> {' % pkg
+ for req in deps:
+ print '"%s"' % req
+ print '} [color="%s %s %s"];\n' % (h, s, b)
+
+ def __del__(self):
+ print "}"
# abstract class
class pkgQuery:
@@ -230,16 +257,31 @@ class pkgQuery:
return self._translated_qf[self.qf] % self
def fmt_requires(self, **kw):
- return "\n".join(self.prco('requires'))
+ if self.yb.options.output in ("ascii-tree", "dot-tree"):
+ self.fmt_tree_requires(output = self.yb.options.output,
+ tree_level = self.yb.options.tree_level,
+ dot = self.yb.options.dot)
+ else:
+ return "\n".join(self.prco('requires'))
def fmt_provides(self, **kw):
return "\n".join(self.prco('provides'))
def fmt_conflicts(self, **kw):
- return "\n".join(self.prco('conflicts'))
+ if self.yb.options.output in ("ascii-tree", "dot-tree"):
+ self.fmt_tree_conflicts(output = self.yb.options.output,
+ tree_level = self.yb.options.tree_level,
+ dot = self.yb.options.dot)
+ else:
+ return "\n".join(self.prco('conflicts'))
def fmt_obsoletes(self, **kw):
- return "\n".join(self.prco('obsoletes'))
+ if self.yb.options.output in ("ascii-tree", "dot-tree"):
+ self.fmt_tree_obsoletes(output = self.yb.options.output,
+ tree_level = self.yb.options.tree_level,
+ dot = self.yb.options.dot)
+ else:
+ return "\n".join(self.prco('obsoletes'))
def fmt_list(self, **kw):
return "\n".join(self.files())
@@ -317,6 +359,22 @@ class pkgQuery:
req = kw.get('req', 'cmd line')
level = kw.get('level', 0)
all_reqs = kw.get('all_reqs', {})
+
+ if kw['output'].lower() == 'dot-tree':
+ if 'dot' not in kw.keys() or kw['dot'] is None:
+ kw['dot'] = Dot()
+ elif 'dot' not in kw.keys() or kw['dot'] is None:
+ kw['dot'] = None
+
+ if str(kw['tree_level']).lower() != 'all':
+ try:
+ kw['tree_level'] = int(kw['tree_level'])
+ except ValueError, er:
+ kw['tree_level'] = 'all'
+
+ if not 'output' in kw.keys():
+ kw['output'] = 'ascii-tree'
+
__req2pkgs = {}
def req2pkgs(ignore, req):
req = str(req)
@@ -353,22 +411,37 @@ class pkgQuery:
return []
__req2pkgs[req] = providers
- return providers
-
- self._tree_print_req(pkg, req, level)
+ return providers
+
+ dot = kw['dot']
+
tups = getattr(pkg, prco_type)
rpkgs, loc_reqs = self._tree_maybe_add_pkgs(all_reqs, tups, req2pkgs)
+ if dot is None:
+ self._tree_print_req(pkg, req, level)
+ lim = level + 1
+ else:
+ dot.addPackage(pkg, rpkgs)
+ lim = level + 2
nlevel = level + 1
+ if str(kw['tree_level']).lower() != 'all' and \
+ int(kw['tree_level']) < int(lim):
+ return
for rpkg in sorted(rpkgs):
if pkg.verEQ(rpkg):
continue
if rpkgs[rpkg] is None:
req = self._tree_pkg2val(loc_reqs, rpkg)
- self._tree_print_req(rpkg, req, nlevel)
+ if dot is None:
+ self._tree_print_req(rpkg, req, nlevel)
continue
self._fmt_tree_prov(prco_type,
- pkg=rpkg, level=nlevel, all_reqs=all_reqs,
- req=self._tree_pkg2val(loc_reqs, rpkg))
+ pkg = rpkg, level = nlevel, all_reqs = all_reqs,
+ req = self._tree_pkg2val(loc_reqs, rpkg),
+ tree_level = kw['tree_level'],
+ output = kw['output'],
+ dot = dot)
+
def fmt_tree_requires(self, **kw):
return self._fmt_tree_prov('requires', **kw)
def fmt_tree_conflicts(self, **kw):
@@ -378,6 +451,22 @@ class pkgQuery:
pkg = kw.get('pkg', self.pkg)
level = kw.get('level', 0)
all_reqs = kw.get('all_reqs', {})
+
+ if kw['output'].lower() == 'dot-tree':
+ if 'dot' not in kw.keys() or kw['dot'] is None:
+ kw['dot'] = Dot()
+ elif 'dot' not in kw.keys() or kw['dot'] is None:
+ kw['dot'] = None
+
+ if str(kw['tree_level']).lower() != 'all':
+ try:
+ kw['tree_level'] = int(kw['tree_level'])
+ except ValueError, er:
+ kw['tree_level'] = 'all'
+
+ if not 'output' in kw.keys():
+ kw['output'] = 'ascii-tree'
+
def obs2pkgs():
if self.yb is None:
return []
@@ -400,26 +489,53 @@ class pkgQuery:
return obss
+ dot = kw['dot']
+
if level:
reason = ''
else:
reason = 'cmd line'
- self._tree_print_req(pkg, reason, level)
+ rpkgs = obs2pkgs()
+ if dot is None:
+ self._tree_print_req(pkg, reason, level)
+ lim = level + 1
+ else:
+ dot.addPackage(pkg, rpkgs)
+ lim = level + 2
all_reqs[pkg] = None
nlevel = level + 1
- for rpkg in sorted(obs2pkgs()):
+ if str(kw['tree_level']).lower() != 'all' and \
+ int(kw['tree_level']) < int(lim):
+ return
+ for rpkg in sorted(rpkgs):
if pkg.verEQ(rpkg):
continue
- if rpkg in all_reqs:
+ if rpkg in all_reqs and dot is None:
self._tree_print_req(rpkg, '', nlevel)
continue
- self.fmt_tree_obsoletes(pkg=rpkg, level=nlevel, all_reqs=all_reqs)
+ self.fmt_tree_obsoletes(pkg=rpkg, level=nlevel, all_reqs=all_reqs,
+ tree_level = kw['tree_level'],
+ output = kw['output'],
+ dot = dot)
def fmt_tree_what_requires(self, **kw):
pkg = kw.get('pkg', self.pkg)
req = kw.get('req', 'cmd line')
level = kw.get('level', 0)
all_reqs = kw.get('all_reqs', {})
+
+ if kw['output'].lower() == 'dot-tree':
+ if 'dot' not in kw.keys() or kw['dot'] is None:
+ kw['dot'] = Dot()
+
+ if str(kw['tree_level']).lower() != 'all':
+ try:
+ kw['tree_level'] = int(kw['tree_level'])
+ except ValueError, er:
+ kw['tree_level'] = 'all'
+
+ if not 'output' in kw.keys():
+ kw['output'] = 'ascii-tree'
__prov2pkgs = {}
def prov2pkgs(prov, ignore):
@@ -453,24 +569,39 @@ class pkgQuery:
__prov2pkgs[str(prov)] = arequirers + irequirers
return arequirers + irequirers
- self._tree_print_req(pkg, req, level)
filetupes = []
for n in pkg.filelist + pkg.dirlist + pkg.ghostlist:
filetupes.append((n, None, (None, None, None)))
-
+
tups = pkg.provides + filetupes
rpkgs, loc_reqs = self._tree_maybe_add_pkgs(all_reqs, tups, prov2pkgs)
+ dot = kw['dot']
+
+ if dot is None:
+ self._tree_print_req(pkg, req, level)
+ lim = level + 1
+ else:
+ dot.addPackage(pkg, rpkgs)
+ lim = level + 2
nlevel = level + 1
+
+ if str(kw['tree_level']).lower() != 'all' and \
+ int(kw['tree_level']) < int(lim):
+ return
for rpkg in sorted(rpkgs):
if pkg.verEQ(rpkg): # Remove deps. on self.
continue
if rpkgs[rpkg] is None:
req = self._tree_pkg2val(loc_reqs, rpkg)
- self._tree_print_req(rpkg, req, nlevel)
+ if dot is None:
+ self._tree_print_req(rpkg, req, nlevel)
continue
self.fmt_tree_what_requires(pkg=rpkg,
level=nlevel, all_reqs=all_reqs,
- req=self._tree_pkg2val(loc_reqs, rpkg))
+ req=self._tree_pkg2val(loc_reqs, rpkg),
+ tree_level = kw['tree_level'],
+ output = kw['output'],
+ dot = dot)
class repoPkgQuery(pkgQuery):
@@ -837,7 +968,10 @@ class YumBaseQuery(yum.YumBase):
print to_unicode(pkg)
for oper in self.pkgops:
try:
- out = pkg.doQuery(oper)
+ out = pkg.doQuery(oper,
+ tree_level = self.options.tree_level,
+ output = self.options.output,
+ dot = self.options.dot)
if out:
print to_unicode(out)
except queryError, e:
@@ -881,7 +1015,9 @@ class YumBaseQuery(yum.YumBase):
require_recursive(pkg.name)
- require_recursive(name)
+
+ if self.options.output not in ('ascii-tree','dot-tree'):
+ require_recursive(name)
return self.queryPkgFactory(sorted(pkgs.values()))
def fmt_whatobsoletes(self, name, **kw):
@@ -902,7 +1038,6 @@ class YumBaseQuery(yum.YumBase):
def fmt_requires(self, name, **kw):
pkgs = {}
-
for pkg in self.returnByName(name):
for req in pkg.prco("requires"):
for res in self.fmt_whatprovides(req):
@@ -1002,7 +1137,7 @@ def main(args):
dest="show_dupes",
help="show all versions of packages")
parser.add_option("--show-dupes", action="store_true",
- help="show all versions of packages")
+ help=SUPPRESS_HELP)
parser.add_option("--repoid", action="append",
help="specify repoids to query, can be specified multiple times (default is all enabled)")
parser.add_option("--enablerepo", action="append", dest="enablerepos",
@@ -1027,16 +1162,20 @@ def main(args):
help="config file location")
parser.add_option("--tree-requires", action="store_true",
dest="tree_requires",
- help="list recursive requirements, in tree form")
+ help=SUPPRESS_HELP)
parser.add_option("--tree-conflicts", action="store_true",
dest="tree_conflicts",
- help="list recursive conflicts, in tree form")
+ help=SUPPRESS_HELP)
parser.add_option("--tree-obsoletes", action="store_true",
dest="tree_obsoletes",
- help="list recursive obsoletes, in tree form")
+ help=SUPPRESS_HELP)
parser.add_option("--tree-whatrequires", action="store_true",
dest="tree_what_requires",
- help="list recursive what requires, in tree form")
+ help=SUPPRESS_HELP)
+ parser.add_option("--level", dest="tree_level", default="all",
+ help="levels to display (can be any number of 'all', default to 'all')")
+ parser.add_option("--output", dest="output", default="text",
+ help="output format to use (can be text|ascii-tree|dot-tree, default to 'text')")
parser.add_option("--search", action="store_true",
dest="search", default=False,
help="Use yum's search to return pkgs")
@@ -1088,17 +1227,27 @@ def main(args):
if opts.source:
pkgops.append("source")
if opts.tree_requires:
+ opts.output = "ascii-tree"
pkgops.append("tree_requires")
if opts.tree_conflicts:
+ opts.output = "ascii-tree"
pkgops.append("tree_conflicts")
if opts.tree_obsoletes:
+ opts.output = "ascii-tree"
pkgops.append("tree_obsoletes")
if opts.tree_what_requires:
+ opts.output = "ascii-tree"
pkgops.append("tree_what_requires")
+ if opts.output == "dot-tree":
+ opts.dot = DotPlot()
+ else:
+ opts.dot = None
if opts.srpm:
needsource = 1
if opts.whatrequires:
sackops.append("whatrequires")
+ if opts.output != 'text':
+ pkgops.append("tree_what_requires")
if opts.whatprovides:
sackops.append("whatprovides")
if opts.whatobsoletes:
More information about the Yum-commits
mailing list