Skip to content

Commit 2309152

Browse files
committed
DRAFT 2
1 parent af4513f commit 2309152

File tree

19 files changed

+302
-201
lines changed

19 files changed

+302
-201
lines changed

Diff for: commands/service_platform_search_test.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ func TestPlatformSearch(t *testing.T) {
4141
conf, err := paths.TempDir().Join("test", "arduino-cli.yaml").ReadFile()
4242
require.NoError(t, err)
4343
_, err = srv.ConfigurationOpen(ctx, &rpc.ConfigurationOpenRequest{
44-
Format: "yaml",
44+
SettingsFormat: "yaml",
4545
EncodedSettings: string(conf),
4646
})
4747
require.NoError(t, err)
@@ -350,7 +350,7 @@ func TestPlatformSearchSorting(t *testing.T) {
350350
conf, err := paths.TempDir().Join("test", "arduino-cli.yaml").ReadFile()
351351
require.NoError(t, err)
352352
_, err = srv.ConfigurationOpen(ctx, &rpc.ConfigurationOpenRequest{
353-
Format: "yaml",
353+
SettingsFormat: "yaml",
354354
EncodedSettings: string(conf),
355355
})
356356
require.NoError(t, err)

Diff for: commands/service_settings.go

+39-14
Original file line numberDiff line numberDiff line change
@@ -95,16 +95,31 @@ func (s *arduinoCoreServerImpl) SettingsSetValue(ctx context.Context, req *rpc.S
9595
key := req.GetKey()
9696

9797
// Extract the value from the request
98-
jsonValue := []byte(req.GetValueJson())
99-
if len(jsonValue) == 0 {
98+
encodedValue := []byte(req.GetEncodedValue())
99+
if len(encodedValue) == 0 {
100100
// If the value is empty, unset the key
101101
s.settings.Delete(key)
102102
return &rpc.SettingsSetValueResponse{}, nil
103103
}
104104

105105
var newValue any
106-
if err := json.Unmarshal(jsonValue, &newValue); err != nil {
107-
return nil, &cmderrors.InvalidArgumentError{Message: fmt.Sprintf("invalid value: %v", err)}
106+
switch req.GetValueFormat() {
107+
case "", "json":
108+
if err := json.Unmarshal(encodedValue, &newValue); err != nil {
109+
return nil, &cmderrors.InvalidArgumentError{Message: fmt.Sprintf("invalid value: %v", err)}
110+
}
111+
case "yaml":
112+
if err := yaml.Unmarshal(encodedValue, &newValue); err != nil {
113+
return nil, &cmderrors.InvalidArgumentError{Message: fmt.Sprintf("invalid value: %v", err)}
114+
}
115+
case "cli":
116+
err := s.settings.SetFromCLIArgs(key, req.GetEncodedValue())
117+
if err != nil {
118+
return nil, err
119+
}
120+
return &rpc.SettingsSetValueResponse{}, nil
121+
default:
122+
return nil, &cmderrors.InvalidArgumentError{Message: fmt.Sprintf("unsupported value format: %s", req.ValueFormat)}
108123
}
109124

110125
// If the value is "null", unset the key
@@ -130,18 +145,28 @@ func (s *arduinoCoreServerImpl) SettingsGetValue(ctx context.Context, req *rpc.S
130145
if !ok {
131146
return nil, &cmderrors.InvalidArgumentError{Message: fmt.Sprintf("key %s not found", key)}
132147
}
133-
valueJson, err := json.Marshal(value)
134-
if err != nil {
135-
return nil, fmt.Errorf("error marshalling value: %v", err)
148+
149+
switch req.ValueFormat {
150+
case "json":
151+
valueJson, err := json.Marshal(value)
152+
if err != nil {
153+
return nil, fmt.Errorf("error marshalling value: %v", err)
154+
}
155+
return &rpc.SettingsGetValueResponse{EncodedValue: string(valueJson)}, nil
156+
case "yaml":
157+
valueYaml, err := yaml.Marshal(value)
158+
if err != nil {
159+
return nil, fmt.Errorf("error marshalling value: %v", err)
160+
}
161+
return &rpc.SettingsGetValueResponse{EncodedValue: string(valueYaml)}, nil
162+
default:
163+
return nil, &cmderrors.InvalidArgumentError{Message: fmt.Sprintf("unsupported value format: %s", req.ValueFormat)}
136164
}
137-
return &rpc.SettingsGetValueResponse{
138-
ValueJson: string(valueJson),
139-
}, nil
140165
}
141166

142167
// ConfigurationSave encodes the current configuration in the specified format
143168
func (s *arduinoCoreServerImpl) ConfigurationSave(ctx context.Context, req *rpc.ConfigurationSaveRequest) (*rpc.ConfigurationSaveResponse, error) {
144-
switch req.GetFormat() {
169+
switch req.GetSettingsFormat() {
145170
case "yaml":
146171
data, err := yaml.Marshal(s.settings)
147172
if err != nil {
@@ -155,13 +180,13 @@ func (s *arduinoCoreServerImpl) ConfigurationSave(ctx context.Context, req *rpc.
155180
}
156181
return &rpc.ConfigurationSaveResponse{EncodedSettings: string(data)}, nil
157182
default:
158-
return nil, &cmderrors.InvalidArgumentError{Message: fmt.Sprintf("unsupported format: %s", req.GetFormat())}
183+
return nil, &cmderrors.InvalidArgumentError{Message: fmt.Sprintf("unsupported format: %s", req.GetSettingsFormat())}
159184
}
160185
}
161186

162187
// SettingsReadFromFile read settings from a YAML file and replace the settings currently stored in memory.
163188
func (s *arduinoCoreServerImpl) ConfigurationOpen(ctx context.Context, req *rpc.ConfigurationOpenRequest) (*rpc.ConfigurationOpenResponse, error) {
164-
switch req.GetFormat() {
189+
switch req.GetSettingsFormat() {
165190
case "yaml":
166191
err := yaml.Unmarshal([]byte(req.GetEncodedSettings()), s.settings)
167192
if err != nil {
@@ -175,7 +200,7 @@ func (s *arduinoCoreServerImpl) ConfigurationOpen(ctx context.Context, req *rpc.
175200
}
176201
return &rpc.ConfigurationOpenResponse{}, nil
177202
default:
178-
return nil, &cmderrors.InvalidArgumentError{Message: fmt.Sprintf("unsupported format: %s", req.GetFormat())}
203+
return nil, &cmderrors.InvalidArgumentError{Message: fmt.Sprintf("unsupported format: %s", req.GetSettingsFormat())}
179204
}
180205
}
181206

Diff for: go-configmap/cli.go

+97
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
package configmap
2+
3+
import (
4+
"fmt"
5+
"strconv"
6+
"strings"
7+
)
8+
9+
func (c *Map) SetFromCLIArgs(key string, args ...string) error {
10+
if len(args) == 0 {
11+
c.Delete(key)
12+
return nil
13+
}
14+
15+
// in case of schemaless configuration, we don't know the type of the setting
16+
// we will save it as a string or array of strings
17+
if len(c.schema) == 0 {
18+
switch len(args) {
19+
case 1:
20+
c.Set(key, args[0])
21+
default:
22+
c.Set(key, args)
23+
}
24+
return nil
25+
}
26+
fmt.Println(key, args)
27+
28+
// Find the correct type for the given setting
29+
valueType, ok := c.schema[key]
30+
if !ok {
31+
return fmt.Errorf("key not found: %s", key)
32+
}
33+
34+
var value any
35+
isArray := false
36+
{
37+
var conversionError error
38+
switch valueType.String() {
39+
case "uint":
40+
value, conversionError = strconv.Atoi(args[0])
41+
case "bool":
42+
value, conversionError = strconv.ParseBool(args[0])
43+
case "string":
44+
value = args[0]
45+
case "[]string":
46+
value = args
47+
isArray = true
48+
default:
49+
return fmt.Errorf("unhandled type: %s", valueType)
50+
}
51+
if conversionError != nil {
52+
return fmt.Errorf("error setting value: %v", conversionError)
53+
}
54+
}
55+
if !isArray && len(args) != 1 {
56+
return fmt.Errorf("error setting value: key is not an array, but multiple values were provided")
57+
}
58+
59+
return c.Set(key, value)
60+
}
61+
62+
func (c *Map) InjectEnvVars(env []string, prefix string) []error {
63+
if prefix != "" {
64+
prefix = strings.ToUpper(prefix) + "_"
65+
}
66+
67+
errs := []error{}
68+
69+
envKeyToConfigKey := map[string]string{}
70+
for _, k := range c.AllKeys() {
71+
normalizedKey := prefix + strings.ToUpper(k)
72+
normalizedKey = strings.Replace(normalizedKey, ".", "_", -1)
73+
envKeyToConfigKey[normalizedKey] = k
74+
}
75+
76+
for _, e := range env {
77+
// Extract key and value from env
78+
parts := strings.SplitN(e, "=", 2)
79+
if len(parts) != 2 {
80+
continue
81+
}
82+
envKey := strings.ToUpper(parts[0])
83+
envValue := parts[1]
84+
85+
// Check if the configuration has a matching key
86+
key, ok := envKeyToConfigKey[envKey]
87+
if !ok {
88+
continue
89+
}
90+
91+
// Update the configuration value
92+
if err := c.SetFromCLIArgs(key, envValue); err != nil {
93+
errs = append(errs, err)
94+
}
95+
}
96+
return errs
97+
}

Diff for: go-configmap/configuration.go

-42
Original file line numberDiff line numberDiff line change
@@ -142,48 +142,6 @@ func (c Map) delete(keys []string) {
142142
}
143143
}
144144

145-
func (c Map) InjectEnvVars(env []string, prefix string) {
146-
if prefix != "" {
147-
prefix = strings.ToUpper(prefix) + "_"
148-
}
149-
150-
// Try submaps first
151-
for k, v := range c.values {
152-
if subConf, ok := v.(*Map); ok {
153-
subConf.InjectEnvVars(env, prefix+k)
154-
}
155-
}
156-
157-
for _, e := range env {
158-
parts := strings.SplitN(e, "=", 2)
159-
if len(parts) != 2 {
160-
continue
161-
}
162-
key := strings.ToUpper(parts[0])
163-
value := parts[1]
164-
if !strings.HasPrefix(key, prefix) {
165-
continue
166-
}
167-
key = strings.TrimPrefix(key, prefix)
168-
169-
// check if the configuration has a matching key
170-
matchingKey := ""
171-
for k := range c.values {
172-
if k == key {
173-
matchingKey = k
174-
break
175-
}
176-
if strings.EqualFold(k, key) {
177-
matchingKey = k
178-
}
179-
}
180-
if matchingKey == "" {
181-
continue
182-
}
183-
c.Set(matchingKey, value)
184-
}
185-
}
186-
187145
func (c *Map) Merge(x *Map) error {
188146
for xk, xv := range x.values {
189147
if xSubConf, ok := xv.(*Map); ok {

Diff for: internal/cli/cli.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ func NewCommand(srv rpc.ArduinoCoreServiceServer) *cobra.Command {
9595
set := func(key string, value any) {
9696
if valueJson, err := json.Marshal(value); err != nil {
9797
feedback.Fatal(tr("Error setting value %s: %v", key, err), feedback.ErrGeneric)
98-
} else if _, err := srv.SettingsSetValue(ctx, &rpc.SettingsSetValueRequest{Key: key, ValueJson: string(valueJson)}); err != nil {
98+
} else if _, err := srv.SettingsSetValue(ctx, &rpc.SettingsSetValueRequest{Key: key, EncodedValue: string(valueJson)}); err != nil {
9999
feedback.Fatal(tr("Error setting value %s: %v", key, err), feedback.ErrGeneric)
100100
}
101101
}

Diff for: internal/cli/config/add.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ func runAddCommand(ctx context.Context, srv rpc.ArduinoCoreServiceServer, args [
6060
var currentValues []string
6161
if resp, err := srv.SettingsGetValue(ctx, &rpc.SettingsGetValueRequest{Key: key}); err != nil {
6262
feedback.Fatal(tr("Cannot get the configuration key %[1]s: %[2]v", key, err), feedback.ErrGeneric)
63-
} else if err := json.Unmarshal([]byte(resp.GetValueJson()), &currentValues); err != nil {
63+
} else if err := json.Unmarshal([]byte(resp.GetEncodedValue()), &currentValues); err != nil {
6464
feedback.Fatal(tr("Cannot get the configuration key %[1]s: %[2]v", key, err), feedback.ErrGeneric)
6565
}
6666

@@ -72,7 +72,7 @@ func runAddCommand(ctx context.Context, srv rpc.ArduinoCoreServiceServer, args [
7272

7373
if newValuesJSON, err := json.Marshal(currentValues); err != nil {
7474
feedback.Fatal(tr("Cannot remove the configuration key %[1]s: %[2]v", key, err), feedback.ErrGeneric)
75-
} else if _, err := srv.SettingsSetValue(ctx, &rpc.SettingsSetValueRequest{Key: key, ValueJson: string(newValuesJSON)}); err != nil {
75+
} else if _, err := srv.SettingsSetValue(ctx, &rpc.SettingsSetValueRequest{Key: key, EncodedValue: string(newValuesJSON)}); err != nil {
7676
feedback.Fatal(tr("Cannot remove the configuration key %[1]s: %[2]v", key, err), feedback.ErrGeneric)
7777
}
7878

Diff for: internal/cli/config/config.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ func getAllArraySettingsKeys(ctx context.Context, srv rpc.ArduinoCoreServiceServ
6666

6767
func saveConfiguration(ctx context.Context, srv rpc.ArduinoCoreServiceServer) {
6868
var outConfig []byte
69-
if res, err := srv.ConfigurationSave(ctx, &rpc.ConfigurationSaveRequest{Format: "yaml"}); err != nil {
69+
if res, err := srv.ConfigurationSave(ctx, &rpc.ConfigurationSaveRequest{SettingsFormat: "yaml"}); err != nil {
7070
feedback.Fatal(tr("Error writing to file: %v", err), feedback.ErrGeneric)
7171
} else {
7272
outConfig = []byte(res.GetEncodedSettings())

Diff for: internal/cli/config/delete.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ func runDeleteCommand(ctx context.Context, srv rpc.ArduinoCoreServiceServer, arg
5050
logrus.Info("Executing `arduino-cli config delete`")
5151

5252
key := args[0]
53-
if _, err := srv.SettingsSetValue(ctx, &rpc.SettingsSetValueRequest{Key: key, ValueJson: ""}); err != nil {
53+
if _, err := srv.SettingsSetValue(ctx, &rpc.SettingsSetValueRequest{Key: key, EncodedValue: ""}); err != nil {
5454
feedback.Fatal(tr("Cannot delete the key %[1]s: %[2]v", key, err), feedback.ErrGeneric)
5555
}
5656

Diff for: internal/cli/config/dump.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -36,13 +36,13 @@ func initDumpCommand(srv rpc.ArduinoCoreServiceServer) *cobra.Command {
3636
res := &rawResult{}
3737
switch feedback.GetFormat() {
3838
case feedback.JSON, feedback.MinifiedJSON:
39-
resp, err := srv.ConfigurationSave(cmd.Context(), &rpc.ConfigurationSaveRequest{Format: "json"})
39+
resp, err := srv.ConfigurationSave(cmd.Context(), &rpc.ConfigurationSaveRequest{SettingsFormat: "json"})
4040
if err != nil {
4141
logrus.Fatalf("Error creating configuration: %v", err)
4242
}
4343
res.rawJSON = []byte(resp.GetEncodedSettings())
4444
case feedback.YAML, feedback.Text:
45-
resp, err := srv.ConfigurationSave(cmd.Context(), &rpc.ConfigurationSaveRequest{Format: "yaml"})
45+
resp, err := srv.ConfigurationSave(cmd.Context(), &rpc.ConfigurationSaveRequest{SettingsFormat: "yaml"})
4646
if err != nil {
4747
logrus.Fatalf("Error creating configuration: %v", err)
4848
}

Diff for: internal/cli/config/get.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ func runGetCommand(srv rpc.ArduinoCoreServiceServer, args []string) {
5959
feedback.Fatal(tr("Cannot get the configuration key %[1]s: %[2]v", toGet, err), feedback.ErrGeneric)
6060
}
6161
var result getResult
62-
if err := json.Unmarshal([]byte(resp.GetValueJson()), &result.resp); err != nil {
62+
if err := json.Unmarshal([]byte(resp.GetEncodedValue()), &result.resp); err != nil {
6363
// Should never happen...
6464
panic(fmt.Sprintf("Cannot parse JSON for key %[1]s: %[2]v", toGet, err))
6565
}

Diff for: internal/cli/config/init.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ func runInitCommand(srv rpc.ArduinoCoreServiceServer) {
104104
// }
105105
// }
106106

107-
resp, err := srv.ConfigurationSave(ctx, &rpc.ConfigurationSaveRequest{Format: "yaml"})
107+
resp, err := srv.ConfigurationSave(ctx, &rpc.ConfigurationSaveRequest{SettingsFormat: "yaml"})
108108
if err != nil {
109109
feedback.Fatal(tr("Error creating configuration: %v", err), feedback.ErrGeneric)
110110
}

Diff for: internal/cli/config/remove.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ func runRemoveCommand(ctx context.Context, srv rpc.ArduinoCoreServiceServer, arg
6060
var currentValues []string
6161
if resp, err := srv.SettingsGetValue(ctx, &rpc.SettingsGetValueRequest{Key: key}); err != nil {
6262
feedback.Fatal(tr("Cannot get the configuration key %[1]s: %[2]v", key, err), feedback.ErrGeneric)
63-
} else if err := json.Unmarshal([]byte(resp.GetValueJson()), &currentValues); err != nil {
63+
} else if err := json.Unmarshal([]byte(resp.GetEncodedValue()), &currentValues); err != nil {
6464
feedback.Fatal(tr("Cannot get the configuration key %[1]s: %[2]v", key, err), feedback.ErrGeneric)
6565
}
6666

@@ -70,7 +70,7 @@ func runRemoveCommand(ctx context.Context, srv rpc.ArduinoCoreServiceServer, arg
7070

7171
if newValuesJSON, err := json.Marshal(currentValues); err != nil {
7272
feedback.Fatal(tr("Cannot remove the configuration key %[1]s: %[2]v", key, err), feedback.ErrGeneric)
73-
} else if _, err := srv.SettingsSetValue(ctx, &rpc.SettingsSetValueRequest{Key: key, ValueJson: string(newValuesJSON)}); err != nil {
73+
} else if _, err := srv.SettingsSetValue(ctx, &rpc.SettingsSetValueRequest{Key: key, EncodedValue: string(newValuesJSON)}); err != nil {
7474
feedback.Fatal(tr("Cannot remove the configuration key %[1]s: %[2]v", key, err), feedback.ErrGeneric)
7575
}
7676

0 commit comments

Comments
 (0)