sync_addtarget rework

Now '-S provision' handling is done in the back-end.

In case of multiple providers, the first one is selected (behavior change:
deleted provision002.py). The old processing order was: literal, group,
provision; the new one: literal, provision, group. This is more rational,
but "pacman -S group" will be slower now. "pacman -S repo/provision" also
works. Provision was generalized to dependencies, so you can resolve deps by
hand: "pacman -S 'bash>2.0'" or "pacman -S 'core/bash>2.0'" etc. This can be
useful in makepkg dependency resolving. The changes were documented in
pacman manual.

alpm_find_pkg_satisfiers and _alpm_find_dep_satisfiers functions were
removed, since they are no longer needed.

I added some verbosity to "select provider instead of literal" and
"fallback to group".

Signed-off-by: Nagy Gabor <ngaba@bibl.u-szeged.hu>
Signed-off-by: Dan McGee <dan@archlinux.org>
This commit is contained in:
Nagy Gabor 2008-07-08 10:07:05 +02:00 committed by Dan McGee
parent f724fb2702
commit fd8969f678
7 changed files with 34 additions and 123 deletions

View File

@ -49,7 +49,9 @@ Operations
example, `pacman -S qt` will download and install qt and all the
packages it depends on. If a package name exists in more than one repo, the
repo can be explicitly specified to clarify the package to install:
`pacman -S testing/qt`.
`pacman -S testing/qt`. You can also specify version requirements:
`pacman -S "bash>=3.2"`. (Quotes are needed, otherwise your shell
interprets ">" as redirection to file.)
+
In addition to packages, groups can be specified as well. For example, if
gnome is a defined package group, then `pacman -S gnome` will install every

View File

@ -433,7 +433,6 @@ int alpm_depcmp(pmpkg_t *pkg, pmdepend_t *dep);
alpm_list_t *alpm_checkdeps(pmdb_t *db, int reversedeps,
alpm_list_t *remove, alpm_list_t *upgrade);
alpm_list_t *alpm_deptest(pmdb_t *db, alpm_list_t *targets);
alpm_list_t *alpm_find_pkg_satisfiers(alpm_list_t *pkgs, const char *pkgname);
const char *alpm_miss_get_target(const pmdepmissing_t *miss);
pmdepend_t *alpm_miss_get_dep(pmdepmissing_t *miss);

View File

@ -202,32 +202,6 @@ pmpkg_t *_alpm_find_dep_satisfier(alpm_list_t *pkgs, pmdepend_t *dep)
return(NULL);
}
alpm_list_t *_alpm_find_dep_satisfiers(alpm_list_t *pkgs, pmdepend_t *dep)
{
alpm_list_t *i, *ret = NULL;
for(i = pkgs; i; i = alpm_list_next(i)) {
pmpkg_t *pkg = i->data;
if(alpm_depcmp(pkg, dep)) {
ret = alpm_list_add(ret, pkg);
}
}
return(ret);
}
/** Find packages in a list that provide a given package.
* @param pkgs an alpm_list_t* of package to search
* @param pkgname the name of the package
* @return an alpm_list_t* of packages that provide pkgname
*/
alpm_list_t SYMEXPORT *alpm_find_pkg_satisfiers(alpm_list_t *pkgs, const char *pkgname)
{
pmdepend_t *dep = _alpm_splitdep(pkgname);
alpm_list_t *res = _alpm_find_dep_satisfiers(pkgs, dep);
_alpm_dep_free(dep);
return(res);
}
/** Checks dependencies and returns missing ones in a list.
* Dependencies can include versions with depmod operators.
* @param db pointer to the local package database
@ -567,6 +541,8 @@ pmpkg_t *_alpm_resolvedep(pmdepend_t *dep, alpm_list_t *dbs, alpm_list_t *exclud
continue;
}
}
_alpm_log(PM_LOG_WARNING, _("provider package was selected (%s provides %s)\n"),
pkg->name, dep->name);
return(pkg);
}
}

View File

@ -53,7 +53,6 @@ int _alpm_resolvedeps(pmdb_t *local, alpm_list_t *dbs_sync, alpm_list_t *list,
int _alpm_dep_edge(pmpkg_t *pkg1, pmpkg_t *pkg2);
pmdepend_t *_alpm_splitdep(const char *depstring);
pmpkg_t *_alpm_find_dep_satisfier(alpm_list_t *pkgs, pmdepend_t *dep);
alpm_list_t *_alpm_find_dep_satisfiers(alpm_list_t *pkgs, pmdepend_t *dep);
#endif /* _ALPM_DEPS_H */

View File

@ -272,65 +272,54 @@ int _alpm_sync_addtarget(pmtrans_t *trans, pmdb_t *db_local, alpm_list_t *dbs_sy
char *targline;
char *targ;
alpm_list_t *j;
pmpkg_t *local;
pmpkg_t *spkg = NULL;
pmsyncpkg_t *sync;
int repo_found = 0;
pmpkg_t *local, *spkg;
pmdepend_t *dep; /* provisions and dependencies are also allowed */
ALPM_LOG_FUNC;
ASSERT(db_local != NULL, RET_ERR(PM_ERR_DB_NULL, -1));
ASSERT(trans != NULL, RET_ERR(PM_ERR_TRANS_NULL, -1));
ASSERT(name != NULL, RET_ERR(PM_ERR_WRONG_ARGS, -1));
STRDUP(targline, name, RET_ERR(PM_ERR_MEMORY, -1));
STRDUP(targline, name, RET_ERR(PM_ERR_MEMORY, -1));
targ = strchr(targline, '/');
if(targ) {
/* we are looking for a package in a specific database */
alpm_list_t *dbs = NULL;
*targ = '\0';
targ++;
_alpm_log(PM_LOG_DEBUG, "searching for target '%s' in repo\n", targ);
for(j = dbs_sync; j && !spkg; j = j->next) {
_alpm_log(PM_LOG_DEBUG, "searching for target '%s' in repo '%s'\n", targ, targline);
for(j = dbs_sync; j; j = j->next) {
pmdb_t *db = j->data;
if(strcmp(db->treename, targline) == 0) {
repo_found = 1;
spkg = _alpm_db_get_pkgfromcache(db, targ);
if(spkg == NULL) {
pm_errno = PM_ERR_PKG_NOT_FOUND;
goto error;
}
dbs = alpm_list_add(NULL, db);
break;
}
}
if(!repo_found) {
if(dbs == NULL) {
_alpm_log(PM_LOG_ERROR, _("repository '%s' not found\n"), targline);
pm_errno = PM_ERR_PKG_REPO_NOT_FOUND;
goto error;
FREE(targline);
RET_ERR(PM_ERR_PKG_REPO_NOT_FOUND, -1);
}
dep = _alpm_splitdep(targ);
spkg = _alpm_resolvedep(dep, dbs, NULL, NULL);
_alpm_dep_free(dep);
alpm_list_free(dbs);
} else {
targ = targline;
for(j = dbs_sync; j && !spkg; j = j->next) {
pmdb_t *db = j->data;
spkg = _alpm_db_get_pkgfromcache(db, targ);
}
if(spkg == NULL) {
pm_errno = PM_ERR_PKG_NOT_FOUND;
goto error;
}
dep = _alpm_splitdep(targline);
spkg = _alpm_resolvedep(dep, dbs_sync, NULL, NULL);
_alpm_dep_free(dep);
}
FREE(targline);
if(spkg == NULL) {
RET_ERR(PM_ERR_PKG_NOT_FOUND, -1);
}
if(_alpm_sync_find(trans->packages, alpm_pkg_get_name(spkg))) {
FREE(targline);
RET_ERR(PM_ERR_TRANS_DUP_TARGET, -1);
}
if(_alpm_pkg_should_ignore(spkg)) {
int resp;
QUESTION(trans, PM_TRANS_CONV_INSTALL_IGNOREPKG, spkg, NULL, NULL, &resp);
if (!resp) {
return(0);
}
}
local = _alpm_db_get_pkgfromcache(db_local, alpm_pkg_get_name(spkg));
if(local) {
if(_alpm_pkg_compare_versions(local, spkg) == 0) {
@ -349,22 +338,15 @@ int _alpm_sync_addtarget(pmtrans_t *trans, pmdb_t *db_local, alpm_list_t *dbs_sy
}
/* add the package to the transaction */
sync = _alpm_sync_new(PM_PKG_REASON_EXPLICIT, spkg, NULL);
pmsyncpkg_t *sync = _alpm_sync_new(PM_PKG_REASON_EXPLICIT, spkg, NULL);
if(sync == NULL) {
goto error;
return(-1);
}
_alpm_log(PM_LOG_DEBUG, "adding target '%s' to the transaction set\n",
alpm_pkg_get_name(spkg));
trans->packages = alpm_list_add(trans->packages, sync);
FREE(targline);
return(0);
error:
if(targline) {
FREE(targline);
}
return(-1);
}
/* Helper functions for alpm_list_remove

View File

@ -1,15 +0,0 @@
self.description = "-S provision"
sp = pmpkg("pkg1")
sp.provides = ["provision=1.0-1"]
self.addpkg2db("sync", sp)
sp = pmpkg("pkg2")
sp.provides = ["provision=1.0-1"]
self.addpkg2db("sync", sp)
self.args = "-S provision"
self.addrule("PACMAN_RETCODE=1")
self.addrule("!PKG_EXIST=pkg1")
self.addrule("!PKG_EXIST=pkg2")

View File

@ -583,7 +583,7 @@ static int sync_trans(alpm_list_t *targets)
goto cleanup;
}
/* target not found: check if it's a group */
printf(_("%s package not found, searching for group...\n"), targ);
for(j = sync_dbs; j; j = alpm_list_next(j)) {
pmdb_t *db = alpm_list_getdata(j);
grp = alpm_db_readgrp(db, targ);
@ -617,41 +617,9 @@ static int sync_trans(alpm_list_t *targets)
}
}
if(!found) {
/* targ not found in sync db, searching for providers... */
alpm_list_t *prov = NULL;
for(j = sync_dbs; j; j = alpm_list_next(j)) {
pmdb_t *db = alpm_list_getdata(j);
alpm_list_t *dblist = alpm_db_getpkgcache(db);
alpm_list_t *satisfiers = alpm_find_pkg_satisfiers(dblist, targ);
prov = alpm_list_join(prov, satisfiers);
}
if(prov != NULL) {
if(alpm_list_count(prov) == 1) {
const char *pname = NULL;
pmpkg_t *pkg = alpm_list_getdata(prov);
pname = alpm_pkg_get_name(pkg);
alpm_list_free(prov);
printf(_("Warning: %s provides %s\n"), pname, targ);
targets = alpm_list_add(targets, strdup(pname));
} else {
alpm_list_t *k;
pm_fprintf(stderr, PM_LOG_ERROR,
_("several packages provide %s, please specify one :\n"), targ);
for(k = prov; k; k = alpm_list_next(k)) {
pmpkg_t *pkg = alpm_list_getdata(k);
printf("%s ", alpm_pkg_get_name(pkg));
}
printf("\n");
alpm_list_free(prov);
retval = 1;
goto cleanup;
}
} else {
pm_fprintf(stderr, PM_LOG_ERROR,
_("'%s': not found in sync db\n"), targ);
retval = 1;
goto cleanup;
}
pm_fprintf(stderr, PM_LOG_ERROR, _("'%s': not found in sync db\n"), targ);
retval = 1;
goto cleanup;
}
}
}