dbohdan 2015-04-18: When you are developing a Tcl module, it is often more convenient from an SCM standpoint to not rename the module file each time you want to increase its version number. An alternative to renaming is to keep the module's ongoing development in a file named ${module}-dev.tcl and copy its contents to ${module}-${version}.tm as needed. Under this approach, you can treat .tm files essentially as disposable build artifacts.
If your module code has the structure
namespace eval ::mymodule {
variable version 1.2.3
# ...
}
# ...it is especially easy to automate the creation of .tm files. The following module creation script shows how; here it is configured for fptools.
#!/bin/sh
source=fptools-dev.tcl
version=$(awk '/variable version/ { print $3 }' "$source")
dest=fptools-$version.tm
cp "$source" "$dest"dbohdan 2025-12-07: Today, I'd name the module foo.tcl and use symlinks. The copying workflow was dictated in part by Windows compatibility. This is no longer an issue in recent Windows 10 and 11.
The following shell transcript shows the setup for a simple project. The commands are compatible with POSIX shells and the fish shell.
$ echo 'proc greet {} { puts {Hello, world!} }' > foo.tcl
$ ln -s foo.tcl foo-0.1.0.tm
$ printf '::tcl::tm::path add [file dirname [file normalize [info script]]]\npackage require foo\ngreet\n' > hello.tcl
$ cat hello.tcl
::tcl::tm::path add [file dirname [file normalize [info script]]]
package require foo
greet
$ git init
Initialized empty Git repository in /tmp/example/.git/
$ git add foo.tcl foo-0.1.0.tm hello.tcl
$ git commit -m 'Initial commit'
[master (root-commit) 617d4c0] Initial commit
3 files changed, 5 insertions(+)
create mode 120000 foo-0.1.0.tm
create mode 100644 foo.tcl
create mode 100644 hello.tcl
$ tclsh hello.tcl
Hello, world!In a more complex project, you can move the modules to lib/.