2014-10-31 04:09:33 +02:00
# 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/>.
2015-03-27 03:01:01 +02:00
use strict ;
2014-10-31 04:09:33 +02:00
use File::Basename ;
use File::Copy ;
2014-10-31 18:41:08 +02:00
AddModuleDescription ( 'module-bisect.pl' , 'Module Bisect Extension' ) ;
2014-10-31 04:09:33 +02:00
2015-04-10 13:31:28 +03:00
our ( $ q , @ MyAdminCode , % Action , $ ModuleDir ) ;
2015-03-27 03:01:01 +02:00
2014-10-31 18:41:08 +02:00
push ( @ MyAdminCode , \ & ModuleBisectMenu ) ;
2014-10-31 04:09:33 +02:00
$ Action { bisect } = \ & BisectAction ;
2014-10-31 18:41:08 +02:00
sub ModuleBisectMenu {
return unless UserIsAdmin ( ) ;
my ( $ id , $ menuref , $ restref ) = @ _ ;
push ( @$ menuref , ScriptLink ( 'action=bisect' , T ( 'Bisect modules' ) , 'modulebisect' ) ) ;
}
2014-10-31 04:09:33 +02:00
sub BisectAction {
UserIsAdminOrError ( ) ;
RequestLockOrError ( ) ;
2014-10-31 18:41:08 +02:00
print GetHeader ( '' , T ( 'Module Bisect' ) , '' , 'nocache' ) ;
2014-10-31 04:09:33 +02:00
if ( GetParam ( 'stop' ) ) {
BisectEnableAll ( 1 ) ;
print $ q - > br ( ) , $ q - > strong ( T ( 'All modules enabled now!' ) ) ;
print GetFormStart ( undef , 'get' , 'bisect' ) ;
print GetHiddenValue ( 'action' , 'bisect' ) ;
2014-10-31 18:41:08 +02:00
print $ q - > submit ( - name = > 'noop' , - value = > T ( 'Go back' ) ) ;
2014-10-31 04:09:33 +02:00
print $ q - > end_form ( ) ;
2014-10-31 18:41:08 +02:00
} elsif ( GetParam ( 'good' ) or GetParam ( 'bad' ) ) {
BisectProcess ( GetParam ( 'good' ) ) ;
} else {
BisectInitialScreen ( ) ;
2014-10-31 04:09:33 +02:00
}
PrintFooter ( ) ;
ReleaseLock ( ) ;
}
2014-10-31 18:41:08 +02:00
sub BisectInitialScreen {
print GetFormStart ( undef , 'get' , 'bisect' ) ;
print GetHiddenValue ( 'action' , 'bisect' ) ;
my @ disabledFiles = bsd_glob ( "$ModuleDir/*.p[ml].disabled" ) ;
if ( @ disabledFiles == 0 ) {
print T ( 'Test / Always enabled / Always disabled' ) , $ q - > br ( ) ;
my @ files = bsd_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 ( 'Biscecting proccess is already active.' ) , $ q - > br ( ) ;
print $ q - > submit ( - name = > 'stop' , - value = > T ( 'Stop' ) ) ;
}
print $ q - > end_form ( ) ;
}
2014-10-31 04:09:33 +02:00
sub BisectProcess {
my ( $ isGood ) = @ _ ;
my $ parameterHandover = '' ;
BisectEnableAll ( ) ;
my @ files = bsd_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 ;
}
}
2014-10-31 18:41:08 +02:00
my $ start = GetParam ( 'start' , 1 ) - 1 ; # $start and $end are indexes
my $ end = GetParam ( 'end' , @ files * 2 ) - 1 ;
2014-10-31 04:09:33 +02:00
if ( $ end - $ start <= 1 ) {
2014-10-31 18:41:08 +02:00
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! ;)' ) ;
2014-10-31 04:09:33 +02:00
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 ) ) {
2014-10-31 04:45:16 +02:00
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' ) ;
2014-10-31 04:09:33 +02:00
} 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 ( bsd_glob ( "$ModuleDir/*.p[ml].disabled" ) ) { # reenable all modules
my $ oldName = $ _ ;
s/\.disabled$// ;
2014-10-31 18:41:08 +02:00
print Ts ( 'Enabling %s' , ( fileparse ( $ _ ) ) [ 0 ] ) , '...' , $ q - > br ( ) if $ _ [ 0 ] ;
2014-10-31 04:09:33 +02:00
move ( $ oldName , $ _ ) ;
}
}