[DDG] 2020-02-25: Below is a small utility script which writes all `package require` calls to stdout. This is useful to check if making a release of your application which packages are required for your application. It shows recursively all packages on the terminal. I use this to create standalone files which contains all embedded modules before the actual application script using the script `mk_tm.tcl` at the bottom of the Wiki page [Another Tcl module maker]. So this helps in creating single file Tcl applications where the application is the last file and all modules files are added before. Here is the code: ====== #!/bin/env tclsh # file pkgDeps.tcl rename package package.orig proc package {args} { set subcmd [lindex $args 0] if {$subcmd eq "require"} { puts stderr "package require $args" } package.orig {*}$args } if {[info exists argv0] && $argv0 eq [info script]} { if {[llength $argv] == 0} { puts "Usage: [info script] app.tcl ?other args?" exit 0 } set ::argv0 [lindex $argv 0] set ::argv [lrange $argv 1 end] source $argv0 } ====== Example call for the package [mkdoc::mkdoc]: ====== $ checkPkg.tcl mkdoc.tcl package require require Tcl 8.4 package require require Markdown package require require Tcl 8.4 package require require Tcl 8.2 package require require Tcl package require require Tcl package require require textutil package require require Tcl 8.2 package require require textutil::string package require require Tcl 8.2 package require require textutil::repeat package require require Tcl 8.2 package require require textutil::adjust package require require Tcl 8.2 package require require textutil::repeat package require require textutil::string package require require textutil::split package require require Tcl 8.2 package require require textutil::tabify package require require Tcl 8.2 package require require textutil::repeat package require require textutil::trim package require require Tcl 8.2 ... ====== Now my Makefile to create the application: ====== app: tclsh ../tools/mk_tm.tcl mkdoc 0.4 \ any-script ../libs/textutil/string.tcl \ any-script ../libs/textutil/repeat.tcl \ any-script ../libs/textutil/adjust.tcl \ any-script ../libs/textutil/expander.tcl \ any-script ../libs/textutil/split.tcl \ any-script ../libs/textutil/tabify.tcl \ any-script ../libs/textutil/trim.tcl \ any-script ../libs/textutil/textutil.tcl \ any-script ../libs/markdown/markdown.tcl \ any-script mkdoc.tcl ====== Using a [tclkit] interpreter, which does not(!) use the Tcl library on the current machine, I can check if the order of the files in the output follows the inverse calling order in `package require`. Means that because "Markdown" needs "textutils" the latter must be added first. '''Tracing the source command''' Let's extend the script a little bit further by tracing as well the source command: ====== #!/bin/env tclsh # file pkgDeps.tcl rename package package.orig rename source source.orig proc package {args} { set subcmd [lindex $args 0] if {$subcmd eq "require"} { puts stderr "package require $args" } package.orig {*}$args } proc source {args} { set file [lindex $args end] # be sure do show only source commands from not standard Tcl/Tk files if {[file tail $file] ne "pkgIndex.tcl"} { puts stderr "source $args" } uplevel 1 [list source.orig {*}$args] } if {[info exists argv0] && $argv0 eq [info script]} { if {[llength $argv] == 0} { puts "Usage: [info script] app.tcl ?other args?" exit 0 } set ::argv0 [lindex $argv 0] set ::argv [lrange $argv 1 end] source $argv0 } ====== We now see as well which files are sourced. '''Discussion:''' Please discuss here ... ---- '''[bll] - 2020-02-25 16:21:55''' I actually have a script that traverses all of my modules, creates a dependency list, runs a topological sort on it (using 'tsort'), then rewrites each module's list of 'package require' statements in dependency order. It warns of missing dependencies and unused dependencies. It's by no means perfect, but generally works well enough for occasional use. It doesn't handle classes and instantiation very well, there's some hard-coded data in there to handle some of my classes and other oddities. It's also rather dependent on my style of fully qualifying my procedure calls. I use '::uiutils::initUI' for example, I don't use namespace imports. [DDG] - 2020-02-25: Yes, my approach above certainly only is useful for small apps with a few dependencies. For larger applications your approach, wrapping into [starkit]s, [freewrap], [thatch] etc. might be more useful. However I felt that in many cases this simple sample script above might be a good starter for small console applications. <> Application | Deployment | Dev. Tools