-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathautoreducebuild
executable file
·72 lines (67 loc) · 1.85 KB
/
autoreducebuild
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
#!/usr/bin/perl -w
# helper for autoreduce
# to drops lines as long as the code still builds and remains unreproducible
# exit codes:
# 0 FTBR / unreproducible - was OK to drop
# 1 FTBFS / broken build
# 2 reproducible
# expects build to produce one md5sum-like line on stdout and no stderr
# expects reproducible builds to produce the same stdout every time
use strict;
use IO::Pipe;
use IO::Select;
our $loops = 5;
our $debug = 0;
our $info = 1;
if(!@ARGV) {
die "usage: $0 BUILDCMD\n"
}
sub diag($)
{
print STDERR "info: ", @_, "\n" if $info;
}
my $prevresult;
for(1..$loops) {
my $outpipe = IO::Pipe->new();
my $errpipe = IO::Pipe->new();
my $pid = fork();
if($pid == 0) { # child
$outpipe->writer();
$errpipe->writer();
open(STDOUT, ">&", $outpipe) or die;
open(STDERR, ">&", $errpipe) or die;
exec(@ARGV);
} elsif ($pid > 0) { # parent
$outpipe->reader();
$errpipe->reader();
my $s = IO::Select->new($outpipe, $errpipe);
my @ready = $s->can_read();
foreach my $fh (@ready) {
if($fh == $errpipe) {
my @lines=<$errpipe>;
next unless @lines;
diag "FTBFS: build failed with @lines" if $debug;
exit 1; # FTBFS
} elsif($fh == $outpipe) {
my $line = <$fh>;
chomp $line;
$prevresult//=$line;
diag "debug: built with result $line";
if($prevresult ne $line) {
diag "build was unreproducible";
exit 0; # FTBR
}
} else {
die "unexpected"
}
}
waitpid($pid, 0);
if($?) {
exit 1; # FTBFS
}
} else {
die "fork failed";
}
}
diag "build was reproducible";
exit 2;