From 283074a4b5dfcb4fb3b5836aa7d3d72fcf3120a6 Mon Sep 17 00:00:00 2001 From: Michael Schroeder Date: Thu, 12 Sep 2024 12:37:09 +0200 Subject: [PATCH] Support rpm's "orderwithrequires" dependency Note that the rpmmd parser cannot set it as the xml schema does not include this type of dependency. --- ext/repo_rpmdb.c | 51 ++++++++++++++++++++++++++++++++++++++++++------ ext/repo_rpmdb.h | 27 +++++++++++++------------ src/knownid.h | 1 + src/order.c | 21 ++++++++++++++++++++ 4 files changed, 81 insertions(+), 19 deletions(-) diff --git a/ext/repo_rpmdb.c b/ext/repo_rpmdb.c index 17334e6e..c2556086 100644 --- a/ext/repo_rpmdb.c +++ b/ext/repo_rpmdb.c @@ -119,6 +119,9 @@ /* rpm4 tags */ #define TAG_LONGFILESIZES 5008 #define TAG_LONGSIZE 5009 +#define TAG_ORDERNAME 5035 +#define TAG_ORDERVERSION 5036 +#define TAG_ORDERFLAGS 5037 #define TAG_RECOMMENDNAME 5046 #define TAG_RECOMMENDVERSION 5047 #define TAG_RECOMMENDFLAGS 5048 @@ -647,8 +650,17 @@ makedeps(Pool *pool, Repo *repo, RpmHead *rpmhead, int tagn, int tagv, int tagf, return 0; } cc += haspre; /* add slot for the prereq marker */ - olddeps = repo_reserve_ids(repo, 0, cc); - ida = repo->idarraydata + olddeps; + if (repo) + { + olddeps = repo_reserve_ids(repo, 0, cc); + ida = repo->idarraydata + olddeps; + } + else + { + olddeps = 0; + queue_prealloc(ignq, cc); + ida = ignq->elements + ignq->count; + } has_ign = 0; for (i = 0; ; i++) @@ -706,19 +718,27 @@ makedeps(Pool *pool, Repo *repo, RpmHead *rpmhead, int tagn, int tagv, int tagf, } } *ida++ = id; - if (haspre == 2 && ignq) + if (haspre == 2 && ignq && repo) { int is_ign = (f[i] & DEP_PRE_IN) != 0 && (f[i] & DEP_PRE_UN) == 0 ? 1 : 0; has_ign |= is_ign; queue_push2(ignq, id, is_ign); } } - *ida++ = 0; - repo->idarraysize += cc + 1; + if (repo) + { + *ida++ = 0; + repo->idarraysize += cc + 1; + } + else + { + ignq->count += cc; + ignq->left -= cc; + } solv_free(n); solv_free(v); solv_free(f); - if (ignq && ignq->count) + if (ignq && ignq->count && repo) { int j = 0; if (has_ign && ignq->count == 2) @@ -1142,6 +1162,13 @@ rpmhead2solv(Pool *pool, Repo *repo, Repodata *data, Solvable *s, RpmHead *rpmhe if (data && ignq.count) repodata_set_idarray(data, s - pool->solvables, SOLVABLE_PREREQ_IGNOREINST, &ignq); + if (data && flags && RPM_ADD_WITH_ORDERWITHREQUIRES) + { + queue_empty(&ignq); + makedeps(pool, NULL, rpmhead, TAG_ORDERNAME, TAG_ORDERVERSION, TAG_ORDERFLAGS, 0, &ignq); + if (ignq.count) + repodata_set_idarray(data, s - pool->solvables, SOLVABLE_ORDERWITHREQUIRES, &ignq); + } queue_free(&ignq); if (data) @@ -1894,6 +1921,7 @@ repo_add_rpm(Repo *repo, const char *rpm, int flags) Chksum *chksumh = 0; Chksum *leadsigchksumh = 0; + flags |= RPM_ADD_WITH_ORDERWITHREQUIRES; data = repo_add_repodata(repo, flags); if ((flags & RPM_ADD_WITH_SHA256SUM) != 0) @@ -2125,6 +2153,7 @@ repo_add_rpm_handle(Repo *repo, void *rpmhandle, int flags) Solvable *s; char *payloadformat; + flags |= RPM_ADD_WITH_ORDERWITHREQUIRES; data = repo_add_repodata(repo, flags); if (headexists(rpmhead, TAG_PATCHESNAME)) { @@ -2381,12 +2410,22 @@ rpm_query_num(void *rpmhandle, Id what, unsigned long long notfound) { RpmHead *rpmhead = rpmhandle; unsigned int u32; + unsigned long long u64; switch (what) { + case SOLVABLE_BUILDTIME: + u32 = headint32(rpmhead, TAG_BUILDTIME); + return u32 ? u32 : notfound; case SOLVABLE_INSTALLTIME: u32 = headint32(rpmhead, TAG_INSTALLTIME); return u32 ? u32 : notfound; + case SOLVABLE_INSTALLSIZE: + u64 = headint64(rpmhead, TAG_LONGSIZE); + if (u64) + return u64; + u32 = headint32(rpmhead, TAG_SIZE); + return u32 ? u32 : notfound; } return notfound; } diff --git a/ext/repo_rpmdb.h b/ext/repo_rpmdb.h index 22aab886..08f83195 100644 --- a/ext/repo_rpmdb.h +++ b/ext/repo_rpmdb.h @@ -15,20 +15,21 @@ extern int repo_add_rpmdb(Repo *repo, Repo *ref, int flags); extern int repo_add_rpmdb_reffp(Repo *repo, FILE *reffp, int flags); extern Id repo_add_rpm(Repo *repo, const char *rpm, int flags); -#define RPMDB_REPORT_PROGRESS (1 << 8) -#define RPM_ADD_WITH_PKGID (1 << 9) -#define RPM_ADD_NO_FILELIST (1 << 10) -#define RPM_ADD_NO_RPMLIBREQS (1 << 11) -#define RPM_ADD_WITH_SHA1SUM (1 << 12) -#define RPM_ADD_WITH_SHA256SUM (1 << 13) -#define RPM_ADD_TRIGGERS (1 << 14) -#define RPM_ADD_WITH_HDRID (1 << 15) -#define RPM_ADD_WITH_LEADSIGID (1 << 16) -#define RPM_ADD_WITH_CHANGELOG (1 << 17) -#define RPM_ADD_FILTERED_FILELIST (1 << 18) -#define RPMDB_KEEP_GPG_PUBKEY (1 << 19) +#define RPMDB_REPORT_PROGRESS (1 << 8) +#define RPM_ADD_WITH_PKGID (1 << 9) +#define RPM_ADD_NO_FILELIST (1 << 10) +#define RPM_ADD_NO_RPMLIBREQS (1 << 11) +#define RPM_ADD_WITH_SHA1SUM (1 << 12) +#define RPM_ADD_WITH_SHA256SUM (1 << 13) +#define RPM_ADD_TRIGGERS (1 << 14) +#define RPM_ADD_WITH_HDRID (1 << 15) +#define RPM_ADD_WITH_LEADSIGID (1 << 16) +#define RPM_ADD_WITH_CHANGELOG (1 << 17) +#define RPM_ADD_FILTERED_FILELIST (1 << 18) +#define RPMDB_KEEP_GPG_PUBKEY (1 << 19) +#define RPM_ADD_WITH_ORDERWITHREQUIRES (1 << 20) -#define RPMDB_EMPTY_REFREPO (1 << 30) /* internal */ +#define RPMDB_EMPTY_REFREPO (1 << 30) /* internal */ #define RPM_ITERATE_FILELIST_ONLYDIRS (1 << 0) #define RPM_ITERATE_FILELIST_WITHMD5 (1 << 1) diff --git a/src/knownid.h b/src/knownid.h index 19f67aef..3d558af3 100644 --- a/src/knownid.h +++ b/src/knownid.h @@ -273,6 +273,7 @@ KNOWNID(SOLVABLE_LANGONLY, "solvable:langonly"), KNOWNID(UPDATE_COLLECTIONLIST, "update:collectionlist"), /* list of UPDATE_COLLECTION (actually packages) and UPDATE_MODULE */ KNOWNID(SOLVABLE_MULTIARCH, "solvable:multiarch"), /* debian multi-arch field */ KNOWNID(SOLVABLE_SIGNATUREDATA, "solvable:signaturedata"), /* conda */ +KNOWNID(SOLVABLE_ORDERWITHREQUIRES, "solvable:orderwithrequires"), /* rpm */ KNOWNID(ID_NUM_INTERNAL, 0) diff --git a/src/order.c b/src/order.c index f36e4468..bd3296d4 100644 --- a/src/order.c +++ b/src/order.c @@ -558,6 +558,27 @@ addsolvableedges(struct orderdata *od, Solvable *s) } } } + if (s->repo != installed && solvable_lookup_idarray(s, SOLVABLE_ORDERWITHREQUIRES, &depq) && depq.count) + { + for (i = 0; i < depq.count; i++) + { + Id req = depq.elements[i]; + FOR_PROVIDES(p2, pp2, req) + { + if (p == p2) + continue; + s2 = pool->solvables + p2; + if (!s2->repo || s2->repo == installed) + continue; + if (!MAPTST(&trans->transactsmap, p2)) + continue; /* not in transaction */ +#if 0 + printf("add orderwithrequires inst->inst edge (%s -> %s -> %s)\n", pool_solvid2str(pool, p), pool_dep2str(pool, req), pool_solvid2str(pool, p2)); +#endif + addedge(od, p, p2, TYPE_REQ); + } + } + } queue_free(&ignoreinst); queue_free(&depq); } -- 2.47.3