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
|
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
|
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:
|
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
|
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
|
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 *alpm_checkdeps(pmdb_t *db, int reversedeps,
|
||||||
alpm_list_t *remove, alpm_list_t *upgrade);
|
alpm_list_t *remove, alpm_list_t *upgrade);
|
||||||
alpm_list_t *alpm_deptest(pmdb_t *db, alpm_list_t *targets);
|
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);
|
const char *alpm_miss_get_target(const pmdepmissing_t *miss);
|
||||||
pmdepend_t *alpm_miss_get_dep(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);
|
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.
|
/** Checks dependencies and returns missing ones in a list.
|
||||||
* Dependencies can include versions with depmod operators.
|
* Dependencies can include versions with depmod operators.
|
||||||
* @param db pointer to the local package database
|
* @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;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
_alpm_log(PM_LOG_WARNING, _("provider package was selected (%s provides %s)\n"),
|
||||||
|
pkg->name, dep->name);
|
||||||
return(pkg);
|
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);
|
int _alpm_dep_edge(pmpkg_t *pkg1, pmpkg_t *pkg2);
|
||||||
pmdepend_t *_alpm_splitdep(const char *depstring);
|
pmdepend_t *_alpm_splitdep(const char *depstring);
|
||||||
pmpkg_t *_alpm_find_dep_satisfier(alpm_list_t *pkgs, pmdepend_t *dep);
|
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 */
|
#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 *targline;
|
||||||
char *targ;
|
char *targ;
|
||||||
alpm_list_t *j;
|
alpm_list_t *j;
|
||||||
pmpkg_t *local;
|
pmpkg_t *local, *spkg;
|
||||||
pmpkg_t *spkg = NULL;
|
pmdepend_t *dep; /* provisions and dependencies are also allowed */
|
||||||
pmsyncpkg_t *sync;
|
|
||||||
int repo_found = 0;
|
|
||||||
|
|
||||||
ALPM_LOG_FUNC;
|
ALPM_LOG_FUNC;
|
||||||
|
|
||||||
ASSERT(db_local != NULL, RET_ERR(PM_ERR_DB_NULL, -1));
|
ASSERT(db_local != NULL, RET_ERR(PM_ERR_DB_NULL, -1));
|
||||||
ASSERT(trans != NULL, RET_ERR(PM_ERR_TRANS_NULL, -1));
|
ASSERT(trans != NULL, RET_ERR(PM_ERR_TRANS_NULL, -1));
|
||||||
ASSERT(name != NULL, RET_ERR(PM_ERR_WRONG_ARGS, -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, '/');
|
targ = strchr(targline, '/');
|
||||||
if(targ) {
|
if(targ) {
|
||||||
/* we are looking for a package in a specific database */
|
/* we are looking for a package in a specific database */
|
||||||
|
alpm_list_t *dbs = NULL;
|
||||||
*targ = '\0';
|
*targ = '\0';
|
||||||
targ++;
|
targ++;
|
||||||
_alpm_log(PM_LOG_DEBUG, "searching for target '%s' in repo\n", targ);
|
_alpm_log(PM_LOG_DEBUG, "searching for target '%s' in repo '%s'\n", targ, targline);
|
||||||
for(j = dbs_sync; j && !spkg; j = j->next) {
|
for(j = dbs_sync; j; j = j->next) {
|
||||||
pmdb_t *db = j->data;
|
pmdb_t *db = j->data;
|
||||||
if(strcmp(db->treename, targline) == 0) {
|
if(strcmp(db->treename, targline) == 0) {
|
||||||
repo_found = 1;
|
dbs = alpm_list_add(NULL, db);
|
||||||
spkg = _alpm_db_get_pkgfromcache(db, targ);
|
break;
|
||||||
if(spkg == NULL) {
|
|
||||||
pm_errno = PM_ERR_PKG_NOT_FOUND;
|
|
||||||
goto error;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
if(dbs == NULL) {
|
||||||
if(!repo_found) {
|
|
||||||
_alpm_log(PM_LOG_ERROR, _("repository '%s' not found\n"), targline);
|
_alpm_log(PM_LOG_ERROR, _("repository '%s' not found\n"), targline);
|
||||||
pm_errno = PM_ERR_PKG_REPO_NOT_FOUND;
|
FREE(targline);
|
||||||
goto error;
|
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 {
|
} else {
|
||||||
targ = targline;
|
dep = _alpm_splitdep(targline);
|
||||||
for(j = dbs_sync; j && !spkg; j = j->next) {
|
spkg = _alpm_resolvedep(dep, dbs_sync, NULL, NULL);
|
||||||
pmdb_t *db = j->data;
|
_alpm_dep_free(dep);
|
||||||
spkg = _alpm_db_get_pkgfromcache(db, targ);
|
|
||||||
}
|
}
|
||||||
|
FREE(targline);
|
||||||
|
|
||||||
if(spkg == NULL) {
|
if(spkg == NULL) {
|
||||||
pm_errno = PM_ERR_PKG_NOT_FOUND;
|
RET_ERR(PM_ERR_PKG_NOT_FOUND, -1);
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(_alpm_sync_find(trans->packages, alpm_pkg_get_name(spkg))) {
|
if(_alpm_sync_find(trans->packages, alpm_pkg_get_name(spkg))) {
|
||||||
FREE(targline);
|
|
||||||
RET_ERR(PM_ERR_TRANS_DUP_TARGET, -1);
|
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));
|
local = _alpm_db_get_pkgfromcache(db_local, alpm_pkg_get_name(spkg));
|
||||||
if(local) {
|
if(local) {
|
||||||
if(_alpm_pkg_compare_versions(local, spkg) == 0) {
|
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 */
|
/* 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) {
|
if(sync == NULL) {
|
||||||
goto error;
|
return(-1);
|
||||||
}
|
}
|
||||||
_alpm_log(PM_LOG_DEBUG, "adding target '%s' to the transaction set\n",
|
_alpm_log(PM_LOG_DEBUG, "adding target '%s' to the transaction set\n",
|
||||||
alpm_pkg_get_name(spkg));
|
alpm_pkg_get_name(spkg));
|
||||||
trans->packages = alpm_list_add(trans->packages, sync);
|
trans->packages = alpm_list_add(trans->packages, sync);
|
||||||
|
|
||||||
FREE(targline);
|
|
||||||
return(0);
|
return(0);
|
||||||
|
|
||||||
error:
|
|
||||||
if(targline) {
|
|
||||||
FREE(targline);
|
|
||||||
}
|
|
||||||
return(-1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Helper functions for alpm_list_remove
|
/* 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;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
/* target not found: check if it's a group */
|
/* 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)) {
|
for(j = sync_dbs; j; j = alpm_list_next(j)) {
|
||||||
pmdb_t *db = alpm_list_getdata(j);
|
pmdb_t *db = alpm_list_getdata(j);
|
||||||
grp = alpm_db_readgrp(db, targ);
|
grp = alpm_db_readgrp(db, targ);
|
||||||
@ -617,42 +617,10 @@ static int sync_trans(alpm_list_t *targets)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(!found) {
|
if(!found) {
|
||||||
/* targ not found in sync db, searching for providers... */
|
pm_fprintf(stderr, PM_LOG_ERROR, _("'%s': not found in sync db\n"), targ);
|
||||||
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;
|
retval = 1;
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
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