The CLI’s Essential ‘Verbose’ Option

For those creating their own CLI tool

If you have played around with any command line interface tools, such as Particle CLI or Git UI, you’ll notice that they oftentimes will have a verbose or -v option with their commands. This allows you to change log levels within the program, outputting as little or as much as you desire.

This example CLI tool makes use of the Click library for Python. If you are having trouble getting started, check out my first blog on making a professional-looking CLI tool or Click’s documentation.

Why Do I Need the Verbose Option?

When using your CLI tool, users may have a variety of reasons for wanting to change how much information is displayed.

If a user is debugging a process or needs to know a little more about the error being thrown, they may want to use the verbose option to dump out more logs and information to nail down their issue.

On the other side, a user may just want to be quickly using the CLI commands and does not want or need to see the multitudes of code on every successful run. Some users may not have a firm grasp on functionality behind your CLI tool and it’ll look messy and confusing to them.

verbose option
What your user sees when you print out everything

Logging Levels

Here’s how I set up my ‘cool_logger’ in mysupercoolscript from the last blog post.

First off, click.option is added. This will add the option —verbose or -v. Both of these options will dump out the same log, one just being longer and the other quicker to type out. Secondly, we want to edit the mysupercoolscript definition. Before, the only parameter was self. Now, it will take in the parameters self and verbose. Then, the if/else statement will set the log level to either DEBUG or INFO depending on if the verbose option was given or not.

@click.group()
@click.option('--verbose', '-v', is_flag=True, help="Will print more logging messages.")
@click.pass_context
def mysupercoolscript(self, verbose):
  if verbose:
    cool_logger.setLevel(logging.DEBUG)
  else:
    cool_logger.setLevel(logging.INFO)
  pass

The next step and easiest way to implement the verbose option is to set logging levels. If you are a bit confused on how python’s logging works, lay your confusion to rest here. This is in “main” in mysupercoolscript.py file, which you can find a link to at the bottom of this post.

import logging

cool_logger = logging.getLogger('cool_logger')
cl = logging.StreamHandler()
cl.setLevel(logging.DEBUG)
formatter = logging.Formatter('%(message)s')
cl.setFormatter(formatter)
cool_logger.addHandler(cl)

Adding the above code snippit with your own logger name (or you could keep cool_logger 😎) will initialize your logger. Now, we need to add a bit to our main function in mysupercoolscript.py to allow the option to work. In the initialization of our group, we will add:

Now on to the final piece of the puzzle. Instead of using the print or another function, we will use cool_logger.debug and cool_logger.info based on when we want our information printed. With the current setup, when you want something printed all the time, you want to use cool_logger.info. When you want a line to print only when the verbose option is used, you want to use cool_logger.debug.

Guide on Where and When to Use Different Levels

Now Python’s logger actually has six different levels for you to utilize, but I’ll only be showing off two of them: DEBUG and INFO.

Here at Dojo Five, we try to keep our CLI tool’s logger to a guideline so we keep it nice and tidy.

Generally, keeping your reporting short and sweet, especially on successful runs. Only mention important parts, and be descriptive but short.

For failures, we will want to give one error line. It should be short and to the point, but readable.

For example, say you have a command build that compiles a script, then stores the output into a folder named outputs.

Running build may yield:

Compiled Successfully.

ERROR: Output not stored. 
Message: Directory outputs not found

Whereas if you ran build --verbose, it may yield a more-inclusive:

Building test.cpp...
Building test2.cpp...
WARNING: Variable A is delcared but not used.

Compiled Successfully.

Error during output stage:
ERROR: Output not stored. 
Directory: outputs not found.
Output files will not be saved.

The Dry Stuff (Code)

Just in case you’re a bit confused about how everything is being implemented, you can find my source code for these examples on gitlab: source code.

There you can find both setup.py and supercoolscript.py

What are some things you’re struggling with on your CLI? Feel free to reach out  if you would like help. Good luck with your future CLI endeavors!

And if you have questions about an embedded project you’re working on, Dojo Five can help you with all aspects of your devops for embedded journey! We are always happy to hear about cool projects or interesting problems to solve. Bring your interesting problems that need solving – we are always happy to help out. You can reach out at any time on LinkedIn or through email!, 

Sign up to get our content updates!

Unlock the full potential of your embedded projects with our expert insights! Dive into our comprehensive resources to stay ahead in firmware development. Subscribe now to get the latest best practices and guides delivered straight to your inbox.

Sign Up for Updates

Discover why Dojo Five EmbedOps is the embedded enterprise choice for build tool and test management.

Sign up to receive a free account to the EmbedOps platform and start building with confidence..

  • Connect a repo
  • Use Dev Containers with your Continuous Integration (CI) provider
  • Analyze memory usage
  • Integrate and visualize static analysis results
  • Perform Hardware-in-the-Loop (HIL) tests
  • Install the Command Line Interface for a developer-friendly experience

Subscribe to our Monthly Newsletter

Subscribe to our monthly newsletter for development insights delivered straight to your inbox.

Interested in learning more?

Best-in-class embedded firmware content, resources and best practices

Futuristic development graphic

Controlled Development Environments

Docker is a great solution for controlled development environments. One of the great things about Docker is specifying an entire environment. You create a list that includes the OS, along with all of the tools, accessories, scripts, and whatever else you want to appear in that image. Docker, in turn, goes and collects all of those components and builds a custom image to match your list. The real value here is for development environments that need to be controlled for

Read More »
Power Optimization Techniques for Firmware

Power Optimization Techniques for Firmware

Introduction Power efficiency is a critical factor in the success of modern embedded systems, especially for battery-powered devices. Efficient firmware design can significantly extend battery life, reduce heat, and improve overall system reliability. Whether your team is optimizing performance or focusing on product longevity, understanding how firmware impacts power consumption is essential. In this post, we’ll explore five practical techniques to help you build smarter, low-power embedded applications. Sleep/Power Modes One of the most effective ways to reduce power consumption

Read More »
Firmware Development vs. Software Development: What Sets These Disciplines Apart

Firmware Development vs. Software Development: What Sets These Disciplines Apart

Managing firmware projects is fundamentally different from managing traditional software projects. While both disciplines require technical expertise, planning, and coordination, firmware project management introduces unique challenges due to its deep integration with hardware, higher risk profile, and the multidisciplinary skills required.  This guide examines how the firmware development process diverges from standard software practices, explores the impact of modern firmware tools, and outlines what project managers must do to optimize firmware projects for today’s embedded systems development landscape. Embedded Systems

Read More »