The following commit has been merged in the master branch:
commit 5962f9d2b2f5e70b223d04638302c0f2239af36e
Author: Raphael Hertzog <[email protected]>
Date:   Mon May 18 23:22:04 2009 +0200

    dpkg-parsechangelog: handle better non-existing versions
    
    When a non-existing version is passed in one of the --since, --until,
    --to, --from options, the code will now replace them by a closely related
    version that really exists.

diff --git a/debian/changelog b/debian/changelog
index 33952bb..ebc736c 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -87,6 +87,9 @@ dpkg (1.15.1) UNRELEASED; urgency=low
     is interrupted/killed by a signal. Closes: #498734
   * Fix dpkg-buildpackage/dpkg-genchanges to properly interpret option -v0.
     Closes: #475916
+  * Improves how dpkg-parsechangelog handles non-existing versions
+    in its --since, --until, --to, --from options. Approximate the intent
+    by selectioning the nearest version instead. Closes: #477638
 
   [ Guillem Jover ]
   * Fix typo in dpkg output (‘unexecpted’ → ‘unexpected’). Closes: #519082
diff --git a/scripts/Dpkg/Changelog.pm b/scripts/Dpkg/Changelog.pm
index e44ab0a..7c4b1ca 100644
--- a/scripts/Dpkg/Changelog.pm
+++ b/scripts/Dpkg/Changelog.pm
@@ -2,6 +2,7 @@
 # Dpkg::Changelog
 #
 # Copyright © 2005, 2007 Frank Lichtenheld <[email protected]>
+# Copyright © 2009       Raphaël Hertzog <[email protected]>
 #
 #    This program is free software; you can redistribute it and/or modify
 #    it under the terms of the GNU General Public License as published by
@@ -42,6 +43,7 @@ use Dpkg::Gettext;
 use Dpkg::ErrorHandling qw(:DEFAULT report);
 use Dpkg::Cdata;
 use Dpkg::Fields;
+use Dpkg::Version qw(compare_versions);
 
 use base qw(Exporter);
 
@@ -239,6 +241,71 @@ sub __sanity_check_range {
        warning(_g( "you can only specify one of 'to' and 'until', using 
'until'" ));
        $$to = '';
     }
+    $$start = 0 if $$start < 0;
+    return if $$start > $#$data;
+    $$end = $#$data if $$end > $#$data;
+    return if $$end < 0;
+    $$end = $$start if $$end < $$start;
+
+    # Handle non-existing versions
+    my (%versions, @versions);
+    foreach my $entry (@{$data}) {
+        $versions{$entry->{Version}} = 1;
+        push @versions, $entry->{Version};
+    }
+    if ((length($$since) and not exists $versions{$$since})) {
+        warning(_g("'%s' option specifies non-existing version"), "since");
+        warning(_g("use newest entry that is smaller than the one specified"));
+        foreach my $v (@versions) {
+            if (compare_versions($v, "<<", $$since)) {
+                $$since = $v;
+                last;
+            }
+        }
+        $$since = '' if not exists $versions{$$since}; # No version was smaller
+    }
+    if ((length($$from) and not exists $versions{$$from})) {
+        warning(_g("'%s' option specifies non-existing version"), "from");
+        warning(_g("use oldest entry that is bigger than the one specified"));
+        my $oldest;
+        foreach my $v (@versions) {
+            if (compare_versions($v, ">>", $$from)) {
+                $oldest = $v;
+            }
+        }
+        if (defined($oldest)) {
+            $$from = $oldest;
+        } else {
+            $$from = ''; # No version was bigger
+        }
+    }
+    if ((length($$until) and not exists $versions{$$until})) {
+        warning(_g("'%s' option specifies non-existing version"), "until");
+        warning(_g("use oldest entry that is bigger than the one specified"));
+        my $oldest;
+        foreach my $v (@versions) {
+            if (compare_versions($v, ">>", $$until)) {
+                $oldest = $v;
+            }
+        }
+        if (defined($oldest)) {
+            $$until = $oldest;
+        } else {
+            $$until = ''; # No version was bigger
+        }
+    }
+    if ((length($$to) and not exists $versions{$$to})) {
+        warning(_g("'%s' option specifies non-existing version"), "to");
+        warning(_g("use newest entry that is smaller than the one specified"));
+        foreach my $v (@versions) {
+            if (compare_versions($v, "<<", $$to)) {
+                $$to = $v;
+                last;
+            }
+        }
+        $$to = '' if not exists $versions{$$to}; # No version was smaller
+    }
+
     if (length($$since) && ($data->[0]{Version} eq $$since)) {
        warning(_g( "'since' option specifies most recent version, ignoring" ));
        $$since = '';
@@ -247,12 +314,6 @@ sub __sanity_check_range {
        warning(_g( "'until' option specifies oldest version, ignoring" ));
        $$until = '';
     }
-    $$start = 0 if $$start < 0;
-    return if $$start > $#$data;
-    $$end = $#$data if $$end > $#$data;
-    return if $$end < 0;
-    $$end = $$start if $$end < $$start;
-    #TODO: compare versions
     return 1;
 }
 
@@ -312,7 +373,8 @@ sub _data_range {
        last if $v eq $from;
     }
 
-    return \...@result;
+    return \...@result if scalar(@result);
+    return undef;
 }
 
 sub _abort_early {
@@ -872,6 +934,7 @@ Frank Lichtenheld, E<lt>[email protected]<gt>
 =head1 COPYRIGHT AND LICENSE
 
 Copyright E<copy> 2005, 2007 by Frank Lichtenheld
+Copyright E<copy> 2009 by Raphael Hertzog
 
 This program is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by

-- 
dpkg's main repository


-- 
To UNSUBSCRIBE, email to [email protected]
with a subject of "unsubscribe". Trouble? Contact [email protected]

Reply via email to