summaryrefslogtreecommitdiff
path: root/repo/bin/diff-dists
blob: 95382975c4d06dd7928883c97a84d8d694b35c0e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
#!/usr/bin/perl

# Diff two Sources files, comparing version numbers for each package found in the second file.
# Usage example: ./diff-dists [-OPTIONS] <debian-sid-main-Sources> <pgapt-sid-pgdg-testing-main-Sources>
#   -b remove +bN binnmu version suffix before comparing
#   -p remove pgdg version suffix before comparing
#   -m don't show packages missing in 2nd file
#   -t force colored output
#   -u show unchanged packages

use strict;
use warnings;
use Dpkg::Version;
use Getopt::Long;
Getopt::Long::config('bundling');

my $mangle_binnmu_version = 0;
my $show_missing = 1;
my $mangle_pgdg_version = 0;
my $print_promotes = 0;
my $to_term = (-t 1);
my $unchanged = 0;

GetOptions (
  '-b' => \$mangle_binnmu_version,
  '-m' => sub { $show_missing = 0 },
  '-p' => \$mangle_pgdg_version,
  '-P' => \$print_promotes,
  '-t' => \$to_term,
  '-u' => \$unchanged,
) or die;

# enable ansi codes if outputting to a terminal
my ($b, $r, $g, $n) = $to_term ? ("\e[1m", "\e[31m", "\e[32m", "\e[0m") : ("", "", "", "");

die "Syntax: $0 [-m] <source1> <source2>" unless (@ARGV == 2);
my ($source1, $source2) = @ARGV;
my (%pkg1, %pkg2, %src);

$/ = ''; # slurp paragraphs

open S2, $source2 or die "$source2: $!";
while (<S2>) {
	my ($pkg) = /^Package: (.+)/m or die "$source2: paragraph without Package: $_";
	my ($ver) = /^Version: (.+)/m or die "$source2: paragraph without Version: $_";
	my ($src) = /^Source: (\S+)/m;
	my $v = Dpkg::Version->new($ver);
	$pkg2{$pkg} = $v if (not exists $pkg2{$pkg} or $v > $pkg2{$pkg});
	$src{$pkg} = $src if ($src);
}
close S2;

open S1, $source1 or die "$source1: $!";
while (<S1>) {
	my ($pkg) = /^Package: (.+)/m or die "$source1: paragraph without Package: $_";
	my ($ver) = /^Version: (.+)/m or die "$source1: paragraph without Version: $_";
	my ($src) = /^Source: (\S+)/m;
	my $v = Dpkg::Version->new($ver);
	$pkg1{$pkg} = $v if (not exists $pkg1{$pkg} or $v > $pkg1{$pkg});
	$src{$pkg} = $src if ($src);
}
close S1;

my %promotes;

foreach my $pkg (sort keys %pkg1) {
	my $s = '';
	$s = " ($src{$pkg})" if ($src{$pkg} and $src{$pkg} ne $pkg);
	my $ver1 = my $ver1mangled = $pkg1{$pkg};
	$ver1mangled =~ s/\+b\d+$// if ($mangle_binnmu_version); # remove +b1
	$ver1mangled =~ s/.pgdg(?:[\d.]+)?\+\d$// if ($mangle_pgdg_version); # remove .pgdg80+1
	if (not exists $pkg2{$pkg}) {
		if ($show_missing and $pkg ne 'pgdg-buildenv') {
			print "$g$pkg$s$n $b$ver1$n <missing>\n";
			$promotes{$s ? $src{$pkg} : $pkg} = 1;
		}
		next;
	}

	my $ver2 = my $ver2mangled = $pkg2{$pkg};
	$ver2mangled =~ s/\+b\d+$// if ($mangle_binnmu_version); # remove +b1
	$ver2mangled =~ s/.pgdg(?:[\d.]+)?\+\d$// if ($mangle_pgdg_version); # remove .pgdg80+1
	if ($ver1mangled eq $ver2mangled) {
		print "OK: $pkg$s $ver1 $ver2\n" if ($unchanged);
		delete $pkg2{$pkg};
		next;
	}

	if ($ver1 > $ver2) {
		print "$g$pkg$s$n $b$ver1$n $ver2\n";
		$promotes{$s ? $src{$pkg} : $pkg} = 1;;
	} else {
		print "$r$pkg$s$n $ver1 $b$ver2$n\n";
	}
	delete $pkg2{$pkg};
}

foreach my $pkg (sort keys %pkg2) {
	my $s = '';
	$s = " ($src{$pkg})" if ($src{$pkg} and $src{$pkg} ne $pkg);
	print "$r$pkg$s$n <missing> $b$pkg2{$pkg}$n\n";
}

if ($print_promotes and %promotes) {
	for my $pkg (sort keys %promotes) {
		print "promote $pkg\n";
	}
}