razor.c
changeset 149 43cac7931189
parent 146 1d4043c9f869
child 150 b838d74663a7
     1.1 --- a/razor.c	Wed Mar 05 19:01:51 2008 -0500
     1.2 +++ b/razor.c	Thu Mar 06 00:55:51 2008 -0500
     1.3 @@ -1794,9 +1794,9 @@
     1.4  
     1.5  		if (packages[i].state == RAZOR_PACKAGE_REMOVE) {
     1.6  			if (sp < send && strcmp(packages[i].name, &spool[sp->name]) == 0) {
     1.7 -				packages[i].package = sp;
     1.8 +				packages[i].old_package = sp;
     1.9  				packages[i].name = &spool[sp->name];
    1.10 -				packages[i].version = &spool[sp->version];
    1.11 +				packages[i].old_version = &spool[sp->version];
    1.12  				bitarray_set(&trans->syspkgs, sp - spkgs, 0);
    1.13  			} else {
    1.14  				packages[i].name = strdup(packages[i].name);
    1.15 @@ -1805,10 +1805,12 @@
    1.16  			}
    1.17  		} else {
    1.18  			if (up < uend && strcmp(packages[i].name, &upool[up->name]) == 0) {
    1.19 -				packages[i].package = up;
    1.20 +				packages[i].new_package = up;
    1.21  				packages[i].name = &upool[up->name];
    1.22 -				packages[i].version = &upool[up->version];
    1.23 +				packages[i].new_version = &upool[up->version];
    1.24  				if (sp < send && strcmp(packages[i].name, &spool[sp->name]) == 0) {
    1.25 +					packages[i].old_package = sp;
    1.26 +					packages[i].old_version = &spool[sp->version];
    1.27  					if (versioncmp(&spool[sp->version], &upool[up->version]) >= 0) {
    1.28  						packages[i].state = RAZOR_PACKAGE_UP_TO_DATE;
    1.29  						trans->errors++;
    1.30 @@ -1846,8 +1848,11 @@
    1.31  		if (strcmp(&spool[sp->name], &upool[up->name]) == 0) {
    1.32  			tp = array_add(&trans->packages, sizeof *tp);
    1.33  			memset(tp, 0, sizeof *tp);
    1.34 +			tp->old_package = sp;
    1.35 +			tp->new_package = up;
    1.36  			tp->name = &upool[up->name];
    1.37 -			tp->version = &upool[up->version];
    1.38 +			tp->old_version = &spool[sp->version];
    1.39 +			tp->new_version = &upool[up->version];
    1.40  			tp->state = RAZOR_PACKAGE_INSTALL;
    1.41  			bitarray_set(&trans->uppkgs, up - upkgs, 1);
    1.42  			bitarray_set(&trans->syspkgs, sp - spkgs, 0);
    1.43 @@ -2136,21 +2141,52 @@
    1.44  	return 0;
    1.45  }
    1.46  
    1.47 +static struct razor_transaction_package *
    1.48 +find_transaction_package(struct razor_transaction_resolver *trans,
    1.49 +			 const char *name)
    1.50 +{
    1.51 +	struct razor_transaction_package *packages;
    1.52 +	int count, i;
    1.53 +
    1.54 +	packages = trans->packages.data;
    1.55 +	count = trans->packages.size / sizeof *packages;
    1.56 +	for (i = 0; i < count; i++) {
    1.57 +		if (packages[i].name && !strcmp(packages[i].name, name))
    1.58 +			return &packages[i];
    1.59 +	}
    1.60 +	return NULL;
    1.61 +}
    1.62 +
    1.63  static void
    1.64  add_transaction_package(struct razor_transaction_resolver *trans,
    1.65 -			struct razor_package *package,
    1.66 +			struct razor_package *new_package,
    1.67 +			struct razor_package *old_package,
    1.68  			enum razor_transaction_package_state state,
    1.69  			const char *req_package,
    1.70  			struct razor_property *req_prop)
    1.71  {
    1.72 -	struct razor_set *package_set, *req_set;
    1.73 -	struct bitarray *reqpkgbits;
    1.74 -	struct razor_transaction_package *tp, *packages;
    1.75 +	struct razor_set *new_package_set, *old_package_set, *req_set;
    1.76 +	struct bitarray *newpkgbits, *oldpkgbits, *reqpkgbits;
    1.77 +	struct razor_transaction_package *tp, *already;
    1.78  	const char *pool;
    1.79  	struct razor_package *pkgs;
    1.80  	struct list *pkg;
    1.81 -
    1.82 -	package_set = package_in_set(package, trans->system) ? trans->system : trans->upstream;
    1.83 +	int contradiction = 0;
    1.84 +
    1.85 +	if (package_in_set(new_package, trans->system)) {
    1.86 +		new_package_set = trans->system;
    1.87 +		newpkgbits = &trans->syspkgs;
    1.88 +	} else {
    1.89 +		new_package_set = trans->upstream;
    1.90 +		newpkgbits = &trans->uppkgs;
    1.91 +	}
    1.92 +	if (package_in_set(old_package, trans->system)) {
    1.93 +		old_package_set = trans->system;
    1.94 +		oldpkgbits = &trans->syspkgs;
    1.95 +	} else {
    1.96 +		old_package_set = trans->upstream;
    1.97 +		oldpkgbits = &trans->uppkgs;
    1.98 +	}
    1.99  	if (property_in_set(req_prop, trans->system)) {
   1.100  		req_set = trans->system;
   1.101  		reqpkgbits = &trans->syspkgs;
   1.102 @@ -2159,48 +2195,67 @@
   1.103  		reqpkgbits = &trans->uppkgs;
   1.104  	}
   1.105  
   1.106 +	if (new_package) {
   1.107 +		pool = new_package_set->string_pool.data;
   1.108 +		already = find_transaction_package(trans, &pool[new_package->name]);
   1.109 +		if (already) {
   1.110 +			if (already->new_package == new_package) {
   1.111 +				/* Already taken care of */
   1.112 +				return;
   1.113 +			}
   1.114 +			/* Oops. We lose */
   1.115 +			if (state != RAZOR_PACKAGE_CONTRADICTION)
   1.116 +				contradiction = 1;
   1.117 +		}
   1.118 +	} else if (old_package) {
   1.119 +		pool = old_package_set->string_pool.data;
   1.120 +		already = find_transaction_package(trans, &pool[old_package->name]);
   1.121 +		if (already) {
   1.122 +			if (already->old_package == old_package) {
   1.123 +				/* Already taken care of */
   1.124 +				return;
   1.125 +			}
   1.126 +			/* Oops. We lose */
   1.127 +			if (state != RAZOR_PACKAGE_CONTRADICTION)
   1.128 +				contradiction = 1;
   1.129 +		}
   1.130 +	} else
   1.131 +		state = RAZOR_PACKAGE_UNSATISFIABLE;
   1.132 +
   1.133  	tp = array_add(&trans->packages, sizeof *tp);
   1.134  	memset(tp, 0, sizeof *tp);
   1.135  
   1.136 -	if (package) {
   1.137 -		int i, count;
   1.138 -
   1.139 -		/* Make sure we aren't already acting on this package */
   1.140 -		packages = trans->packages.data;
   1.141 -		count = trans->packages.size / sizeof *packages;
   1.142 -		pool = package_set->string_pool.data;
   1.143 -		for (i = 0; i < count; i++) {
   1.144 -			if (packages[i].name &&
   1.145 -			    !strcmp(packages[i].name, &pool[package->name])) {
   1.146 -				if (state == packages[i].state) {
   1.147 -					/* Already taken care of */
   1.148 -					return;
   1.149 -				}
   1.150 -				/* Oops. We lose */
   1.151 -				if (state != RAZOR_PACKAGE_CONTRADICTION) {
   1.152 -					add_transaction_package(trans, package,
   1.153 -								RAZOR_PACKAGE_CONTRADICTION,
   1.154 -								NULL, NULL);
   1.155 -				}
   1.156 -				break;
   1.157 -			}
   1.158 -		}
   1.159 -
   1.160 -		tp->package = package;
   1.161 -		tp->name = &pool[package->name];
   1.162 -		tp->version = &pool[package->version];
   1.163 -		tp->state = state;
   1.164 -
   1.165 -		pkgs = package_set->packages.data;
   1.166 -		if (tp->state == RAZOR_PACKAGE_INSTALL)
   1.167 -			bitarray_set(&trans->uppkgs, package - pkgs, 1);
   1.168 -		else if (tp->state == RAZOR_PACKAGE_REMOVE)
   1.169 -			bitarray_set(&trans->syspkgs, package - pkgs, 0);
   1.170 -		else
   1.171 -			trans->errors++;
   1.172 -	} else {
   1.173 -		tp->state = RAZOR_PACKAGE_UNSATISFIABLE;
   1.174 +	if (new_package) {
   1.175 +		pool = new_package_set->string_pool.data;
   1.176 +		tp->new_package = new_package;
   1.177 +		tp->name = &pool[new_package->name];
   1.178 +		tp->new_version = &pool[new_package->version];
   1.179 +
   1.180 +		pkgs = new_package_set->packages.data;
   1.181 +		bitarray_set(newpkgbits, new_package - pkgs, 1);
   1.182 +	}
   1.183 +	if (old_package) {
   1.184 +		pool = old_package_set->string_pool.data;
   1.185 +		tp->old_package = old_package;
   1.186 +		tp->name = &pool[old_package->name];
   1.187 +		tp->old_version = &pool[old_package->version];
   1.188 +
   1.189 +		pkgs = old_package_set->packages.data;
   1.190 +		bitarray_set(oldpkgbits, old_package - pkgs, 0);
   1.191 +	}
   1.192 +
   1.193 +	tp->state = state;
   1.194 +	if (state != RAZOR_PACKAGE_INSTALL &&
   1.195 +	    state != RAZOR_PACKAGE_REMOVE)
   1.196  		trans->errors++;
   1.197 +
   1.198 +	if (contradiction) {
   1.199 +		/* Do this now, after adding tp, so that it ends up
   1.200 +		 * after both the INSTALL and the REMOVE in the array.
   1.201 +		 */
   1.202 +		add_transaction_package(trans, new_package, old_package,
   1.203 +					RAZOR_PACKAGE_CONTRADICTION,
   1.204 +					NULL, NULL);
   1.205  	}
   1.206  
   1.207  	if (req_package)
   1.208 @@ -2245,6 +2300,30 @@
   1.209  		bitarray_set(&trans->syspkgs, sp - spkgs, 0);
   1.210  }
   1.211  
   1.212 +/* FIXME: this too */
   1.213 +static struct razor_package *
   1.214 +find_old_version(struct razor_transaction_resolver *trans,
   1.215 +		 struct razor_package *pkg)
   1.216 +{
   1.217 +	struct razor_package *spkgs, *sp, *send;
   1.218 +	const char *spool, *upool;
   1.219 +
   1.220 +	if (!package_in_set(pkg, trans->upstream))
   1.221 +		return NULL;
   1.222 +
   1.223 +	sp = spkgs = trans->system->packages.data;
   1.224 +	send = trans->system->packages.data + trans->system->packages.size;
   1.225 +	spool = trans->system->string_pool.data;
   1.226 +	upool = trans->upstream->string_pool.data;
   1.227 +
   1.228 +	while (sp < send &&
   1.229 +	       strcmp(&spool[sp->name], &upool[pkg->name]) < 0)
   1.230 +		sp++;
   1.231 +	if (sp < send && strcmp(&spool[sp->name], &upool[pkg->name]) == 0)
   1.232 +		return sp;
   1.233 +	return NULL;
   1.234 +}
   1.235 +
   1.236  static void
   1.237  razor_transaction_satisfy_installs(struct razor_transaction_resolver *trans)
   1.238  {
   1.239 @@ -2296,7 +2375,7 @@
   1.240  					maybe_mark_upgraded(trans, pkg);
   1.241  				}
   1.242  			}
   1.243 -			add_transaction_package(trans, pkg,
   1.244 +			add_transaction_package(trans, pkg, find_old_version(trans, pkg),
   1.245  						RAZOR_PACKAGE_INSTALL,
   1.246  						NULL, up);
   1.247  			break;
   1.248 @@ -2316,14 +2395,14 @@
   1.249  				upgrade = find_upgrade_for_installed_conflict(trans, pkg, up);
   1.250  				if (upgrade) {
   1.251  					bitarray_set(&trans->syspkgs, pkg - spkgs, 0);
   1.252 -					add_transaction_package(trans, upgrade,
   1.253 +					add_transaction_package(trans, upgrade, pkg,
   1.254  								RAZOR_PACKAGE_INSTALL,
   1.255  								&spool[pkg->name], sp);
   1.256  				}
   1.257  				break;
   1.258  			}
   1.259  
   1.260 -			add_transaction_package(trans, pkg,
   1.261 +			add_transaction_package(trans, NULL, pkg,
   1.262  						RAZOR_PACKAGE_OLD_CONFLICT,
   1.263  						NULL, up);
   1.264  			break;
   1.265 @@ -2340,14 +2419,14 @@
   1.266  				upgrade = find_upgrade(trans, sp, up);
   1.267  				if (upgrade) {
   1.268  					bitarray_set(&trans->syspkgs, pkg - spkgs, 0);
   1.269 -					add_transaction_package(trans, upgrade,
   1.270 +					add_transaction_package(trans, upgrade, pkg,
   1.271  								RAZOR_PACKAGE_INSTALL,
   1.272  								NULL, up);
   1.273  					break;
   1.274  				}
   1.275  			}
   1.276  
   1.277 -			add_transaction_package(trans, pkg,
   1.278 +			add_transaction_package(trans, pkg, NULL,
   1.279  						RAZOR_PACKAGE_NEW_CONFLICT,
   1.280  						NULL, up);
   1.281  			break;
   1.282 @@ -2358,7 +2437,7 @@
   1.283  				/* If pkg is to-be-installed, this
   1.284  				 * will add a CONTRADICTION error as well.
   1.285  				 */
   1.286 -				add_transaction_package(trans, pkg,
   1.287 +				add_transaction_package(trans, NULL, pkg,
   1.288  							RAZOR_PACKAGE_REMOVE,
   1.289  							NULL, up);
   1.290  			}
   1.291 @@ -2426,7 +2505,7 @@
   1.292  	lost_package = &pkgs[list_first(lost_package_list, &trans->system->package_pool)->data];
   1.293  
   1.294  	for (p = list_first(&req->packages, &trans->system->package_pool); p; p = list_next(p)) {
   1.295 -		add_transaction_package(trans, &pkgs[p->data],
   1.296 +		add_transaction_package(trans, NULL, &pkgs[p->data],
   1.297  					RAZOR_PACKAGE_REMOVE,
   1.298  					&pool[lost_package->name], req);
   1.299  	}
   1.300 @@ -2480,12 +2559,14 @@
   1.301  	array_init(&lost_files);
   1.302  	array_init(&lost_provides);
   1.303  	for (r = start; r < end; r++) {
   1.304 -		if (packages[r].state != RAZOR_PACKAGE_REMOVE)
   1.305 +		if (!packages[r].old_package ||
   1.306 +		    (packages[r].state != RAZOR_PACKAGE_REMOVE &&
   1.307 +		     packages[r].state != RAZOR_PACKAGE_INSTALL))
   1.308  			continue;
   1.309  
   1.310 -		gather_lost_provides(trans->system, packages[r].package,
   1.311 +		gather_lost_provides(trans->system, packages[r].old_package,
   1.312  				     &lost_provides);
   1.313 -		gather_lost_files(trans->system, packages[r].package,
   1.314 +		gather_lost_files(trans->system, packages[r].old_package,
   1.315  				  &lost_files);
   1.316  	}
   1.317  
   1.318 @@ -2601,12 +2682,12 @@
   1.319  			if (errors_only)
   1.320  				break;
   1.321  
   1.322 -			printf("Installing %s %s", p->name, p->version);
   1.323 +			printf("Installing %s %s", p->name, p->new_version);
   1.324  			if (p->dep_package) {
   1.325  				if (p->dep_type == RAZOR_PROPERTY_CONFLICTS &&
   1.326  				    !strcmp(p->dep_package, p->name)) {
   1.327 -					printf(" because installed %s conflicts with %s",
   1.328 -					       p->name, p->dep_property);
   1.329 +					printf(" because %s %s conflicts with %s",
   1.330 +					       p->name, p->old_version, p->dep_property);
   1.331  					if (*p->dep_version) {
   1.332  						printf(" %s %s",
   1.333  						       razor_version_relations[p->dep_relation],
   1.334 @@ -2633,7 +2714,7 @@
   1.335  		case RAZOR_PACKAGE_REMOVE:
   1.336  			if (errors_only)
   1.337  				break;
   1.338 -			printf("Removing %s %s", p->name, p->version);
   1.339 +			printf("Removing %s %s", p->name, p->old_version);
   1.340  			if (p->dep_package) {
   1.341  				if (p->dep_type == RAZOR_PROPERTY_OBSOLETES) {
   1.342  					printf(" which is obsoleted by %s",
   1.343 @@ -2659,12 +2740,12 @@
   1.344  			break;
   1.345  
   1.346  		case RAZOR_PACKAGE_UP_TO_DATE:
   1.347 -			printf("Error: can't upgrade %s: no newer version is available", p->name);
   1.348 +			printf("Error: can't upgrade %s: %s is most recent version\n", p->name, p->old_version);
   1.349  			errors_only = 1;
   1.350  			break;
   1.351  
   1.352  		case RAZOR_PACKAGE_CONTRADICTION:
   1.353 -			printf("Error: package %s is marked for both installation and removal", p->name);
   1.354 +			printf("Error: package %s is marked for both installation and removal\n", p->name);
   1.355  			errors_only = 1;
   1.356  			break;
   1.357  
   1.358 @@ -2734,11 +2815,13 @@
   1.359  	array_init(&install_packages);
   1.360  	array_init(&remove_packages);
   1.361  	for (p = 0; p < trans->package_count; p++) {
   1.362 -		if (trans->packages[p].state == RAZOR_PACKAGE_INSTALL)
   1.363 +		if (trans->packages[p].state == RAZOR_PACKAGE_INSTALL) {
   1.364  			pkg = array_add(&install_packages, sizeof *pkg);
   1.365 -		else
   1.366 +			*pkg = *trans->packages[p].new_package;
   1.367 +		} else {
   1.368  			pkg = array_add(&remove_packages, sizeof *pkg);
   1.369 -		*pkg = *trans->packages[p].package;
   1.370 +			*pkg = *trans->packages[p].old_package;
   1.371 +		}
   1.372  	}
   1.373  	map = qsort_with_data(install_packages.data,
   1.374  			      install_packages.size / sizeof *pkg,