Skip to content

Commit 6a668fc

Browse files
mdegat01CopilotagnersCopilot
authored
Add --feature-flag option to supervisor options command (#649)
* Add --feature-flag option to supervisor options command Allows users to enable/disable development feature flags via: ha supervisor options --feature-flag supervisor_v2_api=true ha supervisor options --feature-flag supervisor_v2_api (defaults to true) ha supervisor options --feature-flag supervisor_v2_api=false Multiple flags can be set by repeating the argument. Tab completion calls /supervisor/info and suggests each flag with its opposite value (e.g. supervisor_v2_api=true when currently false). Related: home-assistant/supervisor#6719 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Format file * Update cmd/supervisor_options.go Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: Stefan Agner <stefan@agner.ch> Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
1 parent 3e9f19c commit 6a668fc

1 file changed

Lines changed: 58 additions & 1 deletion

File tree

cmd/supervisor_options.go

Lines changed: 58 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
package cmd
22

33
import (
4+
"fmt"
45
"log/slog"
6+
"strconv"
57
"strings"
68

79
helper "github.com/home-assistant/cli/client"
@@ -16,7 +18,8 @@ var supervisorOptionsCmd = &cobra.Command{
1618
This command allows you to set configuration options for on the Home Assistant
1719
Supervisor running on your Home Assistant system.`,
1820
Example: `
19-
ha supervisor options --channel beta`,
21+
ha supervisor options --channel beta
22+
ha supervisor options --feature-flag supervisor_v2_api=true`,
2023
ValidArgsFunction: cobra.NoFileCompletions,
2124
Args: cobra.NoArgs,
2225
Run: func(cmd *cobra.Command, args []string) {
@@ -52,6 +55,34 @@ Supervisor running on your Home Assistant system.`,
5255
}
5356
}
5457

58+
featureFlags, err := cmd.Flags().GetStringArray("feature-flag")
59+
if err == nil && len(featureFlags) > 0 {
60+
flagMap := make(map[string]bool)
61+
for _, entry := range featureFlags {
62+
parts := strings.SplitN(entry, "=", 2)
63+
name := strings.TrimSpace(parts[0])
64+
if name == "" {
65+
helper.PrintError(fmt.Errorf("invalid feature flag %q: name must not be empty", entry))
66+
ExitWithError = true
67+
return
68+
}
69+
70+
var val bool
71+
if len(parts) == 1 {
72+
val = true
73+
} else {
74+
val, err = strconv.ParseBool(parts[1])
75+
if err != nil {
76+
helper.PrintError(fmt.Errorf("invalid value for feature flag %q: %q, expected true or false", name, parts[1]))
77+
ExitWithError = true
78+
return
79+
}
80+
}
81+
flagMap[name] = val
82+
}
83+
options["feature_flags"] = flagMap
84+
}
85+
5586
resp, err := helper.GenericJSONPost(section, command, options)
5687
if err != nil {
5788
helper.PrintError(err)
@@ -72,6 +103,7 @@ func init() {
72103
supervisorOptionsCmd.Flags().BoolP("debug-block", "", false, "Enable debug mode with blocking startup")
73104
supervisorOptionsCmd.Flags().BoolP("diagnostics", "", false, "Enable diagnostics mode")
74105
supervisorOptionsCmd.Flags().BoolP("auto-update", "", true, "Enable/disable supervisor auto update")
106+
supervisorOptionsCmd.Flags().StringArrayP("feature-flag", "", []string{}, "Set a development feature flag (name=true|false). Use multiple times for multiple flags.")
75107

76108
supervisorOptionsCmd.Flags().Lookup("debug").NoOptDefVal = "false"
77109
supervisorOptionsCmd.Flags().Lookup("debug-block").NoOptDefVal = "false"
@@ -92,6 +124,31 @@ func init() {
92124
supervisorOptionsCmd.RegisterFlagCompletionFunc("debug", boolCompletions)
93125
supervisorOptionsCmd.RegisterFlagCompletionFunc("debug-block", boolCompletions)
94126
supervisorOptionsCmd.RegisterFlagCompletionFunc("diagnostics", boolCompletions)
127+
supervisorOptionsCmd.RegisterFlagCompletionFunc("feature-flag", featureFlagCompletions)
95128

96129
supervisorCmd.AddCommand(supervisorOptionsCmd)
97130
}
131+
132+
func featureFlagCompletions(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
133+
resp, err := helper.GenericJSONGet("supervisor", "info")
134+
if err != nil || !resp.IsSuccess() {
135+
return nil, cobra.ShellCompDirectiveNoFileComp
136+
}
137+
data := resp.Result().(*helper.Response)
138+
if data.Result != "ok" || data.Data["feature_flags"] == nil {
139+
return nil, cobra.ShellCompDirectiveNoFileComp
140+
}
141+
flags, ok := data.Data["feature_flags"].(map[string]any)
142+
if !ok {
143+
return nil, cobra.ShellCompDirectiveNoFileComp
144+
}
145+
var ret []string
146+
for name, val := range flags {
147+
current, ok := val.(bool)
148+
if !ok {
149+
continue
150+
}
151+
ret = append(ret, fmt.Sprintf("%s=%v\tcurrently %v", name, !current, current))
152+
}
153+
return ret, cobra.ShellCompDirectiveNoFileComp
154+
}

0 commit comments

Comments
 (0)