@@ -17,8 +17,11 @@ package commands
1717
1818import (
1919 "context"
20+ "slices"
2021
2122 "github.com/arduino/arduino-cli/commands/cmderrors"
23+ "github.com/arduino/arduino-cli/commands/internal/instances"
24+ "github.com/arduino/arduino-cli/internal/arduino/libraries/librariesindex"
2225 "github.com/arduino/arduino-cli/internal/arduino/sketch"
2326 rpc "github.com/arduino/arduino-cli/rpc/cc/arduino/cli/commands/v1"
2427 paths "github.com/arduino/go-paths-helper"
@@ -47,19 +50,79 @@ func (s *arduinoCoreServerImpl) ProfileLibRemove(ctx context.Context, req *rpc.P
4750 return nil , err
4851 }
4952
53+ var removedLibraries []* rpc.ProfileLibraryReference
54+ remove := func (libraryToRemove * sketch.ProfileLibraryReference ) error {
55+ removedLibrary , err := profile .RemoveLibrary (libraryToRemove )
56+ if err != nil {
57+ return & cmderrors.InvalidArgumentError {Cause : err }
58+ }
59+ removedLibraries = append (removedLibraries , removedLibrary .ToRpc ())
60+ return nil
61+ }
62+
5063 libToRemove , err := sketch .FromRpcProfileLibraryReference (req .GetLibrary ())
5164 if err != nil {
5265 return nil , & cmderrors.InvalidArgumentError {Message : "invalid library reference" , Cause : err }
5366 }
54- removedLib , err := profile .RemoveLibrary (libToRemove )
55- if err != nil {
56- return nil , & cmderrors.InvalidArgumentError {Cause : err }
67+ if err := remove (libToRemove ); err != nil {
68+ return nil , err
69+ }
70+
71+ // Get the dependencies of the libraries to see if any of them could be removed as well
72+ if req .GetRemoveDependencies () {
73+ if req .GetLibrary ().GetIndexLibrary () == nil {
74+ // No dependencies to remove
75+ return nil , & cmderrors.InvalidArgumentError {Message : "automatic dependency removal is supported only for IndexLibraries" }
76+ }
77+ // Obtain the library index from the manager
78+ li , err := instances .GetLibrariesIndex (req .GetInstance ())
79+ if err != nil {
80+ return nil , err
81+ }
82+
83+ // Get all the dependencies required by the profile excluding the removed library
84+ requiredDeps := map [string ]bool {}
85+ requiredDeps [libToRemove .String ()] = true
86+ for _ , profLib := range profile .Libraries {
87+ if profLib .IsDependency {
88+ continue
89+ }
90+ if profLib .Library == "" {
91+ continue
92+ }
93+ deps , err := libraryResolveDependencies (li , profLib .Library , profLib .Version .String (), nil )
94+ if err != nil {
95+ return nil , & cmderrors.InvalidArgumentError {Cause : err , Message : "cannot resolve dependencies for installed libraries" }
96+ }
97+ for _ , dep := range deps {
98+ requiredDeps [dep .String ()] = true
99+ }
100+ }
101+
102+ depsOfLibToRemove , err := libraryResolveDependencies (li , libToRemove .Library , libToRemove .Version .String (), nil )
103+ if err != nil {
104+ return nil , err
105+ }
106+ // sort to make the output order deterministic
107+ slices .SortFunc (depsOfLibToRemove , librariesindex .ReleaseCompare )
108+ // deps contains the main library as well, so we skip it when removing dependencies
109+ for _ , depToRemove := range depsOfLibToRemove {
110+ if requiredDeps [depToRemove .String ()] {
111+ continue
112+ }
113+ if err := remove (& sketch.ProfileLibraryReference {Library : depToRemove .Library .Name , Version : depToRemove .Version }); err != nil {
114+ return nil , err
115+ }
116+ }
57117 }
58118
59119 err = projectFilePath .WriteFile ([]byte (sk .Project .AsYaml ()))
60120 if err != nil {
61121 return nil , err
62122 }
63123
64- return & rpc.ProfileLibRemoveResponse {Library : removedLib .ToRpc (), ProfileName : profileName }, nil
124+ return & rpc.ProfileLibRemoveResponse {
125+ RemovedLibraries : removedLibraries ,
126+ ProfileName : profileName ,
127+ }, nil
65128}
0 commit comments