Teach rpm about pre-transaction dependencies
authorPanu Matilainen <pmatilai@redhat.com>
Mon, 29 Mar 2010 05:58:27 +0000 (08:58 +0300)
committerPanu Matilainen <pmatilai@redhat.com>
Mon, 29 Mar 2010 05:58:27 +0000 (08:58 +0300)
- A pre-transaction dependency is generally anything that must be
  available at the start of the transaction, and cannot be resolved
  by packages *in* the transaction. This lets %pretrans scriptlet
  dependencies be expressed correctly, and could be also used for
  other kinds of pre-conditions.
- rpmlib() dependencies are a special case of pre-trans dependencies
  but leaving them handled separately as they cannot be provided by
  anything in rpmdb either, whereas pretrans dependencies can.

build/parsePreamble.c
build/parseScript.c
lib/depends.c
lib/formats.c
lib/order.c
lib/rpmds.h

index 7d5e9ca..eb6385a 100644 (file)
@@ -126,6 +126,7 @@ static struct tokenBits_s const installScriptBits[] = {
     { "post",          RPMSENSE_SCRIPT_POST },
     { "rpmlib",                RPMSENSE_RPMLIB },
     { "verify",                RPMSENSE_SCRIPT_VERIFY },
+    { "pretrans",      RPMSENSE_PRETRANS },
     { NULL, 0 }
 };
 
index 492df0e..0948ba9 100644 (file)
@@ -131,7 +131,7 @@ int parseScript(rpmSpec spec, int parsePart)
        break;
       case PART_PRETRANS:
        tag = RPMTAG_PRETRANS;
-       tagflags = 0;
+       tagflags = RPMSENSE_PRETRANS;
        progtag = RPMTAG_PRETRANSPROG;
        flagtag = RPMTAG_PRETRANSFLAGS;
        partname = "%pretrans";
index ec02a7b..37bc0df 100644 (file)
@@ -364,6 +364,7 @@ static int unsatisfiedDepend(rpmts ts, depCache dcache, rpmds dep)
     int *cachedrc = NULL;
     int cacheThis = 0;
     int adding = (rpmdsInstance(dep) == 0);
+    rpmsenseFlags dsflags = rpmdsFlags(dep);
 
 retry:
     rc = 0;    /* assume dependency is satisfied */
@@ -373,7 +374,7 @@ retry:
      * on rpmlib provides. The dependencies look like "rpmlib(YaddaYadda)".
      * Check those dependencies now.
      */
-    if (rpmdsFlags(dep) & RPMSENSE_RPMLIB) {
+    if (dsflags & RPMSENSE_RPMLIB) {
        static int oneshot = -1;
        if (oneshot) 
            oneshot = rpmdsRpmlib(&rpmlibP, NULL);
@@ -385,8 +386,9 @@ retry:
        goto unsatisfied;
     }
 
-    /* Search added packages for the dependency. */
-    if (rpmalSatisfiesDepend(tsmem->addedPackages, dep) != NULL) {
+    /* Pretrans dependencies can't be satisfied by added packages. */
+    if (!(dsflags & RPMSENSE_PRETRANS) &&
+               rpmalSatisfiesDepend(tsmem->addedPackages, dep) != NULL) {
        goto exit;
     }
 
@@ -423,7 +425,8 @@ retry:
     /*
      * Search for an unsatisfied dependency.
      */
-    if (adding && !retrying && !(rpmtsFlags(ts) & RPMTRANS_FLAG_NOSUGGEST)) {
+    if (adding && !retrying && !(dsflags & RPMSENSE_PRETRANS) &&
+               !(rpmtsFlags(ts) & RPMTRANS_FLAG_NOSUGGEST)) {
        xx = rpmtsSolve(ts, dep);
        if (xx == 0)
            goto exit;
index c13f46d..0700955 100644 (file)
@@ -254,6 +254,8 @@ static char * deptypeFormat(rpmtd td, char * formatPrefix)
            argvAdd(&sdeps, "auto");
        if (item & RPMSENSE_PREREQ)
            argvAdd(&sdeps, "prereq");
+       if (item & RPMSENSE_PRETRANS)
+           argvAdd(&sdeps, "pretrans");
 
        if (sdeps) {
            val = argvJoin(sdeps, ",");
index f82ca6a..e0b6924 100644 (file)
@@ -165,8 +165,8 @@ static inline int addRelation(rpmts ts,
 
     dsflags = rpmdsFlags(requires);
 
-    /* Avoid rpmlib feature and package config dependencies */
-    if (dsflags & (RPMSENSE_RPMLIB|RPMSENSE_CONFIG))
+    /* Avoid dependendencies which are not relevant for ordering */
+    if (dsflags & (RPMSENSE_RPMLIB|RPMSENSE_CONFIG|RPMSENSE_PRETRANS))
        return 0;
 
     q = rpmalSatisfiesDepend(al, requires);
index 03ebf79..e71b866 100644 (file)
@@ -28,8 +28,8 @@ typedef       enum rpmsenseFlags_e {
     RPMSENSE_GREATER   = (1 << 2),
     RPMSENSE_EQUAL     = (1 << 3),
     /* bits 4-5 unused */
-    RPMSENSE_PREREQ    = (1 << 6), /* legacy prereq dependency */
-    /* bit 7 unused */
+    RPMSENSE_PREREQ    = (1 << 6),     /* legacy prereq dependency */
+    RPMSENSE_PRETRANS  = (1 << 7),     /*!< Pre-transaction dependency. */
     RPMSENSE_INTERP    = (1 << 8),     /*!< Interpreter used by scriptlet. */
     RPMSENSE_SCRIPT_PRE        = (1 << 9),     /*!< %pre dependency. */
     RPMSENSE_SCRIPT_POST = (1 << 10),  /*!< %post dependency. */
@@ -67,11 +67,12 @@ typedef     enum rpmsenseFlags_e {
     RPMSENSE_FIND_REQUIRES | \
     RPMSENSE_RPMLIB | \
     RPMSENSE_KEYRING | \
+    RPMSENSE_PRETRANS | \
     RPMSENSE_PREREQ)
 
 #define        _notpre(_x)             ((_x) & ~RPMSENSE_PREREQ)
 #define        _INSTALL_ONLY_MASK \
-    _notpre(RPMSENSE_SCRIPT_PRE|RPMSENSE_SCRIPT_POST|RPMSENSE_RPMLIB|RPMSENSE_KEYRING)
+    _notpre(RPMSENSE_SCRIPT_PRE|RPMSENSE_SCRIPT_POST|RPMSENSE_RPMLIB|RPMSENSE_KEYRING|RPMSENSE_PRETRANS)
 #define        _ERASE_ONLY_MASK  \
     _notpre(RPMSENSE_SCRIPT_PREUN|RPMSENSE_SCRIPT_POSTUN)