Files
modules/script/mtreview
2022-09-01 06:43:38 +02:00

211 lines
6.1 KiB
Tcl
Executable File

#!/usr/bin/env tclsh
#
# MTREVIEW, review test suite log file
# Copyright (C) 2019-2022 Xavier Delaruelle
#
# 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 2 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/>.
##########################################################################
proc reportUsage {} {
puts "Usage: $::argv0 \[options\] testlogfile
Review test suite log file
Options:
-h, --help Show this help message and exit
Examples:
$::argv0 modules.log
$::argv0 install.log
$::argv0 lint.log"
}
proc sgr {sgrcode str} {
return "\033\[${sgrcode}m$str\033\[0m"
}
proc reportError {str} {
puts "[sgr {1;31} ERROR]: $str"
}
proc diffWithIcdiff {} {
if {![info exists ::diff_with_icdiff]} {
# use local installation of icdiff, check it operates correctly
set ::diff_with_icdiff [expr {[auto_execok ./icdiff] ne\
{} && ![catch {exec ./icdiff --version}]}]
}
return $::diff_with_icdiff
}
proc diffWithDiff {} {
if {![info exists ::diff_with_diff]} {
set ::diff_with_diff [expr {[auto_execok diff] ne {}}]
}
return $::diff_with_diff
}
proc getDiffCommand {} {
# preferably use icdiff if possible
if {[diffWithIcdiff]} {
set cmdlist [list ./icdiff --no-headers]
# force term size on the different CI environments
if {[info exists ::env(GITHUB_ACTIONS)]} {
lappend cmdlist --cols=170
} elseif {[info exists ::env(CIRRUS_CI)]} {
lappend cmdlist --cols=150
}
} else {
set cmdlist [list diff -u]
if {![catch {exec diff --color=auto /dev/null /dev/null}]} {
lappend cmdlist --color=auto
}
}
return $cmdlist
}
# parse arguments
set hintmsg "\n Try '$argv0 --help' for more information."
if {$argc != 1} {
reportError "Unexpected number of arguments$hintmsg"
exit 1
}
set arg [lindex $argv 0]
switch -glob -- $arg {
-h - --help {
reportUsage
exit 0
}
-* {
reportError "Invalid option '$arg'$hintmsg"
exit 1
}
default {
set logfile $arg
}
}
set fid [open $logfile r]
set state {}
while {[gets $fid line] >= 0} {
switch -- $state {
recres {
##nagelfar ignore Unknown variable
if {$res ne {}} {
append res \n
} else {
# trim first line
set line [string range $line [string first ' $line] end]
}
append res $line
# end of obtained output?
if {[string range $line end-2 end] eq {'#>}} {
set state recexp
# clean content
set res [string range $res 1 end-3]
}
}
recexp {
##nagelfar ignore Unknown variable
if {$exp ne {}} {
append exp \n
} else {
# trim first line
set line [string range $line [string first ' $line] end]
}
append exp $line
# end of expected output?
if {[string range $line end-2 end] eq {'#>}} {
# clean expecting content from regexp special char escaping
set trimstart 1
set trimend 3
if {[string index $exp 1] eq {^}} {
incr trimstart
}
if {[string index $exp end-3] eq {$}} {
incr trimend
}
set exp [string range $exp $trimstart end-$trimend]
set exp [regsub -all {\\([\\"'$|{}`* ()!&])} $exp {\1}]
# diff obtained and expecting output
if {![info exists externaldiff]} {
set externaldiff [expr {[diffWithIcdiff] || [diffWithDiff]}]
}
# use an external command to diff output
if {$externaldiff} {
if {![info exists diffcmdlist]} {
set diffcmdlist [getDiffCommand]
}
set fidres [open mtreview_res w]
puts $fidres $res
close $fidres
set fidexp [open mtreview_exp w]
puts $fidexp $exp
close $fidexp
if {[set errCode [catch {
eval exec >@stdout $diffcmdlist mtreview_exp mtreview_res
} errMsg]]} {
# report trouble of diff command
if {[diffWithDiff] && $errCode == 2} {
puts "[sgr {1;31} ERROR]: $errMsg"
}
}
file delete mtreview_exp mtreview_res
} else {
puts [sgr {1;31} $exp]
puts --
puts [sgr {1;32} $res]
}
# clear state to search for next failed test
set state {}
}
}
sumup {
if {[string index $line 0] eq "#"} {
puts $line
}
}
default {
if {![string compare -length 6 $line {FAIL: }]} {
if {![info exists failure_found]} {
set failure_found 1
}
set state recres
set res {}
set exp {}
##nagelfar ignore #3 Unknown variable
if {![info exists testfile_printed($testfile)]} {
set testfile_printed($testfile) 1
puts [sgr {1;34;7} "=== $testfile ==="]
}
puts [sgr 7 $line]
} elseif {![string compare -length 8 $line {Running }]} {
set testfile [lindex [split $line] 1]
} elseif {[string match {*Summary ===} $line]} {
set state sumup
puts [sgr {1;33;7} {=== test summary ===}]
}
}
}
}
close $fid
exit [info exists failure_found]
# vim:set tabstop=3 shiftwidth=3 expandtab autoindent syntax=tcl: