mirror of
https://github.com/moparisthebest/pacman
synced 2024-08-13 17:03:46 -04:00
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:
parent
f724fb2702
commit
fd8969f678
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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 */
|
||||
|
||||
|
@ -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
|
||||
|
@ -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")
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user