diff --git a/internal/cli/arguments/profiles.go b/internal/cli/arguments/profiles.go index 67253332582..6516cbdec08 100644 --- a/internal/cli/arguments/profiles.go +++ b/internal/cli/arguments/profiles.go @@ -27,7 +27,13 @@ type Profile struct { // AddToCommand adds the flags used to set fqbn to the specified Command func (f *Profile) AddToCommand(cmd *cobra.Command) { cmd.Flags().StringVarP(&f.profile, "profile", "m", "", tr("Sketch profile to use")) - // TODO: register autocompletion + cmd.RegisterFlagCompletionFunc("profile", func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + var sketchProfile string + if len(args) > 0 { + sketchProfile = args[0] + } + return GetSketchProfiles(sketchProfile), cobra.ShellCompDirectiveDefault + }) } // Get returns the profile name diff --git a/internal/cli/arguments/sketch.go b/internal/cli/arguments/sketch.go index 58df45e3367..9b43173e7db 100644 --- a/internal/cli/arguments/sketch.go +++ b/internal/cli/arguments/sketch.go @@ -16,8 +16,12 @@ package arguments import ( + "context" + + "github.com/arduino/arduino-cli/commands/sketch" sk "github.com/arduino/arduino-cli/commands/sketch" "github.com/arduino/arduino-cli/internal/cli/feedback" + rpc "github.com/arduino/arduino-cli/rpc/cc/arduino/cli/commands/v1" "github.com/arduino/go-paths-helper" "github.com/sirupsen/logrus" ) @@ -43,3 +47,24 @@ func InitSketchPath(path string, printWarnings bool) (sketchPath *paths.Path) { } return sketchPath } + +// GetSketchProfiles is an helper function useful to autocomplete. +// It returns the profile names set in the sketch.yaml +func GetSketchProfiles(sketchPath string) []string { + if sketchPath == "" { + if wd, _ := paths.Getwd(); wd != nil && wd.String() != "" { + sketchPath = wd.String() + } else { + return nil + } + } + list, _ := sketch.LoadSketch(context.Background(), &rpc.LoadSketchRequest{ + SketchPath: sketchPath, + }) + profiles := list.GetProfiles() + res := make([]string, len(profiles)) + for i, p := range list.GetProfiles() { + res[i] = p.GetName() + } + return res +} diff --git a/internal/integrationtest/completion/completion_test.go b/internal/integrationtest/completion/completion_test.go index 75da997a357..a216eb0f6ff 100644 --- a/internal/integrationtest/completion/completion_test.go +++ b/internal/integrationtest/completion/completion_test.go @@ -19,6 +19,7 @@ import ( "testing" "github.com/arduino/arduino-cli/internal/integrationtest" + "github.com/arduino/go-paths-helper" "github.com/stretchr/testify/require" ) @@ -229,3 +230,30 @@ func TestCoreCompletion(t *testing.T) { stdout, _, _ = cli.Run("__complete", "upload", "-P", "") require.Contains(t, string(stdout), "atmel_ice") } + +func TestProfileCompletion(t *testing.T) { + env, cli := integrationtest.CreateArduinoCLIWithEnvironment(t) + defer env.CleanUp() + + // Create test sketches + sketchWithProfilesPath, err := paths.New("testdata", "SketchWithProfiles").Abs() + require.NoError(t, err) + require.True(t, sketchWithProfilesPath.IsDir()) + + stdout, _, _ := cli.Run("__complete", "compile", sketchWithProfilesPath.String(), "--profile", "") + require.Contains(t, string(stdout), "profile1") + stdout, _, _ = cli.Run("__complete", "monitor", sketchWithProfilesPath.String(), "--profile", "") + require.Contains(t, string(stdout), "profile1") + stdout, _, _ = cli.Run("__complete", "upload", sketchWithProfilesPath.String(), "--profile", "") + require.Contains(t, string(stdout), "profile1") + + // The cli is running in the sketch folder, so need the explictly specify the path in the cli + cli.SetWorkingDir(sketchWithProfilesPath) + stdout, _, _ = cli.Run("__complete", "compile", "--profile", "") + require.Contains(t, string(stdout), "profile1") + stdout, _, _ = cli.Run("__complete", "monitor", "--profile", "") + require.Contains(t, string(stdout), "profile1") + stdout, _, _ = cli.Run("__complete", "upload", "--profile", "") + require.Contains(t, string(stdout), "profile1") + +} diff --git a/internal/integrationtest/completion/testdata/SketchWithProfiles/SketchWithProfiles.ino b/internal/integrationtest/completion/testdata/SketchWithProfiles/SketchWithProfiles.ino new file mode 100644 index 00000000000..5054c040393 --- /dev/null +++ b/internal/integrationtest/completion/testdata/SketchWithProfiles/SketchWithProfiles.ino @@ -0,0 +1,3 @@ + +void setup() {} +void loop() {} diff --git a/internal/integrationtest/completion/testdata/SketchWithProfiles/sketch.yaml b/internal/integrationtest/completion/testdata/SketchWithProfiles/sketch.yaml new file mode 100644 index 00000000000..7143ea94b9a --- /dev/null +++ b/internal/integrationtest/completion/testdata/SketchWithProfiles/sketch.yaml @@ -0,0 +1,5 @@ +default_port: /dev/ttyDEF +default_fqbn: arduino:avr:yun +profiles: + profile1: + fqbn: "arduino:avr:uno"