summaryrefslogtreecommitdiffstats
path: root/tcllib/support/devel/sak/validate/versions.tcl
diff options
context:
space:
mode:
Diffstat (limited to 'tcllib/support/devel/sak/validate/versions.tcl')
-rw-r--r--tcllib/support/devel/sak/validate/versions.tcl258
1 files changed, 258 insertions, 0 deletions
diff --git a/tcllib/support/devel/sak/validate/versions.tcl b/tcllib/support/devel/sak/validate/versions.tcl
new file mode 100644
index 0000000..4d622ae
--- /dev/null
+++ b/tcllib/support/devel/sak/validate/versions.tcl
@@ -0,0 +1,258 @@
+# -*- tcl -*-
+# (C) 2008 Andreas Kupries <andreas_kupries@users.sourceforge.net>
+##
+# ###
+
+package require sak::animate
+package require sak::feedback
+package require sak::color
+
+getpackage textutil::repeat textutil/repeat.tcl
+getpackage interp interp/interp.tcl
+getpackage struct::set struct/sets.tcl
+getpackage struct::list struct/list.tcl
+
+namespace eval ::sak::validate::versions {
+ 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::versions {modules mode stem tclv} {
+ versions::run $modules $mode $stem $tclv
+ versions::summary
+ return
+}
+
+proc ::sak::validate::versions::run {modules mode stem tclv} {
+ sak::feedback::init $mode $stem
+ sak::feedback::first log "\[ Versions \] ===================================================="
+ sak::feedback::first warn "\[ Versions \] ===================================================="
+ sak::feedback::first fail "\[ Versions \] ===================================================="
+
+ # Preprocessing of module names to allow better formatting of the
+ # progress output, i.e. vertically aligned columns
+
+ # Per module
+ # - List modules without package index (error)
+ # - List packages provided missing from pkgIndex.tcl
+ # - List packages in the pkgIndex.tcl, but not provided.
+ # - List packages where provided and indexed versions differ.
+
+ 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
+
+ if {![llength [glob -nocomplain [file join [At $m] pkgIndex.tcl]]]} {
+ +e "No package index"
+ } else {
+ # Compare package provided to ifneeded.
+
+ struct::list assign \
+ [struct::set intersect3 [Indexed $m] [Provided $m]] \
+ compare only_indexed only_provided
+
+ foreach p [lsort -dict $only_indexed ] { +w "Indexed/No Provider: $p" }
+ foreach p [lsort -dict $only_provided] { +w "Provided/Not Indexed: $p" }
+
+ foreach p [lsort -dict $compare] {
+ set iv [IndexedVersions $m $p]
+ set pv [ProvidedVersions $m $p]
+ if {[struct::set equal $iv $pv]} continue
+
+ struct::list assign \
+ [struct::set intersect3 $pv $iv] \
+ __ pmi imp
+
+ +w "Indexed </> Provided: $p \[<$imp </> $pmi\]"
+ }
+ }
+ ModuleSummary
+ }
+ return
+}
+
+proc ::sak::validate::versions::summary {} {
+ Summary
+ return
+}
+
+# ###
+
+proc ::sak::validate::versions::MapPackages {} {
+ variable pkg
+ array unset pkg *
+
+ !
+ += Package
+ foreach {pname pdata} [ipackages] {
+ = "$pname ..."
+ foreach {pvlist pmodule} $pdata break
+ lappend pkg(mi,$pmodule) $pname
+ lappend pkg(vi,$pmodule,$pname) $pvlist
+
+ foreach {pname pvlist} [ppackages $pmodule] {
+ lappend pkg(mp,$pmodule) $pname
+ lappend pkg(vp,$pmodule,$pname) $pvlist
+ }
+ }
+ !
+ =| {Packages mapped ...}
+ return
+}
+
+proc ::sak::validate::versions::Provided {m} {
+ variable pkg
+ if {![info exists pkg(mp,$m)]} { return {} }
+ return [lsort -dict $pkg(mp,$m)]
+}
+
+proc ::sak::validate::versions::Indexed {m} {
+ variable pkg
+ if {![info exists pkg(mi,$m)]} { return {} }
+ return [lsort -dict $pkg(mi,$m)]
+}
+
+proc ::sak::validate::versions::ProvidedVersions {m p} {
+ variable pkg
+ return [lsort -dict $pkg(vp,$m,$p)]
+}
+
+proc ::sak::validate::versions::IndexedVersions {m p} {
+ variable pkg
+ return [lsort -dict $pkg(vi,$m,$p)]
+}
+
+###
+
+proc ::sak::validate::versions::+e {msg} {
+ variable merrors ; incr merrors
+ variable errors ; incr errors
+ log "@@ ERROR $msg"
+ return
+}
+
+proc ::sak::validate::versions::+w {msg} {
+ variable mwarnings ; incr mwarnings
+ variable warnings ; incr warnings
+ log "@@ WARN $msg"
+ return
+}
+
+proc ::sak::validate::versions::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 versions (indexed vs. provided) ..."
+ return
+}
+
+proc ::sak::validate::versions::Head {m} {
+ variable maxml
+ += ${m}[blank [expr {$maxml - [string length $m]}]]
+ return
+}
+
+###
+
+proc ::sak::validate::versions::InitModuleCounters {} {
+ variable merrors 0
+ variable mwarnings 0
+ return
+}
+
+proc ::sak::validate::versions::ModuleSummary {} {
+ variable merrors
+ variable mwarnings
+
+ set err "E [F $merrors]"
+ set wrn "W [F $mwarnings]"
+
+ if {$mwarnings} { set wrn [=yel $wrn] ; >> warn }
+ if {$merrors} { set err [=red $err] ; >> fail }
+
+ =| "~~ $err $wrn"
+ return
+}
+
+###
+
+proc ::sak::validate::versions::InitCounters {} {
+ variable errors 0
+ variable warnings 0
+ return
+}
+
+proc ::sak::validate::versions::Summary {} {
+ variable errors
+ variable warnings
+
+ set err [F $errors]
+ set wrn [F $warnings]
+
+ if {$errors} { set err [=red $err] }
+ if {$warnings} { set wrn [=yel $wrn] }
+
+ sum ""
+ sum "Versions statistics"
+ sum "#Errors: $err"
+ sum "#Warnings: $wrn"
+ return
+}
+
+###
+
+proc ::sak::validate::versions::F {n} { format %6d $n }
+
+###
+
+proc ::sak::validate::versions::At {m} {
+ global distribution
+ return [file join $distribution modules $m]
+}
+
+# ###
+
+namespace eval ::sak::validate::versions {
+ # Max length of module names and patchlevel information.
+ variable maxml 0
+
+ # Counters across all modules
+ variable errors 0 ; # Number of errors found (= modules without pkg index)
+ variable warnings 0 ; # Number of warings
+
+ # Same counters, per module.
+ variable merrors 0
+ variable mwarnings 0
+
+ # Map from modules to packages and their versions.
+ variable pkg
+ array set pkg {}
+}
+
+##
+# ###
+
+package provide sak::validate::versions 1.0