shithub: hugo

Download patch

ref: 5b4b8bb3c1ecb30e7a38ed44eb795f1d972cd320
parent: 2278b0eb02ccdd3c2d4358d39074767d33fecb71
author: Ruslan Nasonov <[email protected]>
date: Sat May 4 17:21:21 EDT 2019

commands: Create new 'hugo list all' command

New:
- command `hugo list all`, return all posts meta in csv format

Refactoring:
- move common parts in commands/list.go to function `buildSites`
- change way to detect path to content

See #5904

--- a/commands/list.go
+++ b/commands/list.go
@@ -16,7 +16,8 @@
 import (
 	"encoding/csv"
 	"os"
-	"path/filepath"
+	"strconv"
+	"strings"
 	"time"
 
 	"github.com/gohugoio/hugo/hugolib"
@@ -32,6 +33,32 @@
 	*baseCmd
 }
 
+func (lc *listCmd) buildSites(config map[string]interface{}) (*hugolib.HugoSites, error) {
+	cfgInit := func(c *commandeer) error {
+		for key, value := range config {
+			c.Set(key, value)
+		}
+		return nil
+	}
+
+	c, err := initializeConfig(true, false, &lc.hugoBuilderCommon, lc, cfgInit)
+	if err != nil {
+		return nil, err
+	}
+
+	sites, err := hugolib.NewHugoSites(*c.DepsCfg)
+
+	if err != nil {
+		return nil, newSystemError("Error creating sites", err)
+	}
+
+	if err := sites.Build(hugolib.BuildCfg{SkipRender: true}); err != nil {
+		return nil, newSystemError("Error Processing Source Content", err)
+	}
+
+	return sites, nil
+}
+
 func newListCmd() *listCmd {
 	cc := &listCmd{}
 
@@ -50,67 +77,41 @@
 			Short: "List all drafts",
 			Long:  `List all of the drafts in your content directory.`,
 			RunE: func(cmd *cobra.Command, args []string) error {
-				cfgInit := func(c *commandeer) error {
-					c.Set("buildDrafts", true)
-					return nil
-				}
-				c, err := initializeConfig(true, false, &cc.hugoBuilderCommon, cc, cfgInit)
-				if err != nil {
-					return err
-				}
+				sites, err := cc.buildSites(map[string]interface{}{"buildDrafts": true})
 
-				sites, err := hugolib.NewHugoSites(*c.DepsCfg)
-
 				if err != nil {
-					return newSystemError("Error creating sites", err)
+					return newSystemError("Error building sites", err)
 				}
 
-				if err := sites.Build(hugolib.BuildCfg{SkipRender: true}); err != nil {
-					return newSystemError("Error Processing Source Content", err)
-				}
-
 				for _, p := range sites.Pages() {
 					if p.Draft() {
-						jww.FEEDBACK.Println(filepath.Join(p.File().Dir(), p.File().LogicalName()))
+						jww.FEEDBACK.Println(strings.TrimPrefix(p.File().Filename(), sites.WorkingDir+string(os.PathSeparator)))
 					}
-
 				}
 
 				return nil
-
 			},
 		},
 		&cobra.Command{
 			Use:   "future",
 			Short: "List all posts dated in the future",
-			Long: `List all of the posts in your content directory which will be
-posted in the future.`,
+			Long:  `List all of the posts in your content directory which will be posted in the future.`,
 			RunE: func(cmd *cobra.Command, args []string) error {
-				cfgInit := func(c *commandeer) error {
-					c.Set("buildFuture", true)
-					return nil
-				}
-				c, err := initializeConfig(true, false, &cc.hugoBuilderCommon, cc, cfgInit)
-				if err != nil {
-					return err
-				}
+				sites, err := cc.buildSites(map[string]interface{}{"buildFuture": true})
 
-				sites, err := hugolib.NewHugoSites(*c.DepsCfg)
-
 				if err != nil {
-					return newSystemError("Error creating sites", err)
+					return newSystemError("Error building sites", err)
 				}
 
-				if err := sites.Build(hugolib.BuildCfg{SkipRender: true}); err != nil {
-					return newSystemError("Error Processing Source Content", err)
-				}
-
 				writer := csv.NewWriter(os.Stdout)
 				defer writer.Flush()
 
 				for _, p := range sites.Pages() {
 					if resource.IsFuture(p) {
-						err := writer.Write([]string{filepath.Join(p.File().Dir(), p.File().LogicalName()), p.PublishDate().Format(time.RFC3339)})
+						err := writer.Write([]string{
+							strings.TrimPrefix(p.File().Filename(), sites.WorkingDir+string(os.PathSeparator)),
+							p.PublishDate().Format(time.RFC3339),
+						})
 						if err != nil {
 							return newSystemError("Error writing future posts to stdout", err)
 						}
@@ -118,49 +119,85 @@
 				}
 
 				return nil
-
 			},
 		},
 		&cobra.Command{
 			Use:   "expired",
 			Short: "List all posts already expired",
-			Long: `List all of the posts in your content directory which has already
-expired.`,
+			Long:  `List all of the posts in your content directory which has already expired.`,
 			RunE: func(cmd *cobra.Command, args []string) error {
-				cfgInit := func(c *commandeer) error {
-					c.Set("buildExpired", true)
-					return nil
-				}
-				c, err := initializeConfig(true, false, &cc.hugoBuilderCommon, cc, cfgInit)
-				if err != nil {
-					return err
-				}
+				sites, err := cc.buildSites(map[string]interface{}{"buildExpired": true})
 
-				sites, err := hugolib.NewHugoSites(*c.DepsCfg)
-
 				if err != nil {
-					return newSystemError("Error creating sites", err)
+					return newSystemError("Error building sites", err)
 				}
 
-				if err := sites.Build(hugolib.BuildCfg{SkipRender: true}); err != nil {
-					return newSystemError("Error Processing Source Content", err)
-				}
-
 				writer := csv.NewWriter(os.Stdout)
 				defer writer.Flush()
 
 				for _, p := range sites.Pages() {
 					if resource.IsExpired(p) {
-						err := writer.Write([]string{filepath.Join(p.File().Dir(), p.File().LogicalName()), p.ExpiryDate().Format(time.RFC3339)})
+						err := writer.Write([]string{
+							strings.TrimPrefix(p.File().Filename(), sites.WorkingDir+string(os.PathSeparator)),
+							p.ExpiryDate().Format(time.RFC3339),
+						})
 						if err != nil {
 							return newSystemError("Error writing expired posts to stdout", err)
 						}
-
 					}
 				}
 
 				return nil
+			},
+		},
+		&cobra.Command{
+			Use:   "all",
+			Short: "List all posts",
+			Long:  `List all of the posts in your content directory, include drafts, future and expired pages.`,
+			RunE: func(cmd *cobra.Command, args []string) error {
+				sites, err := cc.buildSites(map[string]interface{}{
+					"buildExpired": true,
+					"buildDrafts":  true,
+					"buildFuture":  true,
+				})
 
+				if err != nil {
+					return newSystemError("Error building sites", err)
+				}
+
+				writer := csv.NewWriter(os.Stdout)
+				defer writer.Flush()
+
+				writer.Write([]string{
+					"path",
+					"slug",
+					"title",
+					"date",
+					"expiryDate",
+					"publishDate",
+					"draft",
+					"permalink",
+				})
+				for _, p := range sites.Pages() {
+					if !p.IsPage() {
+						continue
+					}
+					err := writer.Write([]string{
+						strings.TrimPrefix(p.File().Filename(), sites.WorkingDir+string(os.PathSeparator)),
+						p.Slug(),
+						p.Title(),
+						p.Date().Format(time.RFC3339),
+						p.ExpiryDate().Format(time.RFC3339),
+						p.PublishDate().Format(time.RFC3339),
+						strconv.FormatBool(p.Draft()),
+						p.Permalink(),
+					})
+					if err != nil {
+						return newSystemError("Error writing posts to stdout", err)
+					}
+				}
+
+				return nil
 			},
 		},
 	)
--- /dev/null
+++ b/commands/list_test.go
@@ -1,0 +1,70 @@
+package commands
+
+import (
+	"bytes"
+	"encoding/csv"
+	"io"
+	"os"
+	"path/filepath"
+	"strings"
+	"testing"
+
+	"github.com/spf13/cobra"
+	"github.com/stretchr/testify/require"
+)
+
+func captureStdout(f func() (*cobra.Command, error)) (string, error) {
+	old := os.Stdout
+	r, w, _ := os.Pipe()
+	os.Stdout = w
+
+	_, err := f()
+
+	if err != nil {
+		return "", err
+	}
+
+	w.Close()
+	os.Stdout = old
+
+	var buf bytes.Buffer
+	io.Copy(&buf, r)
+	return buf.String(), nil
+}
+
+func TestListAll(t *testing.T) {
+	assert := require.New(t)
+	dir, err := createSimpleTestSite(t, testSiteConfig{})
+
+	assert.NoError(err)
+
+	hugoCmd := newCommandsBuilder().addAll().build()
+	cmd := hugoCmd.getCommand()
+
+	defer func() {
+		os.RemoveAll(dir)
+	}()
+
+	cmd.SetArgs([]string{"-s=" + dir, "list", "all"})
+
+	out, err := captureStdout(cmd.ExecuteC)
+	assert.NoError(err)
+
+	r := csv.NewReader(strings.NewReader(out))
+
+	header, err := r.Read()
+	assert.NoError(err)
+
+	assert.Equal([]string{
+		"path", "slug", "title",
+		"date", "expiryDate", "publishDate",
+		"draft", "permalink",
+	}, header)
+
+	record, err := r.Read()
+	assert.Equal([]string{
+		filepath.Join("content", "p1.md"), "", "P1",
+		"0001-01-01T00:00:00Z", "0001-01-01T00:00:00Z", "0001-01-01T00:00:00Z",
+		"false", "https://example.org/p1/",
+	}, record)
+}