commands: Fix config environment handling

Fixes #6503
Fixes #6824
This commit is contained in:
Bjørn Erik Pedersen 2020-01-31 09:09:11 +01:00
parent 0792cfa9fa
commit 2bbc865f7b
13 changed files with 211 additions and 204 deletions

View file

@ -47,12 +47,12 @@ func (b *commandsBuilder) addAll() *commandsBuilder {
b.newServerCmd(), b.newServerCmd(),
newVersionCmd(), newVersionCmd(),
newEnvCmd(), newEnvCmd(),
newConfigCmd(), b.newConfigCmd(),
newCheckCmd(), newCheckCmd(),
newDeployCmd(), b.newDeployCmd(),
newConvertCmd(), b.newConvertCmd(),
b.newNewCmd(), b.newNewCmd(),
newListCmd(), b.newListCmd(),
newImportCmd(), newImportCmd(),
newGenCmd(), newGenCmd(),
createReleaser(), createReleaser(),
@ -111,6 +111,12 @@ func (b *commandsBuilder) newBuilderCmd(cmd *cobra.Command) *baseBuilderCmd {
return bcmd return bcmd
} }
func (b *commandsBuilder) newBuilderBasicCmd(cmd *cobra.Command) *baseBuilderCmd {
bcmd := &baseBuilderCmd{commandsBuilder: b, baseCmd: &baseCmd{cmd: cmd}}
bcmd.hugoBuilderCommon.handleCommonBuilderFlags(cmd)
return bcmd
}
func (c *baseCmd) flagsToConfig(cfg config.Provider) { func (c *baseCmd) flagsToConfig(cfg config.Provider) {
initializeFlags(c.cmd, cfg) initializeFlags(c.cmd, cfg)
} }

View file

@ -20,6 +20,12 @@ import (
"path/filepath" "path/filepath"
"testing" "testing"
"github.com/gohugoio/hugo/htesting"
"github.com/spf13/afero"
"github.com/gohugoio/hugo/hugofs"
"github.com/gohugoio/hugo/common/types" "github.com/gohugoio/hugo/common/types"
"github.com/spf13/cobra" "github.com/spf13/cobra"
@ -32,18 +38,117 @@ func TestExecute(t *testing.T) {
c := qt.New(t) c := qt.New(t)
dir, err := createSimpleTestSite(t, testSiteConfig{}) createSite := func(c *qt.C) (string, func()) {
dir, clean, err := createSimpleTestSite(t, testSiteConfig{})
c.Assert(err, qt.IsNil)
return dir, clean
}
c.Run("hugo", func(c *qt.C) {
dir, clean := createSite(c)
defer clean()
resp := Execute([]string{"-s=" + dir})
c.Assert(resp.Err, qt.IsNil)
result := resp.Result
c.Assert(len(result.Sites) == 1, qt.Equals, true)
c.Assert(len(result.Sites[0].RegularPages()) == 1, qt.Equals, true)
c.Assert(result.Sites[0].Info.Params()["myparam"], qt.Equals, "paramproduction")
})
c.Run("hugo, set environment", func(c *qt.C) {
dir, clean := createSite(c)
defer clean()
resp := Execute([]string{"-s=" + dir, "-e=staging"})
c.Assert(resp.Err, qt.IsNil)
result := resp.Result
c.Assert(result.Sites[0].Info.Params()["myparam"], qt.Equals, "paramstaging")
})
c.Run("convert toJSON", func(c *qt.C) {
dir, clean := createSite(c)
output := filepath.Join(dir, "myjson")
defer clean()
resp := Execute([]string{"convert", "toJSON", "-s=" + dir, "-e=staging", "-o=" + output})
c.Assert(resp.Err, qt.IsNil)
converted := readFileFrom(c, filepath.Join(output, "content", "p1.md"))
c.Assert(converted, qt.Equals, "{\n \"title\": \"P1\",\n \"weight\": 1\n}\n\nContent\n\n", qt.Commentf(converted))
})
c.Run("config, set environment", func(c *qt.C) {
dir, clean := createSite(c)
defer clean()
out, err := captureStdout(func() error {
resp := Execute([]string{"config", "-s=" + dir, "-e=staging"})
return resp.Err
})
c.Assert(err, qt.IsNil)
c.Assert(out, qt.Contains, "params = map[myparam:paramstaging]", qt.Commentf(out))
})
c.Run("deploy, environment set", func(c *qt.C) {
dir, clean := createSite(c)
defer clean()
resp := Execute([]string{"deploy", "-s=" + dir, "-e=staging", "--target=mydeployment", "--dryRun"})
c.Assert(resp.Err, qt.Not(qt.IsNil))
c.Assert(resp.Err.Error(), qt.Contains, `no provider registered for "hugocloud"`)
})
c.Run("list", func(c *qt.C) {
dir, clean := createSite(c)
defer clean()
out, err := captureStdout(func() error {
resp := Execute([]string{"list", "all", "-s=" + dir, "-e=staging"})
return resp.Err
})
c.Assert(err, qt.IsNil)
c.Assert(out, qt.Contains, "p1.md")
})
c.Run("new theme", func(c *qt.C) {
dir, clean := createSite(c)
defer clean()
themesDir := filepath.Join(dir, "mythemes")
resp := Execute([]string{"new", "theme", "mytheme", "-s=" + dir, "-e=staging", "--themesDir=" + themesDir})
c.Assert(resp.Err, qt.IsNil)
themeTOML := readFileFrom(c, filepath.Join(themesDir, "mytheme", "theme.toml"))
c.Assert(themeTOML, qt.Contains, "name = \"Mytheme\"")
})
c.Run("new site", func(c *qt.C) {
dir, clean := createSite(c)
defer clean()
siteDir := filepath.Join(dir, "mysite")
resp := Execute([]string{"new", "site", siteDir, "-e=staging"})
c.Assert(resp.Err, qt.IsNil)
config := readFileFrom(c, filepath.Join(siteDir, "config.toml"))
c.Assert(config, qt.Contains, "baseURL = \"http://example.org/\"")
checkNewSiteInited(c, siteDir)
})
}
func checkNewSiteInited(c *qt.C, basepath string) {
paths := []string{
filepath.Join(basepath, "layouts"),
filepath.Join(basepath, "content"),
filepath.Join(basepath, "archetypes"),
filepath.Join(basepath, "static"),
filepath.Join(basepath, "data"),
filepath.Join(basepath, "config.toml"),
}
for _, path := range paths {
_, err := os.Stat(path)
c.Assert(err, qt.IsNil)
}
}
func readFileFrom(c *qt.C, filename string) string {
c.Helper()
filename = filepath.Clean(filename)
b, err := afero.ReadFile(hugofs.Os, filename)
c.Assert(err, qt.IsNil) c.Assert(err, qt.IsNil)
return string(b)
defer func() {
os.RemoveAll(dir)
}()
resp := Execute([]string{"-s=" + dir})
c.Assert(resp.Err, qt.IsNil)
result := resp.Result
c.Assert(len(result.Sites) == 1, qt.Equals, true)
c.Assert(len(result.Sites[0].RegularPages()) == 1, qt.Equals, true)
} }
func TestCommandsPersistentFlags(t *testing.T) { func TestCommandsPersistentFlags(t *testing.T) {
@ -146,16 +251,14 @@ func TestCommandsExecute(t *testing.T) {
c := qt.New(t) c := qt.New(t)
dir, err := createSimpleTestSite(t, testSiteConfig{}) dir, clean, err := createSimpleTestSite(t, testSiteConfig{})
c.Assert(err, qt.IsNil) c.Assert(err, qt.IsNil)
dirOut, err := ioutil.TempDir("", "hugo-cli-out") dirOut, clean2, err := htesting.CreateTempDir(hugofs.Os, "hugo-cli-out")
c.Assert(err, qt.IsNil) c.Assert(err, qt.IsNil)
defer func() { defer clean()
os.RemoveAll(dir) defer clean2()
os.RemoveAll(dirOut)
}()
sourceFlag := fmt.Sprintf("-s=%s", dir) sourceFlag := fmt.Sprintf("-s=%s", dir)
@ -222,10 +325,10 @@ type testSiteConfig struct {
contentDir string contentDir string
} }
func createSimpleTestSite(t *testing.T, cfg testSiteConfig) (string, error) { func createSimpleTestSite(t *testing.T, cfg testSiteConfig) (string, func(), error) {
d, e := ioutil.TempDir("", "hugo-cli") d, clean, e := htesting.CreateTempDir(hugofs.Os, "hugo-cli")
if e != nil { if e != nil {
return "", e return "", nil, e
} }
cfgStr := ` cfgStr := `
@ -233,6 +336,7 @@ func createSimpleTestSite(t *testing.T, cfg testSiteConfig) (string, error) {
baseURL = "https://example.org" baseURL = "https://example.org"
title = "Hugo Commands" title = "Hugo Commands"
` `
contentDir := "content" contentDir := "content"
@ -244,8 +348,19 @@ title = "Hugo Commands"
contentDir = cfg.contentDir contentDir = cfg.contentDir
} }
os.MkdirAll(filepath.Join(d, "public"), 0777)
// Just the basic. These are for CLI tests, not site testing. // Just the basic. These are for CLI tests, not site testing.
writeFile(t, filepath.Join(d, "config.toml"), cfgStr) writeFile(t, filepath.Join(d, "config.toml"), cfgStr)
writeFile(t, filepath.Join(d, "config", "staging", "params.toml"), `myparam="paramstaging"`)
writeFile(t, filepath.Join(d, "config", "staging", "deployment.toml"), `
[[targets]]
name = "mydeployment"
URL = "hugocloud://hugotestbucket"
`)
writeFile(t, filepath.Join(d, "config", "testing", "params.toml"), `myparam="paramtesting"`)
writeFile(t, filepath.Join(d, "config", "production", "params.toml"), `myparam="paramproduction"`)
writeFile(t, filepath.Join(d, contentDir, "p1.md"), ` writeFile(t, filepath.Join(d, contentDir, "p1.md"), `
--- ---
@ -270,7 +385,7 @@ Environment: {{ hugo.Environment }}
`) `)
return d, nil return d, clean, nil
} }

View file

@ -15,6 +15,7 @@ package commands
import ( import (
"encoding/json" "encoding/json"
"fmt"
"os" "os"
"reflect" "reflect"
"regexp" "regexp"
@ -27,27 +28,23 @@ import (
"github.com/gohugoio/hugo/modules" "github.com/gohugoio/hugo/modules"
"github.com/spf13/cobra" "github.com/spf13/cobra"
jww "github.com/spf13/jwalterweatherman"
"github.com/spf13/viper" "github.com/spf13/viper"
) )
var _ cmder = (*configCmd)(nil) var _ cmder = (*configCmd)(nil)
type configCmd struct { type configCmd struct {
hugoBuilderCommon *baseBuilderCmd
*baseCmd
} }
func newConfigCmd() *configCmd { func (b *commandsBuilder) newConfigCmd() *configCmd {
cc := &configCmd{} cc := &configCmd{}
cc.baseCmd = newBaseCmd(&cobra.Command{ cmd := &cobra.Command{
Use: "config", Use: "config",
Short: "Print the site configuration", Short: "Print the site configuration",
Long: `Print the site configuration, both default and custom settings.`, Long: `Print the site configuration, both default and custom settings.`,
RunE: cc.printConfig, RunE: cc.printConfig,
}) }
cc.cmd.PersistentFlags().StringVarP(&cc.source, "source", "s", "", "filesystem path to read files relative from")
printMountsCmd := &cobra.Command{ printMountsCmd := &cobra.Command{
Use: "mounts", Use: "mounts",
@ -55,7 +52,9 @@ func newConfigCmd() *configCmd {
RunE: cc.printMounts, RunE: cc.printMounts,
} }
cc.cmd.AddCommand(printMountsCmd) cmd.AddCommand(printMountsCmd)
cc.baseBuilderCmd = b.newBuilderBasicCmd(cmd)
return cc return cc
} }
@ -105,9 +104,9 @@ func (c *configCmd) printConfig(cmd *cobra.Command, args []string) error {
for _, k := range keys { for _, k := range keys {
kv := reflect.ValueOf(allSettings[k]) kv := reflect.ValueOf(allSettings[k])
if kv.Kind() == reflect.String { if kv.Kind() == reflect.String {
jww.FEEDBACK.Printf("%s%s\"%+v\"\n", k, separator, allSettings[k]) fmt.Printf("%s%s\"%+v\"\n", k, separator, allSettings[k])
} else { } else {
jww.FEEDBACK.Printf("%s%s%+v\n", k, separator, allSettings[k]) fmt.Printf("%s%s%+v\n", k, separator, allSettings[k])
} }
} }

View file

@ -44,27 +44,25 @@ var (
) )
type convertCmd struct { type convertCmd struct {
hugoBuilderCommon
outputDir string outputDir string
unsafe bool unsafe bool
*baseCmd *baseBuilderCmd
} }
func newConvertCmd() *convertCmd { func (b *commandsBuilder) newConvertCmd() *convertCmd {
cc := &convertCmd{} cc := &convertCmd{}
cc.baseCmd = newBaseCmd(&cobra.Command{ cmd := &cobra.Command{
Use: "convert", Use: "convert",
Short: "Convert your content to different formats", Short: "Convert your content to different formats",
Long: `Convert your content (e.g. front matter) to different formats. Long: `Convert your content (e.g. front matter) to different formats.
See convert's subcommands toJSON, toTOML and toYAML for more information.`, See convert's subcommands toJSON, toTOML and toYAML for more information.`,
RunE: nil, RunE: nil,
}) }
cc.cmd.AddCommand( cmd.AddCommand(
&cobra.Command{ &cobra.Command{
Use: "toJSON", Use: "toJSON",
Short: "Convert front matter to JSON", Short: "Convert front matter to JSON",
@ -94,10 +92,10 @@ to use YAML for the front matter.`,
}, },
) )
cc.cmd.PersistentFlags().StringVarP(&cc.outputDir, "output", "o", "", "filesystem path to write files to") cmd.PersistentFlags().StringVarP(&cc.outputDir, "output", "o", "", "filesystem path to write files to")
cc.cmd.PersistentFlags().StringVarP(&cc.source, "source", "s", "", "filesystem path to read files relative from") cmd.PersistentFlags().BoolVar(&cc.unsafe, "unsafe", false, "enable less safe operations, please backup first")
cc.cmd.PersistentFlags().BoolVar(&cc.unsafe, "unsafe", false, "enable less safe operations, please backup first")
cc.cmd.PersistentFlags().SetAnnotation("source", cobra.BashCompSubdirsInDir, []string{}) cc.baseBuilderCmd = b.newBuilderBasicCmd(cmd)
return cc return cc
} }

View file

@ -24,8 +24,7 @@ var _ cmder = (*deployCmd)(nil)
// deployCmd supports deploying sites to Cloud providers. // deployCmd supports deploying sites to Cloud providers.
type deployCmd struct { type deployCmd struct {
hugoBuilderCommon *baseBuilderCmd
*baseCmd
} }
// TODO: In addition to the "deploy" command, consider adding a "--deploy" // TODO: In addition to the "deploy" command, consider adding a "--deploy"
@ -38,10 +37,10 @@ type deployCmd struct {
// run "hugo && hugo deploy" again and again and upload new stuff every time. Is // run "hugo && hugo deploy" again and again and upload new stuff every time. Is
// this intended? // this intended?
func newDeployCmd() *deployCmd { func (b *commandsBuilder) newDeployCmd() *deployCmd {
cc := &deployCmd{} cc := &deployCmd{}
cc.baseCmd = newBaseCmd(&cobra.Command{ cmd := &cobra.Command{
Use: "deploy", Use: "deploy",
Short: "Deploy your site to a Cloud provider.", Short: "Deploy your site to a Cloud provider.",
Long: `Deploy your site to a Cloud provider. Long: `Deploy your site to a Cloud provider.
@ -64,14 +63,16 @@ documentation.
} }
return deployer.Deploy(context.Background()) return deployer.Deploy(context.Background())
}, },
}) }
cc.cmd.Flags().String("target", "", "target deployment from deployments section in config file; defaults to the first one") cmd.Flags().String("target", "", "target deployment from deployments section in config file; defaults to the first one")
cc.cmd.Flags().Bool("confirm", false, "ask for confirmation before making changes to the target") cmd.Flags().Bool("confirm", false, "ask for confirmation before making changes to the target")
cc.cmd.Flags().Bool("dryRun", false, "dry run") cmd.Flags().Bool("dryRun", false, "dry run")
cc.cmd.Flags().Bool("force", false, "force upload of all files") cmd.Flags().Bool("force", false, "force upload of all files")
cc.cmd.Flags().Bool("invalidateCDN", true, "invalidate the CDN cache listed in the deployment target") cmd.Flags().Bool("invalidateCDN", true, "invalidate the CDN cache listed in the deployment target")
cc.cmd.Flags().Int("maxDeletes", 256, "maximum # of files to delete, or -1 to disable") cmd.Flags().Int("maxDeletes", 256, "maximum # of files to delete, or -1 to disable")
cc.baseBuilderCmd = b.newBuilderBasicCmd(cmd)
return cc return cc
} }

View file

@ -14,7 +14,6 @@
package commands package commands
import ( import (
"os"
"testing" "testing"
qt "github.com/frankban/quicktest" qt "github.com/frankban/quicktest"
@ -37,12 +36,9 @@ title = "Hugo Commands"
contentDir = "thisdoesnotexist" contentDir = "thisdoesnotexist"
` `
dir, err := createSimpleTestSite(t, testSiteConfig{configTOML: cfgStr, contentDir: contentDir}) dir, clean, err := createSimpleTestSite(t, testSiteConfig{configTOML: cfgStr, contentDir: contentDir})
c.Assert(err, qt.IsNil) c.Assert(err, qt.IsNil)
defer clean()
defer func() {
os.RemoveAll(dir)
}()
cmd.SetArgs([]string{"-s=" + dir, "-c=" + contentDir}) cmd.SetArgs([]string{"-s=" + dir, "-c=" + contentDir})

View file

@ -29,8 +29,7 @@ import (
var _ cmder = (*listCmd)(nil) var _ cmder = (*listCmd)(nil)
type listCmd struct { type listCmd struct {
hugoBuilderCommon *baseBuilderCmd
*baseCmd
} }
func (lc *listCmd) buildSites(config map[string]interface{}) (*hugolib.HugoSites, error) { func (lc *listCmd) buildSites(config map[string]interface{}) (*hugolib.HugoSites, error) {
@ -59,19 +58,19 @@ func (lc *listCmd) buildSites(config map[string]interface{}) (*hugolib.HugoSites
return sites, nil return sites, nil
} }
func newListCmd() *listCmd { func (b *commandsBuilder) newListCmd() *listCmd {
cc := &listCmd{} cc := &listCmd{}
cc.baseCmd = newBaseCmd(&cobra.Command{ cmd := &cobra.Command{
Use: "list", Use: "list",
Short: "Listing out various types of content", Short: "Listing out various types of content",
Long: `Listing out various types of content. Long: `Listing out various types of content.
List requires a subcommand, e.g. ` + "`hugo list drafts`.", List requires a subcommand, e.g. ` + "`hugo list drafts`.",
RunE: nil, RunE: nil,
}) }
cc.cmd.AddCommand( cmd.AddCommand(
&cobra.Command{ &cobra.Command{
Use: "drafts", Use: "drafts",
Short: "List all drafts", Short: "List all drafts",
@ -202,8 +201,7 @@ List requires a subcommand, e.g. ` + "`hugo list drafts`.",
}, },
) )
cc.cmd.PersistentFlags().StringVarP(&cc.source, "source", "s", "", "filesystem path to read files relative from") cc.baseBuilderCmd = b.newBuilderBasicCmd(cmd)
cc.cmd.PersistentFlags().SetAnnotation("source", cobra.BashCompSubdirsInDir, []string{})
return cc return cc
} }

View file

@ -10,31 +10,27 @@ import (
"testing" "testing"
qt "github.com/frankban/quicktest" qt "github.com/frankban/quicktest"
"github.com/spf13/cobra"
) )
func captureStdout(f func() (*cobra.Command, error)) (string, error) { func captureStdout(f func() error) (string, error) {
old := os.Stdout old := os.Stdout
r, w, _ := os.Pipe() r, w, _ := os.Pipe()
os.Stdout = w os.Stdout = w
_, err := f() err := f()
if err != nil {
return "", err
}
w.Close() w.Close()
os.Stdout = old os.Stdout = old
var buf bytes.Buffer var buf bytes.Buffer
io.Copy(&buf, r) io.Copy(&buf, r)
return buf.String(), nil return buf.String(), err
} }
func TestListAll(t *testing.T) { func TestListAll(t *testing.T) {
c := qt.New(t) c := qt.New(t)
dir, err := createSimpleTestSite(t, testSiteConfig{}) dir, clean, err := createSimpleTestSite(t, testSiteConfig{})
defer clean()
c.Assert(err, qt.IsNil) c.Assert(err, qt.IsNil)
@ -47,7 +43,10 @@ func TestListAll(t *testing.T) {
cmd.SetArgs([]string{"-s=" + dir, "list", "all"}) cmd.SetArgs([]string{"-s=" + dir, "list", "all"})
out, err := captureStdout(cmd.ExecuteC) out, err := captureStdout(func() error {
_, err := cmd.ExecuteC()
return err
})
c.Assert(err, qt.IsNil) c.Assert(err, qt.IsNil)
r := csv.NewReader(strings.NewReader(out)) r := csv.NewReader(strings.NewReader(out))

View file

@ -55,8 +55,8 @@ Ensure you run this within the root directory of your site.`,
cmd.Flags().StringVarP(&cc.contentType, "kind", "k", "", "content type to create") cmd.Flags().StringVarP(&cc.contentType, "kind", "k", "", "content type to create")
cmd.Flags().StringVar(&cc.contentEditor, "editor", "", "edit new content with this editor, if provided") cmd.Flags().StringVar(&cc.contentEditor, "editor", "", "edit new content with this editor, if provided")
cmd.AddCommand(newNewSiteCmd().getCommand()) cmd.AddCommand(b.newNewSiteCmd().getCommand())
cmd.AddCommand(newNewThemeCmd().getCommand()) cmd.AddCommand(b.newNewThemeCmd().getCommand())
cmd.RunE = cc.newContent cmd.RunE = cc.newContent

View file

@ -17,9 +17,6 @@ import (
"path/filepath" "path/filepath"
"testing" "testing"
"github.com/gohugoio/hugo/hugofs"
"github.com/spf13/viper"
qt "github.com/frankban/quicktest" qt "github.com/frankban/quicktest"
) )
@ -30,105 +27,3 @@ func TestNewContentPathSectionWithForwardSlashes(t *testing.T) {
c.Assert(p, qt.Equals, filepath.FromSlash("/post/new.md")) c.Assert(p, qt.Equals, filepath.FromSlash("/post/new.md"))
c.Assert(s, qt.Equals, "post") c.Assert(s, qt.Equals, "post")
} }
func checkNewSiteInited(fs *hugofs.Fs, basepath string, t *testing.T) {
c := qt.New(t)
paths := []string{
filepath.Join(basepath, "layouts"),
filepath.Join(basepath, "content"),
filepath.Join(basepath, "archetypes"),
filepath.Join(basepath, "static"),
filepath.Join(basepath, "data"),
filepath.Join(basepath, "config.toml"),
}
for _, path := range paths {
_, err := fs.Source.Stat(path)
c.Assert(err, qt.IsNil)
}
}
func TestDoNewSite(t *testing.T) {
c := qt.New(t)
n := newNewSiteCmd()
basepath := filepath.Join("base", "blog")
_, fs := newTestCfg()
c.Assert(n.doNewSite(fs, basepath, false), qt.IsNil)
checkNewSiteInited(fs, basepath, t)
}
func TestDoNewSite_noerror_base_exists_but_empty(t *testing.T) {
c := qt.New(t)
basepath := filepath.Join("base", "blog")
_, fs := newTestCfg()
n := newNewSiteCmd()
c.Assert(fs.Source.MkdirAll(basepath, 0777), qt.IsNil)
c.Assert(n.doNewSite(fs, basepath, false), qt.IsNil)
}
func TestDoNewSite_error_base_exists(t *testing.T) {
c := qt.New(t)
basepath := filepath.Join("base", "blog")
_, fs := newTestCfg()
n := newNewSiteCmd()
c.Assert(fs.Source.MkdirAll(basepath, 0777), qt.IsNil)
_, err := fs.Source.Create(filepath.Join(basepath, "foo"))
c.Assert(err, qt.IsNil)
// Since the directory already exists and isn't empty, expect an error
c.Assert(n.doNewSite(fs, basepath, false), qt.Not(qt.IsNil))
}
func TestDoNewSite_force_empty_dir(t *testing.T) {
c := qt.New(t)
basepath := filepath.Join("base", "blog")
_, fs := newTestCfg()
n := newNewSiteCmd()
c.Assert(fs.Source.MkdirAll(basepath, 0777), qt.IsNil)
c.Assert(n.doNewSite(fs, basepath, true), qt.IsNil)
checkNewSiteInited(fs, basepath, t)
}
func TestDoNewSite_error_force_dir_inside_exists(t *testing.T) {
c := qt.New(t)
basepath := filepath.Join("base", "blog")
_, fs := newTestCfg()
n := newNewSiteCmd()
contentPath := filepath.Join(basepath, "content")
c.Assert(fs.Source.MkdirAll(contentPath, 0777), qt.IsNil)
c.Assert(n.doNewSite(fs, basepath, true), qt.Not(qt.IsNil))
}
func TestDoNewSite_error_force_config_inside_exists(t *testing.T) {
c := qt.New(t)
basepath := filepath.Join("base", "blog")
_, fs := newTestCfg()
n := newNewSiteCmd()
configPath := filepath.Join(basepath, "config.toml")
c.Assert(fs.Source.MkdirAll(basepath, 0777), qt.IsNil)
_, err := fs.Source.Create(configPath)
c.Assert(err, qt.IsNil)
c.Assert(n.doNewSite(fs, basepath, true), qt.Not(qt.IsNil))
}
func newTestCfg() (*viper.Viper, *hugofs.Fs) {
v := viper.New()
fs := hugofs.NewMem(v)
v.SetFs(fs.Source)
return v, fs
}

View file

@ -37,11 +37,11 @@ var _ cmder = (*newSiteCmd)(nil)
type newSiteCmd struct { type newSiteCmd struct {
configFormat string configFormat string
*baseCmd *baseBuilderCmd
} }
func newNewSiteCmd() *newSiteCmd { func (b *commandsBuilder) newNewSiteCmd() *newSiteCmd {
ccmd := &newSiteCmd{} cc := &newSiteCmd{}
cmd := &cobra.Command{ cmd := &cobra.Command{
Use: "site [path]", Use: "site [path]",
@ -49,15 +49,15 @@ func newNewSiteCmd() *newSiteCmd {
Long: `Create a new site in the provided directory. Long: `Create a new site in the provided directory.
The new site will have the correct structure, but no content or theme yet. The new site will have the correct structure, but no content or theme yet.
Use ` + "`hugo new [contentPath]`" + ` to create new content.`, Use ` + "`hugo new [contentPath]`" + ` to create new content.`,
RunE: ccmd.newSite, RunE: cc.newSite,
} }
cmd.Flags().StringVarP(&ccmd.configFormat, "format", "f", "toml", "config & frontmatter format") cmd.Flags().StringVarP(&cc.configFormat, "format", "f", "toml", "config & frontmatter format")
cmd.Flags().Bool("force", false, "init inside non-empty directory") cmd.Flags().Bool("force", false, "init inside non-empty directory")
ccmd.baseCmd = newBaseCmd(cmd) cc.baseBuilderCmd = b.newBuilderBasicCmd(cmd)
return ccmd return cc
} }

View file

@ -29,12 +29,11 @@ import (
var _ cmder = (*newThemeCmd)(nil) var _ cmder = (*newThemeCmd)(nil)
type newThemeCmd struct { type newThemeCmd struct {
*baseCmd *baseBuilderCmd
hugoBuilderCommon
} }
func newNewThemeCmd() *newThemeCmd { func (b *commandsBuilder) newNewThemeCmd() *newThemeCmd {
ccmd := &newThemeCmd{baseCmd: newBaseCmd(nil)} cc := &newThemeCmd{}
cmd := &cobra.Command{ cmd := &cobra.Command{
Use: "theme [name]", Use: "theme [name]",
@ -43,12 +42,12 @@ func newNewThemeCmd() *newThemeCmd {
New theme is a skeleton. Please add content to the touched files. Add your New theme is a skeleton. Please add content to the touched files. Add your
name to the copyright line in the license and adjust the theme.toml file name to the copyright line in the license and adjust the theme.toml file
as you see fit.`, as you see fit.`,
RunE: ccmd.newTheme, RunE: cc.newTheme,
} }
ccmd.cmd = cmd cc.baseBuilderCmd = b.newBuilderBasicCmd(cmd)
return ccmd return cc
} }
// newTheme creates a new Hugo theme template // newTheme creates a new Hugo theme template

View file

@ -34,7 +34,8 @@ func TestServer(t *testing.T) {
t.Skip("Skip server test on appveyor") t.Skip("Skip server test on appveyor")
} }
c := qt.New(t) c := qt.New(t)
dir, err := createSimpleTestSite(t, testSiteConfig{}) dir, clean, err := createSimpleTestSite(t, testSiteConfig{})
defer clean()
c.Assert(err, qt.IsNil) c.Assert(err, qt.IsNil)
// Let us hope that this port is available on all systems ... // Let us hope that this port is available on all systems ...