Skip to content

Commit f98bf7d

Browse files
Add profile lib remove command
It removes a library from the specified profile.
1 parent d3d7a59 commit f98bf7d

File tree

7 files changed

+953
-597
lines changed

7 files changed

+953
-597
lines changed

commands/service_profile_lib_add.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ func (s *arduinoCoreServerImpl) ProfileLibAdd(ctx context.Context, req *rpc.Prof
6262
}
6363

6464
// If the library has been already added to the profile, just update the version
65-
if lib, _ := profile.GetLibrary(req.LibName); lib != nil {
65+
if lib, _ := profile.GetLibrary(req.LibName, false); lib != nil {
6666
lib.Version = libRelease.GetVersion()
6767
} else {
6868
profile.Libraries = append(profile.Libraries, &sketch.ProfileLibraryReference{
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
// This file is part of arduino-cli.
2+
//
3+
// Copyright 2025 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 commands
17+
18+
import (
19+
"context"
20+
21+
"github.com/arduino/arduino-cli/commands/cmderrors"
22+
"github.com/arduino/arduino-cli/internal/arduino/sketch"
23+
rpc "github.com/arduino/arduino-cli/rpc/cc/arduino/cli/commands/v1"
24+
paths "github.com/arduino/go-paths-helper"
25+
)
26+
27+
func (s *arduinoCoreServerImpl) ProfileLibRemove(ctx context.Context, req *rpc.ProfileLibRemoveRequest) (*rpc.ProfileLibRemoveResponse, error) {
28+
sketchPath := paths.New(req.GetSketchPath())
29+
projectFilePath, err := sketchPath.Join("sketch.yaml").Abs()
30+
if err != nil {
31+
return nil, err
32+
}
33+
34+
if req.GetProfileName() == "" {
35+
return nil, &cmderrors.MissingProfileError{}
36+
}
37+
38+
// Returns an error if the main file is missing from the sketch so there is no need to check if the path exists
39+
sk, err := sketch.New(sketchPath)
40+
if err != nil {
41+
return nil, err
42+
}
43+
44+
profile, err := sk.GetProfile(req.ProfileName)
45+
if err != nil {
46+
return nil, err
47+
}
48+
49+
lib, err := profile.GetLibrary(req.LibName, true)
50+
if err != nil {
51+
return nil, err
52+
}
53+
54+
err = projectFilePath.WriteFile([]byte(sk.Project.AsYaml()))
55+
if err != nil {
56+
return nil, err
57+
}
58+
59+
return &rpc.ProfileLibRemoveResponse{LibName: lib.Library, LibVersion: lib.Version.String()}, nil
60+
}

internal/arduino/sketch/profiles.go

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import (
2222
"fmt"
2323
"net/url"
2424
"regexp"
25+
"slices"
2526
"strings"
2627

2728
"github.com/arduino/arduino-cli/commands/cmderrors"
@@ -121,9 +122,12 @@ type Profile struct {
121122
}
122123

123124
// GetLibrary returns the requested library or an error if not found
124-
func (p *Profile) GetLibrary(libraryName string) (*ProfileLibraryReference, error) {
125-
for _, l := range p.Libraries {
125+
func (p *Profile) GetLibrary(libraryName string, toDelete bool) (*ProfileLibraryReference, error) {
126+
for i, l := range p.Libraries {
126127
if l.Library == libraryName {
128+
if toDelete {
129+
p.Libraries = slices.Delete(p.Libraries, i, i+1)
130+
}
127131
return l, nil
128132
}
129133
}

internal/cli/profile/lib.go

Lines changed: 66 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ func initLibCommand(srv rpc.ArduinoCoreServiceServer) *cobra.Command {
4040
}
4141

4242
libCommand.AddCommand(initLibAddCommand(srv))
43+
libCommand.AddCommand(initLibRemoveCommand(srv))
4344

4445
return libCommand
4546
}
@@ -88,20 +89,80 @@ func runLibAddCommand(ctx context.Context, args []string, srv rpc.ArduinoCoreSer
8889
if err != nil {
8990
feedback.Fatal(i18n.Tr("Error adding %s to the profile %s: %v", lib.Name, profileArg.Get(), err), feedback.ErrGeneric)
9091
}
91-
feedback.PrintResult(libResult{LibName: resp.GetLibName(), LibVersion: resp.GetLibVersion(), ProfileName: profileArg.Get()})
92+
feedback.PrintResult(libAddResult{LibName: resp.GetLibName(), LibVersion: resp.GetLibVersion(), ProfileName: profileArg.Get()})
9293
}
9394
}
9495

95-
type libResult struct {
96+
func initLibRemoveCommand(srv rpc.ArduinoCoreServiceServer) *cobra.Command {
97+
var destDir string
98+
99+
removeCommand := &cobra.Command{
100+
Use: fmt.Sprintf("remove %s[@%s]...", i18n.Tr("LIBRARY"), i18n.Tr("VERSION_NUMBER")),
101+
Short: i18n.Tr("Removes a library from the profile."),
102+
Long: i18n.Tr("Removes a library from the profile."),
103+
Example: "" +
104+
" " + os.Args[0] + " profile lib remove AudioZero -m my_profile\n" +
105+
" " + os.Args[0] + " profile lib remove [email protected] --profile my_profile\n",
106+
Args: cobra.MinimumNArgs(1),
107+
Run: func(cmd *cobra.Command, args []string) {
108+
runLibRemoveCommand(cmd.Context(), args, srv, destDir)
109+
},
110+
ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
111+
return arguments.GetInstallableLibs(cmd.Context(), srv), cobra.ShellCompDirectiveDefault
112+
},
113+
}
114+
115+
removeCommand.Flags().StringVar(&destDir, "dest-dir", "", i18n.Tr("Location of the project file."))
116+
profileArg.AddToCommand(removeCommand, srv)
117+
118+
return removeCommand
119+
}
120+
121+
func runLibRemoveCommand(ctx context.Context, args []string, srv rpc.ArduinoCoreServiceServer, destDir string) {
122+
sketchPath := arguments.InitSketchPath(destDir)
123+
124+
instance := instance.CreateAndInit(ctx, srv)
125+
libRefs, err := lib.ParseLibraryReferenceArgsAndAdjustCase(ctx, srv, instance, args)
126+
if err != nil {
127+
feedback.Fatal(i18n.Tr("Arguments error: %v", err), feedback.ErrBadArgument)
128+
}
129+
for _, lib := range libRefs {
130+
resp, err := srv.ProfileLibRemove(ctx, &rpc.ProfileLibRemoveRequest{
131+
SketchPath: sketchPath.String(),
132+
ProfileName: profileArg.Get(),
133+
LibName: lib.Name,
134+
})
135+
if err != nil {
136+
feedback.Fatal(i18n.Tr("Error removing %s from the profile %s: %v", lib.Name, profileArg.Get(), err), feedback.ErrGeneric)
137+
}
138+
feedback.PrintResult(libRemoveResult{LibName: resp.GetLibName(), LibVersion: resp.GetLibVersion(), ProfileName: profileArg.Get()})
139+
}
140+
}
141+
142+
type libAddResult struct {
143+
LibName string `json:"library_name"`
144+
LibVersion string `json:"library_version"`
145+
ProfileName string `json:"profile_name"`
146+
}
147+
148+
func (lr libAddResult) Data() interface{} {
149+
return lr
150+
}
151+
152+
func (lr libAddResult) String() string {
153+
return i18n.Tr("Profile %s: %s@%s added successfully", lr.ProfileName, lr.LibName, lr.LibVersion)
154+
}
155+
156+
type libRemoveResult struct {
96157
LibName string `json:"library_name"`
97158
LibVersion string `json:"library_version"`
98159
ProfileName string `json:"profile_name"`
99160
}
100161

101-
func (lr libResult) Data() interface{} {
162+
func (lr libRemoveResult) Data() interface{} {
102163
return lr
103164
}
104165

105-
func (lr libResult) String() string {
106-
return i18n.Tr("Profile %s: %s@%s added succesfully", lr.ProfileName, lr.LibName, lr.LibVersion)
166+
func (lr libRemoveResult) String() string {
167+
return i18n.Tr("Profile %s: %s@%s removed successfully", lr.ProfileName, lr.LibName, lr.LibVersion)
107168
}

0 commit comments

Comments
 (0)