summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFlorian Festi <ffesti@redhat.com>2016-09-09 14:00:58 +0200
committerIgor Gnatenko <i.gnatenko.brain@gmail.com>2016-09-09 15:31:45 +0200
commitbcda7bd03716df216b037d717a37d7647cb3634a (patch)
tree1cae6ba90763752fbbb005e655bad8e857071031
parent932f14fdf8dc0ef0a911e5af7eae4ecddfa759c4 (diff)
downloadrpm-bcda7bd03716df216b037d717a37d7647cb3634a.tar.gz
Add support for sorting caret higher than other separators in version/release
- This allows much nicer handling some scenarios where out of line versions are alphabetically smaller than previous verion numbers. - Add a rpmlib() tracking dependency to prevent older rpm versions from getting confused with packages relying on the new behavior. Signed-off-by: Florian Festi <ffesti@redhat.com> Signed-off-by: Igor Gnatenko <i.gnatenko.brain@gmail.com>
-rw-r--r--build/pack.c10
-rw-r--r--build/parsePreamble.c2
-rw-r--r--build/parseReqs.c2
-rw-r--r--lib/rpmds.c3
-rw-r--r--lib/rpmvercmp.c9
-rw-r--r--tests/rpmvercmp.at12
6 files changed, 33 insertions, 5 deletions
diff --git a/build/pack.c b/build/pack.c
index 82c12624e..80a1c90d7 100644
--- a/build/pack.c
+++ b/build/pack.c
@@ -280,12 +280,12 @@ exit:
return rc;
}
-static int haveTildeDep(Package pkg)
+static int haveCharInDep(Package pkg, char c)
{
for (int i = 0; i < PACKAGE_NUM_DEPS; i++) {
rpmds ds = rpmdsInit(pkg->dependencies[i]);
while (rpmdsNext(ds) >= 0) {
- if (strchr(rpmdsEVR(ds), '~'))
+ if (strchr(rpmdsEVR(ds), c))
return 1;
}
}
@@ -392,9 +392,13 @@ static rpmRC writeRPM(Package pkg, unsigned char ** pkgidp,
}
/* check if the package has a dependency with a '~' */
- if (haveTildeDep(pkg))
+ if (haveCharInDep(pkg, '~'))
(void) rpmlibNeedsFeature(pkg, "TildeInVersions", "4.10.0-1");
+ /* check if the package has a dependency with a '^' */
+ if (haveCharInDep(pkg, '^'))
+ (void) rpmlibNeedsFeature(pkg, "CaretInVersions", "4.14.0-1");
+
/* check if the package has a rich dependency */
if (haveRichDep(pkg))
(void) rpmlibNeedsFeature(pkg, "RichDependencies", "4.12.0-1");
diff --git a/build/parsePreamble.c b/build/parsePreamble.c
index 0d8d06609..629d67574 100644
--- a/build/parsePreamble.c
+++ b/build/parsePreamble.c
@@ -749,7 +749,7 @@ static rpmRC handlePreambleTag(rpmSpec spec, Package pkg, rpmTagVal tag,
case RPMTAG_VERSION:
case RPMTAG_RELEASE:
SINGLE_TOKEN_ONLY;
- if (rpmCharCheck(spec, field, "._+%{}~"))
+ if (rpmCharCheck(spec, field, "._+%{}~^"))
goto exit;
headerPutString(pkg->header, tag, field);
break;
diff --git a/build/parseReqs.c b/build/parseReqs.c
index a443505e4..92a6f6e6d 100644
--- a/build/parseReqs.c
+++ b/build/parseReqs.c
@@ -57,7 +57,7 @@ static rpmRC checkDep(rpmSpec spec, char *N, char *EVR, char **emsg)
rasprintf(emsg, _("Versioned file name not permitted"));
return RPMRC_FAIL;
}
- if (rpmCharCheck(spec, EVR, ".-_+:%{}~"))
+ if (rpmCharCheck(spec, EVR, ".-_+:%{}~^"))
return RPMRC_FAIL;
if (checkSep(EVR, '-', emsg) != RPMRC_OK ||
checkSep(EVR, ':', emsg) != RPMRC_OK ||
diff --git a/lib/rpmds.c b/lib/rpmds.c
index 04be01266..985ab14b7 100644
--- a/lib/rpmds.c
+++ b/lib/rpmds.c
@@ -1278,6 +1278,9 @@ static const struct rpmlibProvides_s rpmlibProvides[] = {
{ "rpmlib(RichDependencies)", "4.12.0-1",
( RPMSENSE_EQUAL),
N_("support for rich dependencies.") },
+ { "rpmlib(CaretInVersions)", "4.14.0-1",
+ ( RPMSENSE_EQUAL),
+ N_("dependency comparison supports versions with caret.") },
{ NULL, NULL, 0, NULL }
};
diff --git a/lib/rpmvercmp.c b/lib/rpmvercmp.c
index b3d08faa4..115edac2d 100644
--- a/lib/rpmvercmp.c
+++ b/lib/rpmvercmp.c
@@ -45,6 +45,15 @@ int rpmvercmp(const char * a, const char * b)
continue;
}
+ /* handle the caret separator, it sorts before everything else */
+ if (*one == '^' || *two == '^') {
+ if (*one != '^') return -1;
+ if (*two != '^') return 1;
+ one++;
+ two++;
+ continue;
+ }
+
/* If we ran to the end of either, we are finished with the loop */
if (!(*one && *two)) break;
diff --git a/tests/rpmvercmp.at b/tests/rpmvercmp.at
index 2a25bdd9b..bebab3ee1 100644
--- a/tests/rpmvercmp.at
+++ b/tests/rpmvercmp.at
@@ -100,6 +100,18 @@ RPMVERCMP(1.0~rc1~git123, 1.0~rc1~git123, 0)
RPMVERCMP(1.0~rc1~git123, 1.0~rc1, -1)
RPMVERCMP(1.0~rc1, 1.0~rc1~git123, 1)
+dnl Basic testcases for caret sorting
+RPMVERCMP(1.0^git1, 1.0^git1, 0)
+RPMVERCMP(1.0^git1, 1.0, 1)
+RPMVERCMP(1.0^git1, 1.1, -1)
+RPMVERCMP(1.0, 1.0^git1, -1)
+RPMVERCMP(1.1, 1.0^git1, 1)
+RPMVERCMP(1.0^git1, 1.0^git2, -1)
+RPMVERCMP(1.0^git2, 1.0^git1, 1)
+RPMVERCMP(1.0^post^git1, 1.0^post^git1, 0)
+RPMVERCMP(1.0^post^git1, 1.0^post, 1)
+RPMVERCMP(1.0^post, 1.0^post^git1, -1)
+
dnl These are included here to document current, arguably buggy behaviors
dnl for reference purposes and for easy checking against unintended
dnl behavior changes.