Building a CLI for Firmware Projects using Invoke | Interrupt

Building a small (or large) command line interface (CLI) for a project is a great way to get an entire team to build, test, debug, and work with a project in the same way using the same set of tools. This post goes into detail about how to think about a project’s CLI and implementing one using the Invoke Python package.


This is a companion discussion topic for the original entry at https://interrupt.memfault.com/blog/building-a-cli-for-firmware-projects

@tyler Great post, as I had built something similar at a previous company and was looking for a replacement.

Do you know how any good open source projects using Invoke? I’d like to see how people use some of it’s more powerful features.

Cheers,
Darren

My new favorite tool that was posted on HackerNews last week was grep.app. It allows one to search Github quickly and optionally with regex. I quickly ran a search for from invoke import and found a few larger repositories using Invoke.

The projects I’ve found are:

Adding to Tyler’s response: we use invoke in our own projects. Check out invoke tasks in our SDK: https://github.com/memfault/memfault-firmware-sdk/tree/master/tasks

@tyler, @francois,

Thank you for reachout with the examples I will be sure to take a look!

BTW, I’m really enjoying the blog.

Thanks for doing these blog posts, it’s a really great source for learning new things.

Currently, when I need to debug the target, my IDE starts the GDB server and connects to it automatically. I am curious what your workflow is when using invoke. Am I correct to assume you run invoke gdbserver in a shell and leave that running, in another shell then run invoke debug?

Yes, that is generally what I do when using invoke. I’ve had mixed luck when having an IDE launch the gdbserver for me, as sometimes it hangs, or becomes a zombie process and I’m forced to kill the process manually. I find I’m generally happier starting the gdbserver separately, and then just attaching with the IDE.

Everyone does something differently!

1 Like

This is a great read, thanks! I don’t have a whole lot of experience with this, and have only previously used argparse for a CLI in Python. I’ve noticed you mention Click a couple of times - once in this article saying you like to use a combination of Invoke and Click, and also in your article on tracking code size (Tracking Firmware Code Size | Interrupt).

@tyler , do you have any other tips on using Invoke vs Click - when would you choose one over the other? Would you expect it to be more complex to achieve what you’ve described in this article but using Click?

If I was starting from scratch today, I would use Click and just create some convenience wrappers around subprocess. Click offers more advanced documentation features, argument and option parsing, and nice formatting options. The draw of Invoke is that it has a very easy interface for running shell commands, but it’s not necessarily more difficult than subprocess.

1 Like