shithub: hugo

Download patch

ref: 96689a5c319f720368491226f034d0ff9585217c
parent: e7010c1b621d68ee53411a5ba8143d07b976d9fe
author: Bjørn Erik Pedersen <[email protected]>
date: Wed Apr 11 16:17:28 EDT 2018

commands: Make commands.Execute return a Response object

We have no global `Hugo` object no more (yay!), and there are some external tools that depends on that value.

These tools need to use get that value from `Response.Result`.

Note that `commands.Execute` now also takes the arguments as a string slice. This should also make it easier to use, not having to modify `os.Args`.

This commit also wraps up this particular issue. Phew!

Test coverage in /commands before: 14.4%
Now:  53.5%

Still work to do, now it is at least possible.

Closes #4598

--- a/commands/commands.go
+++ b/commands/commands.go
@@ -22,10 +22,10 @@
 )
 
 // newHugoCompleteCmd builds the complete set of Hugo CLI commands.
-func newHugoCompleteCmd() *cobra.Command {
-	hugoCmd := newHugoCmd().getCommand()
-	addAllCommands(hugoCmd)
-	return hugoCmd
+func newHugoCompleteCmd() *hugoCmd {
+	h := newHugoCmd()
+	addAllCommands(h.getCommand())
+	return h
 }
 
 // addAllCommands adds child commands to the root command HugoCmd.
@@ -81,6 +81,9 @@
 
 type hugoCmd struct {
 	*baseBuilderCmd
+
+	// Need to get the sites once built.
+	c *commandeer
 }
 
 func newHugoCmd() *hugoCmd {
@@ -107,6 +110,7 @@
 			if err != nil {
 				return err
 			}
+			cc.c = c
 
 			return c.build()
 		},
--- a/commands/commands_test.go
+++ b/commands/commands_test.go
@@ -23,6 +23,24 @@
 	"github.com/stretchr/testify/require"
 )
 
+func TestExecute(t *testing.T) {
+
+	assert := require.New(t)
+
+	dir, err := createSimpleTestSite(t)
+	assert.NoError(err)
+
+	defer func() {
+		os.RemoveAll(dir)
+	}()
+
+	resp := Execute([]string{"-s=" + dir})
+	assert.NoError(resp.Err)
+	result := resp.Result
+	assert.True(len(result.Sites) == 1)
+	assert.True(len(result.Sites[0].RegularPages) == 1)
+}
+
 func TestCommands(t *testing.T) {
 
 	assert := require.New(t)
@@ -72,7 +90,7 @@
 
 	for _, test := range tests {
 
-		hugoCmd := newHugoCompleteCmd()
+		hugoCmd := newHugoCompleteCmd().getCommand()
 		test.flags = append(test.flags, "--quiet")
 		hugoCmd.SetArgs(append(test.commands, test.flags...))
 
--- a/commands/hugo.go
+++ b/commands/hugo.go
@@ -51,20 +51,55 @@
 	jww "github.com/spf13/jwalterweatherman"
 )
 
-// TODO(bep) cli refactor consider a exported Hugo() method to fix the API
+// The Response value from Execute.
+type Response struct {
+	// The build Result will only be set in the hugo build command.
+	Result *hugolib.HugoSites
 
+	// Err is set when the command failed to execute.
+	Err error
+
+	// The command that was executed.
+	Cmd *cobra.Command
+}
+
+func (r Response) IsUserError() bool {
+	return r.Err != nil && isUserError(r.Err)
+}
+
 // Execute adds all child commands to the root command HugoCmd and sets flags appropriately.
-func Execute() {
+// The args are usually filled with os.Args[1:].
+func Execute(args []string) Response {
 	hugoCmd := newHugoCompleteCmd()
+	cmd := hugoCmd.getCommand()
+	cmd.SetArgs(args)
 
-	if c, err := hugoCmd.ExecuteC(); err != nil {
-		if isUserError(err) {
-			c.Println("")
-			c.Println(c.UsageString())
+	c, err := cmd.ExecuteC()
+
+	var resp Response
+
+	if c == cmd && hugoCmd.c != nil {
+		// Root command executed
+		resp.Result = hugoCmd.c.hugo
+	}
+
+	if err == nil {
+		errCount := jww.LogCountForLevelsGreaterThanorEqualTo(jww.LevelError)
+		if errCount > 0 {
+			err = fmt.Errorf("logged %d errors", errCount)
+		} else if resp.Result != nil {
+			errCount = resp.Result.Log.LogCountForLevelsGreaterThanorEqualTo(jww.LevelError)
+			if errCount > 0 {
+				err = fmt.Errorf("logged %d errors", errCount)
+			}
 		}
 
-		os.Exit(-1)
 	}
+
+	resp.Err = err
+	resp.Cmd = c
+
+	return resp
 }
 
 // InitializeConfig initializes a config file with sensible default configuration flags.
@@ -612,7 +647,6 @@
 
 func (c *commandeer) initSites() error {
 	if c.hugo != nil {
-		// TODO(bep) cli refactor check
 		c.hugo.Cfg = c.Cfg
 		c.hugo.Log.ResetLogCounters()
 		return nil
--- a/main.go
+++ b/main.go
@@ -19,22 +19,19 @@
 	"os"
 
 	"github.com/gohugoio/hugo/commands"
-	jww "github.com/spf13/jwalterweatherman"
 )
 
 func main() {
 
 	runtime.GOMAXPROCS(runtime.NumCPU())
-	commands.Execute()
+	resp := commands.Execute(os.Args[1:])
 
-	if jww.LogCountForLevelsGreaterThanorEqualTo(jww.LevelError) > 0 {
+	if resp.Err != nil {
+		if resp.IsUserError() {
+			resp.Cmd.Println("")
+			resp.Cmd.Println(resp.Cmd.UsageString())
+		}
 		os.Exit(-1)
 	}
 
-	// TODO(bep) cli refactor
-	/*if commands.Hugo != nil {
-		if commands.Hugo.Log.LogCountForLevelsGreaterThanorEqualTo(jww.LevelError) > 0 {
-			os.Exit(-1)
-		}
-	}*/
 }