pkgIndex.tcl

Summary

pkgIndex.tcl is used by the package command to identify and load packages

Description

See package for the details of how the pkgIndex.tcl file is used.

See also pkg_mkIndex.

This is different from the unknown proc and its use of tclIndex.

PkgIndexUtil.tcl - determining a platform name

Recently in comp.lang.tcl, DKF writes (in part) [L1 ]:

Further investigation reveals a badly-written pkgIndex.tcl file, so it 
is doing: 
   package ifneeded foo 1.0 "load [file join $dir foo.dll]" 
instead of: 
   package ifneeded foo 1.0 "load [file join [list $dir] foo.dll]" 
(or one of the many variants on both those). 

I advise that all package authors should test their code when it is 
installed in a directory with a space (or square bracket) in the name, 
and if they find any problems, fix them using [list] carefully to wrap 
$dir or the value derived from it. (Remember, when you're in quoting 
hell, [list] is the road out.) 

Later in that thread, it is observed that both of the above are actually wrong.

Possible corrections of the second are:

package ifneeded foo 1.0 [list load [file join $dir foo.dll]]     ; # File join when setting script
package ifneeded foo 1.0 "load \[file join [list $dir] foo.dll\]" ; # File join when evaluating script

but for multiple-command scripts, DKF ends up recommending:

package ifneeded foo 1.0 [list apply {dir { 
    load [file join $dir foo.dll] 
    uplevel 1 [list source [file join $dir foo.tcl]] 
}} $dir] 

DGP WARNING: if you want to use that last version, you need to guard against interps that lack the apply command. Be sure to start the pkgIndex.tcl file with

if {![package vsatisfies [package provide Tcl] 8.5]} {return}

More generally, see the package index script interface guidelines.


Use pkgIndex.tcl in package subfolders

HaO 2011-05-04 A package has subpackages in subfolders.

Typically, the parent folder of packages is in the auto_path and thus only the package main folder is scanned for any pkgIndex.tcl files. Any pkgIndex.tcl files in subfolders are ignored.

To include pkgIndex.tcl files in package subfolders, one may add to the pkgIndex.tcl file of the package:

lappend auto_path $dir

Specify encoding with source to be portable

HaO 2015-07-07

Package index files contain source commands which are system dependent, as they load the file using the system encoding. If the file contains non-ASCII characters, the encoding should be passed with the source command.

Beware of special characters in comments which might also destroy the file.

The file 'pkgIndex.tcl' should never contain non-ASCII characters. I suppose they are sourced using the system encoding and you can not change that.

My practice is as follows:

  • use tcl files coded in utf-8 with a BOM
  • utf-8 is "saver" against misinterpretation, as special characters in strings lead to multiple nonsense characters but do not cause an encoding error. A system encoding interpreted as utf-8 or probably some multibyte encodings may cause encoding errors and quite strange things.
  • if there are no non-ASCII characters, they may be sourced without specifying the encoding (that is the reason avoiding the BOM. A BOM always requires to specify the encoding).
  • If there are non-ASCII characters, the encodation must be specified with the source command
  • I always specify the encoding in the pkgIndex.tcl file
# Comment not using non-ASCII (the following German text would require an Umlaut which is replaced by ASCII characters)
# Sie koennen das auch lesen..
if {![package vsatisfies [package provide Tcl] 8.5]} {return}
package ifneeded foo 1.0 [list source -encoding utf-8 [file join $dir foo.tcl]]
# File foo.tcl
# Non-ASCII characters may be used here.
# Hier können jetzt Umlaute genutzt werden.
# The file is saved as utf-8 without a leading BOM
package provide foo 1.0
puts "Äußerst praktisch..."