summaryrefslogtreecommitdiffstats
path: root/commands
diff options
context:
space:
mode:
authorBjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>2018-04-13 08:42:29 +0200
committerBjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>2018-04-13 09:08:49 +0200
commit2aab6dee850517533683504a6158e0ef0a3ffc57 (patch)
treebf490b5add868d98e85590a3c7a4696cec2297f2 /commands
parentf3775877c61c11ab7c8fd1fc3e15470bf5da4820 (diff)
commands: Fix handling of persistent CLI flags
See #4607
Diffstat (limited to 'commands')
-rw-r--r--commands/benchmark.go4
-rw-r--r--commands/commands.go56
-rw-r--r--commands/commands_test.go43
-rw-r--r--commands/hugo.go2
-rw-r--r--commands/server.go11
-rw-r--r--commands/server_test.go6
6 files changed, 94 insertions, 28 deletions
diff --git a/commands/benchmark.go b/commands/benchmark.go
index 4cdac883f..3938acf1b 100644
--- a/commands/benchmark.go
+++ b/commands/benchmark.go
@@ -31,7 +31,7 @@ type benchmarkCmd struct {
*baseBuilderCmd
}
-func newBenchmarkCmd() *benchmarkCmd {
+func (b *commandsBuilder) newBenchmarkCmd() *benchmarkCmd {
cmd := &cobra.Command{
Use: "benchmark",
Short: "Benchmark Hugo by building a site a number of times.",
@@ -39,7 +39,7 @@ func newBenchmarkCmd() *benchmarkCmd {
creating a benchmark.`,
}
- c := &benchmarkCmd{baseBuilderCmd: newBuilderCmd(cmd)}
+ c := &benchmarkCmd{baseBuilderCmd: b.newBuilderCmd(cmd)}
cmd.Flags().StringVar(&c.cpuProfileFile, "cpuprofile", "", "path/filename for the CPU profile file")
cmd.Flags().StringVar(&c.memProfileFile, "memprofile", "", "path/filename for the memory profile file")
diff --git a/commands/commands.go b/commands/commands.go
index 86486d2a4..d0cc97b85 100644
--- a/commands/commands.go
+++ b/commands/commands.go
@@ -21,29 +21,43 @@ import (
"github.com/spf13/nitro"
)
-// newHugoCompleteCmd builds the complete set of Hugo CLI commands.
-func newHugoCompleteCmd() *hugoCmd {
- h := newHugoCmd()
- addAllCommands(h.getCommand())
- return h
+type commandsBuilder struct {
+ hugoBuilderCommon
+
+ commands []cmder
+}
+
+func newCommandsBuilder() *commandsBuilder {
+ return &commandsBuilder{}
+}
+
+func (b *commandsBuilder) addCommands(commands ...cmder) *commandsBuilder {
+ b.commands = append(b.commands, commands...)
+ return b
}
-// addAllCommands adds child commands to the root command HugoCmd.
-func addAllCommands(root *cobra.Command) {
- addCommands(
- root,
- newServerCmd(),
+func (b *commandsBuilder) addAll() *commandsBuilder {
+ b.addCommands(
+ b.newServerCmd(),
newVersionCmd(),
newEnvCmd(),
newConfigCmd(),
newCheckCmd(),
- newBenchmarkCmd(),
+ b.newBenchmarkCmd(),
newConvertCmd(),
newNewCmd(),
newListCmd(),
newImportCmd(),
newGenCmd(),
)
+
+ return b
+}
+
+func (b *commandsBuilder) build() *hugoCmd {
+ h := b.newHugoCmd()
+ addCommands(h.getCommand(), b.commands...)
+ return h
}
func addCommands(root *cobra.Command, commands ...cmder) {
@@ -56,9 +70,19 @@ type baseCmd struct {
cmd *cobra.Command
}
+var _ commandsBuilderGetter = (*baseBuilderCmd)(nil)
+
+// Used in tests.
+type commandsBuilderGetter interface {
+ getCmmandsBuilder() *commandsBuilder
+}
type baseBuilderCmd struct {
- hugoBuilderCommon
*baseCmd
+ *commandsBuilder
+}
+
+func (b *baseBuilderCmd) getCmmandsBuilder() *commandsBuilder {
+ return b.commandsBuilder
}
func (c *baseCmd) getCommand() *cobra.Command {
@@ -69,8 +93,8 @@ func newBaseCmd(cmd *cobra.Command) *baseCmd {
return &baseCmd{cmd: cmd}
}
-func newBuilderCmd(cmd *cobra.Command) *baseBuilderCmd {
- bcmd := &baseBuilderCmd{baseCmd: &baseCmd{cmd: cmd}}
+func (b *commandsBuilder) newBuilderCmd(cmd *cobra.Command) *baseBuilderCmd {
+ bcmd := &baseBuilderCmd{commandsBuilder: b, baseCmd: &baseCmd{cmd: cmd}}
bcmd.hugoBuilderCommon.handleFlags(cmd)
return bcmd
}
@@ -86,10 +110,10 @@ type hugoCmd struct {
c *commandeer
}
-func newHugoCmd() *hugoCmd {
+func (b *commandsBuilder) newHugoCmd() *hugoCmd {
cc := &hugoCmd{}
- cc.baseBuilderCmd = newBuilderCmd(&cobra.Command{
+ cc.baseBuilderCmd = b.newBuilderCmd(&cobra.Command{
Use: "hugo",
Short: "hugo builds your site",
Long: `hugo is the main command, used to build your Hugo site.
diff --git a/commands/commands_test.go b/commands/commands_test.go
index ea9d3f74d..6fabbbb0b 100644
--- a/commands/commands_test.go
+++ b/commands/commands_test.go
@@ -20,6 +20,8 @@ import (
"path/filepath"
"testing"
+ "github.com/spf13/cobra"
+
"github.com/stretchr/testify/require"
)
@@ -41,7 +43,44 @@ func TestExecute(t *testing.T) {
assert.True(len(result.Sites[0].RegularPages) == 1)
}
-func TestCommands(t *testing.T) {
+func TestCommandsPersistentFlags(t *testing.T) {
+ assert := require.New(t)
+
+ noOpRunE := func(cmd *cobra.Command, args []string) error {
+ return nil
+ }
+
+ tests := []struct {
+ args []string
+ check func(command []cmder)
+ }{{[]string{"server", "--config=myconfig.toml", "-b=https://example.com/b/", "--source=mysource"}, func(commands []cmder) {
+ for _, command := range commands {
+ if b, ok := command.(commandsBuilderGetter); ok {
+ v := b.getCmmandsBuilder().hugoBuilderCommon
+ assert.Equal("myconfig.toml", v.cfgFile)
+ assert.Equal("mysource", v.source)
+ assert.Equal("https://example.com/b/", v.baseURL)
+ }
+ }
+ }}}
+
+ for _, test := range tests {
+ b := newCommandsBuilder()
+ root := b.addAll().build()
+
+ for _, c := range b.commands {
+ // We are only intereseted in the flag handling here.
+ c.getCommand().RunE = noOpRunE
+ }
+ rootCmd := root.getCommand()
+ rootCmd.SetArgs(test.args)
+ assert.NoError(rootCmd.Execute())
+ test.check(b.commands)
+ }
+
+}
+
+func TestCommandsExecute(t *testing.T) {
assert := require.New(t)
@@ -90,7 +129,7 @@ func TestCommands(t *testing.T) {
for _, test := range tests {
- hugoCmd := newHugoCompleteCmd().getCommand()
+ hugoCmd := newCommandsBuilder().addAll().build().getCommand()
test.flags = append(test.flags, "--quiet")
hugoCmd.SetArgs(append(test.commands, test.flags...))
diff --git a/commands/hugo.go b/commands/hugo.go
index c1cf9833f..84e265cf2 100644
--- a/commands/hugo.go
+++ b/commands/hugo.go
@@ -70,7 +70,7 @@ func (r Response) IsUserError() bool {
// Execute adds all child commands to the root command HugoCmd and sets flags appropriately.
// The args are usually filled with os.Args[1:].
func Execute(args []string) Response {
- hugoCmd := newHugoCompleteCmd()
+ hugoCmd := newCommandsBuilder().addAll().build()
cmd := hugoCmd.getCommand()
cmd.SetArgs(args)
diff --git a/commands/server.go b/commands/server.go
index 8db6fa918..c05180de9 100644
--- a/commands/server.go
+++ b/commands/server.go
@@ -57,14 +57,14 @@ type serverCmd struct {
*baseBuilderCmd
}
-func newServerCmd() *serverCmd {
- return newServerCmdSignaled(nil)
+func (b *commandsBuilder) newServerCmd() *serverCmd {
+ return b.newServerCmdSignaled(nil)
}
-func newServerCmdSignaled(stop <-chan bool) *serverCmd {
+func (b *commandsBuilder) newServerCmdSignaled(stop <-chan bool) *serverCmd {
cc := &serverCmd{stop: stop}
- cc.baseBuilderCmd = newBuilderCmd(&cobra.Command{
+ cc.baseBuilderCmd = b.newBuilderCmd(&cobra.Command{
Use: "server",
Aliases: []string{"serve"},
Short: "A high performance webserver",
@@ -463,7 +463,8 @@ func (sc *serverCmd) fixURL(cfg config.Provider, s string, port int) (string, er
}
func memStats() error {
- sc := newServerCmd().getCommand()
+ b := newCommandsBuilder()
+ sc := b.newServerCmd().getCommand()
memstats := sc.Flags().Lookup("memstats").Value.String()
if memstats != "" {
interval, err := time.ParseDuration(sc.Flags().Lookup("meminterval").Value.String())
diff --git a/commands/server_test.go b/commands/server_test.go
index 648664697..7b9cdcfaa 100644
--- a/commands/server_test.go
+++ b/commands/server_test.go
@@ -40,7 +40,8 @@ func TestServer(t *testing.T) {
stop := make(chan bool)
- scmd := newServerCmdSignaled(stop)
+ b := newCommandsBuilder()
+ scmd := b.newServerCmdSignaled(stop)
cmd := scmd.getCommand()
cmd.SetArgs([]string{"-s=" + dir, fmt.Sprintf("-p=%d", port)})
@@ -90,7 +91,8 @@ func TestFixURL(t *testing.T) {
}
for i, test := range tests {
- s := newServerCmd()
+ b := newCommandsBuilder()
+ s := b.newServerCmd()
v := viper.New()
baseURL := test.CLIBaseURL
v.Set("baseURL", test.CfgBaseURL)