Move the fallback on providers from backend to frontend.

This reverts commit e28973169d.
This code might fit better in the frontend than in the backend finally.
Ref: http://www.archlinux.org/pipermail/pacman-dev/2007-November/010150.html

I also changed it for fixing FS#8763 :
if there is exactly one provider, pacman will pull it and print a warning.
if there are several providers, pacman will list them and fail. It's up to
the user to pick one. Add sync501 pactest to reflect that.
This commit is contained in:
Chantry Xavier 2008-01-05 19:45:07 +01:00 committed by Dan McGee
parent 33f6fda8b6
commit 47761d5aec
3 changed files with 48 additions and 29 deletions

View File

@ -301,16 +301,7 @@ int _alpm_sync_addtarget(pmtrans_t *trans, pmdb_t *db_local, alpm_list_t *dbs_sy
repo_found = 1;
spkg = _alpm_db_get_pkgfromcache(db, targ);
if(spkg == NULL) {
/* Search provides */
_alpm_log(PM_LOG_DEBUG, "target '%s' not found in db '%s' -- looking for provisions\n", targ, db->treename);
alpm_list_t *p = _alpm_db_whatprovides(db, targ);
if(!p) {
RET_ERR(PM_ERR_PKG_NOT_FOUND, -1);
}
spkg = (pmpkg_t *) p->data;
_alpm_log(PM_LOG_DEBUG, "found '%s' as a provision for '%s'\n",
alpm_pkg_get_name(spkg), targ);
alpm_list_free(p);
RET_ERR(PM_ERR_PKG_NOT_FOUND, -1);
}
}
}
@ -325,25 +316,10 @@ int _alpm_sync_addtarget(pmtrans_t *trans, pmdb_t *db_local, alpm_list_t *dbs_sy
spkg = _alpm_db_get_pkgfromcache(db, targ);
}
if(spkg == NULL) {
/* Search provides */
_alpm_log(PM_LOG_DEBUG, "target '%s' not found -- looking for provisions\n", targ);
for(j = dbs_sync; j && !spkg; j = j->next) {
pmdb_t *db = j->data;
alpm_list_t *p = _alpm_db_whatprovides(db, targ);
if(p) {
spkg = (pmpkg_t *) p->data;
_alpm_log(PM_LOG_DEBUG, "found '%s' as a provision for '%s' in db '%s'\n",
alpm_pkg_get_name(spkg), targ, db->treename);
alpm_list_free(p);
}
}
RET_ERR(PM_ERR_PKG_NOT_FOUND, -1);
}
}
if(spkg == NULL) {
RET_ERR(PM_ERR_PKG_NOT_FOUND, -1);
}
if(_alpm_pkg_should_ignore(spkg)) {
int resp;
QUESTION(trans, PM_TRANS_CONV_INSTALL_IGNOREPKG, spkg, NULL, NULL, &resp);

15
pactest/tests/sync501.py Normal file
View File

@ -0,0 +1,15 @@
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

@ -605,9 +605,37 @@ static int sync_trans(alpm_list_t *targets, int sync_only)
}
}
if(!found) {
fprintf(stderr, _("error: '%s': not found in sync db\n"), targ);
retval = 1;
goto cleanup;
/* 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);
prov = alpm_list_join(prov, alpm_db_whatprovides(db, targ));
}
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;
fprintf(stderr, _("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 {
fprintf(stderr, _("error: '%s': not found in sync db\n"), targ);
retval = 1;
goto cleanup;
}
}
}
}