summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Vogt <michael.vogt@ubuntu.com>2005-06-20 21:26:23 +0000
committerMichael Vogt <michael.vogt@ubuntu.com>2005-06-20 21:26:23 +0000
commitc25600f6cfb209dde14fbfc17aaef78519411a30 (patch)
treefb9e5b57e2404b76e568689b7d719461d5f10e90
parent33c18310943c8ee582fe57b1295e753f417d5eb8 (diff)
downloadpython-apt-c25600f6cfb209dde14fbfc17aaef78519411a30.tar.gz
* added support for the pkgProblemResolver()
-rw-r--r--apt/cache.py6
-rw-r--r--apt/package.py20
-rw-r--r--python/apt_pkgmodule.cc3
-rw-r--r--python/apt_pkgmodule.h4
-rw-r--r--python/depcache.cc162
-rw-r--r--tests/apt-test.py7
-rw-r--r--tests/pkgproblemresolver.py69
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)