TEKI - A generic install utility for TCL Applications

(c) Cornell University, 1998

Brian Smith, Sumit Kapoor


Teki install file format (*.tek files)

Introduction
    This file describes the format of TEKI install files (.tek files).  It
    is probably only of interest to Tcl extension writers.

    A .tek file is read by The Tek Installer (TEKI) to announce the
    availability of one or more extensions to TCL.  The .tek file
    communicates this information to TEKI by setting elements in
    the newPackage array.  To read the .tek file , 
	
	The easiest way to make a .tek file is to use TED (Short for TEKI Editor :)).
	TED provides an interactive GUI interface which walks you through the creation of a
	.tek file with the help of wizards. To use TED please refer to the file ted_readme.
	Another, but more tedious way to create a .tek file is to start start with one of the example
	.tek files and modify it.  I'll walk through a sample file below.

    The first line of a .tek file looks like this:

    # TekiFile 1.0

    It identifies this file as a .tek file, and gives the version number
    of this .tek file (note 2).  This information is hidden inside a Tcl
    comment.

Concepts
    The rest of the file contains commands to set elements in the
    newPackage array.  Before describing these elements in detail, I
    will describe a few concepts used in the file.

    o Each extension has a unique identifier that is used internally to
      identify a single extension.  The id must be one word (i.e., it
      must contain no white-space).  For example, "dp4.0" is the id of
      the Tcl-dp extension, version 4.0.

    o Each extension consists of seven types of files, all of which are
      optional:
        - an informational file (e.g. a readme) that describes the extension
        - a copyright file
        - a set of architecture independent Tcl files that are source'd when the
          extension is loaded
        - a set of architecture dependent Tcl and object files that are loaded
          (using the Tcl "load" command) when the extension is loaded.
        - a set documentation files, in HTML format
        - a set of data files (e.g., images or sample data) used by the extension
        - a set of examples
		- an initialization tcl script

    o To support architecture dependent files (such as shared libraries), Teki
      predefines a set of "system names."  Examples are names like
      "solaris," "win95," and "windows."  System names are matched with
      names and versions of the operating system,  For example, the "solaris"
      system is matched with SunOS version 5.*

    The ".tek" file is also known as a bundle file and has three parts. 
	The first part defines attributes that are global to the .tek file.
	The second part defines attributes for each package in this .tek file.
	The third part defines default installation parameters.  These parts
	are described in detail below. In each part, a sample from a .tek file
	is given follow by an explanation.  Keep in mind that the current
	directory is the directory where the .tek file is located when the file
	is sourced.

File-wide variables

	System Names = {{Solaris SunOS 5*}
					{SunOS SunOS 4*}
					{HPUX HP* 9*}
					{Linux Linux* 2*}
					{Win95/NT Win* *}
	}
    This section defines one attribute: System Names

    "System Names" is a list of system definitions.  These names are
    used to identify architectural dependencies at runtime (note 3).
    Each definition is a three-tuple consisting of the system name,
    the operating system (OS), and the OS version number.  The OS and
    OS version are determined at runtime by matching (glob-style)
    the OS and OS version in the system definition to the
    tcl_platform(os) and tcl_platform(osVersion) variables.  These
    systemNames are stored in the tekiInfo global variable, which
    is set by teki to the following value:

        set tekiInfo(systemNames)   {
                {Solaris SunOS 5*}
                {SunOS SunOS 4*}
                {HPUX HP* 9*}
                {Linux Linux* 2*}
                {Win95/NT Win* *}
        }

    For example, some of the systemNames defined above are Solaris, SunOS,
    and Win95/NT.  Solaris corresponds to tcl_platform(os) ~= SunOS and
    tcl_platform(osVersion) ~= 5* (where ~= denotes glob-style string
    matching).  Similarly, the Win95/NT matches any version of the
    operating system where tcl_platform(os) ~= Win*.

    The following defines a system named "Windows" that matches Win95
    (any version) and Windows NT version 4, and a system name Solaris2
    that matches SunOS version 5.2 and later. System names should preferably
	be unique although same system names are allowed (TED treats the
	system name as a unique identifier)

Package attributes:
    For each package in newPackage(available), several attributes are
    defined.  An excerpt of these definitions from the dp4.0 .tek file
    are shown below:

		Package Id. = dp4.0
		Package Name = {dp Version 4.0}
		Version = {4.0}
		Description = {Tcl Distributed Programming Environment, Version 4.0 Beta 1}
		Requires = {Tcl 7.6}
		Teki File = {dp.tek}
		Update URL = {http://www.cs.cornell.edu/zeno/projects/tcldp/update}
		Register URL = {http://www2.cs.cornell.edu/zeno/tcl-dp/register.html}
		Source URL = {http://www.cs.cornell.edu/zeno/projects/tcldp}
		Source Directory = {.}
		Destination Directory = {dp4.0}
		Copyright = {LICENSE}
		Information File = {README}
		Tcl Files = {library/acl.tcl library/distribObj.tcl library/dp_atclose.tcl 
		library/dp_atexit.tcl library/ldelete.tcl library/oo.tcl library/rpc.tcl
		}
		Example Files = {
			examples/conference/enter.tcl examples/conference/README 
			examples/conference/room.tcl examples/ftp/client.tcl 
			examples/ftp/server.tcl examples/tictactoe/board.tcl 
			examples/tictactoe/interface.tcl examples/tictactoe/playerO.tcl 
			examples/tictactoe/playerX.tcl examples/tictactoe/README 
			examples/whiteboard/readme examples/whiteboard/wbClient.tcl 
			examples/whiteboard/wbServer.tcl
		}
		Data Files = {api/dpApi.c api/dpApi.h api/dpExample.c api/readme.api}
		Object Files = {{Win95/NT win/dp40.dll}
						{Solaris solaris/libdp.so}
						{Linux linux2/libdp40.so}
						{SunOS sun4/libdp.so}
						{HPUX hpux9/libdp40.sl}
					   }
		Document Directory = {doc}
		Document Files = {dp_accept.html dp_admin.html dp_connect.html
			dp_copy.html dp_netinfo.html dp_rdo.html dp_recv.html dp_rpc.html
			dp_send.html email.html filter.html index.html ipm.html
			makerpcclient.html makerpcserver.html sample.html serial.html
			tcp.html udp.html}
		Initialization File = {init.tcl}
		Browse URL = {}

---------------------------------------------------------------------------------

    Let's go through this, line by line:

		Package Id. = dp4.0

	Package Id. is the unique extension identifier as described before. It also
	defines the start of the definition of a package setting. Two such definitions
	delimit the boundary of a package, the rest of the parameters can be shuffled
	within this boundary.


		Package Name = {dp Version 4.0}
		Version = {4.0}

    "Package Name" and "Version" give the name and version number of the
    extension.  These correspond to the package require command used
    to load the extension.  In the example above, the extension would
    be loaded using "package require dp 4.0".


		Description = {Tcl Distributed Programming Environment, Version 4.0 Beta 1}

    "Description" is a short string describing the package.  It appears
    in the TEKI user interface under the manifest of installed packages.


		Requires = {Tcl 7.6}

    "Requires" is a list of {package version} pairs indicating which
    packages are required.  It is not used currently, but it could be
    used later to auto-load the required packages.


		Teki File = {dp.tek}

	"Teki File" defines the name of the Teki ".tek" file. This name is also used for 
	retrieving the latest ".tek" file from the update URL for a web based update


		Update URL = {http://www.cs.cornell.edu/zeno/projects/tcldp/update}

    "Update URL" is a URL where package updates can be found.  It is
    used by the "update" command to automatically install new versions of a package.


		Register URL = {http://www2.cs.cornell.edu/zeno/tcl-dp/register.html}

    "Register URL" is a URL where users can go to fill out a registration form. It's
	 currently not used.


		Source URL = {http://www.cs.cornell.edu/zeno/projects/tcldp}
		Source Directory = {.}

    "Source URL" and "Source Directory" are the base directories for finding the
    files to copy for an over the web install.  The Source URL is the base URL where
	all the documentation, tcl, binary, data, and example files can be found -- it is
	prepended to every file in the package for web based installs.

    The Source Directory is relative to the directory where the ".tek" file is
    located, and contains all files relevant to this package.  It's
    useful when bundling many packages, since each can have its
    own subdirectory.  If you're bundling just one package, you can
    set it to "."

		Destination Directory = {dp4.0}

    "Destination Directory" is the name of the directory where the package will
    be installed.  Typically, this is the name of a sibling directory
    to [info library] that will be created when the package is installed.
    On my system, [info library] returns /usr/local/lib/tcl/tcl7.6, so
    the example above would install Tcl-DP in /usr/local/lib/tcl/dp4.0
    (although the prefix, /usr/local/lib/tcl, is determined by the user
    at run-time).  We call this the "code target directory" in what
    follows.

		Copyright = {LICENSE}

    "Copyright" is a name of a file giving the copyright notice and
    license terms.  It's thrown up in a dialog (with "accept" and 
	"do not accept" buttons) when the pakcage is about to be installed.
	A "do not accept" aborts installation.

		Information File = {README}

    "Information File" is a file describing the package. Its contents appear
    in the upper portion of the TEKI window when the user selects on
    this package.  It's typically a README file.

		Tcl Files = {library/acl.tcl library/distribObj.tcl library/dp_atclose.tcl 
		library/dp_atexit.tcl library/ldelete.tcl library/oo.tcl library/rpc.tcl
		}

    "Tcl Files" is a list of Tcl files that are source'd when the
    extension is loaded via the "package require" command.  All
    file names are relative to the .tek file's directory.  They are
    installed in the code target directory.  The directory structure
    is preserved in the target directory.

		Example Files = {
			examples/conference/enter.tcl examples/conference/README 
			examples/conference/room.tcl examples/ftp/client.tcl 
			examples/ftp/server.tcl examples/tictactoe/board.tcl 
			examples/tictactoe/interface.tcl examples/tictactoe/playerO.tcl 
			examples/tictactoe/playerX.tcl examples/tictactoe/README 
			examples/whiteboard/readme examples/whiteboard/wbClient.tcl 
			examples/whiteboard/wbServer.tcl
		}

    "Example Files" is a list of example or demo files.  These are
    (optionally) copied to the code target directory.  The directory
    structure is preserved in the target directory.  The files in
    the "demos" subdirectory of the tk directory is an example of
    a set of exampleFiles.

		Data Files = {api/dpApi.c api/dpApi.h api/dpExample.c api/readme.api}

    "Data Files" is a list of data files that are optionally installed
    in the code target directory.  These might include sample data sets
    and the like.  The directory structure is preserved in the target
    directory.  The files in "$tk_library/_demos/images" is an example
    of dataFiles

		Object Files = {{Win95/NT win/dp40.dll}
						{Solaris solaris/libdp.so}
						{SunOS sun4/libdp.so}
						{Linux linux2/libdp40.so}
						{HPUX hpux9/libdp40.sl}
					   }

    "Object Files" is a list of architecture dependent files associated with
    a system.  The format of each list element is a system name (which
    must be defined in the "System Names") followed by a list of object and
	system dependent tcl files.  

    At install time, the user selects which system names to install.
    The associated files are copied to the code target directory,
    preserving any directory structure that is present.  At run-time,
    when the extension is loaded through a "package require" command,
    the run-time system-name is found as described above (see
    "systemNames"), and the associated files are loaded or source'd.
    Files matching *.tcl will be source'd, other files will be load'ed

    In the excerpt above, object files are defined for five
    architectures, Wind95/NT, Solaris, SunOS, Linux and HPUX.

    As a more complex example, suppose my architecture dependent files
    consist of win/dp40.dll (for windows) and unix/solaris/libdp.so
    (solaris), and unix/sun4/libdp.so (SunOSv4). Furthermore, under
    unix systems, the file unix/gui.tcl has bindings appropriate for
    x-windows, and win/gui.tcl has bindings for Windows 95 and NT.
    Assuming Solaris, SunOS, and Wind95/NT are defined, I would set
    objFiles like this:

      Object Files = {
              {Win95/NT win/dp40.dll win/gui.tcl}
              {Solaris unix/gui.tcl unix/solaris/libdp.so}
              {SunOS unix/gui.tcl unix/sun4/libdp.so}
      }

    As you can see, the mechanism is fairly powerful and flexible.

		Document Directory = {doc}
		Document Files = {dp_accept.html dp_admin.html dp_connect.html
			dp_copy.html dp_netinfo.html dp_rdo.html dp_recv.html dp_rpc.html
			dp_send.html email.html filter.html index.html ipm.html
			makerpcclient.html makerpcserver.html sample.html serial.html
			tcp.html udp.html}

    "Document Directory"  and "Document Files" are used for documentation. 
	"Document Directory" is a directory where documentation files are stored,
	 and "Document Files" is a list of HTML files, whose names are given relative to
    "Document Directory."

    Just as code file are installed in the "code target directory,",
    documentation is installed in a the "documentation target
    directory."  The name of this directory is obtained from the
    user (e.g., /usr/local/doc/tcl) with the "destDir" attribute
    appended.  For example, on my windows system, I install Tcl_DP
    in C:\Program Files\Tcl\doc\dp4.0.  All the html files in "docDir"
    will be copied to the documentation target directory, and the
    directory structure beneath "Document Directory" will be preserved.

		Initialization File = {init.tcl}

	The "Initialization File" is a tcl file which is sourced after the package
	has been installed. You can specify a tcl script which initializes any required
	parameters.

		Browse URL = {http://www2.cs.cornell.edu/zeno/tcl-dp/dp.tkc}

	The Browse URL gives the URL address for .tkc, or the Table of Contents File,
	which has the following format:

	# TekiTOC 1.0
	#   name  version  requires descript  readme-url  tek-file-url pkg-identifier

	set TekiInfo(contents) {
		{Tcl-DP 4.0 {{Tcl 7.6}} {Tcl Distributed programming for Tcl 7.6}
			  http://www2.cs.cornell.edu/zeno/bsmith/dp/readme
			  http://www2.cs.cornell.edu/zeno/bsmith/dp/dp.tek
			  dp4.0}
		{Example 1.0 {{Tcl 7.6}} {A C extension for Tcl 7.6 or 8.0}
			  http://www2.cs.cornell.edu/zeno/bsmith/example/readme
			  http://www2.cs.cornell.edu/zeno/bsmith/example/example.tek
			  example1.0}
	}

	The Table of Contents file is a simple tcl script file which defines the packages 
	that you would like to provide to potential users and the URL to the respective .tek
	files of the packages for over the web install.


Default Settings

    The third section of the .tek file defines the default paramters
    for installation.  This is what happens when the user selects the
    "typical" install option (as opposed to "custom" installation).
    This section sets five variables:

		Default Packages = {dp4.0}
		Default Architecture = {Win95/NT}
		Default Install Documentation = {1}
		Default Install Examples = {0}
		Default Install Data = {0}

    "Default Packages" is a list of package identifiers installed
    by default.

    "Default Architecture" is a list of systems names to install (i.e.,
    defined in the "System Names" attribute), or the string "all"

    "Default Install Documentation" is a boolean indicating whether or not to
    install documentation

    "Default Install Examples" is a boolean indicating whether or not to
    install example files

    "Default Install Data" is a boolean indicating whether or not to
    install data files


-----------------
Notes:

1. The function TekiReadFile looks at first line of the teki file, to be sure that
   the file is a teki install file.  It only source's the file if it
   looks like a TEKI install file.  This will prevent accidentlly
   sourcing a non-.tek file

2. There can be more complex scenarios, where an extension may only want
   to load some files when a certain condition is true (e.g., when the
   g++ compiler is installed), but because such conditions would
   unnecessairly complicate TEKI they have been left for now. They can always
   be handled by the extension author at load time.

----------------------
Appendix: .tek file for Tcl-DP


# TekiFile 1.0
#
# TEKI install file
#
System Names = {{Win95/NT Win* *}}

###############################################################
# Information for Package: dp4.0

Package Id. = dp4.0
Package Name = {TCL-DP}
Version = {4.0}
Description = {Tcl Distributed Programming Environment}
Requires = {Tcl 7.6}
Teki File = {dp.tek}
Update URL = {http://www.cs.cornell.edu/zeno/projects/tcldp}
Register URL = {http://www.cs.cornell.edu/zeno/projects/tcldp}
Source URL = {http://www.cs.cornell.edu/zeno/projects/tcldp/test}
Source Directory = {.}
Destination Directory = {dp4.0}
Copyright = {License}
Information File = {Readme}
Tcl Files = {library/acl.tcl library/distribObj.tcl library/dp_atclose.tcl library/dp_atexit.tcl library/ldelete.tcl library/oo.tcl library/rpc.tcl}
Data Files = {api/dpApi.c api/dpApi.h api/dpExample.c api/makefile.win api/readme.api tests/00-first.test tests/all tests/connect.test tests/copy.test tests/defs tests/email.test tests/identity.test tests/ipm.test tests/make-server tests/netinfo.test tests/plugin.test tests/plugin2.test tests/rpc.test tests/ser_xmit.test tests/serial.test tests/server tests/tcp.test tests/udp.test tests/xmit.test}
Document Directory = {doc}
Document Files = {dp_accept.html dp_admin.html dp_connect.html dp_copy.html dp_netinfo.html dp_rdo.html dp_recv.html dp_rpc.html dp_send.html email.html filter.html index.html ipm.html makerpcclient.html makerpcserver.html sample.html serial.html tcp.html udp.html}
Example Files = {examples/conference/enter.tcl examples/conference/README examples/conference/room.tcl examples/ftp/client.tcl examples/ftp/server.tcl examples/tictactoe/board.tcl examples/tictactoe/interface.tcl examples/tictactoe/playerO.tcl examples/tictactoe/playerX.tcl examples/tictactoe/README examples/whiteboard/readme examples/whiteboard/wbClient.tcl examples/whiteboard/wbServer.tcl}
Object Files = {{Win95/NT win/dp40.dll}}
Initialization File = {}
Browse URL = {http://www.cs.cornell.edu/zeno/projects/tcldp/tcldp.tkc}

###############################################################

# Default Settings

Default Packages = {dp4.0}
Default Architecture = {Win95/NT}
Default Install Documentation = {1}
Default Install Examples = {1}
Default Install Data = {1}
