

package provide pist 1.0

# pist_requireAll -- cherche et installe la librairie pist 
# 
# Argument : 
# 
#  - appliName : nom du tableau à initialiser (i.e gred, stead, ...).
#    Par défaut ce tableau est "pist"
# 
# Description :
# 
#  Le fonction principale de cette procédure est de mémoriser le répertoire 
#  d'installation de la librairie PIST utilisée et de la rendre utilisable
#  par une appli.
#  Si la variable d'environnement PIST_SETUP est positionnée, elle est 
#  utilisée.
#  
#  Sinon, la librairie pist est recherchée successivement dans les 
#  répertopoires suivants :
#   ./pist ./lib/pist ../pist ../lib/pist ../../pist ../../lib/pist ...
#  
#  Il est possible de créer un lien "pist" dans un des répertoire recherché
#  La variable d'environnement PIST_SETUP est alors positionnée pour 
#  les process fils éventuels
# 
# Hypothese :
#  
#  Chaque répertoire contenant un package pist **doit** avoir le même nom que
#  le package lui-meme :
#  Le package "Comm" doit etre dans le répertoire "Comm/", et nom par 
#  "comm/" ni "Comm-3.7/"
#  
# 
# sortie : 
# 
#  positionnement des variables suivantes (pist ou appliName si spécifié) :
#   - pist(exe) : nom absolu (normalisé) de cet exécutable
#   - pist(pistsetup) et env(PIST_SETUP) : installation de PIST
#   - auto_path : insertion de pist(pistsetup) **devant** cette globale
# 
# 
proc pist_requireAll { {appliName pist} } {

global env auto_path
upvar #0 $appliName appli
   
    array set appli {
        exe         UNKNOWN
        pistsetup   UNKNOWN
    }
    
    # On normalise le nom de ce sript en suivant les liens ...
    # extrait de la proc "file:normalName"
    set name [info script]
    if {[file pathtype $name] == "relative"} {
       set name [file join [pwd] $name]
    }
    # One follows a possible link (which can be absolute or relative)
    while {[string match "link" [file type $name] ]} {
       set followName [file readlink $name]
       # If the name is relative: one make it absolute
       if {[file pathtype $followName] == "relative"} {
          set followName \
               [file join [file dirname $name] $followName]
       }
       set name $followName
    }
    # parent itself could be a link !
    set pwd_ori [pwd]
    cd [file dirname $name]
    set theDir [pwd]
    set name [file join $theDir [file tail $name]]
    cd $pwd_ori
    
    # Enfin, on mémorise le nom canonnique de ce script :
    set appli(exe) $name
    
    
    # Recherche de la librairie PIST
    if {[info exists env(PIST_SETUP)]} {
        set appli(pistsetup) $env(PIST_SETUP)
    } else {
        set direxe [file dir $appli(exe)]
        set dirsToScan [list                                      \
           $direxe                                                \
           [file dir $direxe]                                     \
           [file dir [file dir $direxe]]                          \
           [file dir [file dir [file dir $direxe]]]               \
           [file dir [file dir [file dir [file dir $direxe]]]]    \
        ]
        
        # On cherche dans ce répertoire s'il y a un un plusieurs nom
        # répertoire, mais aussi lien !) commençant par pist...
        foreach dir $dirsToScan {
           
           set pistDirs [glob -nocomplain [file join $dir pist]* ]
           if {[llength $pistDirs] == 0} {
               # avant de hurler, on cherche dans un sous répertoire "lib/"
               set pistDirs [glob -nocomplain [file join $dir lib pist]* ]
               if {[llength $pistDirs] == 0} {
                   continue
               }
           } 
           
           # S'il existe plusieurs lib potentielle au même niveau, 
           # (pist-1.9.a et pist-1.10.a), on doit sélectionner 
           # pist-1.10 (la plus ancienne)
           # 
           foreach name [lsort -decreasing -dictionary $pistDirs] {
              set pkgIndexes [glob -nocomplain  \
                            [file join $name * pkgIndex.tcl]]
              if {[llength $pkgIndexes]} {
                 set pistSetup $name
                 break
              }
           }

           if {[info exists pistSetup]} break
         }
        
         if {![info exists pistSetup]} {
           error "Librairie PIST introuvable à partir de $appli(pistsetup) "
           exit
         }
        
         set appli(pistsetup) $pistSetup
         set env(PIST_SETUP) $appli(pistsetup)
    }
    # On ajout la librairie pist à l'auto_path
    set auto_path [concat [list $appli(pistsetup)]  $auto_path]
    
    # On demande chaque package (sous-répertoire contenant un fichier 
    # pkgIndex.tcl)
    set pkFiles [glob -nocomplain  \
            [file join $appli(pistsetup) * pkgIndex.tcl] ]

    foreach pkFile $pkFiles   {
        set pk [file tail [file dir $pkFile]]
        package require $pk
    }
    # parray appli
}
# ./
