Skip to content

Commit 16d2531

Browse files
committed
Introducing key/value flag type
1 parent 47a858e commit 16d2531

File tree

2 files changed

+91
-19
lines changed

2 files changed

+91
-19
lines changed

Diff for: internal/cli/arguments/key_value.go

+81
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
// This file is part of arduino-cli.
2+
//
3+
// Copyright 2023 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 [email protected].
15+
16+
package arguments
17+
18+
import (
19+
"errors"
20+
"fmt"
21+
"strings"
22+
23+
"github.com/spf13/cobra"
24+
)
25+
26+
// AddKeyValuePFlag adds a flag to the command that accepts a (possibly repeated) key=value pair.
27+
func AddKeyValuePFlag(cmd *cobra.Command, field *map[string]string, name, shorthand string, value []string, usage string) {
28+
cmd.Flags().VarP(newKVArrayValue(value, field), name, shorthand, usage)
29+
}
30+
31+
type kvArrayValue struct {
32+
value *map[string]string
33+
changed bool
34+
}
35+
36+
func newKVArrayValue(val []string, p *map[string]string) *kvArrayValue {
37+
ssv := &kvArrayValue{
38+
value: p,
39+
}
40+
for _, v := range val {
41+
ssv.Set(v)
42+
}
43+
ssv.changed = false
44+
return ssv
45+
}
46+
47+
func (s *kvArrayValue) Set(arg string) error {
48+
split := strings.SplitN(arg, "=", 2)
49+
if len(split) != 2 {
50+
return errors.New("required format is 'key=value'")
51+
}
52+
k, v := split[0], split[1]
53+
if k == "" {
54+
return errors.New("key cannot be empty")
55+
}
56+
if !s.changed {
57+
// Remove the default value
58+
*s.value = make(map[string]string)
59+
s.changed = true
60+
}
61+
if _, ok := (*s.value)[k]; ok {
62+
return errors.New("duplicate key: " + k)
63+
}
64+
(*s.value)[k] = v
65+
return nil
66+
}
67+
68+
func (s *kvArrayValue) Type() string {
69+
return "key=value"
70+
}
71+
72+
func (s *kvArrayValue) String() string {
73+
if len(*s.value) == 0 {
74+
return "[]"
75+
}
76+
res := "["
77+
for k, v := range *s.value {
78+
res += fmt.Sprintf("%s=%s, ", k, v)
79+
}
80+
return res[:len(res)-2] + "]"
81+
}

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

+10-19
Original file line numberDiff line numberDiff line change
@@ -51,29 +51,20 @@ var (
5151

5252
// NewCommand created a new `upload` command
5353
func NewCommand() *cobra.Command {
54-
var uploadFields []string
55-
var parsedUploadFields map[string]string
54+
uploadFields := map[string]string{}
5655
uploadCommand := &cobra.Command{
57-
Use: "upload",
58-
Short: tr("Upload Arduino sketches."),
59-
Long: tr("Upload Arduino sketches. This does NOT compile the sketch prior to upload."),
60-
Example: " " + os.Args[0] + " upload /home/user/Arduino/MySketch",
61-
Args: cobra.MaximumNArgs(1),
56+
Use: "upload",
57+
Short: tr("Upload Arduino sketches."),
58+
Long: tr("Upload Arduino sketches. This does NOT compile the sketch prior to upload."),
59+
Example: "" +
60+
" " + os.Args[0] + " upload /home/user/Arduino/MySketch -p /dev/ttyACM0 -b arduino:avr:uno\n" +
61+
" " + os.Args[0] + " upload -p 192.168.10.1 -b arduino:avr:uno --upload-field password=abc",
62+
Args: cobra.MaximumNArgs(1),
6263
PreRun: func(cmd *cobra.Command, args []string) {
6364
arguments.CheckFlagsConflicts(cmd, "input-file", "input-dir")
64-
if len(uploadFields) > 0 {
65-
parsedUploadFields = map[string]string{}
66-
for _, field := range uploadFields {
67-
split := strings.SplitN(field, "=", 2)
68-
if len(split) != 2 {
69-
feedback.Fatal(tr("Invalid upload field: %s", field), feedback.ErrBadArgument)
70-
}
71-
parsedUploadFields[split[0]] = split[1]
72-
}
73-
}
7465
},
7566
Run: func(cmd *cobra.Command, args []string) {
76-
runUploadCommand(args, parsedUploadFields)
67+
runUploadCommand(args, uploadFields)
7768
},
7869
}
7970

@@ -87,7 +78,7 @@ func NewCommand() *cobra.Command {
8778
programmer.AddToCommand(uploadCommand)
8879
uploadCommand.Flags().BoolVar(&dryRun, "dry-run", false, tr("Do not perform the actual upload, just log out actions"))
8980
uploadCommand.Flags().MarkHidden("dry-run")
90-
uploadCommand.Flags().StringArrayVar(&uploadFields, "upload-field", uploadFields, tr("Set a value for a field required to upload.")+" (field=value)")
81+
arguments.AddKeyValuePFlag(uploadCommand, &uploadFields, "upload-field", "F", nil, tr("Set a value for a field required to upload."))
9182
return uploadCommand
9283
}
9384

0 commit comments

Comments
 (0)