If you structure your program in a certain way, there's no need to distinguish between procedures and commands. See git and rbenv, which expose a single meta-command to your $PATH but are comprised internally of many smaller commands that invoke each other and communicate over standard I/O.
Comments
If you structure your program in a certain way, there's no need to distinguish between procedures and commands. See git and rbenv, which expose a single meta-command to your $PATH but are comprised internally of many smaller commands that invoke each other and communicate over standard I/O.
This is also known as the UNIX philosophy :)
I doubt that all of git commit is implemented in main. So I'm sure that there is still plenty of use for unit tests.
As a matter of fact, all automated tests of the Git project are powered by a shell-based TAP harness, which tests executable commands only.
To be fair, there are some dedicated C tools driving unit tests via CLI, but most of the tests are based on the final plumbing and porcelain commands.