diff options
| author | Michael Vogt <michael.vogt@ubuntu.com> | 2005-06-20 21:26:23 +0000 |
|---|---|---|
| committer | Michael Vogt <michael.vogt@ubuntu.com> | 2005-06-20 21:26:23 +0000 |
| commit | c25600f6cfb209dde14fbfc17aaef78519411a30 (patch) | |
| tree | fb9e5b57e2404b76e568689b7d719461d5f10e90 | |
| parent | 33c18310943c8ee582fe57b1295e753f417d5eb8 (diff) | |
| download | python-apt-c25600f6cfb209dde14fbfc17aaef78519411a30.tar.gz | |
* added support for the pkgProblemResolver()
| -rw-r--r-- | apt/cache.py | 6 | ||||
| -rw-r--r-- | apt/package.py | 20 | ||||
| -rw-r--r-- | python/apt_pkgmodule.cc | 3 | ||||
| -rw-r--r-- | python/apt_pkgmodule.h | 4 | ||||
| -rw-r--r-- | python/depcache.cc | 162 | ||||
| -rw-r--r-- | tests/apt-test.py | 7 | ||||
| -rw-r--r-- | tests/pkgproblemresolver.py | 69 |
7 files changed, 264 insertions, 7 deletions
diff --git a/apt/cache.py b/apt/cache.py index 39dca925..9852f26f 100644 --- a/apt/cache.py +++ b/apt/cache.py @@ -142,11 +142,13 @@ class FilteredCache(object): " set the current active filter " self._filters = [] self._filters.append(filter) - self._reapplyFilter() + #self._reapplyFilter() + # force a cache-change event that will result in a refiltering + self.cache.CachePostChange() def FilterCachePostChange(self): " called internally if the cache changes, emit a signal then " - print "FilterCachePostChange()" + #print "FilterCachePostChange()" self._reapplyFilter() # def connect(self, name, callback): diff --git a/apt/package.py b/apt/package.py index de9a9dbb..806cb0c3 100644 --- a/apt/package.py +++ b/apt/package.py @@ -19,12 +19,18 @@ class Package(object): ver = self._depcache.GetCandidateVer(self._pkg) else: ver = self._pkg.CurrentVer + + # check if we found a version + if ver == None: + print "No version for: %s (Candiate: %s)" % (self._pkg.Name, UseCandidate) + return False + if ver.FileList == None: - print "got: %s " % ver.FileList - return + print "No FileList for: %s " % self._pkg.Name() + return False file, index = ver.FileList.pop(0) self._records.Lookup((file,index)) - + return True # basic information def Name(self): @@ -123,9 +129,15 @@ class Package(object): self._pcache.CachePreChange() self._depcache.MarkDelete(self._pkg) self._pcache.CachePostChange() - def MarkInstall(self): + def MarkInstall(self, autoFix=True): self._pcache.CachePreChange() self._depcache.MarkInstall(self._pkg) + # try to fix broken stuff + if autoFix and self._depcache.BrokenCount > 0: + fixer = apt_pkg.GetPkgProblemResolver(self._depcache) + fixer.Clear(self._pkg) + fixer.Protect(self._pkg) + fixer.Resolve(True) self._pcache.CachePostChange() def MarkUpgrade(self): if self.IsUpgradable(): diff --git a/python/apt_pkgmodule.cc b/python/apt_pkgmodule.cc index 7bf7f3e3..1c58316c 100644 --- a/python/apt_pkgmodule.cc +++ b/python/apt_pkgmodule.cc @@ -336,6 +336,9 @@ static PyMethodDef methods[] = {"GetPkgSrcRecords",GetPkgSrcRecords,METH_VARARGS,"GetPkgSrcRecords() -> PkgSrcRecords"}, {"GetPkgSourceList",GetPkgSourceList,METH_VARARGS,"GetPkgSourceList() -> PkgSourceList"}, + // misc + {"GetPkgProblemResolver",GetPkgProblemResolver,METH_VARARGS,"GetDepProblemResolver(DepCache) -> PkgProblemResolver"}, + // Cdrom {"GetCdrom",GetCdrom,METH_VARARGS,"GetCdrom() -> Cdrom"}, diff --git a/python/apt_pkgmodule.h b/python/apt_pkgmodule.h index f239f01d..eefa6ca7 100644 --- a/python/apt_pkgmodule.h +++ b/python/apt_pkgmodule.h @@ -64,6 +64,10 @@ PyObject *TmpGetCache(PyObject *Self,PyObject *Args); extern PyTypeObject PkgDepCacheType; PyObject *GetDepCache(PyObject *Self,PyObject *Args); +// pkgProblemResolver +extern PyTypeObject PkgProblemResolverType; +PyObject *GetPkgProblemResolver(PyObject *Self, PyObject *Args); + // cdrom extern PyTypeObject PkgCdromType; PyObject *GetCdrom(PyObject *Self,PyObject *Args); diff --git a/python/depcache.cc b/python/depcache.cc index 027fb9bb..cb2cd540 100644 --- a/python/depcache.cc +++ b/python/depcache.cc @@ -28,6 +28,8 @@ #include "progress.h" + + // DepCache Class /*{{{*/ // --------------------------------------------------------------------- @@ -188,6 +190,25 @@ static PyObject *PkgDepCacheCommit(PyObject *Self,PyObject *Args) return HandleErrors(Py_None); } +static PyObject *PkgDepCacheSetCandidateVer(PyObject *Self,PyObject *Args) +{ + pkgDepCache *depcache = GetCpp<pkgDepCache *>(Self); + PyObject *PackageObj; + PyObject *VersionObj; + if (PyArg_ParseTuple(Args,"O!O!", + &PackageType, &PackageObj, + &VersionType, &VersionObj) == 0) + return 0; + + pkgCache::PkgIterator &Pkg = GetCpp<pkgCache::PkgIterator>(PackageObj); + pkgCache::VerIterator I = GetCpp<pkgCache::VerIterator>(VersionObj); + if(I.end()) { + return HandleErrors(Py_BuildValue("b",false)); + } + depcache->SetCandidateVersion(I); + + return HandleErrors(Py_BuildValue("b",true)); +} static PyObject *PkgDepCacheGetCandidateVer(PyObject *Self,PyObject *Args) { @@ -298,7 +319,8 @@ static PyObject *PkgDepCacheMarkInstall(PyObject *Self,PyObject *Args) return 0; pkgCache::PkgIterator &Pkg = GetCpp<pkgCache::PkgIterator>(PackageObj); - depcache->MarkInstall(Pkg); + depcache->MarkInstall(Pkg, true); + pkgDepCache::StateCache & State = (*depcache)[Pkg]; Py_INCREF(Py_None); return HandleErrors(Py_None); @@ -438,6 +460,7 @@ static PyMethodDef PkgDepCacheMethods[] = { {"Init",PkgDepCacheInit,METH_VARARGS,"Init the depcache (done on construct automatically)"}, {"GetCandidateVer",PkgDepCacheGetCandidateVer,METH_VARARGS,"Get candidate version"}, + {"SetCandidateVer",PkgDepCacheSetCandidateVer,METH_VARARGS,"Get candidate version"}, // global cache operations {"Upgrade",PkgDepCacheUpgrade,METH_VARARGS,"Perform Upgrade (optional boolean argument if dist-upgrade should be performed)"}, @@ -537,3 +560,140 @@ PyObject *GetDepCache(PyObject *Self,PyObject *Args) /*}}}*/ + + +// pkgProblemResolver Class /*{{{*/ +// --------------------------------------------------------------------- + + +PyObject *GetPkgProblemResolver(PyObject *Self,PyObject *Args) +{ + PyObject *Owner; + if (PyArg_ParseTuple(Args,"O!",&PkgDepCacheType,&Owner) == 0) + return 0; + + pkgDepCache *depcache = GetCpp<pkgDepCache*>(Owner); + pkgProblemResolver *fixer = new pkgProblemResolver(depcache); + CppOwnedPyObject<pkgProblemResolver*> *PkgProblemResolverPyObj; + PkgProblemResolverPyObj = CppOwnedPyObject_NEW<pkgProblemResolver*>(Owner, + &PkgProblemResolverType, + fixer); + HandleErrors(PkgProblemResolverPyObj); + + return PkgProblemResolverPyObj; + +} + + +static PyObject *PkgProblemResolverResolve(PyObject *Self,PyObject *Args) +{ + pkgProblemResolver *fixer = GetCpp<pkgProblemResolver *>(Self); + + char brokenFix=1; + if (PyArg_ParseTuple(Args,"|b",&brokenFix) == 0) + return 0; + + bool res = fixer->Resolve(brokenFix); + + return HandleErrors(Py_BuildValue("b", res)); +} + +static PyObject *PkgProblemResolverResolveByKeep(PyObject *Self,PyObject *Args) +{ + pkgProblemResolver *fixer = GetCpp<pkgProblemResolver *>(Self); + if (PyArg_ParseTuple(Args,"") == 0) + return 0; + bool res = fixer->ResolveByKeep(); + return HandleErrors(Py_BuildValue("b", res)); +} + +static PyObject *PkgProblemResolverProtect(PyObject *Self,PyObject *Args) +{ + pkgProblemResolver *fixer = GetCpp<pkgProblemResolver *>(Self); + PyObject *PackageObj; + if (PyArg_ParseTuple(Args,"O!",&PackageType,&PackageObj) == 0) + return 0; + pkgCache::PkgIterator &Pkg = GetCpp<pkgCache::PkgIterator>(PackageObj); + fixer->Protect(Pkg); + Py_INCREF(Py_None); + return HandleErrors(Py_None); + +} +static PyObject *PkgProblemResolverRemove(PyObject *Self,PyObject *Args) +{ + pkgProblemResolver *fixer = GetCpp<pkgProblemResolver *>(Self); + PyObject *PackageObj; + if (PyArg_ParseTuple(Args,"O!",&PackageType,&PackageObj) == 0) + return 0; + pkgCache::PkgIterator &Pkg = GetCpp<pkgCache::PkgIterator>(PackageObj); + fixer->Remove(Pkg); + Py_INCREF(Py_None); + return HandleErrors(Py_None); +} + +static PyObject *PkgProblemResolverClear(PyObject *Self,PyObject *Args) +{ + pkgProblemResolver *fixer = GetCpp<pkgProblemResolver *>(Self); + PyObject *PackageObj; + if (PyArg_ParseTuple(Args,"O!",&PackageType,&PackageObj) == 0) + return 0; + pkgCache::PkgIterator &Pkg = GetCpp<pkgCache::PkgIterator>(PackageObj); + fixer->Clear(Pkg); + Py_INCREF(Py_None); + return HandleErrors(Py_None); +} + +static PyObject *PkgProblemResolverInstallProtect(PyObject *Self,PyObject *Args) +{ + pkgProblemResolver *fixer = GetCpp<pkgProblemResolver *>(Self); + if (PyArg_ParseTuple(Args,"") == 0) + return 0; + fixer->InstallProtect(); + Py_INCREF(Py_None); + return HandleErrors(Py_None); +} + +static PyMethodDef PkgProblemResolverMethods[] = +{ + // config + {"Protect", PkgProblemResolverProtect, METH_VARARGS, "Protect(PkgIterator)"}, + {"Remove", PkgProblemResolverRemove, METH_VARARGS, "Remove(PkgIterator)"}, + {"Clear", PkgProblemResolverClear, METH_VARARGS, "Clear(PkgIterator)"}, + {"InstallProtect", PkgProblemResolverInstallProtect, METH_VARARGS, "ProtectInstalled()"}, + + // Actions + {"Resolve", PkgProblemResolverResolve, METH_VARARGS, "Try to intelligently resolve problems by installing and removing packages"}, + {"ResolveByKeep", PkgProblemResolverResolveByKeep, METH_VARARGS, "Try to resolv problems only by using keep"}, + {} +}; + + +static PyObject *ProblemResolverAttr(PyObject *Self,char *Name) +{ + pkgProblemResolver *fixer = GetCpp<pkgProblemResolver *>(Self); + + return Py_FindMethod(PkgProblemResolverMethods,Self,Name); +} + + +PyTypeObject PkgProblemResolverType = +{ + PyObject_HEAD_INIT(&PyType_Type) + 0, // ob_size + "pkgProblemResolver", // tp_name + sizeof(CppOwnedPyObject<pkgProblemResolver *>), // tp_basicsize + 0, // tp_itemsize + // Methods + CppOwnedDealloc<pkgProblemResolver *>, // tp_dealloc + 0, // tp_print + ProblemResolverAttr, // tp_getattr + 0, // tp_setattr + 0, // tp_compare + 0, // tp_repr + 0, // tp_as_number + 0, // tp_as_sequence + 0, // tp_as_mapping + 0, // tp_hash +}; + + /*}}}*/ diff --git a/tests/apt-test.py b/tests/apt-test.py index 4e41ae00..6ae9f702 100644 --- a/tests/apt-test.py +++ b/tests/apt-test.py @@ -4,4 +4,11 @@ if __name__ == "__main__": progress = apt.progress.OpTextProgress() cache = apt.Cache(progress) print cache + for name in cache.keys(): + pkg = cache[name] + if pkg.IsUpgradable(): + pkg.MarkInstall() + for pkg in cache.GetChanges(): + print pkg.Name() + print "Broken: %s " % cache._depcache.BrokenCount diff --git a/tests/pkgproblemresolver.py b/tests/pkgproblemresolver.py new file mode 100644 index 00000000..27747e43 --- /dev/null +++ b/tests/pkgproblemresolver.py @@ -0,0 +1,69 @@ +#!/usr/bin/env python2.4 +# +# Test for the DepCache code +# + +import apt_pkg +import sys + +def main(): + apt_pkg.init() + cache = apt_pkg.GetCache() + depcache = apt_pkg.GetDepCache(cache) + depcache.Init() + i=0 + all=cache.PackageCount + print "Running DepCache test on all packages" + print "(trying to install each and then mark it keep again):" + # first, get all pkgs + for pkg in cache.Packages: + i += 1 + x = pkg.Name + # then get each version + ver =depcache.GetCandidateVer(pkg) + if ver != None: + depcache.MarkInstall(pkg) + if depcache.BrokenCount > 0: + fixer = apt_pkg.GetPkgProblemResolver(depcache) + fixer.Clear(pkg) + fixer.Protect(pkg) + # we first try to resolve the problem + # with the package that should be installed + # protected + try: + fixer.Resolve(True) + except SystemError: + # the pkg seems to be broken, the + # returns a exception + fixer.Clear(pkg) + fixer.Resolve(True) + if not depcache.MarkedInstall(pkg): + print "broken in archive: %s " % pkg.Name + fixer = None + if depcache.InstCount == 0: + if depcache.IsUpgradable(pkg): + print "Error marking %s for install" % x + for p in cache.Packages: + if depcache.MarkedInstall(p) or depcache.MarkedUpgrade(p): + depcache.MarkKeep(p) + if depcache.InstCount != 0: + print "Error undoing the selection for %s" % x + print "\r%i/%i=%.3f%% " % (i,all,(float(i)/float(all)*100)), + + print + print "Trying Upgrade:" + depcache.Upgrade() + print "To install: %s " % depcache.InstCount + print "To remove: %s " % depcache.DelCount + print "Kept back: %s " % depcache.KeepCount + + print "Trying DistUpgrade:" + depcache.Upgrade(True) + print "To install: %s " % depcache.InstCount + print "To remove: %s " % depcache.DelCount + print "Kept back: %s " % depcache.KeepCount + + +if __name__ == "__main__": + main() + sys.exit(0) |
