Merge lp:~paul-eggleton/smart/yocto-smart-fixes into lp:smart

Proposed by Paul-eggleton
Status: Needs review
Proposed branch: lp:~paul-eggleton/smart/yocto-smart-fixes
Merge into: lp:smart
Diff against target: 1794 lines (+730/-71)
26 files modified
smart/backends/rpm/base.py (+36/-7)
smart/backends/rpm/header.py (+12/-5)
smart/backends/rpm/metadata.py (+21/-8)
smart/backends/rpm/pm.py (+17/-0)
smart/cache.py (+72/-3)
smart/ccache.c (+355/-24)
smart/channels/rpm_sys.py (+4/-4)
smart/commands/channel.py (+15/-2)
smart/commands/check.py (+3/-0)
smart/commands/config.py (+10/-1)
smart/commands/download.py (+8/-0)
smart/commands/flag.py (+4/-1)
smart/commands/info.py (+4/-0)
smart/commands/install.py (+4/-0)
smart/commands/mirror.py (+4/-1)
smart/commands/priority.py (+4/-1)
smart/commands/query.py (+51/-0)
smart/commands/reinstall.py (+5/-1)
smart/commands/remove.py (+4/-0)
smart/commands/search.py (+2/-0)
smart/commands/upgrade.py (+3/-0)
smart/control.py (+2/-2)
smart/plugins/detectsys.py (+2/-1)
smart/searcher.py (+11/-3)
smart/transaction.py (+21/-7)
smart/util/optparse.py (+56/-0)
To merge this branch: bzr merge lp:~paul-eggleton/smart/yocto-smart-fixes
Reviewer Review Type Date Requested Status
Smart Package Manager Team Pending
Review via email: mp+147946@code.launchpad.net

Description of the change

Included are most of the patches for Smart developed within the Yocto Project and being carried in OE-core which are now being carried in OpenEmbedded-Core. Each patch has a commit message explaining what it does; if further clarification or adjustments are needed please let me know.

To post a comment you must log in.

Unmerged revisions

1096. By Paul-eggleton

Print a more friendly error if YAML output is requested without PyYAML

Signed-off-by: Paul Eggleton <email address hidden>

1095. By Bogdan Marinescu <email address hidden>

To fix some multilib issues, change the way the RPM backend decides
if two packages can coexist: if they have a different architecture,
automatically assume that they can coexist (which is fundamental for
multilib).

Signed-off-by: Bogdan Marinescu <email address hidden>

1094. By Bogdan Marinescu <email address hidden>

Improve error reporting in smart

Add code to check proper command line arguments for various
smart commands. Exit with error if erroneous/additional arguments
are given in the command line.

Signed-off-by: Bogdan Marinescu <email address hidden>

1093. By Mark Hatle <email address hidden>

backends/rpm: Fix incorrect call to the match function

The match function should take three parameters, name, comparison, version...
The original code was passing it a reference to the object holding the data
instead, which caused the comparison in match to always fail.

Signed-off-by: Mark Hatle <email address hidden>

1092. By Paul-eggleton

backends/rpm: remove creation of /var/tmp

This doesn't appear to be needed, and breaks installation of base-files
in OpenEmbedded (since that is a symlink installed as part of the
package).

Signed-off-by: Paul Eggleton <email address hidden>

1091. By Paul-eggleton

backends/rpm: fix parsing of rpm-md metadata

If assertions are disabled then the queue.pop() wasn't being executed,
leading to requires, recommends etc. not being read properly.

Signed-off-by: Paul Eggleton <email address hidden>

1090. By Paul-eggleton

backends/rpm: add support for setting dependency flags

This is useful for OpenEmbedded so that we can do the equivalent of
the --nolinktos and --noparentdirs rpm command line options.

Signed-off-by: Paul Eggleton <email address hidden>

1089. By Paul-eggleton

backends/rpm: implement rpm-extra-macros option

Allow defining extra macros in the smart configuration to be passed
to rpm before opening the database.

Signed-off-by: Paul Eggleton <email address hidden>

1088. By Paul-eggleton

Handle recommended packages in core and rpm backends

Identify and store recommended packages in the cache, add a query option
to read them and ignore them if they are not present when installing.

Initial identification code from Mark Hatle <email address hidden>.

Signed-off-by: Paul Eggleton <email address hidden>

1087. By Paul-eggleton

Fix smart RPM backend to handle rpm-dbpath/rpm-root properly

Don't assume that if the dbpath starts with / that it is an absolute
path. This matches the behaviour of rpm itself. (If the root path is
specified and does not start with /, rpm will prepend the root path
twice and fail).

Signed-off-by: Paul Eggleton <email address hidden>

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'smart/backends/rpm/base.py'
--- smart/backends/rpm/base.py 2011-10-06 07:10:20 +0000
+++ smart/backends/rpm/base.py 2013-02-12 14:46:20 +0000
@@ -46,7 +46,17 @@
46 "rpm", "getTS", "getArchScore", "getArchColor", "system_provides",46 "rpm", "getTS", "getArchScore", "getArchColor", "system_provides",
47 "collapse_libc_requires"]47 "collapse_libc_requires"]
4848
49def rpm_join_dbpath(root, dbpath):
50 if dbpath.startswith('/') and root:
51 return os.path.join(root, dbpath[1:])
52 else:
53 return os.path.join(root, dbpath)
54
49def getTS(new=False):55def getTS(new=False):
56 if sysconf.get("rpm-extra-macros"):
57 for key, value in sysconf.get("rpm-extra-macros").items():
58 rpm.addMacro(key, str(value))
59
50 rpm_root = os.path.abspath(sysconf.get("rpm-root", "/"))60 rpm_root = os.path.abspath(sysconf.get("rpm-root", "/"))
51 if not hasattr(getTS, "ts") or getTS.root != rpm_root:61 if not hasattr(getTS, "ts") or getTS.root != rpm_root:
52 getTS.root = rpm_root62 getTS.root = rpm_root
@@ -56,7 +66,7 @@
56 if not sysconf.get("rpm-check-signatures", False):66 if not sysconf.get("rpm-check-signatures", False):
57 getTS.ts.setVSFlags(rpm._RPMVSF_NOSIGNATURES)67 getTS.ts.setVSFlags(rpm._RPMVSF_NOSIGNATURES)
58 rpm_dbpath = sysconf.get("rpm-dbpath", "var/lib/rpm")68 rpm_dbpath = sysconf.get("rpm-dbpath", "var/lib/rpm")
59 dbdir = os.path.join(getTS.root, rpm_dbpath)69 dbdir = rpm_join_dbpath(getTS.root, rpm_dbpath)
60 if not os.path.isdir(dbdir):70 if not os.path.isdir(dbdir):
61 try:71 try:
62 os.makedirs(dbdir)72 os.makedirs(dbdir)
@@ -72,12 +82,6 @@
72 else:82 else:
73 iface.warning(_("Initialized new rpm database at %s")83 iface.warning(_("Initialized new rpm database at %s")
74 % getTS.root)84 % getTS.root)
75 tmpdir = os.path.join(getTS.root, "var/tmp")
76 if not os.path.isdir(tmpdir):
77 try:
78 os.makedirs(tmpdir)
79 except OSError:
80 pass
81 if new:85 if new:
82 if sysconf.get("rpm-dbpath"):86 if sysconf.get("rpm-dbpath"):
83 rpm.addMacro('_dbpath', "/" + sysconf.get("rpm-dbpath"))87 rpm.addMacro('_dbpath', "/" + sysconf.get("rpm-dbpath"))
@@ -192,6 +196,29 @@
192 break196 break
193 else:197 else:
194 return False198 return False
199 srecs = fk(self.recommends)
200 orecs = fk(other.recommends)
201 if srecs != orecs:
202 for srec in srecs:
203 if srec.name[0] == "/" or srec in orecs:
204 continue
205 for orec in orecs:
206 if (srec.name == orec.name and
207 srec.relation == orec.relation and
208 checkver(srec.version, orec.version)):
209 break
210 else:
211 return False
212 for orec in orecs:
213 if orec.name[0] == "/" or orec in srecs:
214 continue
215 for srec in srecs:
216 if (srec.name == orec.name and
217 srec.relation == orec.relation and
218 checkver(srec.version, orec.version)):
219 break
220 else:
221 return False
195 return True222 return True
196223
197 def coexists(self, other):224 def coexists(self, other):
@@ -201,6 +228,8 @@
201 return False228 return False
202 selfver, selfarch = splitarch(self.version)229 selfver, selfarch = splitarch(self.version)
203 otherver, otherarch = splitarch(other.version)230 otherver, otherarch = splitarch(other.version)
231 if selfarch != otherarch:
232 return True
204 selfcolor = getArchColor(selfarch)233 selfcolor = getArchColor(selfarch)
205 othercolor = getArchColor(otherarch)234 othercolor = getArchColor(otherarch)
206 if (selfcolor and othercolor and selfcolor != othercolor and235 if (selfcolor and othercolor and selfcolor != othercolor and
207236
=== modified file 'smart/backends/rpm/header.py'
--- smart/backends/rpm/header.py 2011-10-05 15:09:41 +0000
+++ smart/backends/rpm/header.py 2013-02-12 14:46:20 +0000
@@ -292,6 +292,7 @@
292 f = [0]292 f = [0]
293 elif type(f) != list:293 elif type(f) != list:
294 f = [f]294 f = [f]
295 recdict = {}
295 reqdict = {}296 reqdict = {}
296 for i in range(len(n)):297 for i in range(len(n)):
297 ni = n[i]298 ni = n[i]
@@ -308,10 +309,16 @@
308 # RPMSENSE_SCRIPT_PREUN |309 # RPMSENSE_SCRIPT_PREUN |
309 # RPMSENSE_SCRIPT_POST |310 # RPMSENSE_SCRIPT_POST |
310 # RPMSENSE_SCRIPT_POSTUN == 7744311 # RPMSENSE_SCRIPT_POSTUN == 7744
311 reqdict[(f[i]&7744 and PreReq or Req,312 if (f[i]&rpm.RPMSENSE_MISSINGOK):
312 intern(ni), r, vi)] = True313 recdict[(f[i]&7744 and PreReq or Req,
314 intern(ni), r, vi)] = True
315 else:
316 reqdict[(f[i]&7744 and PreReq or Req,
317 intern(ni), r, vi)] = True
318 recargs = collapse_libc_requires(recdict.keys())
313 reqargs = collapse_libc_requires(reqdict.keys())319 reqargs = collapse_libc_requires(reqdict.keys())
314 else:320 else:
321 recargs = None
315 reqargs = None322 reqargs = None
316323
317 n = h[1054] # RPMTAG_CONFLICTNAME324 n = h[1054] # RPMTAG_CONFLICTNAME
@@ -365,7 +372,7 @@
365 versionarch = "%s@%s" % (distversion, arch)372 versionarch = "%s@%s" % (distversion, arch)
366373
367 pkg = self.buildPackage((Pkg, name, versionarch),374 pkg = self.buildPackage((Pkg, name, versionarch),
368 prvargs, reqargs, upgargs, cnfargs)375 prvargs, reqargs, upgargs, cnfargs, recargs)
369 pkg.loaders[self] = offset376 pkg.loaders[self] = offset
370 self._offsets[offset] = pkg377 self._offsets[offset] = pkg
371 self._groups[pkg] = intern(h[rpm.RPMTAG_GROUP])378 self._groups[pkg] = intern(h[rpm.RPMTAG_GROUP])
@@ -583,8 +590,8 @@
583 def setErrataFlags(self, flagdict):590 def setErrataFlags(self, flagdict):
584 self._flagdict = flagdict591 self._flagdict = flagdict
585 592
586 def buildPackage(self, pkgargs, prvargs, reqargs, upgargs, cnfargs):593 def buildPackage(self, pkgargs, prvargs, reqargs, upgargs, cnfargs, recargs):
587 pkg = Loader.buildPackage(self, pkgargs, prvargs, reqargs, upgargs, cnfargs)594 pkg = Loader.buildPackage(self, pkgargs, prvargs, reqargs, upgargs, cnfargs, recargs)
588 name = pkgargs[1]595 name = pkgargs[1]
589 if hasattr(self, '_flagdict') and self._flagdict and name in self._flagdict:596 if hasattr(self, '_flagdict') and self._flagdict and name in self._flagdict:
590 if sysconf.getReadOnly():597 if sysconf.getReadOnly():
591598
=== modified file 'smart/backends/rpm/metadata.py'
--- smart/backends/rpm/metadata.py 2011-10-05 15:09:41 +0000
+++ smart/backends/rpm/metadata.py 2013-02-12 14:46:20 +0000
@@ -165,6 +165,7 @@
165 distepoch = None165 distepoch = None
166 info = {}166 info = {}
167 reqdict = {}167 reqdict = {}
168 recdict = {}
168 prvdict = {}169 prvdict = {}
169 upgdict = {}170 upgdict = {}
170 cnfdict = {}171 cnfdict = {}
@@ -188,7 +189,8 @@
188189
189 elif event == "end":190 elif event == "end":
190191
191 assert queue.pop() is elem192 popped = queue.pop()
193 assert popped is elem
192194
193 if skip:195 if skip:
194 if tag == skip:196 if tag == skip:
@@ -287,12 +289,16 @@
287289
288 lasttag = queue[-1].tag290 lasttag = queue[-1].tag
289 if lasttag == REQUIRES:291 if lasttag == REQUIRES:
290 if elem.get("pre") == "1":292 if elem.get("missingok") == "1":
291 reqdict[(RPMPreRequires,293 recdict[(RPMRequires,
292 ename, erelation, eversion)] = True294 ename, erelation, eversion)] = True
293 else:295 else:
294 reqdict[(RPMRequires,296 if elem.get("pre") == "1":
295 ename, erelation, eversion)] = True297 reqdict[(RPMPreRequires,
298 ename, erelation, eversion)] = True
299 else:
300 reqdict[(RPMRequires,
301 ename, erelation, eversion)] = True
296302
297 elif lasttag == PROVIDES:303 elif lasttag == PROVIDES:
298 if ename[0] == "/":304 if ename[0] == "/":
@@ -326,8 +332,14 @@
326 reqargs = [x for x in reqdict332 reqargs = [x for x in reqdict
327 if not ((x[2] is None or "=" in x[2]) and333 if not ((x[2] is None or "=" in x[2]) and
328 (RPMProvides, x[1], x[3]) in prvdict or334 (RPMProvides, x[1], x[3]) in prvdict or
329 system_provides.match(*x[:3]))]335 system_provides.match(x[1], x[2], x[3]))]
330 reqargs = collapse_libc_requires(reqargs)336 reqargs = collapse_libc_requires(reqargs)
337
338 recargs = [x for x in recdict
339 if not ((x[2] is None or "=" in x[2]) and
340 (RPMProvides, x[1], x[3]) in prvdict or
341 system_provides.match(x[1], x[2], x[3]))]
342
331 prvargs = prvdict.keys()343 prvargs = prvdict.keys()
332 cnfargs = cnfdict.keys()344 cnfargs = cnfdict.keys()
333 upgargs = upgdict.keys()345 upgargs = upgdict.keys()
@@ -339,7 +351,7 @@
339 versionarch = "%s@%s" % (distversion, arch)351 versionarch = "%s@%s" % (distversion, arch)
340352
341 pkg = self.buildPackage((RPMPackage, name, versionarch),353 pkg = self.buildPackage((RPMPackage, name, versionarch),
342 prvargs, reqargs, upgargs, cnfargs)354 prvargs, reqargs, upgargs, cnfargs, recargs)
343 pkg.loaders[self] = info355 pkg.loaders[self] = info
344356
345 # Store the provided files for future usage.357 # Store the provided files for future usage.
@@ -362,6 +374,7 @@
362 distepoch = None374 distepoch = None
363 pkgid = None375 pkgid = None
364 reqdict.clear()376 reqdict.clear()
377 recdict.clear()
365 prvdict.clear()378 prvdict.clear()
366 upgdict.clear()379 upgdict.clear()
367 cnfdict.clear()380 cnfdict.clear()
368381
=== modified file 'smart/backends/rpm/pm.py'
--- smart/backends/rpm/pm.py 2010-12-17 11:26:28 +0000
+++ smart/backends/rpm/pm.py 2013-02-12 14:46:20 +0000
@@ -106,6 +106,23 @@
106 flags |= rpm.RPMTRANS_FLAG_TEST106 flags |= rpm.RPMTRANS_FLAG_TEST
107 ts.setFlags(flags)107 ts.setFlags(flags)
108108
109 dflags = ts.setDFlags(0)
110 if sysconf.get("rpm-noupgrade", False):
111 dflags |= rpm.RPMDEPS_FLAG_NOUPGRADE
112 if sysconf.get("rpm-norequires", False):
113 dflags |= rpm.RPMDEPS_FLAG_NOREQUIRES
114 if sysconf.get("rpm-noconflicts", False):
115 dflags |= rpm.RPMDEPS_FLAG_NOCONFLICTS
116 if sysconf.get("rpm-noobsoletes", False):
117 dflags |= rpm.RPMDEPS_FLAG_NOOBSOLETES
118 if sysconf.get("rpm-noparentdirs", False):
119 dflags |= rpm.RPMDEPS_FLAG_NOPARENTDIRS
120 if sysconf.get("rpm-nolinktos", False):
121 dflags |= rpm.RPMDEPS_FLAG_NOLINKTOS
122 if sysconf.get("rpm-nosuggest", False):
123 dflags |= rpm.RPMDEPS_FLAG_NOSUGGEST
124 ts.setDFlags(dflags)
125
109 # Set rpm verbosity level.126 # Set rpm verbosity level.
110 levelname = sysconf.get('rpm-log-level')127 levelname = sysconf.get('rpm-log-level')
111 level = {128 level = {
112129
=== modified file 'smart/cache.py'
--- smart/cache.py 2010-08-24 08:15:35 +0000
+++ smart/cache.py 2013-02-12 14:46:20 +0000
@@ -32,7 +32,8 @@
32 self.name = name32 self.name = name
33 self.version = version33 self.version = version
34 self.provides = ()34 self.provides = ()
35 self.requires = ()35 self.requires = []
36 self.recommends = []
36 self.upgrades = ()37 self.upgrades = ()
37 self.conflicts = ()38 self.conflicts = ()
38 self.installed = False39 self.installed = False
@@ -55,7 +56,9 @@
55 fk([x for x in self.provides if x.name[0] != "/"]) !=56 fk([x for x in self.provides if x.name[0] != "/"]) !=
56 fk([x for x in other.provides if x.name[0] != "/"]) or57 fk([x for x in other.provides if x.name[0] != "/"]) or
57 fk([x for x in self.requires if x.name[0] != "/"]) !=58 fk([x for x in self.requires if x.name[0] != "/"]) !=
58 fk([x for x in other.requires if x.name[0] != "/"])):59 fk([x for x in other.requires if x.name[0] != "/"]) or
60 fk([x for x in self.recommends if x.name[0] != "/"]) !=
61 fk([x for x in other.recommends if x.name[0] != "/"])):
59 return False62 return False
60 return True63 return True
6164
@@ -110,6 +113,7 @@
110 self.version,113 self.version,
111 self.provides,114 self.provides,
112 self.requires,115 self.requires,
116 self.recommends,
113 self.upgrades,117 self.upgrades,
114 self.conflicts,118 self.conflicts,
115 self.installed,119 self.installed,
@@ -122,6 +126,7 @@
122 self.version,126 self.version,
123 self.provides,127 self.provides,
124 self.requires,128 self.requires,
129 self.recommends,
125 self.upgrades,130 self.upgrades,
126 self.conflicts,131 self.conflicts,
127 self.installed,132 self.installed,
@@ -274,6 +279,7 @@
274 self.version = version279 self.version = version
275 self.packages = []280 self.packages = []
276 self.requiredby = ()281 self.requiredby = ()
282 self.recommendedby = ()
277 self.upgradedby = ()283 self.upgradedby = ()
278 self.conflictedby = ()284 self.conflictedby = ()
279285
@@ -401,7 +407,7 @@
401 def loadFileProvides(self, fndict):407 def loadFileProvides(self, fndict):
402 pass408 pass
403409
404 def buildPackage(self, pkgargs, prvargs, reqargs, upgargs, cnfargs):410 def buildPackage(self, pkgargs, prvargs, reqargs, upgargs, cnfargs, recargs = None):
405 cache = self._cache411 cache = self._cache
406 pkg = pkgargs[0](*pkgargs[1:])412 pkg = pkgargs[0](*pkgargs[1:])
407 relpkgs = []413 relpkgs = []
@@ -427,6 +433,17 @@
427 relpkgs.append(req.packages)433 relpkgs.append(req.packages)
428 pkg.requires.append(req)434 pkg.requires.append(req)
429435
436 if recargs:
437 pkg.recommends = []
438 for args in recargs:
439 rec = cache._objmap.get(args)
440 if not rec:
441 rec = args[0](*args[1:])
442 cache._objmap[args] = rec
443 cache._recommends.append(rec)
444 relpkgs.append(rec.packages)
445 pkg.recommends.append(rec)
446
430 if upgargs:447 if upgargs:
431 pkg.upgrades = []448 pkg.upgrades = []
432 for args in upgargs:449 for args in upgargs:
@@ -572,6 +589,7 @@
572 self._packages = []589 self._packages = []
573 self._provides = []590 self._provides = []
574 self._requires = []591 self._requires = []
592 self._recommends = []
575 self._upgrades = []593 self._upgrades = []
576 self._conflicts = []594 self._conflicts = []
577 self._objmap = {}595 self._objmap = {}
@@ -581,6 +599,8 @@
581 del prv.packages[:]599 del prv.packages[:]
582 if prv.requiredby:600 if prv.requiredby:
583 del prv.requiredby[:]601 del prv.requiredby[:]
602 if prv.recommendedby:
603 del prv.recommendedby[:]
584 if prv.upgradedby:604 if prv.upgradedby:
585 del prv.upgradedby[:]605 del prv.upgradedby[:]
586 if prv.conflictedby:606 if prv.conflictedby:
@@ -589,6 +609,10 @@
589 del req.packages[:]609 del req.packages[:]
590 if req.providedby:610 if req.providedby:
591 del req.providedby[:]611 del req.providedby[:]
612 for rec in self._recommends:
613 del rec.packages[:]
614 if rec.providedby:
615 del rec.providedby[:]
592 for upg in self._upgrades:616 for upg in self._upgrades:
593 del upg.packages[:]617 del upg.packages[:]
594 if upg.providedby:618 if upg.providedby:
@@ -600,6 +624,7 @@
600 del self._packages[:]624 del self._packages[:]
601 del self._provides[:]625 del self._provides[:]
602 del self._requires[:]626 del self._requires[:]
627 del self._recommends[:]
603 del self._upgrades[:]628 del self._upgrades[:]
604 del self._conflicts[:]629 del self._conflicts[:]
605 self._objmap.clear()630 self._objmap.clear()
@@ -621,6 +646,7 @@
621 packages = {}646 packages = {}
622 provides = {}647 provides = {}
623 requires = {}648 requires = {}
649 recommends = {}
624 upgrades = {}650 upgrades = {}
625 conflicts = {}651 conflicts = {}
626 objmap = self._objmap652 objmap = self._objmap
@@ -646,6 +672,11 @@
646 if req not in requires:672 if req not in requires:
647 objmap[req.getInitArgs()] = req673 objmap[req.getInitArgs()] = req
648 requires[req] = True674 requires[req] = True
675 for rec in pkg.recommends[:]:
676 rec.packages.append(pkg)
677 if rec not in recommends:
678 objmap[rec.getInitArgs()] = rec
679 recommends[rec] = True
649 for upg in pkg.upgrades:680 for upg in pkg.upgrades:
650 upg.packages.append(pkg)681 upg.packages.append(pkg)
651 if upg not in upgrades:682 if upg not in upgrades:
@@ -659,6 +690,7 @@
659 self._packages[:] = packages.keys()690 self._packages[:] = packages.keys()
660 self._provides[:] = provides.keys()691 self._provides[:] = provides.keys()
661 self._requires[:] = requires.keys()692 self._requires[:] = requires.keys()
693 self._recommends[:] = recommends.keys()
662 self._upgrades[:] = upgrades.keys()694 self._upgrades[:] = upgrades.keys()
663 self._conflicts[:] = conflicts.keys()695 self._conflicts[:] = conflicts.keys()
664696
@@ -710,6 +742,14 @@
710 lst.append(req)742 lst.append(req)
711 else:743 else:
712 reqnames[name] = [req]744 reqnames[name] = [req]
745 recnames = {}
746 for rec in self._recommends:
747 for name in rec.getMatchNames():
748 lst = recnames.get(name)
749 if lst:
750 lst.append(rec)
751 else:
752 recnames[name] = [rec]
713 upgnames = {}753 upgnames = {}
714 for upg in self._upgrades:754 for upg in self._upgrades:
715 for name in upg.getMatchNames():755 for name in upg.getMatchNames():
@@ -739,6 +779,18 @@
739 prv.requiredby.append(req)779 prv.requiredby.append(req)
740 else:780 else:
741 prv.requiredby = [req]781 prv.requiredby = [req]
782 lst = recnames.get(prv.name)
783 if lst:
784 for rec in lst:
785 if rec.matches(prv):
786 if rec.providedby:
787 rec.providedby.append(prv)
788 else:
789 rec.providedby = [prv]
790 if prv.recommendedby:
791 prv.recommendedby.append(rec)
792 else:
793 prv.recommendedby = [rec]
742 lst = upgnames.get(prv.name)794 lst = upgnames.get(prv.name)
743 if lst:795 if lst:
744 for upg in lst:796 for upg in lst:
@@ -782,6 +834,12 @@
782 else:834 else:
783 return [x for x in self._requires if x.name == name]835 return [x for x in self._requires if x.name == name]
784836
837 def getRecommends(self, name=None):
838 if not name:
839 return self._recommends
840 else:
841 return [x for x in self._recommends if x.name == name]
842
785 def getUpgrades(self, name=None):843 def getUpgrades(self, name=None):
786 if not name:844 if not name:
787 return self._upgrades845 return self._upgrades
@@ -807,6 +865,12 @@
807 for req in self._requires:865 for req in self._requires:
808 if prvname in req.getMatchNames() and req.matches(prv):866 if prvname in req.getMatchNames() and req.matches(prv):
809 searcher.addResult(req)867 searcher.addResult(req)
868 if searcher.recommends:
869 for prv in searcher.recommends:
870 prvname = prv.name
871 for req in self._recommends:
872 if prvname in req.getMatchNames() and req.matches(prv):
873 searcher.addResult(req)
810 if searcher.upgrades:874 if searcher.upgrades:
811 for prv in searcher.upgrades:875 for prv in searcher.upgrades:
812 prvname = prv.name876 prvname = prv.name
@@ -839,6 +903,7 @@
839 self._packages = state["_packages"]903 self._packages = state["_packages"]
840 provides = {}904 provides = {}
841 requires = {}905 requires = {}
906 recommends = {}
842 upgrades = {}907 upgrades = {}
843 conflicts = {}908 conflicts = {}
844 for pkg in self._packages:909 for pkg in self._packages:
@@ -848,6 +913,9 @@
848 for req in pkg.requires:913 for req in pkg.requires:
849 req.packages.append(pkg)914 req.packages.append(pkg)
850 requires[req] = True915 requires[req] = True
916 for rec in pkg.recommends:
917 rec.packages.append(pkg)
918 recommends[rec] = True
851 for upg in pkg.upgrades:919 for upg in pkg.upgrades:
852 upg.packages.append(pkg)920 upg.packages.append(pkg)
853 upgrades[upg] = True921 upgrades[upg] = True
@@ -856,6 +924,7 @@
856 conflicts[cnf] = True924 conflicts[cnf] = True
857 self._provides = provides.keys()925 self._provides = provides.keys()
858 self._requires = requires.keys()926 self._requires = requires.keys()
927 self._recommends = recommends.keys()
859 self._upgrades = upgrades.keys()928 self._upgrades = upgrades.keys()
860 self._conflicts = conflicts.keys()929 self._conflicts = conflicts.keys()
861 self._objmap = {}930 self._objmap = {}
862931
=== modified file 'smart/ccache.c'
--- smart/ccache.c 2009-03-02 12:56:54 +0000
+++ smart/ccache.c 2013-02-12 14:46:20 +0000
@@ -82,6 +82,7 @@
82 PyObject *version;82 PyObject *version;
83 PyObject *provides;83 PyObject *provides;
84 PyObject *requires;84 PyObject *requires;
85 PyObject *recommends;
85 PyObject *upgrades;86 PyObject *upgrades;
86 PyObject *conflicts;87 PyObject *conflicts;
87 PyObject *installed;88 PyObject *installed;
@@ -96,6 +97,7 @@
96 PyObject *version;97 PyObject *version;
97 PyObject *packages;98 PyObject *packages;
98 PyObject *requiredby;99 PyObject *requiredby;
100 PyObject *recommendedby;
99 PyObject *upgradedby;101 PyObject *upgradedby;
100 PyObject *conflictedby;102 PyObject *conflictedby;
101} ProvidesObject;103} ProvidesObject;
@@ -123,6 +125,7 @@
123 PyObject *_packages;125 PyObject *_packages;
124 PyObject *_provides;126 PyObject *_provides;
125 PyObject *_requires;127 PyObject *_requires;
128 PyObject *_recommends;
126 PyObject *_upgrades;129 PyObject *_upgrades;
127 PyObject *_conflicts;130 PyObject *_conflicts;
128 PyObject *_objmap;131 PyObject *_objmap;
@@ -211,7 +214,8 @@
211 Py_INCREF(self->name);214 Py_INCREF(self->name);
212 Py_INCREF(self->version);215 Py_INCREF(self->version);
213 self->provides = PyTuple_New(0);216 self->provides = PyTuple_New(0);
214 self->requires = PyTuple_New(0);217 self->requires = PyList_New(0);
218 self->recommends = PyList_New(0);
215 self->upgrades = PyTuple_New(0);219 self->upgrades = PyTuple_New(0);
216 self->conflicts = PyTuple_New(0);220 self->conflicts = PyTuple_New(0);
217 Py_INCREF(Py_False);221 Py_INCREF(Py_False);
@@ -228,6 +232,7 @@
228{232{
229 Py_VISIT(self->provides);233 Py_VISIT(self->provides);
230 Py_VISIT(self->requires);234 Py_VISIT(self->requires);
235 Py_VISIT(self->recommends);
231 Py_VISIT(self->upgrades);236 Py_VISIT(self->upgrades);
232 Py_VISIT(self->conflicts);237 Py_VISIT(self->conflicts);
233 Py_VISIT(self->loaders);238 Py_VISIT(self->loaders);
@@ -239,6 +244,7 @@
239{244{
240 Py_CLEAR(self->provides);245 Py_CLEAR(self->provides);
241 Py_CLEAR(self->requires);246 Py_CLEAR(self->requires);
247 Py_CLEAR(self->recommends);
242 Py_CLEAR(self->upgrades);248 Py_CLEAR(self->upgrades);
243 Py_CLEAR(self->conflicts);249 Py_CLEAR(self->conflicts);
244 Py_CLEAR(self->loaders);250 Py_CLEAR(self->loaders);
@@ -252,6 +258,7 @@
252 Py_XDECREF(self->version);258 Py_XDECREF(self->version);
253 Py_XDECREF(self->provides);259 Py_XDECREF(self->provides);
254 Py_XDECREF(self->requires);260 Py_XDECREF(self->requires);
261 Py_XDECREF(self->recommends);
255 Py_XDECREF(self->upgrades);262 Py_XDECREF(self->upgrades);
256 Py_XDECREF(self->conflicts);263 Py_XDECREF(self->conflicts);
257 Py_XDECREF(self->installed);264 Py_XDECREF(self->installed);
@@ -453,6 +460,46 @@
453 }460 }
454 }461 }
455462
463 ilen = 0;
464 jlen = 0;
465 for (i = 0; i != PyList_GET_SIZE(self->recommends); i++) {
466 PyObject *item = PyList_GET_ITEM(self->recommends, i);
467 if (!PyObject_IsInstance(item, (PyObject *)&Depends_Type)) {
468 PyErr_SetString(PyExc_TypeError, "Depends instance expected");
469 return NULL;
470 }
471 if (STR(((DependsObject *)item)->name)[0] != '/')
472 ilen += 1;
473 }
474 for (j = 0; j != PyList_GET_SIZE(other->recommends); j++) {
475 PyObject *item = PyList_GET_ITEM(other->recommends, j);
476 if (!PyObject_IsInstance(item, (PyObject *)&Depends_Type)) {
477 PyErr_SetString(PyExc_TypeError, "Depends instance expected");
478 return NULL;
479 }
480 if (STR(((DependsObject *)item)->name)[0] != '/')
481 jlen += 1;
482 }
483 if (ilen != jlen) {
484 ret = Py_False;
485 goto exit;
486 }
487
488 ilen = PyList_GET_SIZE(self->recommends);
489 jlen = PyList_GET_SIZE(other->recommends);
490 for (i = 0; i != ilen; i++) {
491 PyObject *item = PyList_GET_ITEM(self->recommends, i);
492 if (STR(((DependsObject *)item)->name)[0] != '/') {
493 for (j = 0; j != jlen; j++)
494 if (item == PyList_GET_ITEM(other->recommends, j))
495 break;
496 if (j == jlen) {
497 ret = Py_False;
498 goto exit;
499 }
500 }
501 }
502
456exit:503exit:
457 Py_INCREF(ret);504 Py_INCREF(ret);
458 return ret;505 return ret;
@@ -606,13 +653,14 @@
606static PyObject *653static PyObject *
607Package__getstate__(PackageObject *self, PyObject *args)654Package__getstate__(PackageObject *self, PyObject *args)
608{655{
609 PyObject *state = PyTuple_New(10);656 PyObject *state = PyTuple_New(11);
610 if (!state) return NULL;657 if (!state) return NULL;
611658
612 Py_INCREF(self->name);659 Py_INCREF(self->name);
613 Py_INCREF(self->version);660 Py_INCREF(self->version);
614 Py_INCREF(self->provides);661 Py_INCREF(self->provides);
615 Py_INCREF(self->requires);662 Py_INCREF(self->requires);
663 Py_INCREF(self->recommends);
616 Py_INCREF(self->upgrades);664 Py_INCREF(self->upgrades);
617 Py_INCREF(self->conflicts);665 Py_INCREF(self->conflicts);
618 Py_INCREF(self->installed);666 Py_INCREF(self->installed);
@@ -620,16 +668,17 @@
620 Py_INCREF(self->priority);668 Py_INCREF(self->priority);
621 Py_INCREF(self->loaders);669 Py_INCREF(self->loaders);
622670
623 PyTuple_SET_ITEM(state, 0, self->name);671 PyTuple_SET_ITEM(state, 0, self->name);
624 PyTuple_SET_ITEM(state, 1, self->version);672 PyTuple_SET_ITEM(state, 1, self->version);
625 PyTuple_SET_ITEM(state, 2, self->provides);673 PyTuple_SET_ITEM(state, 2, self->provides);
626 PyTuple_SET_ITEM(state, 3, self->requires);674 PyTuple_SET_ITEM(state, 3, self->requires);
627 PyTuple_SET_ITEM(state, 4, self->upgrades);675 PyTuple_SET_ITEM(state, 4, self->recommends);
628 PyTuple_SET_ITEM(state, 5, self->conflicts);676 PyTuple_SET_ITEM(state, 5, self->upgrades);
629 PyTuple_SET_ITEM(state, 6, self->installed);677 PyTuple_SET_ITEM(state, 6, self->conflicts);
630 PyTuple_SET_ITEM(state, 7, self->essential);678 PyTuple_SET_ITEM(state, 7, self->installed);
631 PyTuple_SET_ITEM(state, 8, self->priority);679 PyTuple_SET_ITEM(state, 8, self->essential);
632 PyTuple_SET_ITEM(state, 9, self->loaders);680 PyTuple_SET_ITEM(state, 9, self->priority);
681 PyTuple_SET_ITEM(state, 10, self->loaders);
633682
634 return state;683 return state;
635}684}
@@ -637,7 +686,7 @@
637static PyObject *686static PyObject *
638Package__setstate__(PackageObject *self, PyObject *state)687Package__setstate__(PackageObject *self, PyObject *state)
639{688{
640 if (!PyTuple_Check(state) || PyTuple_GET_SIZE(state) != 10) {689 if (!PyTuple_Check(state) || PyTuple_GET_SIZE(state) != 11) {
641 PyErr_SetString(StateVersionError, "");690 PyErr_SetString(StateVersionError, "");
642 return NULL;691 return NULL;
643 }692 }
@@ -645,18 +694,20 @@
645 self->version = PyTuple_GET_ITEM(state, 1);694 self->version = PyTuple_GET_ITEM(state, 1);
646 self->provides = PyTuple_GET_ITEM(state, 2);695 self->provides = PyTuple_GET_ITEM(state, 2);
647 self->requires = PyTuple_GET_ITEM(state, 3);696 self->requires = PyTuple_GET_ITEM(state, 3);
648 self->upgrades = PyTuple_GET_ITEM(state, 4);697 self->recommends = PyTuple_GET_ITEM(state, 4);
649 self->conflicts = PyTuple_GET_ITEM(state, 5);698 self->upgrades = PyTuple_GET_ITEM(state, 5);
650 self->installed = PyTuple_GET_ITEM(state, 6);699 self->conflicts = PyTuple_GET_ITEM(state, 6);
651 self->essential = PyTuple_GET_ITEM(state, 7);700 self->installed = PyTuple_GET_ITEM(state, 7);
652 self->priority = PyTuple_GET_ITEM(state, 8);701 self->essential = PyTuple_GET_ITEM(state, 8);
653 self->loaders = PyTuple_GET_ITEM(state, 9);702 self->priority = PyTuple_GET_ITEM(state, 9);
703 self->loaders = PyTuple_GET_ITEM(state, 10);
654704
655705
656 Py_INCREF(self->name);706 Py_INCREF(self->name);
657 Py_INCREF(self->version);707 Py_INCREF(self->version);
658 Py_INCREF(self->provides);708 Py_INCREF(self->provides);
659 Py_INCREF(self->requires);709 Py_INCREF(self->requires);
710 Py_INCREF(self->recommends);
660 Py_INCREF(self->upgrades);711 Py_INCREF(self->upgrades);
661 Py_INCREF(self->conflicts);712 Py_INCREF(self->conflicts);
662 Py_INCREF(self->installed);713 Py_INCREF(self->installed);
@@ -686,6 +737,7 @@
686 {"version", T_OBJECT, OFF(version), 0, 0},737 {"version", T_OBJECT, OFF(version), 0, 0},
687 {"provides", T_OBJECT, OFF(provides), 0, 0},738 {"provides", T_OBJECT, OFF(provides), 0, 0},
688 {"requires", T_OBJECT, OFF(requires), 0, 0},739 {"requires", T_OBJECT, OFF(requires), 0, 0},
740 {"recommends", T_OBJECT, OFF(recommends), 0, 0},
689 {"upgrades", T_OBJECT, OFF(upgrades), 0, 0},741 {"upgrades", T_OBJECT, OFF(upgrades), 0, 0},
690 {"conflicts", T_OBJECT, OFF(conflicts), 0, 0},742 {"conflicts", T_OBJECT, OFF(conflicts), 0, 0},
691 {"installed", T_OBJECT, OFF(installed), 0, 0},743 {"installed", T_OBJECT, OFF(installed), 0, 0},
@@ -750,6 +802,7 @@
750 Py_INCREF(self->version);802 Py_INCREF(self->version);
751 self->packages = PyList_New(0);803 self->packages = PyList_New(0);
752 self->requiredby = PyTuple_New(0);804 self->requiredby = PyTuple_New(0);
805 self->recommendedby = PyTuple_New(0);
753 self->upgradedby = PyTuple_New(0);806 self->upgradedby = PyTuple_New(0);
754 self->conflictedby = PyTuple_New(0);807 self->conflictedby = PyTuple_New(0);
755 return 0;808 return 0;
@@ -760,6 +813,7 @@
760{813{
761 Py_VISIT(self->packages);814 Py_VISIT(self->packages);
762 Py_VISIT(self->requiredby);815 Py_VISIT(self->requiredby);
816 Py_VISIT(self->recommendedby);
763 Py_VISIT(self->upgradedby);817 Py_VISIT(self->upgradedby);
764 Py_VISIT(self->conflictedby);818 Py_VISIT(self->conflictedby);
765 return 0;819 return 0;
@@ -770,6 +824,7 @@
770{824{
771 Py_CLEAR(self->packages);825 Py_CLEAR(self->packages);
772 Py_CLEAR(self->requiredby);826 Py_CLEAR(self->requiredby);
827 Py_CLEAR(self->recommendedby);
773 Py_CLEAR(self->upgradedby);828 Py_CLEAR(self->upgradedby);
774 Py_CLEAR(self->conflictedby);829 Py_CLEAR(self->conflictedby);
775 return 0;830 return 0;
@@ -782,6 +837,7 @@
782 Py_XDECREF(self->version);837 Py_XDECREF(self->version);
783 Py_XDECREF(self->packages);838 Py_XDECREF(self->packages);
784 Py_XDECREF(self->requiredby);839 Py_XDECREF(self->requiredby);
840 Py_XDECREF(self->recommendedby);
785 Py_XDECREF(self->upgradedby);841 Py_XDECREF(self->upgradedby);
786 Py_XDECREF(self->conflictedby);842 Py_XDECREF(self->conflictedby);
787 self->ob_type->tp_free((PyObject *)self);843 self->ob_type->tp_free((PyObject *)self);
@@ -960,6 +1016,7 @@
960 {"version", T_OBJECT, OFF(version), 0, 0},1016 {"version", T_OBJECT, OFF(version), 0, 0},
961 {"packages", T_OBJECT, OFF(packages), 0, 0},1017 {"packages", T_OBJECT, OFF(packages), 0, 0},
962 {"requiredby", T_OBJECT, OFF(requiredby), 0, 0},1018 {"requiredby", T_OBJECT, OFF(requiredby), 0, 0},
1019 {"recommendedby", T_OBJECT, OFF(recommendedby), 0, 0},
963 {"upgradedby", T_OBJECT, OFF(upgradedby), 0, 0},1020 {"upgradedby", T_OBJECT, OFF(upgradedby), 0, 0},
964 {"conflictedby", T_OBJECT, OFF(conflictedby), 0, 0},1021 {"conflictedby", T_OBJECT, OFF(conflictedby), 0, 0},
965 {NULL}1022 {NULL}
@@ -1555,6 +1612,7 @@
1555 PyObject *reqargs;1612 PyObject *reqargs;
1556 PyObject *upgargs;1613 PyObject *upgargs;
1557 PyObject *cnfargs;1614 PyObject *cnfargs;
1615 PyObject *recargs = NULL;
1558 PyObject *callargs;1616 PyObject *callargs;
1559 1617
1560 PyObject *pkg;1618 PyObject *pkg;
@@ -1574,9 +1632,10 @@
15741632
1575 cache = (CacheObject *)self->_cache;1633 cache = (CacheObject *)self->_cache;
15761634
1577 if (!PyArg_ParseTuple(args, "O!O&O&O&O&", &PyTuple_Type, &pkgargs,1635 if (!PyArg_ParseTuple(args, "O!O&O&O&O&|O&", &PyTuple_Type, &pkgargs,
1578 mylist, &prvargs, mylist, &reqargs,1636 mylist, &prvargs, mylist, &reqargs,
1579 mylist, &upgargs, mylist, &cnfargs))1637 mylist, &upgargs, mylist, &cnfargs,
1638 mylist, &recargs))
1580 return NULL;1639 return NULL;
15811640
1582 if (PyTuple_GET_SIZE(pkgargs) < 2) {1641 if (PyTuple_GET_SIZE(pkgargs) < 2) {
@@ -1701,6 +1760,59 @@
1701 }1760 }
1702 }1761 }
17031762
1763 /* if recargs: */
1764 if (recargs) {
1765 int i = 0;
1766 int len = PyList_GET_SIZE(recargs);
1767 /* pkg.recommends = [] */
1768 Py_DECREF(pkgobj->recommends);
1769 pkgobj->recommends = PyList_New(len);
1770 /* for args in recargs: */
1771 for (; i != len; i++) {
1772 PyObject *args = PyList_GET_ITEM(recargs, i);
1773 DependsObject *recobj;
1774 PyObject *rec;
1775
1776 if (!PyTuple_Check(args)) {
1777 PyErr_SetString(PyExc_TypeError,
1778 "Item in recargs is not a tuple");
1779 return NULL;
1780 }
1781
1782 /* rec = cache._objmap.get(args) */
1783 rec = PyDict_GetItem(cache->_objmap, args);
1784 recobj = (DependsObject *)rec;
1785
1786 /* if not rec: */
1787 if (!rec) {
1788 if (!PyTuple_Check(args) || PyTuple_GET_SIZE(args) < 2) {
1789 PyErr_SetString(PyExc_ValueError, "Invalid recargs tuple");
1790 return NULL;
1791 }
1792 /* rec = args[0](*args[1:]) */
1793 callargs = PyTuple_GetSlice(args, 1, PyTuple_GET_SIZE(args));
1794 rec = PyObject_CallObject(PyTuple_GET_ITEM(args, 0), callargs);
1795 Py_DECREF(callargs);
1796 if (!rec) return NULL;
1797 recobj = (DependsObject *)rec;
1798
1799 /* cache._objmap[args] = rec */
1800 PyDict_SetItem(cache->_objmap, args, rec);
1801 Py_DECREF(rec);
1802
1803 /* cache._recommends.append(rec) */
1804 PyList_Append(cache->_recommends, rec);
1805 }
1806
1807 /* relpkgs.append(rec.packages) */
1808 PyList_Append(relpkgs, recobj->packages);
1809
1810 /* pkg.recommends.append(rec) */
1811 Py_INCREF(rec);
1812 PyList_SET_ITEM(pkgobj->recommends, i, rec);
1813 }
1814 }
1815
1704 /* if upgargs: */1816 /* if upgargs: */
1705 if (upgargs) {1817 if (upgargs) {
1706 int i = 0;1818 int i = 0;
@@ -2391,6 +2503,7 @@
2391 self->_packages = PyList_New(0);2503 self->_packages = PyList_New(0);
2392 self->_provides = PyList_New(0);2504 self->_provides = PyList_New(0);
2393 self->_requires = PyList_New(0);2505 self->_requires = PyList_New(0);
2506 self->_recommends = PyList_New(0);
2394 self->_upgrades = PyList_New(0);2507 self->_upgrades = PyList_New(0);
2395 self->_conflicts = PyList_New(0);2508 self->_conflicts = PyList_New(0);
2396 self->_objmap = PyDict_New();2509 self->_objmap = PyDict_New();
@@ -2404,6 +2517,7 @@
2404 Py_VISIT(self->_packages);2517 Py_VISIT(self->_packages);
2405 Py_VISIT(self->_provides);2518 Py_VISIT(self->_provides);
2406 Py_VISIT(self->_requires);2519 Py_VISIT(self->_requires);
2520 Py_VISIT(self->_recommends);
2407 Py_VISIT(self->_upgrades);2521 Py_VISIT(self->_upgrades);
2408 Py_VISIT(self->_conflicts);2522 Py_VISIT(self->_conflicts);
2409 Py_VISIT(self->_objmap);2523 Py_VISIT(self->_objmap);
@@ -2417,6 +2531,7 @@
2417 Py_CLEAR(self->_packages);2531 Py_CLEAR(self->_packages);
2418 Py_CLEAR(self->_provides);2532 Py_CLEAR(self->_provides);
2419 Py_CLEAR(self->_requires);2533 Py_CLEAR(self->_requires);
2534 Py_CLEAR(self->_recommends);
2420 Py_CLEAR(self->_upgrades);2535 Py_CLEAR(self->_upgrades);
2421 Py_CLEAR(self->_conflicts);2536 Py_CLEAR(self->_conflicts);
2422 Py_CLEAR(self->_objmap);2537 Py_CLEAR(self->_objmap);
@@ -2430,6 +2545,7 @@
2430 Py_XDECREF(self->_packages);2545 Py_XDECREF(self->_packages);
2431 Py_XDECREF(self->_provides);2546 Py_XDECREF(self->_provides);
2432 Py_XDECREF(self->_requires);2547 Py_XDECREF(self->_requires);
2548 Py_XDECREF(self->_recommends);
2433 Py_XDECREF(self->_upgrades);2549 Py_XDECREF(self->_upgrades);
2434 Py_XDECREF(self->_conflicts);2550 Py_XDECREF(self->_conflicts);
2435 Py_XDECREF(self->_objmap);2551 Py_XDECREF(self->_objmap);
@@ -2449,6 +2565,8 @@
2449 LIST_CLEAR(prvobj->packages);2565 LIST_CLEAR(prvobj->packages);
2450 if (PyList_Check(prvobj->requiredby))2566 if (PyList_Check(prvobj->requiredby))
2451 LIST_CLEAR(prvobj->requiredby);2567 LIST_CLEAR(prvobj->requiredby);
2568 if (PyList_Check(prvobj->recommendedby))
2569 LIST_CLEAR(prvobj->recommendedby);
2452 if (PyList_Check(prvobj->upgradedby))2570 if (PyList_Check(prvobj->upgradedby))
2453 LIST_CLEAR(prvobj->upgradedby);2571 LIST_CLEAR(prvobj->upgradedby);
2454 if (PyList_Check(prvobj->conflictedby))2572 if (PyList_Check(prvobj->conflictedby))
@@ -2464,6 +2582,16 @@
2464 if (PyList_Check(reqobj->providedby))2582 if (PyList_Check(reqobj->providedby))
2465 LIST_CLEAR(reqobj->providedby);2583 LIST_CLEAR(reqobj->providedby);
2466 }2584 }
2585 len = PyList_GET_SIZE(self->_recommends);
2586 for (i = 0; i != len; i++) {
2587 DependsObject *reqobj;
2588 PyObject *req;
2589 req = PyList_GET_ITEM(self->_recommends, i);
2590 reqobj = (DependsObject *)req;
2591 LIST_CLEAR(reqobj->packages);
2592 if (PyList_Check(reqobj->providedby))
2593 LIST_CLEAR(reqobj->providedby);
2594 }
2467 len = PyList_GET_SIZE(self->_upgrades);2595 len = PyList_GET_SIZE(self->_upgrades);
2468 for (i = 0; i != len; i++) {2596 for (i = 0; i != len; i++) {
2469 DependsObject *upgobj;2597 DependsObject *upgobj;
@@ -2487,6 +2615,7 @@
2487 LIST_CLEAR(self->_packages);2615 LIST_CLEAR(self->_packages);
2488 LIST_CLEAR(self->_provides);2616 LIST_CLEAR(self->_provides);
2489 LIST_CLEAR(self->_requires);2617 LIST_CLEAR(self->_requires);
2618 LIST_CLEAR(self->_recommends);
2490 LIST_CLEAR(self->_upgrades);2619 LIST_CLEAR(self->_upgrades);
2491 LIST_CLEAR(self->_conflicts);2620 LIST_CLEAR(self->_conflicts);
2492 PyDict_Clear(self->_objmap);2621 PyDict_Clear(self->_objmap);
@@ -2534,6 +2663,7 @@
2534 packages = {}2663 packages = {}
2535 provides = {}2664 provides = {}
2536 requires = {}2665 requires = {}
2666 recommends = {}
2537 upgrades = {}2667 upgrades = {}
2538 conflicts = {}2668 conflicts = {}
2539 objmap = self._objmap2669 objmap = self._objmap
@@ -2541,11 +2671,12 @@
2541 PyObject *packages = PyDict_New();2671 PyObject *packages = PyDict_New();
2542 PyObject *provides = PyDict_New();2672 PyObject *provides = PyDict_New();
2543 PyObject *requires = PyDict_New();2673 PyObject *requires = PyDict_New();
2674 PyObject *recommends = PyDict_New();
2544 PyObject *upgrades = PyDict_New();2675 PyObject *upgrades = PyDict_New();
2545 PyObject *conflicts = PyDict_New();2676 PyObject *conflicts = PyDict_New();
2546 PyObject *objmap = self->_objmap;2677 PyObject *objmap = self->_objmap;
2547 int i, ilen;2678 int i, ilen;
2548 if (!packages || !provides || !requires || !conflicts)2679 if (!packages || !provides || !requires || !recommends || !conflicts )
2549 return NULL;2680 return NULL;
25502681
2551 /* for loader in loaders: */2682 /* for loader in loaders: */
@@ -2679,6 +2810,30 @@
2679 }2810 }
26802811
2681 /*2812 /*
2813 for rec in pkg.recommends:
2814 rec.packages.append(pkg)
2815 if rec not in recommends:
2816 recommends[rec] = True
2817 objmap[rec.getInitArgs()] = rec
2818 */
2819 if (PyList_Check(pkg->recommends)) {
2820 klen = PyList_GET_SIZE(pkg->recommends);
2821 for (k = 0; k != klen; k++) {
2822 PyObject *rec = PyList_GET_ITEM(pkg->recommends, k);
2823 PyList_Append(((DependsObject *)rec)->packages,
2824 (PyObject *)pkg);
2825 if (!PyDict_GetItem(recommends, rec)) {
2826 PyDict_SetItem(recommends, rec, Py_True);
2827 args = PyObject_CallMethod(rec, "getInitArgs",
2828 NULL);
2829 if (!args) return NULL;
2830 PyDict_SetItem(objmap, args, rec);
2831 Py_DECREF(args);
2832 }
2833 }
2834 }
2835
2836 /*
2682 for upg in pkg.upgrades:2837 for upg in pkg.upgrades:
2683 upg.packages.append(pkg)2838 upg.packages.append(pkg)
2684 if upg not in upgrades:2839 if upg not in upgrades:
@@ -2747,6 +2902,11 @@
2747 self->_requires = PyDict_Keys(requires);2902 self->_requires = PyDict_Keys(requires);
2748 Py_DECREF(requires);2903 Py_DECREF(requires);
27492904
2905 /* self._recommends[:] = recommends.keys() */
2906 Py_DECREF(self->_recommends);
2907 self->_recommends = PyDict_Keys(recommends);
2908 Py_DECREF(recommends);
2909
2750 /* self._upgrades[:] = upgrades.keys() */2910 /* self._upgrades[:] = upgrades.keys() */
2751 Py_DECREF(self->_upgrades);2911 Py_DECREF(self->_upgrades);
2752 self->_upgrades = PyDict_Keys(upgrades);2912 self->_upgrades = PyDict_Keys(upgrades);
@@ -2852,7 +3012,7 @@
2852Cache_linkDeps(CacheObject *self, PyObject *args)3012Cache_linkDeps(CacheObject *self, PyObject *args)
2853{3013{
2854 int i, j, len;3014 int i, j, len;
2855 PyObject *reqnames, *upgnames, *cnfnames;3015 PyObject *reqnames, *recnames, *upgnames, *cnfnames;
2856 PyObject *lst;3016 PyObject *lst;
28573017
2858 /* reqnames = {} */3018 /* reqnames = {} */
@@ -2896,6 +3056,47 @@
2896 Py_DECREF(seq);3056 Py_DECREF(seq);
2897 }3057 }
28983058
3059 /* recnames = {} */
3060 recnames = PyDict_New();
3061 /* for rec in self._recommends: */
3062 len = PyList_GET_SIZE(self->_recommends);
3063 for (i = 0; i != len; i++) {
3064 PyObject *rec = PyList_GET_ITEM(self->_recommends, i);
3065
3066 /* for name in rec.getMatchNames(): */
3067 PyObject *names = PyObject_CallMethod(rec, "getMatchNames", NULL);
3068 PyObject *seq = PySequence_Fast(names, "getMatchNames() returned "
3069 "non-sequence object");
3070 int nameslen;
3071 if (!seq) return NULL;
3072 nameslen = PySequence_Fast_GET_SIZE(seq);
3073 for (j = 0; j != nameslen; j++) {
3074 PyObject *name = PySequence_Fast_GET_ITEM(seq, j);
3075
3076 /* lst = recnames.get(name) */
3077 lst = PyDict_GetItem(recnames, name);
3078
3079 /*
3080 if lst:
3081 lst.append(rec)
3082 else:
3083 recnames[name] = [rec]
3084 */
3085 if (lst) {
3086 PyList_Append(lst, rec);
3087 } else {
3088 lst = PyList_New(1);
3089 Py_INCREF(rec);
3090 PyList_SET_ITEM(lst, 0, rec);
3091 PyDict_SetItem(recnames, name, lst);
3092 Py_DECREF(lst);
3093 }
3094 }
3095
3096 Py_DECREF(names);
3097 Py_DECREF(seq);
3098 }
3099
2899 /* upgnames = {} */3100 /* upgnames = {} */
2900 upgnames = PyDict_New();3101 upgnames = PyDict_New();
2901 /* for upg in self._upgrades: */3102 /* for upg in self._upgrades: */
@@ -3035,6 +3236,56 @@
3035 }3236 }
3036 }3237 }
30373238
3239 /* lst = recnames.get(prv.name) */
3240 lst = PyDict_GetItem(recnames, prv->name);
3241
3242 /* if lst: */
3243 if (lst) {
3244 /* for rec in lst: */
3245 int reclen = PyList_GET_SIZE(lst);
3246 for (j = 0; j != reclen; j++) {
3247 DependsObject *rec = (DependsObject *)PyList_GET_ITEM(lst, j);
3248 /* if rec.matches(prv): */
3249 PyObject *ret = PyObject_CallMethod((PyObject *)rec, "matches",
3250 "O", (PyObject *)prv);
3251 if (!ret) return NULL;
3252 if (PyObject_IsTrue(ret)) {
3253 /*
3254 if rec.providedby:
3255 rec.providedby.append(prv)
3256 else:
3257 rec.providedby = [prv]
3258 */
3259 if (PyList_Check(rec->providedby)) {
3260 PyList_Append(rec->providedby, (PyObject *)prv);
3261 } else {
3262 PyObject *_lst = PyList_New(1);
3263 Py_INCREF(prv);
3264 PyList_SET_ITEM(_lst, 0, (PyObject *)prv);
3265 Py_DECREF(rec->providedby);
3266 rec->providedby = _lst;
3267 }
3268
3269 /*
3270 if prv.recommendedby:
3271 prv.recommendedby.append(prv)
3272 else:
3273 prv.recommendedby = [prv]
3274 */
3275 if (PyList_Check(prv->recommendedby)) {
3276 PyList_Append(prv->recommendedby, (PyObject *)rec);
3277 } else {
3278 PyObject *_lst = PyList_New(1);
3279 Py_INCREF(rec);
3280 PyList_SET_ITEM(_lst, 0, (PyObject *)rec);
3281 Py_DECREF(prv->recommendedby);
3282 prv->recommendedby = _lst;
3283 }
3284 }
3285 Py_DECREF(ret);
3286 }
3287 }
3288
3038 /* lst = upgnames.get(prv.name) */3289 /* lst = upgnames.get(prv.name) */
3039 lst = PyDict_GetItem(upgnames, prv->name);3290 lst = PyDict_GetItem(upgnames, prv->name);
30403291
@@ -3139,6 +3390,7 @@
3139 }3390 }
31403391
3141 Py_DECREF(reqnames);3392 Py_DECREF(reqnames);
3393 Py_DECREF(recnames);
3142 Py_DECREF(upgnames);3394 Py_DECREF(upgnames);
3143 Py_DECREF(cnfnames);3395 Py_DECREF(cnfnames);
31443396
@@ -3215,6 +3467,29 @@
3215}3467}
32163468
3217PyObject *3469PyObject *
3470Cache_getRecommends(CacheObject *self, PyObject *args)
3471{
3472 const char *name = NULL;
3473 PyObject *lst;
3474 int i, len;
3475 if (!PyArg_ParseTuple(args, "|s", &name))
3476 return NULL;
3477 if (!name) {
3478 Py_INCREF(self->_recommends);
3479 return self->_recommends;
3480 }
3481 lst = PyList_New(0);
3482 len = PyList_GET_SIZE(self->_recommends);
3483 for (i = 0; i != len; i++) {
3484 DependsObject *rec =
3485 (DependsObject*)PyList_GET_ITEM(self->_recommends, i);
3486 if (strcmp(STR(rec->name), name) == 0)
3487 PyList_Append(lst, (PyObject *)rec);
3488 }
3489 return lst;
3490}
3491
3492PyObject *
3218Cache_getUpgrades(CacheObject *self, PyObject *args)3493Cache_getUpgrades(CacheObject *self, PyObject *args)
3219{3494{
3220 const char *name = NULL;3495 const char *name = NULL;
@@ -3324,6 +3599,38 @@
3324 }3599 }
3325 Py_DECREF(lst);3600 Py_DECREF(lst);
33263601
3602 lst = PyObject_GetAttrString(searcher, "recommends");
3603 if (lst == NULL || !PyList_Check(lst)) {
3604 PyErr_SetString(PyExc_TypeError, "Invalid recommends attribute");
3605 return NULL;
3606 }
3607 for (i = 0; i != PyList_GET_SIZE(lst); i++) {
3608 ProvidesObject *prv = (ProvidesObject *)PyList_GET_ITEM(lst, i);
3609 for (j = 0; j != PyList_GET_SIZE(self->_recommends); j++) {
3610 PyObject *rec = PyList_GET_ITEM(self->_recommends, j);
3611 PyObject *names = PyObject_CallMethod(rec, "getMatchNames", NULL);
3612 PyObject *seq = PySequence_Fast(names, "getMatchNames() returned "
3613 "non-sequence object");
3614 if (seq == NULL) return NULL;
3615 for (k = 0; k != PySequence_Fast_GET_SIZE(seq); k++) {
3616 if (strcmp(PyString_AS_STRING(PySequence_Fast_GET_ITEM(seq, k)),
3617 PyString_AS_STRING(prv->name)) == 0) {
3618 res = PyObject_CallMethod(rec, "matches", "O", prv);
3619 if (res == NULL)
3620 return NULL;
3621 if (PyObject_IsTrue(res))
3622 CALLMETHOD(searcher, "addResult", "O", rec);
3623 Py_DECREF(res);
3624 break;
3625 }
3626 }
3627
3628 Py_DECREF(names);
3629 Py_DECREF(seq);
3630 }
3631 }
3632 Py_DECREF(lst);
3633
3327 lst = PyObject_GetAttrString(searcher, "upgrades");3634 lst = PyObject_GetAttrString(searcher, "upgrades");
3328 if (lst == NULL || !PyList_Check(lst)) {3635 if (lst == NULL || !PyList_Check(lst)) {
3329 PyErr_SetString(PyExc_TypeError, "Invalid upgrades attribute");3636 PyErr_SetString(PyExc_TypeError, "Invalid upgrades attribute");
@@ -3420,7 +3727,7 @@
3420static PyObject *3727static PyObject *
3421Cache__setstate__(CacheObject *self, PyObject *state)3728Cache__setstate__(CacheObject *self, PyObject *state)
3422{3729{
3423 PyObject *provides, *requires, *upgrades, *conflicts;3730 PyObject *provides, *requires, *recommends, *upgrades, *conflicts;
3424 int i, ilen;3731 int i, ilen;
3425 int j, jlen;3732 int j, jlen;
3426 3733
@@ -3452,11 +3759,13 @@
3452 /*3759 /*
3453 provides = {}3760 provides = {}
3454 requires = {}3761 requires = {}
3762 recommends = {}
3455 upgrades = {}3763 upgrades = {}
3456 conflicts = {}3764 conflicts = {}
3457 */3765 */
3458 provides = PyDict_New();3766 provides = PyDict_New();
3459 requires = PyDict_New();3767 requires = PyDict_New();
3768 recommends = PyDict_New();
3460 upgrades = PyDict_New();3769 upgrades = PyDict_New();
3461 conflicts = PyDict_New();3770 conflicts = PyDict_New();
34623771
@@ -3497,6 +3806,21 @@
3497 }3806 }
34983807
3499 /*3808 /*
3809 for rec in pkg.recommends:
3810 rec.packages.append(pkg)
3811 recommends[rec] = True
3812 */
3813 if (PyList_Check(pkgobj->recommends)) {
3814 jlen = PyList_GET_SIZE(pkgobj->recommends);
3815 for (j = 0; j != jlen; j++) {
3816 PyObject *rec = PyList_GET_ITEM(pkgobj->recommends, j);
3817 DependsObject *recobj = (DependsObject *)rec;
3818 PyList_Append(recobj->packages, pkg);
3819 PyDict_SetItem(recommends, rec, Py_True);
3820 }
3821 }
3822
3823 /*
3500 for upg in pkg.upgrades:3824 for upg in pkg.upgrades:
3501 upg.packages.append(pkg)3825 upg.packages.append(pkg)
3502 upgrades[upg] = True3826 upgrades[upg] = True
@@ -3525,6 +3849,7 @@
3525 PyDict_SetItem(conflicts, cnf, Py_True);3849 PyDict_SetItem(conflicts, cnf, Py_True);
3526 }3850 }
3527 }3851 }
3852
3528 }3853 }
35293854
3530 /* self._provides = provides.keys() */3855 /* self._provides = provides.keys() */
@@ -3535,6 +3860,10 @@
3535 self->_requires = PyDict_Keys(requires);3860 self->_requires = PyDict_Keys(requires);
3536 Py_DECREF(requires);3861 Py_DECREF(requires);
35373862
3863 /* self._recommends = recommends.keys() */
3864 self->_recommends = PyDict_Keys(recommends);
3865 Py_DECREF(recommends);
3866
3538 /* self._upgrades = upgrades.keys() */3867 /* self._upgrades = upgrades.keys() */
3539 self->_upgrades = PyDict_Keys(upgrades);3868 self->_upgrades = PyDict_Keys(upgrades);
3540 Py_DECREF(upgrades);3869 Py_DECREF(upgrades);
@@ -3562,6 +3891,7 @@
3562 {"getPackages", (PyCFunction)Cache_getPackages, METH_VARARGS, NULL},3891 {"getPackages", (PyCFunction)Cache_getPackages, METH_VARARGS, NULL},
3563 {"getProvides", (PyCFunction)Cache_getProvides, METH_VARARGS, NULL},3892 {"getProvides", (PyCFunction)Cache_getProvides, METH_VARARGS, NULL},
3564 {"getRequires", (PyCFunction)Cache_getRequires, METH_VARARGS, NULL},3893 {"getRequires", (PyCFunction)Cache_getRequires, METH_VARARGS, NULL},
3894 {"getRecommends", (PyCFunction)Cache_getRecommends, METH_VARARGS, NULL},
3565 {"getUpgrades", (PyCFunction)Cache_getUpgrades, METH_VARARGS, NULL},3895 {"getUpgrades", (PyCFunction)Cache_getUpgrades, METH_VARARGS, NULL},
3566 {"getConflicts", (PyCFunction)Cache_getConflicts, METH_VARARGS, NULL},3896 {"getConflicts", (PyCFunction)Cache_getConflicts, METH_VARARGS, NULL},
3567 {"search", (PyCFunction)Cache_search, METH_O, NULL},3897 {"search", (PyCFunction)Cache_search, METH_O, NULL},
@@ -3576,6 +3906,7 @@
3576 {"_packages", T_OBJECT, OFF(_packages), RO, 0},3906 {"_packages", T_OBJECT, OFF(_packages), RO, 0},
3577 {"_provides", T_OBJECT, OFF(_provides), RO, 0},3907 {"_provides", T_OBJECT, OFF(_provides), RO, 0},
3578 {"_requires", T_OBJECT, OFF(_requires), RO, 0},3908 {"_requires", T_OBJECT, OFF(_requires), RO, 0},
3909 {"_recommends", T_OBJECT, OFF(_recommends), RO, 0},
3579 {"_upgrades", T_OBJECT, OFF(_upgrades), RO, 0},3910 {"_upgrades", T_OBJECT, OFF(_upgrades), RO, 0},
3580 {"_conflicts", T_OBJECT, OFF(_conflicts), RO, 0},3911 {"_conflicts", T_OBJECT, OFF(_conflicts), RO, 0},
3581 {"_objmap", T_OBJECT, OFF(_objmap), RO, 0},3912 {"_objmap", T_OBJECT, OFF(_objmap), RO, 0},
35823913
=== modified file 'smart/channels/rpm_sys.py'
--- smart/channels/rpm_sys.py 2009-12-18 14:50:03 +0000
+++ smart/channels/rpm_sys.py 2013-02-12 14:46:20 +0000
@@ -20,7 +20,7 @@
20# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA20# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21#21#
22from smart.backends.rpm.header import RPMDBLoader22from smart.backends.rpm.header import RPMDBLoader
23from smart.backends.rpm.base import getTS23from smart.backends.rpm.base import getTS, rpm_join_dbpath
24from smart.channel import PackageChannel24from smart.channel import PackageChannel
25from smart import *25from smart import *
26import os26import os
@@ -32,9 +32,9 @@
3232
33 def fetch(self, fetcher, progress):33 def fetch(self, fetcher, progress):
34 getTS() # Make sure the db exists.34 getTS() # Make sure the db exists.
35 path = os.path.join(sysconf.get("rpm-root", "/"),35 dbdir = rpm_join_dbpath(sysconf.get("rpm-root", "/"),
36 sysconf.get("rpm-dbpath", "var/lib/rpm"),36 sysconf.get("rpm-dbpath", "var/lib/rpm"))
37 "Packages")37 path = os.path.join(dbdir, "Packages")
38 digest = os.path.getmtime(path)38 digest = os.path.getmtime(path)
39 if digest == self._digest:39 if digest == self._digest:
40 return True40 return True
4141
=== modified file 'smart/commands/channel.py'
--- smart/commands/channel.py 2010-12-06 07:35:59 +0000
+++ smart/commands/channel.py 2013-02-12 14:46:20 +0000
@@ -157,7 +157,17 @@
157 opts.show is None and opts.yaml is None):157 opts.show is None and opts.yaml is None):
158 iface.warning(_("Can't edit channels information."))158 iface.warning(_("Can't edit channels information."))
159 raise Error, _("Configuration is in readonly mode.")159 raise Error, _("Configuration is in readonly mode.")
160 160
161 # Argument check
162 opts.check_args_of_option("set", -1)
163 opts.check_args_of_option("remove", -1)
164 opts.check_args_of_option("edit", 0)
165 opts.check_args_of_option("enable", -1)
166 opts.check_args_of_option("disable", -1)
167 opts.ensure_action("channel", ["add", "set", "remove", "remove-all",
168 "list", "show", "yaml", "enable", "disable"])
169 opts.check_remaining_args()
170
161 if opts.add is not None:171 if opts.add is not None:
162 if not opts.add and opts.args == ["-"]:172 if not opts.add and opts.args == ["-"]:
163 newchannels = []173 newchannels = []
@@ -329,7 +339,10 @@
329 print339 print
330340
331 if opts.yaml is not None:341 if opts.yaml is not None:
332 import yaml342 try:
343 import yaml
344 except ImportError:
345 raise Error, _("Please install PyYAML in order to use this function")
333 yamlchannels = {}346 yamlchannels = {}
334 for alias in (opts.yaml or sysconf.get("channels", ())):347 for alias in (opts.yaml or sysconf.get("channels", ())):
335 channel = sysconf.get(("channels", alias))348 channel = sysconf.get(("channels", alias))
336349
=== modified file 'smart/commands/check.py'
--- smart/commands/check.py 2010-06-22 20:51:32 +0000
+++ smart/commands/check.py 2013-02-12 14:46:20 +0000
@@ -72,6 +72,9 @@
7272
73def main(ctrl, opts, reloadchannels=True):73def main(ctrl, opts, reloadchannels=True):
7474
75 # Argument check
76 opts.check_args_of_option("channels", 1)
77
75 if sysconf.get("auto-update"):78 if sysconf.get("auto-update"):
76 from smart.commands import update79 from smart.commands import update
77 updateopts = update.parse_options([])80 updateopts = update.parse_options([])
7881
=== modified file 'smart/commands/config.py'
--- smart/commands/config.py 2010-07-02 13:55:04 +0000
+++ smart/commands/config.py 2013-02-12 14:46:20 +0000
@@ -80,6 +80,12 @@
80 globals["false"] = False80 globals["false"] = False
81 globals["no"] = False81 globals["no"] = False
8282
83 # Check arguments
84 opts.check_args_of_option("set", -1)
85 opts.check_args_of_option("remove", -1)
86 opts.ensure_action("config", ["set", "show", "yaml", "remove"])
87 opts.check_remaining_args()
88
83 if opts.set:89 if opts.set:
84 for opt in opts.set:90 for opt in opts.set:
85 m = SETRE.match(opt)91 m = SETRE.match(opt)
@@ -131,7 +137,10 @@
131 pprint.pprint(sysconf.get((), hard=True))137 pprint.pprint(sysconf.get((), hard=True))
132138
133 if opts.yaml is not None:139 if opts.yaml is not None:
134 import yaml140 try:
141 import yaml
142 except ImportError:
143 raise Error, _("Please install PyYAML in order to use this function")
135 if opts.yaml:144 if opts.yaml:
136 marker = object()145 marker = object()
137 for opt in opts.yaml:146 for opt in opts.yaml:
138147
=== modified file 'smart/commands/download.py'
--- smart/commands/download.py 2010-06-22 20:51:32 +0000
+++ smart/commands/download.py 2013-02-12 14:46:20 +0000
@@ -81,6 +81,14 @@
8181
82def main(ctrl, opts):82def main(ctrl, opts):
8383
84 # Argument check
85 opts.check_args_of_option("target", 1)
86 opts.check_args_of_option("output", 1)
87 opts.check_args_of_option("from_urls", -1)
88 opts.check_args_of_option("from_metalink", -1)
89 if not opts.args and not opts.from_metalink and not opts.from_urls:
90 raise Error, _("no package(s) given")
91
84 packages = []92 packages = []
85 if opts.args:93 if opts.args:
86 if sysconf.get("auto-update"):94 if sysconf.get("auto-update"):
8795
=== modified file 'smart/commands/flag.py'
--- smart/commands/flag.py 2010-12-05 15:14:50 +0000
+++ smart/commands/flag.py 2013-02-12 14:46:20 +0000
@@ -138,7 +138,10 @@
138 print138 print
139139
140 if opts.yaml is not None:140 if opts.yaml is not None:
141 import yaml141 try:
142 import yaml
143 except ImportError:
144 raise Error, _("Please install PyYAML in order to use this function")
142 yamlflags = {}145 yamlflags = {}
143 for flag in opts.yaml or pkgconf.getFlagNames():146 for flag in opts.yaml or pkgconf.getFlagNames():
144 flag = flag.strip()147 flag = flag.strip()
145148
=== modified file 'smart/commands/info.py'
--- smart/commands/info.py 2010-06-22 20:51:32 +0000
+++ smart/commands/info.py 2013-02-12 14:46:20 +0000
@@ -58,6 +58,10 @@
5858
59def main(ctrl, opts, reloadchannels=True):59def main(ctrl, opts, reloadchannels=True):
6060
61 # Argument check
62 if not opts.args:
63 raise Error, _("No package(s) given")
64
61 if sysconf.get("auto-update"):65 if sysconf.get("auto-update"):
62 from smart.commands import update66 from smart.commands import update
63 updateopts = update.parse_options([])67 updateopts = update.parse_options([])
6468
=== modified file 'smart/commands/install.py'
--- smart/commands/install.py 2011-01-30 21:55:29 +0000
+++ smart/commands/install.py 2013-02-12 14:46:20 +0000
@@ -76,6 +76,10 @@
7676
77def main(ctrl, opts):77def main(ctrl, opts):
78 78
79 # Argument check
80 if not opts.args:
81 raise Error, _("no package(s) given")
82
79 if opts.explain:83 if opts.explain:
80 sysconf.set("explain-changesets", True, soft=True)84 sysconf.set("explain-changesets", True, soft=True)
8185
8286
=== modified file 'smart/commands/mirror.py'
--- smart/commands/mirror.py 2010-07-02 13:55:04 +0000
+++ smart/commands/mirror.py 2013-02-12 14:46:20 +0000
@@ -218,7 +218,10 @@
218 print218 print
219219
220 if opts.yaml:220 if opts.yaml:
221 import yaml221 try:
222 import yaml
223 except ImportError:
224 raise Error, _("Please install PyYAML in order to use this function")
222 yamlmirrors = {}225 yamlmirrors = {}
223 mirrors = sysconf.get("mirrors", ())226 mirrors = sysconf.get("mirrors", ())
224 for origin in mirrors:227 for origin in mirrors:
225228
=== modified file 'smart/commands/priority.py'
--- smart/commands/priority.py 2010-07-02 13:55:04 +0000
+++ smart/commands/priority.py 2013-02-12 14:46:20 +0000
@@ -117,7 +117,10 @@
117 print117 print
118118
119 elif opts.yaml:119 elif opts.yaml:
120 import yaml120 try:
121 import yaml
122 except ImportError:
123 raise Error, _("Please install PyYAML in order to use this function")
121 yamlpriorities = {}124 yamlpriorities = {}
122 priorities = sysconf.get("package-priorities", {})125 priorities = sysconf.get("package-priorities", {})
123 for name in opts.args or priorities:126 for name in opts.args or priorities:
124127
=== modified file 'smart/commands/query.py'
--- smart/commands/query.py 2010-12-05 15:11:14 +0000
+++ smart/commands/query.py 2013-02-12 14:46:20 +0000
@@ -107,6 +107,8 @@
107 help=_("show requires for the given packages"))107 help=_("show requires for the given packages"))
108 parser.add_option("--show-prerequires", action="store_true",108 parser.add_option("--show-prerequires", action="store_true",
109 help=_("show requires selecting only pre-dependencies"))109 help=_("show requires selecting only pre-dependencies"))
110 parser.add_option("--show-recommends", action="store_true",
111 help=_("show recommends for the given packages"))
110 parser.add_option("--show-upgrades", action="store_true",112 parser.add_option("--show-upgrades", action="store_true",
111 help=_("show upgrades for the given packages"))113 help=_("show upgrades for the given packages"))
112 parser.add_option("--show-conflicts", action="store_true",114 parser.add_option("--show-conflicts", action="store_true",
@@ -488,6 +490,19 @@
488 continue490 continue
489 output.showRequiresProvidedBy(pkg, req,491 output.showRequiresProvidedBy(pkg, req,
490 prv, prvpkg)492 prv, prvpkg)
493 if pkg.recommends and (opts.show_recommends):
494 pkg.recommends.sort()
495 first = True
496 for req in pkg.recommends:
497 output.showRecommends(pkg, req)
498 if opts.show_providedby and req.providedby:
499 for prv in req.providedby:
500 prv.packages.sort()
501 for prvpkg in prv.packages:
502 if opts.installed and not prvpkg.installed:
503 continue
504 output.showRecommendsProvidedBy(pkg, req,
505 prv, prvpkg)
491 if pkg.upgrades and (opts.show_upgrades or whoupgrades):506 if pkg.upgrades and (opts.show_upgrades or whoupgrades):
492 pkg.upgrades.sort()507 pkg.upgrades.sort()
493 first = True508 first = True
@@ -594,6 +609,12 @@
594 def showRequiresProvidedBy(self, pkg, req, prv, prvpkg):609 def showRequiresProvidedBy(self, pkg, req, prv, prvpkg):
595 pass610 pass
596611
612 def showRecommends(self, pkg, req):
613 pass
614
615 def showRecommendsProvidedBy(self, pkg, req, prv, prvpkg):
616 pass
617
597 def showUpgrades(self, pkg, upg):618 def showUpgrades(self, pkg, upg):
598 pass619 pass
599620
@@ -619,6 +640,8 @@
619 self._firstconflictedby = True640 self._firstconflictedby = True
620 self._firstrequires = True641 self._firstrequires = True
621 self._firstrequiresprovidedby = True642 self._firstrequiresprovidedby = True
643 self._firstrecommends = True
644 self._firstrecommendsprovidedby = True
622 self._firstupgrades = True645 self._firstupgrades = True
623 self._firstupgradesprovidedby = True646 self._firstupgradesprovidedby = True
624 self._firstconflicts = True647 self._firstconflicts = True
@@ -711,6 +734,22 @@
711 name = str(prvpkg)734 name = str(prvpkg)
712 print " ", "%s (%s)" % (name, prv)735 print " ", "%s (%s)" % (name, prv)
713736
737 def showRecommends(self, pkg, rec):
738 if self._firstrecommends:
739 self._firstrecommends = False
740 print " ", _("Recommends:")
741 print " ", rec
742
743 def showRecommendsProvidedBy(self, pkg, req, prv, prvpkg):
744 if self._firstrecommendsprovidedby:
745 self._firstrecommendsprovidedby = False
746 print " ", _("Provided By:")
747 if self.opts.hide_version:
748 name = prvpkg.name
749 else:
750 name = str(prvpkg)
751 print " ", "%s (%s)" % (name, prv)
752
714 def showUpgrades(self, pkg, upg):753 def showUpgrades(self, pkg, upg):
715 if self._firstupgrades:754 if self._firstupgrades:
716 self._firstupgrades = False755 self._firstupgrades = False
@@ -797,6 +836,18 @@
797 self._shown[req, prv] = True836 self._shown[req, prv] = True
798 print ' "Requires: %s" -> "Provides: %s";' % (req, prv)837 print ' "Requires: %s" -> "Provides: %s";' % (req, prv)
799838
839 def showRecommends(self, pkg, req):
840 if (pkg, req) not in self._shown:
841 self._shown[pkg, req] = True
842 print ' "%s" -> "Recommends: %s";' % (pkg, req)
843
844 def showRecommendsProvidedBy(self, pkg, req, prv, prvpkg):
845 self.showPackage(prvpkg)
846 self.showProvides(prvpkg, prv)
847 if (req, prv) not in self._shown:
848 self._shown[req, prv] = True
849 print ' "Recommends: %s" -> "Provides: %s";' % (req, prv)
850
800 def showUpgrades(self, pkg, upg):851 def showUpgrades(self, pkg, upg):
801 if (pkg, upg) not in self._shown:852 if (pkg, upg) not in self._shown:
802 self._shown[pkg, upg] = True853 self._shown[pkg, upg] = True
803854
=== modified file 'smart/commands/reinstall.py'
--- smart/commands/reinstall.py 2010-06-22 20:51:32 +0000
+++ smart/commands/reinstall.py 2013-02-12 14:46:20 +0000
@@ -68,7 +68,11 @@
68 return opts68 return opts
6969
70def main(ctrl, opts):70def main(ctrl, opts):
71 71
72 # Argument check
73 if not opts.args:
74 raise Error, _("no package(s) given")
75
72 if opts.explain:76 if opts.explain:
73 sysconf.set("explain-changesets", True, soft=True)77 sysconf.set("explain-changesets", True, soft=True)
7478
7579
=== modified file 'smart/commands/remove.py'
--- smart/commands/remove.py 2010-06-22 20:51:32 +0000
+++ smart/commands/remove.py 2013-02-12 14:46:20 +0000
@@ -74,6 +74,10 @@
7474
75def main(ctrl, opts):75def main(ctrl, opts):
7676
77 # Argument check
78 if not opts.args:
79 raise Error, _("no package(s) given")
80
77 if opts.explain:81 if opts.explain:
78 sysconf.set("explain-changesets", True, soft=True)82 sysconf.set("explain-changesets", True, soft=True)
7983
8084
=== modified file 'smart/commands/search.py'
--- smart/commands/search.py 2010-11-28 13:12:37 +0000
+++ smart/commands/search.py 2013-02-12 14:46:20 +0000
@@ -44,6 +44,8 @@
44def parse_options(argv):44def parse_options(argv):
45 opts = query.parse_options(argv, usage=USAGE, \45 opts = query.parse_options(argv, usage=USAGE, \
46 description=DESCRIPTION, examples=EXAMPLES)46 description=DESCRIPTION, examples=EXAMPLES)
47 if not argv:
48 raise Error, _("Search expression not specified")
47 opts.name = opts.args49 opts.name = opts.args
48 opts.summary = opts.args50 opts.summary = opts.args
49 opts.description = opts.args51 opts.description = opts.args
5052
=== modified file 'smart/commands/upgrade.py'
--- smart/commands/upgrade.py 2010-12-05 15:11:14 +0000
+++ smart/commands/upgrade.py 2013-02-12 14:46:20 +0000
@@ -91,6 +91,9 @@
9191
92def main(ctrl, opts):92def main(ctrl, opts):
9393
94 # Argument check
95 opts.check_args_of_option("flag", 1)
96
94 if opts.explain:97 if opts.explain:
95 sysconf.set("explain-changesets", True, soft=True)98 sysconf.set("explain-changesets", True, soft=True)
9699
97100
=== modified file 'smart/control.py'
--- smart/control.py 2011-10-05 22:02:21 +0000
+++ smart/control.py 2013-02-12 14:46:20 +0000
@@ -447,7 +447,7 @@
447 queue = marked.keys()447 queue = marked.keys()
448 while queue:448 while queue:
449 pkg = queue.pop(0)449 pkg = queue.pop(0)
450 for req in pkg.requires:450 for req in pkg.requires + pkg.recommends:
451 for prv in req.providedby:451 for prv in req.providedby:
452 for prvpkg in prv.packages:452 for prvpkg in prv.packages:
453 if (prvpkg.installed and453 if (prvpkg.installed and
@@ -794,7 +794,7 @@
794 pkglst = []794 pkglst = []
795 for pkg in changeset:795 for pkg in changeset:
796 n = 0796 n = 0
797 for req in pkg.requires:797 for req in pkg.requires + pkg.recommends:
798 for prv in req.providedby:798 for prv in req.providedby:
799 for prvpkg in prv.packages:799 for prvpkg in prv.packages:
800 if changeset.get(prvpkg) is INSTALL:800 if changeset.get(prvpkg) is INSTALL:
801801
=== modified file 'smart/plugins/detectsys.py'
--- smart/plugins/detectsys.py 2011-09-22 20:06:16 +0000
+++ smart/plugins/detectsys.py 2013-02-12 14:46:20 +0000
@@ -20,10 +20,11 @@
20# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA20# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21#21#
22from smart import *22from smart import *
23from smart.backends.rpm.base import rpm_join_dbpath
23import os24import os
2425
25def detectRPMSystem():26def detectRPMSystem():
26 dir = os.path.join(sysconf.get("rpm-root", "/"),27 dir = rpm_join_dbpath(sysconf.get("rpm-root", "/"),
27 sysconf.get("rpm-dbpath", "var/lib/rpm"))28 sysconf.get("rpm-dbpath", "var/lib/rpm"))
28 file = os.path.join(dir, "Packages")29 file = os.path.join(dir, "Packages")
29 if os.path.exists(file):30 if os.path.exists(file):
3031
=== modified file 'smart/searcher.py'
--- smart/searcher.py 2010-06-22 10:41:16 +0000
+++ smart/searcher.py 2013-02-12 14:46:20 +0000
@@ -45,9 +45,9 @@
4545
46 - provides is matched in Provides.search(), for the same reason.46 - provides is matched in Provides.search(), for the same reason.
4747
48 - requires, upgrades, and conflicts don't have special searching48 - requires, recommends, upgrades, and conflicts don't have special
49 methods. Instead, their usual match() method is given an instance49 searching methods. Instead, their usual match() method is given
50 of the Provides type.50 an instance of the Provides type.
5151
52 - group, path, url, and other information which is found by52 - group, path, url, and other information which is found by
53 PackageInfo, is searched by the Loader.search() method and53 PackageInfo, is searched by the Loader.search() method and
@@ -62,6 +62,7 @@
62 self.nameversion = []62 self.nameversion = []
63 self.provides = []63 self.provides = []
64 self.requires = []64 self.requires = []
65 self.recommends = []
65 self.upgrades = []66 self.upgrades = []
66 self.conflicts = []67 self.conflicts = []
67 self.path = []68 self.path = []
@@ -76,6 +77,7 @@
76 del self.nameversion[:]77 del self.nameversion[:]
77 del self.provides[:]78 del self.provides[:]
78 del self.requires[:]79 del self.requires[:]
80 del self.recommends[:]
79 del self.upgrades[:]81 del self.upgrades[:]
80 del self.conflicts[:]82 del self.conflicts[:]
81 del self.path[:]83 del self.path[:]
@@ -122,6 +124,8 @@
122 self.addProvides(s[9:], cutoff)124 self.addProvides(s[9:], cutoff)
123 elif s.startswith("requires:"):125 elif s.startswith("requires:"):
124 self.addRequires(s[9:])126 self.addRequires(s[9:])
127 elif s.startswith("recommends:"):
128 self.addRecommends(s[11:])
125 elif s.startswith("upgrades:"):129 elif s.startswith("upgrades:"):
126 self.addUpgrades(s[9:])130 self.addUpgrades(s[9:])
127 elif s.startswith("conflicts:"):131 elif s.startswith("conflicts:"):
@@ -151,6 +155,7 @@
151 return s and (155 return s and (
152 s.startswith("provides:") or156 s.startswith("provides:") or
153 s.startswith("requires:") or157 s.startswith("requires:") or
158 s.startswith("recommends:") or
154 s.startswith("upgrades:") or159 s.startswith("upgrades:") or
155 s.startswith("conflicts:") or160 s.startswith("conflicts:") or
156 s.startswith("url:") or161 s.startswith("url:") or
@@ -182,6 +187,9 @@
182 def addRequires(self, s):187 def addRequires(self, s):
183 self.requires.append(self._buildProvides(s))188 self.requires.append(self._buildProvides(s))
184189
190 def addRecommends(self, s):
191 self.recommends.append(self._buildProvides(s))
192
185 def addUpgrades(self, s):193 def addUpgrades(self, s):
186 self.upgrades.append(self._buildProvides(s))194 self.upgrades.append(self._buildProvides(s))
187195
188196
=== modified file 'smart/transaction.py'
--- smart/transaction.py 2010-06-22 17:01:09 +0000
+++ smart/transaction.py 2013-02-12 14:46:20 +0000
@@ -573,7 +573,7 @@
573 self._remove(namepkg, changeset, locked, pending, depth)573 self._remove(namepkg, changeset, locked, pending, depth)
574574
575 # Install packages required by this one.575 # Install packages required by this one.
576 for req in pkg.requires:576 for req in pkg.requires + pkg.recommends:
577577
578 # Check if someone is already providing it.578 # Check if someone is already providing it.
579 prvpkgs = {}579 prvpkgs = {}
@@ -596,8 +596,12 @@
596596
597 if not prvpkgs:597 if not prvpkgs:
598 # No packages provide it at all. Give up.598 # No packages provide it at all. Give up.
599 raise Failed, _("Can't install %s: no package provides %s") % \599 if req in pkg.requires:
600 (pkg, req)600 raise Failed, _("Can't install %s: no package provides %s") % \
601 (pkg, req)
602 else:
603 # It's only a recommend, skip
604 continue
601605
602 if len(prvpkgs) == 1:606 if len(prvpkgs) == 1:
603 # Don't check locked here. prvpkgs was607 # Don't check locked here. prvpkgs was
@@ -1359,7 +1363,7 @@
1359 set = self._changeset1363 set = self._changeset
13601364
1361 # Check all dependencies needed by this package.1365 # Check all dependencies needed by this package.
1362 for req in pkg.requires:1366 for req in pkg.requires + pkg.recommends:
13631367
1364 # Check if any already installed or to be installed1368 # Check if any already installed or to be installed
1365 # package will solve the problem.1369 # package will solve the problem.
@@ -1424,8 +1428,9 @@
14241428
1425 # There are no solutions for the problem.1429 # There are no solutions for the problem.
1426 # Should we really care about it?1430 # Should we really care about it?
1427 if (self._forcerequires or1431 if ((self._forcerequires or
1428 isinstance(req, PreRequires)):1432 isinstance(req, PreRequires))
1433 and req in pkg.requires):
1429 raise Error, _("No providers for '%s', "1434 raise Error, _("No providers for '%s', "
1430 "required by '%s'") % (req, pkg)1435 "required by '%s'") % (req, pkg)
14311436
@@ -1625,7 +1630,7 @@
1625 return n1630 return n
16261631
1627def forwardRequires(pkg, map):1632def forwardRequires(pkg, map):
1628 for req in pkg.requires:1633 for req in pkg.requires + pkg.recommends:
1629 if req not in map:1634 if req not in map:
1630 map[req] = True1635 map[req] = True
1631 for prv in req.providedby:1636 for prv in req.providedby:
@@ -1794,6 +1799,15 @@
1794 iface.info(_("Unsatisfied dependency: %s requires %s") %1799 iface.info(_("Unsatisfied dependency: %s requires %s") %
1795 (pkg, req))1800 (pkg, req))
17961801
1802 for req in pkg.recommends:
1803 for prv in req.providedby:
1804 for prvpkg in prv.packages:
1805 if prvpkg in relateset:
1806 break
1807 else:
1808 continue
1809 break
1810
1797 if not pkg.installed:1811 if not pkg.installed:
1798 continue1812 continue
17991813
18001814
=== modified file 'smart/util/optparse.py'
--- smart/util/optparse.py 2005-06-14 17:41:24 +0000
+++ smart/util/optparse.py 2013-02-12 14:46:20 +0000
@@ -70,6 +70,8 @@
70import types70import types
71import textwrap71import textwrap
72from gettext import gettext as _72from gettext import gettext as _
73from smart import Error
74import re
7375
74def _repr(self):76def _repr(self):
75 return "<%s at 0x%x: %s>" % (self.__class__.__name__, id(self), self)77 return "<%s at 0x%x: %s>" % (self.__class__.__name__, id(self), self)
@@ -708,6 +710,12 @@
708 self.action, self.dest, opt, value, values, parser)710 self.action, self.dest, opt, value, values, parser)
709711
710 def take_action(self, action, dest, opt, value, values, parser):712 def take_action(self, action, dest, opt, value, values, parser):
713 # Keep all the options in the command line in the '_given_opts' array
714 # This will be used later to validate the command line
715 given_opts = getattr(parser.values, "_given_opts", [])
716 user_opt = re.sub(r"^\-*", "", opt).replace("-", "_")
717 given_opts.append(user_opt)
718 setattr(parser.values, "_given_opts", given_opts)
711 if action == "store":719 if action == "store":
712 setattr(values, dest, value)720 setattr(values, dest, value)
713 elif action == "store_const":721 elif action == "store_const":
@@ -819,6 +827,54 @@
819 setattr(self, attr, value)827 setattr(self, attr, value)
820 return getattr(self, attr)828 return getattr(self, attr)
821829
830 # Check if the given option has the specified number of arguments
831 # Raise an error if the option has an invalid number of arguments
832 # A negative number for 'nargs' means "at least |nargs| arguments are needed"
833 def check_args_of_option(self, opt, nargs, err=None):
834 given_opts = getattr(self, "_given_opts", [])
835 if not opt in given_opts:
836 return
837 values = getattr(self, opt, [])
838 if type(values) != type([]):
839 return
840 if nargs < 0:
841 nargs = -nargs
842 if len(values) >= nargs:
843 return
844 if not err:
845 if nargs == 1:
846 err = _("Option '%s' requires at least one argument") % opt
847 else:
848 err = _("Option '%s' requires at least %d arguments") % (opt, nargs)
849 raise Error, err
850 elif nargs == 0:
851 if len( values ) == 0:
852 return
853 raise Error, err
854 else:
855 if len(values) == nargs:
856 return
857 if not err:
858 if nargs == 1:
859 err = _("Option '%s' requires one argument") % opt
860 else:
861 err = _("Option '%s' requires %d arguments") % (opt, nargs)
862 raise Error, err
863
864 # Check that at least one of the options in 'actlist' was given as an argument
865 # to the command 'cmdname'
866 def ensure_action(self, cmdname, actlist):
867 given_opts = getattr(self, "_given_opts", [])
868 for action in actlist:
869 if action in given_opts:
870 return
871 raise Error, _("No action specified for command '%s'") % cmdname
872
873 # Check if there are any other arguments left after parsing the command line and
874 # raise an error if such arguments are found
875 def check_remaining_args(self):
876 if self.args:
877 raise Error, _("Invalid argument(s) '%s'" % str(self.args))
822878
823class OptionContainer:879class OptionContainer:
824880

Subscribers

People subscribed via source and target branches