can't find package sak::animate
while executing
"package require sak::animate"
(in namespace eval "::request" script line 6)
invoked from within
"namespace eval ::request $script"
("::try" body line 12)
OUTPUT BUFFER:
# -*- tcl -*-
# (C) 2008 Andreas Kupries
##
# ###
package require sak::animate
package require sak::feedback
package require sak::color
getpackage textutil::repeat textutil/repeat.tcl
getpackage interp interp/interp.tcl
namespace eval ::sak::validate::testsuites {
namespace import ::textutil::repeat::blank
namespace import ::sak::color::*
namespace import ::sak::feedback::!
namespace import ::sak::feedback::>>
namespace import ::sak::feedback::+=
namespace import ::sak::feedback::=
namespace import ::sak::feedback::=|
namespace import ::sak::feedback::log
namespace import ::sak::feedback::summary
rename summary sum
}
# ###
proc ::sak::validate::testsuites {modules mode stem tclv} {
testsuites::run $modules $mode $stem $tclv
testsuites::summary
return
}
proc ::sak::validate::testsuites::run {modules mode stem tclv} {
sak::feedback::init $mode $stem
sak::feedback::first log "\[ Testsuites \] =================================================="
sak::feedback::first unc "\[ Testsuites \] =================================================="
sak::feedback::first fail "\[ Testsuites \] =================================================="
sak::feedback::first miss "\[ Testsuites \] =================================================="
sak::feedback::first none "\[ Testsuites \] =================================================="
# Preprocessing of module names to allow better formatting of the
# progress output, i.e. vertically aligned columns
# Per module we can distinguish the following levels of
# testsuite completeness:
# - No package has a testsuite
# - Some, but not all packages have a testsuite
# - All packages have a testsuite.
#
# Validity of the testsuites is not done here. It requires
# execution, see 'sak test run ...'.
# Progress report per module: Packages it is working on.
# Summary at module level:
# - Number of packages, number of packages with testsuites,
# Full log:
# - Lists packages without testsuites.
# Global preparation: Pull information about all packages and the
# modules they belong to.
Setup
Count $modules
MapPackages
InitCounters
foreach m $modules {
# Skip tcllibc shared library, not a module.
if {[string equal $m tcllibc]} continue
InitModuleCounters
!
log "@@ Module $m"
Head $m
# Per module: Find all testsuites in the module and process
# them. We determine the package(s) they may belong to.
# Per package: Have they .test files claiming them? After
# that, are .test files left over (i.e. without a package)?
ProcessTestsuites $m
ProcessPackages $m
ProcessUnclaimed
ModuleSummary
}
Shutdown
return
}
proc ::sak::validate::testsuites::summary {} {
Summary
return
}
# ###
proc ::sak::validate::testsuites::ProcessTestsuites {m} {
!claims
foreach f [glob -nocomplain [file join [At $m] *.test]] {
ProcessTestsuite $f
}
return
}
proc ::sak::validate::testsuites::ProcessTestsuite {f} {
variable testing
=file $f
if {[catch {
Scan [get_input $f]
} msg]} {
+e $msg
} else {
foreach p $testing { +claim $p }
}
return
}
proc ::sak::validate::testsuites::Setup {} {
variable ip [interp create]
# Make it mostly empty (We keep the 'set' command).
foreach n [interp eval $ip [list ::namespace children ::]] {
if {[string equal $n ::tcl]} continue
interp eval $ip [list namespace delete $n]
}
foreach c [interp eval $ip [list ::info commands]] {
if {[string equal $c set]} continue
if {[string equal $c if]} continue
if {[string equal $c rename]} continue
if {[string equal $c namespace]} continue
interp eval $ip [list ::rename $c {}]
}
if {![package vsatisfies [package present Tcl] 8.6]} {
interp eval $ip [list ::namespace delete ::tcl]
}
interp eval $ip [list ::rename namespace {}]
interp eval $ip [list ::rename rename {}]
foreach m {
testing unknown useLocal useLocalKeep useAccel
} {
interp alias $ip $m {} ::sak::validate::testsuites::Process/$m $ip
}
return
}
proc ::sak::validate::testsuites::Shutdown {} {
variable ip
interp delete $ip
return
}
proc ::sak::validate::testsuites::Scan {data} {
variable ip
while {1} {
if {[catch {
$ip eval $data
} msg]} {
if {[string match {can't read "*": no such variable} $msg]} {
regexp {can't read "(.*)": no such variable} $msg -> var
log "@@ + variable \"$var\""
$ip eval [list set $var {}]
continue
}
return -code error $msg
}
break
}
return
}
proc ::sak::validate::testsuites::Process/useTcllibC {ip args} {
return 0
}
proc ::sak::validate::testsuites::Process/unknown {ip args} {
return 0
}
proc ::sak::validate::testsuites::Process/testing {ip script} {
variable testing {}
$ip eval $script
return -code return
}
proc ::sak::validate::testsuites::Process/useLocal {ip f p args} {
variable testing
lappend testing $p
return
}
proc ::sak::validate::testsuites::Process/useLocalKeep {ip f p args} {
variable testing
lappend testing $p
return
}
proc ::sak::validate::testsuites::Process/useAccel {ip _ f p} {
variable testing
lappend testing $p
return
}
proc ::sak::validate::testsuites::ProcessPackages {m} {
!used
if {![HasPackages $m]} return
foreach p [ThePackages $m] {
+pkg $p
if {[claimants $p]} {
+tests $p
} else {
notests $p
}
}
return
}
proc ::sak::validate::testsuites::ProcessUnclaimed {} {
variable claims
if {![array size claims]} return
foreach p [lsort -dict [array names claims]] {
foreach fx $claims($p) { +u $fx }
}
return
}
###
proc ::sak::validate::testsuites::=file {f} {
variable current [file tail $f]
= "$current ..."
return
}
###
proc ::sak::validate::testsuites::!claims {} {
variable claims
array unset claims *
return
}
proc ::sak::validate::testsuites::+claim {pkg} {
variable current
variable claims
lappend claims($pkg) $current
return
}
proc ::sak::validate::testsuites::claimants {pkg} {
variable claims
expr { [info exists claims($pkg)] && [llength $claims($pkg)] }
}
###
proc ::sak::validate::testsuites::!used {} {
variable used
array unset used *
return
}
proc ::sak::validate::testsuites::+use {pkg} {
variable used
variable claims
foreach fx $claims($pkg) { set used($fx) . }
unset claims($pkg)
return
}
###
proc ::sak::validate::testsuites::MapPackages {} {
variable pkg
array unset pkg *
!
+= Package
foreach {pname pdata} [ipackages] {
= "$pname ..."
foreach {pver pmodule} $pdata break
lappend pkg($pmodule) $pname
}
!
=| {Packages mapped ...}
return
}
proc ::sak::validate::testsuites::HasPackages {m} {
variable pkg
expr { [info exists pkg($m)] && [llength $pkg($m)] }
}
proc ::sak::validate::testsuites::ThePackages {m} {
variable pkg
return [lsort -dict $pkg($m)]
}
###
proc ::sak::validate::testsuites::+pkg {pkg} {
variable mtotal ; incr mtotal
variable total ; incr total
return
}
proc ::sak::validate::testsuites::+tests {pkg} {
variable mhavetests ; incr mhavetests
variable havetests ; incr havetests
= "$pkg Ok"
+use $pkg
return
}
proc ::sak::validate::testsuites::notests {pkg} {
= "$pkg Bad"
log "@@ WARN No testsuite: $pkg"
return
}
###
proc ::sak::validate::testsuites::+e {msg} {
variable merrors ; incr merrors
variable errors ; incr errors
variable current
log "@@ ERROR $current $msg"
return
}
proc ::sak::validate::testsuites::+u {f} {
variable used
if {[info exists used($f)]} return
variable munclaimed ; incr munclaimed
variable unclaimed ; incr unclaimed
set used($f) .
log "@@ NOTE Unclaimed testsuite $f"
return
}
###
proc ::sak::validate::testsuites::Count {modules} {
variable maxml 0
!
foreach m [linsert $modules 0 Module] {
= "M $m"
set l [string length $m]
if {$l > $maxml} {set maxml $l}
}
=| "Validate testsuites (existence) ..."
return
}
proc ::sak::validate::testsuites::Head {m} {
variable maxml
+= ${m}[blank [expr {$maxml - [string length $m]}]]
return
}
###
proc ::sak::validate::testsuites::InitModuleCounters {} {
variable mtotal 0
variable mhavetests 0
variable munclaimed 0
variable merrors 0
return
}
proc ::sak::validate::testsuites::ModuleSummary {} {
variable mtotal
variable mhavetests
variable munclaimed
variable merrors
set complete [F $mhavetests]/[F $mtotal]
set not "! [F [expr {$mtotal - $mhavetests}]]"
set err "E [F $merrors]"
set unc "U [F $munclaimed]"
if {$munclaimed} {
set unc [=cya $unc]
>> unc
}
if {!$mhavetests && $mtotal} {
set complete [=red $complete]
set not [=red $not]
>> none
} elseif {$mhavetests < $mtotal} {
set complete [=yel $complete]
set not [=yel $not]
>> miss
}
if {$merrors} {
set err [red]$err[rst]
>> fail
}
=| "~~ $complete $not $unc $err"
return
}
###
proc ::sak::validate::testsuites::InitCounters {} {
variable total 0
variable havetests 0
variable unclaimed 0
variable errors 0
return
}
proc ::sak::validate::testsuites::Summary {} {
variable total
variable havetests
variable unclaimed
variable errors
set tot [F $total]
set tst [F $havetests]
set uts [F [expr {$total - $havetests}]]
set unc [F $unclaimed]
set per [format %6.2f [expr {$havetests*100./$total}]]
set uper [format %6.2f [expr {($total - $havetests)*100./$total}]]
set err [F $errors]
if {$errors} { set err [=red $err] }
if {$unclaimed} { set unc [=cya $unc] }
if {!$havetests && $total} {
set tst [=red $tst]
set uts [=red $uts]
} elseif {$havetests < $total} {
set tst [=yel $tst]
set uts [=yel $uts]
}
sum ""
sum "Testsuite statistics"
sum "#Packages: $tot"
sum "#Tested: $tst (${per}%)"
sum "#Untested: $uts (${uper}%)"
sum "#Unclaimed: $unc"
sum "#Errors: $err"
return
}
###
proc ::sak::validate::testsuites::F {n} { format %6d $n }
###
proc ::sak::validate::testsuites::At {m} {
global distribution
return [file join $distribution modules $m]
}
# ###
namespace eval ::sak::validate::testsuites {
# Max length of module names and patchlevel information.
variable maxml 0
# Counters across all modules
variable total 0 ; # Number of packages overall.
variable havetests 0 ; # Number of packages with testsuites.
variable unclaimed 0 ; # Number of testsuites not claimed by a specific package.
variable errors 0 ; # Number of errors found with all testsuites.
# Same counters, per module.
variable mtotal 0
variable mhavetests 0
variable munclaimed 0
variable merrors 0
# Name of currently processed testsuite
variable current ""
# Map from packages to files claiming to test them.
variable claims
array set claims {}
# Set of files taken by packages, as array
variable used
array set used {}
# Map from modules to packages contained in them
variable pkg
array set pkg {}
# Transient storage used while collecting packages per testsuite.
variable testing {}
variable ip {}
}
##
# ###
package provide sak::validate::testsuites 1.0