Skip to content

Commit 9c13e87

Browse files
authored
Merge pull request #1542 from arduino/umbynos/flags_refactoring
[breaking] uniform cli commands and flag
2 parents e72f683 + 294c7bc commit 9c13e87

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

57 files changed

+655
-536
lines changed

cli/arguments/arguments.go

+20-1
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,25 @@
1515

1616
package arguments
1717

18-
import "github.com/arduino/arduino-cli/i18n"
18+
import (
19+
"os"
20+
"strings"
21+
22+
"github.com/arduino/arduino-cli/cli/errorcodes"
23+
"github.com/arduino/arduino-cli/cli/feedback"
24+
"github.com/arduino/arduino-cli/i18n"
25+
"github.com/spf13/cobra"
26+
)
1927

2028
var tr = i18n.Tr
29+
30+
// CheckFlagsConflicts is a helper function useful to report errors when more than one conflicting flag is used
31+
func CheckFlagsConflicts(command *cobra.Command, flagNames ...string) {
32+
for _, flagName := range flagNames {
33+
if !command.Flag(flagName).Changed {
34+
return
35+
}
36+
}
37+
feedback.Errorf(tr("Can't use %s flags at the same time.", "--"+strings.Join(flagNames, " "+tr("and")+" --")))
38+
os.Exit(errorcodes.ErrBadArgument)
39+
}

cli/arguments/fqbn.go

+43
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
// This file is part of arduino-cli.
2+
//
3+
// Copyright 2020 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 arguments
17+
18+
import "github.com/spf13/cobra"
19+
20+
// Fqbn contains the fqbn flag data.
21+
// This is useful so all flags used by commands that need
22+
// this information are consistent with each other.
23+
type Fqbn struct {
24+
fqbn string
25+
}
26+
27+
// AddToCommand adds the flags used to set fqbn to the specified Command
28+
func (f *Fqbn) AddToCommand(cmd *cobra.Command) {
29+
cmd.Flags().StringVarP(&f.fqbn, "fqbn", "b", "", tr("Fully Qualified Board Name, e.g.: arduino:avr:uno"))
30+
cmd.RegisterFlagCompletionFunc("fqbn", func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
31+
return GetInstalledBoards(), cobra.ShellCompDirectiveDefault
32+
})
33+
}
34+
35+
// String returns the fqbn
36+
func (f *Fqbn) String() string {
37+
return f.fqbn
38+
}
39+
40+
// Set sets the fqbn
41+
func (f *Fqbn) Set(fqbn string) {
42+
f.fqbn = fqbn
43+
}

cli/arguments/port.go

+17
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,12 @@ package arguments
1818
import (
1919
"fmt"
2020
"net/url"
21+
"os"
2122
"time"
2223

2324
"github.com/arduino/arduino-cli/arduino/discovery"
2425
"github.com/arduino/arduino-cli/arduino/sketch"
26+
"github.com/arduino/arduino-cli/cli/errorcodes"
2527
"github.com/arduino/arduino-cli/cli/feedback"
2628
"github.com/arduino/arduino-cli/commands"
2729
rpc "github.com/arduino/arduino-cli/rpc/cc/arduino/cli/commands/v1"
@@ -144,3 +146,18 @@ func (p *Port) GetPort(instance *rpc.Instance, sk *sketch.Sketch) (*discovery.Po
144146
}
145147
}
146148
}
149+
150+
// GetSearchTimeout returns the timeout
151+
func (p *Port) GetSearchTimeout() time.Duration {
152+
return p.timeout
153+
}
154+
155+
// GetDiscoveryPort is a helper function useful to get the port and handle possible errors
156+
func (p *Port) GetDiscoveryPort(instance *rpc.Instance, sk *sketch.Sketch) *discovery.Port {
157+
discoveryPort, err := p.GetPort(instance, sk)
158+
if err != nil {
159+
feedback.Errorf(tr("Error discovering port: %v"), err)
160+
os.Exit(errorcodes.ErrGeneric)
161+
}
162+
return discoveryPort
163+
}

cli/arguments/post_install.go

+66
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
// This file is part of arduino-cli.
2+
//
3+
// Copyright 2020 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 arguments
17+
18+
import (
19+
"github.com/arduino/arduino-cli/configuration"
20+
"github.com/sirupsen/logrus"
21+
"github.com/spf13/cobra"
22+
)
23+
24+
// PostInstallFlags contains flags data used by the core install and the upgrade command
25+
// This is useful so all flags used by commands that need
26+
// this information are consistent with each other.
27+
type PostInstallFlags struct {
28+
runPostInstall bool // force the execution of installation scripts
29+
skipPostInstall bool //skip the execution of installation scripts
30+
}
31+
32+
// AddToCommand adds flags that can be used to force running or skipping
33+
// of post installation scripts
34+
func (p *PostInstallFlags) AddToCommand(cmd *cobra.Command) {
35+
cmd.Flags().BoolVar(&p.runPostInstall, "run-post-install", false, tr("Force run of post-install scripts (if the CLI is not running interactively)."))
36+
cmd.Flags().BoolVar(&p.skipPostInstall, "skip-post-install", false, tr("Force skip of post-install scripts (if the CLI is running interactively)."))
37+
}
38+
39+
// GetRunPostInstall returns the run-post-install flag value
40+
func (p *PostInstallFlags) GetRunPostInstall() bool {
41+
return p.runPostInstall
42+
}
43+
44+
// GetSkipPostInstall returns the skip-post-install flag value
45+
func (p *PostInstallFlags) GetSkipPostInstall() bool {
46+
return p.skipPostInstall
47+
}
48+
49+
// DetectSkipPostInstallValue returns true if a post install script must be run
50+
func (p *PostInstallFlags) DetectSkipPostInstallValue() bool {
51+
if p.GetRunPostInstall() {
52+
logrus.Info("Will run post-install by user request")
53+
return false
54+
}
55+
if p.GetSkipPostInstall() {
56+
logrus.Info("Will skip post-install by user request")
57+
return true
58+
}
59+
60+
if !configuration.IsInteractive {
61+
logrus.Info("Not running from console, will skip post-install by default")
62+
return true
63+
}
64+
logrus.Info("Running from console, will run post-install by default")
65+
return false
66+
}

cli/arguments/programmer.go

+38
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
// This file is part of arduino-cli.
2+
//
3+
// Copyright 2020 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 arguments
17+
18+
import "github.com/spf13/cobra"
19+
20+
// Programmer contains the programmer flag data.
21+
// This is useful so all flags used by commands that need
22+
// this information are consistent with each other.
23+
type Programmer struct {
24+
programmer string
25+
}
26+
27+
// AddToCommand adds the flags used to set the programmer to the specified Command
28+
func (p *Programmer) AddToCommand(cmd *cobra.Command) {
29+
cmd.Flags().StringVarP(&p.programmer, "programmer", "P", "", tr("Programmer to use, e.g: atmel_ice"))
30+
cmd.RegisterFlagCompletionFunc("programmer", func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
31+
return GetInstalledProgrammers(), cobra.ShellCompDirectiveDefault
32+
})
33+
}
34+
35+
// String returns the programmer
36+
func (p *Programmer) String() string {
37+
return p.programmer
38+
}

cli/arguments/sketch.go

+32-7
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ package arguments
1818
import (
1919
"os"
2020

21+
"github.com/arduino/arduino-cli/arduino/sketch"
2122
"github.com/arduino/arduino-cli/cli/errorcodes"
2223
"github.com/arduino/arduino-cli/cli/feedback"
2324
"github.com/arduino/go-paths-helper"
@@ -26,16 +27,40 @@ import (
2627

2728
// InitSketchPath returns an instance of paths.Path pointing to sketchPath.
2829
// If sketchPath is an empty string returns the current working directory.
29-
func InitSketchPath(sketchPath string) *paths.Path {
30-
if sketchPath != "" {
31-
return paths.New(sketchPath)
30+
// In both cases it warns the user if he's using deprecated files
31+
func InitSketchPath(path string) (sketchPath *paths.Path) {
32+
if path != "" {
33+
sketchPath = paths.New(path)
34+
} else {
35+
wd, err := paths.Getwd()
36+
if err != nil {
37+
feedback.Errorf(tr("Couldn't get current working directory: %v"), err)
38+
os.Exit(errorcodes.ErrGeneric)
39+
}
40+
logrus.Infof("Reading sketch from dir: %s", wd)
41+
sketchPath = wd
3242
}
43+
WarnDeprecatedFiles(sketchPath)
44+
return sketchPath
45+
}
3346

34-
wd, err := paths.Getwd()
47+
// NewSketch is a helper function useful to create a sketch instance
48+
func NewSketch(sketchPath *paths.Path) *sketch.Sketch {
49+
sketch, err := sketch.New(sketchPath)
3550
if err != nil {
36-
feedback.Errorf(tr("Couldn't get current working directory: %v"), err)
51+
feedback.Errorf(tr("Error creating sketch: %v"), err)
3752
os.Exit(errorcodes.ErrGeneric)
3853
}
39-
logrus.Infof("Reading sketch from dir: %s", wd)
40-
return wd
54+
return sketch
55+
}
56+
57+
// WarnDeprecatedFiles warns the user that a type of sketch files are deprecated
58+
func WarnDeprecatedFiles(sketchPath *paths.Path) {
59+
// .pde files are still supported but deprecated, this warning urges the user to rename them
60+
if files := sketch.CheckForPdeFiles(sketchPath); len(files) > 0 {
61+
feedback.Error(tr("Sketches with .pde extension are deprecated, please rename the following files to .ino:"))
62+
for _, f := range files {
63+
feedback.Error(f)
64+
}
65+
}
4166
}

cli/board/attach.go

+28-15
Original file line numberDiff line numberDiff line change
@@ -27,43 +27,56 @@ import (
2727
"github.com/arduino/arduino-cli/cli/output"
2828
"github.com/arduino/arduino-cli/commands/board"
2929
rpc "github.com/arduino/arduino-cli/rpc/cc/arduino/cli/commands/v1"
30+
"github.com/sirupsen/logrus"
3031
"github.com/spf13/cobra"
3132
)
3233

34+
var (
35+
port arguments.Port
36+
)
37+
3338
func initAttachCommand() *cobra.Command {
3439
attachCommand := &cobra.Command{
35-
Use: fmt.Sprintf("attach <%s>|<%s> [%s]", tr("port"), tr("FQBN"), tr("sketchPath")),
40+
Use: fmt.Sprintf("attach -p <%s>|-b <%s> [%s]", tr("port"), tr("FQBN"), tr("sketchPath")),
3641
Short: tr("Attaches a sketch to a board."),
3742
Long: tr("Attaches a sketch to a board."),
38-
Example: " " + os.Args[0] + " board attach serial:///dev/ttyACM0\n" +
39-
" " + os.Args[0] + " board attach serial:///dev/ttyACM0 HelloWorld\n" +
40-
" " + os.Args[0] + " board attach arduino:samd:mkr1000",
41-
Args: cobra.RangeArgs(1, 2),
43+
Example: " " + os.Args[0] + " board attach -p /dev/ttyACM0\n" +
44+
" " + os.Args[0] + " board attach -p /dev/ttyACM0 HelloWorld\n" +
45+
" " + os.Args[0] + " board attach -b arduino:samd:mkr1000",
46+
Args: cobra.MaximumNArgs(1),
4247
Run: runAttachCommand,
4348
}
44-
attachCommand.Flags().StringVar(&attachFlags.searchTimeout, "timeout", "5s",
45-
tr("The connected devices search timeout, raise it if your board doesn't show up (e.g. to %s).", "10s"))
46-
return attachCommand
47-
}
49+
fqbn.AddToCommand(attachCommand)
50+
port.AddToCommand(attachCommand)
4851

49-
var attachFlags struct {
50-
searchTimeout string // Expressed in a parsable duration, is the timeout for the list and attach commands.
52+
return attachCommand
5153
}
5254

5355
func runAttachCommand(cmd *cobra.Command, args []string) {
5456
instance := instance.CreateAndInit()
5557

58+
logrus.Info("Executing `arduino-cli board attach`")
59+
5660
path := ""
57-
if len(args) > 1 {
58-
path = args[1]
61+
if len(args) > 0 {
62+
path = args[0]
5963
}
6064
sketchPath := arguments.InitSketchPath(path)
6165

66+
// ugly hack to allow user to specify fqbn and port as flags (consistency)
67+
// a more meaningful fix would be to fix board.Attach
68+
var boardURI string
69+
discoveryPort, _ := port.GetPort(instance, nil)
70+
if fqbn.String() != "" {
71+
boardURI = fqbn.String()
72+
} else if discoveryPort != nil {
73+
boardURI = discoveryPort.Address
74+
}
6275
if _, err := board.Attach(context.Background(), &rpc.BoardAttachRequest{
6376
Instance: instance,
64-
BoardUri: args[0],
77+
BoardUri: boardURI,
6578
SketchPath: sketchPath.String(),
66-
SearchTimeout: attachFlags.searchTimeout,
79+
SearchTimeout: port.GetSearchTimeout().String(),
6780
}, output.TaskProgress()); err != nil {
6881
feedback.Errorf(tr("Attach board error: %v"), err)
6982
os.Exit(errorcodes.ErrGeneric)

cli/board/board.go

+3
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,12 @@ package board
1818
import (
1919
"os"
2020

21+
"github.com/arduino/arduino-cli/i18n"
2122
"github.com/spf13/cobra"
2223
)
2324

25+
var tr = i18n.Tr
26+
2427
// NewCommand created a new `board` command
2528
func NewCommand() *cobra.Command {
2629
boardCommand := &cobra.Command{

0 commit comments

Comments
 (0)