Skip to content

Commit 998ae02

Browse files
committed
Perl 6 rewrite of bisectable
Everything looks fine. It does segfault sometimes, but it is most likely not our fault.
1 parent 1c58482 commit 998ae02

File tree

1 file changed

+163
-0
lines changed

1 file changed

+163
-0
lines changed

Bisectable.p6

Lines changed: 163 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,163 @@
1+
#!/usr/bin/env perl6
2+
# Copyright © 2016
3+
# Aleks-Daniel Jakimenko-Aleksejev <alex.jakimenko@gmail.com>
4+
# Daniel Green <ddgreen@gmail.com>
5+
#
6+
# This program is free software: you can redistribute it and/or modify
7+
# it under the terms of the GNU Affero General Public License as published by
8+
# the Free Software Foundation, either version 3 of the License, or
9+
# (at your option) any later version.
10+
#
11+
# This program is distributed in the hope that it will be useful,
12+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
13+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+
# GNU Affero General Public License for more details.
15+
#
16+
# You should have received a copy of the GNU Affero General Public License
17+
# along with this program. If not, see <http://www.gnu.org/licenses/>.
18+
19+
use lib .;
20+
use Whateverable;
21+
22+
use File::Temp;
23+
use IRC::Client;
24+
25+
unit class Bisectable is Whateverable;
26+
27+
constant LINK = https://github.com/rakudo/rakudo/commit;
28+
constant COMMIT-TESTER = ./test-commit.IO.absolute;
29+
constant BUILD-LOCK = ./lock.IO.absolute;
30+
31+
method help($message) {
32+
~ Like this: {$message.server.current-nick}
33+
~ : good=2015.12 bad=HEAD exit 1 if (^∞).grep({ last })[5] // 0 == 4 # RT128181
34+
}
35+
36+
my regex spaceeq { \s* ‘=’ \s* | \s+ }
37+
my regex bisect-cmd {
38+
^ \s*
39+
[
40+
[ good <spaceeq> $<good>=\S+ \s* ]
41+
[ bad <spaceeq> $<bad> =\S+ \s* ]?
42+
|
43+
[ bad <spaceeq> $<bad> =\S+ \s* ]?
44+
[ good <spaceeq> $<good>=\S+ \s* ]?
45+
]
46+
$<code>=.*
47+
$
48+
}
49+
50+
multi method irc-to-me($message where { .text !~~ /^ [help|source|url] ‘?’? $/
51+
# ↑ stupid, I know. See RT #123577
52+
and .text ~~ &bisect-cmd}) {
53+
my $value = self.process($message, ~$<code>,
54+
~($<good> // 2015.12), ~($<bad> // HEAD));
55+
return ResponseStr.new(:$value, :$message);
56+
}
57+
58+
method process($message, $code is copy, $good, $bad) {
59+
my ($succeeded, $code-response) = self.process-code($code, $message);
60+
return $code-response unless $succeeded;
61+
$code = $code-response;
62+
63+
# convert to real ids so we can look up the builds
64+
my $full-good = self.to-full-commit($good);
65+
return Cannot find ‘good’ revision unless defined $full-good;
66+
67+
if {BUILDS}/$full-good/bin/perl6.IO !~~ :e {
68+
if BUILD-LOCK.IO ~~ :e {
69+
# TODO make it possible to use bisectable while it is building something
70+
return No build for ‘good’ revision. Right now the build process is in action, please try again later or specify some older ‘good’ commit (e.g., good=HEAD~10);
71+
}
72+
return No build for ‘good’ revision;
73+
}
74+
75+
my $full-bad = self.to-full-commit($bad);
76+
my $short-bad = substr($bad eq HEAD ?? $full-bad !! $bad, 0, 7);
77+
return Cannot find ‘bad’ revision unless defined $full-bad;
78+
79+
if {BUILDS}/$full-bad/bin/perl6.IO !~~ :e {
80+
if BUILD-LOCK.IO ~~ :e {
81+
# TODO make it possible to use bisectable while it is building something
82+
return No build for ‘bad’ revision. Right now the build process is in action, please try again later or specify some older ‘bad’ commit (e.g., bad=HEAD~40);
83+
}
84+
return No build for ‘bad’ revision;
85+
}
86+
87+
my $filename = self.write-code($code);
88+
89+
my $old-dir = $*CWD;
90+
chdir RAKUDO;
91+
my ($out-good, $exit-good, $signal-good, $time-good) = self.get-output({BUILDS}/$full-good/bin/perl6, $filename);
92+
my ($out-bad, $exit-bad, $signal-bad, $time-bad) = self.get-output({BUILDS}/$full-bad/bin/perl6, $filename);
93+
chdir $old-dir;
94+
$out-good //= ;
95+
$out-bad //= ;
96+
97+
if $exit-good == $exit-bad and $out-good eq $out-bad {
98+
$message.reply: On both starting points (good=$good bad=$short-bad) the exit code is $exit-bad and the output is identical as well;
99+
return Output on both points: $out-good; # will be gisted automatically if required
100+
}
101+
my $output-file = ;
102+
if $exit-good == $exit-bad {
103+
$message.reply: Exit code is $exit-bad on both starting points (good=$good bad=$short-bad), bisecting by using the output;
104+
($output-file, my $fh) = tempfile :unlink;
105+
$fh.print: $out-good;
106+
$fh.close;
107+
}
108+
if $exit-good != $exit-bad and $exit-good != 0 {
109+
$message.reply: For the given starting points (good=$good bad=$short-bad), exit code on a ‘good’ revision is $exit-good (which is bad), bisecting with inverted logic;
110+
}
111+
112+
my $dir = tempdir :unlink;
113+
run(git, clone, RAKUDO, $dir);
114+
chdir($dir);
115+
116+
self.get-output(git, bisect, start);
117+
self.get-output(git, bisect, good, $full-good);
118+
my ($init-output, $init-status) = self.get-output(git, bisect, bad, $full-bad);
119+
if $init-status != 0 {
120+
chdir($old-dir);
121+
$message.reply: bisect log: ~ self.upload({ query => $message.text,
122+
result => $init-output });
123+
return bisect init failure;
124+
}
125+
my ($bisect-output, $bisect-status);
126+
if $output-file {
127+
($bisect-output, $bisect-status) = self.get-output(git, bisect, run,
128+
COMMIT-TESTER, BUILDS, $filename, $output-file);
129+
} else {
130+
if $exit-good == 0 {
131+
($bisect-output, $bisect-status) = self.get-output(git, bisect, run,
132+
COMMIT-TESTER, BUILDS, $filename);
133+
} else {
134+
($bisect-output, $bisect-status) = self.get-output(git, bisect, run,
135+
COMMIT-TESTER, BUILDS, $filename, $exit-good);
136+
}
137+
}
138+
$message.reply: bisect log: ~ self.upload({ query => $message.text,
139+
result => $init-output\n$bisect-output });
140+
if $bisect-status != 0 {
141+
chdir($old-dir);
142+
return ‘bisect run’ failure;
143+
}
144+
my ($result) = self.get-output(git, show, --quiet, --date=short, --pretty=(%cd) {LINK}/%h, bisect/bad);
145+
chdir($old-dir);
146+
return $result;
147+
}
148+
149+
my $plugin = Bisectable.new;
150+
my $nick = bisectable6;
151+
152+
.run with IRC::Client.new(
153+
:$nick
154+
:userreal($nick.tc)
155+
:username($nick.tc)
156+
:host<irc.freenode.net>
157+
:channels(%*ENV<DEBUGGABLE> ?? <#whateverable> !! <#perl6 #perl6-dev>)
158+
:debug(?%*ENV<DEBUGGABLE>)
159+
:plugins($plugin)
160+
:filters( -> |c { $plugin.filter(|c) } )
161+
);
162+
163+
# vim: expandtab shiftwidth=4 ft=perl6

0 commit comments

Comments
 (0)