[pacman-dev] [patch] III. deps.c/checkdeps tuned remove-check + remove041.py

Nagy Gabor ngaba at petra.hos.u-szeged.hu
Sat Apr 21 17:57:13 EDT 2007


Hi!
My patch creates remove041.py remove050.py and patches remove040.py.
I removed a messy part of the source and patched sync.c instead; and
implemented sophisticated (but slower) remove-checkdep (derived from the
upgrade-checkdep). I also add a small speed-tuning to
upgrade-checkdep ;-)
Notes: sync895.py reports false error imho, we should implement --debug
to pactest. (sync.c lines 680- is very messy... )
Enjoy, ngaba
--------------------
diff -Naur pacman-lib/lib/libalpm/deps.c pacman-lib.new/lib/libalpm/deps.c
--- pacman-lib/lib/libalpm/deps.c	2007-03-19 05:23:45.000000000 +0100
+++ pacman-lib.new/lib/libalpm/deps.c	2007-04-21 22:45:25.000000000 +0200
@@ -234,12 +234,12 @@
 			for(j = alpm_pkg_get_requiredby(oldpkg); j; j = j->next) {
 				pmpkg_t *p;
 				found = 0;
-				if((p = _alpm_db_get_pkgfromcache(db, j->data)) == NULL) {
-					/* hmmm... package isn't installed.. */
+				if(_alpm_pkg_find(j->data, packages)) {
+					/* this package also in the upgrade list, so don't worry about it */
 					continue;
 				}
-				if(_alpm_pkg_find(alpm_pkg_get_name(p), packages)) {
-					/* this package also in the upgrade list, so don't worry about it */
+				if((p = _alpm_db_get_pkgfromcache(db, j->data)) == NULL) {
+					/* hmmm... package isn't installed.. */
 					continue;
 				}
 				for(k = alpm_pkg_get_depends(p); k; k = k->next) {
@@ -370,52 +370,55 @@
 			}
 		}
 	} else if(op == PM_TRANS_TYPE_REMOVE) {
-		/* check requiredby fields */
 		for(i = packages; i; i = i->next) {
-			pmpkg_t *tp = i->data;
-			if(tp == NULL) {
+			pmpkg_t *rempkg = i->data;
+
+			if(rempkg == NULL) {
+				_alpm_log(PM_LOG_DEBUG, _("null package found in package list"));
 				continue;
 			}
 
-			found=0;
-			for(j = alpm_pkg_get_requiredby(tp); j; j = j->next) {
-				/* Search for 'reqname' in packages for removal */
-				char *reqname = j->data;
-				alpm_list_t *x = NULL;
-				for(x = packages; x; x = x->next) {
-					pmpkg_t *xp = x->data;
-					if(strcmp(reqname, alpm_pkg_get_name(xp)) == 0) {
-						found = 1;
-						break;
-					}
+			for(j = alpm_pkg_get_requiredby(rempkg); j; j = j->next) {
+				pmpkg_t *p;
+				found = 0;
+				if(_alpm_pkg_find(j->data, packages)) {
+					/* this package also in the remove list, so don't worry about it */
+					continue;
 				}
-				if(!found) {
-					/* check if a package in trans->packages provides this package */
-					for(k = trans->packages; !found && k; k=k->next) {
-						pmpkg_t *spkg = NULL;
-						if(trans->type == PM_TRANS_TYPE_SYNC) {
-							pmsyncpkg_t *sync = k->data;
-							spkg = sync->pkg;
-						} else {
-							spkg = k->data;
-						}
-						if(spkg) {
-							if(alpm_list_find_str(alpm_pkg_get_provides(spkg), tp->name)) {
-								found = 1;
+				if((p = _alpm_db_get_pkgfromcache(db, j->data)) == NULL) {
+					/* hmmm... package isn't installed.. */
+					continue;
+				}
+				for(k = alpm_pkg_get_depends(p); k; k = k->next) {
+					pmdepend_t *depend = alpm_splitdep(k->data);
+					if(depend == NULL) {
+						continue;
+					}					
+					/* if rempkg satisfied this dep, we try to find an other satisfyer (which won't be removed)*/
+					if(alpm_depcmp(rempkg, depend)) {	
+						int satisfied = 0;
+						for(l = _alpm_db_get_pkgcache(db); l; l = l->next) {
+							pmpkg_t *pkg = l->data;
+							if(alpm_depcmp(pkg, depend) && !_alpm_pkg_find(alpm_pkg_get_name(pkg), packages)) {
+								_alpm_log(PM_LOG_DEBUG, _("checkdeps: dependency '%s' satisfied by installed package '%s'"),
+												depend->name, alpm_pkg_get_name(pkg));
+							satisfied = 1;
+							break;
 							}
 						}
-					}
-					if(!found) {
-						_alpm_log(PM_LOG_DEBUG, _("checkdeps: found %s as required by %s"),
-								reqname, alpm_pkg_get_name(tp));
-						miss = _alpm_depmiss_new(alpm_pkg_get_name(tp), PM_DEP_TYPE_DEPEND,
-																		 PM_DEP_MOD_ANY, j->data, NULL);
-						if(!_alpm_depmiss_isin(miss, baddeps)) {
-							baddeps = alpm_list_add(baddeps, miss);
-						} else {
-							FREE(miss);
+						if(!satisfied) {
+							_alpm_log(PM_LOG_DEBUG, _("checkdeps: found %s as required by %s"),
+												alpm_pkg_get_name(rempkg), alpm_pkg_get_name(p));
+							miss = _alpm_depmiss_new(p->name, PM_DEP_TYPE_DEPEND, depend->mod,
+																			 depend->name, depend->version);
+							if(!_alpm_depmiss_isin(miss, baddeps)) {
+								baddeps = alpm_list_add(baddeps, miss);
+							} else {
+								FREE(miss);
+							}
 						}
 					}
+					free(depend);
 				}
 			}
 		}
diff -Naur pacman-lib/pactest/tests/remove040.py pacman-lib.new/pactest/tests/remove040.py
--- pacman-lib/pactest/tests/remove040.py	2007-03-04 01:14:26.000000000 +0100
+++ pacman-lib.new/pactest/tests/remove040.py	2007-04-21 21:00:03.000000000 +0200
@@ -10,9 +10,9 @@
 self.addpkg2db("local", lp2)
 
 
-self.args = "-R %s" % lp1.name
+self.args = "-R %s" % lp2.name
 
-self.addrule("PACMAN_RETCODE=0")
-self.addrule("!PKG_EXIST=pkg1")
+self.addrule("!PACMAN_RETCODE=0")
+self.addrule("PKG_EXIST=pkg1")
 self.addrule("PKG_EXIST=pkg2")
-self.addrule("!PKG_REQUIREDBY=pkg2|pkg1")
+self.addrule("PKG_REQUIREDBY=pkg2|pkg1")
diff -Naur pacman-lib/pactest/tests/remove041.py pacman-lib.new/pactest/tests/remove041.py
--- pacman-lib/pactest/tests/remove041.py	1970-01-01 01:00:00.000000000 +0100
+++ pacman-lib.new/pactest/tests/remove041.py	2007-04-21 22:56:16.000000000 +0200
@@ -0,0 +1,21 @@
+self.description = "Remove a package required by another package, but no longer needed (multiple provision)"
+
+lp1 = pmpkg("pkg1")
+lp1.provides = ["imaginary"]
+lp1.requiredby = ["pkg3"]
+self.addpkg2db("local", lp1)
+
+lp2 = pmpkg("pkg2")
+lp2.provides = ["imaginary"]
+lp2.requiredby = ["pkg3"]
+self.addpkg2db("local", lp2)
+
+lp3 = pmpkg("pkg3")
+lp3.depends = ["imaginary"]
+self.addpkg2db("local", lp3)
+
+self.args = "-R %s" % lp1.name
+
+self.addrule("PACMAN_RETCODE=0")
+self.addrule("!PKG_EXIST=pkg1")
+self.addrule("PKG_EXIST=pkg2")




More information about the pacman-dev mailing list