|
| 1 | +# The three pillars of the Arduino CLI |
| 2 | + |
| 3 | +The Arduino CLI is an open source Command Line Application written in [Golang] |
| 4 | +that can be used from a terminal to compile, verify and upload sketches to |
| 5 | +Arduino boards and that’s capable of managing all the software and tools needed |
| 6 | +in the process. But don’t get fooled by its name: Arduino CLI can do much more |
| 7 | +than the average console application, as shown by the [Arduino Pro IDE] and |
| 8 | +[Arduino Create], which rely on it for similar purposes but each one in a |
| 9 | +completely different way from the other. In this article we introduce the three |
| 10 | +pillars of the Arduino CLI, explaining how we designed the software so that it |
| 11 | +can be effectively leveraged under different scenarios. |
| 12 | + |
| 13 | +## The first pillar: command line interface |
| 14 | + |
| 15 | +### Console applications for humans |
| 16 | + |
| 17 | +As you might expect, the first way to use the Arduino CLI is from a terminal and |
| 18 | +by a human, and user experience plays a key role here. The UX is under a |
| 19 | +continuous improvement process as we want the tool to be powerful without being |
| 20 | +too complicated. We heavily rely on sub-commands to provide a rich set of |
| 21 | +different operations logically grouped together, so that users can easily |
| 22 | +explore the interface while getting very specific contextual help. |
| 23 | + |
| 24 | +![contextual help screenshot][] |
| 25 | + |
| 26 | +### Console applications for robots |
| 27 | + |
| 28 | +Humans are not the only type of customers we want to support and the Arduino CLI |
| 29 | +was also designed to be used programmatically - think about automation pipelines |
| 30 | +or a [CI][continuous integration]/[CD][continuous deployment] system. |
| 31 | +There are some niceties to observe when you write software that’s supposed to be |
| 32 | +easy to run when unattended and one in particular is the ability to run without |
| 33 | +a configuration file. This is possible because every configuration option you |
| 34 | +find in the arduino-cli.yaml configuration file can be provided either through a |
| 35 | +command line flag or by setting an environment variable. To give an example, the |
| 36 | +following commands are all equivalent and will proceed fetching the unstable |
| 37 | +package index that can be used to work with experimental versions of cores: |
| 38 | + |
| 39 | +![configuration methods screenshot][] |
| 40 | + |
| 41 | +One note about the example above: passing a value through a command line flag |
| 42 | +always takes precedence over reading an environment variable, which in turn |
| 43 | +always takes precedence over reading the same value from the configuration file |
| 44 | +(if you have one). |
| 45 | +Consistent with the previous paragraph, when it comes to providing output the |
| 46 | +Arduino CLI aims to be user friendly but also slightly verbose, something that |
| 47 | +doesn’t play well with robots. This is why we added an option to provide output |
| 48 | +that’s easy to parse, for example the following figure shows what getting the |
| 49 | +software version in [JSON] format looks like. |
| 50 | + |
| 51 | +![JSON output screenshot][] |
| 52 | + |
| 53 | +Even if not related to software design, one last feature that’s worth mentioning |
| 54 | +is the availability of a one-line [installation script] that can be used to make |
| 55 | +the latest version of the Arduino CLI available on most systems with an HTTP |
| 56 | +client like curl or wget and a shell like bash. |
| 57 | + |
| 58 | +For more information on Arduino CLI's command line interface, see the |
| 59 | +[command reference]. |
| 60 | + |
| 61 | +## The second pillar: gRPC interface |
| 62 | + |
| 63 | +[gRPC] is a high performance [RPC] framework that can efficiently connect client |
| 64 | +and server applications. The Arduino CLI can act as a gRPC server (we call it |
| 65 | +[daemon mode]), exposing a set of procedures that implement the very same set of |
| 66 | +features of the command line interface and waiting for clients to connect and |
| 67 | +use them. To give an idea, the following is some [Golang] code capable of |
| 68 | +retrieving the version number of a remote running Arduino CLI server instance: |
| 69 | + |
| 70 | +![gRPC interface screenshot][] |
| 71 | + |
| 72 | +gRPC is language agnostic: even if the example is written in Golang, the |
| 73 | +programming language used for the client can be Python, JavaScript or any of the |
| 74 | +many [supported ones][gRPC supported languages], leading to a variety of |
| 75 | +possible scenarios. The new [Arduino Pro IDE] is a good example of how to |
| 76 | +leverage the daemon mode of the Arduino CLI with a clean separation of concerns: |
| 77 | +the Pro IDE knows nothing about how to download a core, compile a sketch or talk |
| 78 | +to an Arduino board and it demands all these features of an Arduino CLI instance. |
| 79 | +Conversely, the Arduino CLI doesn’t even know that the client that’s connected |
| 80 | +is the Pro IDE, and neither does it care. |
| 81 | + |
| 82 | +For more information on Arduino CLI's gRPC interface, see the |
| 83 | +[gRPC interface reference]. |
| 84 | + |
| 85 | +## The third pillar: embedding |
| 86 | + |
| 87 | +Arduino CLI is written in [Golang] and the code is organized in a way that makes |
| 88 | +it easy to use it as a library by including the modules you need in another |
| 89 | +Golang application at compile time. Both the first and second pillars rely on a |
| 90 | +common Golang API, a set of functions that abstract all the functionalities |
| 91 | +offered by the Arduino CLI, so that when we provide a fix or a new feature, they |
| 92 | +are automatically available to both the command line and gRPC interfaces. |
| 93 | +The source modules implementing this API can be imported in other Golang |
| 94 | +programs to embed a full fledged Arduino CLI. For example, this is how some |
| 95 | +backend services powering [Arduino Create] can compile sketches and manage |
| 96 | +libraries. Just to give you a taste of what it means to embed the Arduino CLI, |
| 97 | +here is how to search for a core using the API: |
| 98 | + |
| 99 | +![Go library interface screenshot][] |
| 100 | + |
| 101 | +Embedding the Arduino CLI is limited to Golang applications and requires a deep |
| 102 | +knowledge of its internals; for the average use case the gRPC interface might be |
| 103 | +a better alternative, nevertheless this remains a valid option that we use and |
| 104 | +provide support for. |
| 105 | + |
| 106 | +## Conclusions |
| 107 | + |
| 108 | +You can start playing with the Arduino CLI right away. The code is open source |
| 109 | +and [the repo][Arduino CLI repository] contains |
| 110 | +[example code showing how to implement a gRPC client][gRPC client example]. If |
| 111 | +you’re curious about how we designed the low level API, have a look at the |
| 112 | +[commands package] and don’t hesitate to leave feedback on the [issue tracker] |
| 113 | +if you’ve got a use case that doesn’t fit one of the three pillars. |
| 114 | + |
| 115 | + |
| 116 | +[Golang]: https://golang.org/ |
| 117 | +[Arduino Pro IDE]: https://www.arduino.cc/pro/arduino-pro-ide |
| 118 | +[Arduino Create]: https://create.arduino.cc |
| 119 | +[continuous integration]: https://en.wikipedia.org/wiki/Continuous_integration |
| 120 | +[continuous deployment]: https://en.wikipedia.org/wiki/Continuous_deployment |
| 121 | +[JSON]: https://www.json.org |
| 122 | +[installation script]: installation.md#use-the-install-script |
| 123 | +[command reference]: ../commands/arduino-cli |
| 124 | +[gRPC]: https://grpc.io/ |
| 125 | +[RPC]: https://en.wikipedia.org/wiki/Remote_procedure_call |
| 126 | +[daemon mode]: ../commands/arduino-cli_daemon |
| 127 | +[gRPC interface reference]: ../rpc/commands |
| 128 | +[gRPC supported languages]: https://grpc.io/docs/languages/ |
| 129 | +[Arduino CLI repository]: https://github.com/arduino/arduino-cli |
| 130 | +[gRPC client example]: https://github.com/arduino/arduino-cli/blob/master/client_example |
| 131 | +[commands package]: https://github.com/arduino/arduino-cli/tree/master/commands |
| 132 | +[issue tracker]: https://github.com/arduino/arduino-cli/issues |
| 133 | + |
| 134 | +[contextual help screenshot]: img/CLI_contextual_help_screenshot.png |
| 135 | +[configuration methods screenshot]: img/CLI_configuration_methods_screenshot.png |
| 136 | +[JSON output screenshot]: img/CLI_JSON_output_screenshot.png |
| 137 | +[gRPC interface screenshot]: img/CLI_gRPC_interface_screenshot.png |
| 138 | +[Go library interface screenshot]: img/CLI_Go_library_interface_screenshot.png |
0 commit comments