Add support for weak dependencies: A) use RPMTAG_SUGGESTS and RPMTAG_ENHANCES to store them. This is different to upstream, which uses RPMSENSE_MISSINGOK and RPMTAG_REQUIRES/RPMTAG_PROVIDES instead. I chose different tags because I wanted to be compatible. The point is that applications that don't know about the new MISSINGOK semantics will mis-interpret the provides/requires otherwise, which I deemed to risky. B) use RPMSENSE_STRONG to support a "strong" version, "Recommends" instead of "Suggests" and "Supplements" instead of "Enhances". Needs extcond.diff for query operations. --- build/parsePreamble.c +++ build/parsePreamble.c @@ -342,6 +342,8 @@ { "verify", RPMSENSE_SCRIPT_VERIFY }, { "pretrans", RPMSENSE_PRETRANS }, { "posttrans", RPMSENSE_POSTTRANS }, + { "hint", RPMSENSE_MISSINGOK }, + { "strong", RPMSENSE_STRONG }, { NULL, 0 } }; @@ -816,6 +818,18 @@ if (parseRCPOT(spec, pkg, field, tag, 0, tagflags)) goto exit; break; + case RPMTAG_SUGGESTSFLAGS: + case RPMTAG_ENHANCESFLAGS: + case RPMTAG_BUILDSUGGESTS: + case RPMTAG_BUILDENHANCES: + tagflags = RPMSENSE_MISSINGOK; + if (macro && (!strcmp(macro, "recommends") || !strcmp(macro, "buildrecommends"))) + tagflags |= RPMSENSE_STRONG; + if (macro && (!strcmp(macro, "supplements") || !strcmp(macro, "buildsupplements"))) + tagflags |= RPMSENSE_STRONG; + if ((rc = parseRCPOT(spec, pkg, field, tag, 0, tagflags))) + return rc; + break; case RPMTAG_EXCLUDEARCH: case RPMTAG_EXCLUSIVEARCH: case RPMTAG_EXCLUDEOS: @@ -924,6 +938,14 @@ {RPMTAG_BUGURL, 0, 0, LEN_AND_STR("bugurl")}, {RPMTAG_COLLECTIONS, 0, 0, LEN_AND_STR("collections")}, {RPMTAG_ORDERFLAGS, 2, 0, LEN_AND_STR("orderwithrequires")}, + {RPMTAG_SUGGESTSFLAGS, 0, 0, LEN_AND_STR("recommends")}, + {RPMTAG_SUGGESTSFLAGS, 0, 0, LEN_AND_STR("suggests")}, + {RPMTAG_ENHANCESFLAGS, 0, 0, LEN_AND_STR("supplements")}, + {RPMTAG_ENHANCESFLAGS, 0, 0, LEN_AND_STR("enhances")}, + {RPMTAG_BUILDSUGGESTS, 0, 0, LEN_AND_STR("buildrecommends")}, + {RPMTAG_BUILDSUGGESTS, 0, 0, LEN_AND_STR("buildsuggests")}, + {RPMTAG_BUILDENHANCES, 0, 0, LEN_AND_STR("buildsupplements")}, + {RPMTAG_BUILDENHANCES, 0, 0, LEN_AND_STR("buildenhances")}, {0, 0, 0, 0} }; --- build/parseReqs.c +++ build/parseReqs.c @@ -95,6 +95,20 @@ nametag = RPMTAG_CONFLICTNAME; h = spec->buildRestrictions; break; + case RPMTAG_SUGGESTSFLAGS: + nametag = RPMTAG_SUGGESTSNAME; + break; + case RPMTAG_ENHANCESFLAGS: + nametag = RPMTAG_ENHANCESNAME; + break; + case RPMTAG_BUILDSUGGESTS: + nametag = RPMTAG_SUGGESTSNAME; + h = spec->buildRestrictions; + break; + case RPMTAG_BUILDENHANCES: + nametag = RPMTAG_ENHANCESNAME; + h = spec->buildRestrictions; + break; } for (r = field; *r != '\0'; r = re) { --- build/reqprov.c +++ build/reqprov.c @@ -75,6 +75,16 @@ indextag = RPMTAG_TRIGGERINDEX; extra = Flags & RPMSENSE_TRIGGER; break; + case RPMTAG_SUGGESTSNAME: + versiontag = RPMTAG_SUGGESTSVERSION; + flagtag = RPMTAG_SUGGESTSFLAGS; + extra = Flags & _ALL_REQUIRES_MASK; + break; + case RPMTAG_ENHANCESNAME: + versiontag = RPMTAG_ENHANCESVERSION; + flagtag = RPMTAG_ENHANCESFLAGS; + extra = Flags & _ALL_REQUIRES_MASK; + break; case RPMTAG_REQUIRENAME: default: tagN = RPMTAG_REQUIRENAME; --- build/rpmfc.c +++ build/rpmfc.c @@ -1084,6 +1084,12 @@ { "Obsoletes", { "%{?__find_obsoletes}", NULL, NULL, NULL }, RPMTAG_OBSOLETENAME, RPMTAG_OBSOLETEVERSION, RPMTAG_OBSOLETEFLAGS, 0, -1 }, + { "Enhances", { "%{?__find_enhances}", NULL, NULL, NULL }, + RPMTAG_ENHANCESNAME, RPMTAG_ENHANCESVERSION, RPMTAG_ENHANCESFLAGS, + RPMSENSE_STRONG, RPMSENSE_STRONG }, + { "Supplements", { "%{?__find_supplements}", NULL, NULL, NULL }, + RPMTAG_ENHANCESNAME, RPMTAG_ENHANCESVERSION, RPMTAG_ENHANCESFLAGS, + RPMSENSE_STRONG, 0 }, { NULL, { NULL, NULL, NULL, NULL }, 0, 0, 0, 0, 0 } }; @@ -1160,6 +1166,14 @@ continue; tagflags = RPMSENSE_FIND_REQUIRES; break; + case RPMTAG_ENHANCESFLAGS: + if (!pkg->autoProv) + continue; + failnonzero = 0; + tagflags = RPMSENSE_FIND_REQUIRES | RPMSENSE_MISSINGOK; + if (strcmp(dm->msg, "Supplements") == 0) + tagflags |= RPMSENSE_STRONG; + break; default: continue; break; --- lib/formats.c +++ lib/formats.c @@ -486,6 +486,19 @@ return val; } +static char * depflag_strongFormat(rpmtd td) +{ + char * val = NULL; + + if (rpmtdClass(td) != RPM_NUMERIC_CLASS) { + val = xstrdup(_("(not a number)")); + } else { + uint64_t anint = rpmtdGetNumber(td); + val = xstrdup(anint & RPMSENSE_STRONG ? "strong" : ""); + } + return val; +} + /** * Return tag container array size. * @param td tag data container @@ -591,6 +604,7 @@ { RPMTD_FORMAT_VFLAGS, "vflags", vflagsFormat }, { RPMTD_FORMAT_EXPAND, "expand", expandFormat }, { RPMTD_FORMAT_FSTATUS, "fstatus", fstatusFormat }, + { RPMTD_FORMAT_DEPFLAG_STRONG, "depflag_strong", depflag_strongFormat }, { -1, NULL, NULL } }; --- lib/rpmds.c +++ lib/rpmds.c @@ -69,6 +69,10 @@ t = "Trigger"; evr = RPMTAG_TRIGGERVERSION; f = RPMTAG_TRIGGERFLAGS; + } else if (tag == RPMTAG_ENHANCESNAME) { + t = "Enhances"; + evr = RPMTAG_ENHANCESVERSION; + f = RPMTAG_ENHANCESFLAGS; } else { rc = 1; } --- lib/rpmds.h +++ lib/rpmds.h @@ -48,7 +48,7 @@ RPMSENSE_RPMLIB = (1 << 24), /*!< rpmlib(feature) dependency. */ RPMSENSE_TRIGGERPREIN = (1 << 25), /*!< %triggerprein dependency. */ RPMSENSE_KEYRING = (1 << 26), - /* bit 27 unused */ + RPMSENSE_STRONG = (1 << 27), RPMSENSE_CONFIG = (1 << 28) }; @@ -70,6 +70,7 @@ RPMSENSE_FIND_REQUIRES | \ RPMSENSE_RPMLIB | \ RPMSENSE_KEYRING | \ + RPMSENSE_STRONG | \ RPMSENSE_PRETRANS | \ RPMSENSE_POSTTRANS | \ RPMSENSE_PREREQ | \ --- lib/rpmtag.h +++ lib/rpmtag.h @@ -217,14 +217,14 @@ RPMTAG_PRETRANSPROG = 1153, /* s[] */ RPMTAG_POSTTRANSPROG = 1154, /* s[] */ RPMTAG_DISTTAG = 1155, /* s */ - RPMTAG_SUGGESTSNAME = 1156, /* s[] extension (unimplemented) */ -#define RPMTAG_SUGGESTS RPMTAG_SUGGESTSNAME /* s[] (unimplemented) */ - RPMTAG_SUGGESTSVERSION = 1157, /* s[] extension (unimplemented) */ - RPMTAG_SUGGESTSFLAGS = 1158, /* i[] extension (unimplemented) */ - RPMTAG_ENHANCESNAME = 1159, /* s[] extension placeholder (unimplemented) */ -#define RPMTAG_ENHANCES RPMTAG_ENHANCESNAME /* s[] (unimplemented) */ - RPMTAG_ENHANCESVERSION = 1160, /* s[] extension placeholder (unimplemented) */ - RPMTAG_ENHANCESFLAGS = 1161, /* i[] extension placeholder (unimplemented) */ + RPMTAG_SUGGESTSNAME = 1156, /* s[] extension */ +#define RPMTAG_SUGGESTS RPMTAG_SUGGESTSNAME /* s[] */ + RPMTAG_SUGGESTSVERSION = 1157, /* s[] extension */ + RPMTAG_SUGGESTSFLAGS = 1158, /* i[] extension */ + RPMTAG_ENHANCESNAME = 1159, /* s[] extension */ +#define RPMTAG_ENHANCES RPMTAG_ENHANCESNAME /* s[] */ + RPMTAG_ENHANCESVERSION = 1160, /* s[] extension */ + RPMTAG_ENHANCESFLAGS = 1161, /* i[] extension */ RPMTAG_PRIORITY = 1162, /* i[] extension placeholder (unimplemented) */ RPMTAG_CVSID = 1163, /* s (unimplemented) */ #define RPMTAG_SVNID RPMTAG_CVSID /* s (unimplemented) */ --- lib/rpmtd.h +++ lib/rpmtd.h @@ -228,6 +228,7 @@ RPMTD_FORMAT_VFLAGS = 17, /* file verify flags (int types) */ RPMTD_FORMAT_EXPAND = 18, /* macro expansion (string types) */ RPMTD_FORMAT_FSTATUS = 19, /* file verify status (int types) */ + RPMTD_FORMAT_DEPFLAG_STRONG = 20, /* strong dependency (int types) */ } rpmtdFormats; /** \ingroup rpmtd --- python/rpmmodule.c +++ python/rpmmodule.c @@ -395,6 +395,7 @@ REGISTER_ENUM(RPMSENSE_RPMLIB); REGISTER_ENUM(RPMSENSE_TRIGGERPREIN); REGISTER_ENUM(RPMSENSE_KEYRING); + REGISTER_ENUM(RPMSENSE_STRONG); REGISTER_ENUM(RPMSENSE_CONFIG); REGISTER_ENUM(RPMTRANS_FLAG_TEST); --- rpmpopt.in +++ rpmpopt.in @@ -67,6 +67,22 @@ --POPTdesc=$"list capabilities required by package(s)" rpm alias -R --requires +rpm alias --suggests --qf \ + "[%|SUGGESTSFLAGS:depflag_strong?{}:{%{SUGGESTSNAME} %{SUGGESTSFLAGS:depflags} %{SUGGESTSVERSION}\n}|]" \ + --POPTdesc=$"list capabilities this package suggests" + +rpm alias --recommends --qf \ + "[%|SUGGESTSFLAGS:depflag_strong?{%{SUGGESTSNAME} %{SUGGESTSFLAGS:depflags} %{SUGGESTSVERSION}\n}|]" \ + --POPTdesc=$"list capabilities this package recommends" + +rpm alias --enhances --qf \ + "[%|ENHANCESFLAGS:depflag_strong?{}:{%{ENHANCESNAME} %{ENHANCESFLAGS:depflags} %{ENHANCESVERSION}\n}|]" \ + --POPTdesc=$"list capabilities this package enhances" + +rpm alias --supplements --qf \ + "[%|ENHANCESFLAGS:depflag_strong?{%{ENHANCESNAME} %{ENHANCESFLAGS:depflags} %{ENHANCESVERSION}\n}|]" \ + --POPTdesc=$"list capabilities this package supplements" + rpm alias --info --qf '\ Name : %{NAME}\n\ %|EPOCH?{Epoch : %{EPOCH}\n}|\ --- tests/rpmgeneral.at +++ tests/rpmgeneral.at @@ -79,6 +79,10 @@ DISTURL DSAHEADER E +ENHANCES +ENHANCESFLAGS +ENHANCESNAME +ENHANCESVERSION EPOCH EPOCHNUM EVR @@ -219,6 +223,10 @@ SOURCEPACKAGE SOURCEPKGID SOURCERPM +SUGGESTS +SUGGESTSFLAGS +SUGGESTSNAME +SUGGESTSVERSION SUMMARY TRIGGERCONDS TRIGGERFLAGS