ref: 2aab6dee850517533683504a6158e0ef0a3ffc57
parent: f3775877c61c11ab7c8fd1fc3e15470bf5da4820
author: Bjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>
date: Fri Apr 13 04:42:29 EDT 2018
commands: Fix handling of persistent CLI flags See #4607
--- a/commands/benchmark.go
+++ b/commands/benchmark.go
@@ -31,7 +31,7 @@
*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 @@
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")
--- a/commands/commands.go
+++ b/commands/commands.go
@@ -21,23 +21,29 @@
"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
}
-// addAllCommands adds child commands to the root command HugoCmd.
-func addAllCommands(root *cobra.Command) {- addCommands(
- root,
- newServerCmd(),
+func newCommandsBuilder() *commandsBuilder {+ return &commandsBuilder{}+}
+
+func (b *commandsBuilder) addCommands(commands ...cmder) *commandsBuilder {+ b.commands = append(b.commands, commands...)
+ return b
+}
+
+func (b *commandsBuilder) addAll() *commandsBuilder {+ b.addCommands(
+ b.newServerCmd(),
newVersionCmd(),
newEnvCmd(),
newConfigCmd(),
newCheckCmd(),
- newBenchmarkCmd(),
+ b.newBenchmarkCmd(),
newConvertCmd(),
newNewCmd(),
newListCmd(),
@@ -44,8 +50,16 @@
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) { for _, command := range commands {root.AddCommand(command.getCommand())
@@ -56,11 +70,21 @@
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 {return c.cmd
}
@@ -69,8 +93,8 @@
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 @@
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.
--- a/commands/commands_test.go
+++ b/commands/commands_test.go
@@ -20,6 +20,8 @@
"path/filepath"
"testing"
+ "github.com/spf13/cobra"
+
"github.com/stretchr/testify/require"
)
@@ -41,8 +43,45 @@
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)
dir, err := createSimpleTestSite(t)
@@ -90,7 +129,7 @@
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...))
--- a/commands/hugo.go
+++ b/commands/hugo.go
@@ -70,7 +70,7 @@
// 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)
--- a/commands/server.go
+++ b/commands/server.go
@@ -57,14 +57,14 @@
*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 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())--- a/commands/server_test.go
+++ b/commands/server_test.go
@@ -40,7 +40,8 @@
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 @@
}
for i, test := range tests {- s := newServerCmd()
+ b := newCommandsBuilder()
+ s := b.newServerCmd()
v := viper.New()
baseURL := test.CLIBaseURL
v.Set("baseURL", test.CfgBaseURL)--
⑨