Contributing
Thank you for considering contributing to Modules!
Support questions
Please use the modules-interest mailing list for questions. Do not use the issue tracker for this.
Asking for new features
Please submit your new feature wishes first to the modules-interest mailing list. Discussion will help to clarify your needs and sometimes the wanted feature may already be available.
Reporting issues
Describe what you expected to happen.
If possible, include a minimal, complete, and verifiable example to help us identify the issue.
Describe what actually happened. Run the
module
command in--debug
mode and include all the debug output obtained in your report.Provide the current configuration and state of your Modules installation by running the
module config --dump-state
command.Provide the name and content of the modulefiles you try to manipulate.
Submitting patches
Whether your patch is supposed to solve a bug or add a new feature, please include tests. In case of a bug, explain clearly under which circumstances it happens and make sure the test fails without your patch.
If you are not yet familiar with the
git
command and GitHub, please read the don't be afraid to commit tutorial.
Start coding
Create a branch to identify the issue or feature you would like to work on
Using your favorite editor, make your changes, committing as you go.
Comply to the coding conventions of this project.
Your Tcl code has to be compatible with Tcl version 8.5 and above (see Tcl 8.5 commands reference)
Include tests that cover any code changes you make. Make sure the test fails without your patch.
Push your commits to GitHub and create a pull request.
Design notes
See the Design notes for recent feature specifications. You may also find there some development howtos:
Running the tests
Run the basic test suite with:
make test
This only runs the tests for the current environment. GitHub Actions and Cirrus CI will run the full suite when you submit your pull request.
There are more than 17 000 test cases thus it generally takes around 12 minutes to run the full test suite. It can be executed in quick mode to just run the most essential tests in about 1 minute:
make test QUICKTEST=y
The script/mt utility is also available to just execute one or
several testfiles. If a test fails, script/mt reports the diff
comparison between expected and actual results. For instance, to only
execute testsuite/modules.50-cmds/470-variant.exp
testfile, run:
script/mt 50/470
Run script/mt with --help
option to get usage details and
syntax to select several testfiles.
Running test coverage
Generating a report of lines that do not have test coverage can indicate where to start contributing or what your tests should cover for the code changes you submit.
Run make test COVERAGE=y
which will automatically setup the Nagelfar
Tcl code coverage tool in your modules
development directory and
instrument the source Tcl scripts. Then the full testsuite will be run in
coverage mode and an annotated script will be produced for each Tcl script in
tcl
source directory (tcl/*.tcl_m
):
make test COVERAGE=y
# then open tcl/*.tcl_m files and look for ';# Not covered' lines
The script/mt utility may also be used to run the test suite in coverage mode on full testsuite or on a few testfiles:
script/mt cov 70/{280,290}
Running linter tests
Linter tools check code syntax and report issues and good practices to follow. Modules uses Nagelfar to check syntax of Tcl scripts and ShellCheck to lint sh, bash and ksh scripts.
Run make testlint
to lint all sh, bash, ksh and Tcl scripts in your local
Modules repository.
The script/mt utility may also be used to run the full lint test suite or just specific testfiles. For instance to only lint Tcl scripts:
script/mt lint 00/030
Check performances
The script/mb utility checks from your local repository the performances of major releases of Modules and current branch. Current ongoing modifications are first stashed, then modulecmd.tcl of the releases and current branch are built. Different tests are run against each version and the execution time of each test is reported in millisecond:
$ script/mb
| v4.1.4 | v4.3.1 | v4.5.3 | v4.7.1 | v5.1.1 | main |
----------+----------+----------+----------+----------+----------+----------+
help | 9 | 12 | 12 | 15 | 16 | 16 |
avail | 61 | 67 | 76 | 82 | 91 | 86 |
avail2 | 11 | 16 | 19 | 21 | 23 | 23 |
avail3 | - | - | - | 120 | 128 | 130 |
whatis | 208 | 155 | 233 | 216 | 221 | 224 |
whatis2 | 10 | 15 | 17 | 20 | 21 | 22 |
whatis3 | - | - | - | 287 | 307 | 314 |
apropos | 208 | 153 | 222 | 210 | 220 | 223 |
load | 66 | 87 | 134 | 162 | 120 | 126 |
list | 24 | 23 | 33 | 22 | 25 | 25 |
unload | 46 | 24 | 25 | 29 | 31 | 31 |
It helps to verify that current work committed in local repository does not
impact performances on simple test scenarios. Run script/mb with
--help
option to get its usage details.
The profile
mode may also be interesting to learn what are the internal
procedures of modulecmd.tcl taking most of the execution time for
each test:
script/mb profile
Building the docs
Build the docs in the doc
directory using Sphinx:
cd doc
make html
Open _build/html/index.html
in your browser to view the docs.
Read more about Sphinx.
Coding conventions
Maximum line length is 78 characters
Use 3 spaces to indent code (do not use tab character)
Procedure names:
lowerCameCase
Variable names:
nocaseatall
Curly brace and square bracket placement:
if {![isStateDefined already_report]} { setState already_report 1 }
Commit hooks
A pre-commit hook script is provided in the script
directory of the project to help you check that the contribution made is free
of misspellings and trailing spaces. It requires the codespell utility that
checks for typos in any kind of files and the Hunspell utility that spell
checks documentation files. The pre-commit could be enabled in your
local repository with following command:
ln -s ../../script/pre-commit .git/hooks/pre-commit
A commit-msg hook script is also provided in the script
directory of the project to help you check that your commit messages are free
of misspellings. It requires the Hunspell utility and could be enabled in
your local repository with following command:
ln -s ../../script/commit-msg .git/hooks/commit-msg
Emacs settings for coding conventions
This is an example Emacs configuration that adheres to the first two
coding conventions. You may wish to add this to your .emacs
or
.emacs.d/
to modify your tcl-mode:
(add-hook 'tcl-mode-hook
(lambda ()
(setq indent-tabs-mode nil)
(setq tcl-indent-level 3)
(setq tcl-continued-indent-level 3)
(font-lock-add-keywords nil '(("^[^\n]\\{79\\}\\(.*\\)$" 1
font-lock-warning-face prepend)))))
Submitting installation recipes
If you want to share your installation tips and tricks, efficient ways you have to write or organize your modulefiles or some extension you made to the
module
command please add a recipe to the cookbook section of the documentation.Create a directory under
doc/example
and put there the extension code or example modulefiles your recipe is about.Describe this recipe through a reStructuredText document in
doc/source/cookbook
. It is suggested to have an Implementation, an Installation and an Usage example sections in that document to get as much as possible the same document layout across recipes.Submit a patch with all the above content.