Tcl Library Source Code

Check-in [6cca025e4c]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Dev guide - Tweaked phrasing in commitments. - Reworked and expanded section on branches and workflow around them. Installer - Redone instructions, split by platform again. - Separated out the more advanced pieces into a tooling section.
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | doc-overhaul
Files: files | file ages | folders
SHA3-256: 6cca025e4c7a286af25a9289a6c6aff3322a06aa5d7a54b6b3d642f1176c2e25
User & Date: aku 2019-03-28 22:14:26.237
Context
2019-03-29
04:16
Brought md list fixes into the work on the guides check-in: d821fa1849 user: aku tags: doc-overhaul
2019-03-28
22:14
Dev guide - Tweaked phrasing in commitments. - Reworked and expanded section on branches and workflow around them. Installer - Redone instructions, split by platform again. - Separated out the more advanced pieces into a tooling section. check-in: 6cca025e4c user: aku tags: doc-overhaul
2019-03-25
21:30
Brought MD work into the overhaul of dev docs. check-in: b072dfa9b8 user: aku tags: doc-overhaul
Changes
Unified Diff Ignore Whitespace Patch
Changes to devdoc/parts/b_critcl.inc.
1


2
3

4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33


[subsection {Critcl & Accelerators}]



[para] A number of packages come with [term accelerators], i.e.

[syscmd critcl]-based C code whose use will boost the performance of
the packages using them. As these accelerators are optional they are
not installed by default.

[para] To build the accelerators the normally optional dependency on
[syscmd critcl] becomes required.

[para] To install Tcllib with the accelerators in a Unix-type
environment invoke:

[example {
    ./configure
    make critcl # This builds the shared library holding
                # the accelerators
    make install
}]

[para] The underlying tool is [file sak.tcl] in the toplevel directory
of Tcllib and the command [cmd {make critcl}] is just a wrapper around

[example {
    ./sak.tcl critcl
}]

[para] Therefore in a Windows environment instead invoke

[example {
    /path/to/tclsh ./sak.tcl critcl
    /path/to/tclsh ./installer.tcl
}]


|
>
>

|
>
|
|
|


|

|
|


|
|
|
|






|





|
|

>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38

While the majority of Tcllib consists of packages written in pure Tcl
a number of packages also have [term accelerators] associated with them.

These are [syscmd critcl]-based C packages whose use will boost the
performance of the packages using them.

These accelerators are optional, and they are not installed by
default.

[para] To build the accelerators the normally optional dependency on
       [syscmd critcl] becomes required.

[para] To build and install Tcllib with the accelerators in a
       Unix-like environment invoke:

[example {
  ./configure
  make critcl # This builds the shared library holding
              # the accelerators
  make install
}]

[para] The underlying tool is [file sak.tcl] in the toplevel directory
of Tcllib and the command [cmd {make critcl}] is just a wrapper around

[example {
  ./sak.tcl critcl
}]

[para] Therefore in a Windows environment instead invoke

[example {
  ./sak.tcl critcl
  ./installer.tcl
}]

from within a DOS window, i.e. [syscmd cmd.exe].
Changes to devdoc/parts/b_tooling.inc.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21


22
23


24
25
26
27


28
29
30

31
32
33
34
35
36
37
38
39
40
41
42
43

44
45
46
47
48
49


50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87


88


89

90

91
















































The Tcllib distribution, whether a checkout directly from the source
repository, or an official release, offers a single method for
installing it, based on Tcl itself.

[para] This is based on the assumption that for Tcllib to be of use
Tcl has to be present, and therefore can be used in the implementation
of the install code.

[para] The relevant tool is the [file installer.tcl] script found in
the toplevel directory of a checkout or release.

[para] It can be used in a variety of ways:

[list_begin enumerated]

[enum] It is always possible to invoke the tool directly, either as

[example {
    ./installer.tcl
}]



or



[example {
    /path/to/tclsh ./installer.tcl
}]



The second form is required on Windows (without a Unix emulation),
except if the Tcl installation is configured to handle [file .tcl]

files on a double-click.

[enum]

In a Unix-type environment, i.e. Linux, BSD and related, including OS
X, and Windows using some kind of unix-emulation like [syscmd MSYS],
[syscmd Cygwin], etc.) it is also possible to use

[example {
    ./configure
    make install
}]


in the toplevel directory of Tcllib itself.

[para] To build in a directory [file D] outside of Tcllib's toplevel
directory simply make [file D] the current working directory and
invoke [syscmd configure] with either its absolute path or a proper
relative path.



[para] This will non-interactively install all packages, applications
found in Tcllib, and their manpages, in directories derived from what
[syscmd configure] found out about the system.

[list_end]

[para] The installer selects automatically either a GUI based mode, or
a command line based mode. If the package [package Tk] is present and
can be loaded, then the GUI mode is entered, else the system falls
back to the command line.

[para] Note that it is possible to specify options on the command line
even if the installer ultimatively selects GUI mode. In that case the
hardwired defaults and the options determine the data presented to the
user for editing.

[para] Command line help can be asked for by using the option [option -help] when
invoking the installer, i.e.

[example {
    ./installer.tcl -help
}]

This will print a short list of the available options to the standard
output channel. For more examples see the various [term install]
targets found in [file Makefile.in].

[para] The installer will select a number of defaults for the
locations of packages, examples, and documentation, and also the
format of the documentation. The user can overide these defaults in
the GUI, or by specifying additional options.

[para] The defaults depend on the platform detected (Unix/Windows) and
on the [syscmd tclsh] executable used to run the installer.

[para][emph Attention] The installer will overwrite an existing
installation of a Tcllib with the same version without asking back


after the initial confirmation is given.




Further if the user chooses the same directory as chosen for/by

previous installations then these will be overwritten as well.
















































<
<
<
|
<
<
<
<
<
|

|
<
<
<
<
<
|
|
|
>
>

<
>
>

<
<
<
>
>

<
<
>
<

<
<
<
<
<
<
|
<
|
|

>
|

|
<
<
<
>
>

|
<
<

<
|
<
|
|
|


|
|
|
<
<
<
<
<
<
<
<
<
<
<


|
|
|

|
|

|
|
>
>
|
>
>

>
|
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1



2





3
4
5





6
7
8
9
10
11

12
13
14



15
16
17


18

19






20

21
22
23
24
25
26
27



28
29
30
31


32

33

34
35
36
37
38
39
40
41











42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109




The core of Tcllib's build system is the script [file installer.tcl]





found in the toplevel directory of a checkout or release.

[para] The





       [example {
         configure ; make install
       }]
       setup available to
       developers on Unix-like systems is just a wrapper around it.


       To go beyond the standard embodied in the wrapper it is
       necessary to directly invoke this script.




[para] On Windows system using it directly is the only way to invoke
       it.



[para] For basic help invoke it as








       [example {

         ./installer.tcl -help
       }]

       This will print a short list of all the available options to
       the standard output channel.

[para] The commands associated with the various [term install] targets



       in the [term Makefile.in] for Unix can be used as additional
       examples on how to use this tool as well.

[para] The installer can operate in GUI and CLI modes.




       By default it chooses the mode automatically, based on if the

       Tcl package [package Tk] can be used or not.

       The option [option -no-gui] can be used to force CLI mode.

[para] Note that it is possible to specify options on the command line
       even if the installer ultimatively selects GUI mode. In that
       case the hardwired defaults and the options determine the data
       presented to the user for editing.












[para] The installer will select a number of defaults for the
       locations of packages, examples, and documentation, and also
       the format of the documentation. The user can overide these
       defaults in the GUI, or by specifying additional options.

       The defaults depend on the platform detected (Unix/Windows) and
       on the [syscmd tclsh] executable used to run the installer.

[para][emph Options]

[list_begin options]
[opt_def -help]

Show the list of options explained here on the standard output channel
and exit.

[opt_def +excluded]

Include deprecated packages in the installation.

[opt_def -no-gui]

Force command line operation of the installer

[opt_def -no-wait]

In CLI mode the installer will by default ask the user to confirm that
the chosen configuration (destination paths, things to install) is
correct before performing any action. Using this option causes the
installer to skip this query and immediately jump to installation.

[opt_def -app-path [arg path]]
[opt_def -example-path [arg path]]
[opt_def -html-path [arg path]]
[opt_def -nroff-path [arg path]]
[opt_def -pkg-path [arg path]]

Declare the destination paths for the applications, examples, html
documentation, nroff manpages, and packages. The defaults are derived
from the location of the [syscmd tclsh] used to run the installer.

[opt_def -dry-run]
[opt_def -simulate]

Run the installer without modifying the destination directories.

[opt_def -apps]
[opt_def -no-apps]
[opt_def -examples]
[opt_def -no-examples]
[opt_def -pkgs]
[opt_def -no-pkgs]
[opt_def -html]
[opt_def -no-html]
[opt_def -nroff]
[opt_def -no-nroff]

(De)activate the installation of applications, examples, packages,
html documentation, and nroff manpages.

[para] Applications, examples, and packages are installed by default.

[para] On Windows the html documentation is installed by default.

[para] On Unix the nroff manpages are installed by default.

[list_end]
Added devdoc/parts/b_unix.inc.












































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

For [term Unix]-like environments Tcllib comes with the standard set
of files to make

[example {
  ./configure
  make install
}]

a suitable way of installing it.

This is a standard non-interactive install automatically figuring out
where to place everything, i.e. packages, applications, and the
manpages.

[para] To get a graphical installer invoke

[example {
  ./installer.tcl
}]

instead.
Added devdoc/parts/b_windows.inc.




































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

In a Windows environment we have the [cmd installer.tcl] script to
perform installation.

[para] If the desired [syscmd tclsh] is associated [file .tcl] files
       then double-clicking / opening the [cmd installer.tcl] is
       enough to invoke it in graphical mode.

       This assumes that [term Tk] is installed and available as well.

[para] Without [term Tk] the only way to invoke the installer are to
       open a DOS window, i.e. [syscmd cmd.exe], and then to invoke
      
[example {
  ./installer.tcl
}]

inside it.
Added devdoc/parts/d_bf_branchcmds.inc.


























































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29

In the hope of engendering good work practices now a few example
operations which will come up with branches, and their associated
fossil command (sequences).

[list_begin definitions]

[comment ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~]
[def [emph Awareness]]
[include d_op_aware.inc]

[comment ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~]
[def [emph {Clean checkouts}]]
[include d_op_clean.inc]

[comment ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~]
[def [emph {Starting a new branch}]]
[include d_op_branch_open.inc]

[comment ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~]
[def [emph {Merging a branch into trunk}]]
[include d_op_branch_close.inc]

[comment ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~]
[def [emph {Merging from trunk}]]
[include d_op_branch_import.inc]

[list_end]

Added devdoc/parts/d_bf_branches.inc.










































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37

Given the constraints placed on the [term trunk] branch of the
repository it is (strongly) recommended to perform any development
going beyond trivial changes on a non-trunk branch.

[para] Outside of the trunk developers are allowed to commit
       intermediate broken states of their work.

       Only at the end of a development cycle, when the relevant
       branch is considered ready for merging, will it be necessary to
       perform full the set of validations ensuring that the merge to
       come will create a good commit on trunk.

[para] Note that while a review from a second developer is not a
       required condition for merging a branch it is recommended to
       seek out such an independent opinion as a means of
       cross-checking the work.

[para] It also recommended to give any new branch a name which aids in
       determining additional details about it. Examples of good
       things to stick into a branch name would be

[list_begin itemized]
[item]	Developer (nick)name
[item]	Ticket hash/reference
[item]	One or two keywords applicable to the work
[item]	...
[list_end]

[para] Further, while most development branches are likely quite
       short-lived, no prohibitions exist against making longer-lived
       branches.

       Creators should however be mindful that the longer such a
       branch exists without merges the more divergent they will tend
       to be, with an associated increase in the effort which will
       have to be spent on either merging from and merging to trunk.
Added devdoc/parts/d_bf_dependencies.inc.


























































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61

Regarding packages and dependencies between them Tcllib occupies a
middle position between two extremes:

[list_begin enumerated]

[enum] On one side a strongly interdependent set of packages, usually
       by a single author, for a single project. Looking at my
       (Andreas Kupries) own work examples of such are
       [uri https://core.tcl.tk/akupries/marpa/index Marpa],
       [uri https://core.tcl.tk/akupries/crimp/index CRIMP],
       [uri https://core.tcl.tk/akupries/kinetcl/index Kinetcl], etc.

[para] For every change the author of the project handles all the
       modifications cascading from any incompatibilities it
       introduced to the system.

[enum] On the other side, the world of semi-independent projects by
       many different authors where authors know what packages their
       own creations depend on, yet usually do not know who else
       depends on them.

[para] The best thing an author making an (incompatible) change to
       their project can do is to for one announce such changes in
       some way, and for two use versioning to distinguish the code
       before and after the change.

[para] The world is then responsible for adapting, be it by updating
       their own projects to the new version, or by sticking to the
       old.

[list_end]

As mentioned already, Tcllib lives in the middle of that.

[para] While we as maintainers cannot be aware of all users of
       Tcllib's packages, and thus have to rely on the mechanisms
       touched on in point 2 above for that, the dependencies between
       the packages contained in Tcllib are a different matter.

[para] As we are collectively responsible for the usability of Tcllib
       in toto to the outside world, it behooves us to be individually
       mindful even of Tcllib packages we are not directly
       maintaining, when they depend on packages under our
       maintainership.

       This may be as simple as coordinating with the maintainers of
       the affected packages.

       It may also require us to choose how to adapt affected packages
       which do not have maintainers, i.e. modify them to use our
       changed package properly, or modify them to properly depend on
       the unchanged version of our package.

[para] Note that the above is not only a chore but an opportunity as
       well.

       Additional insight can be had by forcing ourselves to look at
       our package and the planned change(s) from an outside
       perspective, to consider the ramafications of our actions on
       others in general, and on dependent packages in particular.
Added devdoc/parts/d_bf_trunk.inc.




























































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30

The management and use of branches is an important part of working
with a [term {Distributed Version Control System}] ([term DVCS]) like
[uri https://www.fossil-scm.org/ fossil].

[para] For Tcllib the main branch of the collection is
       [term trunk]. In [term git] this branch would be called
       [term master], and this exactly the case in the
       [uri https://github.com/tcltk/tcllib/ {github mirror}] of
       Tcllib.

[para] To properly support debugging [emph {each commit}] on this
       branch [emph {has to pass the entire testsuite}] of the
       collection. Using bisection to determine when an issue appeared
       is an example of an action made easier by this constraint.

[para] This is part of our collective responsibility for the usability
       of Tcllib in toto to the outside world.

       As [term fossil] has no mechanism to enforce this condition
       this is handled on the honor system for developers and maintainers.

[para] To make the task easier Tcllib comes with a tool
       ([file sak.tcl]) providing a number of commands in
       support. These commands are explained in the following sections
       of this guide.

[para] While it is possible and allowed to commit directly to trunk
       remember the above constraint regarding the testsuite, and the
       coming notes about other possible issues with a commit.
Added devdoc/parts/d_bf_versions.inc.
























































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
In Tcllib all changes to a package have to come with an increment of
its version number. What part is incremented (patchlevel, minor, major
version) depends on the kind of change made. With multiple changes in
a commit the highest "wins".

[para] When working in a development branch the version change can be
       deferred until it is time to merge, and then has to cover all
       the changes in the branch.

[para] Below a list of the kinds of changes and their associated
       version increments:

[list_begin definitions]
[def [term {D - documentation}]] No increment
[def [term {T - testsuite}]] No increment
[def [term {B - bugfix}]] Patchlevel
[def [term {I - implementation tweak}]] Patchlevel
[def [term {P - performance tweak}]] Patchlevel
[def [term {E - backward-compatible extension}]] Minor
[def [term {API - incompatible change}]] Major
[list_end]

[para] Note that a commit containing a version increment has to
       mention the new version number in its commit message, as well
       as the kind of change which caused it.

[para] Note further that the version number of a package currently
       exists in three places. An increment has to update all of them:

[list_begin enumerated]
[enum] The package implementation.
[enum] The package index ([file pkgIndex.tcl])
[enum] The package documentation.
[list_end]

[para] The [file sak.tcl] command [cmd {validate version}] helps
       finding discrepancies between the first two.

       All the other [cmd validate] methods are also of interest to
       any developer. Invoke it with

       [example { sak.tcl help validate }]

       to see their documentation.
Changes to devdoc/parts/d_branchflow.inc.

1
2
3
4
5
6
7

8
9
10
11
12
13
14

15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34

35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82

[subsection Branches]

An important part of working with a
[term {Distributed Version Control System}] ([term DVCS]) like
[uri https://www.fossil-scm.org/ fossil]
is the management and use of branches.


[para] For Tcllib the main branch of the collection is
[term trunk]. In [term git] this branch would be called [term master],
and this exactly the case in the
[uri https://github.com/tcltk/tcllib/ {github mirror}] of Tcllib.

[para] In support of debugging, like searching for when an issue
appeared via bisection, each commit on this branch must pass the

entire testsuite of the collection.

[para] As fossil has no mechanism to enforce this this is handled on
the honor system for developers and maintainers.

[para] To make the task easier Tcllib comes with a tool
([file sak.tcl]) providing a number of commands in support. These
commands are explained in the following sections of this guide.

[para] While it is possible and allowed to commit directly to trunk
remember the above regarding the testsuite, and the coming notes about
other possible issues with a commit.

[para] Because of this it is (strongly) recommended to perform any
development on a nicely named (nick of dev, ticket reference if any,
keywords applicable to the work, ...) non-trunk branch. Outside of the
trunk developers are allowed to commit intermediate broken states of
their work. Only at the end, when the branch is considered ready for
merging will it be necessary to perform full validation.


[subsection {Version numbers}]

In Tcllib all changes to a package have to come with an increment of
its version number. What part is incremented (patchlevel, minor,
major version) depends on the kind of change made. With multiple
changes in a commit the highest "wins".

[para] When working in a development branch the version change can be
deferred until it is time to merge, and then has to cover all the
changes in the branch.

[para] Below a list of the kinds of changes and their association
version increments:

[list_begin definitions]
[def [term {D - documentation}]] No increment
[def [term {T - testsuite}]] No increment
[def [term {B - bugfix}]] Patchlevel
[def [term {I - implementation tweak}]] Patchlevel
[def [term {P - performance tweak}]] Patchlevel
[def [term {E - backward-compatible extension}]] Minor
[def [term {API - incompatible change}]] Major
[list_end]

[para] Note, a commit containing a version increment has to mention
the kind of change which caused it in the commit message, as well as
the new version number.

[para] Note further that the version number of a package currently
exists in 3 places. An increment has to update all of them:

[list_begin enumerated]
[enum] The package implementation.
[enum] The package index ([file pkgIndex.tcl])
[enum] The package documentation.
[list_end]

[para] The [file sak.tcl] command [cmd {validate version}] helps
finding discrepancies between the first two.

All the other [cmd validate] methods are also of interest to any
developer. Invoke it with

[example {
    sak.tcl help validate
}]

to see their documentation.
>
|
|
<
<
<
<

>
|
|
<
<

<
<
>
|
|
<
<

<
<
<
|
<
<
|
|
<
<
<
<
<
<

>

|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
1
2
3




4
5
6
7


8


9
10
11


12



13


14
15






16
17
18
19














































[comment {===================================================================}]
[subsection {Package Dependencies}]
[include d_bf_dependencies.inc]





[comment {===================================================================}]
[subsection Trunk]
[include d_bf_trunk.inc]





[comment {===================================================================}]
[subsection Branches]
[include d_bf_branches.inc]






[comment {===================================================================}]


[subsection {Working with Branches}]
[include d_bf_branchcmds.inc]







[comment {===================================================================}]
[subsection {Version numbers}]
[include d_bf_versions.inc]














































Changes to devdoc/parts/d_contrib.inc.
1
2
3
4
5
6
7


8
9
10
11
12
13
14

As a contributor to Tcllib you are committing yourself to:

[list_begin enumerated]

[enum] Follow the guidelines laid down in
       [term {Tcl Community - Kind Communication}]



[enum] Your contributions getting distributed under a BSD/MIT license.
       For the details see [term {Tcllib - License}]

[list_end]

Contributions are made by entering tickets into our tracker, providing





|
|
>
>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

As a contributor to Tcllib you are committing yourself to:

[list_begin enumerated]

[enum] keep the guidelines written down in
       [term {Tcl Community - Kind Communication}] in your mind.
       The main point to take away from there is
       [emph {to be kind to each other}].

[enum] Your contributions getting distributed under a BSD/MIT license.
       For the details see [term {Tcllib - License}]

[list_end]

Contributions are made by entering tickets into our tracker, providing
Changes to devdoc/parts/d_maintain.inc.
1
2
3
4
5
6
7
8
9

10
11
12
13
14
15
16

When contributing one or more packages for full inclusion into Tcllib
you are committing yourself to

[list_begin enumerated]

[enum] Follow the guidelines laid down in
       [term {Tcl Community - Kind Communication}]
       (as any contributor)


[enum] Your packages getting distributed under a BSD/MIT license.  For
       the details see [term {Tcllib - License}]

[enum] Maintenance of the new packages for a period of two years under
       the following rules, and responsibilities:







|

|
>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

When contributing one or more packages for full inclusion into Tcllib
you are committing yourself to

[list_begin enumerated]

[enum] Keep the guidelines written down in
       [term {Tcl Community - Kind Communication}]
       (as any contributor) in your mind. The main point to take away
       from there is [emph {to be kind to each other}].

[enum] Your packages getting distributed under a BSD/MIT license.  For
       the details see [term {Tcllib - License}]

[enum] Maintenance of the new packages for a period of two years under
       the following rules, and responsibilities:

Added devdoc/parts/d_op_aware.inc.


























































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45

When developing we have to keep ourselves aware of the context of our
work. On what branch are we ? What files have we changed ? What new
files are not yet known to the repository ?

This becomes especially important when using a long-lived checkout and
coming back to it after some time away.

[para] Commands to answer questions like the above are:

[list_begin definitions]
[def [cmd {fossil info | grep tags}]]
[def [cmd {fossil branch list | grep '\*'}]]

       Two different ways of determining the branch our checkout is
       on.

[def [cmd {fossil timeline}]]

       What have we (and others) done recently ?

[para] [emph Attention], this information is very likely outdated, the
       more the longer we did not use this checkout.

       Run [cmd {fossil pull}] first to get latest information from
       the remote repository of the project.

[def [cmd {fossil timeline current}]]

       Place the commit our checkout is based on at the top of the
       timeline.

[def [cmd {fossil changes}]]

       Lists the files we have changed compared to the commit the
       checkout is based on.

[def [cmd {fossil extra}]]

       Lists the files we have in the checkout the repository does not
       know about. This may be leftover chaff from our work, or
       something we have forgotten to [cmd {fossil add}] to the
       repository yet.

[list_end]
Added devdoc/parts/d_op_branch_close.inc.


















































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73

Be aware of where you are (see first definition).

[para] Ensure that you have clean checkout (see second definition).

       In the full-blown sequence (zig-zag) it is [emph required], due
       to the merging from trunk. In the shorter sequence it is only
       desired. That said, keeping the checkout clean before
       any major operations is a good habit to have, in my opinion.

[para] The full-blown sequencing with checks all the way is to

[list_begin enumerated]

[enum] Validate the checkout, i.e. last commit on your branch. Run the
       full test suite and other validations, fix all the issues which
       have cropped up.

[enum] Merge the latest state of the [term trunk] (see next definition).

[enum] Validate the checkout again. The incoming trunk changes may
       have broken something now. Do any required fixes.

[enum] Now merge to the trunk using

[example {
    fossil update trunk
    fossil merge --integrate YOU_BRANCH
}]

[enum] At this point the checkout should be in the same state as at
       the end of point (3) above, because we resolved any issues with
       the trunk already. Thus a simple

[example {
    fossil commit ...
}]

       should be sufficient now to commit the merge back and close the
       branch (due to the [option --integrate] we used on the merge).

[para] The more paranoid may validate the checkout a third time before
       commiting.
[list_end]

[para] I call this a [term {zig-zag merge}] because of how the arrows
       look in the timeline, from trunk to feature branch for the
       first merge, and then back for the final merge.

[para] A less paranoid can do what I call a [term {simple merge}],
       which moves step (2) after step (4) and skips step (3)
       entirely. The resulting shorter sequence is

[list_begin enumerated]
[enum] Validate
[enum] Merge to trunk
[enum] Validate again
[enum] Commit to trunk
[list_end]

The last step after either zig-zag or plain merge is to

[example {
    fossil sync
}]

This saves our work to the remote side, and further gives us any other
work done while we were doing our merge. It especially allows us to
check if we raced somebody else, resulting in a split trunk.

[para] When that happens we should coordinate with the other developer
       on who fixes the split, to ensure that we do not race each
       other again.
Added devdoc/parts/d_op_branch_import.inc.
































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32

Be aware of where you are (see first definition).

[para] Ensure that you have clean checkout (see second definition).
       It is [emph required].
       
[para] In most situations you want to import the latest commit of
       branch [term trunk] (or other origin). To get it use

[example {
    fossil pull
}]

[para] With that done we can now import this commit into our current
       branch with

[example {
    fossil merge trunk
}]

[para] Even if [syscmd fossil] does not report any conflicts it is a
       good idea to check that the operation has not broken the new
       and/or changed functionality we are working on.

[para] With the establishment of a good merge we then save the state
       with

[example {
    fossil commit ...
}]

before continuing development.
Added devdoc/parts/d_op_branch_open.inc.






















































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59

Be aware of where you are (see first definition).

[para] Ensure that you have clean checkout (see second definition).
       It is [emph required].

[para] In most situations you want to be on branch [term trunk], and
       you want to be on the latest commit for it. To get there use

[example {
    fossil pull
    fossil update trunk
}]

If some other branch is desired as the starting point for the coming
work replace [term trunk] in the commands above with the name of that
branch.

[para] With the base line established we now have two ways of creating
       the new branch, with differing (dis)advantages.

       The simpler way is to

[example {
    fossil branch new NAME_OF_NEW_BRANCH
}]

and start developing. The advantage here is that you cannot forget to
create the branch. The disadvantages are that we have a branch commit
unchanged from where we branched from, and that we have to use
high-handed techniques like hiding or shunning to get rid of the
commit should we decide to abandon the work before the first actual
commit on the branch.

[para] The other way of creating the branch is to start developing,
and then on the first commit use the option [option --branch] to tell
[syscmd fossil] that we are starting a branch now. I.e. run

[example {
    fossil commit --branch NAME_OF_NEW_BRANCH ...
}]

where [term ...] are any other options used to supply the commit
message, files to commit, etc.

[para] The (dis)advantages are now reversed.

[para] We have no superflous commit, only what is actually
       developed. The work is hidden until we commit to make our first
       commit.

[para] We may forget to use [option {--branch NAME_OF_NEW_BRANCH}] and
       then have to correct that oversight via the fossil web
       interface (I am currently unaware of ways of doing such from
       the command line, although some magic incantantion of
       [cmd {fossil tag create}] may work).

[para] It helps tp keep awareness, like checking before any commit
       that we are on the desired branch.
Added devdoc/parts/d_op_clean.inc.




























>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14

Be aware of where you are (see first definition).

[para] For pretty much all the operation recipes below a clean
       checkout is at least desired, often required.
       To check that a checkout is clean invoke

[example {
    fossil changes
    fossil extra
}]

How to clean up when uncommitted changes of all sorts are found is
context-specific and outside of the scope of this guide.
Changes to devdoc/tcllib_installer.man.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
[comment {-*- tcl -*- doctools manpage}]
[manpage_begin tcllib_install_guide n 1]
[titledesc {Tcllib - The Installer's Guide}]
[description]
[include parts/welcome.inc]

[para]

The audience of this document is anyone wishing to build the packages,
for either themselves, or others.

[para]

For a developer intending to extend or modify the packages we
additionally provide

[list_begin enum]
[enum] [term {Tcllib - The Developer's Guide}].
[list_end]

[para]








|
|



|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
[comment {-*- tcl -*- doctools manpage}]
[manpage_begin tcllib_install_guide n 1]
[titledesc {Tcllib - The Installer's Guide}]
[description]
[include parts/welcome.inc]

[para]

The audience of this document is anyone wishing to build and install
the packages found in Tcllib, for either themselves, or others.

[para]

For developers intending to work on the packages themselves we
additionally provide

[list_begin enum]
[enum] [term {Tcllib - The Developer's Guide}].
[list_end]

[para]
48
49
50
51
52
53
54




















55







56




57
58
59

[include parts/rq_tcl.inc]
[include parts/rq_critcl.inc]

[comment {= build instructions ==============================================}]
[section {Build & Installation Instructions}]





















[include parts/b_tooling.inc]







[include parts/b_critcl.inc]





[manpage_end]








>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
>
>
>
>
>

>
>
>
>



48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90

[include parts/rq_tcl.inc]
[include parts/rq_critcl.inc]

[comment {= build instructions ==============================================}]
[section {Build & Installation Instructions}]

As Tcllib is mainly a bundle of packages written in pure Tcl building
it is the same as installing it. The exceptions to this have their own
subsection, [sectref {Critcl & Accelerators}], later on.

[para] Before that however comes the standard case, differentiated by
       the platforms with material differences in the instruction, i.e.
       [term Unix]-like, versus [term Windows].

[para] Regarding the latter it should also be noted that it is
       possible set up an [term Unix]-like environment using projects
       like [term MSYS], [term Cygwin], and others. In that case the
       user has the choice of which instructions to follow.

[para] Regardless of environment or platform, a suitable [term Tcl]
       has to be installed, and its [syscmd tclsh] should be placed on
       the [variable PATH] ([term Unix]) or associated with
       [file .tcl] files ([term Windows]).

[comment %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%]
[subsection {Installing on Unix}]
[include parts/b_unix.inc]

[comment %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%]
[subsection {Installing on Windows}]
[include parts/b_windows.inc]

[comment %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%]
[subsection {Critcl & Accelerators}]
[include parts/b_critcl.inc]

[comment %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%]
[subsection Tooling]
[include parts/b_tooling.inc]

[manpage_end]

Changes to embedded/md/tcllib/files/devdoc/tcllib_devguide.md.
26
27
28
29
30
31
32




33
34


35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74

      - [Contributor](#subsection1)

      - [Maintainer](#subsection2)

  - [Branching and Workflow](#section3)





      - [Branches](#subsection3)



      - [Version numbers](#subsection4)

  - [Structural Overview](#section4)

      - [Main Directories](#subsection5)

      - [More Directories](#subsection6)

      - [Top Files](#subsection7)

      - [File Types](#subsection8)

  - [Testsuite Tooling](#section5)

      - [Invoke the testsuites of a specific module](#subsection9)

      - [Invoke the testsuites of all modules](#subsection10)

      - [Detailed Test Logs](#subsection11)

      - [Shell Selection](#subsection12)

      - [Help](#subsection13)

  - [Documentation Tooling](#section6)

      - [Generate documentation for a specific module](#subsection14)

      - [Generate documentation for all modules](#subsection15)

      - [Available output formats, help](#subsection16)

      - [Validation without output](#subsection17)

  - [Notes On Writing A Testsuite](#section7)

  - [Installation Tooling](#section8)

# <a name='synopsis'></a>SYNOPSIS








>
>
>
>
|

>
>
|



|

|

|

|



|

|

|

|

|



|

|

|

|







26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80

      - [Contributor](#subsection1)

      - [Maintainer](#subsection2)

  - [Branching and Workflow](#section3)

      - [Package Dependencies](#subsection3)

      - [Trunk](#subsection4)

      - [Branches](#subsection5)

      - [Working with Branches](#subsection6)

      - [Version numbers](#subsection7)

  - [Structural Overview](#section4)

      - [Main Directories](#subsection8)

      - [More Directories](#subsection9)

      - [Top Files](#subsection10)

      - [File Types](#subsection11)

  - [Testsuite Tooling](#section5)

      - [Invoke the testsuites of a specific module](#subsection12)

      - [Invoke the testsuites of all modules](#subsection13)

      - [Detailed Test Logs](#subsection14)

      - [Shell Selection](#subsection15)

      - [Help](#subsection16)

  - [Documentation Tooling](#section6)

      - [Generate documentation for a specific module](#subsection17)

      - [Generate documentation for all modules](#subsection18)

      - [Available output formats, help](#subsection19)

      - [Validation without output](#subsection20)

  - [Notes On Writing A Testsuite](#section7)

  - [Installation Tooling](#section8)

# <a name='synopsis'></a>SYNOPSIS

102
103
104
105
106
107
108
109
110

111
112
113
114
115
116
117
118
119
120
121
122
123
124
125


126
127
128
129
130
131
132

# <a name='section2'></a>Commitments

## <a name='subsection1'></a>Contributor

As a contributor to Tcllib you are committing yourself to:

  1. Follow the guidelines laid down in *[Tcl Community \- Kind
     Communication](tcl\_community\_communication\.md)*


  1. Your contributions getting distributed under a BSD/MIT license\. For the
     details see *[Tcllib \- License](tcllib\_license\.md)*

Contributions are made by entering tickets into our tracker, providing patches,
bundles or branches of code for inclusion, or posting to the Tcllib related
mailing lists\.

## <a name='subsection2'></a>Maintainer

When contributing one or more packages for full inclusion into Tcllib you are
committing yourself to

  1. Follow the guidelines laid down in *[Tcl Community \- Kind
     Communication](tcl\_community\_communication\.md)* \(as any contributor\)



  1. Your packages getting distributed under a BSD/MIT license\. For the details
     see *[Tcllib \- License](tcllib\_license\.md)*

  1. Maintenance of the new packages for a period of two years under the
     following rules, and responsibilities:








|
|
>













|
|
>
>







108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141

# <a name='section2'></a>Commitments

## <a name='subsection1'></a>Contributor

As a contributor to Tcllib you are committing yourself to:

  1. keep the guidelines written down in *[Tcl Community \- Kind
     Communication](tcl\_community\_communication\.md)* in your mind\. The main
     point to take away from there is *to be kind to each other*\.

  1. Your contributions getting distributed under a BSD/MIT license\. For the
     details see *[Tcllib \- License](tcllib\_license\.md)*

Contributions are made by entering tickets into our tracker, providing patches,
bundles or branches of code for inclusion, or posting to the Tcllib related
mailing lists\.

## <a name='subsection2'></a>Maintainer

When contributing one or more packages for full inclusion into Tcllib you are
committing yourself to

  1. Keep the guidelines written down in *[Tcl Community \- Kind
     Communication](tcl\_community\_communication\.md)* \(as any contributor\) in
     your mind\. The main point to take away from there is *to be kind to each
     other*\.

  1. Your packages getting distributed under a BSD/MIT license\. For the details
     see *[Tcllib \- License](tcllib\_license\.md)*

  1. Maintenance of the new packages for a period of two years under the
     following rules, and responsibilities:

168
169
170
171
172
173
174
175
176














































177
178
179
180
181
182
183
184
185
186
187
188

189
190
191
192
193
194
195
196
197
198





















































































































199



200

201


202

203


204




















































205
206











































207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
       1) Coordination and discussion with ticket submitter during the
          development and/or application of bug fixes\.

  1. Follow the [Branching and Workflow](#section3) of this guide\.

# <a name='section3'></a>Branching and Workflow

## <a name='subsection3'></a>Branches















































An important part of working with a *Distributed Version Control System*
\(*DVCS*\) like [fossil](https://www\.fossil\-scm\.org/) is the management and
use of branches\.

For Tcllib the main branch of the collection is *trunk*\. In *git* this
branch would be called *master*, and this exactly the case in the [github
mirror](https://github\.com/tcltk/tcllib/) of Tcllib\.

In support of debugging, like searching for when an issue appeared via
bisection, each commit on this branch must pass the entire testsuite of the
collection\.


As fossil has no mechanism to enforce this this is handled on the honor system
for developers and maintainers\.

To make the task easier Tcllib comes with a tool \("sak\.tcl"\) providing a number
of commands in support\. These commands are explained in the following sections
of this guide\.

While it is possible and allowed to commit directly to trunk remember the above
regarding the testsuite, and the coming notes about other possible issues with a
commit\.

























































































































Because of this it is \(strongly\) recommended to perform any development on a

nicely named \(nick of dev, ticket reference if any, keywords applicable to the


work, \.\.\.\) non\-trunk branch\. Outside of the trunk developers are allowed to

commit intermediate broken states of their work\. Only at the end, when the


branch is considered ready for merging will it be necessary to perform full




















































validation\.












































## <a name='subsection4'></a>Version numbers

In Tcllib all changes to a package have to come with an increment of its version
number\. What part is incremented \(patchlevel, minor, major version\) depends on
the kind of change made\. With multiple changes in a commit the highest "wins"\.

When working in a development branch the version change can be deferred until it
is time to merge, and then has to cover all the changes in the branch\.

Below a list of the kinds of changes and their association version increments:

  - *D \- documentation*

    No increment

  - *T \- testsuite*








|

>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
|
<





|
|
|

>
|
|






|
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>

>
>
>
|
>
|
>
>
|
>
|
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|

>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|








|







177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233

234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
       1) Coordination and discussion with ticket submitter during the
          development and/or application of bug fixes\.

  1. Follow the [Branching and Workflow](#section3) of this guide\.

# <a name='section3'></a>Branching and Workflow

## <a name='subsection3'></a>Package Dependencies

Regarding packages and dependencies between them Tcllib occupies a middle
position between two extremes:

  1. On one side a strongly interdependent set of packages, usually by a single
     author, for a single project\. Looking at my \(Andreas Kupries\) own work
     examples of such are [Marpa](https://core\.tcl\.tk/akupries/marpa/index),
     [CRIMP](https://core\.tcl\.tk/akupries/crimp/index),
     [Kinetcl](https://core\.tcl\.tk/akupries/kinetcl/index), etc\.

     For every change the author of the project handles all the modifications
     cascading from any incompatibilities it introduced to the system\.

  1. On the other side, the world of semi\-independent projects by many different
     authors where authors know what packages their own creations depend on, yet
     usually do not know who else depends on them\.

     The best thing an author making an \(incompatible\) change to their project
     can do is to for one announce such changes in some way, and for two use
     versioning to distinguish the code before and after the change\.

     The world is then responsible for adapting, be it by updating their own
     projects to the new version, or by sticking to the old\.

As mentioned already, Tcllib lives in the middle of that\.

While we as maintainers cannot be aware of all users of Tcllib's packages, and
thus have to rely on the mechanisms touched on in point 2 above for that, the
dependencies between the packages contained in Tcllib are a different matter\.

As we are collectively responsible for the usability of Tcllib in toto to the
outside world, it behooves us to be individually mindful even of Tcllib packages
we are not directly maintaining, when they depend on packages under our
maintainership\. This may be as simple as coordinating with the maintainers of
the affected packages\. It may also require us to choose how to adapt affected
packages which do not have maintainers, i\.e\. modify them to use our changed
package properly, or modify them to properly depend on the unchanged version of
our package\.

Note that the above is not only a chore but an opportunity as well\. Additional
insight can be had by forcing ourselves to look at our package and the planned
change\(s\) from an outside perspective, to consider the ramafications of our
actions on others in general, and on dependent packages in particular\.

## <a name='subsection4'></a>Trunk

The management and use of branches is an important part of working with a
*Distributed Version Control System* \(*DVCS*\) like
[fossil](https://www\.fossil\-scm\.org/)\.


For Tcllib the main branch of the collection is *trunk*\. In *git* this
branch would be called *master*, and this exactly the case in the [github
mirror](https://github\.com/tcltk/tcllib/) of Tcllib\.

To properly support debugging *each commit* on this branch *has to pass the
entire testsuite* of the collection\. Using bisection to determine when an issue
appeared is an example of an action made easier by this constraint\.

This is part of our collective responsibility for the usability of Tcllib in
toto to the outside world\. As *fossil* has no mechanism to enforce this
condition this is handled on the honor system for developers and maintainers\.

To make the task easier Tcllib comes with a tool \("sak\.tcl"\) providing a number
of commands in support\. These commands are explained in the following sections
of this guide\.

While it is possible and allowed to commit directly to trunk remember the above
constraint regarding the testsuite, and the coming notes about other possible
issues with a commit\.

## <a name='subsection5'></a>Branches

Given the constraints placed on the *trunk* branch of the repository it is
\(strongly\) recommended to perform any development going beyond trivial changes
on a non\-trunk branch\.

Outside of the trunk developers are allowed to commit intermediate broken states
of their work\. Only at the end of a development cycle, when the relevant branch
is considered ready for merging, will it be necessary to perform full the set of
validations ensuring that the merge to come will create a good commit on trunk\.

Note that while a review from a second developer is not a required condition for
merging a branch it is recommended to seek out such an independent opinion as a
means of cross\-checking the work\.

It also recommended to give any new branch a name which aids in determining
additional details about it\. Examples of good things to stick into a branch name
would be

  - Developer \(nick\)name

  - Ticket hash/reference

  - One or two keywords applicable to the work

  - \.\.\.

Further, while most development branches are likely quite short\-lived, no
prohibitions exist against making longer\-lived branches\. Creators should however
be mindful that the longer such a branch exists without merges the more
divergent they will tend to be, with an associated increase in the effort which
will have to be spent on either merging from and merging to trunk\.

## <a name='subsection6'></a>Working with Branches

In the hope of engendering good work practices now a few example operations
which will come up with branches, and their associated fossil command
\(sequences\)\.

  - *Awareness*

    When developing we have to keep ourselves aware of the context of our work\.
    On what branch are we ? What files have we changed ? What new files are not
    yet known to the repository ? This becomes especially important when using a
    long\-lived checkout and coming back to it after some time away\.

    Commands to answer questions like the above are:

      * __fossil info &#124; grep tags__

      * __fossil branch list &#124; grep '\\\*'__

        Two different ways of determining the branch our checkout is on\.

      * __fossil timeline__

        What have we \(and others\) done recently ?

        *Attention*, this information is very likely outdated, the more the
        longer we did not use this checkout\. Run __fossil pull__ first to
        get latest information from the remote repository of the project\.

      * __fossil timeline current__

        Place the commit our checkout is based on at the top of the timeline\.

      * __fossil changes__

        Lists the files we have changed compared to the commit the checkout is
        based on\.

      * __fossil extra__

        Lists the files we have in the checkout the repository does not know
        about\. This may be leftover chaff from our work, or something we have
        forgotten to __fossil add__ to the repository yet\.

  - *Clean checkouts*

    Be aware of where you are \(see first definition\)\.

    For pretty much all the operation recipes below a clean checkout is at least
    desired, often required\. To check that a checkout is clean invoke

        fossil changes
        fossil extra

    How to clean up when uncommitted changes of all sorts are found is
    context\-specific and outside of the scope of this guide\.

  - *Starting a new branch*

    Be aware of where you are \(see first definition\)\.

    Ensure that you have clean checkout \(see second definition\)\. It is
    *required*\.

    In most situations you want to be on branch *trunk*, and you want to be on
    the latest commit for it\. To get there use

        fossil pull
        fossil update trunk

    If some other branch is desired as the starting point for the coming work
    replace *trunk* in the commands above with the name of that branch\.

    With the base line established we now have two ways of creating the new
    branch, with differing \(dis\)advantages\. The simpler way is to

        fossil branch new NAME\_OF\_NEW\_BRANCH

    and start developing\. The advantage here is that you cannot forget to create
    the branch\. The disadvantages are that we have a branch commit unchanged
    from where we branched from, and that we have to use high\-handed techniques
    like hiding or shunning to get rid of the commit should we decide to abandon
    the work before the first actual commit on the branch\.

    The other way of creating the branch is to start developing, and then on the
    first commit use the option __\-\-branch__ to tell __fossil__ that we
    are starting a branch now\. I\.e\. run

        fossil commit \-\-branch NAME\_OF\_NEW\_BRANCH \.\.\.

    where *\.\.\.* are any other options used to supply the commit message, files
    to commit, etc\.

    The \(dis\)advantages are now reversed\.

    We have no superflous commit, only what is actually developed\. The work is
    hidden until we commit to make our first commit\.

    We may forget to use __\-\-branch NAME\_OF\_NEW\_BRANCH__ and then have to
    correct that oversight via the fossil web interface \(I am currently unaware
    of ways of doing such from the command line, although some magic
    incantantion of __fossil tag create__ may work\)\.

    It helps tp keep awareness, like checking before any commit that we are on
    the desired branch\.

  - *Merging a branch into trunk*

    Be aware of where you are \(see first definition\)\.

    Ensure that you have clean checkout \(see second definition\)\. In the
    full\-blown sequence \(zig\-zag\) it is *required*, due to the merging from
    trunk\. In the shorter sequence it is only desired\. That said, keeping the
    checkout clean before any major operations is a good habit to have, in my
    opinion\.

    The full\-blown sequencing with checks all the way is to

    Validate the checkout, i\.e\. last commit on your branch\. Run the full test
    suite and other validations, fix all the issues which have cropped up\.

    Merge the latest state of the *trunk* \(see next definition\)\.

    Validate the checkout again\. The incoming trunk changes may have broken
    something now\. Do any required fixes\.

    Now merge to the trunk using

        fossil update trunk
        fossil merge \-\-integrate YOU\_BRANCH

    At this point the checkout should be in the same state as at the end of
    point \(3\) above, because we resolved any issues with the trunk already\. Thus
    a simple

        fossil commit \.\.\.

    should be sufficient now to commit the merge back and close the branch \(due
    to the __\-\-integrate__ we used on the merge\)\.

    The more paranoid may validate the checkout a third time before commiting\.

    I call this a *zig\-zag merge* because of how the arrows look in the
    timeline, from trunk to feature branch for the first merge, and then back
    for the final merge\.

    A less paranoid can do what I call a *simple merge*, which moves step \(2\)
    after step \(4\) and skips step \(3\) entirely\. The resulting shorter sequence
    is

    Validate

    Merge to trunk

    Validate again

    Commit to trunk

    The last step after either zig\-zag or plain merge is to

        fossil sync

    This saves our work to the remote side, and further gives us any other work
    done while we were doing our merge\. It especially allows us to check if we
    raced somebody else, resulting in a split trunk\.

    When that happens we should coordinate with the other developer on who fixes
    the split, to ensure that we do not race each other again\.

  - *Merging from trunk*

    Be aware of where you are \(see first definition\)\.

    Ensure that you have clean checkout \(see second definition\)\. It is
    *required*\.

    In most situations you want to import the latest commit of branch *trunk*
    \(or other origin\)\. To get it use

        fossil pull

    With that done we can now import this commit into our current branch with

        fossil merge trunk

    Even if __fossil__ does not report any conflicts it is a good idea to
    check that the operation has not broken the new and/or changed functionality
    we are working on\.

    With the establishment of a good merge we then save the state with

        fossil commit \.\.\.

    before continuing development\.

## <a name='subsection7'></a>Version numbers

In Tcllib all changes to a package have to come with an increment of its version
number\. What part is incremented \(patchlevel, minor, major version\) depends on
the kind of change made\. With multiple changes in a commit the highest "wins"\.

When working in a development branch the version change can be deferred until it
is time to merge, and then has to cover all the changes in the branch\.

Below a list of the kinds of changes and their associated version increments:

  - *D \- documentation*

    No increment

  - *T \- testsuite*

239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275

    Minor

  - *API \- incompatible change*

    Major

Note, a commit containing a version increment has to mention the kind of change
which caused it in the commit message, as well as the new version number\.

Note further that the version number of a package currently exists in 3 places\.
An increment has to update all of them:

  1. The package implementation\.

  1. The package index \("pkgIndex\.tcl"\)

  1. The package documentation\.

The "sak\.tcl" command __validate version__ helps finding discrepancies
between the first two\. All the other __validate__ methods are also of
interest to any developer\. Invoke it with

    sak\.tcl help validate

to see their documentation\.

# <a name='section4'></a>Structural Overview

## <a name='subsection5'></a>Main Directories

The main directories in the Tcllib toplevel directory and of interest to a
developer are:

  - "modules"

    Each child directory represents one or more packages\. In the case of the







|
|

|
|

















|







515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551

    Minor

  - *API \- incompatible change*

    Major

Note that a commit containing a version increment has to mention the new version
number in its commit message, as well as the kind of change which caused it\.

Note further that the version number of a package currently exists in three
places\. An increment has to update all of them:

  1. The package implementation\.

  1. The package index \("pkgIndex\.tcl"\)

  1. The package documentation\.

The "sak\.tcl" command __validate version__ helps finding discrepancies
between the first two\. All the other __validate__ methods are also of
interest to any developer\. Invoke it with

    sak\.tcl help validate

to see their documentation\.

# <a name='section4'></a>Structural Overview

## <a name='subsection8'></a>Main Directories

The main directories in the Tcllib toplevel directory and of interest to a
developer are:

  - "modules"

    Each child directory represents one or more packages\. In the case of the
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299

  - "examples"

    Each child directory "foo" contains one or more example application for the
    packages in "modules/foo"\. These examples are generally not polished enough
    to be considered for installation\.

## <a name='subsection6'></a>More Directories

  - "config"

    This directory contains files supporting the Unix build system, i\.e\.
    "configure" and "Makefile\.in"\.

  - "devdoc"







|







561
562
563
564
565
566
567
568
569
570
571
572
573
574
575

  - "examples"

    Each child directory "foo" contains one or more example application for the
    packages in "modules/foo"\. These examples are generally not polished enough
    to be considered for installation\.

## <a name='subsection9'></a>More Directories

  - "config"

    This directory contains files supporting the Unix build system, i\.e\.
    "configure" and "Makefile\.in"\.

  - "devdoc"
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
    is the documentation which will be installed\.

  - "support"

    This directory contains the sources of internal packages and utilities used
    in the implementation of the "installer\.tcl" and "sak\.tcl" scripts/tools\.

## <a name='subsection7'></a>Top Files

  - "aclocal\.m4"

  - "configure"

  - "configure\.in"








|







594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
    is the documentation which will be installed\.

  - "support"

    This directory contains the sources of internal packages and utilities used
    in the implementation of the "installer\.tcl" and "sak\.tcl" scripts/tools\.

## <a name='subsection10'></a>Top Files

  - "aclocal\.m4"

  - "configure"

  - "configure\.in"

381
382
383
384
385
386
387
388
389
390
391
392
393
394
395

  - "tcllib\.tap"

  - "tcllib\.yml"

    ????

## <a name='subsection8'></a>File Types

The most common file types, by file extension, are:

  - "\.tcl"

    Tcl code for a package, application, or example\.








|







657
658
659
660
661
662
663
664
665
666
667
668
669
670
671

  - "tcllib\.tap"

  - "tcllib\.yml"

    ????

## <a name='subsection11'></a>File Types

The most common file types, by file extension, are:

  - "\.tcl"

    Tcl code for a package, application, or example\.

417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
plus utilities found in the directory "modules/devtools"

Tcllib developers invoke the suites through the __test run__ method of the
"sak\.tcl" tool, with other methods of __[test](\.\./\.\./\.\./index\.md\#test)__
providing management operations, for example setting a list of standard Tcl
shells to use\.

## <a name='subsection9'></a>Invoke the testsuites of a specific module

Invoke either

    \./sak\.tcl test run foo

or

    \./sak\.tcl test run modules/foo

to invoke the testsuites found in a specific module "foo"\.

## <a name='subsection10'></a>Invoke the testsuites of all modules

Invoke the tool without a module name, i\.e\.

    \./sak\.tcl test run

to invoke the testsuites of all modules\.

## <a name='subsection11'></a>Detailed Test Logs

In all the previous examples the test runner will write a combination of
progress display and testsuite log to the standard output, showing for each
module only the tests that passed or failed and how many of each in a summary at
the end\.

To get a detailed log, it is necessary to invoke the test runner with additional







|











|







|







693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
plus utilities found in the directory "modules/devtools"

Tcllib developers invoke the suites through the __test run__ method of the
"sak\.tcl" tool, with other methods of __[test](\.\./\.\./\.\./index\.md\#test)__
providing management operations, for example setting a list of standard Tcl
shells to use\.

## <a name='subsection12'></a>Invoke the testsuites of a specific module

Invoke either

    \./sak\.tcl test run foo

or

    \./sak\.tcl test run modules/foo

to invoke the testsuites found in a specific module "foo"\.

## <a name='subsection13'></a>Invoke the testsuites of all modules

Invoke the tool without a module name, i\.e\.

    \./sak\.tcl test run

to invoke the testsuites of all modules\.

## <a name='subsection14'></a>Detailed Test Logs

In all the previous examples the test runner will write a combination of
progress display and testsuite log to the standard output, showing for each
module only the tests that passed or failed and how many of each in a summary at
the end\.

To get a detailed log, it is necessary to invoke the test runner with additional
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
    \./sak\.tcl test run \-v foo

This writes the detailed log to the standard output, instead of the short log\.

Regardless of form, the detailed log contains a list of all test cases executed,
which failed, and how they failed \(expected versus actual results\)\.

## <a name='subsection12'></a>Shell Selection

By default the test runner will use all the Tcl shells specified via __test
add__ to invoke the specified testsuites, if any\. If no such are specified it
will fall back to the Tcl shell used to run the tool itself\.

Use option __\-\-shell__ to explicitly specify the Tcl shell to use, like

    \./sak\.tcl test run \-\-shell /path/to/tclsh \.\.\.

## <a name='subsection13'></a>Help

Invoke the tool as

    \./sak\.tcl help test

to see the detailed help for all methods of
__[test](\.\./\.\./\.\./index\.md\#test)__, and the associated options\.

# <a name='section6'></a>Documentation Tooling

The standard format used for documentation of packages and other things in
Tcllib is *[doctools](\.\./\.\./\.\./index\.md\#doctools)*\. Its supporting
packages are a part of Tcllib, see the directories "modules/doctools" and
"modules/dtplite"\. The latter is an application package, with the actual
application "apps/dtplite" a light wrapper around it\.

Tcllib developers gain access to these through the __doc__ method of the
"sak\.tcl" tool, another \(internal\) wrapper around the "modules/dtplite"
application package\.

## <a name='subsection14'></a>Generate documentation for a specific module

Invoke either

    \./sak\.tcl doc html foo

or

    \./sak\.tcl doc html modules/foo

to generate HTML for the documentation found in the module "foo"\. Instead of
__html__ any other supported format can be used here, of course\.

The generated formatted documentation will be placed into a directory "doc" in
the current working directory\.

## <a name='subsection15'></a>Generate documentation for all modules

Invoke the tool without a module name, i\.e\.

    \./sak\.tcl doc html

to generate HTML for the documentation found in all modules\. Instead of
__html__ any other supported format can be used here, of course\.

The generated formatted documentation will be placed into a directory "doc" in
the current working directory\.

## <a name='subsection16'></a>Available output formats, help

Invoke the tool as

    \./sak\.tcl help doc

to see the entire set of supported output formats which can be generated\.

## <a name='subsection17'></a>Validation without output

Note the special format __validate__\.

Using this value as the name of the format to generate forces the tool to simply
check that the documentation is syntactically correct, without generating actual
output\.








|









|




















|















|











|







|







740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
    \./sak\.tcl test run \-v foo

This writes the detailed log to the standard output, instead of the short log\.

Regardless of form, the detailed log contains a list of all test cases executed,
which failed, and how they failed \(expected versus actual results\)\.

## <a name='subsection15'></a>Shell Selection

By default the test runner will use all the Tcl shells specified via __test
add__ to invoke the specified testsuites, if any\. If no such are specified it
will fall back to the Tcl shell used to run the tool itself\.

Use option __\-\-shell__ to explicitly specify the Tcl shell to use, like

    \./sak\.tcl test run \-\-shell /path/to/tclsh \.\.\.

## <a name='subsection16'></a>Help

Invoke the tool as

    \./sak\.tcl help test

to see the detailed help for all methods of
__[test](\.\./\.\./\.\./index\.md\#test)__, and the associated options\.

# <a name='section6'></a>Documentation Tooling

The standard format used for documentation of packages and other things in
Tcllib is *[doctools](\.\./\.\./\.\./index\.md\#doctools)*\. Its supporting
packages are a part of Tcllib, see the directories "modules/doctools" and
"modules/dtplite"\. The latter is an application package, with the actual
application "apps/dtplite" a light wrapper around it\.

Tcllib developers gain access to these through the __doc__ method of the
"sak\.tcl" tool, another \(internal\) wrapper around the "modules/dtplite"
application package\.

## <a name='subsection17'></a>Generate documentation for a specific module

Invoke either

    \./sak\.tcl doc html foo

or

    \./sak\.tcl doc html modules/foo

to generate HTML for the documentation found in the module "foo"\. Instead of
__html__ any other supported format can be used here, of course\.

The generated formatted documentation will be placed into a directory "doc" in
the current working directory\.

## <a name='subsection18'></a>Generate documentation for all modules

Invoke the tool without a module name, i\.e\.

    \./sak\.tcl doc html

to generate HTML for the documentation found in all modules\. Instead of
__html__ any other supported format can be used here, of course\.

The generated formatted documentation will be placed into a directory "doc" in
the current working directory\.

## <a name='subsection19'></a>Available output formats, help

Invoke the tool as

    \./sak\.tcl help doc

to see the entire set of supported output formats which can be generated\.

## <a name='subsection20'></a>Validation without output

Note the special format __validate__\.

Using this value as the name of the format to generate forces the tool to simply
check that the documentation is syntactically correct, without generating actual
output\.

Changes to embedded/md/tcllib/files/devdoc/tcllib_installer.md.
24
25
26
27
28
29
30




31


32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50

      - [Tcl](#subsection1)

      - [Critcl](#subsection2)

  - [Build & Installation Instructions](#section3)





      - [Critcl & Accelerators](#subsection3)



# <a name='description'></a>DESCRIPTION

Welcome to Tcllib, the Tcl Standard Library\. Note that Tcllib is not a package
itself\. It is a collection of \(semi\-independent\)
*[Tcl](\.\./\.\./\.\./index\.md\#tcl)* packages that provide utility functions
useful to a large collection of Tcl programmers\.

The audience of this document is anyone wishing to build the packages, for
either themselves, or others\.

For a developer intending to extend or modify the packages we additionally
provide

  1. *[Tcllib \- The Developer's Guide](tcllib\_devguide\.md)*\.

Please read *[Tcllib \- How To Get The Sources](tcllib\_sources\.md)* first,
if that was not done already\. Here we assume that the sources are already
available in a directory of your choice\.







>
>
>
>
|
>
>








|
|

|







24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56

      - [Tcl](#subsection1)

      - [Critcl](#subsection2)

  - [Build & Installation Instructions](#section3)

      - [Installing on Unix](#subsection3)

      - [Installing on Windows](#subsection4)

      - [Critcl & Accelerators](#subsection5)

      - [Tooling](#subsection6)

# <a name='description'></a>DESCRIPTION

Welcome to Tcllib, the Tcl Standard Library\. Note that Tcllib is not a package
itself\. It is a collection of \(semi\-independent\)
*[Tcl](\.\./\.\./\.\./index\.md\#tcl)* packages that provide utility functions
useful to a large collection of Tcl programmers\.

The audience of this document is anyone wishing to build and install the
packages found in Tcllib, for either themselves, or others\.

For developers intending to work on the packages themselves we additionally
provide

  1. *[Tcllib \- The Developer's Guide](tcllib\_devguide\.md)*\.

Please read *[Tcllib \- How To Get The Sources](tcllib\_sources\.md)* first,
if that was not done already\. Here we assume that the sources are already
available in a directory of your choice\.
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
distribution, and *not* *[Tcllib](\.\./\.\./\.\./index\.md\#tcllib)*\.

## <a name='subsection2'></a>Critcl

The __critcl__ tool is an *optional* dependency\.

It is only required when trying to build the C\-based *accelerators* for a
number of packages, as explained in [Critcl & Accelerators](#subsection3)

Tcllib's build system looks for it in the , using the name __critcl__\. This
is for Unix\. On Windows on the other hand the search is more complex\. First we
look for a proper application __critcl\.exe__\. When that is not found we look
for a combination of interpreter \(__tclkitsh\.exe__, __tclsh\.exe__\) and
starkit \(__critcl\.kit__, __critcl__\) instead\. *Note* that the choice
of starkit can be overriden via the environment variable \.







|







113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
distribution, and *not* *[Tcllib](\.\./\.\./\.\./index\.md\#tcllib)*\.

## <a name='subsection2'></a>Critcl

The __critcl__ tool is an *optional* dependency\.

It is only required when trying to build the C\-based *accelerators* for a
number of packages, as explained in [Critcl & Accelerators](#subsection5)

Tcllib's build system looks for it in the , using the name __critcl__\. This
is for Unix\. On Windows on the other hand the search is more complex\. First we
look for a proper application __critcl\.exe__\. When that is not found we look
for a combination of interpreter \(__tclkitsh\.exe__, __tclsh\.exe__\) and
starkit \(__critcl\.kit__, __critcl__\) instead\. *Note* that the choice
of starkit can be overriden via the environment variable \.
133
134
135
136
137
138
139
140
141
142
143
144
145

146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166

167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188

189
190
191

192

193
194


195
196
197

198
199
200
201

202
203
204
205
206
207
208
209

210
211
212

213
214

215
216
217
218
219
220

221
222
223
224
225
226
227
228
229
230
231
232
233
234
235


















































































































including a list of its dependencies\.

Its instructions will not be repeated here\. If there are problems with these
directions please file a ticket against the *Critcl* project, and not Tcllib\.

# <a name='section3'></a>Build & Installation Instructions

The Tcllib distribution, whether a checkout directly from the source repository,
or an official release, offers a single method for installing it, based on Tcl
itself\.

This is based on the assumption that for Tcllib to be of use Tcl has to be
present, and therefore can be used in the implementation of the install code\.


The relevant tool is the "installer\.tcl" script found in the toplevel directory
of a checkout or release\.

It can be used in a variety of ways:

  1. It is always possible to invoke the tool directly, either as

         \./installer\.tcl

     or

         /path/to/tclsh \./installer\.tcl

     The second form is required on Windows \(without a Unix emulation\), except
     if the Tcl installation is configured to handle "\.tcl" files on a
     double\-click\.

  1. In a Unix\-type environment, i\.e\. Linux, BSD and related, including OS X,
     and Windows using some kind of unix\-emulation like __MSYS__,
     __Cygwin__, etc\.\) it is also possible to use


         \./configure
         make install

     in the toplevel directory of Tcllib itself\.

     To build in a directory "D" outside of Tcllib's toplevel directory simply
     make "D" the current working directory and invoke __configure__ with
     either its absolute path or a proper relative path\.

     This will non\-interactively install all packages, applications found in
     Tcllib, and their manpages, in directories derived from what
     __configure__ found out about the system\.

The installer selects automatically either a GUI based mode, or a command line
based mode\. If the package __[Tk](\.\./\.\./\.\./index\.md\#tk)__ is present and
can be loaded, then the GUI mode is entered, else the system falls back to the
command line\.

Note that it is possible to specify options on the command line even if the
installer ultimatively selects GUI mode\. In that case the hardwired defaults and
the options determine the data presented to the user for editing\.


Command line help can be asked for by using the option __\-help__ when
invoking the installer, i\.e\.



    \./installer\.tcl \-help



This will print a short list of the available options to the standard output
channel\. For more examples see the various *install* targets found in
"Makefile\.in"\.


The installer will select a number of defaults for the locations of packages,
examples, and documentation, and also the format of the documentation\. The user
can overide these defaults in the GUI, or by specifying additional options\.


The defaults depend on the platform detected \(Unix/Windows\) and on the
__tclsh__ executable used to run the installer\.

*Attention* The installer will overwrite an existing installation of a Tcllib
with the same version without asking back after the initial confirmation is
given\. Further if the user chooses the same directory as chosen for/by previous
installations then these will be overwritten as well\.


## <a name='subsection3'></a>Critcl & Accelerators


A number of packages come with *accelerators*, i\.e\. __critcl__\-based C
code whose use will boost the performance of the packages using them\. As these

accelerators are optional they are not installed by default\.

To build the accelerators the normally optional dependency on __critcl__
becomes required\.

To install Tcllib with the accelerators in a Unix\-type environment invoke:


    \./configure
    make critcl \# This builds the shared library holding
                \# the accelerators
    make install

The underlying tool is "sak\.tcl" in the toplevel directory of Tcllib and the
command __make critcl__ is just a wrapper around

    \./sak\.tcl critcl

Therefore in a Windows environment instead invoke

    /path/to/tclsh \./sak\.tcl critcl
    /path/to/tclsh \./installer\.tcl

























































































































|
|
|

|
|
>

<
|
|
|

|
|
<
|
|

<
|
<
<
<

|
<
<
>

|
|

<
|
<
<
<
|
|
<
<

|
<
<
<

<
|
|
>

<
<
>

>
|

>
>
|
<
<
>

|
<
<
>

<
|

<
<
<
<
>

|

>
|
|
>
|




|
>













|
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153

154
155
156
157
158
159

160
161
162

163



164
165


166
167
168
169
170

171



172
173


174
175



176

177
178
179
180


181
182
183
184
185
186
187
188


189
190
191


192
193

194
195




196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
including a list of its dependencies\.

Its instructions will not be repeated here\. If there are problems with these
directions please file a ticket against the *Critcl* project, and not Tcllib\.

# <a name='section3'></a>Build & Installation Instructions

As Tcllib is mainly a bundle of packages written in pure Tcl building it is the
same as installing it\. The exceptions to this have their own subsection,
[Critcl & Accelerators](#subsection5), later on\.

Before that however comes the standard case, differentiated by the platforms
with material differences in the instruction, i\.e\. *Unix*\-like, versus
*Windows*\.


Regarding the latter it should also be noted that it is possible set up an
*Unix*\-like environment using projects like *MSYS*, *Cygwin*, and others\.
In that case the user has the choice of which instructions to follow\.

Regardless of environment or platform, a suitable
*[Tcl](\.\./\.\./\.\./index\.md\#tcl)* has to be installed, and its __tclsh__

should be placed on the \(*Unix*\) or associated with "\.tcl" files
\(*Windows*\)\.


## <a name='subsection3'></a>Installing on Unix




For *Unix*\-like environments Tcllib comes with the standard set of files to


make

    \./configure
    make install


a suitable way of installing it\. This is a standard non\-interactive install



automatically figuring out where to place everything, i\.e\. packages,
applications, and the manpages\.



To get a graphical installer invoke





    \./installer\.tcl

instead\.



## <a name='subsection4'></a>Installing on Windows

In a Windows environment we have the __installer\.tcl__ script to perform
installation\.

If the desired __tclsh__ is associated "\.tcl" files then double\-clicking /
opening the __installer\.tcl__ is enough to invoke it in graphical mode\. This
assumes that *[Tk](\.\./\.\./\.\./index\.md\#tk)* is installed and available as


well\.

Without *[Tk](\.\./\.\./\.\./index\.md\#tk)* the only way to invoke the installer


are to open a DOS window, i\.e\. __cmd\.exe__, and then to invoke


    \./installer\.tcl





inside it\.

## <a name='subsection5'></a>Critcl & Accelerators

While the majority of Tcllib consists of packages written in pure Tcl a number
of packages also have *accelerators* associated with them\. These are
__critcl__\-based C packages whose use will boost the performance of the
packages using them\. These accelerators are optional, and they are not installed
by default\.

To build the accelerators the normally optional dependency on __critcl__
becomes required\.

To build and install Tcllib with the accelerators in a Unix\-like environment
invoke:

    \./configure
    make critcl \# This builds the shared library holding
                \# the accelerators
    make install

The underlying tool is "sak\.tcl" in the toplevel directory of Tcllib and the
command __make critcl__ is just a wrapper around

    \./sak\.tcl critcl

Therefore in a Windows environment instead invoke

    \./sak\.tcl critcl
    \./installer\.tcl

from within a DOS window, i\.e\. __cmd\.exe__\.

## <a name='subsection6'></a>Tooling

The core of Tcllib's build system is the script "installer\.tcl" found in the
toplevel directory of a checkout or release\.

The

    configure ; make install

setup available to developers on Unix\-like systems is just a wrapper around it\.
To go beyond the standard embodied in the wrapper it is necessary to directly
invoke this script\.

On Windows system using it directly is the only way to invoke it\.

For basic help invoke it as

    \./installer\.tcl \-help

This will print a short list of all the available options to the standard output
channel\.

The commands associated with the various *install* targets in the
*Makefile\.in* for Unix can be used as additional examples on how to use this
tool as well\.

The installer can operate in GUI and CLI modes\. By default it chooses the mode
automatically, based on if the Tcl package
__[Tk](\.\./\.\./\.\./index\.md\#tk)__ can be used or not\. The option
__\-no\-gui__ can be used to force CLI mode\.

Note that it is possible to specify options on the command line even if the
installer ultimatively selects GUI mode\. In that case the hardwired defaults and
the options determine the data presented to the user for editing\.

The installer will select a number of defaults for the locations of packages,
examples, and documentation, and also the format of the documentation\. The user
can overide these defaults in the GUI, or by specifying additional options\. The
defaults depend on the platform detected \(Unix/Windows\) and on the __tclsh__
executable used to run the installer\.

*Options*

  - __\-help__

    Show the list of options explained here on the standard output channel and
    exit\.

  - __\+excluded__

    Include deprecated packages in the installation\.

  - __\-no\-gui__

    Force command line operation of the installer

  - __\-no\-wait__

    In CLI mode the installer will by default ask the user to confirm that the
    chosen configuration \(destination paths, things to install\) is correct
    before performing any action\. Using this option causes the installer to skip
    this query and immediately jump to installation\.

  - __\-app\-path__ *path*

  - __\-example\-path__ *path*

  - __\-html\-path__ *path*

  - __\-nroff\-path__ *path*

  - __\-pkg\-path__ *path*

    Declare the destination paths for the applications, examples, html
    documentation, nroff manpages, and packages\. The defaults are derived from
    the location of the __tclsh__ used to run the installer\.

  - __\-dry\-run__

  - __\-simulate__

    Run the installer without modifying the destination directories\.

  - __\-apps__

  - __\-no\-apps__

  - __\-examples__

  - __\-no\-examples__

  - __\-pkgs__

  - __\-no\-pkgs__

  - __\-html__

  - __\-no\-html__

  - __\-nroff__

  - __\-no\-nroff__

    \(De\)activate the installation of applications, examples, packages, html
    documentation, and nroff manpages\.

    Applications, examples, and packages are installed by default\.

    On Windows the html documentation is installed by default\.

    On Unix the nroff manpages are installed by default\.
Changes to idoc/man/files/devdoc/tcllib_devguide.n.
304
305
306
307
308
309
310
311
312


313
314
315
316
317
318
319
320
321
322
323
324
325
326

327
328
329
330
331
332
333
do so\&. The guide to the sources in particular also explains which
source code management system is used, where to find it, how to set it
up, etc\&.
.SH COMMITMENTS
.SS CONTRIBUTOR
As a contributor to Tcllib you are committing yourself to:
.IP [1]
Follow the guidelines laid down in
\fITcl Community - Kind Communication\fR


.IP [2]
Your contributions getting distributed under a BSD/MIT license\&.
For the details see \fITcllib - License\fR
.PP
Contributions are made by entering tickets into our tracker, providing
patches, bundles or branches of code for inclusion, or posting to the
Tcllib related mailing lists\&.
.SS MAINTAINER
When contributing one or more packages for full inclusion into Tcllib
you are committing yourself to
.IP [1]
Follow the guidelines laid down in
\fITcl Community - Kind Communication\fR
(as any contributor)

.IP [2]
Your packages getting distributed under a BSD/MIT license\&.  For
the details see \fITcllib - License\fR
.IP [3]
Maintenance of the new packages for a period of two years under
the following rules, and responsibilities:
.RS







|
|
>
>











|

|
>







304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
do so\&. The guide to the sources in particular also explains which
source code management system is used, where to find it, how to set it
up, etc\&.
.SH COMMITMENTS
.SS CONTRIBUTOR
As a contributor to Tcllib you are committing yourself to:
.IP [1]
keep the guidelines written down in
\fITcl Community - Kind Communication\fR in your mind\&.
The main point to take away from there is
\fIto be kind to each other\fR\&.
.IP [2]
Your contributions getting distributed under a BSD/MIT license\&.
For the details see \fITcllib - License\fR
.PP
Contributions are made by entering tickets into our tracker, providing
patches, bundles or branches of code for inclusion, or posting to the
Tcllib related mailing lists\&.
.SS MAINTAINER
When contributing one or more packages for full inclusion into Tcllib
you are committing yourself to
.IP [1]
Keep the guidelines written down in
\fITcl Community - Kind Communication\fR
(as any contributor) in your mind\&. The main point to take away
from there is \fIto be kind to each other\fR\&.
.IP [2]
Your packages getting distributed under a BSD/MIT license\&.  For
the details see \fITcllib - License\fR
.IP [3]
Maintenance of the new packages for a period of two years under
the following rules, and responsibilities:
.RS
377
378
379
380
381
382
383






















































384
385
386
387
388
389
390
391
392
393

394
395
396
397

398


399
400
401
402
403
404

405
406
407
408





























409


























































410
411


412





























































































413
414


415




























































































416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
Coordination and discussion with ticket submitter during
the development and/or application of bug fixes\&.
.RE
.IP [4]
Follow the \fBBranching and Workflow\fR of this guide\&.
.PP
.SH "BRANCHING AND WORKFLOW"






















































.SS BRANCHES
An important part of working with a
\fIDistributed Version Control System\fR (\fIDVCS\fR) like
\fIfossil\fR [https://www\&.fossil-scm\&.org/]
is the management and use of branches\&.
.PP
For Tcllib the main branch of the collection is
\fItrunk\fR\&. In \fIgit\fR this branch would be called \fImaster\fR,
and this exactly the case in the
\fIgithub mirror\fR [https://github\&.com/tcltk/tcllib/] of Tcllib\&.

.PP
In support of debugging, like searching for when an issue
appeared via bisection, each commit on this branch must pass the
entire testsuite of the collection\&.

.PP


As fossil has no mechanism to enforce this this is handled on
the honor system for developers and maintainers\&.
.PP
To make the task easier Tcllib comes with a tool
("\fIsak\&.tcl\fR") providing a number of commands in support\&. These
commands are explained in the following sections of this guide\&.

.PP
While it is possible and allowed to commit directly to trunk
remember the above regarding the testsuite, and the coming notes about
other possible issues with a commit\&.





























.PP


























































Because of this it is (strongly) recommended to perform any
development on a nicely named (nick of dev, ticket reference if any,


keywords applicable to the work, \&.\&.\&.) non-trunk branch\&. Outside of the





























































































trunk developers are allowed to commit intermediate broken states of
their work\&. Only at the end, when the branch is considered ready for


merging will it be necessary to perform full validation\&.




























































































.SS "VERSION NUMBERS"
In Tcllib all changes to a package have to come with an increment of
its version number\&. What part is incremented (patchlevel, minor,
major version) depends on the kind of change made\&. With multiple
changes in a commit the highest "wins"\&.
.PP
When working in a development branch the version change can be
deferred until it is time to merge, and then has to cover all the
changes in the branch\&.
.PP
Below a list of the kinds of changes and their association
version increments:
.TP
\fID - documentation\fR
No increment
.TP
\fIT - testsuite\fR
No increment







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
|
|
|
<


|
|
|
>

|
|
|
>

>
>
|
|


|
|
>


|
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>

>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
|
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
|
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>


|
|
|


|
|

|







380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444

445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
Coordination and discussion with ticket submitter during
the development and/or application of bug fixes\&.
.RE
.IP [4]
Follow the \fBBranching and Workflow\fR of this guide\&.
.PP
.SH "BRANCHING AND WORKFLOW"
.SS "PACKAGE DEPENDENCIES"
Regarding packages and dependencies between them Tcllib occupies a
middle position between two extremes:
.IP [1]
On one side a strongly interdependent set of packages, usually
by a single author, for a single project\&. Looking at my
(Andreas Kupries) own work examples of such are
\fIMarpa\fR [https://core\&.tcl\&.tk/akupries/marpa/index],
\fICRIMP\fR [https://core\&.tcl\&.tk/akupries/crimp/index],
\fIKinetcl\fR [https://core\&.tcl\&.tk/akupries/kinetcl/index], etc\&.
.sp
For every change the author of the project handles all the
modifications cascading from any incompatibilities it
introduced to the system\&.
.IP [2]
On the other side, the world of semi-independent projects by
many different authors where authors know what packages their
own creations depend on, yet usually do not know who else
depends on them\&.
.sp
The best thing an author making an (incompatible) change to
their project can do is to for one announce such changes in
some way, and for two use versioning to distinguish the code
before and after the change\&.
.sp
The world is then responsible for adapting, be it by updating
their own projects to the new version, or by sticking to the
old\&.
.PP
As mentioned already, Tcllib lives in the middle of that\&.
.PP
While we as maintainers cannot be aware of all users of
Tcllib's packages, and thus have to rely on the mechanisms
touched on in point 2 above for that, the dependencies between
the packages contained in Tcllib are a different matter\&.
.PP
As we are collectively responsible for the usability of Tcllib
in toto to the outside world, it behooves us to be individually
mindful even of Tcllib packages we are not directly
maintaining, when they depend on packages under our
maintainership\&.
This may be as simple as coordinating with the maintainers of
the affected packages\&.
It may also require us to choose how to adapt affected packages
which do not have maintainers, i\&.e\&. modify them to use our
changed package properly, or modify them to properly depend on
the unchanged version of our package\&.
.PP
Note that the above is not only a chore but an opportunity as
well\&.
Additional insight can be had by forcing ourselves to look at
our package and the planned change(s) from an outside
perspective, to consider the ramafications of our actions on
others in general, and on dependent packages in particular\&.
.SS TRUNK
The management and use of branches is an important part of working
with a \fIDistributed Version Control System\fR (\fIDVCS\fR) like
\fIfossil\fR [https://www\&.fossil-scm\&.org/]\&.

.PP
For Tcllib the main branch of the collection is
\fItrunk\fR\&. In \fIgit\fR this branch would be called
\fImaster\fR, and this exactly the case in the
\fIgithub mirror\fR [https://github\&.com/tcltk/tcllib/] of
Tcllib\&.
.PP
To properly support debugging \fIeach commit\fR on this
branch \fIhas to pass the entire testsuite\fR of the
collection\&. Using bisection to determine when an issue appeared
is an example of an action made easier by this constraint\&.
.PP
This is part of our collective responsibility for the usability
of Tcllib in toto to the outside world\&.
As \fIfossil\fR has no mechanism to enforce this condition
this is handled on the honor system for developers and maintainers\&.
.PP
To make the task easier Tcllib comes with a tool
("\fIsak\&.tcl\fR") providing a number of commands in
support\&. These commands are explained in the following sections
of this guide\&.
.PP
While it is possible and allowed to commit directly to trunk
remember the above constraint regarding the testsuite, and the
coming notes about other possible issues with a commit\&.
.SS BRANCHES
Given the constraints placed on the \fItrunk\fR branch of the
repository it is (strongly) recommended to perform any development
going beyond trivial changes on a non-trunk branch\&.
.PP
Outside of the trunk developers are allowed to commit
intermediate broken states of their work\&.
Only at the end of a development cycle, when the relevant
branch is considered ready for merging, will it be necessary to
perform full the set of validations ensuring that the merge to
come will create a good commit on trunk\&.
.PP
Note that while a review from a second developer is not a
required condition for merging a branch it is recommended to
seek out such an independent opinion as a means of
cross-checking the work\&.
.PP
It also recommended to give any new branch a name which aids in
determining additional details about it\&. Examples of good
things to stick into a branch name would be
.IP \(bu
Developer (nick)name
.IP \(bu
Ticket hash/reference
.IP \(bu
One or two keywords applicable to the work
.IP \(bu
\&.\&.\&.
.PP
.PP
Further, while most development branches are likely quite
short-lived, no prohibitions exist against making longer-lived
branches\&.
Creators should however be mindful that the longer such a
branch exists without merges the more divergent they will tend
to be, with an associated increase in the effort which will
have to be spent on either merging from and merging to trunk\&.
.SS "WORKING WITH BRANCHES"
In the hope of engendering good work practices now a few example
operations which will come up with branches, and their associated
fossil command (sequences)\&.
.TP
\fIAwareness\fR
When developing we have to keep ourselves aware of the context of our
work\&. On what branch are we ? What files have we changed ? What new
files are not yet known to the repository ?
This becomes especially important when using a long-lived checkout and
coming back to it after some time away\&.
.sp
Commands to answer questions like the above are:
.RS
.TP
\fBfossil info | grep tags\fR
.TP
\fBfossil branch list | grep '\\*'\fR
Two different ways of determining the branch our checkout is
on\&.
.TP
\fBfossil timeline\fR
What have we (and others) done recently ?
.sp
\fIAttention\fR, this information is very likely outdated, the
more the longer we did not use this checkout\&.
Run \fBfossil pull\fR first to get latest information from
the remote repository of the project\&.
.TP
\fBfossil timeline current\fR
Place the commit our checkout is based on at the top of the
timeline\&.
.TP
\fBfossil changes\fR
Lists the files we have changed compared to the commit the
checkout is based on\&.
.TP
\fBfossil extra\fR
Lists the files we have in the checkout the repository does not
know about\&. This may be leftover chaff from our work, or
something we have forgotten to \fBfossil add\fR to the
repository yet\&.
.RE
.TP
\fIClean checkouts\fR
Be aware of where you are (see first definition)\&.
.sp
For pretty much all the operation recipes below a clean
checkout is at least desired, often required\&.
To check that a checkout is clean invoke
.CS


    fossil changes
    fossil extra

.CE
.IP
How to clean up when uncommitted changes of all sorts are found is
context-specific and outside of the scope of this guide\&.
.TP
\fIStarting a new branch\fR
Be aware of where you are (see first definition)\&.
.sp
Ensure that you have clean checkout (see second definition)\&.
It is \fIrequired\fR\&.
.sp
In most situations you want to be on branch \fItrunk\fR, and
you want to be on the latest commit for it\&. To get there use
.CS


    fossil pull
    fossil update trunk

.CE
.IP
If some other branch is desired as the starting point for the coming
work replace \fItrunk\fR in the commands above with the name of that
branch\&.
.sp
With the base line established we now have two ways of creating
the new branch, with differing (dis)advantages\&.
The simpler way is to
.CS


    fossil branch new NAME_OF_NEW_BRANCH

.CE
.IP
and start developing\&. The advantage here is that you cannot forget to
create the branch\&. The disadvantages are that we have a branch commit
unchanged from where we branched from, and that we have to use
high-handed techniques like hiding or shunning to get rid of the
commit should we decide to abandon the work before the first actual
commit on the branch\&.
.sp
The other way of creating the branch is to start developing,
and then on the first commit use the option \fB--branch\fR to tell
\fBfossil\fR that we are starting a branch now\&. I\&.e\&. run
.CS


    fossil commit --branch NAME_OF_NEW_BRANCH \&.\&.\&.

.CE
.IP
where \fI\&.\&.\&.\fR are any other options used to supply the commit
message, files to commit, etc\&.
.sp
The (dis)advantages are now reversed\&.
.sp
We have no superflous commit, only what is actually
developed\&. The work is hidden until we commit to make our first
commit\&.
.sp
We may forget to use \fB--branch NAME_OF_NEW_BRANCH\fR and
then have to correct that oversight via the fossil web
interface (I am currently unaware of ways of doing such from
the command line, although some magic incantantion of
\fBfossil tag create\fR may work)\&.
.sp
It helps tp keep awareness, like checking before any commit
that we are on the desired branch\&.
.TP
\fIMerging a branch into trunk\fR
Be aware of where you are (see first definition)\&.
.sp
Ensure that you have clean checkout (see second definition)\&.
In the full-blown sequence (zig-zag) it is \fIrequired\fR, due
to the merging from trunk\&. In the shorter sequence it is only
desired\&. That said, keeping the checkout clean before
any major operations is a good habit to have, in my opinion\&.
.sp
The full-blown sequencing with checks all the way is to
.RS
.IP [1]
Validate the checkout, i\&.e\&. last commit on your branch\&. Run the
full test suite and other validations, fix all the issues which
have cropped up\&.
.IP [2]
Merge the latest state of the \fItrunk\fR (see next definition)\&.
.IP [3]
Validate the checkout again\&. The incoming trunk changes may
have broken something now\&. Do any required fixes\&.
.IP [4]
Now merge to the trunk using
.CS


    fossil update trunk
    fossil merge --integrate YOU_BRANCH

.CE
.IP [5]
At this point the checkout should be in the same state as at
the end of point (3) above, because we resolved any issues with
the trunk already\&. Thus a simple
.CS


    fossil commit \&.\&.\&.

.CE
.IP
should be sufficient now to commit the merge back and close the
branch (due to the \fB--integrate\fR we used on the merge)\&.
.sp
The more paranoid may validate the checkout a third time before
commiting\&.
.RE
.sp
I call this a \fIzig-zag merge\fR because of how the arrows
look in the timeline, from trunk to feature branch for the
first merge, and then back for the final merge\&.
.sp
A less paranoid can do what I call a \fIsimple merge\fR,
which moves step (2) after step (4) and skips step (3)
entirely\&. The resulting shorter sequence is
.RS
.IP [1]
Validate
.IP [2]
Merge to trunk
.IP [3]
Validate again
.IP [4]
Commit to trunk
.RE
.IP
The last step after either zig-zag or plain merge is to
.CS


    fossil sync

.CE
.IP
This saves our work to the remote side, and further gives us any other
work done while we were doing our merge\&. It especially allows us to
check if we raced somebody else, resulting in a split trunk\&.
.sp
When that happens we should coordinate with the other developer
on who fixes the split, to ensure that we do not race each
other again\&.
.TP
\fIMerging from trunk\fR
Be aware of where you are (see first definition)\&.
.sp
Ensure that you have clean checkout (see second definition)\&.
It is \fIrequired\fR\&.
.sp
In most situations you want to import the latest commit of
branch \fItrunk\fR (or other origin)\&. To get it use
.CS


    fossil pull

.CE
.sp
With that done we can now import this commit into our current
branch with
.CS


    fossil merge trunk

.CE
.sp
Even if \fBfossil\fR does not report any conflicts it is a
good idea to check that the operation has not broken the new
and/or changed functionality we are working on\&.
.sp
With the establishment of a good merge we then save the state
with
.CS


    fossil commit \&.\&.\&.

.CE
.IP
before continuing development\&.
.PP
.SS "VERSION NUMBERS"
In Tcllib all changes to a package have to come with an increment of
its version number\&. What part is incremented (patchlevel, minor, major
version) depends on the kind of change made\&. With multiple changes in
a commit the highest "wins"\&.
.PP
When working in a development branch the version change can be
deferred until it is time to merge, and then has to cover all
the changes in the branch\&.
.PP
Below a list of the kinds of changes and their associated
version increments:
.TP
\fID - documentation\fR
No increment
.TP
\fIT - testsuite\fR
No increment
444
445
446
447
448
449
450
451

452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
\fIE - backward-compatible extension\fR
Minor
.TP
\fIAPI - incompatible change\fR
Major
.PP
.PP
Note, a commit containing a version increment has to mention

the kind of change which caused it in the commit message, as well as
the new version number\&.
.PP
Note further that the version number of a package currently
exists in 3 places\&. An increment has to update all of them:
.IP [1]
The package implementation\&.
.IP [2]
The package index ("\fIpkgIndex\&.tcl\fR")
.IP [3]
The package documentation\&.
.PP
.PP
The "\fIsak\&.tcl\fR" command \fBvalidate version\fR helps
finding discrepancies between the first two\&.
All the other \fBvalidate\fR methods are also of interest to any
developer\&. Invoke it with
.CS


    sak\&.tcl help validate

.CE
to see their documentation\&.
.SH "STRUCTURAL OVERVIEW"
.SS "MAIN DIRECTORIES"
The main directories in the Tcllib toplevel directory and of interest
to a developer are:
.TP







|
>
|
<


|










|
|


<
|
<







781
782
783
784
785
786
787
788
789
790

791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807

808

809
810
811
812
813
814
815
\fIE - backward-compatible extension\fR
Minor
.TP
\fIAPI - incompatible change\fR
Major
.PP
.PP
Note that a commit containing a version increment has to
mention the new version number in its commit message, as well
as the kind of change which caused it\&.

.PP
Note further that the version number of a package currently
exists in three places\&. An increment has to update all of them:
.IP [1]
The package implementation\&.
.IP [2]
The package index ("\fIpkgIndex\&.tcl\fR")
.IP [3]
The package documentation\&.
.PP
.PP
The "\fIsak\&.tcl\fR" command \fBvalidate version\fR helps
finding discrepancies between the first two\&.
All the other \fBvalidate\fR methods are also of interest to
any developer\&. Invoke it with
.CS


 sak\&.tcl help validate

.CE
to see their documentation\&.
.SH "STRUCTURAL OVERVIEW"
.SS "MAIN DIRECTORIES"
The main directories in the Tcllib toplevel directory and of interest
to a developer are:
.TP
Changes to idoc/man/files/devdoc/tcllib_installer.n.
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
tcllib_install_guide \- Tcllib - The Installer's Guide
.SH DESCRIPTION
Welcome to Tcllib, the Tcl Standard Library\&. Note that Tcllib is not a
package itself\&. It is a collection of (semi-independent) \fITcl\fR
packages that provide utility functions useful to a large collection
of Tcl programmers\&.
.PP
The audience of this document is anyone wishing to build the packages,
for either themselves, or others\&.
.PP
For a developer intending to extend or modify the packages we
additionally provide
.IP [1]
\fITcllib - The Developer's Guide\fR\&.
.PP
.PP
Please read \fITcllib - How To Get The Sources\fR first, if that
was not done already\&. Here we assume that the sources are already







|
|

|







274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
tcllib_install_guide \- Tcllib - The Installer's Guide
.SH DESCRIPTION
Welcome to Tcllib, the Tcl Standard Library\&. Note that Tcllib is not a
package itself\&. It is a collection of (semi-independent) \fITcl\fR
packages that provide utility functions useful to a large collection
of Tcl programmers\&.
.PP
The audience of this document is anyone wishing to build and install
the packages found in Tcllib, for either themselves, or others\&.
.PP
For developers intending to work on the packages themselves we
additionally provide
.IP [1]
\fITcllib - The Developer's Guide\fR\&.
.PP
.PP
Please read \fITcllib - How To Get The Sources\fR first, if that
was not done already\&. Here we assume that the sources are already
377
378
379
380
381
382
383
384
385
386

387
388
389
390

391
392
393


394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434

435
436
437
438

439
440
441

442

443



444

445
446
447
448
449
450

451
452
453
454

455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476

477
478
479

480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513



















































































































At the above url is also an explanation on how to build and
install Critcl, including a list of its dependencies\&.
.PP
Its instructions will not be repeated here\&. If there are
problems with these directions please file a ticket against the
\fICritcl\fR project, and not Tcllib\&.
.SH "BUILD & INSTALLATION INSTRUCTIONS"
The Tcllib distribution, whether a checkout directly from the source
repository, or an official release, offers a single method for
installing it, based on Tcl itself\&.

.PP
This is based on the assumption that for Tcllib to be of use
Tcl has to be present, and therefore can be used in the implementation
of the install code\&.

.PP
The relevant tool is the "\fIinstaller\&.tcl\fR" script found in
the toplevel directory of a checkout or release\&.


.PP
It can be used in a variety of ways:
.IP [1]
It is always possible to invoke the tool directly, either as
.CS


    \&./installer\&.tcl

.CE
.IP
or
.CS


    /path/to/tclsh \&./installer\&.tcl

.CE
.IP
The second form is required on Windows (without a Unix emulation),
except if the Tcl installation is configured to handle "\fI\&.tcl\fR"
files on a double-click\&.
.IP [2]
In a Unix-type environment, i\&.e\&. Linux, BSD and related, including OS
X, and Windows using some kind of unix-emulation like \fBMSYS\fR,
\fBCygwin\fR, etc\&.) it is also possible to use
.CS


    \&./configure
    make install

.CE
.IP
in the toplevel directory of Tcllib itself\&.
.sp
To build in a directory "\fID\fR" outside of Tcllib's toplevel
directory simply make "\fID\fR" the current working directory and
invoke \fBconfigure\fR with either its absolute path or a proper
relative path\&.
.sp

This will non-interactively install all packages, applications
found in Tcllib, and their manpages, in directories derived from what
\fBconfigure\fR found out about the system\&.
.PP

.PP
The installer selects automatically either a GUI based mode, or
a command line based mode\&. If the package \fBTk\fR is present and

can be loaded, then the GUI mode is entered, else the system falls

back to the command line\&.



.PP

Note that it is possible to specify options on the command line
even if the installer ultimatively selects GUI mode\&. In that case the
hardwired defaults and the options determine the data presented to the
user for editing\&.
.PP
Command line help can be asked for by using the option \fB-help\fR when

invoking the installer, i\&.e\&.
.CS



    \&./installer\&.tcl -help

.CE
This will print a short list of the available options to the standard
output channel\&. For more examples see the various \fIinstall\fR
targets found in "\fIMakefile\&.in\fR"\&.
.PP
The installer will select a number of defaults for the
locations of packages, examples, and documentation, and also the
format of the documentation\&. The user can overide these defaults in
the GUI, or by specifying additional options\&.
.PP
The defaults depend on the platform detected (Unix/Windows) and
on the \fBtclsh\fR executable used to run the installer\&.
.PP
\fIAttention\fR The installer will overwrite an existing
installation of a Tcllib with the same version without asking back
after the initial confirmation is given\&.
Further if the user chooses the same directory as chosen for/by
previous installations then these will be overwritten as well\&.
.SS "CRITCL & ACCELERATORS"
.PP

A number of packages come with \fIaccelerators\fR, i\&.e\&.
\fBcritcl\fR-based C code whose use will boost the performance of
the packages using them\&. As these accelerators are optional they are

not installed by default\&.
.PP
To build the accelerators the normally optional dependency on
\fBcritcl\fR becomes required\&.
.PP
To install Tcllib with the accelerators in a Unix-type
environment invoke:
.CS


    \&./configure
    make critcl # This builds the shared library holding
                # the accelerators
    make install

.CE
.PP
The underlying tool is "\fIsak\&.tcl\fR" in the toplevel directory
of Tcllib and the command \fBmake critcl\fR is just a wrapper around
.CS


    \&./sak\&.tcl critcl

.CE
.PP
Therefore in a Windows environment instead invoke
.CS


    /path/to/tclsh \&./sak\&.tcl critcl
    /path/to/tclsh \&./installer\&.tcl

.CE


























































































































|
<
|
>

|
<
|
>

|
|
>
>

<
<
<
<
|
|
<
|
<
<
<
<
|
|
<
|
<
<
<
<
|
<
<
<
<



|
|


<
|
<
<
<
<
<
<
>
|
|
<

>
|
|
|
>
|
>
|
>
>
>

>
|
|
|
<

<
>
|

<

>
|


<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<

<
>
|
|
|
>
|




|
|



|
|
|
|








|







|
|


>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
377
378
379
380
381
382
383
384

385
386
387
388

389
390
391
392
393
394
395
396




397
398

399




400
401

402




403




404
405
406
407
408
409
410

411






412
413
414

415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431

432

433
434
435

436
437
438
439
440














441


442

443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
At the above url is also an explanation on how to build and
install Critcl, including a list of its dependencies\&.
.PP
Its instructions will not be repeated here\&. If there are
problems with these directions please file a ticket against the
\fICritcl\fR project, and not Tcllib\&.
.SH "BUILD & INSTALLATION INSTRUCTIONS"
As Tcllib is mainly a bundle of packages written in pure Tcl building

it is the same as installing it\&. The exceptions to this have their own
subsection, \fBCritcl & Accelerators\fR, later on\&.
.PP
Before that however comes the standard case, differentiated by

the platforms with material differences in the instruction, i\&.e\&.
\fIUnix\fR-like, versus \fIWindows\fR\&.
.PP
Regarding the latter it should also be noted that it is
possible set up an \fIUnix\fR-like environment using projects
like \fIMSYS\fR, \fICygwin\fR, and others\&. In that case the
user has the choice of which instructions to follow\&.
.PP




Regardless of environment or platform, a suitable \fITcl\fR
has to be installed, and its \fBtclsh\fR should be placed on

the  (\fIUnix\fR) or associated with




"\fI\&.tcl\fR" files (\fIWindows\fR)\&.
.SS "INSTALLING ON UNIX"

For \fIUnix\fR-like environments Tcllib comes with the standard set




of files to make




.CS


  \&./configure
  make install

.CE

a suitable way of installing it\&.






This is a standard non-interactive install automatically figuring out
where to place everything, i\&.e\&. packages, applications, and the
manpages\&.

.PP
To get a graphical installer invoke
.CS


  \&./installer\&.tcl

.CE
instead\&.
.SS "INSTALLING ON WINDOWS"
In a Windows environment we have the \fBinstaller\&.tcl\fR script to
perform installation\&.
.PP
If the desired \fBtclsh\fR is associated "\fI\&.tcl\fR" files
then double-clicking / opening the \fBinstaller\&.tcl\fR is
enough to invoke it in graphical mode\&.
This assumes that \fITk\fR is installed and available as well\&.

.PP

Without \fITk\fR the only way to invoke the installer are to
open a DOS window, i\&.e\&. \fBcmd\&.exe\fR, and then to invoke
.CS



  \&./installer\&.tcl

.CE














inside it\&.


.SS "CRITCL & ACCELERATORS"

While the majority of Tcllib consists of packages written in pure Tcl
a number of packages also have \fIaccelerators\fR associated with them\&.
These are \fBcritcl\fR-based C packages whose use will boost the
performance of the packages using them\&.
These accelerators are optional, and they are not installed by
default\&.
.PP
To build the accelerators the normally optional dependency on
\fBcritcl\fR becomes required\&.
.PP
To build and install Tcllib with the accelerators in a
Unix-like environment invoke:
.CS


  \&./configure
  make critcl # This builds the shared library holding
              # the accelerators
  make install

.CE
.PP
The underlying tool is "\fIsak\&.tcl\fR" in the toplevel directory
of Tcllib and the command \fBmake critcl\fR is just a wrapper around
.CS


  \&./sak\&.tcl critcl

.CE
.PP
Therefore in a Windows environment instead invoke
.CS


  \&./sak\&.tcl critcl
  \&./installer\&.tcl

.CE
from within a DOS window, i\&.e\&. \fBcmd\&.exe\fR\&.
.SS TOOLING
The core of Tcllib's build system is the script "\fIinstaller\&.tcl\fR"
found in the toplevel directory of a checkout or release\&.
.PP
The
.CS


         configure ; make install

.CE
setup available to
developers on Unix-like systems is just a wrapper around it\&.
To go beyond the standard embodied in the wrapper it is
necessary to directly invoke this script\&.
.PP
On Windows system using it directly is the only way to invoke
it\&.
.PP
For basic help invoke it as
.CS


         \&./installer\&.tcl -help

.CE
This will print a short list of all the available options to
the standard output channel\&.
.PP
The commands associated with the various \fIinstall\fR targets
in the \fIMakefile\&.in\fR for Unix can be used as additional
examples on how to use this tool as well\&.
.PP
The installer can operate in GUI and CLI modes\&.
By default it chooses the mode automatically, based on if the
Tcl package \fBTk\fR can be used or not\&.
The option \fB-no-gui\fR can be used to force CLI mode\&.
.PP
Note that it is possible to specify options on the command line
even if the installer ultimatively selects GUI mode\&. In that
case the hardwired defaults and the options determine the data
presented to the user for editing\&.
.PP
The installer will select a number of defaults for the
locations of packages, examples, and documentation, and also
the format of the documentation\&. The user can overide these
defaults in the GUI, or by specifying additional options\&.
The defaults depend on the platform detected (Unix/Windows) and
on the \fBtclsh\fR executable used to run the installer\&.
.PP
\fIOptions\fR
.TP
\fB-help\fR
Show the list of options explained here on the standard output channel
and exit\&.
.TP
\fB+excluded\fR
Include deprecated packages in the installation\&.
.TP
\fB-no-gui\fR
Force command line operation of the installer
.TP
\fB-no-wait\fR
In CLI mode the installer will by default ask the user to confirm that
the chosen configuration (destination paths, things to install) is
correct before performing any action\&. Using this option causes the
installer to skip this query and immediately jump to installation\&.
.TP
\fB-app-path\fR \fIpath\fR
.TP
\fB-example-path\fR \fIpath\fR
.TP
\fB-html-path\fR \fIpath\fR
.TP
\fB-nroff-path\fR \fIpath\fR
.TP
\fB-pkg-path\fR \fIpath\fR
Declare the destination paths for the applications, examples, html
documentation, nroff manpages, and packages\&. The defaults are derived
from the location of the \fBtclsh\fR used to run the installer\&.
.TP
\fB-dry-run\fR
.TP
\fB-simulate\fR
Run the installer without modifying the destination directories\&.
.TP
\fB-apps\fR
.TP
\fB-no-apps\fR
.TP
\fB-examples\fR
.TP
\fB-no-examples\fR
.TP
\fB-pkgs\fR
.TP
\fB-no-pkgs\fR
.TP
\fB-html\fR
.TP
\fB-no-html\fR
.TP
\fB-nroff\fR
.TP
\fB-no-nroff\fR
(De)activate the installation of applications, examples, packages,
html documentation, and nroff manpages\&.
.sp
Applications, examples, and packages are installed by default\&.
.sp
On Windows the html documentation is installed by default\&.
.sp
On Unix the nroff manpages are installed by default\&.
.PP
Changes to idoc/www/tcllib/files/devdoc/tcllib_devguide.html.
118
119
120
121
122
123
124
125
126



127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
<ul>
<li class="doctools_subsection"><a href="#subsection1">Contributor</a></li>
<li class="doctools_subsection"><a href="#subsection2">Maintainer</a></li>
</ul>
</li>
<li class="doctools_section"><a href="#section3">Branching and Workflow</a>
<ul>
<li class="doctools_subsection"><a href="#subsection3">Branches</a></li>
<li class="doctools_subsection"><a href="#subsection4">Version numbers</a></li>



</ul>
</li>
<li class="doctools_section"><a href="#section4">Structural Overview</a>
<ul>
<li class="doctools_subsection"><a href="#subsection5">Main Directories</a></li>
<li class="doctools_subsection"><a href="#subsection6">More Directories</a></li>
<li class="doctools_subsection"><a href="#subsection7">Top Files</a></li>
<li class="doctools_subsection"><a href="#subsection8">File Types</a></li>
</ul>
</li>
<li class="doctools_section"><a href="#section5">Testsuite Tooling</a>
<ul>
<li class="doctools_subsection"><a href="#subsection9">Invoke the testsuites of a specific module</a></li>
<li class="doctools_subsection"><a href="#subsection10">Invoke the testsuites of all modules</a></li>
<li class="doctools_subsection"><a href="#subsection11">Detailed Test Logs</a></li>
<li class="doctools_subsection"><a href="#subsection12">Shell Selection</a></li>
<li class="doctools_subsection"><a href="#subsection13">Help</a></li>
</ul>
</li>
<li class="doctools_section"><a href="#section6">Documentation Tooling</a>
<ul>
<li class="doctools_subsection"><a href="#subsection14">Generate documentation for a specific module</a></li>
<li class="doctools_subsection"><a href="#subsection15">Generate documentation for all modules</a></li>
<li class="doctools_subsection"><a href="#subsection16">Available output formats, help</a></li>
<li class="doctools_subsection"><a href="#subsection17">Validation without output</a></li>
</ul>
</li>
<li class="doctools_section"><a href="#section7">Notes On Writing A Testsuite</a></li>
<li class="doctools_section"><a href="#section8">Installation Tooling</a></li>
</ul>
</div>
<div id="synopsis" class="doctools_section"><h2><a name="synopsis">Synopsis</a></h2>







|
|
>
>
>




|
|
|
|




|
|
|
|
|




|
|
|
|







118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
<ul>
<li class="doctools_subsection"><a href="#subsection1">Contributor</a></li>
<li class="doctools_subsection"><a href="#subsection2">Maintainer</a></li>
</ul>
</li>
<li class="doctools_section"><a href="#section3">Branching and Workflow</a>
<ul>
<li class="doctools_subsection"><a href="#subsection3">Package Dependencies</a></li>
<li class="doctools_subsection"><a href="#subsection4">Trunk</a></li>
<li class="doctools_subsection"><a href="#subsection5">Branches</a></li>
<li class="doctools_subsection"><a href="#subsection6">Working with Branches</a></li>
<li class="doctools_subsection"><a href="#subsection7">Version numbers</a></li>
</ul>
</li>
<li class="doctools_section"><a href="#section4">Structural Overview</a>
<ul>
<li class="doctools_subsection"><a href="#subsection8">Main Directories</a></li>
<li class="doctools_subsection"><a href="#subsection9">More Directories</a></li>
<li class="doctools_subsection"><a href="#subsection10">Top Files</a></li>
<li class="doctools_subsection"><a href="#subsection11">File Types</a></li>
</ul>
</li>
<li class="doctools_section"><a href="#section5">Testsuite Tooling</a>
<ul>
<li class="doctools_subsection"><a href="#subsection12">Invoke the testsuites of a specific module</a></li>
<li class="doctools_subsection"><a href="#subsection13">Invoke the testsuites of all modules</a></li>
<li class="doctools_subsection"><a href="#subsection14">Detailed Test Logs</a></li>
<li class="doctools_subsection"><a href="#subsection15">Shell Selection</a></li>
<li class="doctools_subsection"><a href="#subsection16">Help</a></li>
</ul>
</li>
<li class="doctools_section"><a href="#section6">Documentation Tooling</a>
<ul>
<li class="doctools_subsection"><a href="#subsection17">Generate documentation for a specific module</a></li>
<li class="doctools_subsection"><a href="#subsection18">Generate documentation for all modules</a></li>
<li class="doctools_subsection"><a href="#subsection19">Available output formats, help</a></li>
<li class="doctools_subsection"><a href="#subsection20">Validation without output</a></li>
</ul>
</li>
<li class="doctools_section"><a href="#section7">Notes On Writing A Testsuite</a></li>
<li class="doctools_section"><a href="#section8">Installation Tooling</a></li>
</ul>
</div>
<div id="synopsis" class="doctools_section"><h2><a name="synopsis">Synopsis</a></h2>
185
186
187
188
189
190
191
192
193


194
195
196
197
198
199
200
201
202
203
204
205
206
207

208
209
210
211
212
213
214
source code management system is used, where to find it, how to set it
up, etc.</p>
</div>
<div id="section2" class="doctools_section"><h2><a name="section2">Commitments</a></h2>
<div id="subsection1" class="doctools_subsection"><h3><a name="subsection1">Contributor</a></h3>
<p>As a contributor to Tcllib you are committing yourself to:</p>
<ol class="doctools_enumerated">
<li><p>Follow the guidelines laid down in
       <i class="term"><a href="tcl_community_communication.html">Tcl Community - Kind Communication</a></i></p></li>


<li><p>Your contributions getting distributed under a BSD/MIT license.
       For the details see <i class="term"><a href="tcllib_license.html">Tcllib - License</a></i></p></li>
</ol>
<p>Contributions are made by entering tickets into our tracker, providing
patches, bundles or branches of code for inclusion, or posting to the
Tcllib related mailing lists.</p>
</div>
<div id="subsection2" class="doctools_subsection"><h3><a name="subsection2">Maintainer</a></h3>
<p>When contributing one or more packages for full inclusion into Tcllib
you are committing yourself to</p>
<ol class="doctools_enumerated">
<li><p>Follow the guidelines laid down in
       <i class="term"><a href="tcl_community_communication.html">Tcl Community - Kind Communication</a></i>
       (as any contributor)</p></li>

<li><p>Your packages getting distributed under a BSD/MIT license.  For
       the details see <i class="term"><a href="tcllib_license.html">Tcllib - License</a></i></p></li>
<li><p>Maintenance of the new packages for a period of two years under
       the following rules, and responsibilities:</p>
<ol class="doctools_enumerated">
       
<li><p>A maintainer may step down after the mandatory period as







|
|
>
>











|

|
>







188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
source code management system is used, where to find it, how to set it
up, etc.</p>
</div>
<div id="section2" class="doctools_section"><h2><a name="section2">Commitments</a></h2>
<div id="subsection1" class="doctools_subsection"><h3><a name="subsection1">Contributor</a></h3>
<p>As a contributor to Tcllib you are committing yourself to:</p>
<ol class="doctools_enumerated">
<li><p>keep the guidelines written down in
       <i class="term"><a href="tcl_community_communication.html">Tcl Community - Kind Communication</a></i> in your mind.
       The main point to take away from there is
       <em>to be kind to each other</em>.</p></li>
<li><p>Your contributions getting distributed under a BSD/MIT license.
       For the details see <i class="term"><a href="tcllib_license.html">Tcllib - License</a></i></p></li>
</ol>
<p>Contributions are made by entering tickets into our tracker, providing
patches, bundles or branches of code for inclusion, or posting to the
Tcllib related mailing lists.</p>
</div>
<div id="subsection2" class="doctools_subsection"><h3><a name="subsection2">Maintainer</a></h3>
<p>When contributing one or more packages for full inclusion into Tcllib
you are committing yourself to</p>
<ol class="doctools_enumerated">
<li><p>Keep the guidelines written down in
       <i class="term"><a href="tcl_community_communication.html">Tcl Community - Kind Communication</a></i>
       (as any contributor) in your mind. The main point to take away
       from there is <em>to be kind to each other</em>.</p></li>
<li><p>Your packages getting distributed under a BSD/MIT license.  For
       the details see <i class="term"><a href="tcllib_license.html">Tcllib - License</a></i></p></li>
<li><p>Maintenance of the new packages for a period of two years under
       the following rules, and responsibilities:</p>
<ol class="doctools_enumerated">
       
<li><p>A maintainer may step down after the mandatory period as
249
250
251
252
253
254
255
256


































257














258
259
260
261
262
263
264
265

266
267




268
269
270
271
272

273
274
275



276



277













278
















































































279
280





























281



































































282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309

310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
</ol>
</li>
<li><p>Follow the <span class="sectref"><a href="#section3">Branching and Workflow</a></span> of this guide.</p></li>
</ol>
</div>
</div>
<div id="section3" class="doctools_section"><h2><a name="section3">Branching and Workflow</a></h2>
<div id="subsection3" class="doctools_subsection"><h3><a name="subsection3">Branches</a></h3>


































<p>An important part of working with a














<i class="term">Distributed Version Control System</i> (<i class="term">DVCS</i>) like
<a href="https://www.fossil-scm.org/">fossil</a>
is the management and use of branches.</p>
<p>For Tcllib the main branch of the collection is
<i class="term">trunk</i>. In <i class="term">git</i> this branch would be called <i class="term">master</i>,
and this exactly the case in the
<a href="https://github.com/tcltk/tcllib/">github mirror</a> of Tcllib.</p>
<p>In support of debugging, like searching for when an issue

appeared via bisection, each commit on this branch must pass the
entire testsuite of the collection.</p>




<p>As fossil has no mechanism to enforce this this is handled on
the honor system for developers and maintainers.</p>
<p>To make the task easier Tcllib comes with a tool
(&quot;<b class="file">sak.tcl</b>&quot;) providing a number of commands in support. These
commands are explained in the following sections of this guide.</p>

<p>While it is possible and allowed to commit directly to trunk
remember the above regarding the testsuite, and the coming notes about
other possible issues with a commit.</p>



<p>Because of this it is (strongly) recommended to perform any



development on a nicely named (nick of dev, ticket reference if any,













keywords applicable to the work, ...) non-trunk branch. Outside of the
















































































trunk developers are allowed to commit intermediate broken states of
their work. Only at the end, when the branch is considered ready for





























merging will it be necessary to perform full validation.</p>



































































</div>
<div id="subsection4" class="doctools_subsection"><h3><a name="subsection4">Version numbers</a></h3>
<p>In Tcllib all changes to a package have to come with an increment of
its version number. What part is incremented (patchlevel, minor,
major version) depends on the kind of change made. With multiple
changes in a commit the highest &quot;wins&quot;.</p>
<p>When working in a development branch the version change can be
deferred until it is time to merge, and then has to cover all the
changes in the branch.</p>
<p>Below a list of the kinds of changes and their association
version increments:</p>
<dl class="doctools_definitions">
<dt><i class="term">D - documentation</i></dt>
<dd><p>No increment</p></dd>
<dt><i class="term">T - testsuite</i></dt>
<dd><p>No increment</p></dd>
<dt><i class="term">B - bugfix</i></dt>
<dd><p>Patchlevel</p></dd>
<dt><i class="term">I - implementation tweak</i></dt>
<dd><p>Patchlevel</p></dd>
<dt><i class="term">P - performance tweak</i></dt>
<dd><p>Patchlevel</p></dd>
<dt><i class="term">E - backward-compatible extension</i></dt>
<dd><p>Minor</p></dd>
<dt><i class="term">API - incompatible change</i></dt>
<dd><p>Major</p></dd>
</dl>
<p>Note, a commit containing a version increment has to mention

the kind of change which caused it in the commit message, as well as
the new version number.</p>
<p>Note further that the version number of a package currently
exists in 3 places. An increment has to update all of them:</p>
<ol class="doctools_enumerated">
<li><p>The package implementation.</p></li>
<li><p>The package index (&quot;<b class="file">pkgIndex.tcl</b>&quot;)</p></li>
<li><p>The package documentation.</p></li>
</ol>
<p>The &quot;<b class="file">sak.tcl</b>&quot; command <b class="cmd">validate version</b> helps
finding discrepancies between the first two.
All the other <b class="cmd">validate</b> methods are also of interest to any
developer. Invoke it with</p>
<pre class="doctools_example">
    sak.tcl help validate
</pre>
<p>to see their documentation.</p>
</div>
</div>
<div id="section4" class="doctools_section"><h2><a name="section4">Structural Overview</a></h2>
<div id="subsection5" class="doctools_subsection"><h3><a name="subsection5">Main Directories</a></h3>
<p>The main directories in the Tcllib toplevel directory and of interest
to a developer are:</p>
<dl class="doctools_definitions">
<dt>&quot;<b class="file">modules</b>&quot;</dt>
<dd><p>Each child directory represents one or more packages.
In the case of the latter the packages are usually related in some
way. Examples are &quot;<b class="file">base64</b>&quot;, &quot;<b class="file">math</b>&quot;, and &quot;<b class="file">struct</b>&quot;, with
loose (base64) to strong (math) relations between the packages in the
directory.</p></dd>
<dt>&quot;<b class="file">apps</b>&quot;</dt>
<dd><p>This directory contains all the installable applications, with their
documentation. Note that this directory is currently <em>not</em> split
into sub-directories.</p></dd>
<dt>&quot;<b class="file">examples</b>&quot;</dt>
<dd><p>Each child directory &quot;<b class="file">foo</b>&quot; contains one or more example
application for the packages in &quot;<b class="file">modules/foo</b>&quot;. These examples are
generally not polished enough to be considered for installation.</p></dd>
</dl>
</div>
<div id="subsection6" class="doctools_subsection"><h3><a name="subsection6">More Directories</a></h3>
<dl class="doctools_definitions">
<dt>&quot;<b class="file">config</b>&quot;</dt>
<dd><p>This directory contains files supporting the Unix build system,
i.e. &quot;<b class="file">configure</b>&quot; and &quot;<b class="file">Makefile.in</b>&quot;.</p></dd>
<dt>&quot;<b class="file">devdoc</b>&quot;</dt>
<dd><p>This directories contains the doctools sources for the global
documentation, like this document and its sibling guides.</p></dd>







|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
|
<

|
|
|
<
>
|
|
>
>
>
>
|
|

|
|
>

|
|
>
>
>
|
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>

|

|
|
|

|
|
|
|
















|
>
|
<

|






|
|
|
|
<
<




|



















|







255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313

314
315
316
317

318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564

565
566
567
568
569
570
571
572
573
574
575
576


577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
</ol>
</li>
<li><p>Follow the <span class="sectref"><a href="#section3">Branching and Workflow</a></span> of this guide.</p></li>
</ol>
</div>
</div>
<div id="section3" class="doctools_section"><h2><a name="section3">Branching and Workflow</a></h2>
<div id="subsection3" class="doctools_subsection"><h3><a name="subsection3">Package Dependencies</a></h3>
<p>Regarding packages and dependencies between them Tcllib occupies a
middle position between two extremes:</p>
<ol class="doctools_enumerated">
<li><p>On one side a strongly interdependent set of packages, usually
       by a single author, for a single project. Looking at my
       (Andreas Kupries) own work examples of such are
       <a href="https://core.tcl.tk/akupries/marpa/index">Marpa</a>,
       <a href="https://core.tcl.tk/akupries/crimp/index">CRIMP</a>,
       <a href="https://core.tcl.tk/akupries/kinetcl/index">Kinetcl</a>, etc.</p>
<p>For every change the author of the project handles all the
       modifications cascading from any incompatibilities it
       introduced to the system.</p></li>
<li><p>On the other side, the world of semi-independent projects by
       many different authors where authors know what packages their
       own creations depend on, yet usually do not know who else
       depends on them.</p>
<p>The best thing an author making an (incompatible) change to
       their project can do is to for one announce such changes in
       some way, and for two use versioning to distinguish the code
       before and after the change.</p>
<p>The world is then responsible for adapting, be it by updating
       their own projects to the new version, or by sticking to the
       old.</p></li>
</ol>
<p>As mentioned already, Tcllib lives in the middle of that.</p>
<p>While we as maintainers cannot be aware of all users of
       Tcllib's packages, and thus have to rely on the mechanisms
       touched on in point 2 above for that, the dependencies between
       the packages contained in Tcllib are a different matter.</p>
<p>As we are collectively responsible for the usability of Tcllib
       in toto to the outside world, it behooves us to be individually
       mindful even of Tcllib packages we are not directly
       maintaining, when they depend on packages under our
       maintainership.
       This may be as simple as coordinating with the maintainers of
       the affected packages.
       It may also require us to choose how to adapt affected packages
       which do not have maintainers, i.e. modify them to use our
       changed package properly, or modify them to properly depend on
       the unchanged version of our package.</p>
<p>Note that the above is not only a chore but an opportunity as
       well.
       Additional insight can be had by forcing ourselves to look at
       our package and the planned change(s) from an outside
       perspective, to consider the ramafications of our actions on
       others in general, and on dependent packages in particular.</p>
</div>
<div id="subsection4" class="doctools_subsection"><h3><a name="subsection4">Trunk</a></h3>
<p>The management and use of branches is an important part of working
with a <i class="term">Distributed Version Control System</i> (<i class="term">DVCS</i>) like
<a href="https://www.fossil-scm.org/">fossil</a>.</p>

<p>For Tcllib the main branch of the collection is
       <i class="term">trunk</i>. In <i class="term">git</i> this branch would be called
       <i class="term">master</i>, and this exactly the case in the
       <a href="https://github.com/tcltk/tcllib/">github mirror</a> of

       Tcllib.</p>
<p>To properly support debugging <em>each commit</em> on this
       branch <em>has to pass the entire testsuite</em> of the
       collection. Using bisection to determine when an issue appeared
       is an example of an action made easier by this constraint.</p>
<p>This is part of our collective responsibility for the usability
       of Tcllib in toto to the outside world.
       As <i class="term">fossil</i> has no mechanism to enforce this condition
       this is handled on the honor system for developers and maintainers.</p>
<p>To make the task easier Tcllib comes with a tool
       (&quot;<b class="file">sak.tcl</b>&quot;) providing a number of commands in
       support. These commands are explained in the following sections
       of this guide.</p>
<p>While it is possible and allowed to commit directly to trunk
       remember the above constraint regarding the testsuite, and the
       coming notes about other possible issues with a commit.</p>
</div>
<div id="subsection5" class="doctools_subsection"><h3><a name="subsection5">Branches</a></h3>
<p>Given the constraints placed on the <i class="term">trunk</i> branch of the
repository it is (strongly) recommended to perform any development
going beyond trivial changes on a non-trunk branch.</p>
<p>Outside of the trunk developers are allowed to commit
       intermediate broken states of their work.
       Only at the end of a development cycle, when the relevant
       branch is considered ready for merging, will it be necessary to
       perform full the set of validations ensuring that the merge to
       come will create a good commit on trunk.</p>
<p>Note that while a review from a second developer is not a
       required condition for merging a branch it is recommended to
       seek out such an independent opinion as a means of
       cross-checking the work.</p>
<p>It also recommended to give any new branch a name which aids in
       determining additional details about it. Examples of good
       things to stick into a branch name would be</p>
<ul class="doctools_itemized">
<li><p>Developer (nick)name</p></li>
<li><p>Ticket hash/reference</p></li>
<li><p>One or two keywords applicable to the work</p></li>
<li><p>...</p></li>
</ul>
<p>Further, while most development branches are likely quite
       short-lived, no prohibitions exist against making longer-lived
       branches.
       Creators should however be mindful that the longer such a
       branch exists without merges the more divergent they will tend
       to be, with an associated increase in the effort which will
       have to be spent on either merging from and merging to trunk.</p>
</div>
<div id="subsection6" class="doctools_subsection"><h3><a name="subsection6">Working with Branches</a></h3>
<p>In the hope of engendering good work practices now a few example
operations which will come up with branches, and their associated
fossil command (sequences).</p>
<dl class="doctools_definitions">
<dt><em>Awareness</em></dt>
<dd><p>When developing we have to keep ourselves aware of the context of our
work. On what branch are we ? What files have we changed ? What new
files are not yet known to the repository ?
This becomes especially important when using a long-lived checkout and
coming back to it after some time away.</p>
<p>Commands to answer questions like the above are:</p>
<dl class="doctools_definitions">
<dt><b class="cmd">fossil info | grep tags</b></dt>
<dd></dd>
<dt><b class="cmd">fossil branch list | grep '\*'</b></dt>
<dd><p>Two different ways of determining the branch our checkout is
       on.</p></dd>
<dt><b class="cmd">fossil timeline</b></dt>
<dd><p>What have we (and others) done recently ?</p>
<p><em>Attention</em>, this information is very likely outdated, the
       more the longer we did not use this checkout.
       Run <b class="cmd">fossil pull</b> first to get latest information from
       the remote repository of the project.</p></dd>
<dt><b class="cmd">fossil timeline current</b></dt>
<dd><p>Place the commit our checkout is based on at the top of the
       timeline.</p></dd>
<dt><b class="cmd">fossil changes</b></dt>
<dd><p>Lists the files we have changed compared to the commit the
       checkout is based on.</p></dd>
<dt><b class="cmd">fossil extra</b></dt>
<dd><p>Lists the files we have in the checkout the repository does not
       know about. This may be leftover chaff from our work, or
       something we have forgotten to <b class="cmd">fossil add</b> to the
       repository yet.</p></dd>
</dl></dd>
<dt><em>Clean checkouts</em></dt>
<dd><p>Be aware of where you are (see first definition).</p>
<p>For pretty much all the operation recipes below a clean
       checkout is at least desired, often required.
       To check that a checkout is clean invoke</p>
<pre class="doctools_example">
    fossil changes
    fossil extra
</pre>
<p>How to clean up when uncommitted changes of all sorts are found is
context-specific and outside of the scope of this guide.</p></dd>
<dt><em>Starting a new branch</em></dt>
<dd><p>Be aware of where you are (see first definition).</p>
<p>Ensure that you have clean checkout (see second definition).
       It is <em>required</em>.</p>
<p>In most situations you want to be on branch <i class="term">trunk</i>, and
       you want to be on the latest commit for it. To get there use</p>
<pre class="doctools_example">
    fossil pull
    fossil update trunk
</pre>
<p>If some other branch is desired as the starting point for the coming
work replace <i class="term">trunk</i> in the commands above with the name of that
branch.</p>
<p>With the base line established we now have two ways of creating
       the new branch, with differing (dis)advantages.
       The simpler way is to</p>
<pre class="doctools_example">
    fossil branch new NAME_OF_NEW_BRANCH
</pre>
<p>and start developing. The advantage here is that you cannot forget to
create the branch. The disadvantages are that we have a branch commit
unchanged from where we branched from, and that we have to use
high-handed techniques like hiding or shunning to get rid of the
commit should we decide to abandon the work before the first actual
commit on the branch.</p>
<p>The other way of creating the branch is to start developing,
and then on the first commit use the option <b class="option">--branch</b> to tell
<b class="syscmd">fossil</b> that we are starting a branch now. I.e. run</p>
<pre class="doctools_example">
    fossil commit --branch NAME_OF_NEW_BRANCH ...
</pre>
<p>where <i class="term">...</i> are any other options used to supply the commit
message, files to commit, etc.</p>
<p>The (dis)advantages are now reversed.</p>
<p>We have no superflous commit, only what is actually
       developed. The work is hidden until we commit to make our first
       commit.</p>
<p>We may forget to use <b class="option">--branch NAME_OF_NEW_BRANCH</b> and
       then have to correct that oversight via the fossil web
       interface (I am currently unaware of ways of doing such from
       the command line, although some magic incantantion of
       <b class="cmd">fossil tag create</b> may work).</p>
<p>It helps tp keep awareness, like checking before any commit
       that we are on the desired branch.</p></dd>
<dt><em>Merging a branch into trunk</em></dt>
<dd><p>Be aware of where you are (see first definition).</p>
<p>Ensure that you have clean checkout (see second definition).
       In the full-blown sequence (zig-zag) it is <em>required</em>, due
       to the merging from trunk. In the shorter sequence it is only
       desired. That said, keeping the checkout clean before
       any major operations is a good habit to have, in my opinion.</p>
<p>The full-blown sequencing with checks all the way is to</p>
<ol class="doctools_enumerated">
<li><p>Validate the checkout, i.e. last commit on your branch. Run the
       full test suite and other validations, fix all the issues which
       have cropped up.</p></li>
<li><p>Merge the latest state of the <i class="term">trunk</i> (see next definition).</p></li>
<li><p>Validate the checkout again. The incoming trunk changes may
       have broken something now. Do any required fixes.</p></li>
<li><p>Now merge to the trunk using</p>
<pre class="doctools_example">
    fossil update trunk
    fossil merge --integrate YOU_BRANCH
</pre>
</li>
<li><p>At this point the checkout should be in the same state as at
       the end of point (3) above, because we resolved any issues with
       the trunk already. Thus a simple</p>
<pre class="doctools_example">
    fossil commit ...
</pre>
<p>should be sufficient now to commit the merge back and close the
       branch (due to the <b class="option">--integrate</b> we used on the merge).</p>
<p>The more paranoid may validate the checkout a third time before
       commiting.</p></li>
</ol>
<p>I call this a <i class="term">zig-zag merge</i> because of how the arrows
       look in the timeline, from trunk to feature branch for the
       first merge, and then back for the final merge.</p>
<p>A less paranoid can do what I call a <i class="term">simple merge</i>,
       which moves step (2) after step (4) and skips step (3)
       entirely. The resulting shorter sequence is</p>
<ol class="doctools_enumerated">
<li><p>Validate</p></li>
<li><p>Merge to trunk</p></li>
<li><p>Validate again</p></li>
<li><p>Commit to trunk</p></li>
</ol>
<p>The last step after either zig-zag or plain merge is to</p>
<pre class="doctools_example">
    fossil sync
</pre>
<p>This saves our work to the remote side, and further gives us any other
work done while we were doing our merge. It especially allows us to
check if we raced somebody else, resulting in a split trunk.</p>
<p>When that happens we should coordinate with the other developer
       on who fixes the split, to ensure that we do not race each
       other again.</p></dd>
<dt><em>Merging from trunk</em></dt>
<dd><p>Be aware of where you are (see first definition).</p>
<p>Ensure that you have clean checkout (see second definition).
       It is <em>required</em>.</p>
<p>In most situations you want to import the latest commit of
       branch <i class="term">trunk</i> (or other origin). To get it use</p>
<pre class="doctools_example">
    fossil pull
</pre>
<p>With that done we can now import this commit into our current
       branch with</p>
<pre class="doctools_example">
    fossil merge trunk
</pre>
<p>Even if <b class="syscmd">fossil</b> does not report any conflicts it is a
       good idea to check that the operation has not broken the new
       and/or changed functionality we are working on.</p>
<p>With the establishment of a good merge we then save the state
       with</p>
<pre class="doctools_example">
    fossil commit ...
</pre>
<p>before continuing development.</p></dd>
</dl>
</div>
<div id="subsection7" class="doctools_subsection"><h3><a name="subsection7">Version numbers</a></h3>
<p>In Tcllib all changes to a package have to come with an increment of
its version number. What part is incremented (patchlevel, minor, major
version) depends on the kind of change made. With multiple changes in
a commit the highest &quot;wins&quot;.</p>
<p>When working in a development branch the version change can be
       deferred until it is time to merge, and then has to cover all
       the changes in the branch.</p>
<p>Below a list of the kinds of changes and their associated
       version increments:</p>
<dl class="doctools_definitions">
<dt><i class="term">D - documentation</i></dt>
<dd><p>No increment</p></dd>
<dt><i class="term">T - testsuite</i></dt>
<dd><p>No increment</p></dd>
<dt><i class="term">B - bugfix</i></dt>
<dd><p>Patchlevel</p></dd>
<dt><i class="term">I - implementation tweak</i></dt>
<dd><p>Patchlevel</p></dd>
<dt><i class="term">P - performance tweak</i></dt>
<dd><p>Patchlevel</p></dd>
<dt><i class="term">E - backward-compatible extension</i></dt>
<dd><p>Minor</p></dd>
<dt><i class="term">API - incompatible change</i></dt>
<dd><p>Major</p></dd>
</dl>
<p>Note that a commit containing a version increment has to
       mention the new version number in its commit message, as well
       as the kind of change which caused it.</p>

<p>Note further that the version number of a package currently
       exists in three places. An increment has to update all of them:</p>
<ol class="doctools_enumerated">
<li><p>The package implementation.</p></li>
<li><p>The package index (&quot;<b class="file">pkgIndex.tcl</b>&quot;)</p></li>
<li><p>The package documentation.</p></li>
</ol>
<p>The &quot;<b class="file">sak.tcl</b>&quot; command <b class="cmd">validate version</b> helps
       finding discrepancies between the first two.
       All the other <b class="cmd">validate</b> methods are also of interest to
       any developer. Invoke it with</p>
<pre class="doctools_example"> sak.tcl help validate </pre>


<p>to see their documentation.</p>
</div>
</div>
<div id="section4" class="doctools_section"><h2><a name="section4">Structural Overview</a></h2>
<div id="subsection8" class="doctools_subsection"><h3><a name="subsection8">Main Directories</a></h3>
<p>The main directories in the Tcllib toplevel directory and of interest
to a developer are:</p>
<dl class="doctools_definitions">
<dt>&quot;<b class="file">modules</b>&quot;</dt>
<dd><p>Each child directory represents one or more packages.
In the case of the latter the packages are usually related in some
way. Examples are &quot;<b class="file">base64</b>&quot;, &quot;<b class="file">math</b>&quot;, and &quot;<b class="file">struct</b>&quot;, with
loose (base64) to strong (math) relations between the packages in the
directory.</p></dd>
<dt>&quot;<b class="file">apps</b>&quot;</dt>
<dd><p>This directory contains all the installable applications, with their
documentation. Note that this directory is currently <em>not</em> split
into sub-directories.</p></dd>
<dt>&quot;<b class="file">examples</b>&quot;</dt>
<dd><p>Each child directory &quot;<b class="file">foo</b>&quot; contains one or more example
application for the packages in &quot;<b class="file">modules/foo</b>&quot;. These examples are
generally not polished enough to be considered for installation.</p></dd>
</dl>
</div>
<div id="subsection9" class="doctools_subsection"><h3><a name="subsection9">More Directories</a></h3>
<dl class="doctools_definitions">
<dt>&quot;<b class="file">config</b>&quot;</dt>
<dd><p>This directory contains files supporting the Unix build system,
i.e. &quot;<b class="file">configure</b>&quot; and &quot;<b class="file">Makefile.in</b>&quot;.</p></dd>
<dt>&quot;<b class="file">devdoc</b>&quot;</dt>
<dd><p>This directories contains the doctools sources for the global
documentation, like this document and its sibling guides.</p></dd>
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
This is the documentation which will be installed.</p></dd>
<dt>&quot;<b class="file">support</b>&quot;</dt>
<dd><p>This directory contains the sources of internal packages and utilities
used in the implementation of the &quot;<b class="file">installer.tcl</b>&quot; and
&quot;<b class="file">sak.tcl</b>&quot; scripts/tools.</p></dd>
</dl>
</div>
<div id="subsection7" class="doctools_subsection"><h3><a name="subsection7">Top Files</a></h3>
<dl class="doctools_definitions">
<dt>&quot;<b class="file">aclocal.m4</b>&quot;</dt>
<dd></dd>
<dt>&quot;<b class="file">configure</b>&quot;</dt>
<dd></dd>
<dt>&quot;<b class="file">configure.in</b>&quot;</dt>
<dd></dd>







|







618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
This is the documentation which will be installed.</p></dd>
<dt>&quot;<b class="file">support</b>&quot;</dt>
<dd><p>This directory contains the sources of internal packages and utilities
used in the implementation of the &quot;<b class="file">installer.tcl</b>&quot; and
&quot;<b class="file">sak.tcl</b>&quot; scripts/tools.</p></dd>
</dl>
</div>
<div id="subsection10" class="doctools_subsection"><h3><a name="subsection10">Top Files</a></h3>
<dl class="doctools_definitions">
<dt>&quot;<b class="file">aclocal.m4</b>&quot;</dt>
<dd></dd>
<dt>&quot;<b class="file">configure</b>&quot;</dt>
<dd></dd>
<dt>&quot;<b class="file">configure.in</b>&quot;</dt>
<dd></dd>
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
<dd></dd>
<dt>&quot;<b class="file">tcllib.tap</b>&quot;</dt>
<dd></dd>
<dt>&quot;<b class="file">tcllib.yml</b>&quot;</dt>
<dd><p>????</p></dd>
</dl>
</div>
<div id="subsection8" class="doctools_subsection"><h3><a name="subsection8">File Types</a></h3>
<p>The most common file types, by file extension, are:</p>
<dl class="doctools_definitions">
<dt>&quot;<b class="file">.tcl</b>&quot;</dt>
<dd><p>Tcl code for a package, application, or example.</p></dd>
<dt>&quot;<b class="file">.man</b>&quot;</dt>
<dd><p>Doctools-formatted documentation, usually for a package.</p></dd>
<dt>&quot;<b class="file">.test</b>&quot;</dt>







|







666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
<dd></dd>
<dt>&quot;<b class="file">tcllib.tap</b>&quot;</dt>
<dd></dd>
<dt>&quot;<b class="file">tcllib.yml</b>&quot;</dt>
<dd><p>????</p></dd>
</dl>
</div>
<div id="subsection11" class="doctools_subsection"><h3><a name="subsection11">File Types</a></h3>
<p>The most common file types, by file extension, are:</p>
<dl class="doctools_definitions">
<dt>&quot;<b class="file">.tcl</b>&quot;</dt>
<dd><p>Tcl code for a package, application, or example.</p></dd>
<dt>&quot;<b class="file">.man</b>&quot;</dt>
<dd><p>Doctools-formatted documentation, usually for a package.</p></dd>
<dt>&quot;<b class="file">.test</b>&quot;</dt>
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
<p>Testsuites in Tcllib are based on Tcl's standard test package
<b class="package">tcltest</b>, plus utilities found in the directory
&quot;<b class="file">modules/devtools</b>&quot;</p>
<p>Tcllib developers invoke the suites through the
<b class="cmd">test run</b> method of the &quot;<b class="file">sak.tcl</b>&quot; tool, with other methods
of <b class="cmd"><a href="../../../index.html#test">test</a></b> providing management operations, for example setting a
list of standard Tcl shells to use.</p>
<div id="subsection9" class="doctools_subsection"><h3><a name="subsection9">Invoke the testsuites of a specific module</a></h3>
<p>Invoke either</p>
<pre class="doctools_example">  ./sak.tcl test run foo </pre>
<p>or</p>
<pre class="doctools_example">  ./sak.tcl test run modules/foo </pre>
<p>to invoke the testsuites found in a specific module &quot;<b class="file">foo</b>&quot;.</p>
</div>
<div id="subsection10" class="doctools_subsection"><h3><a name="subsection10">Invoke the testsuites of all modules</a></h3>
<p>Invoke the tool without a module name, i.e.</p>
<pre class="doctools_example">  ./sak.tcl test run </pre>
<p>to invoke the testsuites of all modules.</p>
</div>
<div id="subsection11" class="doctools_subsection"><h3><a name="subsection11">Detailed Test Logs</a></h3>
<p>In all the previous examples the test runner will write a combination
of progress display and testsuite log to the standard output, showing
for each module only the tests that passed or failed and how many of
each in a summary at the end.</p>
<p>To get a detailed log, it is necessary to invoke the test
runner with additional options.</p>
<p>For one:</p>







|






|




|







695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
<p>Testsuites in Tcllib are based on Tcl's standard test package
<b class="package">tcltest</b>, plus utilities found in the directory
&quot;<b class="file">modules/devtools</b>&quot;</p>
<p>Tcllib developers invoke the suites through the
<b class="cmd">test run</b> method of the &quot;<b class="file">sak.tcl</b>&quot; tool, with other methods
of <b class="cmd"><a href="../../../index.html#test">test</a></b> providing management operations, for example setting a
list of standard Tcl shells to use.</p>
<div id="subsection12" class="doctools_subsection"><h3><a name="subsection12">Invoke the testsuites of a specific module</a></h3>
<p>Invoke either</p>
<pre class="doctools_example">  ./sak.tcl test run foo </pre>
<p>or</p>
<pre class="doctools_example">  ./sak.tcl test run modules/foo </pre>
<p>to invoke the testsuites found in a specific module &quot;<b class="file">foo</b>&quot;.</p>
</div>
<div id="subsection13" class="doctools_subsection"><h3><a name="subsection13">Invoke the testsuites of all modules</a></h3>
<p>Invoke the tool without a module name, i.e.</p>
<pre class="doctools_example">  ./sak.tcl test run </pre>
<p>to invoke the testsuites of all modules.</p>
</div>
<div id="subsection14" class="doctools_subsection"><h3><a name="subsection14">Detailed Test Logs</a></h3>
<p>In all the previous examples the test runner will write a combination
of progress display and testsuite log to the standard output, showing
for each module only the tests that passed or failed and how many of
each in a summary at the end.</p>
<p>To get a detailed log, it is necessary to invoke the test
runner with additional options.</p>
<p>For one:</p>
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
</pre>
<p>This writes the detailed log to the standard output, instead of the
short log.</p>
<p>Regardless of form, the detailed log contains a list of all test
cases executed, which failed, and how they failed (expected versus
actual results).</p>
</div>
<div id="subsection12" class="doctools_subsection"><h3><a name="subsection12">Shell Selection</a></h3>
<p>By default the test runner will use all the Tcl shells specified via
<b class="cmd">test add</b> to invoke the specified testsuites, if any. If no
such are specified it will fall back to the Tcl shell used to run the
tool itself.</p>
<p>Use option <b class="option">--shell</b> to explicitly specify the Tcl shell
to use, like</p>
<pre class="doctools_example">
  ./sak.tcl test run --shell /path/to/tclsh ...
</pre>
</div>
<div id="subsection13" class="doctools_subsection"><h3><a name="subsection13">Help</a></h3>
<p>Invoke the tool as</p>
<pre class="doctools_example">  ./sak.tcl help test </pre>
<p>to see the detailed help for all methods of <b class="cmd"><a href="../../../index.html#test">test</a></b>, and the
associated options.</p>
</div>
</div>
<div id="section6" class="doctools_section"><h2><a name="section6">Documentation Tooling</a></h2>
<p>The standard format used for documentation of packages and other
things in Tcllib is <i class="term"><a href="../../../index.html#doctools">doctools</a></i>.
Its supporting packages are a part of Tcllib, see the directories
&quot;<b class="file">modules/doctools</b>&quot; and &quot;<b class="file">modules/dtplite</b>&quot;. The latter is
an application package, with the actual application
&quot;<b class="file">apps/dtplite</b>&quot; a light wrapper around it.</p>
<p>Tcllib developers gain access to these through the <b class="cmd">doc</b>
method of the &quot;<b class="file">sak.tcl</b>&quot; tool, another (internal) wrapper around
the &quot;<b class="file">modules/dtplite</b>&quot; application package.</p>
<div id="subsection14" class="doctools_subsection"><h3><a name="subsection14">Generate documentation for a specific module</a></h3>
<p>Invoke either</p>
<pre class="doctools_example">  ./sak.tcl doc html foo </pre>
<p>or</p>
<pre class="doctools_example">  ./sak.tcl doc html modules/foo </pre>
<p>to generate HTML for the documentation found in the module &quot;<b class="file">foo</b>&quot;.
Instead of <b class="const">html</b> any other supported format can be used here,
of course.</p>
<p>The generated formatted documentation will be placed into a
directory &quot;<b class="file">doc</b>&quot; in the current working directory.</p>
</div>
<div id="subsection15" class="doctools_subsection"><h3><a name="subsection15">Generate documentation for all modules</a></h3>
<p>Invoke the tool without a module name, i.e.</p>
<pre class="doctools_example">  ./sak.tcl doc html </pre>
<p>to generate HTML for the documentation found in all modules.
Instead of <b class="const">html</b> any other supported format can be used here,
of course.</p>
<p>The generated formatted documentation will be placed into a
directory &quot;<b class="file">doc</b>&quot; in the current working directory.</p>
</div>
<div id="subsection16" class="doctools_subsection"><h3><a name="subsection16">Available output formats, help</a></h3>
<p>Invoke the tool as</p>
<pre class="doctools_example">  ./sak.tcl help doc </pre>
<p>to see the entire set of supported output formats which can be
generated.</p>
</div>
<div id="subsection17" class="doctools_subsection"><h3><a name="subsection17">Validation without output</a></h3>
<p>Note the special format <b class="const">validate</b>.</p>
<p>Using this value as the name of the format to generate forces
the tool to simply check that the documentation is syntactically
correct, without generating actual output.</p>
<p>Invoke it as either</p>
<pre class="doctools_example">  ./sak.tcl doc validate (modules/)foo </pre>
<p>or</p>







|










|
















|










|








|





|







731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
</pre>
<p>This writes the detailed log to the standard output, instead of the
short log.</p>
<p>Regardless of form, the detailed log contains a list of all test
cases executed, which failed, and how they failed (expected versus
actual results).</p>
</div>
<div id="subsection15" class="doctools_subsection"><h3><a name="subsection15">Shell Selection</a></h3>
<p>By default the test runner will use all the Tcl shells specified via
<b class="cmd">test add</b> to invoke the specified testsuites, if any. If no
such are specified it will fall back to the Tcl shell used to run the
tool itself.</p>
<p>Use option <b class="option">--shell</b> to explicitly specify the Tcl shell
to use, like</p>
<pre class="doctools_example">
  ./sak.tcl test run --shell /path/to/tclsh ...
</pre>
</div>
<div id="subsection16" class="doctools_subsection"><h3><a name="subsection16">Help</a></h3>
<p>Invoke the tool as</p>
<pre class="doctools_example">  ./sak.tcl help test </pre>
<p>to see the detailed help for all methods of <b class="cmd"><a href="../../../index.html#test">test</a></b>, and the
associated options.</p>
</div>
</div>
<div id="section6" class="doctools_section"><h2><a name="section6">Documentation Tooling</a></h2>
<p>The standard format used for documentation of packages and other
things in Tcllib is <i class="term"><a href="../../../index.html#doctools">doctools</a></i>.
Its supporting packages are a part of Tcllib, see the directories
&quot;<b class="file">modules/doctools</b>&quot; and &quot;<b class="file">modules/dtplite</b>&quot;. The latter is
an application package, with the actual application
&quot;<b class="file">apps/dtplite</b>&quot; a light wrapper around it.</p>
<p>Tcllib developers gain access to these through the <b class="cmd">doc</b>
method of the &quot;<b class="file">sak.tcl</b>&quot; tool, another (internal) wrapper around
the &quot;<b class="file">modules/dtplite</b>&quot; application package.</p>
<div id="subsection17" class="doctools_subsection"><h3><a name="subsection17">Generate documentation for a specific module</a></h3>
<p>Invoke either</p>
<pre class="doctools_example">  ./sak.tcl doc html foo </pre>
<p>or</p>
<pre class="doctools_example">  ./sak.tcl doc html modules/foo </pre>
<p>to generate HTML for the documentation found in the module &quot;<b class="file">foo</b>&quot;.
Instead of <b class="const">html</b> any other supported format can be used here,
of course.</p>
<p>The generated formatted documentation will be placed into a
directory &quot;<b class="file">doc</b>&quot; in the current working directory.</p>
</div>
<div id="subsection18" class="doctools_subsection"><h3><a name="subsection18">Generate documentation for all modules</a></h3>
<p>Invoke the tool without a module name, i.e.</p>
<pre class="doctools_example">  ./sak.tcl doc html </pre>
<p>to generate HTML for the documentation found in all modules.
Instead of <b class="const">html</b> any other supported format can be used here,
of course.</p>
<p>The generated formatted documentation will be placed into a
directory &quot;<b class="file">doc</b>&quot; in the current working directory.</p>
</div>
<div id="subsection19" class="doctools_subsection"><h3><a name="subsection19">Available output formats, help</a></h3>
<p>Invoke the tool as</p>
<pre class="doctools_example">  ./sak.tcl help doc </pre>
<p>to see the entire set of supported output formats which can be
generated.</p>
</div>
<div id="subsection20" class="doctools_subsection"><h3><a name="subsection20">Validation without output</a></h3>
<p>Note the special format <b class="const">validate</b>.</p>
<p>Using this value as the name of the format to generate forces
the tool to simply check that the documentation is syntactically
correct, without generating actual output.</p>
<p>Invoke it as either</p>
<pre class="doctools_example">  ./sak.tcl doc validate (modules/)foo </pre>
<p>or</p>
Changes to idoc/www/tcllib/files/devdoc/tcllib_installer.html.
117
118
119
120
121
122
123



124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
<ul>
<li class="doctools_subsection"><a href="#subsection1">Tcl</a></li>
<li class="doctools_subsection"><a href="#subsection2">Critcl</a></li>
</ul>
</li>
<li class="doctools_section"><a href="#section3">Build &amp; Installation Instructions</a>
<ul>



<li class="doctools_subsection"><a href="#subsection3">Critcl &amp; Accelerators</a></ul>
</li>
</ul>
</div>
<div id="section1" class="doctools_section"><h2><a name="section1">Description</a></h2>
<p>Welcome to Tcllib, the Tcl Standard Library. Note that Tcllib is not a
package itself. It is a collection of (semi-independent) <i class="term"><a href="../../../index.html#tcl">Tcl</a></i>
packages that provide utility functions useful to a large collection
of Tcl programmers.</p>
<p>The audience of this document is anyone wishing to build the packages,
for either themselves, or others.</p>
<p>For a developer intending to extend or modify the packages we
additionally provide</p>
<ol class="doctools_enumerated">
<li><p><i class="term"><a href="tcllib_devguide.html">Tcllib - The Developer's Guide</a></i>.</p></li>
</ol>
<p>Please read <i class="term"><a href="tcllib_sources.html">Tcllib - How To Get The Sources</a></i> first, if that
was not done already. Here we assume that the sources are already
available in a directory of your choice.</p>







>
>
>
|








|
|
|







117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
<ul>
<li class="doctools_subsection"><a href="#subsection1">Tcl</a></li>
<li class="doctools_subsection"><a href="#subsection2">Critcl</a></li>
</ul>
</li>
<li class="doctools_section"><a href="#section3">Build &amp; Installation Instructions</a>
<ul>
<li class="doctools_subsection"><a href="#subsection3">Installing on Unix</a></li>
<li class="doctools_subsection"><a href="#subsection4">Installing on Windows</a></li>
<li class="doctools_subsection"><a href="#subsection5">Critcl &amp; Accelerators</a></li>
<li class="doctools_subsection"><a href="#subsection6">Tooling</a></ul>
</li>
</ul>
</div>
<div id="section1" class="doctools_section"><h2><a name="section1">Description</a></h2>
<p>Welcome to Tcllib, the Tcl Standard Library. Note that Tcllib is not a
package itself. It is a collection of (semi-independent) <i class="term"><a href="../../../index.html#tcl">Tcl</a></i>
packages that provide utility functions useful to a large collection
of Tcl programmers.</p>
<p>The audience of this document is anyone wishing to build and install
the packages found in Tcllib, for either themselves, or others.</p>
<p>For developers intending to work on the packages themselves we
additionally provide</p>
<ol class="doctools_enumerated">
<li><p><i class="term"><a href="tcllib_devguide.html">Tcllib - The Developer's Guide</a></i>.</p></li>
</ol>
<p>Please read <i class="term"><a href="tcllib_sources.html">Tcllib - How To Get The Sources</a></i> first, if that
was not done already. Here we assume that the sources are already
available in a directory of your choice.</p>
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
please file a ticket against <i class="term"><a href="../../../index.html#tcl">Tcl</a></i>, or the vendor of your
distribution, and <em>not</em> <i class="term"><a href="../../../index.html#tcllib">Tcllib</a></i>.</p>
</div>
<div id="subsection2" class="doctools_subsection"><h3><a name="subsection2">Critcl</a></h3>
<p>The <b class="syscmd">critcl</b> tool is an <em>optional</em> dependency.</p>
<p>It is only required when trying to build the C-based
<i class="term">accelerators</i> for a number of packages, as explained in
<span class="sectref"><a href="#subsection3">Critcl &amp; Accelerators</a></span></p>
<p>Tcllib's build system looks for it in the ,
using the name <b class="syscmd">critcl</b>. This is for Unix.
On Windows on the other hand the search is more complex. First we look
for a proper application <b class="syscmd">critcl.exe</b>. When that is not found
we look for a combination of interpreter (<b class="syscmd">tclkitsh.exe</b>,
<b class="syscmd">tclsh.exe</b>) and starkit (<b class="syscmd">critcl.kit</b>, <b class="syscmd">critcl</b>)
instead. <em>Note</em> that the choice of starkit can be overriden via







|







194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
please file a ticket against <i class="term"><a href="../../../index.html#tcl">Tcl</a></i>, or the vendor of your
distribution, and <em>not</em> <i class="term"><a href="../../../index.html#tcllib">Tcllib</a></i>.</p>
</div>
<div id="subsection2" class="doctools_subsection"><h3><a name="subsection2">Critcl</a></h3>
<p>The <b class="syscmd">critcl</b> tool is an <em>optional</em> dependency.</p>
<p>It is only required when trying to build the C-based
<i class="term">accelerators</i> for a number of packages, as explained in
<span class="sectref"><a href="#subsection5">Critcl &amp; Accelerators</a></span></p>
<p>Tcllib's build system looks for it in the ,
using the name <b class="syscmd">critcl</b>. This is for Unix.
On Windows on the other hand the search is more complex. First we look
for a proper application <b class="syscmd">critcl.exe</b>. When that is not found
we look for a combination of interpreter (<b class="syscmd">tclkitsh.exe</b>,
<b class="syscmd">tclsh.exe</b>) and starkit (<b class="syscmd">critcl.kit</b>, <b class="syscmd">critcl</b>)
instead. <em>Note</em> that the choice of starkit can be overriden via
215
216
217
218
219
220
221
222
223
224

225
226
227
228
229
230
231

232
233
234
235
236
237
238
239
240

241


242
243
244
245
246
247
248
249
250
251
252
253
254

255
256

257

258
259
260
261
262
263
264
265
266

267
268






269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285

286

287
288
289

290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310

311



























































































312

313
install Critcl, including a list of its dependencies.</p>
<p>Its instructions will not be repeated here. If there are
problems with these directions please file a ticket against the
<i class="term">Critcl</i> project, and not Tcllib.</p>
</div>
</div>
<div id="section3" class="doctools_section"><h2><a name="section3">Build &amp; Installation Instructions</a></h2>
<p>The Tcllib distribution, whether a checkout directly from the source
repository, or an official release, offers a single method for
installing it, based on Tcl itself.</p>

<p>This is based on the assumption that for Tcllib to be of use
Tcl has to be present, and therefore can be used in the implementation
of the install code.</p>
<p>The relevant tool is the &quot;<b class="file">installer.tcl</b>&quot; script found in
the toplevel directory of a checkout or release.</p>
<p>It can be used in a variety of ways:</p>
<ol class="doctools_enumerated">

<li><p>It is always possible to invoke the tool directly, either as</p>
<pre class="doctools_example">
    ./installer.tcl
</pre>
<p>or</p>
<pre class="doctools_example">
    /path/to/tclsh ./installer.tcl
</pre>
<p>The second form is required on Windows (without a Unix emulation),

except if the Tcl installation is configured to handle &quot;<b class="file">.tcl</b>&quot;


files on a double-click.</p></li>
<li><p>In a Unix-type environment, i.e. Linux, BSD and related, including OS
X, and Windows using some kind of unix-emulation like <b class="syscmd">MSYS</b>,
<b class="syscmd">Cygwin</b>, etc.) it is also possible to use</p>
<pre class="doctools_example">
    ./configure
    make install
</pre>
<p>in the toplevel directory of Tcllib itself.</p>
<p>To build in a directory &quot;<b class="file">D</b>&quot; outside of Tcllib's toplevel
directory simply make &quot;<b class="file">D</b>&quot; the current working directory and
invoke <b class="syscmd">configure</b> with either its absolute path or a proper
relative path.</p>

<p>This will non-interactively install all packages, applications
found in Tcllib, and their manpages, in directories derived from what

<b class="syscmd">configure</b> found out about the system.</p></li>

</ol>
<p>The installer selects automatically either a GUI based mode, or
a command line based mode. If the package <b class="package"><a href="../../../index.html#tk">Tk</a></b> is present and
can be loaded, then the GUI mode is entered, else the system falls
back to the command line.</p>
<p>Note that it is possible to specify options on the command line
even if the installer ultimatively selects GUI mode. In that case the
hardwired defaults and the options determine the data presented to the
user for editing.</p>

<p>Command line help can be asked for by using the option <b class="option">-help</b> when
invoking the installer, i.e.</p>






<pre class="doctools_example">
    ./installer.tcl -help
</pre>
<p>This will print a short list of the available options to the standard
output channel. For more examples see the various <i class="term">install</i>
targets found in &quot;<b class="file">Makefile.in</b>&quot;.</p>
<p>The installer will select a number of defaults for the
locations of packages, examples, and documentation, and also the
format of the documentation. The user can overide these defaults in
the GUI, or by specifying additional options.</p>
<p>The defaults depend on the platform detected (Unix/Windows) and
on the <b class="syscmd">tclsh</b> executable used to run the installer.</p>
<p><em>Attention</em> The installer will overwrite an existing
installation of a Tcllib with the same version without asking back
after the initial confirmation is given.
Further if the user chooses the same directory as chosen for/by
previous installations then these will be overwritten as well.</p>

<div id="subsection3" class="doctools_subsection"><h3><a name="subsection3">Critcl &amp; Accelerators</a></h3>

<p>A number of packages come with <i class="term">accelerators</i>, i.e.
<b class="syscmd">critcl</b>-based C code whose use will boost the performance of
the packages using them. As these accelerators are optional they are

not installed by default.</p>
<p>To build the accelerators the normally optional dependency on
<b class="syscmd">critcl</b> becomes required.</p>
<p>To install Tcllib with the accelerators in a Unix-type
environment invoke:</p>
<pre class="doctools_example">
    ./configure
    make critcl # This builds the shared library holding
                # the accelerators
    make install
</pre>
<p>The underlying tool is &quot;<b class="file">sak.tcl</b>&quot; in the toplevel directory
of Tcllib and the command <b class="cmd">make critcl</b> is just a wrapper around</p>
<pre class="doctools_example">
    ./sak.tcl critcl
</pre>
<p>Therefore in a Windows environment instead invoke</p>
<pre class="doctools_example">
    /path/to/tclsh ./sak.tcl critcl
    /path/to/tclsh ./installer.tcl
</pre>

</div>



























































































</div>

</div></body></html>







|
<
|
>
|
<
|
<
<
<
|
>
|
|
<
<
|
|
|
<
<
>
|
>
>
|
<
<
<

|
|

|
<
<
<
<
>
|
|
>
|
>
|
<
<
<
|
<
<
<
|
>
|
|
>
>
>
>
>
>

|

<
<
<
<
<
<
|
<
<
<
<
<
<
<
>
|
>
|
|
|
>
|

|
|
|

|
|
|
|




|



|
|

>

>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>

>

218
219
220
221
222
223
224
225

226
227
228

229



230
231
232
233


234
235
236


237
238
239
240
241



242
243
244
245
246




247
248
249
250
251
252
253



254



255
256
257
258
259
260
261
262
263
264
265
266
267






268







269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
install Critcl, including a list of its dependencies.</p>
<p>Its instructions will not be repeated here. If there are
problems with these directions please file a ticket against the
<i class="term">Critcl</i> project, and not Tcllib.</p>
</div>
</div>
<div id="section3" class="doctools_section"><h2><a name="section3">Build &amp; Installation Instructions</a></h2>
<p>As Tcllib is mainly a bundle of packages written in pure Tcl building

it is the same as installing it. The exceptions to this have their own
subsection, <span class="sectref"><a href="#subsection5">Critcl &amp; Accelerators</a></span>, later on.</p>
<p>Before that however comes the standard case, differentiated by

       the platforms with material differences in the instruction, i.e.



       <i class="term">Unix</i>-like, versus <i class="term">Windows</i>.</p>
<p>Regarding the latter it should also be noted that it is
       possible set up an <i class="term">Unix</i>-like environment using projects
       like <i class="term">MSYS</i>, <i class="term">Cygwin</i>, and others. In that case the


       user has the choice of which instructions to follow.</p>
<p>Regardless of environment or platform, a suitable <i class="term"><a href="../../../index.html#tcl">Tcl</a></i>
       has to be installed, and its <b class="syscmd">tclsh</b> should be placed on


       the  (<i class="term">Unix</i>) or associated with
       &quot;<b class="file">.tcl</b>&quot; files (<i class="term">Windows</i>).</p>
<div id="subsection3" class="doctools_subsection"><h3><a name="subsection3">Installing on Unix</a></h3>
<p>For <i class="term">Unix</i>-like environments Tcllib comes with the standard set
of files to make</p>



<pre class="doctools_example">
  ./configure
  make install
</pre>
<p>a suitable way of installing it.




This is a standard non-interactive install automatically figuring out
where to place everything, i.e. packages, applications, and the
manpages.</p>
<p>To get a graphical installer invoke</p>
<pre class="doctools_example">
  ./installer.tcl
</pre>



<p>instead.</p>



</div>
<div id="subsection4" class="doctools_subsection"><h3><a name="subsection4">Installing on Windows</a></h3>
<p>In a Windows environment we have the <b class="cmd">installer.tcl</b> script to
perform installation.</p>
<p>If the desired <b class="syscmd">tclsh</b> is associated &quot;<b class="file">.tcl</b>&quot; files
       then double-clicking / opening the <b class="cmd">installer.tcl</b> is
       enough to invoke it in graphical mode.
       This assumes that <i class="term"><a href="../../../index.html#tk">Tk</a></i> is installed and available as well.</p>
<p>Without <i class="term"><a href="../../../index.html#tk">Tk</a></i> the only way to invoke the installer are to
       open a DOS window, i.e. <b class="syscmd">cmd.exe</b>, and then to invoke</p>
<pre class="doctools_example">
  ./installer.tcl
</pre>






<p>inside it.</p>







</div>
<div id="subsection5" class="doctools_subsection"><h3><a name="subsection5">Critcl &amp; Accelerators</a></h3>
<p>While the majority of Tcllib consists of packages written in pure Tcl
a number of packages also have <i class="term">accelerators</i> associated with them.
These are <b class="syscmd">critcl</b>-based C packages whose use will boost the
performance of the packages using them.
These accelerators are optional, and they are not installed by
default.</p>
<p>To build the accelerators the normally optional dependency on
       <b class="syscmd">critcl</b> becomes required.</p>
<p>To build and install Tcllib with the accelerators in a
       Unix-like environment invoke:</p>
<pre class="doctools_example">
  ./configure
  make critcl # This builds the shared library holding
              # the accelerators
  make install
</pre>
<p>The underlying tool is &quot;<b class="file">sak.tcl</b>&quot; in the toplevel directory
of Tcllib and the command <b class="cmd">make critcl</b> is just a wrapper around</p>
<pre class="doctools_example">
  ./sak.tcl critcl
</pre>
<p>Therefore in a Windows environment instead invoke</p>
<pre class="doctools_example">
  ./sak.tcl critcl
  ./installer.tcl
</pre>
<p>from within a DOS window, i.e. <b class="syscmd">cmd.exe</b>.</p>
</div>
<div id="subsection6" class="doctools_subsection"><h3><a name="subsection6">Tooling</a></h3>
<p>The core of Tcllib's build system is the script &quot;<b class="file">installer.tcl</b>&quot;
found in the toplevel directory of a checkout or release.</p>
<p>The</p>
<pre class="doctools_example">
         configure ; make install
       </pre>
<p>setup available to
       developers on Unix-like systems is just a wrapper around it.
       To go beyond the standard embodied in the wrapper it is
       necessary to directly invoke this script.</p>
<p>On Windows system using it directly is the only way to invoke
       it.</p>
<p>For basic help invoke it as</p>
<pre class="doctools_example">
         ./installer.tcl -help
       </pre>
<p>This will print a short list of all the available options to
       the standard output channel.</p>
<p>The commands associated with the various <i class="term">install</i> targets
       in the <i class="term">Makefile.in</i> for Unix can be used as additional
       examples on how to use this tool as well.</p>
<p>The installer can operate in GUI and CLI modes.
       By default it chooses the mode automatically, based on if the
       Tcl package <b class="package"><a href="../../../index.html#tk">Tk</a></b> can be used or not.
       The option <b class="option">-no-gui</b> can be used to force CLI mode.</p>
<p>Note that it is possible to specify options on the command line
       even if the installer ultimatively selects GUI mode. In that
       case the hardwired defaults and the options determine the data
       presented to the user for editing.</p>
<p>The installer will select a number of defaults for the
       locations of packages, examples, and documentation, and also
       the format of the documentation. The user can overide these
       defaults in the GUI, or by specifying additional options.
       The defaults depend on the platform detected (Unix/Windows) and
       on the <b class="syscmd">tclsh</b> executable used to run the installer.</p>
<p><em>Options</em></p>
<dl class="doctools_options">
<dt><b class="option">-help</b></dt>
<dd><p>Show the list of options explained here on the standard output channel
and exit.</p></dd>
<dt><b class="option">+excluded</b></dt>
<dd><p>Include deprecated packages in the installation.</p></dd>
<dt><b class="option">-no-gui</b></dt>
<dd><p>Force command line operation of the installer</p></dd>
<dt><b class="option">-no-wait</b></dt>
<dd><p>In CLI mode the installer will by default ask the user to confirm that
the chosen configuration (destination paths, things to install) is
correct before performing any action. Using this option causes the
installer to skip this query and immediately jump to installation.</p></dd>
<dt><b class="option">-app-path</b> <i class="arg">path</i></dt>
<dd></dd>
<dt><b class="option">-example-path</b> <i class="arg">path</i></dt>
<dd></dd>
<dt><b class="option">-html-path</b> <i class="arg">path</i></dt>
<dd></dd>
<dt><b class="option">-nroff-path</b> <i class="arg">path</i></dt>
<dd></dd>
<dt><b class="option">-pkg-path</b> <i class="arg">path</i></dt>
<dd><p>Declare the destination paths for the applications, examples, html
documentation, nroff manpages, and packages. The defaults are derived
from the location of the <b class="syscmd">tclsh</b> used to run the installer.</p></dd>
<dt><b class="option">-dry-run</b></dt>
<dd></dd>
<dt><b class="option">-simulate</b></dt>
<dd><p>Run the installer without modifying the destination directories.</p></dd>
<dt><b class="option">-apps</b></dt>
<dd></dd>
<dt><b class="option">-no-apps</b></dt>
<dd></dd>
<dt><b class="option">-examples</b></dt>
<dd></dd>
<dt><b class="option">-no-examples</b></dt>
<dd></dd>
<dt><b class="option">-pkgs</b></dt>
<dd></dd>
<dt><b class="option">-no-pkgs</b></dt>
<dd></dd>
<dt><b class="option">-html</b></dt>
<dd></dd>
<dt><b class="option">-no-html</b></dt>
<dd></dd>
<dt><b class="option">-nroff</b></dt>
<dd></dd>
<dt><b class="option">-no-nroff</b></dt>
<dd><p>(De)activate the installation of applications, examples, packages,
html documentation, and nroff manpages.</p>
<p>Applications, examples, and packages are installed by default.</p>
<p>On Windows the html documentation is installed by default.</p>
<p>On Unix the nroff manpages are installed by default.</p></dd>
</dl>
</div>
</div>
</div></body></html>
Changes to installer.tcl.
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
	# Starpack. No defaults for location.
    } else {
	# Starkit, or unwrapped. Derive defaults location from the
	# location of the executable running the installer, or the
	# location of its library.

	# For a starkit [info library] is inside the running
	# tclkit. Detect this and derive the lcoation from the
	# location of the executable itself for that case.

	if {[string match [info nameofexecutable]* [info library]]} {
	    # Starkit
	    set libdir [file join [file dirname [file dirname [info nameofexecutable]]] lib]
	} else {
	    # Unwrapped.







|







278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
	# Starpack. No defaults for location.
    } else {
	# Starkit, or unwrapped. Derive defaults location from the
	# location of the executable running the installer, or the
	# location of its library.

	# For a starkit [info library] is inside the running
	# tclkit. Detect this and derive the location from the
	# location of the executable itself for that case.

	if {[string match [info nameofexecutable]* [info library]]} {
	    # Starkit
	    set libdir [file join [file dirname [file dirname [info nameofexecutable]]] lib]
	} else {
	    # Unwrapped.