-
Notifications
You must be signed in to change notification settings - Fork 710
VPP ArtifactVersioning
Dave Wallace edited this page Apr 21, 2026
·
1 revision
DEB artifact versions, in DEB sort order applied,
before change Ib69a59ee98aa296c5cb24b183bba807b6cb3c05c:
19.08.2-release <--- in fdio/release
19.08.2-2~g220e40541~b2500 |
19.08.2-1~g99fa5f722~b2499 | <--- fdio/1908
19.08.1-release <--- in fdio/release
19.08.1-402~g0830008b3~b2497 |
19.08.1-401~g8e4ed521a~b2496 |
...
19.08.1-3~g1ffabcb3d~b2098 |
19.08.1-2~g6b9847e80~b2097 |
19.08.1-1~gda900b25c~b2096 |
19.08-rc2~11-g01685bead~b2067 |
19.08-rc2~10-g2ecbf6dc5~b2066 |
...
19.08-rc2~2-ga5766fe13~b2058 |
19.08-rc2~1-g4c945dacb~b2057 | <--- in fdio/1908
19.08-rc1~19-gbb83b16a3~b2055 |
19.08-rc1~18-g8ef151c90~b2054 |
...
19.08-rc1~2-gc7f0fe030~b2038 |
19.08-rc1~1-g7119c22f8~b2037 --/
19.08-rc0~840-gc0bc26eaf~b2035 ====\
19.08-rc0~839-g08f2a5dae~b2035 |
19.08-rc0~838-g388f418a8~b2033 | <=== in fdio/master
...
19.08-rc0~2-g7c91007e1~b1197 |
19.08-rc0~1-g10dc2eabd~b1196 =====/
19.08-release <--- in fdio/release
19.08-rc2~b2056 <--- in fdio/1908 overshadowed by post-rc1 but pre-rc2 builds, overshadows post-19.08 builds
19.08-rc1~b2036 <--- in fdio/1908 (the first build to go into fdio/1908) overshadows post-19.08 builds
19.08-rc0~b1195 <======== === in fdio/master
19.08-26~g7c33c343e~b2094 ---\
19.08-25~g50f883106~b2093 |
19.08-24~ge6a571262~b2092 | <--- in fdio/1908 (overshadowed by rc1/2 builds)
...
19.08-2~g9e25c7723~b2070 |
19.08-1~g46441cb9c~b2069 --/
19.04-rc0~674-g3f86ca3ee~b1194 ====\
19.04-rc0~673-ge36f44ad9~b1193 | <=== in fdio/master (before stable/1904 branch)
=====/
DEB artifact versions, in DEB sort order applied, after change:
19.08.2-release <---------- in fdio/release
19.08.2-2~g220e40541~b2500 ----\
19.08.2-1~g99fa5f722~b2499 ---/ <-- in fdio/1908
19.08.1-release <---------- in fdio/release
19.08.1-402~g0830008b3~b2497 ---\
19.08.1-401~g8e4ed521a~b2496 |
...
19.08.1-3~g1ffabcb3d~b2098 |
19.08.1-2~g6b9847e80~b2097 |
19.08.1-1~gda900b25c~b2096 |
19.08.0-26~g7c33c343e~b2094 |
19.08.0-25~g50f883106~b2093 |
19.08.0-24~ge6a571262~b2092 | <---- in fdio/1908, all in correct order
...
19.08.0-2~g9e25c7723~b2070 |
19.08.0-1~g46441cb9c~b2069 |
19.08-rc2~11-g01685bead~b2067 |
19.08-rc2~10-g2ecbf6dc5~b2066 |
19.08-rc2~9-g14c7756ad~b2065 |
...
19.08-rc2~1-g4c945dacb~b2057 |
19.08-rc2~0-g2f51729bb~b2056 <------- in fdio/1908 previously was called "19.08-rc2", now in the correct place
19.08-rc1~19-gbb83b16a3~b2055 |
19.08-rc1~18-g8ef151c90~b2054 |
...
19.08-rc1~2-gc7f0fe030~b2038 |
19.08-rc1~1-g7119c22f8~b2037 |
19.08-rc1~0-g23526f78a~b2036 <--/---- in fdio/1908, previously was called "19.08-rc1", now in the correct place
19.08-rc0~840-gc0bc26eaf~b2035 ====\
19.08-rc0~839-g08f2a5dae~b2034 | <=== in fdio/master
...
19.08-rc0~1-g10dc2eabd~b1196 |
19.08-rc0~0-g40fd1f3df~b1195 ======/
19.08-release <---- in fdio/release
19.04-rc0~674-g3f86ca3ee~b1194 <======== in fdio/master (before stable/1904 branch)
19.04-rc0~673-ge36f44ad9~b1193 <=======/
The code used to test was as follows:
#define _GNU_SOURCE
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
static int order(char c)
{
if (isdigit(c))
return 0;
else if (isalpha(c))
return c;
else if (c == '~')
return -1;
else if (c)
return c + 256;
else
return 0;
}
int CmpFragment(const char *A,const char *AEnd,
const char *B,const char *BEnd)
{
/* Iterate over the whole string
What this does is to split the whole string into groups of
numeric and non numeric portions. For instance:
a67bhgs89
Has 4 portions 'a', '67', 'bhgs', '89'. A more normal:
2.7.2-linux-1
Has '2', '.', '7', '.' ,'-linux-','1' */
const char *lhs = A;
const char *rhs = B;
while (lhs != AEnd && rhs != BEnd)
{
int first_diff = 0;
while (lhs != AEnd && rhs != BEnd &&
(!isdigit(*lhs) || !isdigit(*rhs)))
{
int vc = order(*lhs);
int rc = order(*rhs);
if (vc != rc)
return vc - rc;
++lhs; ++rhs;
}
while (*lhs == '0')
++lhs;
while (*rhs == '0')
++rhs;
while (isdigit(*lhs) && isdigit(*rhs))
{
if (!first_diff)
first_diff = *lhs - *rhs;
++lhs;
++rhs;
}
if (isdigit(*lhs))
return 1;
if (isdigit(*rhs))
return -1;
if (first_diff)
return first_diff;
}
// The strings must be equal
if (lhs == AEnd && rhs == BEnd)
return 0;
// lhs is shorter
if (lhs == AEnd)
{
if (*rhs == '~') return 1;
return -1;
}
// rhs is shorter
if (rhs == BEnd)
{
if (*lhs == '~') return -1;
return 1;
}
// Shouldn't happen
return 1;
}
/* This fragments the version into E:V-R triples and compares each
portion separately. */
int DoCmpVersion(char *A,char *AEnd,
char *B, char *BEnd)
{
// Strip off the epoch and compare it
char *lhs = ( char*) memchr(A, ':', AEnd - A);
char *rhs = ( char*) memchr(B, ':', BEnd - B);
if (lhs == NULL)
lhs = A;
if (rhs == NULL)
rhs = B;
// Special case: a zero epoch is the same as no epoch,
// so remove it.
if (lhs != A)
{
for (; *A == '0'; ++A);
if (A == lhs)
{
++A;
++lhs;
}
}
if (rhs != B)
{
for (; *B == '0'; ++B);
if (B == rhs)
{
++B;
++rhs;
}
}
// Compare the epoch
int Res = CmpFragment(A,lhs,B,rhs);
if (Res != 0)
return Res;
// Skip the :
if (lhs != A)
lhs++;
if (rhs != B)
rhs++;
// Find the last -
char *dlhs = ( char*) memrchr(lhs, '-', AEnd - lhs);
char *drhs = ( char*) memrchr(rhs, '-', BEnd - rhs);
if (dlhs == NULL)
dlhs = AEnd;
if (drhs == NULL)
drhs = BEnd;
// Compare the main version
Res = CmpFragment(lhs,dlhs,rhs,drhs);
if (Res != 0)
return Res;
// Skip the -
if (dlhs != lhs)
dlhs++;
if (drhs != rhs)
drhs++;
// no debian revision need to be treated like -0
if (*(dlhs-1) == '-' && *(drhs-1) == '-')
return CmpFragment(dlhs,AEnd,drhs,BEnd);
else if (*(dlhs-1) == '-')
{
char* null = "0";
return CmpFragment(dlhs,AEnd,null, null+1);
}
else if (*(drhs-1) == '-')
{
char* null = "0";
return CmpFragment(null, null+1, drhs, BEnd);
}
else
return 0;
}
char cmp_a[1024];
char cmp_b[1024];
int deb_compare(char **a, char **b) {
int len_a = strlen(*a);
memcpy(cmp_a, *a, len_a+1);
char *end_a = cmp_a + len_a;
int len_b = strlen(*b);
memcpy(cmp_b, *b, len_b+1);
char *end_b = cmp_b + len_b;
int res = -DoCmpVersion(cmp_a, end_a, cmp_b, end_b);
// printf("A: '%s' B: '%s' res:%d\n", cmp_a, cmp_b, res);
return res;
}
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
/* This was lifted pretty much verbatim from
* https://fastapi.metacpan.org/source/HAG/RPM-VersionSort-1.00/VersionSort.xs */
/* This is lifted pretty much verbatim from the RPM 4.0.2 sources.
See lib/misc.c
*/
/* Note that the semantics as documented by redhat are incorrect: some
return value semantics are inherited from strcmp, which only promises
to use integers greater, less, or equal to zero, which is not the same
as (-1,0,1). So we fix this up in the xsub.
*/
/* compare alpha and numeric segments of two versions */
/* return 1: a is newer than b */
/* 0: a and b are the same version */
/* -1: b is newer than a */
int rpmvercmp(const char * a, const char * b)
{
char oldch1, oldch2;
char * str1, * str2;
char * one, * two;
int rc;
int isnum;
/* easy comparison to see if versions are identical */
if (!strcmp(a, b)) return 0;
str1 = alloca(strlen(a) + 1);
str2 = alloca(strlen(b) + 1);
strcpy(str1, a);
strcpy(str2, b);
one = str1;
two = str2;
/* loop through each version segment of str1 and str2 and compare them */
while (*one && *two) {
while (*one && !isalnum(*one)) one++;
while (*two && !isalnum(*two)) two++;
str1 = one;
str2 = two;
/* grab first completely alpha or completely numeric segment */
/* leave one and two pointing to the start of the alpha or numeric */
/* segment and walk str1 and str2 to end of segment */
if (isdigit(*str1)) {
while (*str1 && isdigit(*str1)) str1++;
while (*str2 && isdigit(*str2)) str2++;
isnum = 1;
} else {
while (*str1 && isalpha(*str1)) str1++;
while (*str2 && isalpha(*str2)) str2++;
isnum = 0;
}
/* save character at the end of the alpha or numeric segment */
/* so that they can be restored after the comparison */
oldch1 = *str1;
*str1 = '\0';
oldch2 = *str2;
*str2 = '\0';
/* take care of the case where the two version segments are */
/* different types: one numeric and one alpha */
if (one == str1) return -1; /* arbitrary */
if (two == str2) return -1;
if (isnum) {
/* this used to be done by converting the digit segments */
/* to ints using atoi() - it's changed because long */
/* digit segments can overflow an int - this should fix that. */
/* throw away any leading zeros - it's a number, right? */
while (*one == '0') one++;
while (*two == '0') two++;
/* whichever number has more digits wins */
if (strlen(one) > strlen(two)) return 1;
if (strlen(two) > strlen(one)) return -1;
}
/* strcmp will return which one is greater - even if the two */
/* segments are alpha or if they are numeric. don't return */
/* if they are equal because there might be more segments to */
/* compare */
rc = strcmp(one, two);
if (rc) return rc;
/* restore character that was replaced by null above */
*str1 = oldch1;
one = str1;
*str2 = oldch2;
two = str2;
}
/* this catches the case where all numeric and alpha segments have */
/* compared identically but the segment sepparating characters were */
/* different */
if ((!*one) && (!*two)) return 0;
/* whichever version still has characters left over wins */
if (!*one) return -1; else return 1;
}
int rpm_compare(const char **a, const char **b)
{
int vercmp = rpmvercmp(*a, *b);
int result = 0;
if(vercmp < 0) result = 1;
if(vercmp > 0) result = -1;
// printf("RPM comp '%s' vs '%s': %d\n", *a, *b, result);
return result;
}
int main(int argc, char **argv)
{
FILE * fp;
char * line = NULL;
size_t len = 0;
ssize_t read;
char **versions = malloc(1024000);
int n_versions = 0;
if (argc < 2) {
fp = fopen("versions.txt", "r");
} else {
fp = fopen(argv[1], "r");
}
if (fp == NULL)
exit(EXIT_FAILURE);
int i;
while ((read = getline(&versions[n_versions], &len, fp)) != -1) {
line = versions[n_versions];
if (strlen(line) > 0) {
line[strlen(line)-1] = 0;
}
if (strlen(line) == 0) {
break;
}
n_versions++;
}
/*
printf("Original list:\n");
for (i=0; i<n_versions; i++) {
printf("%s\n", versions[i]);
}
*/
qsort(versions, n_versions, sizeof(char *), deb_compare);
printf("\nDEB sorting:\n");
for (i=0; i<n_versions; i++) {
printf("%s\n", versions[i]);
}
qsort(versions, n_versions, sizeof(char *), rpm_compare);
printf("\nRPM sorting:\n");
for (i=0; i<n_versions; i++) {
printf("%s\n", versions[i]);
}
fclose(fp);
exit(EXIT_SUCCESS);
}
- VPP 2022 Make Test Use Case Poll
- VPP-AArch64
- VPP-ABF
- VPP Alternative Builds
- VPP API Concepts
- VPP API Versioning
- VPP-ApiChangeProcess
- VPP-ArtifactVersioning
- VPP-BIER
- VPP-Bihash
- VPP-BugReports
- VPP Build System Deep Dive
- VPP Build, Install, And Test Images
- VPP-BuildArtifactRetentionPolicy
- VPP-c2cpel
- VPP Code Walkthrough VoD
- VPP Code Walkthrough VoD Topic Index
- VPP Code Walkthrough VoDs
- VPP-CodeStyleConventions
- VPP-CodingTips
- VPP Command Line Arguments
- VPP Command Line Interface CLI Guide
- VPP-CommitMessages
- VPP-Committers-SMEs
- VPP-CommitterTasks-ApiFreeze
- VPP CommitterTasks Compare API Changes
- VPP-CommitterTasks-CutPointRelease
- VPP-CommitterTasks-CutRelease
- VPP-CommitterTasks-FinalReleaseCandidate
- VPP-CommitterTasks-PullThrottleBranch
- VPP-CommitterTasks-ReleasePlan
- VPP Configuration Tool
- VPP Configure An LW46 MAP E Terminator
- VPP Configure VPP As A Router Between Namespaces
- VPP Configure VPP TAP Interfaces For Container Routing
- VPP-CoreFileMismatch
- VPP-cpel
- VPP-cpeldump
- VPP-CurrentData
- VPP-DHCPKit
- VPP-DHCPv6
- VPP-DistributedOwnership
- VPP-Documentation
- VPP DPOs And Feature Arcs
- VPP EC2 Instance With SRIOV
- VPP-elog
- VPP-FAQ
- VPP Feature Arcs
- VPP-Features
- VPP-Features-IPv6
- VPP-FIB
- VPP-g2
- VPP Getting VPP 16.06
- VPP Getting VPP Release Binaries
- VPP-HA
- VPP-HostStack
- VPP-HostStack-BuiltinEchoClientServer
- VPP-HostStack-EchoClientServer
- VPP-HostStack-ExternalEchoClientServer
- VPP HostStack Hs Test
- VPP-HostStack-LDP-iperf
- VPP-HostStack-LDP-nginx
- VPP-HostStack-LDP-sshd
- VPP-HostStack-nginx
- VPP-HostStack-SessionLayerArchitecture
- VPP-HostStack-TestHttpServer
- VPP-HostStack-TestProxy
- VPP-HostStack-TLS
- VPP-HostStack-VCL
- VPP-HostStack-VclEchoClientServer
- VPP-Hotplug
- VPP How To Add A Tunnel Encapsulation
- VPP How To Build The Sample Plugin
- VPP How To Connect A PCI Interface To VPP
- VPP How To Create A VPP Binary Control Plane API
- VPP How To Deploy VPP In EC2 Instance And Use It To Connect Two Different VPCs
- VPP How To Optimize Performance %28System Tuning%29
- VPP How To Use The API Trace Tools
- VPP How To Use The C API
- VPP How To Use The Packet Generator And Packet Tracer
- VPP-Howtos
- VPP-index
- VPP Installing VPP Binaries From Packages
- VPP Interconnecting vRouters With VPP
- VPP Introduction To IP Adjacency
- VPP Introduction To N Tuple Classifiers
- VPP IP Adjacency Introduction
- VPP-IPFIX
- VPP-IPSec
- VPP IPSec And IKEv2
- VPP IPv6 SR VIRL Topology File
- VPP Java API
- VPP Java API Plugin Support
- VPP Jira Workflow
- VPP-Macswapplugin
- VPP-MakeTestFramework
- VPP-Meeting
- VPP-MFIB
- VPP Missing Prefetches
- VPP Modifying The Packet Processing Directed Graph
- VPP MPLS FIB
- VPP-NAT
- VPP Nataas Test
- VPP-OVN
- VPP Per Feature Notes
- VPP Performance Analysis Tools
- VPP-perftop
- VPP Progressive VPP Tutorial
- VPP Project Meeting Minutes
- VPP Pulling, Building, Running, Hacking And Pushing VPP Code
- VPP Pure L3 Between Namespaces With 32s
- VPP Pure L3 Container Networking
- VPP Pushing And Testing A Tag
- VPP Python API
- VPP-PythonVersionPolicy
- VPP-QuickTrexSetup
- VPP Random Hints And Kinks For KVM Usage
- VPP Release Plans Release Plan 16.09
- VPP Release Plans Release Plan 17.01
- VPP Release Plans Release Plan 17.04
- VPP Release Plans Release Plan 17.07
- VPP Release Plans Release Plan 17.10
- VPP Release Plans Release Plan 18.01
- VPP Release Plans Release Plan 18.04
- VPP Release Plans Release Plan 18.07
- VPP Release Plans Release Plan 18.10
- VPP Release Plans Release Plan 19.01
- VPP Release Plans Release Plan 19.04
- VPP Release Plans Release Plan 19.08
- VPP Release Plans Release Plan 20.01
- VPP Release Plans Release Plan 20.05
- VPP Release Plans Release Plan 20.09
- VPP Release Plans Release Plan 21.01
- VPP Release Plans Release Plan 21.06
- VPP Release Plans Release Plan 21.10
- VPP Release Plans Release Plan 22.02
- VPP Release Plans Release Plan 22.06
- VPP Release Plans Release Plan 22.10
- VPP Release Plans Release Plan 23.02
- VPP Release Plans Release Plan 23.06
- VPP Release Plans Release Plan 23.10
- VPP Release Plans Release Plan 24.02
- VPP Release Plans Release Plan 24.06
- VPP Release Plans Release Plan 24.10
- VPP Release Plans Release Plan 25.02
- VPP Release Plans Release Plan 25.06
- VPP Release Plans Release Plan 25.10
- VPP Release Plans Release Plan 26.02
- VPP Release Plans Release Plan 26.06
- VPP-RM
- VPP-SecurityGroups
- VPP Segment Routing For IPv6
- VPP Segment Routing For MPLS
- VPP Setting Up Your Dev Environment
- VPP-SNAT
- VPP Software Architecture
- VPP STN Testing
- VPP The VPP API
- VPP Training Events
- VPP-Troubleshooting
- VPP-Troubleshooting-BuildIssues
- VPP-Troubleshooting-Vagrant
- VPP Tutorial DPDK And MacSwap
- VPP Tutorial Routing And Switching
- VPP-Tutorials
- VPP Use VPP To Chain VMs Using Vhost User Interface
- VPP Use VPP To Connect VMs Using Vhost User Interface
- VPP Using mTCP User Mode TCP Stack With VPP
- VPP Using VPP As A VXLAN Tunnel Terminator
- VPP Using VPP In A Multi Thread Model
- VPP-VOM
- VPP VPP BFD Nexus
- VPP VPP Home Gateway
- VPP VPP WIKI DEPRECATED CONTENT
- VPP-VPPCommunicationsLibrary
- VPP-VPPConfig
- VPP What Is ODP4VPP
- VPP What Is VPP
- VPP Working Environments
- VPP Working With The 16.06 Throttle Branch