summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPanu Matilainen <pmatilai@redhat.com>2010-12-13 12:03:18 +0200
committerPanu Matilainen <pmatilai@redhat.com>2010-12-13 12:26:06 +0200
commit5c43095e1d78b3befe93c746fd182746c3b96c92 (patch)
treec57347a08501be44320ce49c36a774ff6c647b8b
parent185de185262b2772fa692efc69633f41afc5832a (diff)
downloadlibrpm-tizen-5c43095e1d78b3befe93c746fd182746c3b96c92.tar.gz
librpm-tizen-5c43095e1d78b3befe93c746fd182746c3b96c92.tar.bz2
librpm-tizen-5c43095e1d78b3befe93c746fd182746c3b96c92.zip
Implement transaction ordering hinting
- Add support for new "OrderWithRequires: foo" spec syntax which has "if and only if foo is present in transaction, order the transaction as if this package required foo" semantics. While it looks, and in some ways is, a soft dependency, this is not the same as recommends/suggests etc: those have unknown depsolver policy dependent semantics attached to them, whereas ordering hints have a clear definition and is only relevant for rpm itself, depsolvers should not even look at the data. - This allows packages to express correct ordering for optional functionality, such as %post if [ -x %{_bindir}/register-component ]; then %{_bindir}/register-component %{name} fi If the package containing %{_bindir}/register-component is included in the same transaction, it makes sense to have it installed before the package(s) that use it. But as it is fully optional, Requires would not be appropriate. Using OrderWithRequires allows this to be expressed without dragging in extraneous dependencies for optional functionality.
-rw-r--r--build/parsePreamble.c2
-rw-r--r--build/parseReqs.c3
-rw-r--r--build/reqprov.c4
-rw-r--r--lib/order.c6
-rw-r--r--lib/rpmds.c4
-rw-r--r--lib/rpmtag.h3
-rw-r--r--lib/rpmte.c4
-rw-r--r--tests/rpmgeneral.at3
8 files changed, 29 insertions, 0 deletions
diff --git a/build/parsePreamble.c b/build/parsePreamble.c
index 053e3ed41..3d8b859d8 100644
--- a/build/parsePreamble.c
+++ b/build/parsePreamble.c
@@ -768,6 +768,7 @@ static int handlePreambleTag(rpmSpec spec, Package pkg, rpmTagVal tag,
if ((rc = parseNoSource(spec, field, tag)))
return rc;
break;
+ case RPMTAG_ORDERFLAGS:
case RPMTAG_REQUIREFLAGS:
case RPMTAG_PREREQ:
if ((rc = parseBits(lang, installScriptBits, &tagflags))) {
@@ -892,6 +893,7 @@ static struct PreambleRec_s const preambleList[] = {
{RPMTAG_DISTTAG, 0, 0, LEN_AND_STR("disttag")},
{RPMTAG_BUGURL, 0, 0, LEN_AND_STR("bugurl")},
{RPMTAG_COLLECTIONS, 0, 0, LEN_AND_STR("collections")},
+ {RPMTAG_ORDERFLAGS, 2, 0, LEN_AND_STR("orderwithrequires")},
{0, 0, 0, 0}
};
diff --git a/build/parseReqs.c b/build/parseReqs.c
index 12bcd4721..de2680cca 100644
--- a/build/parseReqs.c
+++ b/build/parseReqs.c
@@ -61,6 +61,9 @@ rpmRC parseRCPOT(rpmSpec spec, Package pkg, const char *field, rpmTagVal tagN,
case RPMTAG_CONFLICTFLAGS:
nametag = RPMTAG_CONFLICTNAME;
break;
+ case RPMTAG_ORDERFLAGS:
+ nametag = RPMTAG_ORDERNAME;
+ break;
case RPMTAG_PREREQ:
/* XXX map legacy PreReq into Requires(pre,preun) */
nametag = RPMTAG_REQUIRENAME;
diff --git a/build/reqprov.c b/build/reqprov.c
index 91c3861c3..f2cdb5cd4 100644
--- a/build/reqprov.c
+++ b/build/reqprov.c
@@ -65,6 +65,10 @@ int addReqProv(Header h, rpmTagVal tagN,
versiontag = RPMTAG_CONFLICTVERSION;
flagtag = RPMTAG_CONFLICTFLAGS;
break;
+ case RPMTAG_ORDERNAME:
+ versiontag = RPMTAG_ORDERVERSION;
+ flagtag = RPMTAG_ORDERFLAGS;
+ break;
case RPMTAG_TRIGGERNAME:
versiontag = RPMTAG_TRIGGERVERSION;
flagtag = RPMTAG_TRIGGERFLAGS;
diff --git a/lib/order.c b/lib/order.c
index e794725aa..d7a91e7cb 100644
--- a/lib/order.c
+++ b/lib/order.c
@@ -647,12 +647,18 @@ int rpmtsOrder(rpmts ts)
rpmal al = (rpmteType(p) == TR_REMOVED) ?
erasedPackages : tsmem->addedPackages;
rpmds requires = rpmdsInit(rpmteDS(p, RPMTAG_REQUIRENAME));
+ rpmds order = rpmdsInit(rpmteDS(p, RPMTAG_ORDERNAME));
while (rpmdsNext(requires) >= 0) {
/* Record next "q <- p" relation (i.e. "p" requires "q"). */
(void) addRelation(ts, al, p, requires);
}
+ while (rpmdsNext(order) >= 0) {
+ /* Record next "q <- p" ordering request */
+ (void) addRelation(ts, al, p, order);
+ }
+
addCollRelations(al, p, &seenColls);
}
diff --git a/lib/rpmds.c b/lib/rpmds.c
index b86b5da9f..9b112dceb 100644
--- a/lib/rpmds.c
+++ b/lib/rpmds.c
@@ -61,6 +61,10 @@ static int dsType(rpmTagVal tag,
t = "Obsoletes";
evr = RPMTAG_OBSOLETEVERSION;
f = RPMTAG_OBSOLETEFLAGS;
+ } else if (tag == RPMTAG_ORDERNAME) {
+ t = "Order";
+ evr = RPMTAG_ORDERVERSION;
+ f = RPMTAG_ORDERFLAGS;
} else if (tag == RPMTAG_TRIGGERNAME) {
t = "Trigger";
evr = RPMTAG_TRIGGERVERSION;
diff --git a/lib/rpmtag.h b/lib/rpmtag.h
index 17810114a..50939c63c 100644
--- a/lib/rpmtag.h
+++ b/lib/rpmtag.h
@@ -296,6 +296,9 @@ typedef enum rpmTag_e {
RPMTAG_POLICYTYPESINDEXES = 5032, /* i[] */
RPMTAG_POLICYFLAGS = 5033, /* i[] */
RPMTAG_VCS = 5034, /* s */
+ RPMTAG_ORDERNAME = 5035, /* s[] */
+ RPMTAG_ORDERVERSION = 5036, /* s[] */
+ RPMTAG_ORDERFLAGS = 5037, /* i[] */
RPMTAG_FIRSTFREE_TAG /*!< internal */
} rpmTag;
diff --git a/lib/rpmte.c b/lib/rpmte.c
index 7d2dc080f..c36e8cbb7 100644
--- a/lib/rpmte.c
+++ b/lib/rpmte.c
@@ -45,6 +45,7 @@ struct rpmte_s {
rpmds requires; /*!< Requires: dependencies. */
rpmds conflicts; /*!< Conflicts: dependencies. */
rpmds obsoletes; /*!< Obsoletes: dependencies. */
+ rpmds order; /*!< Order: dependencies. */
rpmfi fi; /*!< File information. */
rpmps probs; /*!< Problems (relocations) */
rpmts ts; /*!< Parent transaction */
@@ -82,6 +83,7 @@ void rpmteCleanDS(rpmte te)
te->requires = rpmdsFree(te->requires);
te->conflicts = rpmdsFree(te->conflicts);
te->obsoletes = rpmdsFree(te->obsoletes);
+ te->order = rpmdsFree(te->order);
}
static rpmfi getFI(rpmte p, Header h)
@@ -232,6 +234,7 @@ static void addTE(rpmte p, Header h, fnpyKey key, rpmRelocation * relocs)
p->requires = rpmdsNew(h, RPMTAG_REQUIRENAME, 0);
p->conflicts = rpmdsNew(h, RPMTAG_CONFLICTNAME, 0);
p->obsoletes = rpmdsNew(h, RPMTAG_OBSOLETENAME, 0);
+ p->order = rpmdsNew(h, RPMTAG_ORDERNAME, 0);
p->fs = rpmfsNew(h, p->type);
p->fi = getFI(p, h);
@@ -532,6 +535,7 @@ rpmds rpmteDS(rpmte te, rpmTagVal tag)
case RPMTAG_REQUIRENAME: return te->requires;
case RPMTAG_CONFLICTNAME: return te->conflicts;
case RPMTAG_OBSOLETENAME: return te->obsoletes;
+ case RPMTAG_ORDERNAME: return te->order;
default: break;
}
return NULL;
diff --git a/tests/rpmgeneral.at b/tests/rpmgeneral.at
index 9c64bb464..cd901180a 100644
--- a/tests/rpmgeneral.at
+++ b/tests/rpmgeneral.at
@@ -163,6 +163,9 @@ OBSOLETES
OBSOLETEVERSION
OLDFILENAMES
OPTFLAGS
+ORDERFLAGS
+ORDERNAME
+ORDERVERSION
ORIGBASENAMES
ORIGDIRINDEXES
ORIGDIRNAMES