Skip to content

Instantly share code, notes, and snippets.

@mwgamera
Last active November 11, 2017 13:05
Show Gist options
  • Save mwgamera/898103a4beee96cac2e30d2312214086 to your computer and use it in GitHub Desktop.
Save mwgamera/898103a4beee96cac2e30d2312214086 to your computer and use it in GitHub Desktop.
#!/usr/bin/env perl
# Show combined changelog for the whole dpkg-based system.
# klg, Nov 2017
use strict;
use File::ReadBackwards;
use Dpkg::Version 'version_compare';
use Dpkg::Changelog::Debian;
open \*STDOUT, '|-', $ENV{PAGER} || 'pager' if -t;
my (%src, %bin);
sub pkgchanges {
my $pkg = shift;
return $bin{$pkg} if $bin{$pkg};
my @files = grep !/[.-]old\b/i, </usr/share/doc/$pkg/changelog.Debian.*>;
@files = grep !/[.-]old\b/i, </usr/share/doc/$pkg/changelog.*> unless @files;
die "No changelog for $pkg found!\n" unless @files;
@files = sort { length $b <=> length $a } @files;
my $c = Dpkg::Changelog::Debian->new(verbose => 0);
my $o = 0;
$c->load(shift @files);
my $srcpkg = eval { $c->get_range({count => 1})->[0]->get_source };
warn "Can't determine source package name of $pkg\n" unless $srcpkg;
return $src{$srcpkg} if $srcpkg && $src{$srcpkg};
$bin{$pkg} =
$src{$srcpkg} =
sub {
my $from = shift;
my @ents;
for (;;) {
my $e = $c->get_range({count => 1, offset => $o});
if (not defined $e) {
if (@files) {
$c->load(shift @files);
$o = 0;
$e = $c->get_range({count => 1, offset => $o});
} else {
return @ents;
}
}
if (version_compare($$e[0]->get_version, $from) > 0) {
push @ents, $$e[0];
$o += 1;
} else {
return @ents;
}
}
}
}
my %deleted;
my $log = File::ReadBackwards->new('/var/log/dpkg.log');
while (defined(local $_ = $log->readline)) {
next unless my ($ts, $action, $pkg, $from, $to) =
m/^(\S+ \S+) (disappear|remove|purge|install|upgrade) (\S+) (\S+) (\S+)$/;
$pkg =~ s/:.*//;
$deleted{$pkg} = 1 if $action =~ /disappear|remove|purge/;
if ($action eq 'upgrade' and not $deleted{$pkg}) {
print $_ for pkgchanges($pkg)->($from);
}
print "$ts $action $pkg $from -> $to$/$/";
}
close;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment