File: //proc/self/root/usr/bin/repoquery
#!/usr/bin/python -tt
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Library General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
# (c) pmatilai@laiskiainen.org
import sys
sys.path.insert(0, '/usr/share/yum-cli')
import signal
import re
import fnmatch
import time
import os
import os.path
import exceptions
from optparse import OptionParser
import logging
import yum
import yum.misc as misc
import yum.config
import yum.Errors
import yum.packages
from yum.i18n import to_unicode
from rpmUtils.arch import getArchList
from rpmUtils.miscutils import formatRequire
import output
from urlgrabber.progress import TextMeter
from urlgrabber.progress import format_number
version = "0.0.11"
flags = { 'EQ':'=', 'LT':'<', 'LE':'<=', 'GT':'>', 'GE':'>=', 'None':' '}
std_qf = {
'nvr': '%{name}-%{version}-%{release}',
'nevra': '%{name}-%{epoch}:%{version}-%{release}.%{arch}',
'envra': '%{epoch}:%{name}-%{version}-%{release}.%{arch}',
'source': '%{sourcerpm}',
'info': """
Name : %{name}
Version : %{version}
Release : %{release}
Architecture: %{arch}
Size : %{installedsize}
Packager : %{packager}
Group : %{group}
URL : %{url}
Repository : %{repoid}
Summary : %{summary}
Description :\n%{description}""",
}
querytags = [ 'name', 'version', 'release', 'epoch', 'arch', 'summary',
'description', 'packager', 'url', 'buildhost', 'sourcerpm',
'vendor', 'group', 'license', 'buildtime', 'filetime',
'installedsize', 'archivesize', 'packagesize', 'repoid',
'requires', 'provides', 'conflicts', 'obsoletes',
'relativepath', 'hdrstart', 'hdrend', 'id',
]
def sec2isodate(timestr):
return time.strftime("%F %T", time.gmtime(int(timestr)))
def sec2date(timestr):
return time.ctime(int(timestr))
def sec2day(timestr):
return time.strftime("%a %b %d %Y", time.gmtime(int(timestr)))
def _size2val(size, off, ui):
size = float(size)
off = 1024
if False: pass
elif size >= (off * 100):
return "%.0f%s" % ((size / off), ui)
elif size >= (off * 10):
return "%.1f%s" % ((size / off), ui)
return "%.2f%s" % ((size / off), ui)
def size2k(size):
return _size2val(size, 1024, " k")
def size2m(size):
return _size2val(size, 1024 * 1024, " M")
def size2g(size):
return _size2val(size, 1024 * 1024 * 1024, " G")
def size2t(size):
return _size2val(size, 1024 * 1024 * 1024 * 1024, " T")
def size2h(size):
return format_number(size)
convertmap = { 'date': sec2date,
'day': sec2day,
'isodate': sec2isodate,
'k': size2k,
'm': size2m,
'g': size2g,
'h': size2h,
}
class queryError(exceptions.Exception):
def __init__(self, msg):
exceptions.Exception.__init__(self)
self.msg = msg
# abstract class
class pkgQuery:
"""
My implementation of __getitem__ either forwards to an implementation
of fmt_(name), or to self.pkg.returnSimple(), allowing subclasses
to override the package's items.
@type pkg: L{yum.package.YumAvailablePackage}
@ivar qf: the query format for this package query
@type qf: str
"""
def __init__(self, pkg, qf):
self.pkg = pkg
self.qf = qf
self.name = pkg.name
self.classname = None
def __getitem__(self, item):
item = item.lower()
if hasattr(self, "fmt_%s" % item):
return getattr(self, "fmt_%s" % item)()
res = None
convert = None
tmp = item.split(':')
if len(tmp) > 1:
item = tmp[0]
conv = tmp[1]
if convertmap.has_key(conv):
convert = convertmap[conv]
else:
raise queryError("Invalid conversion: %s" % conv)
# this construct is the way it is because pkg.licenses isn't
# populated before calling pkg.returnSimple() ?!
try:
res = self.pkg.returnSimple(item)
except KeyError:
if item == "license":
res = ", ".join(self.pkg.licenses)
else:
raise queryError("Invalid querytag '%s' for %s" % (item, self.classname))
if convert:
res = convert(res)
return res
def __str__(self):
return self.fmt_queryformat()
def doQuery(self, method, *args, **kw):
if std_qf.has_key(method):
self.qf = std_qf[method]
return self.fmt_queryformat()
elif hasattr(self, "fmt_%s" % method):
return getattr(self, "fmt_%s" % method)(*args, **kw)
else:
raise queryError("Invalid package query: %s" % method)
def isSource(self):
return self["arch"] == "src"
def prco(self, what, **kw):
"""
Query for the provides/requires/conflicts/obsoletes of this package.
@param what: one of provides, requires, conflicts, obsoletes
@type what: str
@rtype: list of str
"""
# for subclasses to implement
raise NotImplementedError
def fmt_queryformat(self):
if not self.qf:
qf = std_qf["nevra"]
else:
qf = self.qf
qf = qf.replace("\\n", "\n")
qf = qf.replace("\\t", "\t")
pattern = re.compile('%([-\d]*?){([:\w]*?)}')
fmt = re.sub(pattern, r'%(\2)\1s', qf)
return fmt % self
def fmt_requires(self, **kw):
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'))
def fmt_obsoletes(self, **kw):
return "\n".join(self.prco('obsoletes'))
def fmt_list(self, **kw):
return "\n".join(self.files())
def fmt_evr(self, **kw):
return "%(epoch)s:%(version)s-%(release)s" % self
def fmt_nevr(self, **kw):
return "%(name)s-%(evr)s" % self
def fmt_envr(self, **kw):
return "%(epoch)s:%(name)s-%(version)s-%(release)s" % self
def fmt_nevra(self, **kw):
return "%(nevr)s.%(arch)s" % self
def fmt_envra(self, **kw):
return "%(envr)s.%(arch)s" % self
class repoPkgQuery(pkgQuery):
"""
I wrap a query of a non-installed package available in the repository.
"""
def __init__(self, pkg, qf):
pkgQuery.__init__(self, pkg, qf)
self.classname = 'repo pkg'
def prco(self, what, **kw):
rpdict = {}
for rptup in self.pkg.returnPrco(what):
(rpn, rpf, (rp,rpv,rpr)) = rptup
if rpn.startswith('rpmlib'):
continue
rpdict[misc.prco_tuple_to_string(rptup)] = None
rplist = rpdict.keys()
rplist.sort()
return rplist
def files(self, **kw):
fdict = {}
for ftype in self.pkg.returnFileTypes():
for file in self.pkg.returnFileEntries(ftype):
# workaround for yum returning double leading slashes on some
# directories - posix allows that but it looks a bit odd
fdict[os.path.normpath('//%s' % file)] = None
files = fdict.keys()
files.sort()
return files
def fmt_changelog(self, **kw):
changelog = []
for date, author, message in self.pkg.returnChangelog():
changelog.append("* %s %s\n%s\n" % (sec2day(date), author, message))
return "\n".join(changelog)
class instPkgQuery(pkgQuery):
"""
I wrap a query of an installed package
of type L{yum.packages.YumInstalledPackage}
"""
# hmm, thought there'd be more things in need of mapping to rpm names :)
tagmap = { 'installedsize': 'size',
}
def __init__(self, pkg, qf):
pkgQuery.__init__(self, pkg, qf)
self.classname = 'installed pkg'
def __getitem__(self, item):
if self.tagmap.has_key(item):
return self.pkg.tagByName(self.tagmap[item])
else:
return pkgQuery.__getitem__(self, item)
def prco(self, what, **kw):
prcodict = {}
# rpm names are without the trailing s :)
what = what[:-1]
names = self.pkg.tagByName('%sname' % what)
flags = self.pkg.tagByName('%sflags' % what)
ver = self.pkg.tagByName('%sversion' % what)
if names is not None:
for (n, f, v) in zip(names, flags, ver):
req = formatRequire(n, v, f)
# filter out rpmlib deps
if n.startswith('rpmlib'):
continue
prcodict[req] = None
prcolist = prcodict.keys()
prcolist.sort()
return prcolist
def files(self, **kw):
return self.pkg.tagByName('filenames')
def fmt_changelog(self, **kw):
changelog = []
times = self.pkg.tagByName('changelogtime')
names = self.pkg.tagByName('changelogname')
texts = self.pkg.tagByName('changelogtext')
if times is not None:
tmplst = zip(times, names, texts)
for date, author, message in zip(times, names, texts):
changelog.append("* %s %s\n%s\n" % (sec2day(date), author, message))
return "\n".join(changelog)
class groupQuery:
def __init__(self, group, grouppkgs="required"):
self.grouppkgs = grouppkgs
self.id = group.groupid
self.name = group.name
self.group = group
def doQuery(self, method, *args, **kw):
if hasattr(self, "fmt_%s" % method):
return "\n".join(getattr(self, "fmt_%s" % method)(*args, **kw))
else:
raise queryError("Invalid group query: %s" % method)
# XXX temporary hack to make --group -a query work
def fmt_queryformat(self):
return self.fmt_nevra()
def fmt_nevra(self):
return ["%s - %s" % (self.id, self.name)]
def fmt_list(self):
pkgs = []
for t in self.grouppkgs.split(','):
if t == "mandatory":
pkgs.extend(self.group.mandatory_packages)
elif t == "default":
pkgs.extend(self.group.default_packages)
elif t == "optional":
pkgs.extend(self.group.optional_packages)
elif t == "all":
pkgs.extend(self.group.packages)
else:
raise "Unknown group package type %s" % t
return pkgs
def fmt_requires(self):
return self.group.mandatory_packages
def fmt_info(self):
return ["%s:\n\n%s\n" % (self.name, self.group.description)]
class YumBaseQuery(yum.YumBase):
def __init__(self, pkgops = [], sackops = [], options = None):
"""
@type pkgops: list of str
@type sackops: list of str
@type options: L{optparse.Values}
"""
yum.YumBase.__init__(self)
self.logger = logging.getLogger("yum.verbose.repoquery")
self.options = options
self.pkgops = pkgops
self.sackops = sackops
def queryPkgFactory(self, pkgs):
"""
For each given package, create a query.
@type pkgs: list of L{yum.package.YumAvailablePackage}
@rtype: list of L{queryPkg}
"""
qf = self.options.queryformat or std_qf["nevra"]
qpkgs = []
for pkg in pkgs:
if isinstance(pkg, yum.packages.YumInstalledPackage):
qpkg = instPkgQuery(pkg, qf)
else:
qpkg = repoPkgQuery(pkg, qf)
qpkgs.append(qpkg)
return qpkgs
def returnByName(self, name):
"""
Given a name, return a list of package queries matching the name.
@type name: str
@rtype: list of L{queryPkg}
"""
pkgs = []
try:
exact, match, unmatch = yum.packages.parsePackages(self.returnPkgList(), [name], casematch=1)
pkgs = exact + match
except yum.Errors.PackageSackError, err:
self.logger.error(err)
return self.queryPkgFactory(pkgs)
def returnPkgList(self):
pkgs = []
if self.options.pkgnarrow == "repos":
# self.pkgSack is a yum.packageSack.MetaSack
if self.conf.showdupesfromrepos:
pkgs = self.pkgSack.returnPackages()
else:
pkgs = self.pkgSack.returnNewestByNameArch()
else:
what = self.options.pkgnarrow
ygh = self.doPackageLists(what)
if what == "all":
pkgs = ygh.available + ygh.installed
elif hasattr(ygh, what):
pkgs = getattr(ygh, what)
else:
self.logger.error("Unknown pkgnarrow method: %s" % what)
return pkgs
def returnPackagesByDepStr(self, depstring):
provider = []
try:
# XXX rhbz#246519, for some reason returnPackagesByDep() fails
# to find some root level directories while
# searchPackageProvides() does... use that for now
matches = yum.YumBase.searchPackageProvides(self, [str(depstring)])
provider = matches.keys()
# provider.extend(yum.YumBase.returnPackagesByDep(self, depstring))
except yum.Errors.YumBaseError, err:
self.logger.error("No package provides %s" % depstring)
return self.queryPkgFactory(provider)
def returnGroups(self):
grps = []
for group in self.comps.get_groups():
grp = groupQuery(group, grouppkgs = self.options.grouppkgs)
grps.append(grp)
return grps
def matchGroups(self, items):
grps = []
for grp in self.returnGroups():
for expr in items:
if grp.name == expr or fnmatch.fnmatch("%s" % grp.name, expr):
grps.append(grp)
elif grp.id == expr or fnmatch.fnmatch("%s" % grp.id, expr):
grps.append(grp)
return grps
def matchPkgs(self, items):
pkgs = []
notfound = {}
exact, match, unmatch = yum.packages.parsePackages(self.returnPkgList(),
items, casematch=1)
pkgs = exact + match
notfound = unmatch
return self.queryPkgFactory(pkgs)
def matchSrcPkgs(self, items):
srpms = []
for name in items:
for pkg in self.returnByName(name):
if pkg.isSource():
continue
src = pkg["sourcerpm"][:-4]
srpms.extend(self.returnByName(src))
return srpms
def runQuery(self, items):
if self.options.group:
pkgs = self.matchGroups(items)
else:
if self.options.srpm:
pkgs = self.matchSrcPkgs(items)
else:
pkgs = self.matchPkgs(items)
for pkg in pkgs:
for oper in self.pkgops:
try:
print to_unicode(pkg.doQuery(oper))
except queryError, e:
self.logger.error( e.msg)
for prco in items:
for oper in self.sackops:
try:
for p in self.doQuery(oper, prco): print to_unicode(p)
except queryError, e:
self.logger.error( e.msg)
def doQuery(self, method, *args, **kw):
return getattr(self, "fmt_%s" % method)(*args, **kw)
def fmt_groupmember(self, name, **kw):
grps = []
for group in self.comps.get_groups():
if name in group.packages:
grps.append(group.groupid)
return grps
def fmt_whatprovides(self, name, **kw):
return self.returnPackagesByDepStr(name)
def fmt_whatrequires(self, name, **kw):
pkgs = {}
done = [] # keep track of names we have already visited
def require_recursive(name):
if name in done:
return
done.append(name)
provs = [name]
if self.options.alldeps:
for pkg in self.returnByName(name):
provs.extend(pkg.prco("provides"))
provs.extend(pkg.files())
for prov in provs:
# Only look at the providing name, not the whole version. This
# might occasionally give some false positives but that's
# better than missing ones which it had previously
for pkg in self.pkgSack.searchRequires(prov.split()[0]):
pkgs[pkg.pkgtup] = pkg
if self.options.recursive:
require_recursive(pkg.name)
require_recursive(name)
return self.queryPkgFactory(pkgs.values())
def fmt_whatobsoletes(self, name, **kw):
pkgs = []
for pkg in self.pkgSack.searchObsoletes(name):
pkgs.append(pkg)
return self.queryPkgFactory(pkgs)
def fmt_whatconflicts(self, name, **kw):
pkgs = []
for pkg in self.pkgSack.searchConflicts(name):
pkgs.append(pkg)
return self.queryPkgFactory(pkgs)
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):
pkgs[res.name] = res
return pkgs.values()
def fmt_location(self, name):
loc = []
for pkg in self.returnByName(name):
repo = self.repos.getRepo(pkg['repoid'])
loc.append("%s/%s" % (repo.urls[0], pkg['relativepath']))
return loc
def main(args):
needfiles = 0
needother = 0
needgroup = 0
needsource = 0
signal.signal(signal.SIGPIPE, signal.SIG_DFL)
signal.signal(signal.SIGINT, signal.SIG_DFL)
parser = OptionParser(version = "Repoquery version %s" % version)
# query options
parser.add_option("-l", "--list", action="store_true",
help="list files in this package/group")
parser.add_option("-i", "--info", action="store_true",
help="list descriptive info from this package/group")
parser.add_option("-f", "--file", action="store_true",
help="query which package provides this file")
parser.add_option("--qf", "--queryformat", dest="queryformat",
help="specify a custom output format for queries")
parser.add_option("--groupmember", action="store_true",
help="list which group(s) this package belongs to")
# dummy for rpmq compatibility
parser.add_option("-q", "--query", action="store_true",
help="no-op for rpmquery compatibility")
parser.add_option("-a", "--all", action="store_true",
help="query all packages/groups")
parser.add_option("-R", "--requires", action="store_true",
help="list package dependencies")
parser.add_option("--provides", action="store_true",
help="list capabilities this package provides")
parser.add_option("--obsoletes", action="store_true",
help="list other packages obsoleted by this package")
parser.add_option("--conflicts", action="store_true",
help="list capabilities this package conflicts with")
parser.add_option("--changelog", action="store_true",
help="show changelog for this package")
parser.add_option("--location", action="store_true",
help="show download URL for this package")
parser.add_option("--nevra", action="store_true",
help="show name-epoch:version-release.architecture info of package")
parser.add_option("--envra", action="store_true",
help="show epoch:name-version-release.architecture info of package")
parser.add_option("--nvr", action="store_true",
help="show name, version, release info of package")
parser.add_option("-s", "--source", action="store_true",
help="show package source RPM name")
parser.add_option("--srpm", action="store_true",
help="operate on corresponding source RPM")
parser.add_option("--resolve", action="store_true",
help="resolve capabilities to originating package(s)")
parser.add_option("--alldeps", action="store_true",
help="check non-explicit dependencies (files and Provides:) as well")
parser.add_option("--recursive", action="store_true",
help="recursively query for packages (for whatrequires)")
parser.add_option("--whatprovides", action="store_true",
help="query what package(s) provide a capability")
parser.add_option("--whatrequires", action="store_true",
help="query what package(s) require a capability")
parser.add_option("--whatobsoletes", action="store_true",
help="query what package(s) obsolete a capability")
parser.add_option("--whatconflicts", action="store_true",
help="query what package(s) conflicts with a capability")
# group stuff
parser.add_option("-g", "--group", default=0, action="store_true",
help="query groups instead of packages")
parser.add_option("--grouppkgs", default="default",
help="filter which packages (all,optional etc) are shown from groups")
# other opts
parser.add_option("--archlist",
help="only query packages of certain architecture(s)")
parser.add_option("--pkgnarrow", default="repos",
help="limit query to installed / available / recent / updates / extras / available + installed / repository (default) packages")
parser.add_option("--show-duplicates", action="store_true",
dest="show_dupes",
help="show all versions of packages")
parser.add_option("--show-dupes", action="store_true",
help="show all versions of packages")
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",
help="specify repoids to query, can be specified multiple times (default is all enabled)")
parser.add_option("--disablerepo", action="append", dest="disablerepos",
help="specify repoids to disable, can be specified multiple times")
parser.add_option("--repofrompath", action="append",
help="specify repoid & paths of additional repositories - unique repoid and complete path required, can be specified multiple times. Example. --repofrompath=myrepo,/path/to/repo")
parser.add_option("--plugins", action="store_true", default=False,
help="enable yum plugin support")
parser.add_option("--quiet", action="store_true",
help="quiet (no output to stderr)", default=True)
parser.add_option("--verbose", action="store_false",
help="verbose output", dest="quiet")
parser.add_option("-C", "--cache", action="store_true",
help="run from cache only")
parser.add_option("--tempcache", action="store_true",
help="use private cache (default when used as non-root)")
parser.add_option("--querytags", action="store_true",
help="list available tags in queryformat queries")
parser.add_option("-c", dest="conffile", help="config file location")
(opts, regexs) = parser.parse_args()
if opts.querytags:
querytags.sort()
for tag in querytags:
print tag
sys.exit(0)
if len(regexs) < 1:
if opts.all:
regexs = ['*']
else:
parser.print_help()
sys.exit(1)
pkgops = []
sackops = []
archlist = None
if opts.info:
pkgops.append("info")
if opts.requires:
if opts.resolve:
sackops.append("requires")
else:
pkgops.append("requires")
if opts.provides:
pkgops.append("provides")
if opts.obsoletes:
pkgops.append("obsoletes")
if opts.conflicts:
pkgops.append("conflicts")
if opts.changelog:
needother = 1
pkgops.append("changelog")
if opts.list:
if not opts.group:
needfiles = 1
pkgops.append("list")
if opts.alldeps:
needfiles = 1
if opts.envra:
pkgops.append("envra")
if opts.nvr:
pkgops.append("nvr")
if opts.source:
pkgops.append("source")
if opts.srpm:
needsource = 1
if opts.whatrequires:
sackops.append("whatrequires")
if opts.whatprovides:
sackops.append("whatprovides")
if opts.whatobsoletes:
sackops.append("whatobsoletes")
if opts.whatconflicts:
sackops.append("whatconflicts")
if opts.file:
sackops.append("whatprovides")
if opts.location:
sackops.append("location")
if opts.groupmember:
sackops.append("groupmember")
needgroup = 1
if opts.group:
needgroup = 1
if opts.nevra or (len(pkgops) == 0 and len(sackops) == 0):
pkgops.append("queryformat")
repoq = YumBaseQuery(pkgops, sackops, opts)
# silence initialisation junk from modules etc unless verbose mode
initnoise = (not opts.quiet) * 2
if opts.conffile:
repoq.doConfigSetup(fn=opts.conffile, debuglevel=initnoise, init_plugins=opts.plugins)
else:
repoq.doConfigSetup(debuglevel=initnoise, init_plugins=opts.plugins)
if opts.repofrompath:
# setup the fake repos
for repo in opts.repofrompath:
repoid,repopath = tuple(repo.split(','))
if repopath[0] == '/':
baseurl = 'file://' + repopath
else:
baseurl = repopath
repopath = os.path.normpath(repopath)
newrepo = yum.yumRepo.YumRepository(repoid)
newrepo.name = repopath
newrepo.baseurl = baseurl
newrepo.basecachedir = repoq.conf.cachedir
newrepo.metadata_expire = 0
newrepo.timestamp_check = False
repoq.repos.add(newrepo)
repoq.repos.enableRepo(newrepo.id)
repoq.logger.info( "Added %s repo from %s" % (repoid,repopath))
# Show what is going on, if --quiet is not set.
if not opts.quiet and sys.stdout.isatty():
repoq.repos.setProgressBar(TextMeter(fo=sys.stdout))
repoq.repos.callback = output.CacheProgressCallback()
yumout = output.YumOutput()
freport = ( yumout.failureReport, (), {} )
repoq.repos.setFailureCallback( freport )
if os.geteuid() != 0 or opts.tempcache:
cachedir = misc.getCacheDir()
if cachedir is None:
repoq.logger.error("Error: Could not make cachedir, exiting")
sys.exit(50)
repoq.repos.setCacheDir(cachedir)
repoq.conf.cache = 0 # yum set cache=1, if uid != 0
if opts.cache:
repoq.conf.cache = True
if not opts.quiet:
repoq.logger.info('Running from cache, results might be incomplete.')
if opts.show_dupes:
repoq.conf.showdupesfromrepos = True
if opts.repoid:
for repo in repoq.repos.findRepos('*'):
if repo.id not in opts.repoid:
repo.disable()
else:
repo.enable()
if opts.disablerepos:
for repo_match in opts.disablerepos:
for repo in repoq.repos.findRepos(repo_match):
repo.disable()
if opts.enablerepos:
for repo_match in opts.enablerepos:
for repo in repoq.repos.findRepos(repo_match):
repo.enable()
try:
repoq.doRepoSetup()
except yum.Errors.RepoError, e:
repoq.logger.error("Could not setup repo: %s" % (e))
sys.exit(50)
for exp in regexs:
if exp.endswith('.src'):
needsource = 1
break
if opts.archlist:
archlist = opts.archlist.split(',')
elif needsource:
archlist = getArchList()
archlist.append('src')
try:
repoq.doSackSetup(archlist=archlist)
repoq.doTsSetup()
if needfiles:
repoq.repos.populateSack(mdtype='filelists')
if needother:
repoq.repos.populateSack(mdtype='otherdata')
if needgroup:
repoq.doGroupSetup()
except yum.Errors.RepoError, e:
repoq.logger.error( e)
sys.exit(1)
repoq.runQuery(regexs)
if __name__ == "__main__":
misc.setup_locale()
main(sys.argv)
# vim:sw=4:sts=4:expandtab