distromatic,distroquery: added support for weak-deps (recommends)
This commit is contained in:
parent
c56b8ac2b9
commit
a89f9552ec
@ -701,6 +701,22 @@ json DistroqueryAPI::getPackageDetails(string repository, string package, string
|
||||
sqlite3_finalize(stmt2);
|
||||
}
|
||||
|
||||
// Recommends
|
||||
sql = "SELECT * FROM recommends WHERE recommends.id_package=" + to_string(id);
|
||||
j["recommends"] = json::array();
|
||||
if (sqlite3_prepare_v2(db, sql.c_str(), sql.length(), &stmt2, NULL) == SQLITE_OK) {
|
||||
while (sqlite3_step(stmt2) == SQLITE_ROW) {
|
||||
json recommend = {};
|
||||
recommend["name"] = reinterpret_cast<const char*>(sqlite3_column_text(stmt2,sqlite3_find_column_id(stmt2, NULL, "recommendname")));
|
||||
recommend["flags"] = rpmSenseFlagsToString(sqlite3_column_int(stmt2,sqlite3_find_column_id(stmt2, NULL, "recommendflags")));
|
||||
recommend["version"] = reinterpret_cast<const char*>(sqlite3_column_text(stmt2,sqlite3_find_column_id(stmt2, NULL, "recommendversion")));
|
||||
json jproviders = getProvidersForRequirement(repository, recommend["name"], recommend["flags"], recommend["version"], arch);
|
||||
recommend["providers"] = jproviders["providers"];
|
||||
j["recommends"].push_back(recommend);
|
||||
}
|
||||
sqlite3_finalize(stmt2);
|
||||
}
|
||||
|
||||
// Package files
|
||||
json files = getPackageFiles(repository, package, arch);
|
||||
if (files.contains("files"))
|
||||
|
@ -413,6 +413,9 @@ long generateSQLite_add_needrebuild(sqlite3 *db, struct rebuildList* firstRebuil
|
||||
#define SQLITE_TABLE_requires "id INTEGER PRIMARY KEY, "\
|
||||
"id_package INTEGER, id_provided STRING, requirename STRING, requireflags INTEGER, requireversion STRING"
|
||||
|
||||
#define SQLITE_TABLE_recommends "id INTEGER PRIMARY KEY, "\
|
||||
"id_package INTEGER, id_provided STRING, recommendname STRING, recommendflags INTEGER, recommendversion STRING"
|
||||
|
||||
int
|
||||
generateSQLite_packages(struct configTag *ct, sqlite3 *db, int arch) {
|
||||
|
||||
@ -423,6 +426,7 @@ generateSQLite_packages(struct configTag *ct, sqlite3 *db, int arch) {
|
||||
SQLite_init_table(db, "obsoletes", SQLITE_TABLE_obsoletes);
|
||||
SQLite_init_table(db, "provides", SQLITE_TABLE_provides);
|
||||
SQLite_init_table(db, "requires", SQLITE_TABLE_requires);
|
||||
SQLite_init_table(db, "recommends", SQLITE_TABLE_recommends);
|
||||
SQLite_begin_transaction(db);
|
||||
|
||||
currpackage = ct->headerlist[arch];
|
||||
@ -513,6 +517,30 @@ generateSQLite_packages(struct configTag *ct, sqlite3 *db, int arch) {
|
||||
fprintf(stderr, "WARNING: package %s requires %s not in provided list\n", currpackage->name, currpackage->require[i]->name);
|
||||
}
|
||||
}
|
||||
|
||||
/* recommends */
|
||||
for (i = 0; i < currpackage->recommendcount; i++) {
|
||||
if (currpackage->recommend[i]->resolved) {
|
||||
snprintf(sqlite3_query, PATH_MAX, "INSERT INTO recommends VALUES(NULL,%ld,%ld,?,%ld,?);",
|
||||
currpackage->id,
|
||||
currpackage->recommend[i]->resolved->id,
|
||||
currpackage->recommend[i]->flags);
|
||||
|
||||
if (sqlite3_prepare_v2(db, sqlite3_query, -1, &stmt, NULL)) {
|
||||
fprintf(stderr, "ERROR: SQLite: (%s) %s\n", sqlite3_query, sqlite3_errmsg(db));
|
||||
}
|
||||
sqlite3_bind_text(stmt, 1, currpackage->recommend[i]->name, -1, SQLITE_STATIC);
|
||||
sqlite3_bind_text(stmt, 2, currpackage->recommend[i]->version, -1, SQLITE_STATIC);
|
||||
if (sqlite3_step(stmt) != SQLITE_DONE) {
|
||||
fprintf(stderr, "ERROR: SQLite: (%s) %s\n", sqlite3_query, sqlite3_errmsg(db));
|
||||
return 3;
|
||||
}
|
||||
sqlite3_finalize(stmt);
|
||||
} else if (currpackage->obsoleted == 0 && strstr(currpackage->recommend[i]->name,"rpmlib(") != currpackage->recommend[i]->name) {
|
||||
fprintf(stderr, "WARNING: package %s recommends %s not in provided list\n", currpackage->name, currpackage->recommend[i]->name);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
currpackage = currpackage->next;
|
||||
}
|
||||
|
@ -362,6 +362,237 @@ handleObsoletedPackages(struct configTag *ct, int archidx)
|
||||
return 0;
|
||||
}
|
||||
|
||||
void resolveRequire(struct configTag *ct, int archidx, struct headerList *currheader, struct Require *require) {
|
||||
struct providedList *provided;
|
||||
struct headerList *scanheader, **newprovider;
|
||||
struct fileTree *file;
|
||||
char warning[PATH_MAX];
|
||||
|
||||
assert(require != NULL);
|
||||
assert(require->name != NULL);
|
||||
if (!strncmp("executable(",require->name,11)) {
|
||||
/* dynamic requirement for executable file */
|
||||
/*fprintf(stderr,"Warning: skipping unhandled requirement %s for package %s\n",
|
||||
currheader->require[i]->name,currheader->name);*/
|
||||
require->resolved=NULL;
|
||||
} else if (strncmp("rpmlib(",require->name,7) &&
|
||||
strncmp("debuginfo(build-id)",require->name,20)) {
|
||||
provided=findOrCreateProvidedListEntry((struct providedList**) &ct->providedlist_idx[archidx],
|
||||
require->name,1,archidx);
|
||||
if (provided->numproviders == 0) {
|
||||
// check if require[i]->name requirement is met
|
||||
scanheader = ct->headerlist[archidx];
|
||||
if ((require->name)[0] == '/') {
|
||||
/* requirement is a file, find who provides it */
|
||||
file=findOrCreateFileTreeEntry(&ct->filetree[archidx],require->name, archidx);
|
||||
if (file->numproviders > 0) {
|
||||
scanheader=file->provider[0];
|
||||
provided->numproviders=file->numproviders;
|
||||
provided->numbuildproviders=0;
|
||||
provided->provider=file->provider;
|
||||
provided->flags=0;
|
||||
} else {
|
||||
scanheader=NULL;
|
||||
}
|
||||
} else {
|
||||
/* requirement is not a file, cross-check with provides */
|
||||
while (scanheader && !checkRequireWithProvides(require->name, scanheader))
|
||||
scanheader = scanheader->next;
|
||||
if (scanheader) {
|
||||
provided->numproviders=1;
|
||||
provided->numbuildproviders=0;
|
||||
provided->provider=malloc(sizeof(struct headerList*));
|
||||
provided->provider[0]=scanheader;
|
||||
provided->flags=0;
|
||||
}
|
||||
}
|
||||
if (!scanheader && incremental_mode) {
|
||||
snprintf(warning,PATH_MAX,"%s(%s,%s): missing provider for %s",
|
||||
currheader->name,
|
||||
ct->arch[archidx],
|
||||
ct->repository[currheader->altrepository]->tag,
|
||||
require->name);
|
||||
fprintf(stderr,"Warning: %s\n",warning);
|
||||
addWarning(currheader->sourceheader, currheader, warning);
|
||||
}
|
||||
} else { /* provided->numproviders > 0 */
|
||||
/* warn about provides only provided by older packages */
|
||||
int k=0;
|
||||
for (int j = 0; j < provided->numproviders; j++) {
|
||||
if (provided->provider[j]->sourceheader->updatingparent &&
|
||||
provided->provider[j]->sourceheader->updatingparent->firstchild[archidx] && /* skip if not built for arch */
|
||||
!currheader->obsoleted) k++;
|
||||
}
|
||||
if (k == provided->numproviders) { // all provides are from older packages
|
||||
snprintf(warning, PATH_MAX, "%s(%s,%s) requires %s which is only provided by older package(s):",
|
||||
currheader->name,
|
||||
currheader->arch,
|
||||
ct->repository[currheader->altrepository]->tag,
|
||||
provided->name);
|
||||
for (int j = 0; j < provided->numproviders; j++) {
|
||||
snprintf(&warning[strlen(warning)], PATH_MAX - strlen(warning), " %s(%s,%s)",
|
||||
provided->provider[j]->name,
|
||||
provided->provider[j]->arch,
|
||||
ct->repository[provided->provider[j]->altrepository]->tag);
|
||||
addRebuild(provided->provider[j]->sourceheader,
|
||||
currheader->sourceheader, provided->provider[j]);
|
||||
addWarning(provided->provider[j]->sourceheader, currheader, warning);
|
||||
}
|
||||
fprintf(stderr,"Warning: %s\n",warning);
|
||||
} else {
|
||||
/* warn about provides provided by obsoleted packages */
|
||||
int k=0;
|
||||
for (int j = 0; j < provided->numproviders; j++) {
|
||||
if (provided->provider[j]->obsoleted &&
|
||||
!provided->provider[j]->sourceheader->updatingparent && // don't fall in case above
|
||||
!currheader->obsoleted) k++;
|
||||
}
|
||||
if (k == provided->numproviders) { // all provides are obsoleted
|
||||
snprintf(warning, PATH_MAX, "%s(%s,%s) requires %s which is only provided by obsoleted package(s):",
|
||||
currheader->name,
|
||||
currheader->arch,
|
||||
ct->repository[currheader->altrepository]->tag,
|
||||
provided->name);
|
||||
for (int j = 0; j < provided->numproviders; j++) {
|
||||
snprintf(&warning[strlen(warning)], PATH_MAX - strlen(warning), " %s(%s,%s)",
|
||||
provided->provider[j]->name,
|
||||
provided->provider[j]->arch,
|
||||
ct->repository[provided->provider[j]->altrepository]->tag);
|
||||
}
|
||||
fprintf(stderr,"Warning: %s\n",warning);
|
||||
addWarning(currheader->sourceheader, currheader, warning);
|
||||
for (int j = 0; j < provided->numproviders; j++) {
|
||||
addWarning(provided->provider[j]->sourceheader, currheader, warning);
|
||||
}
|
||||
}
|
||||
}
|
||||
if ((require->name)[0] == '/') {
|
||||
/* when there is a Requires: /file/requirement add provide from file tree as well */
|
||||
file=findOrCreateFileTreeEntry(&ct->filetree[archidx],require->name, archidx);
|
||||
for (k = 0; k < file->numproviders; k++) {
|
||||
int found = 0;
|
||||
for (int j = 0; j < provided->numproviders; j++) {
|
||||
/* avoid duplicates */
|
||||
if (file->provider[k] == provided->provider[j]) {
|
||||
found = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
//printf("%s also provided by %s\n", currheader->require[i]->name, file->provider[k]->name);
|
||||
provided->numproviders++;
|
||||
newprovider=malloc(sizeof(struct headerList*)*provided->numproviders);
|
||||
for (int j = 0; j < provided->numproviders-1; j++) {
|
||||
newprovider[j]=provided->provider[j];
|
||||
}
|
||||
newprovider[provided->numproviders-1] = file->provider[k];
|
||||
if (provided->provider) free(provided->provider);
|
||||
provided->provider=newprovider;
|
||||
char **newversion=malloc(sizeof(char *)*provided->numproviders);
|
||||
for (int j = 0; j < provided->numproviders-1; j++) {
|
||||
newversion[j]=provided->version[j];
|
||||
}
|
||||
newversion[provided->numproviders-1] = strdup(provided->provider[provided->numproviders-2]->version);
|
||||
if (provided->version) free(provided->version);
|
||||
provided->version=newversion;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (provided->numproviders > 0) {
|
||||
if (strcmp(require->version,"") &&
|
||||
(require->flags & (RPMSENSE_LESS|RPMSENSE_GREATER|RPMSENSE_EQUAL))) {
|
||||
int found = 0;
|
||||
int foundprovider = -1;
|
||||
int foundupstreamprovider = 0;
|
||||
for (int j = 0; j < provided->numproviders; j++) {
|
||||
/* updated packages: ignore check with upstream package */
|
||||
if ((foundprovider >= 0) &&
|
||||
!strcmp(provided->provider[foundprovider]->name,provided->provider[j]->name) &&
|
||||
provided->provider[foundprovider]->altrepository < provided->provider[j]->altrepository) {
|
||||
found -= 1;
|
||||
foundupstreamprovider = foundprovider;
|
||||
foundprovider = -1;
|
||||
}
|
||||
if (!strcmp(provided->version[j],"")) {
|
||||
/* provider with no version; assume ok */
|
||||
found += 1;
|
||||
foundupstreamprovider = foundprovider;
|
||||
foundprovider = j;
|
||||
} else {
|
||||
if (checkVersionWithFlags(
|
||||
require->version,
|
||||
require->flags,
|
||||
provided->version[j])) {
|
||||
found += 1;
|
||||
foundupstreamprovider = foundprovider;
|
||||
foundprovider = j;
|
||||
}
|
||||
}
|
||||
} /* for */
|
||||
if ((found >= 1) && (!foundupstreamprovider) &&
|
||||
(currheader->altrepository != 0) &&
|
||||
(currheader->altrepository = ct->repository_level) &&
|
||||
(provided->provider[foundprovider]->sourceheader != currheader->sourceheader) &&
|
||||
(provided->provider[foundprovider]->altrepository == currheader->altrepository)) {
|
||||
snprintf(warning, PATH_MAX, "%s(%s,%s) requires %s(%s,%s) because it needs %s=%s",
|
||||
currheader->name, currheader->arch,
|
||||
ct->repository[currheader->altrepository]->tag,
|
||||
provided->provider[foundprovider]->name,
|
||||
provided->provider[foundprovider]->arch,
|
||||
ct->repository[provided->provider[foundprovider]->altrepository]->tag,
|
||||
provided->name,
|
||||
provided->version[foundprovider]);
|
||||
logmsg(LOG_WARNING,"%s", warning);
|
||||
addWarning(currheader->sourceheader, currheader, warning);
|
||||
} else if (!found) {
|
||||
for (int j = 0; j < provided->numproviders; j++) {
|
||||
if (!checkVersionWithFlags(
|
||||
require->version,
|
||||
require->flags,
|
||||
provided->version[j])) {
|
||||
snprintf(warning, PATH_MAX, "%s=%s from %s(%s,%s) fails to provide %s",
|
||||
provided->name,
|
||||
provided->version[j],
|
||||
provided->provider[j]->name,
|
||||
provided->provider[j]->arch,
|
||||
ct->repository[provided->provider[j]->altrepository]->tag,
|
||||
provided->name);
|
||||
if (require->flags & RPMSENSE_LESS)
|
||||
snprintf(&warning[strlen(warning)], PATH_MAX,"<");
|
||||
if (require->flags & RPMSENSE_GREATER)
|
||||
snprintf(&warning[strlen(warning)], PATH_MAX, ">");
|
||||
if (require->flags & RPMSENSE_EQUAL)
|
||||
snprintf(&warning[strlen(warning)], PATH_MAX, "=");
|
||||
snprintf(&warning[strlen(warning)], PATH_MAX, "%s to %s(%s,%s)",
|
||||
require->version,
|
||||
currheader->name,
|
||||
currheader->arch,
|
||||
ct->repository[currheader->altrepository]->tag);
|
||||
logmsg(LOG_WARNING,"%s", warning);
|
||||
for (int k = 0; k < provided->numproviders; k++) {
|
||||
if (provided->provider[k]->sourceheader &&
|
||||
(provided->provider[k]->altrepository == ct->repository_level)) {
|
||||
addWarning(provided->provider[k]->sourceheader, currheader, warning);
|
||||
addRebuild(provided->provider[k]->sourceheader,
|
||||
currheader->sourceheader, provided->provider[k]);
|
||||
}
|
||||
if ((currheader->altrepository == ct->repository_level)) {
|
||||
addWarning(currheader->sourceheader, currheader, warning);
|
||||
}
|
||||
}
|
||||
}
|
||||
} /* for */
|
||||
}
|
||||
}
|
||||
}
|
||||
require->resolved=provided;
|
||||
} else {
|
||||
require->resolved=NULL;
|
||||
} /* if */
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* resolve first level requires for given headerList
|
||||
* note: this function doesn't free allocated memory so it should be called
|
||||
@ -369,19 +600,14 @@ handleObsoletedPackages(struct configTag *ct, int archidx)
|
||||
static int
|
||||
resolveFirstLevelDependencies(struct configTag *ct, int archidx)
|
||||
{
|
||||
struct headerList *currheader, *scanheader, **newprovider;
|
||||
struct providedList *provided;
|
||||
struct fileTree *file;
|
||||
int i,j,k,found,foundprovider, foundupstreamprovider;
|
||||
struct headerList *currheader;
|
||||
char warning[PATH_MAX];
|
||||
char ** newversion;
|
||||
|
||||
currheader = ct->headerlist[archidx];
|
||||
|
||||
logmsg(LOG_DEBUG,"resolveFirstLevelDependencies - binaries");
|
||||
|
||||
while (currheader) {
|
||||
scanheader = ct->headerlist[archidx];
|
||||
currheader->requirelist = NULL;
|
||||
if ((!currheader->obsoleted) && (currheader->next) && (currheader->sourceheader->updatingparent)) {
|
||||
// mark obsoleted any package with same name in upper level repositories
|
||||
@ -424,236 +650,27 @@ resolveFirstLevelDependencies(struct configTag *ct, int archidx)
|
||||
currheader = currheader->next;
|
||||
continue;
|
||||
}
|
||||
// currheader->require.resolved = malloc(sizeof(struct providedList*)*currheader->requirecount);
|
||||
for (i = 0; i < currheader->requirecount; i++) {
|
||||
assert(currheader->require[i] != NULL);
|
||||
assert(currheader->require[i]->name != NULL);
|
||||
if (!strncmp("executable(",currheader->require[i]->name,11)) {
|
||||
/* dynamic requirement for executable file */
|
||||
/*fprintf(stderr,"Warning: skipping unhandled requirement %s for package %s\n",
|
||||
currheader->require[i]->name,currheader->name);*/
|
||||
currheader->require[i]->resolved=NULL;
|
||||
} else if (strncmp("rpmlib(",currheader->require[i]->name,7) &&
|
||||
strncmp("debuginfo(build-id)",currheader->require[i]->name,20)) {
|
||||
provided=findOrCreateProvidedListEntry((struct providedList**) &ct->providedlist_idx[archidx],
|
||||
currheader->require[i]->name,1,archidx);
|
||||
if (provided->numproviders == 0) {
|
||||
// check if require[i]->name requirement is met
|
||||
scanheader = ct->headerlist[archidx];
|
||||
if ((currheader->require[i]->name)[0] == '/') {
|
||||
/* requirement is a file, find who provides it */
|
||||
file=findOrCreateFileTreeEntry(&ct->filetree[archidx],currheader->require[i]->name, archidx);
|
||||
if (file->numproviders > 0) {
|
||||
scanheader=file->provider[0];
|
||||
provided->numproviders=file->numproviders;
|
||||
provided->numbuildproviders=0;
|
||||
provided->provider=file->provider;
|
||||
provided->flags=0;
|
||||
} else {
|
||||
scanheader=NULL;
|
||||
}
|
||||
} else {
|
||||
/* requirement is not a file, cross-check with provides */
|
||||
while (scanheader && !checkRequireWithProvides(
|
||||
currheader->require[i]->name, scanheader))
|
||||
scanheader = scanheader->next;
|
||||
if (scanheader) {
|
||||
provided->numproviders=1;
|
||||
provided->numbuildproviders=0;
|
||||
provided->provider=malloc(sizeof(struct headerList*));
|
||||
provided->provider[0]=scanheader;
|
||||
provided->flags=0;
|
||||
}
|
||||
}
|
||||
if (!scanheader && incremental_mode) {
|
||||
snprintf(warning,PATH_MAX,"%s(%s,%s): missing provider for %s",
|
||||
currheader->name,
|
||||
ct->arch[archidx],
|
||||
ct->repository[currheader->altrepository]->tag,
|
||||
currheader->require[i]->name);
|
||||
fprintf(stderr,"Warning: %s\n",warning);
|
||||
addWarning(currheader->sourceheader, currheader, warning);
|
||||
}
|
||||
} else { /* provided->numproviders > 0 */
|
||||
/* warn about provides only provided by older packages */
|
||||
k=0;
|
||||
for (j = 0; j < provided->numproviders; j++) {
|
||||
if (provided->provider[j]->sourceheader->updatingparent &&
|
||||
provided->provider[j]->sourceheader->updatingparent->firstchild[archidx] && /* skip if not built for arch */
|
||||
!currheader->obsoleted) k++;
|
||||
}
|
||||
if (k == provided->numproviders) { // all provides are from older packages
|
||||
snprintf(warning, PATH_MAX, "%s(%s,%s) requires %s which is only provided by older package(s):",
|
||||
currheader->name,
|
||||
currheader->arch,
|
||||
ct->repository[currheader->altrepository]->tag,
|
||||
provided->name);
|
||||
for (j = 0; j < provided->numproviders; j++) {
|
||||
snprintf(&warning[strlen(warning)], PATH_MAX - strlen(warning), " %s(%s,%s)",
|
||||
provided->provider[j]->name,
|
||||
provided->provider[j]->arch,
|
||||
ct->repository[provided->provider[j]->altrepository]->tag);
|
||||
addRebuild(provided->provider[j]->sourceheader,
|
||||
currheader->sourceheader, provided->provider[j]);
|
||||
addWarning(provided->provider[j]->sourceheader, currheader, warning);
|
||||
}
|
||||
fprintf(stderr,"Warning: %s\n",warning);
|
||||
} else {
|
||||
/* warn about provides provided by obsoleted packages */
|
||||
k=0;
|
||||
for (j = 0; j < provided->numproviders; j++) {
|
||||
if (provided->provider[j]->obsoleted &&
|
||||
!provided->provider[j]->sourceheader->updatingparent && // don't fall in case above
|
||||
!currheader->obsoleted) k++;
|
||||
}
|
||||
if (k == provided->numproviders) { // all provides are obsoleted
|
||||
snprintf(warning, PATH_MAX, "%s(%s,%s) requires %s which is only provided by obsoleted package(s):",
|
||||
currheader->name,
|
||||
currheader->arch,
|
||||
ct->repository[currheader->altrepository]->tag,
|
||||
provided->name);
|
||||
for (j = 0; j < provided->numproviders; j++) {
|
||||
snprintf(&warning[strlen(warning)], PATH_MAX - strlen(warning), " %s(%s,%s)",
|
||||
provided->provider[j]->name,
|
||||
provided->provider[j]->arch,
|
||||
ct->repository[provided->provider[j]->altrepository]->tag);
|
||||
}
|
||||
fprintf(stderr,"Warning: %s\n",warning);
|
||||
addWarning(currheader->sourceheader, currheader, warning);
|
||||
for (j = 0; j < provided->numproviders; j++) {
|
||||
addWarning(provided->provider[j]->sourceheader, currheader, warning);
|
||||
}
|
||||
}
|
||||
}
|
||||
if ((currheader->require[i]->name)[0] == '/') {
|
||||
/* when there is a Requires: /file/requirement add provide from file tree as well */
|
||||
file=findOrCreateFileTreeEntry(&ct->filetree[archidx],currheader->require[i]->name, archidx);
|
||||
for (k = 0; k < file->numproviders; k++) {
|
||||
for (j = 0, found = 0; j < provided->numproviders; j++) {
|
||||
/* avoid duplicates */
|
||||
if (file->provider[k] == provided->provider[j]) {
|
||||
found = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (! found) {
|
||||
//printf("%s also provided by %s\n", currheader->require[i]->name, file->provider[k]->name);
|
||||
provided->numproviders++;
|
||||
newprovider=malloc(sizeof(struct headerList*)*provided->numproviders);
|
||||
for (j = 0; j < provided->numproviders-1; j++) {
|
||||
newprovider[j]=provided->provider[j];
|
||||
}
|
||||
newprovider[provided->numproviders-1] = file->provider[k];
|
||||
if (provided->provider) free(provided->provider);
|
||||
provided->provider=newprovider;
|
||||
newversion=malloc(sizeof(char *)*provided->numproviders);
|
||||
for (j = 0; j < provided->numproviders-1; j++) {
|
||||
newversion[j]=provided->version[j];
|
||||
}
|
||||
newversion[provided->numproviders-1] = strdup(provided->provider[j]->version);
|
||||
if (provided->version) free(provided->version);
|
||||
provided->version=newversion;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (provided->numproviders > 0) {
|
||||
if (strcmp(currheader->require[i]->version,"") &&
|
||||
(currheader->require[i]->flags & (RPMSENSE_LESS|RPMSENSE_GREATER|RPMSENSE_EQUAL))) {
|
||||
found = 0;
|
||||
foundprovider = -1;
|
||||
foundupstreamprovider = 0;
|
||||
for (j = 0; j < provided->numproviders; j++) {
|
||||
/* updated packages: ignore check with upstream package */
|
||||
if ((foundprovider >= 0) &&
|
||||
!strcmp(provided->provider[foundprovider]->name,provided->provider[j]->name) &&
|
||||
provided->provider[foundprovider]->altrepository < provided->provider[j]->altrepository) {
|
||||
found -= 1;
|
||||
foundupstreamprovider = foundprovider;
|
||||
foundprovider = -1;
|
||||
}
|
||||
if (!strcmp(provided->version[j],"")) {
|
||||
/* provider with no version; assume ok */
|
||||
found += 1;
|
||||
foundupstreamprovider = foundprovider;
|
||||
foundprovider = j;
|
||||
} else {
|
||||
if (checkVersionWithFlags(
|
||||
currheader->require[i]->version,
|
||||
currheader->require[i]->flags,
|
||||
provided->version[j])) {
|
||||
found += 1;
|
||||
foundupstreamprovider = foundprovider;
|
||||
foundprovider = j;
|
||||
}
|
||||
}
|
||||
} /* for */
|
||||
if ((found >= 1) && (!foundupstreamprovider) &&
|
||||
(currheader->altrepository != 0) &&
|
||||
(currheader->altrepository = ct->repository_level) &&
|
||||
(provided->provider[foundprovider]->sourceheader != currheader->sourceheader) &&
|
||||
(provided->provider[foundprovider]->altrepository == currheader->altrepository)) {
|
||||
snprintf(warning, PATH_MAX, "%s(%s,%s) requires %s(%s,%s) because it needs %s=%s",
|
||||
currheader->name, currheader->arch,
|
||||
ct->repository[currheader->altrepository]->tag,
|
||||
provided->provider[foundprovider]->name,
|
||||
provided->provider[foundprovider]->arch,
|
||||
ct->repository[provided->provider[foundprovider]->altrepository]->tag,
|
||||
provided->name,
|
||||
provided->version[foundprovider]);
|
||||
logmsg(LOG_WARNING,"%s", warning);
|
||||
addWarning(currheader->sourceheader, currheader, warning);
|
||||
} else if (!found) {
|
||||
for (j = 0; j < provided->numproviders; j++) {
|
||||
if (!checkVersionWithFlags(
|
||||
currheader->require[i]->version,
|
||||
currheader->require[i]->flags,
|
||||
provided->version[j])) {
|
||||
snprintf(warning, PATH_MAX, "%s=%s from %s(%s,%s) fails to provide %s",
|
||||
provided->name,
|
||||
provided->version[j],
|
||||
provided->provider[j]->name,
|
||||
provided->provider[j]->arch,
|
||||
ct->repository[provided->provider[j]->altrepository]->tag,
|
||||
provided->name);
|
||||
if (currheader->require[i]->flags & RPMSENSE_LESS)
|
||||
snprintf(&warning[strlen(warning)], PATH_MAX,"<");
|
||||
if (currheader->require[i]->flags & RPMSENSE_GREATER)
|
||||
snprintf(&warning[strlen(warning)], PATH_MAX, ">");
|
||||
if (currheader->require[i]->flags & RPMSENSE_EQUAL)
|
||||
snprintf(&warning[strlen(warning)], PATH_MAX, "=");
|
||||
snprintf(&warning[strlen(warning)], PATH_MAX, "%s to %s(%s,%s)",
|
||||
currheader->require[i]->version,
|
||||
currheader->name,
|
||||
currheader->arch,
|
||||
ct->repository[currheader->altrepository]->tag);
|
||||
logmsg(LOG_WARNING,"%s", warning);
|
||||
for (k = 0; k < provided->numproviders; k++) {
|
||||
if (provided->provider[k]->sourceheader &&
|
||||
(provided->provider[k]->altrepository == ct->repository_level)) {
|
||||
addWarning(provided->provider[k]->sourceheader, currheader, warning);
|
||||
addRebuild(provided->provider[k]->sourceheader,
|
||||
currheader->sourceheader, provided->provider[k]);
|
||||
}
|
||||
if ((currheader->altrepository == ct->repository_level)) {
|
||||
addWarning(currheader->sourceheader, currheader, warning);
|
||||
}
|
||||
}
|
||||
}
|
||||
} /* for */
|
||||
}
|
||||
}
|
||||
}
|
||||
currheader->require[i]->resolved=provided;
|
||||
} else {
|
||||
currheader->require[i]->resolved=NULL;
|
||||
} /* if */
|
||||
|
||||
// Resolve requires
|
||||
for (int i = 0; i < currheader->requirecount; i++) {
|
||||
resolveRequire(ct, archidx, currheader, currheader->require[i]);
|
||||
} /* for currheader->requirecount */
|
||||
// sort required list by first provider's name
|
||||
qsort((void *) &currheader->require[0],
|
||||
currheader->requirecount,
|
||||
sizeof(struct Require *),
|
||||
compareRequiredList);
|
||||
|
||||
// Resolve recommends
|
||||
for (int i = 0; i < currheader->recommendcount; i++) {
|
||||
resolveRequire(ct, archidx, currheader, currheader->recommend[i]);
|
||||
} /* for currheader->requirecount */
|
||||
// sort recommend list by first provider's name
|
||||
qsort((void *) &currheader->recommend[0],
|
||||
currheader->recommendcount,
|
||||
sizeof(struct Require *),
|
||||
compareRequiredList);
|
||||
|
||||
currheader = currheader->next;
|
||||
}
|
||||
logmsg(LOG_DEBUG,"resolveFirstLevelDependencies - done");
|
||||
|
@ -1472,16 +1472,17 @@ char* advanceXMLPackageNode(xmlNode **primary_node, xmlNode **filelists_node) {
|
||||
char filepath[bufsize + 1], currname[bufsize + 1];
|
||||
char *filename=NULL;
|
||||
long i ,j , k, n=0, altn[ALT_REPS_MAX];
|
||||
int altrepository=0, obsoletecount, providecount, requirecount,
|
||||
int altrepository=0, obsoletecount, providecount, requirecount, recommendcount,
|
||||
filenamecount, dirnamecount, alt_reps_num = 0;
|
||||
int_16 *fileflags;
|
||||
char **obsoletename, **obsoleteversion,
|
||||
**providename, **provideversion,
|
||||
**requirename, **requireversion,
|
||||
**recommendname, **recommendversion,
|
||||
**basename, **dirname, **newversion,
|
||||
**fileusername, **filegroupname;
|
||||
const char* errstr;
|
||||
uint_32 *dirindex, *requireflags, *obsoleteflags, *provideflags;
|
||||
uint_32 *dirindex, *requireflags, *recommendflags, *obsoleteflags, *provideflags;
|
||||
#if RPM_VERSION >= 0x050000
|
||||
rpmts ts = rpmtsCreate();
|
||||
#else
|
||||
@ -1660,6 +1661,9 @@ char* advanceXMLPackageNode(xmlNode **primary_node, xmlNode **filelists_node) {
|
||||
getXMLPackageNFV(newheaderlist->name,
|
||||
findXMLPropertyByName(format, "requires"),
|
||||
&requirename, &requireflags, &requireversion, &requirecount);
|
||||
getXMLPackageNFV(newheaderlist->name,
|
||||
findXMLPropertyByName(format, "recommends"),
|
||||
&recommendname, &recommendflags, &recommendversion, &recommendcount);
|
||||
|
||||
newheaderlist->provided = malloc(sizeof(struct providedList*)*providecount);
|
||||
for (i=0; i < providecount; i++) {
|
||||
@ -1703,6 +1707,7 @@ char* advanceXMLPackageNode(xmlNode **primary_node, xmlNode **filelists_node) {
|
||||
newheaderlist->obsoleteversion = obsoleteversion;
|
||||
newheaderlist->obsoletecount = obsoletecount;
|
||||
newheaderlist->altrepository = altidx;
|
||||
|
||||
// Requires
|
||||
newheaderlist->require = malloc(requirecount * sizeof(struct Require *));
|
||||
for (j=0; j < requirecount; j++) {
|
||||
@ -1713,6 +1718,18 @@ char* advanceXMLPackageNode(xmlNode **primary_node, xmlNode **filelists_node) {
|
||||
newheaderlist->require[j]->resolved = NULL;
|
||||
}
|
||||
newheaderlist->requirecount = requirecount;
|
||||
|
||||
// Recommends
|
||||
newheaderlist->recommend = malloc(recommendcount * sizeof(struct Require *));
|
||||
for (j=0; j < recommendcount; j++) {
|
||||
newheaderlist->recommend[j] = malloc(sizeof(struct Require));
|
||||
newheaderlist->recommend[j]->name = recommendname[j];
|
||||
newheaderlist->recommend[j]->flags = recommendflags[j];
|
||||
newheaderlist->recommend[j]->version = recommendversion[j];
|
||||
newheaderlist->recommend[j]->resolved = NULL;
|
||||
}
|
||||
newheaderlist->recommendcount = recommendcount;
|
||||
|
||||
// Files
|
||||
getXMLPackageFiles(filelists_node[altidx], &basename,
|
||||
&fileusername, &filegroupname, &filenamecount, &fileflags);
|
||||
@ -1826,6 +1843,8 @@ char* advanceXMLPackageNode(xmlNode **primary_node, xmlNode **filelists_node) {
|
||||
&provideversion, &providecount);
|
||||
getPackageRequires(h, &requirename, &requireflags,
|
||||
&requireversion, &requirecount);
|
||||
getPackageRecommends(h, &recommendname, &recommendflags,
|
||||
&recommendversion, &recommendcount);
|
||||
getPackageFiles(h, &dirindex, &dirname, &dirnamecount,
|
||||
&basename, &filenamecount,
|
||||
&fileusername, &filegroupname, &fileflags);
|
||||
@ -1885,6 +1904,8 @@ char* advanceXMLPackageNode(xmlNode **primary_node, xmlNode **filelists_node) {
|
||||
newheaderlist->obsoleteversion = obsoleteversion;
|
||||
newheaderlist->obsoletecount = obsoletecount;
|
||||
newheaderlist->altrepository = altrepository;
|
||||
|
||||
// Requires
|
||||
newheaderlist->require = malloc(requirecount * sizeof(struct Require *));
|
||||
for (j=0; j < requirecount; j++) {
|
||||
newheaderlist->require[j] = malloc(sizeof(struct Require));
|
||||
@ -1894,6 +1915,18 @@ char* advanceXMLPackageNode(xmlNode **primary_node, xmlNode **filelists_node) {
|
||||
newheaderlist->require[j]->resolved = NULL;
|
||||
}
|
||||
newheaderlist->requirecount = requirecount;
|
||||
|
||||
// Recommends
|
||||
newheaderlist->recommend = malloc(recommendcount * sizeof(struct Require *));
|
||||
for (j=0; j < recommendcount; j++) {
|
||||
newheaderlist->recommend[j] = malloc(sizeof(struct Require));
|
||||
newheaderlist->recommend[j]->name = recommendname[j];
|
||||
newheaderlist->recommend[j]->flags = recommendflags[j];
|
||||
newheaderlist->recommend[j]->version = recommendversion[j];
|
||||
newheaderlist->recommend[j]->resolved = NULL;
|
||||
}
|
||||
newheaderlist->recommendcount = recommendcount;
|
||||
|
||||
newheaderlist->file =
|
||||
malloc(sizeof(struct fileTree*) * filenamecount);
|
||||
newheaderlist->fileflags =
|
||||
|
@ -1,7 +1,7 @@
|
||||
/*
|
||||
* distromatic - tool for RPM based repositories
|
||||
*
|
||||
* Copyright (C) 2004-2020 by Silvan Calarco <silvan.calarco@mambasoft.it>
|
||||
* Copyright (C) 2004-2024 by Silvan Calarco <silvan.calarco@mambasoft.it>
|
||||
* Copyright (C) 2006 by Davide Madrisan <davide.madrisan@gmail.com>
|
||||
*/
|
||||
|
||||
@ -95,6 +95,8 @@ struct headerList {
|
||||
int providecount;
|
||||
int requirecount;
|
||||
struct Require **require;
|
||||
int recommendcount;
|
||||
struct Require **recommend;
|
||||
struct providedList **provided;
|
||||
int filenamecount;
|
||||
struct fileTree **file;
|
||||
|
@ -55,6 +55,10 @@ int getPackageRequires(
|
||||
Header h, char ***requirename, uint_32 **requireflags,
|
||||
char ***requireversion, int *requirecount);
|
||||
|
||||
int getPackageRecommends(
|
||||
Header h, char ***recommendname, uint_32 **recommendflags,
|
||||
char ***recommendversion, int *recommendcount);
|
||||
|
||||
int getPackageProvides(
|
||||
Header h, char ***providename, uint_32 **provideflags,
|
||||
char ***provideversion, int *providecount);
|
||||
|
@ -26,7 +26,6 @@
|
||||
#include "reports.h"
|
||||
#include "rpmfunctions.h"
|
||||
#include "functions.h"
|
||||
#include "requirelist.h"
|
||||
#include <errno.h>
|
||||
#include <time.h>
|
||||
|
||||
@ -1833,6 +1832,8 @@ int print_datatables(struct configTag *ct, int arch) {
|
||||
currheaderlist = ct->headerlist[arch];
|
||||
while (currheaderlist) {
|
||||
fprintf(fd,"%s: ", currheaderlist->name);
|
||||
|
||||
// Add requires
|
||||
for (i = 0; i < currheaderlist->requirecount; i++) {
|
||||
if (currheaderlist->require[i]->resolved) {
|
||||
if (currheaderlist->require[i]->resolved->numproviders == 0) {
|
||||
@ -1868,6 +1869,43 @@ int print_datatables(struct configTag *ct, int arch) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Add recommends (weak-deps)
|
||||
for (i = 0; i < currheaderlist->recommendcount; i++) {
|
||||
if (currheaderlist->recommend[i]->resolved) {
|
||||
if (currheaderlist->recommend[i]->resolved->numproviders == 0) {
|
||||
// Filter out complex deps like "(name >= ver1 with name < ver2)
|
||||
if (currheaderlist->recommend[i]->resolved->name[0] != '(') {
|
||||
fprintf_depstable_filtered_var(fd,
|
||||
currheaderlist->recommend[i]->resolved->name);
|
||||
fprintf(fd,"_unresolved_ ");
|
||||
}
|
||||
} else if (currheaderlist->recommend[i]->resolved->numproviders == 1) {
|
||||
if ((i == 0 ||
|
||||
!currheaderlist->recommend[i-1]->resolved ||
|
||||
!currheaderlist->recommend[i-1]->resolved->numproviders ||
|
||||
strcmp(currheaderlist->recommend[i-1]->resolved->provider[0]->name,
|
||||
currheaderlist->recommend[i]->resolved->provider[0]->name)) &&
|
||||
strcmp(currheaderlist->name,
|
||||
currheaderlist->recommend[i]->resolved->provider[0]->name)) {
|
||||
fprintf(fd,"%s ",currheaderlist->recommend[i]->resolved->provider[0]->name);
|
||||
}
|
||||
} else {
|
||||
if (i == 0 ||
|
||||
!currheaderlist->recommend[i-1]->resolved ||
|
||||
!currheaderlist->recommend[i-1]->resolved->numproviders ||
|
||||
strcmp(currheaderlist->recommend[i-1]->resolved->name,
|
||||
currheaderlist->recommend[i]->resolved->name)) {
|
||||
fprintf_depstable_filtered_var(fd,currheaderlist->recommend[i]->resolved->name);
|
||||
fprintf(fd," ");
|
||||
}
|
||||
}
|
||||
for (int j = 0; j < currheaderlist->recommend[i]->resolved->numproviders; j++) {
|
||||
if (currheaderlist->recommend[i]->resolved->provider[j]->sourceheader != currheaderlist->sourceheader)
|
||||
currheaderlist->recommend[i]->resolved->provider[j]->sourceheader->childrenrequiredcount[arch]++;
|
||||
}
|
||||
}
|
||||
}
|
||||
fprintf(fd,"\n");
|
||||
|
||||
//
|
||||
|
@ -303,6 +303,17 @@ getPackageRequires(Header h, char ***requirename, uint_32 **requireflags,
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
getPackageRecommends(Header h, char ***recommendname, uint_32 **recommendflags,
|
||||
char ***recommendversion, int *recommendcount)
|
||||
{
|
||||
*recommendname = headerGetStringArrayEntry(h, RPMTAG_RECOMMENDNAME, recommendcount);
|
||||
*recommendflags = headerGetUIntArrayEntry(h, RPMTAG_RECOMMENDFLAGS, recommendcount);
|
||||
*recommendversion = headerGetStringArrayEntry(h, RPMTAG_RECOMMENDVERSION, recommendcount);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
getPackageProvides(Header h, char ***providename, uint_32 **provideflags,
|
||||
char ***provideversion, int *providecount)
|
||||
|
Loading…
Reference in New Issue
Block a user