Files
kensanata.oddmuse/modules/module-bisect.pl
2016-06-19 11:55:58 +02:00

141 lines
5.4 KiB
Perl

# Copyright (C) 2014 Alex-Daniel Jakimenko <alex.jakimenko@gmail.com>
#
# This program is free software: you can redistribute it and/or modify it under
# the terms of the GNU General Public License as published by the Free Software
# Foundation, either version 3 of the License, or (at your option) any later
# version.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along with
# this program. If not, see <http://www.gnu.org/licenses/>.
use strict;
use v5.10;
use File::Basename;
use File::Copy;
AddModuleDescription('module-bisect.pl', 'Module Bisect Extension');
our ($q, @MyAdminCode, %Action, $ModuleDir);
push(@MyAdminCode, \&ModuleBisectMenu);
$Action{bisect} = \&BisectAction;
sub ModuleBisectMenu {
return unless UserIsAdmin();
my ($id, $menuref, $restref) = @_;
push(@$menuref, ScriptLink('action=bisect', T('Bisect modules'), 'modulebisect'));
}
sub BisectAction {
UserIsAdminOrError();
RequestLockOrError();
print GetHeader('', T('Module Bisect'), '', 'nocache');
if (GetParam('stop')) {
BisectEnableAll(1);
print $q->br(), $q->strong(T('All modules enabled now!'));
print GetFormStart(undef, 'get', 'bisect');
print GetHiddenValue('action', 'bisect');
print $q->submit(-name=>'noop', -value=>T('Go back'));
print $q->end_form();
} elsif (GetParam('good') or GetParam('bad')) {
BisectProcess(GetParam('good'));
} else {
BisectInitialScreen();
}
PrintFooter();
ReleaseLock();
}
sub BisectInitialScreen {
print GetFormStart(undef, 'get', 'bisect');
print GetHiddenValue('action', 'bisect');
my @disabledFiles = Glob("$ModuleDir/*.p[ml].disabled");
if (@disabledFiles == 0) {
print T('Test / Always enabled / Always disabled'), $q->br();
my @files = Glob("$ModuleDir/*.p[ml]");
for (my $i = 0; $i < @files; $i++) {
my $moduleName = fileparse($files[$i]);
my @disabled = ($moduleName eq 'module-bisect.pl' ? (-disabled=>'disabled') : ());
print $q->input({-type=>'radio', -name=>"m$i", -value=>'t', ($moduleName ne 'module-bisect.pl' ? (-checked=>'checked') : ()), @disabled});
print $q->input({-type=>'radio', -name=>"m$i", -value=>'on', ($moduleName eq 'module-bisect.pl' ? (-checked=>'checked') : ())});
print $q->input({-type=>'radio', -name=>"m$i", -value=>'off', @disabled});
print $moduleName, $q->br();
}
print $q->submit(-name=>'bad', -value=>T('Start'));
} else {
print T('Bisecting proccess is already active.'), $q->br();
print $q->submit(-name=>'stop', -value=>T('Stop'));
}
print $q->end_form();
}
sub BisectProcess {
my ($isGood) = @_;
my $parameterHandover = '';
BisectEnableAll();
my @files = Glob("$ModuleDir/*.p[ml]");
for (my $i = @files - 1; $i >= 0; $i--) { # handle user choices
if (GetParam("m$i") eq 'on') {
$parameterHandover .= GetHiddenValue("m$i", GetParam("m$i"));
splice @files, $i, 1;
} elsif (GetParam("m$i") eq 'off') {
$parameterHandover .= GetHiddenValue("m$i", GetParam("m$i"));
move($files[$i], $files[$i] . '.disabled');
splice @files, $i, 1;
}
}
my $start = GetParam('start', 1) - 1; # $start and $end are indexes
my $end = GetParam('end', @files * 2) - 1;
if ($end - $start <= 1) {
print Ts('It seems like module %s is causing your problem.',
$q->strong((fileparse($isGood ? $files[$end] : $files[$start]))[0])), $q->br(), $q->br();
print T('Please note that this module does not handle situations when your problem is caused by a combination of specific modules (which is rare anyway).'), $q->br();
print T('Good luck fixing your problem! ;)');
print GetFormStart(undef, 'get', 'bisect');
print GetHiddenValue('action', 'bisect');
print $q->submit(-name=>'stop', -value=>T('Stop'));
print $q->end_form();
return;
}
print T('Module count (only testable modules):'), ' ', $q->strong(scalar @files), $q->br();
print $q->br(), T('Current module statuses:'), $q->br();
my $halfsize = ($end - $start + 1) / 2.0; # + 1 because it is count
$end -= int($halfsize) unless $isGood;
$start += int($halfsize + 0.51) if $isGood; # ceil
$halfsize = ($end - $start + 1) / 2.0;
for (my $i = 0; $i < @files; $i++) {
if ($i >= $start and $i <= $end - int($halfsize)) {
print $q->strong('> + '), (fileparse($files[$i]))[0], $q->br();
} elsif ($i >= $start and $i <= $end) {
print $q->strong('> - '), (fileparse($files[$i]))[0], $q->br();
move($files[$i], $files[$i] . '.disabled');
} else {
print $q->strong('- '), (fileparse($files[$i]))[0], $q->br();
move($files[$i], $files[$i] . '.disabled');
}
}
print GetFormStart(undef, 'get', 'bisect');
print GetHiddenValue('action', 'bisect');
print GetHiddenValue('start', $start + 1);
print GetHiddenValue('end', $end + 1);
print $parameterHandover;
print $q->submit(-name=>'good', -value=>T('Good')), ' ';
print $q->submit(-name=>'bad', -value=>T('Bad')), ' ';
print $q->submit(-name=>'stop', -value=>T('Stop'));
print $q->end_form();
}
sub BisectEnableAll {
for (Glob("$ModuleDir/*.p[ml].disabled")) { # reenable all modules
my $oldName = $_;
s/\.disabled$//;
print Ts('Enabling %s', (fileparse($_))[0]), '...', $q->br() if $_[0];
move($oldName, $_);
}
}