Cool. So, I tested this by installing:

  - https://alioth.debian.org/anonscm/git/mirrorer/mirrorer.git
    (git repo)

  - branched off the (default) debian branch [2]

  - patched with Add-multiple-version-management.patch

https://bugs.debian.org/cgi-bin/bugreport.cgi?msg=70;filename=Add-multiple-version-management.patch;att=15;bug=570623

  - fixed 3 conflicts in main.c, not sure what was conflicting, probably
    leftover whitespace or something.

  - autoreconf -vi (see INSTALL for dependencies)
  - ./configure --prefix=/usr/local; make; make install
  - renamed the resultant binaries with "-mver" suffix so they don't
    conflict with the rest of my setup


Initial observations:

  - I started a new multi-version repository and loaded up several
    versions of a package: it works.
  - Downgrading/upgrading a single package from that repository
    works.

  - Warnings when including a new package:

debian-mver# reprepro-mver -C acos include wheezy 
/srv/junk/asterisk*13.3.*changes
Error while parsing 'asterisk-config|1:13.3.0-acos1+o0' as version: epoch in 
version is not number
Parse errors processing versions.
Error while parsing 'asterisk-dbg|1:13.3.0-acos1+o0' as version: epoch in 
version is not number
Parse errors processing versions.
...

    It complained about the epoch in version not being a number. I
    assume someone takes "asterisk-config|1" to be an epoch, instead
    of just "1". (See below/attachment for a fix.)

  - When including two packages with the same minor/micro version,
    things were less okay:

debian-mver# reprepro-mver -C acos include wheezy 
/srv/junk/old/asterisk_13.2.0*acos2*changes
Error while parsing 'asterisk-config|1:13.2.0-acos2+o0+2up' as version: epoch 
in version is not number
Parse errors processing versions.
...
Internal error of the underlying BerkeleyDB database:
Within references.db subtable references at put: DB_KEYEXIST: Key/data pair 
already exists
Warning: database 'wheezy|acos|amd64' was modified but no index file was 
exported.
Changes will only be visible after the next 'export'!
There have been errors!

   But a dump [1] of the references file revealed no immediate problem:

debian-mver# diff -pu <(cat -A references.db.2) <(cat -A references.db.3)
--- /dev/fd/63  2015-04-07 11:45:35.900044000 +0200
+++ /dev/fd/62  2015-04-07 11:45:35.900044000 +0200
@@ -8,38 +8,72 @@ db_pagesize=4096$
 HEADER=END$    
 >>>  pool/acos/a/asterisk/asterisk-config_13.2.0-acos1+o0+2up_all.deb^@$
 >>>  wheezy|acos|amd64^@$
+>>>  pool/acos/a/asterisk/asterisk-config_13.2.0-acos2+o0+2up_all.deb^@$
+>>>  wheezy|acos|amd64^@$
...

  I added a few debug prints, and I got this:

...
Skipping inclusion of 'asterisk-modules' '1:13.2.0-acos2+o0+2up' in 
'wheezy|acos|amd64', as this version already exists.
Skipping inclusion of 'asterisk' '1:13.2.0-acos2+o0+2up' in 
'wheezy|acos|amd64', as this version already exists.

db: 'pool/acos/a/asterisk/asterisk_13.2.0-acos2+o0+2up.dsc' adding to 
references.db(references).
Internal error of the underlying BerkeleyDB database:
Within references.db subtable references at put: DB_KEYEXIST: Key/data pair 
already exists
db: 'pool/acos/a/asterisk/asterisk_13.2.0.orig.tar.gz' adding to 
references.db(references).
Internal error of the underlying BerkeleyDB database:
Within references.db subtable references at put: DB_KEYEXIST: Key/data pair 
already exists
db: 'pool/acos/a/asterisk/asterisk_13.2.0-acos2+o0+2up.debian.tar.gz' adding to 
references.db(references).
Internal error of the underlying BerkeleyDB database:
Within references.db subtable references at put: DB_KEYEXIST: Key/data pair 
already exists
There have been errors!

  Those errors only popped up when uploading the 2nd (acos2) version.
  For the first (acos1), I just get the "Skipping" notices like
  expected (when calling it a second/third time).

  - Removing a package worked, unless we have multiple versions:

debian-mver# reprepro-mver -C acos remove wheezy 
libpjproject-dev=2.3.0.0.ast20150218-acos1

  OK

  - Removing a package did not work when we have multiple versions:

debian-mver# reprepro-mver  -C acos list wheezy | head -n2
wheezy|acos|amd64: asterisk 1:13.3.0-acos1+o0
wheezy|acos|amd64: asterisk 1:13.2.0-acos2+o0+2up
...
debian-mver# reprepro-mver -C acos remove wheezy asterisk=1:13.2.0-acos2+o0+2up
removing 'asterisk=1:13.2.0-acos2+o0+2up' from 'wheezy|acos|amd64'...
Error while parsing 'asterisk|1:13.2.0-acos2+o0+2up' as version: epoch in 
version is not number
Parse errors processing versions.
Error while parsing 'asterisk|1:13.2.0-acos2+o0+2up' as version: epoch in 
version is not number
Parse errors processing versions.
/srv/reprepro/debian-mver/db/packages.db/wheezy|acos|amd64: DB_SECONDARY_BAD: 
Secondary index inconsistent with primary
Internal error of the underlying BerkeleyDB database:
Within packages.db subtable wheezy|acos|amd64 at del: DB_SECONDARY_BAD: 
Secondary index inconsistent with primary
There have been errors!

  - However, when adding bug570623_version_compare.patch (attached),
    removal started to work as expected.


In summary:

- patching the version compare helps, but
- multiple closely related versions still cause grief


Thanks for the patches!


Cheers,
Walter Doekes
OSSO B.V.


[1] references.db was dumped like this:
    $ db5.1_dump db/references.db |
      perl -pe '/^ /&&s/^/>>> /&&s/[0-9a-f]{2}/chr hex$&/ige'

[2] changing from the `debian` branch to the `master` branch didn't
    seem to change anything

diff --git a/database.c b/database.c
index d0f2c63..3303239 100644
--- a/database.c
+++ b/database.c
@@ -1903,6 +1903,22 @@ retvalue database_openreferences(void) {
 	return RET_OK;
 }
 
+static retvalue fullversions_cmp(const char *first, const char *second, int *result) {
+	const char *a = strchr(first, '|'); /* name|version */
+	const char *b = strchr(second, '|');
+
+	if (a == NULL && b == NULL) {
+		return dpkgversions_cmp(first, second, result);
+	} else if (a && b) {
+		if ((a - first) == (b - second) && memcmp(first, second, (a - first)) == 0) {
+			return dpkgversions_cmp(a + 1, b + 1, result);
+		}
+	}
+
+	fprintf(stderr, "We have trouble comparing '%s' with '%s'\n", first, second);
+	return RET_ERROR;
+}
+
 static int debianversioncompare(UNUSED(DB *db), const DBT *a, const DBT *b) {
 	const char *a_version;
 	const char *b_version;
@@ -1912,7 +1928,7 @@ static int debianversioncompare(UNUSED(DB *db), const DBT *a, const DBT *b) {
 	// TODO: Check lenght of a->data and b->data
 	a_version = packagedata_getversion(a->data);
 	b_version = packagedata_getversion(b->data);
-	r = dpkgversions_cmp(a_version, b_version, &versioncmp);
+	r = fullversions_cmp(a_version, b_version, &versioncmp);
 	if (RET_WAS_ERROR(r)) {
 		fprintf(stderr, "Parse errors processing versions.\n");
 		return r;

Reply via email to