summaryrefslogtreecommitdiff
path: root/examples/pysolv
diff options
context:
space:
mode:
authorMichael Schroeder <mls@suse.de>2012-10-25 16:55:11 +0200
committerMichael Schroeder <mls@suse.de>2012-10-25 16:55:11 +0200
commit264d9fbb06f811ebb3ca9a8de1732715697cfead (patch)
treebd27a36d3ff57f31514b195d6273b2f6e80f55d6 /examples/pysolv
parent9db24cdc0b107e48f4bd9d66f2f0687fcf397480 (diff)
downloadlibsolv-264d9fbb06f811ebb3ca9a8de1732715697cfead.tar.gz
libsolv-264d9fbb06f811ebb3ca9a8de1732715697cfead.tar.bz2
libsolv-264d9fbb06f811ebb3ca9a8de1732715697cfead.zip
generalize matching code from examples/solv.c to src/selection.c
Adapt the examples to use the new mechanism. This is probably not the final version of the interface, so handle with care.
Diffstat (limited to 'examples/pysolv')
-rwxr-xr-xexamples/pysolv198
1 files changed, 52 insertions, 146 deletions
diff --git a/examples/pysolv b/examples/pysolv
index af86961..40e8c7f 100755
--- a/examples/pysolv
+++ b/examples/pysolv
@@ -38,7 +38,7 @@ import time
import subprocess
import rpm
from stat import *
-from solv import Pool, Repo, Dataiterator, Job, Solver, Transaction
+from solv import Pool, Repo, Dataiterator, Job, Solver, Transaction, Selection
from iniparse import INIConfig
from optparse import OptionParser
@@ -287,7 +287,7 @@ class repo_generic(dict):
def updateaddedprovides(self, addedprovides):
if 'incomplete' in self:
return
- if 'handle' not in self:
+ if not hasattr(self, 'handle'):
return
if self.handle.isempty():
return
@@ -562,141 +562,6 @@ class repo_cmdline(repo_generic):
self.handle.appdata = self
return True
-def validarch(pool, arch):
- if not arch:
- return False
- id = pool.str2id(arch, False)
- if not id:
- return False
- return pool.isknownarch(id)
-
-def limitjobs(pool, jobs, flags, evrstr):
- njobs = []
- evr = pool.str2id(evrstr)
- for j in jobs:
- how = j.how
- sel = how & Job.SOLVER_SELECTMASK
- what = pool.rel2id(j.what, evr, flags)
- if flags == solv.REL_ARCH:
- how |= Job.SOLVER_SETARCH
- elif flags == solv.REL_EQ and sel == Job.SOLVER_SOLVABLE_NAME:
- if evrstr.find('-') >= 0:
- how |= Job.SOLVER_SETEVR
- else:
- how |= Job.SOLVER_SETEV
- njobs.append(pool.Job(how, what))
- return njobs
-
-def limitjobs_evrarch(pool, jobs, flags, evrstr):
- m = re.match(r'(.+)\.(.+?)$', evrstr)
- if m and validarch(pool, m.group(2)):
- jobs = limitjobs(pool, jobs, solv.REL_ARCH, m.group(2))
- evrstr = m.group(1)
- return limitjobs(pool, jobs, flags, evrstr)
-
-def mkjobs_filelist(pool, cmd, arg):
- if re.search(r'[[*?]', arg):
- type = Dataiterator.SEARCH_GLOB
- else:
- type = Dataiterator.SEARCH_STRING
- if cmd == 'erase':
- di = pool.installed.Dataiterator(0, solv.SOLVABLE_FILELIST, arg, type | Dataiterator.SEARCH_FILES|Dataiterator.SEARCH_COMPLETE_FILELIST)
- else:
- di = pool.Dataiterator(0, solv.SOLVABLE_FILELIST, arg, type | Dataiterator.SEARCH_FILES|Dataiterator.SEARCH_COMPLETE_FILELIST)
- matches = []
- for d in di:
- s = d.solvable
- if s and s.installable():
- matches.append(s.id)
- di.skip_solvable() # one match is enough
- if matches:
- print "[using file list match for '%s']" % arg
- if len(matches) > 1:
- return [ pool.Job(Job.SOLVER_SOLVABLE_ONE_OF, pool.towhatprovides(matches)) ]
- else:
- return [ pool.Job(Job.SOLVER_SOLVABLE | Job.SOLVER_NOAUTOSET, matches[0]) ]
- return []
-
-def mkjobs_rel(pool, cmd, name, rel, evr):
- flags = 0
- if rel.find('<') >= 0: flags |= solv.REL_LT
- if rel.find('=') >= 0: flags |= solv.REL_EQ
- if rel.find('>') >= 0: flags |= solv.REL_GT
- jobs = depglob(pool, name, True, True)
- if jobs:
- return limitjobs(pool, jobs, flags, evr)
- m = re.match(r'(.+)\.(.+?)$', name)
- if m and validarch(pool, m.group(2)):
- jobs = depglob(pool, m.group(1), True, True)
- if jobs:
- jobs = limitjobs(pool, jobs, solv.REL_ARCH, m.group(2))
- return limitjobs(pool, jobs, flags, evr)
- return []
-
-def mkjobs_nevra(pool, cmd, arg):
- jobs = depglob(pool, arg, True, True)
- if jobs:
- return jobs
- m = re.match(r'(.+)\.(.+?)$', arg)
- if m and validarch(pool, m.group(2)):
- jobs = depglob(pool, m.group(1), True, True)
- if jobs:
- return limitjobs(pool, jobs, solv.REL_ARCH, m.group(2))
- m = re.match(r'(.+)-(.+?)$', arg)
- if m:
- jobs = depglob(pool, m.group(1), True, False)
- if jobs:
- return limitjobs_evrarch(pool, jobs, solv.REL_EQ, m.group(2))
- m = re.match(r'(.+)-(.+?-.+?)$', arg)
- if m:
- jobs = depglob(pool, m.group(1), True, False)
- if jobs:
- return limitjobs_evrarch(pool, jobs, solv.REL_EQ, m.group(2))
- return []
-
-def mkjobs(pool, cmd, arg):
- if len(arg) and arg[0] == '/':
- jobs = mkjobs_filelist(pool, cmd, arg)
- if jobs:
- return jobs
- m = re.match(r'(.+?)\s*([<=>]+)\s*(.+?)$', arg)
- if m:
- return mkjobs_rel(pool, cmd, m.group(1), m.group(2), m.group(3))
- else:
- return mkjobs_nevra(pool, cmd, arg)
-
-def depglob(pool, name, globname, globdep):
- id = pool.str2id(name, False)
- if id:
- match = False
- for s in pool.whatprovides(id):
- if globname and s.nameid == id:
- return [ pool.Job(Job.SOLVER_SOLVABLE_NAME, id) ]
- match = True
- if match:
- if globname and globdep:
- print "[using capability match for '%s']" % name
- return [ pool.Job(Job.SOLVER_SOLVABLE_PROVIDES, id) ]
- if not re.search(r'[[*?]', name):
- return []
- if globname:
- # try name glob
- idmatches = {}
- for d in pool.Dataiterator(0, solv.SOLVABLE_NAME, name, Dataiterator.SEARCH_GLOB):
- s = d.solvable
- if s.installable():
- idmatches[s.nameid] = True
- if idmatches:
- return [ pool.Job(Job.SOLVER_SOLVABLE_NAME, id) for id in sorted(idmatches.keys()) ]
- if globdep:
- # try dependency glob
- idmatches = pool.matchprovidingids(name, Dataiterator.SEARCH_GLOB)
- if idmatches:
- print "[using capability match for '%s']" % name
- return [ pool.Job(Job.SOLVER_SOLVABLE_PROVIDES, id) for id in sorted(idmatches) ]
- return []
-
-
def load_stub(repodata):
repo = repodata.repo.appdata
if repo:
@@ -705,6 +570,7 @@ def load_stub(repodata):
parser = OptionParser(usage="usage: solv.py [options] COMMAND")
+parser.add_option('-r', '--repo', action="append", type="string", dest="repos")
(options, args) = parser.parse_args()
if not args:
parser.print_help(sys.stderr)
@@ -726,6 +592,12 @@ if cmd == 'se':
# read all repo configs
repos = []
+reposdirs = []
+if os.path.isdir("/etc/zypp/repos.d"):
+ reposdirs = [ "/etc/zypp/repos.d" ]
+else:
+ reposdirs = [ "/etc/yum/repos.d" ]
+
for reposdir in ["/etc/zypp/repos.d"]:
if not os.path.isdir(reposdir):
continue
@@ -758,6 +630,19 @@ for repo in repos:
if int(repo['enabled']):
repo.load(pool)
+repolimiter = None
+if options.repos:
+ for reponame in options.repos:
+ mrepos = [ repo for repo in repos if repo.name == reponame ]
+ if not mrepos:
+ print "no repository matches '%s'" % reponame
+ sys.exit(1)
+ repo = mrepos[0]
+ if hasattr(repo, 'handle'):
+ if not repolimiter:
+ repolimiter = pool.Selection()
+ repolimiter.addsimple(Job.SOLVER_SOLVABLE_REPO, repo.handle.id)
+
if cmd == 'search':
matches = {}
di = pool.Dataiterator(0, solv.SOLVABLE_NAME, args[0], Dataiterator.SEARCH_SUBSTRING|Dataiterator.SEARCH_NOCASE)
@@ -793,11 +678,35 @@ for arg in args:
if cmdlinerepo and arg in cmdlinerepo['packages']:
jobs.append(pool.Job(Job.SOLVER_SOLVABLE, cmdlinerepo['packages'][arg]))
else:
- njobs = mkjobs(pool, cmd, arg)
- if not njobs:
- print "nothing matches '%s'" % arg
+ flags = Selection.SELECTION_NAME|Selection.SELECTION_PROVIDES|Selection.SELECTION_GLOB
+ if len(arg) and arg[0] == '/':
+ flags |= Selection.SELECTION_FILELIST
+ if cmd == 'erase':
+ flags |= Selection.SELECTION_INSTALLED_ONLY
+ sel = pool.select(arg, flags)
+ if repolimiter:
+ sel.limit(repolimiter)
+ if sel.isempty():
+ sel = pool.select(arg, flags | Selection.SELECTION_NOCASE)
+ if repolimiter:
+ sel.limit(repolimiter)
+ if not sel.isempty():
+ print "[ignoring case for '%s']" % arg
+ if sel.isempty():
+ print "nothing matches '%s'" % arg
sys.exit(1)
- jobs += njobs
+ if sel.flags() & Selection.SELECTION_FILELIST:
+ print "[using file list match for '%s']" % arg
+ if sel.flags() & Selection.SELECTION_PROVIDES:
+ print "[using capability match for '%s']" % arg
+ jobs += sel.jobs(0)
+
+if not jobs and (cmd == 'up' or cmd == 'dup' or cmd == 'verify' or repolimiter):
+ sel = pool.Selection()
+ sel.addsimple(Job.SOLVER_SOLVABLE_ALL, 0)
+ if repolimiter:
+ sel.limit(repolimiter)
+ jobs += sel.jobs(0)
if cmd == 'list' or cmd == 'info':
if not jobs:
@@ -824,11 +733,8 @@ if cmd == 'list' or cmd == 'info':
if cmd == 'install' or cmd == 'erase' or cmd == 'up' or cmd == 'dup' or cmd == 'verify':
if not jobs:
- if cmd == 'up' or cmd == 'verify' or cmd == 'dup':
- jobs = [ pool.Job(Job.SOLVER_SOLVABLE_ALL, 0) ]
- else:
- print "no package matched."
- sys.exit(1)
+ print "no package matched."
+ sys.exit(1)
for job in jobs:
if cmd == 'up':
# up magic: use install instead of update if no installed package matches