Add support for weak dependencies:
authorAnas Nashif <anas.nashif@intel.com>
Thu, 11 Oct 2012 19:40:31 +0000 (12:40 -0700)
committerAnas Nashif <anas.nashif@intel.com>
Sun, 3 Feb 2013 00:44:15 +0000 (16:44 -0800)
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".

12 files changed:
build/parsePreamble.c
build/parseReqs.c
build/reqprov.c
build/rpmfc.c
lib/formats.c
lib/rpmds.c
lib/rpmds.h
lib/rpmtag.h
lib/rpmtd.h
python/rpmmodule.c
rpmpopt.in
tests/rpmgeneral.at

index 16848ec..78891db 100644 (file)
@@ -341,6 +341,8 @@ static struct tokenBits_s const installScriptBits[] = {
     { "verify",                RPMSENSE_SCRIPT_VERIFY },
     { "pretrans",      RPMSENSE_PRETRANS },
     { "posttrans",     RPMSENSE_POSTTRANS },
+    { "hint",          RPMSENSE_MISSINGOK },
+    { "strong",        RPMSENSE_STRONG },
     { NULL, 0 }
 };
 
@@ -789,6 +791,18 @@ static rpmRC handlePreambleTag(rpmSpec spec, Package pkg, rpmTagVal tag,
        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:
@@ -897,6 +911,14 @@ static struct PreambleRec_s const preambleList[] = {
     {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}
 };
 
index 5ad0501..1507090 100644 (file)
@@ -95,6 +95,20 @@ rpmRC parseRCPOT(rpmSpec spec, Package pkg, const char *field, rpmTagVal tagN,
        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) {
index f2cdb5c..bc2f7ea 100644 (file)
@@ -75,6 +75,16 @@ int addReqProv(Header h, rpmTagVal tagN,
        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;
index 990abab..261a09e 100644 (file)
@@ -1081,6 +1081,12 @@ static struct DepMsg_s depMsgs[] = {
   { "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 }
 };
 
@@ -1157,6 +1163,14 @@ static rpmRC rpmfcGenerateDependsHelper(const rpmSpec spec, Package pkg, rpmfi f
                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;
index 653f43d..23f4027 100644 (file)
@@ -486,6 +486,19 @@ static char * depflagsFormat(rpmtd td)
     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 @@ static const struct headerFormatFunc_s rpmHeaderFormats[] = {
     { 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 }
 };
 
index 04dc758..1e67986 100644 (file)
@@ -70,6 +70,10 @@ static int dsType(rpmTagVal tag,
        t = "Trigger";
        evr = RPMTAG_TRIGGERVERSION;
        f = RPMTAG_TRIGGERFLAGS;
+    } else if (tag == RPMTAG_ENHANCESNAME) {
+       t = "Enhances";
+       evr = RPMTAG_ENHANCESVERSION;
+       f = RPMTAG_ENHANCESFLAGS;
     } else {
        rc = 1;
     } 
index 811ff86..bceed00 100644 (file)
@@ -48,7 +48,7 @@ enum rpmsenseFlags_e {
     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)
 };
 
@@ -73,7 +73,8 @@ typedef rpmFlags rpmsenseFlags;
     RPMSENSE_PRETRANS | \
     RPMSENSE_POSTTRANS | \
     RPMSENSE_PREREQ | \
-    RPMSENSE_MISSINGOK)
+    RPMSENSE_MISSINGOK | \
+    RPMSENSE_STRONG)
 
 #define        _notpre(_x)             ((_x) & ~RPMSENSE_PREREQ)
 #define        _INSTALL_ONLY_MASK \
index e8e9dee..1295a71 100644 (file)
@@ -217,14 +217,14 @@ typedef enum rpmTag_e {
     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) */
index a8f0b71..de71011 100644 (file)
@@ -228,6 +228,7 @@ typedef enum rpmtdFormats_e {
     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
index 27430ee..a4fe217 100644 (file)
@@ -393,6 +393,7 @@ static int initModule(PyObject *m)
     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);
index 805599e..cd6f6c7 100644 (file)
@@ -67,6 +67,22 @@ rpm  alias --requires        --qf \
        --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}|\
index 13131e2..eb0d86d 100644 (file)
@@ -79,6 +79,10 @@ DISTTAG
 DISTURL
 DSAHEADER
 E
+ENHANCES
+ENHANCESFLAGS
+ENHANCESNAME
+ENHANCESVERSION
 EPOCH
 EPOCHNUM
 EVR
@@ -219,6 +223,10 @@ SOURCE
 SOURCEPACKAGE
 SOURCEPKGID
 SOURCERPM
+SUGGESTS
+SUGGESTSFLAGS
+SUGGESTSNAME
+SUGGESTSVERSION
 SUMMARY
 TRIGGERCONDS
 TRIGGERFLAGS