Skip to content

Commit a2c86ef

Browse files
Add profile set-default command
Sets the default profile to the provided existing profile.
1 parent 4d167f3 commit a2c86ef

File tree

7 files changed

+946
-604
lines changed

7 files changed

+946
-604
lines changed
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
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 license@arduino.cc.
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) ProfileSetDefault(ctx context.Context, req *rpc.ProfileSetDefaultRequest) (*rpc.ProfileSetDefaultResponse, error) {
28+
if req.GetProfileName() == "" {
29+
return nil, &cmderrors.MissingProfileError{}
30+
}
31+
32+
sketchPath := paths.New(req.GetSketchPath())
33+
projectFilePath, err := sketchPath.Join("sketch.yaml").Abs()
34+
if err != nil {
35+
return nil, err
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+
if _, err := sk.GetProfile(req.GetProfileName()); err != nil {
45+
return nil, err
46+
}
47+
48+
sk.Project.DefaultProfile = req.GetProfileName()
49+
err = projectFilePath.WriteFile([]byte(sk.Project.AsYaml()))
50+
if err != nil {
51+
return nil, err
52+
}
53+
54+
return &rpc.ProfileSetDefaultResponse{}, nil
55+
}

internal/cli/profile/profile.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ func NewCommand(srv rpc.ArduinoCoreServiceServer) *cobra.Command {
3939

4040
profileCommand.AddCommand(initInitCommand(srv))
4141
profileCommand.AddCommand(initLibCommand(srv))
42+
profileCommand.AddCommand(initSetDefaultCommand(srv))
4243

4344
return profileCommand
4445
}

internal/cli/profile/set_default.go

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
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 license@arduino.cc.
15+
16+
package profile
17+
18+
import (
19+
"context"
20+
"os"
21+
22+
"github.com/arduino/arduino-cli/internal/cli/arguments"
23+
"github.com/arduino/arduino-cli/internal/cli/feedback"
24+
"github.com/arduino/arduino-cli/internal/i18n"
25+
rpc "github.com/arduino/arduino-cli/rpc/cc/arduino/cli/commands/v1"
26+
"github.com/spf13/cobra"
27+
)
28+
29+
func initSetDefaultCommand(srv rpc.ArduinoCoreServiceServer) *cobra.Command {
30+
var destDir string
31+
setDefaultCommand := &cobra.Command{
32+
Use: "set-default",
33+
Short: i18n.Tr("Sets the default profile."),
34+
Long: i18n.Tr("Sets the default profile."),
35+
Example: "" +
36+
" " + os.Args[0] + " profile set-default my_profile\n",
37+
Args: cobra.ExactArgs(1),
38+
Run: func(cmd *cobra.Command, args []string) {
39+
runSetDefaultCommand(cmd.Context(), args, srv, destDir)
40+
},
41+
}
42+
43+
setDefaultCommand.Flags().StringVar(&destDir, "dest-dir", "", i18n.Tr("Location of the project file."))
44+
45+
return setDefaultCommand
46+
}
47+
48+
func runSetDefaultCommand(ctx context.Context, args []string, srv rpc.ArduinoCoreServiceServer, destDir string) {
49+
profileName := args[0]
50+
sketchPath := arguments.InitSketchPath(destDir)
51+
52+
_, err := srv.ProfileSetDefault(ctx, &rpc.ProfileSetDefaultRequest{SketchPath: sketchPath.String(), ProfileName: profileName})
53+
if err != nil {
54+
feedback.Fatal(i18n.Tr("Cannot set %s as default profile: %v", profileName, err), feedback.ErrGeneric)
55+
}
56+
}

internal/integrationtest/profiles/profiles_test.go

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -365,3 +365,42 @@ func TestProfileLibSpecificProfile(t *testing.T) {
365365
require.NoError(t, err)
366366
require.NotContains(t, string(fileContent), "- Modulino (0.5.0)")
367367
}
368+
369+
func TestProfileSetDefault(t *testing.T) {
370+
env, cli := integrationtest.CreateArduinoCLIWithEnvironment(t)
371+
defer env.CleanUp()
372+
373+
// Init the environment explicitly
374+
_, _, err := cli.Run("core", "update-index")
375+
require.NoError(t, err)
376+
377+
_, _, err = cli.Run("sketch", "new", cli.SketchbookDir().Join("Simple").String())
378+
require.NoError(t, err)
379+
380+
_, _, err = cli.Run("core", "install", "arduino:avr")
381+
require.NoError(t, err)
382+
383+
_, _, err = cli.Run("profile", "init", cli.SketchbookDir().Join("Simple").String(), "-m", "Uno", "-b", "arduino:avr:uno")
384+
require.NoError(t, err)
385+
386+
// Add a second profile
387+
_, _, err = cli.Run("profile", "init", cli.SketchbookDir().Join("Simple").String(), "-m", "my_profile", "-b", "arduino:avr:uno")
388+
require.NoError(t, err)
389+
fileContent, err := cli.SketchbookDir().Join("Simple", "sketch.yaml").ReadFileAsLines()
390+
require.NoError(t, err)
391+
require.Contains(t, fileContent, "default_profile: Uno")
392+
require.NotContains(t, fileContent, "default_profile: my_profile")
393+
394+
// Change default profile
395+
_, _, err = cli.Run("profile", "set-default", "my_profile", "--dest-dir", cli.SketchbookDir().Join("Simple").String())
396+
require.NoError(t, err)
397+
fileContent, err = cli.SketchbookDir().Join("Simple", "sketch.yaml").ReadFileAsLines()
398+
require.NoError(t, err)
399+
require.NotContains(t, fileContent, "default_profile: Uno")
400+
require.Contains(t, fileContent, "default_profile: my_profile")
401+
402+
// Changing to an inexistent profile returns an error
403+
_, stderr, err := cli.Run("profile", "set-default", "inexistent_profile", "--dest-dir", cli.SketchbookDir().Join("Simple").String())
404+
require.Error(t, err)
405+
require.Equal(t, "Cannot set inexistent_profile as default profile: Profile 'inexistent_profile' not found\n", string(stderr))
406+
}

0 commit comments

Comments
 (0)