21 my @opt = <<'=back' =~ /B<--(\S+)>/g;
39 We generate a json file and a txt file. The latter for myself to view
40 the upcoming contents easily, the json for the webserver.
42 The generation took about 1-2 hours in the beginning but it got slower
43 and slower, the more reports arrived.
47 formerly known as cron-comparing-5181-5182rc2.pl
53 use lib
"$FindBin::Bin/../lib";
59 use File
::Basename
qw(dirname);
60 use File
::Path
qw(mkpath);
66 use Hash
::Util
qw(lock_keys);
69 lock_keys
%Opt, map { /([^=|!]+)/ } @opt;
76 $Opt{oldperl
} = ['5.18.2'] unless $Opt{oldperl
} && @
{$Opt{oldperl
}};
77 $Opt{newperl
} = ['5.20.0 RC1'] unless $Opt{newperl
} && @
{$Opt{newperl
}};
78 die "the arrayrefs for oldperl and newperl must be of same length, "
79 . "found lengths %d and %d, cannot continue",
80 scalar @
{$Opt{oldperl
}},
81 scalar @
{$Opt{newperl
}}
82 unless scalar @
{$Opt{oldperl
}}==scalar @
{$Opt{newperl
}};
85 use lib
"$FindBin::Bin/../CPAN-Blame/lib";
86 use CPAN
::Blame
::Config
::Cnntp
;
88 my $HAVE_IPCCL = eval { require IPC
::ConcurrencyLimit
; 1 };
89 die unless $HAVE_IPCCL;
95 $workdir = File
::Spec
->catdir
96 ($CPAN::Blame
::Config
::Cnntp
::Config
->{solver_vardir
},
99 my($basename) = File
::Basename
::basename
(__FILE__
);
100 my $limit = IPC
::ConcurrencyLimit
->new
103 path
=> "$workdir/IPC-ConcurrencyLimit-$basename",
105 my $limitid = $limit->get_lock;
107 warn "Another process appears to be still running. Exiting.";
111 my $pgdbh = DBI
->connect("dbi:Pg:dbname=analysis") or die "Could not connect to 'analysis': $DBI::err";
112 my $sth0 = $pgdbh->prepare("SELECT COUNT(*) FROM cpanstats WHERE perl=?");
113 my $sth2 = $pgdbh->prepare("select perl, state, count(*) from cpanstats where dist=? and version=? and perl in (?,?) and state in ('pass','fail') group by perl, state");
114 my $sth3 = $pgdbh->prepare("SELECT COUNT(distinct(dist||version)) FROM cpanstats WHERE perl=?");
116 my $jsonxs = JSON
::XS
->new->indent(1);
118 for my $i (0..$#{$Opt{newperl}}) {
120 $perl1 = $Opt{oldperl
}[$i];
121 $perl2 = $Opt{newperl
}[$i];
122 unless ($perl1 && $perl2) {
123 die "options oldperl and newperl are mandatory, found $perl1 vs $perl2";
125 $sth0->execute($perl2);
126 my($total) = $sth0->fetchrow_array;
127 $sth3->execute($perl2);
128 my($totalrcdists) = $sth3->fetchrow_array;
130 # on the days 2016062[12] the smoker was of DCOLLINS was broken
131 $pgdbh->do("CREATE temporary TABLE distnames$i AS
132 ( SELECT DISTINCT dist, version FROM cpanstats
135 AND ( tester <> 'DCOLLINS\@cpan.org'
136 OR fulldate >= '201606230000'
137 OR fulldate <= '201606200000' )
138 ) ", undef, $perl2) or die;
139 my $sth1 = $pgdbh->prepare("select dist, version from distnames$i");
144 perls
=> [ $perl1, $perl2 ],
146 totalrcdists
=> $totalrcdists
149 my $ts = POSIX
::strftime
"%FT%T", gmtime(time);
154 my $rows = $sth1->rows;
156 while (my($dist,$version) = $sth1->fetchrow_array) {
158 $sth2->execute($dist,$version,$perl1,$perl2);
160 my %seen = (pass
=> 0, fail
=> 0);
161 while (my($perl,$state,$count) = $sth2->fetchrow_array) {
162 $s->{$perl}{$state} = $count;
165 warn "calculated $i/$rows\n";
167 if ($seen{fail
} == 2 and $seen{pass
} == 0) {
170 if ($seen{fail
} == 2 and $seen{pass
} == 2) {
173 store
($dist,$version,$s,$S,$ts,$perl1,$perl2,$i,$rows,$ignore);
174 warn "wrote $i/$rows\n";
180 my($S, $dist, $version, $s, $ts, $row_i, $rows_total, $perl1, $perl2) = @_;
181 $S->{"!CAND"}{$dist}{$version} = $s;
182 my $outfile = "/home/andreas/var/beforemaintrelease/result-$ts";
184 open my $fh, ">", "$outfile.new" or die;
185 print {$fh} $jsonxs->encode($S);
187 rename "$outfile.new", "$outfile.json" or die "Could not rename: $!";
190 open my $fh, ">", "$outfile.new" or die;
191 for my $k (sort keys %{$S->{"!CAND"}}){ # $k='Date-Formatter'
192 for my $k2 (sort keys %{$S->{"!CAND"}{$k}}){ # $k2='0.11'
193 my $v = $S->{"!CAND"}{$k}{$k2};
194 no warnings
'uninitialized';
195 printf {$fh} "%3d/%d %-56s %3d %3d %3d %3d\n",
198 $v->{$perl1}{pass
}, $v->{$perl1}{fail
},
199 $v->{$perl2}{pass
}, $v->{$perl2}{fail
};
203 rename "$outfile.new", "$outfile.txt" or die "Could not rename: $!";
208 my($dist,$version,$s,$S,$ts,$perl1,$perl2,$row_i,$rows_total,$ignore) = @_;
210 write_new_line
($S, $dist, $version, $s, $ts, $row_i, $rows_total, $perl1, $perl2);
212 if ($row_i == $rows_total) {
214 my $overviewfile = "/home/andreas/var/beforemaintrelease/overview.json";
216 until ($lfh = lockfilehandle
($overviewfile)) {
219 my $slurp = do { local $/; <$lfh> };
221 my $O = $jsonxs->decode($slurp);
222 $O->{join ":", $perl1, $perl2} = $ts;
224 print {$lfh} $jsonxs->canonical->encode($O);
225 truncate $lfh, tell $lfh;
226 close $lfh or die "Could not close '$overviewfile': $!";
233 use File
::Basename
();
235 File
::Path
::mkpath File
::Basename
::dirname
$lockfile;
237 unless (open $lfh, "+<", $lockfile) {
238 unless ( open $lfh, ">>", $lockfile ) {
239 die "ALERT: Could not open >> '$lockfile': $!";
241 unless ( open $lfh, "+<", $lockfile ) {
242 die "ALERT: Could not open +< '$lockfile': $!";
245 if (flock $lfh, Fcntl
::LOCK_EX
|Fcntl
::LOCK_NB
) {
246 # print "Info[$$]: Got the lock, continuing";
249 # print "FATAL[$$]: lockfile '$lockfile' locked by a different process";
256 # cperl-indent-level: 4