mirror of
https://github.com/moparisthebest/pacman
synced 2024-08-13 17:03:46 -04:00
Versioned provisions.
This patch introduces versioned provisions in "provision 1.0-1" format. _alpm_db_whatprovides was modified accordingly (added sync500.py), alpm_depcmp was modified accordingly (add043.py passes now; added add044.py and add045.py). Notes: alpm_db_search now uses the whole versioned %PROVIDES% string in its search. debug logging was simplified in alpm_depcmp. Signed-off-by: Nagy Gabor <ngaba@bibl.u-szeged.hu> [Xavier: fixed a few typos, duplicate const strings with strdup before modifying them, put some debugging back in alpm_depcmp, minor code cleanups (var/function renaming), added a note in PKGBUILD man page.] Signed-off-by: Chantry Xavier <shiningxc@gmail.com> [Dan: made strcmp checks clearer, added a comment] Signed-off-by: Dan McGee <dan@archlinux.org>
This commit is contained in:
parent
23b4e0270b
commit
84ebf82319
@ -133,6 +133,8 @@ Options and Directives
|
|||||||
a package to provide dependencies other than its own package name. For
|
a package to provide dependencies other than its own package name. For
|
||||||
example, the dcron package can provide 'cron', which allows packages to
|
example, the dcron package can provide 'cron', which allows packages to
|
||||||
depend on 'cron' rather than 'dcron OR fcron'.
|
depend on 'cron' rather than 'dcron OR fcron'.
|
||||||
|
Versioned provisions are also possible. For example, dcron can provide
|
||||||
|
'cron 2.0' to satisfy the 'cron>=2.0' dependency of other packages.
|
||||||
|
|
||||||
*replaces (array)*::
|
*replaces (array)*::
|
||||||
An array of packages that this package should replace, and can be used
|
An array of packages that this package should replace, and can be used
|
||||||
|
@ -783,6 +783,25 @@ pmdb_t *_alpm_db_register_sync(const char *treename)
|
|||||||
return(db);
|
return(db);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* helper function for alpm_list_find and _alpm_db_whatprovides
|
||||||
|
*
|
||||||
|
* @return "provision.name" == needle (as string)
|
||||||
|
*/
|
||||||
|
int _alpm_prov_cmp(const void *provision, const void *needle)
|
||||||
|
{
|
||||||
|
char *tmpptr;
|
||||||
|
char *provname = strdup(provision);
|
||||||
|
int retval = 0;
|
||||||
|
tmpptr = strchr(provname, ' ');
|
||||||
|
|
||||||
|
if(tmpptr != NULL) { /* provision-version */
|
||||||
|
*tmpptr='\0';
|
||||||
|
}
|
||||||
|
retval = strcmp(provname, needle);
|
||||||
|
free(provname);
|
||||||
|
return(retval);
|
||||||
|
}
|
||||||
|
|
||||||
/* return a alpm_list_t of packages in "db" that provide "package"
|
/* return a alpm_list_t of packages in "db" that provide "package"
|
||||||
*/
|
*/
|
||||||
alpm_list_t *_alpm_db_whatprovides(pmdb_t *db, const char *package)
|
alpm_list_t *_alpm_db_whatprovides(pmdb_t *db, const char *package)
|
||||||
@ -799,7 +818,7 @@ alpm_list_t *_alpm_db_whatprovides(pmdb_t *db, const char *package)
|
|||||||
for(lp = _alpm_db_get_pkgcache(db); lp; lp = lp->next) {
|
for(lp = _alpm_db_get_pkgcache(db); lp; lp = lp->next) {
|
||||||
pmpkg_t *info = lp->data;
|
pmpkg_t *info = lp->data;
|
||||||
|
|
||||||
if(alpm_list_find_str(alpm_pkg_get_provides(info), package)) {
|
if(alpm_list_find(alpm_pkg_get_provides(info), (const void *)package, _alpm_prov_cmp)) {
|
||||||
pkgs = alpm_list_add(pkgs, info);
|
pkgs = alpm_list_add(pkgs, info);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -58,6 +58,7 @@ pmdb_t *_alpm_db_register_local(void);
|
|||||||
pmdb_t *_alpm_db_register_sync(const char *treename);
|
pmdb_t *_alpm_db_register_sync(const char *treename);
|
||||||
|
|
||||||
/* Provision */
|
/* Provision */
|
||||||
|
int _alpm_prov_cmp(const void *provision, const void *needle);
|
||||||
alpm_list_t *_alpm_db_whatprovides(pmdb_t *db, const char *package);
|
alpm_list_t *_alpm_db_whatprovides(pmdb_t *db, const char *package);
|
||||||
|
|
||||||
/* be.c, backend specific calls */
|
/* be.c, backend specific calls */
|
||||||
|
@ -369,8 +369,10 @@ alpm_list_t *_alpm_checkdeps(pmdb_t *db, pmtranstype_t op,
|
|||||||
|
|
||||||
/* else if still not found... */
|
/* else if still not found... */
|
||||||
if(!found) {
|
if(!found) {
|
||||||
|
char *depstring = alpm_dep_get_string(depend);
|
||||||
_alpm_log(PM_LOG_DEBUG, "missing dependency '%s' for package '%s'\n",
|
_alpm_log(PM_LOG_DEBUG, "missing dependency '%s' for package '%s'\n",
|
||||||
(char*)j->data, alpm_pkg_get_name(tp));
|
depstring, alpm_pkg_get_name(tp));
|
||||||
|
free(depstring);
|
||||||
miss = _alpm_depmiss_new(alpm_pkg_get_name(tp), depend->mod,
|
miss = _alpm_depmiss_new(alpm_pkg_get_name(tp), depend->mod,
|
||||||
depend->name, depend->version);
|
depend->name, depend->version);
|
||||||
if(!_alpm_depmiss_isin(miss, baddeps)) {
|
if(!_alpm_depmiss_isin(miss, baddeps)) {
|
||||||
@ -415,8 +417,10 @@ alpm_list_t *_alpm_checkdeps(pmdb_t *db, pmtranstype_t op,
|
|||||||
for(l = _alpm_db_get_pkgcache(db); l; l = l->next) {
|
for(l = _alpm_db_get_pkgcache(db); l; l = l->next) {
|
||||||
pmpkg_t *pkg = l->data;
|
pmpkg_t *pkg = l->data;
|
||||||
if(alpm_depcmp(pkg, depend) && !_alpm_pkg_find(alpm_pkg_get_name(pkg), packages)) {
|
if(alpm_depcmp(pkg, depend) && !_alpm_pkg_find(alpm_pkg_get_name(pkg), packages)) {
|
||||||
|
char *depstring = alpm_dep_get_string(depend);
|
||||||
_alpm_log(PM_LOG_DEBUG, "checkdeps: dependency '%s' satisfied by installed package '%s'\n",
|
_alpm_log(PM_LOG_DEBUG, "checkdeps: dependency '%s' satisfied by installed package '%s'\n",
|
||||||
(char*)k->data, alpm_pkg_get_name(pkg));
|
depstring, alpm_pkg_get_name(pkg));
|
||||||
|
free(depstring);
|
||||||
satisfied = 1;
|
satisfied = 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -464,38 +468,41 @@ static int dep_vercmp(const char *version1, pmdepmod_t mod,
|
|||||||
|
|
||||||
int SYMEXPORT alpm_depcmp(pmpkg_t *pkg, pmdepend_t *dep)
|
int SYMEXPORT alpm_depcmp(pmpkg_t *pkg, pmdepend_t *dep)
|
||||||
{
|
{
|
||||||
int equal = 0;
|
alpm_list_t *i;
|
||||||
|
|
||||||
ALPM_LOG_FUNC;
|
ALPM_LOG_FUNC;
|
||||||
|
|
||||||
const char *pkgname = alpm_pkg_get_name(pkg);
|
const char *pkgname = alpm_pkg_get_name(pkg);
|
||||||
const char *pkgversion = alpm_pkg_get_version(pkg);
|
const char *pkgversion = alpm_pkg_get_version(pkg);
|
||||||
|
int satisfy = 0;
|
||||||
|
|
||||||
if(strcmp(pkgname, dep->name) == 0
|
/* check (pkg->name, pkg->version) */
|
||||||
|| alpm_list_find_str(alpm_pkg_get_provides(pkg), dep->name)) {
|
satisfy = (strcmp(pkgname, dep->name) == 0
|
||||||
|
&& dep_vercmp(pkgversion, dep->mod, dep->version));
|
||||||
|
|
||||||
equal = dep_vercmp(pkgversion, dep->mod, dep->version);
|
/* check provisions, format : "name version" */
|
||||||
|
for(i = alpm_pkg_get_provides(pkg); i && !satisfy; i = i->next) {
|
||||||
|
char *provname = strdup(i->data);
|
||||||
|
char *provver = strchr(provname, ' ');
|
||||||
|
|
||||||
char *mod = "~=";
|
if(provver == NULL) { /* no provision version */
|
||||||
switch(dep->mod) {
|
satisfy = (dep->mod == PM_DEP_MOD_ANY
|
||||||
case PM_DEP_MOD_EQ: mod = "=="; break;
|
&& strcmp(provname, dep->name) == 0);
|
||||||
case PM_DEP_MOD_GE: mod = ">="; break;
|
|
||||||
case PM_DEP_MOD_LE: mod = "<="; break;
|
|
||||||
default: break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(strlen(dep->version) > 0) {
|
|
||||||
_alpm_log(PM_LOG_DEBUG, "depcmp: %s-%s %s %s-%s => %s\n",
|
|
||||||
pkgname, pkgversion,
|
|
||||||
mod, dep->name, dep->version, (equal ? "match" : "no match"));
|
|
||||||
} else {
|
} else {
|
||||||
_alpm_log(PM_LOG_DEBUG, "depcmp: %s-%s %s %s => %s\n",
|
/* replace the space with a NULL byte, and advance ptr the version */
|
||||||
pkgname, pkgversion,
|
*provver = '\0';
|
||||||
mod, dep->name, (equal ? "match" : "no match"));
|
provver += 1;
|
||||||
|
satisfy = (strcmp(provname, dep->name) == 0
|
||||||
|
&& dep_vercmp(provver, dep->mod, dep->version));
|
||||||
}
|
}
|
||||||
|
free(provname);
|
||||||
}
|
}
|
||||||
|
|
||||||
return(equal);
|
char *depstring = alpm_dep_get_string(dep);
|
||||||
|
_alpm_log(PM_LOG_DEBUG, "alpm_depcmp %s-%s %s : %s\n",
|
||||||
|
pkgname, pkgversion, depstring, satisfy ? "match" : "no match");
|
||||||
|
free(depstring);
|
||||||
|
return(satisfy);
|
||||||
}
|
}
|
||||||
|
|
||||||
pmdepend_t SYMEXPORT *alpm_splitdep(const char *depstring)
|
pmdepend_t SYMEXPORT *alpm_splitdep(const char *depstring)
|
||||||
|
@ -492,8 +492,8 @@ int _alpm_sync_prepare(pmtrans_t *trans, pmdb_t *db_local, alpm_list_t *dbs_sync
|
|||||||
}
|
}
|
||||||
pmpkg_t *local = _alpm_db_get_pkgfromcache(db_local, conflict->package2);
|
pmpkg_t *local = _alpm_db_get_pkgfromcache(db_local, conflict->package2);
|
||||||
/* check if this package provides the package it's conflicting with */
|
/* check if this package provides the package it's conflicting with */
|
||||||
if(alpm_list_find_str(alpm_pkg_get_provides(sync->pkg),
|
if(alpm_list_find(alpm_pkg_get_provides(sync->pkg),
|
||||||
conflict->package2)) {
|
conflict->package2, _alpm_prov_cmp)) {
|
||||||
/* treat like a replaces item so requiredby fields are
|
/* treat like a replaces item so requiredby fields are
|
||||||
* inherited properly. */
|
* inherited properly. */
|
||||||
_alpm_log(PM_LOG_DEBUG, "package '%s' provides its own conflict\n",
|
_alpm_log(PM_LOG_DEBUG, "package '%s' provides its own conflict\n",
|
||||||
|
15
pactest/tests/add044.py
Normal file
15
pactest/tests/add044.py
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
self.description = "provision>=1.0-2 dependency (2)"
|
||||||
|
|
||||||
|
p = pmpkg("pkg1", "1.0-2")
|
||||||
|
p.depends = ["provision>=1.0-2"]
|
||||||
|
self.addpkg(p)
|
||||||
|
|
||||||
|
lp = pmpkg("pkg2", "1.0-2")
|
||||||
|
lp.provides = ["provision 1.0-2"]
|
||||||
|
self.addpkg2db("local", lp)
|
||||||
|
|
||||||
|
self.args = "-A %s" % p.filename()
|
||||||
|
|
||||||
|
self.addrule("PACMAN_RETCODE=0")
|
||||||
|
self.addrule("PKG_EXIST=pkg1")
|
||||||
|
self.addrule("PKG_EXIST=pkg2")
|
15
pactest/tests/add045.py
Normal file
15
pactest/tests/add045.py
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
self.description = "provision>=1.0-2 dependency (3)"
|
||||||
|
|
||||||
|
p = pmpkg("pkg1", "1.0-2")
|
||||||
|
p.depends = ["provision>=1.0-2"]
|
||||||
|
self.addpkg(p)
|
||||||
|
|
||||||
|
lp = pmpkg("pkg2", "1.0-2")
|
||||||
|
lp.provides = ["provision 1.0-1"]
|
||||||
|
self.addpkg2db("local", lp)
|
||||||
|
|
||||||
|
self.args = "-A %s" % p.filename()
|
||||||
|
|
||||||
|
self.addrule("PACMAN_RETCODE=1")
|
||||||
|
self.addrule("!PKG_EXIST=pkg1")
|
||||||
|
self.addrule("PKG_EXIST=pkg2")
|
10
pactest/tests/sync500.py
Normal file
10
pactest/tests/sync500.py
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
self.description = "-S provision"
|
||||||
|
|
||||||
|
sp = pmpkg("pkg1")
|
||||||
|
sp.provides = ["provision 1.0-1"]
|
||||||
|
self.addpkg2db("sync", sp)
|
||||||
|
|
||||||
|
self.args = "-S provision"
|
||||||
|
|
||||||
|
self.addrule("PACMAN_RETCODE=0")
|
||||||
|
self.addrule("PKG_EXIST=pkg1")
|
Loading…
Reference in New Issue
Block a user