Skip to content

Commit ce95ac5

Browse files
committed
Added example of integration by embedding golang
1 parent ec656cd commit ce95ac5

File tree

3 files changed

+150
-8
lines changed

3 files changed

+150
-8
lines changed

Diff for: docs/img/CLI_Go_library_interface_screenshot.png

-88.4 KB
Binary file not shown.

Diff for: docs/integration-options.md

+79-8
Original file line numberDiff line numberDiff line change
@@ -211,14 +211,86 @@ For more information on Arduino CLI's gRPC interface, see the [gRPC interface re
211211

212212
Arduino CLI is written in [Golang] and the code is organized in a way that makes it easy to use it as a library by
213213
including the modules you need in another Golang application at compile time. Both the first and second pillars rely on
214-
a common Golang API, a set of functions that abstract all the functionalities offered by the Arduino CLI, so that when
215-
we provide a fix or a new feature, they are automatically available to both the command line and gRPC interfaces. The
216-
source modules implementing this API are implemented through the `commands` package, and it can be imported in other
217-
Golang programs to embed a full-fledged Arduino CLI. For example, this is how some backend services powering [Arduino
218-
Cloud] can compile sketches and manage libraries. Just to give you a taste of what it means to embed the Arduino CLI,
219-
here is how to search for a core using the API:
214+
a common Golang API, based on the gRPC protobuf definitions: a set of functions that abstract all the functionalities
215+
offered by the Arduino CLI, so that when we provide a fix or a new feature, they are automatically available to both the
216+
command line and gRPC interfaces. The source modules implementing this API are implemented through the `commands`
217+
package, and it can be imported in other Golang programs to embed a full-fledged Arduino CLI. For example, this is how
218+
some backend services powering [Arduino Cloud] can compile sketches and manage libraries. Just to give you a taste of
219+
what it means to embed the Arduino CLI, here is how to search for a core using the API:
220220

221-
![Go library interface screenshot][]
221+
```go
222+
// This file is part of arduino-cli.
223+
//
224+
// Copyright 2024 ARDUINO SA (http://www.arduino.cc/)
225+
//
226+
// This software is released under the GNU General Public License version 3,
227+
// which covers the main part of arduino-cli.
228+
// The terms of this license can be found at:
229+
// https://www.gnu.org/licenses/gpl-3.0.en.html
230+
//
231+
// You can be released from the requirements of the above licenses by purchasing
232+
// a commercial license. Buying such a license is mandatory if you want to
233+
// modify or otherwise use the software for commercial activities involving the
234+
// Arduino software without disclosing the source code of your own applications.
235+
// To purchase a commercial license, send an email to [email protected].
236+
237+
package main
238+
239+
import (
240+
"context"
241+
"fmt"
242+
"io"
243+
"log"
244+
245+
"github.com/arduino/arduino-cli/commands"
246+
rpc "github.com/arduino/arduino-cli/rpc/cc/arduino/cli/commands/v1"
247+
"github.com/sirupsen/logrus"
248+
)
249+
250+
func main() {
251+
// Create a new ArduinoCoreServer
252+
srv := commands.NewArduinoCoreServer()
253+
254+
// Disable logging
255+
logrus.SetOutput(io.Discard)
256+
257+
// Create a new instance in the server
258+
ctx := context.Background()
259+
resp, err := srv.Create(ctx, &rpc.CreateRequest{})
260+
if err != nil {
261+
log.Fatal("Error creating instance:", err)
262+
}
263+
instance := resp.GetInstance()
264+
265+
// Defer the destruction of the instance
266+
defer func() {
267+
if _, err := srv.Destroy(ctx, &rpc.DestroyRequest{Instance: instance}); err != nil {
268+
log.Fatal("Error destroying instance:", err)
269+
}
270+
fmt.Println("Instance successfully destroyed")
271+
}()
272+
273+
// Initialize the instance
274+
initStream := commands.InitStreamResponseToCallbackFunction(ctx, func(r *rpc.InitResponse) error {
275+
fmt.Println("INIT> ", r)
276+
return nil
277+
})
278+
if err := srv.Init(&rpc.InitRequest{Instance: instance}, initStream); err != nil {
279+
log.Fatal("Error during initialization:", err)
280+
}
281+
282+
// Search for platforms and output the result
283+
searchResp, err := srv.PlatformSearch(ctx, &rpc.PlatformSearchRequest{Instance: instance})
284+
if err != nil {
285+
log.Fatal("Error searching for platforms:", err)
286+
}
287+
for _, platformSummary := range searchResp.GetSearchOutput() {
288+
installed := platformSummary.GetInstalledRelease()
289+
meta := platformSummary.GetMetadata()
290+
fmt.Printf("%30s %8s %s\n", meta.GetId(), installed.GetVersion(), installed.GetName())
291+
}
292+
}
293+
```
222294

223295
Embedding the Arduino CLI is limited to Golang applications and requires a deep knowledge of its internals. For the
224296
average use case, the gRPC interface might be a better alternative. Nevertheless, this remains a valid option that we
@@ -250,4 +322,3 @@ tracker] if you’ve got a use case that doesn’t fit one of the three pillars.
250322
[commands package]: https://github.com/arduino/arduino-cli/tree/master/commands
251323
[issue tracker]: https://github.com/arduino/arduino-cli/issues
252324
[contextual help screenshot]: img/CLI_contextual_help_screenshot.png
253-
[go library interface screenshot]: img/CLI_Go_library_interface_screenshot.png

Diff for: rpc/internal/list_cores_example/main.go

+71
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
// This file is part of arduino-cli.
2+
//
3+
// Copyright 2024 ARDUINO SA (http://www.arduino.cc/)
4+
//
5+
// This software is released under the GNU General Public License version 3,
6+
// which covers the main part of arduino-cli.
7+
// The terms of this license can be found at:
8+
// https://www.gnu.org/licenses/gpl-3.0.en.html
9+
//
10+
// You can be released from the requirements of the above licenses by purchasing
11+
// a commercial license. Buying such a license is mandatory if you want to
12+
// modify or otherwise use the software for commercial activities involving the
13+
// Arduino software without disclosing the source code of your own applications.
14+
// To purchase a commercial license, send an email to [email protected].
15+
16+
package main
17+
18+
import (
19+
"context"
20+
"fmt"
21+
"io"
22+
"log"
23+
24+
"github.com/arduino/arduino-cli/commands"
25+
rpc "github.com/arduino/arduino-cli/rpc/cc/arduino/cli/commands/v1"
26+
"github.com/sirupsen/logrus"
27+
)
28+
29+
func main() {
30+
// Create a new ArduinoCoreServer
31+
srv := commands.NewArduinoCoreServer()
32+
33+
// Disable logging
34+
logrus.SetOutput(io.Discard)
35+
36+
// Create a new instance in the server
37+
ctx := context.Background()
38+
resp, err := srv.Create(ctx, &rpc.CreateRequest{})
39+
if err != nil {
40+
log.Fatal("Error creating instance:", err)
41+
}
42+
instance := resp.GetInstance()
43+
44+
// Defer the destruction of the instance
45+
defer func() {
46+
if _, err := srv.Destroy(ctx, &rpc.DestroyRequest{Instance: instance}); err != nil {
47+
log.Fatal("Error destroying instance:", err)
48+
}
49+
fmt.Println("Instance successfully destroyed")
50+
}()
51+
52+
// Initialize the instance
53+
initStream := commands.InitStreamResponseToCallbackFunction(ctx, func(r *rpc.InitResponse) error {
54+
fmt.Println("INIT> ", r)
55+
return nil
56+
})
57+
if err := srv.Init(&rpc.InitRequest{Instance: instance}, initStream); err != nil {
58+
log.Fatal("Error during initialization:", err)
59+
}
60+
61+
// Search for platforms and output the result
62+
searchResp, err := srv.PlatformSearch(ctx, &rpc.PlatformSearchRequest{Instance: instance})
63+
if err != nil {
64+
log.Fatal("Error searching for platforms:", err)
65+
}
66+
for _, platformSummary := range searchResp.GetSearchOutput() {
67+
installed := platformSummary.GetInstalledRelease()
68+
meta := platformSummary.GetMetadata()
69+
fmt.Printf("%30s %8s %s\n", meta.GetId(), installed.GetVersion(), installed.GetName())
70+
}
71+
}

0 commit comments

Comments
 (0)