Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What are the best-practices for implementing a CLI tool in Perl?

I am implementing a CLI tool using Perl. What are the best-practices we can follow here?

like image 981
Anandan Avatar asked Jul 26 '09 06:07

Anandan


People also ask

How can you implement a command line tool?

Create a file index. js in the root of the project. This will be the main entry of the CLI tool that will initialize the commands it will have. NOTE: If you are using Windows for development, make sure that the line end character is set to LF instead of CRLF or the tool will not work.

What is a CLI tool?

A command-line interface (CLI) is a text-based user interface (UI) used to run programs, manage computer files and interact with the computer. Command-line interfaces are also called command-line user interfaces, console user interfaces and character user interfaces.


1 Answers

As a preface, I spent 3 years engineering and implementing a pretty complicated command line toolset in Perl for a major financial company. The ideas below are basically part of our team's design guidelines.

User Interface

  1. Command line option: allow as many as possible have default values.

  2. NO positional parameters for any command that has more than 2 options.

  3. Have readable options names. If length of command line is a concern for non-interactive calling (e.g. some un-named legacy shells have short limits on command lines), provide short aliases - GetOpt::Long allows that easily.

  4. At the very least, print all options' default values in '-help' message.

    Better yet, print all the options' "current" values (e.g. if a parameter and a value are supplied along with "-help", the help message will print parameter's value from command line). That way, people can assemble command line string for complicated command and verify it by appending "-help", before actually running.

  5. Follow Unix standard convention of exiting with non-zero return code if program terminated with errors.

  6. If your program may produce useful (e.g. worth capturing/grepping/whatnot) output, make sure any error/diagnostic messages go to STDERR so they are easily separable.

  7. Ideally, allow the user to specify input/output files via command line parameter, instead of forcing "<" / ">" redirects - this allows MUCH simpler life to people who need to build complicated pipes using your command. Ditto for error messages - have logfile option.

  8. If a command has side effect, having a "whatif/no_post" option is usually a Very Good Idea.

Implementation

  1. As noted previously, don't re-invent the wheel. Use standard command line parameter handling modules - MooseX::Getopt, or Getopt::Long

  2. For Getopt::Long, assign all the parameters to a single hash as opposed to individual variables. Many useful patterns include passing that CLI args hash to object constructors.

  3. Make sure your error messages are clear and informative... E.g. include "$!" in any IO-related error messages. It's worth expending extra 1 minute and 2 lines in your code to have a separate "file not found" vs. "file not readable" errors, as opposed to spending 30 minutes in production emergency because a non-readable file error was misdiagnosed by Production Operations as "No input file" - this is a real life example.

  4. Not really CLI-specific, but validate all parameters, ideally right after getting them. CLI doesn't allow for a "front-end" validation like webapps do, so be super extra vigilant.

  5. As discussed above, modularize business logic. Among other reasons already listed, the amount of times I had to re-implement an existing CLI tool as a web app is vast - and not that difficult if the logic is already a properly designed perm module.

Interesting links

CLI Design Patterns - I think this is ESR's

I will try to add more bullets as I recall them.

like image 182
DVK Avatar answered Sep 22 '22 01:09

DVK