Backport: Add support for dpkg-style sorting of tilde in version/release
Original commit message: - This allows much nicer handling some common scenarios such as upstream pre-releases where the pre-release version would normally appear newer than final release, eg 1.0-rc1 vs 1.0. Previously this required mapping the pre-release tag into the release tag to achieve desired sorting, with tilde this becomes simply 1.0~rc1 < 1.0. - Add a rpmlib() tracking dependency to prevent older rpm versions from getting confused with packages relying on the new behavior. Picked: db28221a4a ("Add support for dpkg-style sorting of tilde in version/release") Authored-by: Michael Schroeder <mls@suse.de> Signed-off-by: Panu Matilainen <pmatilai@redhat.com> Picked: 8002b3f985 ("Spelling fixes.") Authored-by: Ville Skyttä <ville.skytta@iki.fi> Signed-off-by: Panu Matilainen <pmatilai@redhat.com> Link: https://bugzilla.altlinux.org/46585 [ vt: Change to parseRCPOT is not applied because no rpmCharCheck call. Unsupported RPM tags (ORDERVERSION, SUGGESTSVERSION, ENHANCESVERSION) are removed. haveTildeDep is reworked because we don't have headerGet API. ] Signed-off-by: Vitaly Chikunov <vt@altlinux.org>
This commit is contained in:
parent
2d55bbb3bf
commit
785ae7a9a2
38
build/pack.c
38
build/pack.c
@ -479,6 +479,40 @@ static void downgradeLzmaLevel(char *mode, uint64_t archiveSize)
|
||||
#undef T
|
||||
}
|
||||
|
||||
static int haveTildeDep(Header h)
|
||||
{
|
||||
HeaderIterator hi;
|
||||
int_32 tag, type, count;
|
||||
const void *ptr;
|
||||
int ret = 0;
|
||||
|
||||
for (hi = headerInitIterator(h);
|
||||
headerNextIterator(hi, &tag, &type, &ptr, &count);
|
||||
ptr = headerFreeData(ptr, type))
|
||||
{
|
||||
switch (tag) {
|
||||
case RPMTAG_PROVIDEVERSION:
|
||||
case RPMTAG_REQUIREVERSION:
|
||||
case RPMTAG_OBSOLETEVERSION:
|
||||
case RPMTAG_CONFLICTVERSION:
|
||||
case RPMTAG_TRIGGERVERSION:
|
||||
break;
|
||||
default:
|
||||
continue;
|
||||
}
|
||||
if (type != RPM_STRING_ARRAY_TYPE)
|
||||
continue;
|
||||
while (count--) {
|
||||
const char *p = ((const char **)ptr)[count];
|
||||
|
||||
if (strchr(p, '~'))
|
||||
ret = 1;
|
||||
}
|
||||
}
|
||||
hi = headerFreeIterator(hi);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int writeRPM(Header *hdrp, const char *fileName, int type,
|
||||
CSA_t csa, char *passPhrase, const char **cookie)
|
||||
{
|
||||
@ -569,6 +603,10 @@ int writeRPM(Header *hdrp, const char *fileName, int type,
|
||||
(void) headerAddEntry(h, RPMTAG_PAYLOADFLAGS, RPM_STRING_TYPE, buf+1, 1);
|
||||
}
|
||||
|
||||
/* check if the package has a dependency with a '~' */
|
||||
if (haveTildeDep(h))
|
||||
(void) rpmlibNeedsFeature(h, "TildeInVersions", "4.10.0-1");
|
||||
|
||||
/* Create and add the cookie */
|
||||
if (cookie) {
|
||||
if (!headerGetEntry(h, RPMTAG_BUILDHOST, NULL, (void **)&s, NULL))
|
||||
|
@ -581,14 +581,14 @@ static int handlePreambleTag(Spec spec, Package pkg, int tag, const char *macro,
|
||||
break;
|
||||
case RPMTAG_VERSION:
|
||||
SINGLE_TOKEN_ONLY;
|
||||
if (rpmCharCheck(spec, field, "._+", ".."))
|
||||
if (rpmCharCheck(spec, field, "._+~", ".."))
|
||||
return RPMERR_BADSPEC;
|
||||
/* This macro is for backward compatibility */
|
||||
addMacro(spec->macros, "PACKAGE_VERSION", NULL, field, RMIL_OLDSPEC);
|
||||
(void) headerAddEntry(pkg->header, tag, RPM_STRING_TYPE, field, 1);
|
||||
break;
|
||||
case RPMTAG_RELEASE:
|
||||
if (rpmCharCheck(spec, field, "._+", ".."))
|
||||
if (rpmCharCheck(spec, field, "._+~", ".."))
|
||||
return RPMERR_BADSPEC;
|
||||
/* This macro is for backward compatibility */
|
||||
addMacro(spec->macros, "PACKAGE_RELEASE", NULL, field, RMIL_OLDSPEC-1);
|
||||
|
@ -51,6 +51,9 @@ static struct rpmlibProvides_s {
|
||||
{ "rpmlib(SetVersions)", "4.0.4-alt98",
|
||||
( RPMSENSE_EQUAL),
|
||||
N_("dependencies support set/subset versions.") },
|
||||
{ "rpmlib(TildeInVersions)", "4.10.0-1",
|
||||
( RPMSENSE_EQUAL),
|
||||
N_("dependency comparison supports versions with tilde.") },
|
||||
{ NULL, NULL, 0, NULL }
|
||||
};
|
||||
|
||||
|
@ -33,9 +33,18 @@ int rpmvercmp(const char * a, const char * b)
|
||||
two = str2;
|
||||
|
||||
/* loop through each version segment of str1 and str2 and compare them */
|
||||
while (*one && *two) {
|
||||
while (*one && !xisalnum(*one)) one++;
|
||||
while (*two && !xisalnum(*two)) two++;
|
||||
while (*one || *two) {
|
||||
while (*one && !xisalnum(*one) && *one != '~') one++;
|
||||
while (*two && !xisalnum(*two) && *two != '~') two++;
|
||||
|
||||
/* handle the tilde separator, it sorts before everything else */
|
||||
if (*one == '~' || *two == '~') {
|
||||
if (*one != '~') return 1;
|
||||
if (*two != '~') return -1;
|
||||
one++;
|
||||
two++;
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( !*one && !*two )
|
||||
return 0;
|
||||
|
Loading…
Reference in New Issue
Block a user