xbps-bin: the install target gains suppor for installing best pkg available.
This commit is contained in:
		
							
								
								
									
										7
									
								
								NEWS
									
									
									
									
									
								
							
							
						
						
									
										7
									
								
								NEWS
									
									
									
									
									
								
							| @@ -1,5 +1,12 @@ | ||||
| xbps-0.12.0 (???): | ||||
|  | ||||
|  * xbps-bin: the install target will now install the best package | ||||
|    version available in repository pool if just package name has | ||||
|    been specified, otherwise the first repository matching the | ||||
|    specified pattern wins, i.e: | ||||
|  | ||||
| 	$ xbps-bin install foo 'blah>=1.2<2.0' | ||||
|  | ||||
|  * Massive pkgdb API rototill. The xbps-uhelper command gained support | ||||
|    for the 'updatepkgdb' target which will migrate old pkgdb | ||||
|    format to the new 0.12 format. ALERT: make sure to execute | ||||
|   | ||||
| @@ -224,7 +224,7 @@ autoupdate_pkgs(bool yes, bool show_download_pkglist_url) | ||||
| int | ||||
| autoremove_pkgs(bool yes) | ||||
| { | ||||
| 	int rv = 0; | ||||
| 	int rv; | ||||
|  | ||||
| 	if ((rv = xbps_transaction_autoremove_pkgs()) != 0) { | ||||
| 		if (rv == ENOENT) { | ||||
| @@ -242,48 +242,12 @@ autoremove_pkgs(bool yes) | ||||
| int | ||||
| install_new_pkg(const char *pkg, bool reinstall) | ||||
| { | ||||
| 	prop_dictionary_t pkgd; | ||||
| 	char *pkgname = NULL, *pkgpatt = NULL; | ||||
| 	int rv = 0; | ||||
| 	bool pkgmatch = false; | ||||
| 	pkg_state_t state; | ||||
| 	int rv; | ||||
|  | ||||
| 	if (xbps_pkgpattern_version(pkg)) { | ||||
| 		pkgpatt = __UNCONST(pkg); | ||||
| 	} else { | ||||
| 		/* | ||||
| 		 * If only pkgname has been specified, always make it | ||||
| 		 * use a package pattern, i.e 'foo>=0'. | ||||
| 		 */ | ||||
| 		pkgmatch = true; | ||||
| 		pkgpatt = xbps_xasprintf("%s%s", pkg, ">=0"); | ||||
| 		if (pkgpatt == NULL) | ||||
| 			return -1; | ||||
| 	} | ||||
| 	pkgname = xbps_pkgpattern_name(pkgpatt); | ||||
| 	if (pkgname == NULL) | ||||
| 		return -1; | ||||
| 	/* | ||||
| 	 * Find a package in a repository and prepare for installation. | ||||
| 	 */ | ||||
| 	if ((pkgd = xbps_find_pkg_dict_installed(pkgname, false))) { | ||||
| 		if ((rv = xbps_pkg_state_dictionary(pkgd, &state)) != 0) { | ||||
| 			prop_object_release(pkgd); | ||||
| 			goto out; | ||||
| 		} | ||||
| 		prop_object_release(pkgd); | ||||
| 		if (state == XBPS_PKG_STATE_INSTALLED) { | ||||
| 			if (!reinstall) { | ||||
| 				printf("Package '%s' is already installed.\n", | ||||
| 				    pkgname); | ||||
| 				goto out; | ||||
| 			} | ||||
| 		} else { | ||||
| 			printf("Package `%s' needs to be configured.\n", pkgname); | ||||
| 		} | ||||
| 	} | ||||
| 	if ((rv = xbps_transaction_install_pkg(pkgpatt)) != 0) { | ||||
| 		if (rv == ENOENT) { | ||||
| 	if ((rv = xbps_transaction_install_pkg(pkg, reinstall)) != 0) { | ||||
| 		if (rv == ENODEV) { | ||||
| 			printf("Package `%s' already installed.\n", pkg); | ||||
| 		} else if (rv == ENOENT) { | ||||
| 			xbps_error_printf("xbps-bin: unable to locate '%s' in " | ||||
| 			    "repository pool.\n", pkg); | ||||
| 		} else if (rv == ENOTSUP) { | ||||
| @@ -295,18 +259,13 @@ install_new_pkg(const char *pkg, bool reinstall) | ||||
| 			rv = -1; | ||||
| 		} | ||||
| 	} | ||||
| out: | ||||
| 	if (pkgmatch) | ||||
| 		free(pkgpatt); | ||||
| 	free(pkgname); | ||||
|  | ||||
| 	return rv; | ||||
| } | ||||
|  | ||||
| int | ||||
| update_pkg(const char *pkgname) | ||||
| { | ||||
| 	int rv = 0; | ||||
| 	int rv; | ||||
|  | ||||
| 	rv = xbps_transaction_update_pkg(pkgname); | ||||
| 	if (rv == EEXIST) | ||||
|   | ||||
| @@ -56,7 +56,7 @@ | ||||
|  */ | ||||
| #define XBPS_PKGINDEX_VERSION	"1.4" | ||||
|  | ||||
| #define XBPS_API_VERSION	"20120124" | ||||
| #define XBPS_API_VERSION	"20120125" | ||||
| #define XBPS_VERSION		"0.12" | ||||
|  | ||||
| /** | ||||
| @@ -1304,15 +1304,23 @@ int xbps_remove_pkg_files(prop_dictionary_t dict, | ||||
| /*@{*/ | ||||
|  | ||||
| /** | ||||
|  * Finds a package by a pattern and enqueues it into | ||||
|  * the transaction dictionary for future use. The first repository in | ||||
|  * the pool that matched the pattern wins. | ||||
|  * Finds a package by name or by pattern and enqueues it into | ||||
|  * the transaction dictionary for future use. If pkg is a pkgname, the best | ||||
|  * package version in repository pool will be queued, otherwise the first | ||||
|  * repository matching the package pattern wins. | ||||
|  * | ||||
|  * @param pkgpattern Package pattern, i.e `foo>=0' or 'foo<2.0'. | ||||
|  * @param str Package name or package pattern to match, i.e | ||||
|  * `foo>=0' or 'foo<1'. | ||||
|  * @param reinstall If true, package will be queued (if \a str matches) | ||||
|  * even if package is already installed. | ||||
|  * | ||||
|  * @return 0 on success, otherwise an errno value. | ||||
|  * @retval ENODEV Package is already installed (reinstall wasn't enabled). | ||||
|  * @retval ENOENT Package not matched in repository pool. | ||||
|  * @retval ENOTSUP No repositories are available. | ||||
|  * @retval EINVAL Any other error ocurred in the process. | ||||
|  */ | ||||
| int xbps_transaction_install_pkg(const char *pkgpattern); | ||||
| int xbps_transaction_install_pkg(const char *pkg, bool reinstall); | ||||
|  | ||||
| /** | ||||
|  * Marks a package as "going to be updated" in the transaction dictionary. | ||||
|   | ||||
| @@ -214,7 +214,7 @@ find_repo_deps(prop_dictionary_t transd, 	/* transaction dictionary */ | ||||
| 			xbps_dbg_printf(""); | ||||
| 			for (x = 0; x < *depth; x++) | ||||
| 				xbps_dbg_printf_append(" "); | ||||
| 			xbps_dbg_printf_append("%s requires dependency '%s': ", | ||||
| 			xbps_dbg_printf_append("%s: requires dependency '%s': ", | ||||
| 			    curpkg ? curpkg : " ", reqpkg); | ||||
| 		} | ||||
| 		/* | ||||
| @@ -258,7 +258,7 @@ find_repo_deps(prop_dictionary_t transd, 	/* transaction dictionary */ | ||||
| 				break; | ||||
| 			} | ||||
| 			/* Required pkgdep not installed */ | ||||
| 			xbps_dbg_printf_append("not installed"); | ||||
| 			xbps_dbg_printf_append("not installed. "); | ||||
| 			reason = "install"; | ||||
| 			state = XBPS_PKG_STATE_NOT_INSTALLED; | ||||
| 		} else { | ||||
| @@ -403,8 +403,8 @@ find_repo_deps(prop_dictionary_t transd, 	/* transaction dictionary */ | ||||
| 		if (tmpd == NULL) { | ||||
| 			/* dependency not installed */ | ||||
| 			reason = "install"; | ||||
| 			xbps_dbg_printf_append("satisfied by `%s', " | ||||
| 			    "installing...\n", pkgver_q); | ||||
| 			xbps_dbg_printf_append("(found `%s')\n", | ||||
| 			    pkgver_q); | ||||
| 		} else { | ||||
| 			/* dependency installed, check its state */ | ||||
| 			state = 0; | ||||
| @@ -416,12 +416,12 @@ find_repo_deps(prop_dictionary_t transd, 	/* transaction dictionary */ | ||||
| 			} | ||||
| 			if (state == XBPS_PKG_STATE_INSTALLED) { | ||||
| 				reason = "update"; | ||||
| 				xbps_dbg_printf_append("satisfied by `%s', " | ||||
| 				    "updating...\n", pkgver_q); | ||||
| 				xbps_dbg_printf_append("(found `%s')\n", | ||||
| 				    pkgver_q); | ||||
| 			} else if (state == XBPS_PKG_STATE_UNPACKED) { | ||||
| 				reason = "install"; | ||||
| 				xbps_dbg_printf_append("satisfied by `%s', " | ||||
| 				    "installing...\n", pkgver_q); | ||||
| 				xbps_dbg_printf_append("(found `%s')\n", | ||||
| 				    pkgver_q); | ||||
| 			} | ||||
| 			prop_object_release(tmpd); | ||||
| 		} | ||||
|   | ||||
| @@ -57,43 +57,37 @@ enum { | ||||
| }; | ||||
|  | ||||
| static int | ||||
| transaction_find_pkg(const char *pattern, int action) | ||||
| transaction_find_pkg(const char *pkg, bool bypattern, bool bestpkg, int action) | ||||
| { | ||||
| 	prop_dictionary_t pkg_pkgdb, pkg_repod = NULL; | ||||
| 	prop_array_t unsorted; | ||||
| 	struct xbps_handle *xhp = xbps_handle_get(); | ||||
| 	const char *pkgname, *pkgver, *repoloc, *repover, *instver, *reason; | ||||
| 	int rv = 0; | ||||
| 	bool bypattern, bestpkg; | ||||
| 	pkg_state_t state = 0; | ||||
|  | ||||
| 	assert(pattern != NULL); | ||||
| 	assert(pkg != NULL); | ||||
|  | ||||
| 	if (action == TRANS_INSTALL) { | ||||
| 		/* install */ | ||||
| 		bypattern = true; | ||||
| 		bestpkg = false; | ||||
| 		reason = "install"; | ||||
| 	} else { | ||||
| 		/* update */ | ||||
| 		pkg_pkgdb = xbps_find_pkg_dict_installed(pattern, false); | ||||
| 		pkg_pkgdb = xbps_find_pkg_dict_installed(pkg, false); | ||||
| 		if (pkg_pkgdb == NULL) { | ||||
| 			rv = ENODEV; | ||||
| 			goto out; | ||||
| 		} | ||||
| 		bypattern = false; | ||||
| 		bestpkg = true; | ||||
| 		reason = "update"; | ||||
| 	} | ||||
|  | ||||
| 	/* | ||||
| 	 * Find out if the pkg has been found in repository pool. | ||||
| 	 */ | ||||
| 	pkg_repod = xbps_repository_pool_find_pkg(pattern, | ||||
| 	    bypattern, bestpkg); | ||||
| 	pkg_repod = xbps_repository_pool_find_pkg(pkg, bypattern, bestpkg); | ||||
| 	if (pkg_repod == NULL) { | ||||
| 		pkg_repod = | ||||
| 		    xbps_repository_pool_find_virtualpkg(pattern, bypattern); | ||||
| 		    xbps_repository_pool_find_virtualpkg(pkg, bypattern); | ||||
| 		if (pkg_repod == NULL) { | ||||
| 			/* not found */ | ||||
| 			rv = errno; | ||||
| @@ -105,7 +99,7 @@ transaction_find_pkg(const char *pattern, int action) | ||||
| 	prop_dictionary_get_cstring_nocopy(pkg_repod, "repository", &repoloc); | ||||
| 	prop_dictionary_get_cstring_nocopy(pkg_repod, "pkgname", &pkgname); | ||||
|  | ||||
| 	if (bestpkg) { | ||||
| 	if (bestpkg && (action == TRANS_UPDATE)) { | ||||
| 		/* | ||||
| 		 * Compare installed version vs best pkg available in repos. | ||||
| 		 */ | ||||
| @@ -231,13 +225,38 @@ xbps_transaction_update_packages(void) | ||||
| int | ||||
| xbps_transaction_update_pkg(const char *pkgname) | ||||
| { | ||||
| 	return transaction_find_pkg(pkgname, TRANS_UPDATE); | ||||
| 	return transaction_find_pkg(pkgname, false, true, TRANS_UPDATE); | ||||
| } | ||||
|  | ||||
| int | ||||
| xbps_transaction_install_pkg(const char *pkgpattern) | ||||
| xbps_transaction_install_pkg(const char *pkg, bool reinstall) | ||||
| { | ||||
| 	return transaction_find_pkg(pkgpattern, TRANS_INSTALL); | ||||
| 	prop_dictionary_t pkgd; | ||||
| 	pkg_state_t state; | ||||
| 	bool bypattern, bestpkg; | ||||
|  | ||||
| 	if (xbps_pkgpattern_version(pkg)) { | ||||
| 		bypattern = true; | ||||
| 		bestpkg = false; | ||||
| 	} else { | ||||
| 		bypattern = false; | ||||
| 		bestpkg = true; | ||||
| 	} | ||||
|  | ||||
| 	pkgd = xbps_pkgdb_get_pkgd(pkg, bypattern); | ||||
| 	if (pkgd != NULL) { | ||||
| 		if (xbps_pkg_state_dictionary(pkgd, &state) != 0) { | ||||
| 			prop_object_release(pkgd); | ||||
| 			return EINVAL; | ||||
| 		} | ||||
| 		prop_object_release(pkgd); | ||||
| 		if ((state == XBPS_PKG_STATE_INSTALLED) && !reinstall) { | ||||
| 			/* error out if pkg installed and no reinstall */ | ||||
| 			return ENODEV; | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	return transaction_find_pkg(pkg, bypattern, bestpkg, TRANS_INSTALL); | ||||
| } | ||||
|  | ||||
| int | ||||
|   | ||||
		Reference in New Issue
	
	Block a user