mirror of
https://github.com/gohugoio/hugo.git
synced 2025-08-20 21:31:32 +02:00
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
This commit is contained in:
@@ -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
|
||||
|
@@ -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.)")
|
||||
|
||||
|
@@ -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)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -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())
|
||||
|
169
commands/hugo.go
169
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
|
||||
}
|
||||
|
@@ -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
|
||||
|
@@ -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)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -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)
|
||||
|
||||
|
@@ -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 {
|
||||
|
Reference in New Issue
Block a user