Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/gohugoio/hugo.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>2019-01-02 14:33:26 +0300
committerBjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>2019-03-23 20:51:22 +0300
commit597e418cb02883418f2cebb41400e8e61413f651 (patch)
tree177ad9c540b2583b6dab138c9f0490d28989c7f7 /commands
parent44f5c1c14cb1f42cc5f01739c289e9cfc83602af (diff)
Make Page an interface
The main motivation of this commit is to add a `page.Page` interface to replace the very file-oriented `hugolib.Page` struct. This is all a preparation step for issue #5074, "pages from other data sources". But this also fixes a set of annoying limitations, especially related to custom output formats, and shortcodes. Most notable changes: * The inner content of shortcodes using the `{{%` as the outer-most delimiter will now be sent to the content renderer, e.g. Blackfriday. This means that any markdown will partake in the global ToC and footnote context etc. * The Custom Output formats are now "fully virtualized". This removes many of the current limitations. * The taxonomy list type now has a reference to the `Page` object. This improves the taxonomy template `.Title` situation and make common template constructs much simpler. See #5074 Fixes #5763 Fixes #5758 Fixes #5090 Fixes #5204 Fixes #4695 Fixes #5607 Fixes #5707 Fixes #5719 Fixes #3113 Fixes #5706 Fixes #5767 Fixes #5723 Fixes #5769 Fixes #5770 Fixes #5771 Fixes #5759 Fixes #5776 Fixes #5777 Fixes #5778
Diffstat (limited to 'commands')
-rw-r--r--commands/commandeer.go9
-rw-r--r--commands/commands.go20
-rw-r--r--commands/commands_test.go21
-rw-r--r--commands/convert.go22
-rw-r--r--commands/hugo.go169
-rw-r--r--commands/import_jekyll.go10
-rw-r--r--commands/list.go14
-rw-r--r--commands/new_content_test.go12
-rw-r--r--commands/server.go10
9 files changed, 232 insertions, 55 deletions
diff --git a/commands/commandeer.go b/commands/commandeer.go
index 8abb6418d..8c9da53b9 100644
--- a/commands/commandeer.go
+++ b/commands/commandeer.go
@@ -1,4 +1,4 @@
-// Copyright 2018 The Hugo Authors. All rights reserved.
+// Copyright 2019 The Hugo Authors. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -357,6 +357,13 @@ func (c *commandeer) loadConfig(mustHaveConfigFile, running bool) error {
c.changeDetector = changeDetector
}
+ if c.Cfg.GetBool("logPathWarnings") {
+ fs.Destination = hugofs.NewCreateCountingFs(fs.Destination)
+ }
+
+ // To debug hard-to-find path issues.
+ //fs.Destination = hugofs.NewStacktracerFs(fs.Destination, `fr/fr`)
+
err = c.initFs(fs)
if err != nil {
return
diff --git a/commands/commands.go b/commands/commands.go
index 38291fd95..fa02b2e81 100644
--- a/commands/commands.go
+++ b/commands/commands.go
@@ -1,4 +1,4 @@
-// Copyright 2017 The Hugo Authors. All rights reserved.
+// Copyright 2019 The Hugo Authors. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -23,7 +23,6 @@ import (
"github.com/gohugoio/hugo/config"
"github.com/gohugoio/hugo/helpers"
"github.com/spf13/cobra"
- "github.com/spf13/nitro"
)
type commandsBuilder struct {
@@ -197,6 +196,12 @@ type hugoBuilderCommon struct {
gc bool
+ // Profile flags (for debugging of performance problems)
+ cpuprofile string
+ memprofile string
+ mutexprofile string
+ traceprofile string
+
// TODO(bep) var vs string
logging bool
verbose bool
@@ -255,13 +260,22 @@ func (cc *hugoBuilderCommon) handleFlags(cmd *cobra.Command) {
cmd.Flags().Bool("enableGitInfo", false, "add Git revision, date and author info to the pages")
cmd.Flags().BoolVar(&cc.gc, "gc", false, "enable to run some cleanup tasks (remove unused cache files) after the build")
- cmd.Flags().BoolVar(&nitro.AnalysisOn, "stepAnalysis", false, "display memory and timing of different steps of the program")
cmd.Flags().Bool("templateMetrics", false, "display metrics about template executions")
cmd.Flags().Bool("templateMetricsHints", false, "calculate some improvement hints when combined with --templateMetrics")
cmd.Flags().BoolP("forceSyncStatic", "", false, "copy all files when static is changed.")
cmd.Flags().BoolP("noTimes", "", false, "don't sync modification time of files")
cmd.Flags().BoolP("noChmod", "", false, "don't sync permission mode of files")
cmd.Flags().BoolP("i18n-warnings", "", false, "print missing translations")
+ cmd.Flags().BoolP("path-warnings", "", false, "print warnings on duplicate target paths etc.")
+ cmd.Flags().StringVarP(&cc.cpuprofile, "profile-cpu", "", "", "write cpu profile to `file`")
+ cmd.Flags().StringVarP(&cc.memprofile, "profile-mem", "", "", "write memory profile to `file`")
+ cmd.Flags().StringVarP(&cc.mutexprofile, "profile-mutex", "", "", "write Mutex profile to `file`")
+ cmd.Flags().StringVarP(&cc.traceprofile, "trace", "", "", "write trace to `file` (not useful in general)")
+
+ // Hide these for now.
+ cmd.Flags().MarkHidden("profile-cpu")
+ cmd.Flags().MarkHidden("profile-mem")
+ cmd.Flags().MarkHidden("profile-mutex")
cmd.Flags().StringSlice("disableKinds", []string{}, "disable different kind of pages (home, RSS etc.)")
diff --git a/commands/commands_test.go b/commands/commands_test.go
index 2e8b99dc4..a1c6cdd76 100644
--- a/commands/commands_test.go
+++ b/commands/commands_test.go
@@ -1,4 +1,4 @@
-// Copyright 2018 The Hugo Authors. All rights reserved.
+// Copyright 2019 The Hugo Authors. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -20,6 +20,8 @@ import (
"path/filepath"
"testing"
+ "github.com/gohugoio/hugo/common/types"
+
"github.com/spf13/cobra"
"github.com/spf13/viper"
@@ -41,7 +43,7 @@ func TestExecute(t *testing.T) {
assert.NoError(resp.Err)
result := resp.Result
assert.True(len(result.Sites) == 1)
- assert.True(len(result.Sites[0].RegularPages) == 1)
+ assert.True(len(result.Sites[0].RegularPages()) == 1)
}
func TestCommandsPersistentFlags(t *testing.T) {
@@ -75,6 +77,7 @@ func TestCommandsPersistentFlags(t *testing.T) {
"--port=1366",
"--renderToDisk",
"--source=mysource",
+ "--path-warnings",
}, func(commands []cmder) {
var sc *serverCmd
for _, command := range commands {
@@ -112,6 +115,9 @@ func TestCommandsPersistentFlags(t *testing.T) {
assert.True(cfg.GetBool("gc"))
+ // The flag is named path-warnings
+ assert.True(cfg.GetBool("logPathWarnings"))
+
// The flag is named i18n-warnings
assert.True(cfg.GetBool("logI18nWarnings"))
@@ -183,8 +189,8 @@ func TestCommandsExecute(t *testing.T) {
}
for _, test := range tests {
-
- hugoCmd := newCommandsBuilder().addAll().build().getCommand()
+ b := newCommandsBuilder().addAll().build()
+ hugoCmd := b.getCommand()
test.flags = append(test.flags, "--quiet")
hugoCmd.SetArgs(append(test.commands, test.flags...))
@@ -200,6 +206,13 @@ func TestCommandsExecute(t *testing.T) {
assert.NoError(err, fmt.Sprintf("%v", test.commands))
}
+ // Assert that we have not left any development debug artifacts in
+ // the code.
+ if b.c != nil {
+ _, ok := b.c.destinationFs.(types.DevMarker)
+ assert.False(ok)
+ }
+
}
}
diff --git a/commands/convert.go b/commands/convert.go
index c4f88a245..e7ba572bc 100644
--- a/commands/convert.go
+++ b/commands/convert.go
@@ -1,4 +1,4 @@
-// Copyright 2015 The Hugo Authors. All rights reserved.
+// Copyright 2019 The Hugo Authors. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -20,6 +20,8 @@ import (
"strings"
"time"
+ "github.com/gohugoio/hugo/resources/page"
+
"github.com/gohugoio/hugo/hugofs"
"github.com/gohugoio/hugo/helpers"
@@ -124,8 +126,8 @@ func (cc *convertCmd) convertContents(format metadecoders.Format) error {
site := h.Sites[0]
- site.Log.FEEDBACK.Println("processing", len(site.AllPages), "content files")
- for _, p := range site.AllPages {
+ site.Log.FEEDBACK.Println("processing", len(site.AllPages()), "content files")
+ for _, p := range site.AllPages() {
if err := cc.convertAndSavePage(p, site, format); err != nil {
return err
}
@@ -133,24 +135,24 @@ func (cc *convertCmd) convertContents(format metadecoders.Format) error {
return nil
}
-func (cc *convertCmd) convertAndSavePage(p *hugolib.Page, site *hugolib.Site, targetFormat metadecoders.Format) error {
+func (cc *convertCmd) convertAndSavePage(p page.Page, site *hugolib.Site, targetFormat metadecoders.Format) error {
// The resources are not in .Site.AllPages.
- for _, r := range p.Resources.ByType("page") {
- if err := cc.convertAndSavePage(r.(*hugolib.Page), site, targetFormat); err != nil {
+ for _, r := range p.Resources().ByType("page") {
+ if err := cc.convertAndSavePage(r.(page.Page), site, targetFormat); err != nil {
return err
}
}
- if p.Filename() == "" {
+ if p.File() == nil {
// No content file.
return nil
}
errMsg := fmt.Errorf("Error processing file %q", p.Path())
- site.Log.INFO.Println("Attempting to convert", p.LogicalName())
+ site.Log.INFO.Println("Attempting to convert", p.File().Filename())
- f, _ := p.File.(src.ReadableFile)
+ f, _ := p.File().(src.ReadableFile)
file, err := f.Open()
if err != nil {
site.Log.ERROR.Println(errMsg)
@@ -186,7 +188,7 @@ func (cc *convertCmd) convertAndSavePage(p *hugolib.Page, site *hugolib.Site, ta
newContent.Write(pf.content)
- newFilename := p.Filename()
+ newFilename := p.File().Filename()
if cc.outputDir != "" {
contentDir := strings.TrimSuffix(newFilename, p.Path())
diff --git a/commands/hugo.go b/commands/hugo.go
index 3690c0ad5..4ca0eff69 100644
--- a/commands/hugo.go
+++ b/commands/hugo.go
@@ -1,4 +1,4 @@
-// Copyright 2018 The Hugo Authors. All rights reserved.
+// Copyright 2019 The Hugo Authors. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -18,11 +18,16 @@ package commands
import (
"fmt"
"io/ioutil"
-
"os/signal"
+ "runtime/pprof"
+ "runtime/trace"
"sort"
"sync/atomic"
+ "github.com/gohugoio/hugo/hugofs"
+
+ "github.com/gohugoio/hugo/resources/page"
+
"github.com/gohugoio/hugo/common/hugo"
"github.com/pkg/errors"
@@ -214,6 +219,7 @@ func initializeFlags(cmd *cobra.Command, cfg config.Provider) {
"themesDir",
"verbose",
"verboseLog",
+ "duplicateTargetPaths",
}
// Will set a value even if it is the default.
@@ -235,6 +241,7 @@ func initializeFlags(cmd *cobra.Command, cfg config.Provider) {
// Set some "config aliases"
setValueFromFlag(cmd.Flags(), "destination", cfg, "publishDir", false)
setValueFromFlag(cmd.Flags(), "i18n-warnings", cfg, "logI18nWarnings", false)
+ setValueFromFlag(cmd.Flags(), "path-warnings", cfg, "logPathWarnings", false)
}
@@ -290,6 +297,7 @@ func (c *commandeer) fullBuild() error {
}
copyStaticFunc := func() error {
+
cnt, err := c.copyStatic()
if err != nil {
if !os.IsNotExist(err) {
@@ -326,7 +334,7 @@ func (c *commandeer) fullBuild() error {
}
for _, s := range c.hugo.Sites {
- s.ProcessingStats.Static = langCount[s.Language.Lang]
+ s.ProcessingStats.Static = langCount[s.Language().Lang]
}
if c.h.gc {
@@ -344,9 +352,125 @@ func (c *commandeer) fullBuild() error {
}
+func (c *commandeer) initCPUProfile() (func(), error) {
+ if c.h.cpuprofile == "" {
+ return nil, nil
+ }
+
+ f, err := os.Create(c.h.cpuprofile)
+ if err != nil {
+ return nil, errors.Wrap(err, "failed to create CPU profile")
+ }
+ if err := pprof.StartCPUProfile(f); err != nil {
+ return nil, errors.Wrap(err, "failed to start CPU profile")
+ }
+ return func() {
+ pprof.StopCPUProfile()
+ f.Close()
+ }, nil
+}
+
+func (c *commandeer) initMemProfile() {
+ if c.h.memprofile == "" {
+ return
+ }
+
+ f, err := os.Create(c.h.memprofile)
+ if err != nil {
+ c.logger.ERROR.Println("could not create memory profile: ", err)
+ }
+ defer f.Close()
+ runtime.GC() // get up-to-date statistics
+ if err := pprof.WriteHeapProfile(f); err != nil {
+ c.logger.ERROR.Println("could not write memory profile: ", err)
+ }
+}
+
+func (c *commandeer) initTraceProfile() (func(), error) {
+ if c.h.traceprofile == "" {
+ return nil, nil
+ }
+
+ f, err := os.Create(c.h.traceprofile)
+ if err != nil {
+ return nil, errors.Wrap(err, "failed to create trace file")
+ }
+
+ if err := trace.Start(f); err != nil {
+ return nil, errors.Wrap(err, "failed to start trace")
+ }
+
+ return func() {
+ trace.Stop()
+ f.Close()
+ }, nil
+}
+
+func (c *commandeer) initMutexProfile() (func(), error) {
+ if c.h.mutexprofile == "" {
+ return nil, nil
+ }
+
+ f, err := os.Create(c.h.mutexprofile)
+ if err != nil {
+ return nil, err
+ }
+
+ runtime.SetMutexProfileFraction(1)
+
+ return func() {
+ pprof.Lookup("mutex").WriteTo(f, 0)
+ f.Close()
+ }, nil
+
+}
+
+func (c *commandeer) initProfiling() (func(), error) {
+ stopCPUProf, err := c.initCPUProfile()
+ if err != nil {
+ return nil, err
+ }
+
+ defer c.initMemProfile()
+
+ stopMutexProf, err := c.initMutexProfile()
+ if err != nil {
+ return nil, err
+ }
+
+ stopTraceProf, err := c.initTraceProfile()
+ if err != nil {
+ return nil, err
+ }
+
+ return func() {
+ if stopCPUProf != nil {
+ stopCPUProf()
+ }
+ if stopMutexProf != nil {
+ stopMutexProf()
+ }
+
+ if stopTraceProf != nil {
+ stopTraceProf()
+ }
+ }, nil
+}
+
func (c *commandeer) build() error {
defer c.timeTrack(time.Now(), "Total")
+ stopProfiling, err := c.initProfiling()
+ if err != nil {
+ return err
+ }
+
+ defer func() {
+ if stopProfiling != nil {
+ stopProfiling()
+ }
+ }()
+
if err := c.fullBuild(); err != nil {
return err
}
@@ -356,6 +480,13 @@ func (c *commandeer) build() error {
fmt.Println()
c.hugo.PrintProcessingStats(os.Stdout)
fmt.Println()
+
+ if createCounter, ok := c.destinationFs.(hugofs.DuplicatesReporter); ok {
+ dupes := createCounter.ReportDuplicates()
+ if dupes != "" {
+ c.logger.WARN.Println("Duplicate target paths:", dupes)
+ }
+ }
}
if c.h.buildWatch {
@@ -369,7 +500,7 @@ func (c *commandeer) build() error {
checkErr(c.Logger, err)
defer watcher.Close()
- var sigs = make(chan os.Signal)
+ var sigs = make(chan os.Signal, 1)
signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM)
<-sigs
@@ -381,6 +512,17 @@ func (c *commandeer) build() error {
func (c *commandeer) serverBuild() error {
defer c.timeTrack(time.Now(), "Total")
+ stopProfiling, err := c.initProfiling()
+ if err != nil {
+ return err
+ }
+
+ defer func() {
+ if stopProfiling != nil {
+ stopProfiling()
+ }
+ }()
+
if err := c.fullBuild(); err != nil {
return err
}
@@ -474,11 +616,9 @@ func (c *commandeer) copyStaticTo(sourceFs *filesystems.SourceFilesystem) (uint6
}
c.logger.INFO.Println("syncing static files to", publishDir)
- var err error
-
// because we are using a baseFs (to get the union right).
// set sync src to root
- err = syncer.Sync(publishDir, helpers.FilePathSeparator)
+ err := syncer.Sync(publishDir, helpers.FilePathSeparator)
if err != nil {
return 0, err
}
@@ -619,13 +759,6 @@ func (c *commandeer) getDirList() ([]string, error) {
return a, nil
}
-func (c *commandeer) resetAndBuildSites() (err error) {
- if !c.h.quiet {
- c.logger.FEEDBACK.Println("Started building sites ...")
- }
- return c.hugo.Build(hugolib.BuildCfg{ResetState: true})
-}
-
func (c *commandeer) buildSites() (err error) {
return c.hugo.Build(hugolib.BuildCfg{})
}
@@ -973,7 +1106,7 @@ func (c *commandeer) handleEvents(watcher *watcher.Batcher,
navigate := c.Cfg.GetBool("navigateToChanged")
// We have fetched the same page above, but it may have
// changed.
- var p *hugolib.Page
+ var p page.Page
if navigate {
if onePageName != "" {
@@ -982,7 +1115,7 @@ func (c *commandeer) handleEvents(watcher *watcher.Batcher,
}
if p != nil {
- livereload.NavigateToPathForPort(p.RelPermalink(), p.Site.ServerPort())
+ livereload.NavigateToPathForPort(p.RelPermalink(), p.Site().ServerPort())
} else {
livereload.ForceRefresh()
}
@@ -1044,9 +1177,11 @@ func (c *commandeer) isThemeVsHugoVersionMismatch(fs afero.Fs) (dir string, mism
}
b, err := afero.ReadFile(fs, path)
+ if err != nil {
+ continue
+ }
tomlMeta, err := metadecoders.Default.UnmarshalToMap(b, metadecoders.TOML)
-
if err != nil {
continue
}
diff --git a/commands/import_jekyll.go b/commands/import_jekyll.go
index d3301b48f..1d37cfd9d 100644
--- a/commands/import_jekyll.go
+++ b/commands/import_jekyll.go
@@ -1,4 +1,4 @@
-// Copyright 2016 The Hugo Authors. All rights reserved.
+// Copyright 2019 The Hugo Authors. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -340,7 +340,7 @@ func copyDir(source string, dest string) error {
if err != nil {
return err
}
- entries, err := ioutil.ReadDir(source)
+ entries, _ := ioutil.ReadDir(source)
for _, entry := range entries {
sfp := filepath.Join(source, entry.Name())
dfp := filepath.Join(dest, entry.Name())
@@ -373,6 +373,10 @@ func (i *importCmd) copyJekyllFilesAndFolders(jekyllRoot, dest string, jekyllPos
return err
}
entries, err := ioutil.ReadDir(jekyllRoot)
+ if err != nil {
+ return err
+ }
+
for _, entry := range entries {
sfp := filepath.Join(jekyllRoot, entry.Name())
dfp := filepath.Join(dest, entry.Name())
@@ -464,7 +468,7 @@ func convertJekyllPost(s *hugolib.Site, path, relPath, targetDir string, draft b
fs := hugofs.Os
if err := helpers.WriteToDisk(targetFile, strings.NewReader(content), fs); err != nil {
- return fmt.Errorf("Failed to save file %q:", filename)
+ return fmt.Errorf("failed to save file %q: %s", filename, err)
}
return nil
diff --git a/commands/list.go b/commands/list.go
index f49726b62..99e9afe40 100644
--- a/commands/list.go
+++ b/commands/list.go
@@ -1,4 +1,4 @@
-// Copyright 2015 The Hugo Authors. All rights reserved.
+// Copyright 2019 The Hugo Authors. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -20,6 +20,7 @@ import (
"time"
"github.com/gohugoio/hugo/hugolib"
+ "github.com/gohugoio/hugo/resources/resource"
"github.com/spf13/cobra"
jww "github.com/spf13/jwalterweatherman"
)
@@ -70,7 +71,7 @@ List requires a subcommand, e.g. ` + "`hugo list drafts`.",
for _, p := range sites.Pages() {
if p.IsDraft() {
- jww.FEEDBACK.Println(filepath.Join(p.File.Dir(), p.File.LogicalName()))
+ jww.FEEDBACK.Println(filepath.Join(p.File().Dir(), p.File().LogicalName()))
}
}
@@ -108,8 +109,8 @@ posted in the future.`,
defer writer.Flush()
for _, p := range sites.Pages() {
- if p.IsFuture() {
- err := writer.Write([]string{filepath.Join(p.File.Dir(), p.File.LogicalName()), p.PublishDate.Format(time.RFC3339)})
+ if resource.IsFuture(p) {
+ err := writer.Write([]string{filepath.Join(p.File().Dir(), p.File().LogicalName()), p.PublishDate().Format(time.RFC3339)})
if err != nil {
return newSystemError("Error writing future posts to stdout", err)
}
@@ -149,11 +150,12 @@ expired.`,
defer writer.Flush()
for _, p := range sites.Pages() {
- if p.IsExpired() {
- err := writer.Write([]string{filepath.Join(p.File.Dir(), p.File.LogicalName()), p.ExpiryDate.Format(time.RFC3339)})
+ if resource.IsExpired(p) {
+ err := writer.Write([]string{filepath.Join(p.File().Dir(), p.File().LogicalName()), p.ExpiryDate().Format(time.RFC3339)})
if err != nil {
return newSystemError("Error writing expired posts to stdout", err)
}
+
}
}
diff --git a/commands/new_content_test.go b/commands/new_content_test.go
index fb8bca7b4..5a55094d6 100644
--- a/commands/new_content_test.go
+++ b/commands/new_content_test.go
@@ -1,4 +1,4 @@
-// Copyright 2018 The Hugo Authors. All rights reserved.
+// Copyright 2019 The Hugo Authors. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -62,7 +62,7 @@ func TestDoNewSite_noerror_base_exists_but_empty(t *testing.T) {
_, fs := newTestCfg()
n := newNewSiteCmd()
- require.NoError(t, fs.Source.MkdirAll(basepath, 777))
+ require.NoError(t, fs.Source.MkdirAll(basepath, 0777))
require.NoError(t, n.doNewSite(fs, basepath, false))
}
@@ -72,7 +72,7 @@ func TestDoNewSite_error_base_exists(t *testing.T) {
_, fs := newTestCfg()
n := newNewSiteCmd()
- require.NoError(t, fs.Source.MkdirAll(basepath, 777))
+ require.NoError(t, fs.Source.MkdirAll(basepath, 0777))
_, err := fs.Source.Create(filepath.Join(basepath, "foo"))
require.NoError(t, err)
// Since the directory already exists and isn't empty, expect an error
@@ -85,7 +85,7 @@ func TestDoNewSite_force_empty_dir(t *testing.T) {
_, fs := newTestCfg()
n := newNewSiteCmd()
- require.NoError(t, fs.Source.MkdirAll(basepath, 777))
+ require.NoError(t, fs.Source.MkdirAll(basepath, 0777))
require.NoError(t, n.doNewSite(fs, basepath, true))
@@ -99,7 +99,7 @@ func TestDoNewSite_error_force_dir_inside_exists(t *testing.T) {
contentPath := filepath.Join(basepath, "content")
- require.NoError(t, fs.Source.MkdirAll(contentPath, 777))
+ require.NoError(t, fs.Source.MkdirAll(contentPath, 0777))
require.Error(t, n.doNewSite(fs, basepath, true))
}
@@ -109,7 +109,7 @@ func TestDoNewSite_error_force_config_inside_exists(t *testing.T) {
n := newNewSiteCmd()
configPath := filepath.Join(basepath, "config.toml")
- require.NoError(t, fs.Source.MkdirAll(basepath, 777))
+ require.NoError(t, fs.Source.MkdirAll(basepath, 0777))
_, err := fs.Source.Create(configPath)
require.NoError(t, err)
diff --git a/commands/server.go b/commands/server.go
index c2bd76dae..5d50ebe2c 100644
--- a/commands/server.go
+++ b/commands/server.go
@@ -1,4 +1,4 @@
-// Copyright 2018 The Hugo Authors. All rights reserved.
+// Copyright 2019 The Hugo Authors. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -358,7 +358,7 @@ func (f *fileServer) createEndpoint(i int) (*http.ServeMux, string, string, erro
if err := f.c.partialReRender(p); err != nil {
f.c.handleBuildErr(err, fmt.Sprintf("Failed to render %q", p))
if f.c.showErrorInBrowser {
- http.Redirect(w, r, p, 301)
+ http.Redirect(w, r, p, http.StatusMovedPermanently)
return
}
}
@@ -386,7 +386,7 @@ func (f *fileServer) createEndpoint(i int) (*http.ServeMux, string, string, erro
return mu, u.String(), endpoint, nil
}
-var logErrorRe = regexp.MustCompile("(?s)ERROR \\d{4}/\\d{2}/\\d{2} \\d{2}:\\d{2}:\\d{2} ")
+var logErrorRe = regexp.MustCompile(`(?s)ERROR \d{4}/\d{2}/\d{2} \d{2}:\d{2}:\d{2} `)
func removeErrorPrefixFromLog(content string) string {
return logErrorRe.ReplaceAllLiteralString(content, "")
@@ -403,7 +403,7 @@ func (c *commandeer) serve(s *serverCmd) error {
if isMultiHost {
for _, s := range c.hugo.Sites {
baseURLs = append(baseURLs, s.BaseURL.String())
- roots = append(roots, s.Language.Lang)
+ roots = append(roots, s.Language().Lang)
}
} else {
s := c.hugo.Sites[0]
@@ -430,7 +430,7 @@ func (c *commandeer) serve(s *serverCmd) error {
livereload.Initialize()
}
- var sigs = make(chan os.Signal)
+ var sigs = make(chan os.Signal, 1)
signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM)
for i := range baseURLs {