This is still undergoing testing, and I should write some unit tests.

The idea is that sometimes, joined updates will all have the same version
number:

.e.g.,
ibus-1.5.5p15:py-gobject3-3.32.1p0+py-gobject3-common-3.32.1p0+py3-gobject3-3.32.1p0->py-gobject3-3.32.2+py-gobject3-common-3.32.2+py3-gobject3-3.32.2:
 418/741

so, smart_join will simplify this into:
py-gobject3+py-gobject3-common+py3-gobject3-3.32.1p0->py-gobject3-common+py3-gobject-3.32.2

(and stop there, because the two "stems" don't match)

Note that this is slightly abusing splitstem/splitname to do the right
thing, as they will indeed split things at the first -[0-9]...


Index: UpdateSet.pm
===================================================================
RCS file: /cvs/src/usr.sbin/pkg_add/OpenBSD/UpdateSet.pm,v
retrieving revision 1.83
diff -u -p -r1.83 UpdateSet.pm
--- UpdateSet.pm        7 Apr 2019 10:44:25 -0000       1.83
+++ UpdateSet.pm        29 Jun 2019 15:59:29 -0000
@@ -128,10 +128,29 @@ sub has_error
        &OpenBSD::Handle::has_error;
 }
 
+sub smart_join
+{
+       my $self = shift;
+       if (@_ <= 1) {
+               return join('+', @_);
+       }
+       my ($k, @stems);
+       for my $l (@_) {
+               my ($stem, @rest) = OpenBSD::PackageName::splitname($l);
+               my $k2 = join('-', @rest);
+               $k //= $k2;
+               if ($k2 ne $k) {
+                       return join('+', sort @_);
+               }
+               push(@stems, $stem);
+       }
+       return join('+', sort @stems).'-'.$k;
+}
+
 sub print
 {
        my $self = shift;
-       return join('+', sort $self->older_names);
+       return $self->smart_join($self->older_names);
 }
 
 sub todo_names
@@ -142,7 +161,7 @@ sub todo_names
 sub short_print
 {
        my $self = shift;
-       my $result = join('+', sort $self->todo_names);
+       my $result = $self->smart_join($self->todo_names);
        if (length $result > 30) {
                return substr($result, 0, 27)."...";
        } else {
@@ -382,25 +401,31 @@ sub print
        my $self = shift;
        my $result = "";
        if ($self->kept > 0) {
-               $result = "[".join('+', sort $self->kept_names)."]";
+               $result = "[".$self->smart_join($self->kept_names)."]";
+       }
+       my ($old, $new);
+       if ($self->older > 0) {
+               $old = $self->SUPER::print;
+       }
+       if ($self->newer > 0) {
+               $new = $self->smart_join($self->newer_names);
        }
        # XXX common case
-       if ($self->newer == 1 && $self->older == 1) {
-               my ($a, $b) = ($self->older_names, $self->newer_names);
-               my $stema = OpenBSD::PackageName::splitstem($a);
-               my ($stemb, @rest) = OpenBSD::PackageName::splitname($b);
+       if (defined $old && defined $new) {
+               my $stema = OpenBSD::PackageName::splitstem($old);
+               my ($stemb, @rest) = OpenBSD::PackageName::splitname($new);
                if ($stema eq $stemb) {
-                       return $result .$a."->".join('-', @rest);
+                       return $result .$old."->".join('-', @rest);
                }
        }
 
-       if ($self->older > 0) {
-               $result .= $self->SUPER::print."->";
+       if (defined $old) {
+               $result .= $old."->";
        }
-       if ($self->newer > 0) {
-               $result .= join('+', sort $self->newer_names);
+       if (defined $new) {
+               $result .= $new;
        } elsif ($self->hints > 0) {
-               $result .= join('+', sort $self->hint_names);
+               $result .= $self->smart_join($self->hint_names);
        }
        return $result;
 }

Reply via email to