summaryrefslogtreecommitdiffstats
path: root/commands
diff options
context:
space:
mode:
authorBjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>2022-03-21 09:35:15 +0100
committerBjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>2022-04-08 13:26:17 +0200
commitd070bdf10f14d233288f7318a4e9f7555f070a65 (patch)
treefff8d59f98bdab3027bb45c4e10ca88594332872 /commands
parentb08193971a821fc27e549a73120c15e5e5186775 (diff)
Rework the Destination filesystem to make --renderStaticToDisk work
See #9626
Diffstat (limited to 'commands')
-rw-r--r--commands/commandeer.go78
-rw-r--r--commands/commands.go9
-rw-r--r--commands/commands_test.go124
-rw-r--r--commands/hugo.go12
-rw-r--r--commands/hugo_test.go6
-rw-r--r--commands/list_test.go5
-rw-r--r--commands/new_site.go6
-rw-r--r--commands/server.go18
-rw-r--r--commands/server_test.go12
-rw-r--r--commands/static_syncer.go21
10 files changed, 155 insertions, 136 deletions
diff --git a/commands/commandeer.go b/commands/commandeer.go
index ced149e7a..1162a4b70 100644
--- a/commands/commandeer.go
+++ b/commands/commandeer.go
@@ -30,6 +30,7 @@ import (
"github.com/gohugoio/hugo/common/herrors"
"github.com/gohugoio/hugo/common/hugo"
+ "github.com/gohugoio/hugo/common/paths"
jww "github.com/spf13/jwalterweatherman"
@@ -42,6 +43,7 @@ import (
"github.com/spf13/afero"
"github.com/bep/debounce"
+ "github.com/bep/overlayfs"
"github.com/gohugoio/hugo/common/types"
"github.com/gohugoio/hugo/deps"
"github.com/gohugoio/hugo/helpers"
@@ -73,8 +75,10 @@ type commandeer struct {
// be fast enough that we could maybe just add it for all server modes.
changeDetector *fileChangeDetector
- // We need to reuse this on server rebuilds.
- destinationFs afero.Fs
+ // We need to reuse these on server rebuilds.
+ // These 2 will be different if --renderStaticToDisk is set.
+ publishDirFs afero.Fs
+ publishDirServerFs afero.Fs
h *hugoBuilderCommon
ftch flagsToConfigHandler
@@ -162,7 +166,8 @@ func (c *commandeer) Set(key string, value any) {
}
func (c *commandeer) initFs(fs *hugofs.Fs) error {
- c.destinationFs = fs.Destination
+ c.publishDirFs = fs.PublishDir
+ c.publishDirServerFs = fs.PublishDirServer
c.DepsCfg.Fs = fs
return nil
@@ -378,28 +383,63 @@ func (c *commandeer) loadConfig() error {
createMemFs := config.GetBool("renderToMemory")
c.renderStaticToDisk = config.GetBool("renderStaticToDisk")
- if createMemFs && !c.renderStaticToDisk {
+ if createMemFs {
// Rendering to memoryFS, publish to Root regardless of publishDir.
config.Set("publishDir", "/")
+ config.Set("publishDirStatic", "/")
+ } else if c.renderStaticToDisk {
+ // Hybrid, render dynamic content to Root.
+ config.Set("publishDirStatic", config.Get("publishDir"))
+ config.Set("publishDir", "/")
+
}
c.fsCreate.Do(func() {
fs := hugofs.NewFrom(sourceFs, config)
- if c.destinationFs != nil {
+ if c.publishDirFs != nil {
// Need to reuse the destination on server rebuilds.
- fs.Destination = c.destinationFs
- } else if createMemFs && c.renderStaticToDisk {
- // Writes the dynamic output on memory,
- // while serve others directly from publishDir
+ fs.PublishDir = c.publishDirFs
+ fs.PublishDirServer = c.publishDirServerFs
+ } else {
publishDir := config.GetString("publishDir")
- writableFs := afero.NewBasePathFs(afero.NewMemMapFs(), publishDir)
- publicFs := afero.NewOsFs()
- fs.Destination = afero.NewCopyOnWriteFs(afero.NewReadOnlyFs(publicFs), writableFs)
- fs.DestinationStatic = publicFs
- } else if createMemFs {
- // Hugo writes the output to memory instead of the disk.
- fs.Destination = new(afero.MemMapFs)
+ publishDirStatic := config.GetString("publishDirStatic")
+ workingDir := config.GetString("workingDir")
+ absPublishDir := paths.AbsPathify(workingDir, publishDir)
+ absPublishDirStatic := paths.AbsPathify(workingDir, publishDirStatic)
+
+ if c.renderStaticToDisk {
+ // Writes the dynamic output oton memory,
+ // while serve others directly from /public on disk.
+ dynamicFs := afero.NewMemMapFs()
+ staticFs := afero.NewBasePathFs(afero.NewOsFs(), absPublishDirStatic)
+
+ // Serve from both the static and dynamic fs,
+ // the first will take priority.
+ // THis is a read-only filesystem,
+ // we do all the writes to
+ // fs.Destination and fs.DestinationStatic.
+ fs.PublishDirServer = overlayfs.New(
+ overlayfs.Options{
+ Fss: []afero.Fs{
+ dynamicFs,
+ staticFs,
+ },
+ },
+ )
+ fs.PublishDir = dynamicFs
+ fs.PublishDirStatic = staticFs
+ } else if createMemFs {
+ // Hugo writes the output to memory instead of the disk.
+ fs.PublishDir = new(afero.MemMapFs)
+ fs.PublishDirServer = fs.PublishDir
+ fs.PublishDirStatic = fs.PublishDir
+ } else {
+ // Write everything to disk.
+ fs.PublishDir = afero.NewBasePathFs(afero.NewOsFs(), absPublishDir)
+ fs.PublishDirServer = fs.PublishDir
+ fs.PublishDirStatic = fs.PublishDir
+ }
}
if c.fastRenderMode {
@@ -413,15 +453,15 @@ func (c *commandeer) loadConfig() error {
}
changeDetector.PrepareNew()
- fs.Destination = hugofs.NewHashingFs(fs.Destination, changeDetector)
- fs.DestinationStatic = hugofs.NewHashingFs(fs.DestinationStatic, changeDetector)
+ fs.PublishDir = hugofs.NewHashingFs(fs.PublishDir, changeDetector)
+ fs.PublishDirStatic = hugofs.NewHashingFs(fs.PublishDirStatic, changeDetector)
c.changeDetector = changeDetector
}
if c.Cfg.GetBool("logPathWarnings") {
// Note that we only care about the "dynamic creates" here,
// so skip the static fs.
- fs.Destination = hugofs.NewCreateCountingFs(fs.Destination)
+ fs.PublishDir = hugofs.NewCreateCountingFs(fs.PublishDir)
}
// To debug hard-to-find path issues.
diff --git a/commands/commands.go b/commands/commands.go
index 01f076d1a..99b0866e5 100644
--- a/commands/commands.go
+++ b/commands/commands.go
@@ -18,10 +18,9 @@ import (
"os"
"time"
- "github.com/gohugoio/hugo/hugolib/paths"
-
"github.com/gohugoio/hugo/common/hugo"
"github.com/gohugoio/hugo/common/loggers"
+ hpaths "github.com/gohugoio/hugo/common/paths"
"github.com/gohugoio/hugo/config"
"github.com/gohugoio/hugo/helpers"
"github.com/spf13/cobra"
@@ -243,14 +242,14 @@ func (cc *hugoBuilderCommon) timeTrack(start time.Time, name string) {
func (cc *hugoBuilderCommon) getConfigDir(baseDir string) string {
if cc.cfgDir != "" {
- return paths.AbsPathify(baseDir, cc.cfgDir)
+ return hpaths.AbsPathify(baseDir, cc.cfgDir)
}
if v, found := os.LookupEnv("HUGO_CONFIGDIR"); found {
- return paths.AbsPathify(baseDir, v)
+ return hpaths.AbsPathify(baseDir, v)
}
- return paths.AbsPathify(baseDir, "config")
+ return hpaths.AbsPathify(baseDir, "config")
}
func (cc *hugoBuilderCommon) getEnvironment(isServer bool) string {
diff --git a/commands/commands_test.go b/commands/commands_test.go
index 43c7f8520..e3ec7bd99 100644
--- a/commands/commands_test.go
+++ b/commands/commands_test.go
@@ -22,8 +22,6 @@ import (
"github.com/gohugoio/hugo/config"
- "github.com/gohugoio/hugo/htesting"
-
"github.com/spf13/afero"
"github.com/gohugoio/hugo/hugofs"
@@ -38,15 +36,13 @@ import (
func TestExecute(t *testing.T) {
c := qt.New(t)
- createSite := func(c *qt.C) (string, func()) {
- dir, clean, err := createSimpleTestSite(t, testSiteConfig{})
- c.Assert(err, qt.IsNil)
- return dir, clean
+ createSite := func(c *qt.C) string {
+ dir := createSimpleTestSite(t, testSiteConfig{})
+ return dir
}
c.Run("hugo", func(c *qt.C) {
- dir, clean := createSite(c)
- defer clean()
+ dir := createSite(c)
resp := Execute([]string{"-s=" + dir})
c.Assert(resp.Err, qt.IsNil)
result := resp.Result
@@ -56,8 +52,7 @@ func TestExecute(t *testing.T) {
})
c.Run("hugo, set environment", func(c *qt.C) {
- dir, clean := createSite(c)
- defer clean()
+ dir := createSite(c)
resp := Execute([]string{"-s=" + dir, "-e=staging"})
c.Assert(resp.Err, qt.IsNil)
result := resp.Result
@@ -65,9 +60,8 @@ func TestExecute(t *testing.T) {
})
c.Run("convert toJSON", func(c *qt.C) {
- dir, clean := createSite(c)
+ dir := 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"))
@@ -75,8 +69,7 @@ func TestExecute(t *testing.T) {
})
c.Run("config, set environment", func(c *qt.C) {
- dir, clean := createSite(c)
- defer clean()
+ dir := createSite(c)
out, err := captureStdout(func() error {
resp := Execute([]string{"config", "-s=" + dir, "-e=staging"})
return resp.Err
@@ -86,16 +79,14 @@ func TestExecute(t *testing.T) {
})
c.Run("deploy, environment set", func(c *qt.C) {
- dir, clean := createSite(c)
- defer clean()
+ dir := createSite(c)
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 driver registered for "hugocloud"`)
})
c.Run("list", func(c *qt.C) {
- dir, clean := createSite(c)
- defer clean()
+ dir := createSite(c)
out, err := captureStdout(func() error {
resp := Execute([]string{"list", "all", "-s=" + dir, "-e=staging"})
return resp.Err
@@ -105,8 +96,7 @@ func TestExecute(t *testing.T) {
})
c.Run("new theme", func(c *qt.C) {
- dir, clean := createSite(c)
- defer clean()
+ dir := createSite(c)
themesDir := filepath.Join(dir, "mythemes")
resp := Execute([]string{"new", "theme", "mytheme", "-s=" + dir, "-e=staging", "--themesDir=" + themesDir})
c.Assert(resp.Err, qt.IsNil)
@@ -115,8 +105,7 @@ func TestExecute(t *testing.T) {
})
c.Run("new site", func(c *qt.C) {
- dir, clean := createSite(c)
- defer clean()
+ dir := createSite(c)
siteDir := filepath.Join(dir, "mysite")
resp := Execute([]string{"new", "site", siteDir, "-e=staging"})
c.Assert(resp.Err, qt.IsNil)
@@ -167,7 +156,7 @@ func TestFlags(t *testing.T) {
name: "ignoreVendorPaths",
args: []string{"server", "--ignoreVendorPaths=github.com/**"},
check: func(c *qt.C, cmd *serverCmd) {
- cfg := config.New()
+ cfg := config.NewWithTestDefaults()
cmd.flagsToConfig(cfg)
c.Assert(cfg.Get("ignoreVendorPaths"), qt.Equals, "github.com/**")
},
@@ -208,7 +197,7 @@ func TestFlags(t *testing.T) {
c.Assert(sc.serverPort, qt.Equals, 1366)
c.Assert(sc.environment, qt.Equals, "testing")
- cfg := config.New()
+ cfg := config.NewWithTestDefaults()
sc.flagsToConfig(cfg)
c.Assert(cfg.GetString("publishDir"), qt.Equals, "/tmp/mydestination")
c.Assert(cfg.GetString("contentDir"), qt.Equals, "mycontent")
@@ -253,14 +242,8 @@ func TestFlags(t *testing.T) {
func TestCommandsExecute(t *testing.T) {
c := qt.New(t)
- dir, clean, err := createSimpleTestSite(t, testSiteConfig{})
- c.Assert(err, qt.IsNil)
-
- dirOut, clean2, err := htesting.CreateTempDir(hugofs.Os, "hugo-cli-out")
- c.Assert(err, qt.IsNil)
-
- defer clean()
- defer clean2()
+ dir := createSimpleTestSite(t, testSiteConfig{})
+ dirOut := t.TempDir()
sourceFlag := fmt.Sprintf("-s=%s", dir)
@@ -297,29 +280,35 @@ func TestCommandsExecute(t *testing.T) {
}
for _, test := range tests {
- b := newCommandsBuilder().addAll().build()
- hugoCmd := b.getCommand()
- test.flags = append(test.flags, "--quiet")
- hugoCmd.SetArgs(append(test.commands, test.flags...))
-
- // TODO(bep) capture output and add some simple asserts
- // TODO(bep) misspelled subcommands does not return an error. We should investigate this
- // but before that, check for "Error: unknown command".
-
- _, err := hugoCmd.ExecuteC()
- if test.expectErrToContain != "" {
- c.Assert(err, qt.Not(qt.IsNil))
- c.Assert(err.Error(), qt.Contains, test.expectErrToContain)
- } else {
- c.Assert(err, qt.IsNil)
+ name := "hugo"
+ if len(test.commands) > 0 {
+ name = test.commands[0]
}
+ c.Run(name, func(c *qt.C) {
+ b := newCommandsBuilder().addAll().build()
+ hugoCmd := b.getCommand()
+ test.flags = append(test.flags, "--quiet")
+ hugoCmd.SetArgs(append(test.commands, test.flags...))
+
+ // TODO(bep) capture output and add some simple asserts
+ // TODO(bep) misspelled subcommands does not return an error. We should investigate this
+ // but before that, check for "Error: unknown command".
+
+ _, err := hugoCmd.ExecuteC()
+ if test.expectErrToContain != "" {
+ c.Assert(err, qt.Not(qt.IsNil))
+ c.Assert(err.Error(), qt.Contains, test.expectErrToContain)
+ } else {
+ c.Assert(err, qt.IsNil)
+ }
- // Assert that we have not left any development debug artifacts in
- // the code.
- if b.c != nil {
- _, ok := b.c.destinationFs.(types.DevMarker)
- c.Assert(ok, qt.Equals, false)
- }
+ // Assert that we have not left any development debug artifacts in
+ // the code.
+ if b.c != nil {
+ _, ok := b.c.publishDirFs.(types.DevMarker)
+ c.Assert(ok, qt.Equals, false)
+ }
+ })
}
}
@@ -329,11 +318,8 @@ type testSiteConfig struct {
contentDir string
}
-func createSimpleTestSite(t testing.TB, cfg testSiteConfig) (string, func(), error) {
- d, clean, e := htesting.CreateTempDir(hugofs.Os, "hugo-cli")
- if e != nil {
- return "", nil, e
- }
+func createSimpleTestSite(t testing.TB, cfg testSiteConfig) string {
+ dir := t.TempDir()
cfgStr := `
@@ -352,23 +338,23 @@ title = "Hugo Commands"
contentDir = cfg.contentDir
}
- os.MkdirAll(filepath.Join(d, "public"), 0777)
+ os.MkdirAll(filepath.Join(dir, "public"), 0777)
// 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", "staging", "params.toml"), `myparam="paramstaging"`)
- writeFile(t, filepath.Join(d, "config", "staging", "deployment.toml"), `
+ writeFile(t, filepath.Join(dir, "config.toml"), cfgStr)
+ writeFile(t, filepath.Join(dir, "config", "staging", "params.toml"), `myparam="paramstaging"`)
+ writeFile(t, filepath.Join(dir, "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(dir, "config", "testing", "params.toml"), `myparam="paramtesting"`)
+ writeFile(t, filepath.Join(dir, "config", "production", "params.toml"), `myparam="paramproduction"`)
- writeFile(t, filepath.Join(d, "static", "myfile.txt"), `Hello World!`)
+ writeFile(t, filepath.Join(dir, "static", "myfile.txt"), `Hello World!`)
- writeFile(t, filepath.Join(d, contentDir, "p1.md"), `
+ writeFile(t, filepath.Join(dir, contentDir, "p1.md"), `
---
title: "P1"
weight: 1
@@ -378,20 +364,20 @@ Content
`)
- writeFile(t, filepath.Join(d, "layouts", "_default", "single.html"), `
+ writeFile(t, filepath.Join(dir, "layouts", "_default", "single.html"), `
Single: {{ .Title }}
`)
- writeFile(t, filepath.Join(d, "layouts", "_default", "list.html"), `
+ writeFile(t, filepath.Join(dir, "layouts", "_default", "list.html"), `
List: {{ .Title }}
Environment: {{ hugo.Environment }}
`)
- return d, clean, nil
+ return dir
}
func writeFile(t testing.TB, filename, content string) {
diff --git a/commands/hugo.go b/commands/hugo.go
index 21140fa43..9033fac90 100644
--- a/commands/hugo.go
+++ b/commands/hugo.go
@@ -508,7 +508,7 @@ func (c *commandeer) build() error {
c.hugo().PrintProcessingStats(os.Stdout)
fmt.Println()
- if createCounter, ok := c.destinationFs.(hugofs.DuplicatesReporter); ok {
+ if createCounter, ok := c.publishDirFs.(hugofs.DuplicatesReporter); ok {
dupes := createCounter.ReportDuplicates()
if dupes != "" {
c.logger.Warnln("Duplicate target paths:", dupes)
@@ -634,11 +634,7 @@ func chmodFilter(dst, src os.FileInfo) bool {
}
func (c *commandeer) copyStaticTo(sourceFs *filesystems.SourceFilesystem) (uint64, error) {
- publishDir := c.hugo().PathSpec.PublishDir
- // If root, remove the second '/'
- if publishDir == "//" {
- publishDir = helpers.FilePathSeparator
- }
+ publishDir := helpers.FilePathSeparator
if sourceFs.PublishFolder != "" {
publishDir = filepath.Join(publishDir, sourceFs.PublishFolder)
@@ -651,9 +647,9 @@ func (c *commandeer) copyStaticTo(sourceFs *filesystems.SourceFilesystem) (uint6
syncer.NoChmod = c.Cfg.GetBool("noChmod")
syncer.ChmodFilter = chmodFilter
syncer.SrcFs = fs
- syncer.DestFs = c.Fs.Destination
+ syncer.DestFs = c.Fs.PublishDir
if c.renderStaticToDisk {
- syncer.DestFs = c.Fs.DestinationStatic
+ syncer.DestFs = c.Fs.PublishDirStatic
}
// Now that we are using a unionFs for the static directories
// We can effectively clean the publishDir on initial sync
diff --git a/commands/hugo_test.go b/commands/hugo_test.go
index 4bead09f0..aca3de2fd 100644
--- a/commands/hugo_test.go
+++ b/commands/hugo_test.go
@@ -36,12 +36,10 @@ title = "Hugo Commands"
contentDir = "thisdoesnotexist"
`
- dir, clean, err := createSimpleTestSite(t, testSiteConfig{configTOML: cfgStr, contentDir: contentDir})
- c.Assert(err, qt.IsNil)
- defer clean()
+ dir := createSimpleTestSite(t, testSiteConfig{configTOML: cfgStr, contentDir: contentDir})
cmd.SetArgs([]string{"-s=" + dir, "-c=" + contentDir})
- _, err = cmd.ExecuteC()
+ _, err := cmd.ExecuteC()
c.Assert(err, qt.IsNil)
}
diff --git a/commands/list_test.go b/commands/list_test.go
index 6f3d6c74d..56a3ee9b9 100644
--- a/commands/list_test.go
+++ b/commands/list_test.go
@@ -29,10 +29,7 @@ func captureStdout(f func() error) (string, error) {
func TestListAll(t *testing.T) {
c := qt.New(t)
- dir, clean, err := createSimpleTestSite(t, testSiteConfig{})
- defer clean()
-
- c.Assert(err, qt.IsNil)
+ dir := createSimpleTestSite(t, testSiteConfig{})
hugoCmd := newCommandsBuilder().addAll().build()
cmd := hugoCmd.getCommand()
diff --git a/commands/new_site.go b/commands/new_site.go
index 1e3ed710b..e49a60202 100644
--- a/commands/new_site.go
+++ b/commands/new_site.go
@@ -122,8 +122,10 @@ func (n *newSiteCmd) newSite(cmd *cobra.Command, args []string) error {
}
forceNew, _ := cmd.Flags().GetBool("force")
-
- return n.doNewSite(hugofs.NewDefault(config.New()), createpath, forceNew)
+ cfg := config.New()
+ cfg.Set("workingDir", createpath)
+ cfg.Set("publishDir", "public")
+ return n.doNewSite(hugofs.NewDefault(cfg), createpath, forceNew)
}
func createConfig(fs *hugofs.Fs, inpath string, kind string) (err error) {
diff --git a/commands/server.go b/commands/server.go
index da1918ede..145a889bb 100644
--- a/commands/server.go
+++ b/commands/server.go
@@ -23,6 +23,7 @@ import (
"net/url"
"os"
"os/signal"
+ "path"
"path/filepath"
"regexp"
"runtime"
@@ -148,7 +149,7 @@ func (sc *serverCmd) server(cmd *cobra.Command, args []string) error {
var serverCfgInit sync.Once
cfgInit := func(c *commandeer) (rerr error) {
- c.Set("renderToMemory", !sc.renderToDisk)
+ c.Set("renderToMemory", !(sc.renderToDisk || sc.renderStaticToDisk))
c.Set("renderStaticToDisk", sc.renderStaticToDisk)
if cmd.Flags().Changed("navigateToChanged") {
c.Set("navigateToChanged", sc.navigateToChanged)
@@ -330,13 +331,18 @@ func (f *fileServer) createEndpoint(i int) (*http.ServeMux, net.Listener, string
port := f.c.serverPorts[i].p
listener := f.c.serverPorts[i].ln
+ // For logging only.
+ // TODO(bep) consolidate.
publishDir := f.c.Cfg.GetString("publishDir")
+ publishDirStatic := f.c.Cfg.GetString("publishDirStatic")
+ workingDir := f.c.Cfg.GetString("workingDir")
if root != "" {
publishDir = filepath.Join(publishDir, root)
+ publishDirStatic = filepath.Join(publishDirStatic, root)
}
-
- absPublishDir := f.c.hugo().PathSpec.AbsPathify(publishDir)
+ absPublishDir := paths.AbsPathify(workingDir, publishDir)
+ absPublishDirStatic := paths.AbsPathify(workingDir, publishDirStatic)
jww.FEEDBACK.Printf("Environment: %q", f.c.hugo().Deps.Site.Hugo().Environment)
@@ -344,14 +350,14 @@ func (f *fileServer) createEndpoint(i int) (*http.ServeMux, net.Listener, string
if f.s.renderToDisk {
jww.FEEDBACK.Println("Serving pages from " + absPublishDir)
} else if f.s.renderStaticToDisk {
- jww.FEEDBACK.Println("Serving pages from memory and static files from " + absPublishDir)
+ jww.FEEDBACK.Println("Serving pages from memory and static files from " + absPublishDirStatic)
} else {
jww.FEEDBACK.Println("Serving pages from memory")
}
}
- httpFs := afero.NewHttpFs(f.c.destinationFs)
- fs := filesOnlyFs{httpFs.Dir(absPublishDir)}
+ httpFs := afero.NewHttpFs(f.c.publishDirServerFs)
+ fs := filesOnlyFs{httpFs.Dir(path.Join("/", root))}
if i == 0 && f.c.fastRenderMode {
jww.FEEDBACK.Println("Running in Fast Render Mode. For full rebuilds on change: hugo server --disableFastRender")
diff --git a/commands/server_test.go b/commands/server_test.go
index 6972bbe69..ea50afd94 100644
--- a/commands/server_test.go
+++ b/commands/server_test.go
@@ -77,6 +77,9 @@ func TestServerFlags(t *testing.T) {
{"--renderToDisk", func(c *qt.C, r serverTestResult) {
assertPublic(c, r, true)
}},
+ {"--renderStaticToDisk", func(c *qt.C, r serverTestResult) {
+ assertPublic(c, r, true)
+ }},
} {
c.Run(test.flag, func(c *qt.C) {
config := `
@@ -105,9 +108,7 @@ type serverTestResult struct {
}
func runServerTest(c *qt.C, getHome bool, config string, args ...string) (result serverTestResult) {
- dir, clean, err := createSimpleTestSite(c, testSiteConfig{configTOML: config})
- defer clean()
- c.Assert(err, qt.IsNil)
+ dir := createSimpleTestSite(c, testSiteConfig{configTOML: config})
sp, err := helpers.FindAvailablePort()
c.Assert(err, qt.IsNil)
@@ -141,12 +142,15 @@ func runServerTest(c *qt.C, getHome bool, config string, args ...string) (result
time.Sleep(567 * time.Millisecond)
resp, err := http.Get(fmt.Sprintf("http://localhost:%d/", port))
c.Check(err, qt.IsNil)
+ c.Check(resp.StatusCode, qt.Equals, http.StatusOK)
if err == nil {
defer resp.Body.Close()
result.homeContent = helpers.ReaderToString(resp.Body)
}
}
+ time.Sleep(1 * time.Second)
+
select {
case <-stop:
case stop <- true:
@@ -191,7 +195,7 @@ func TestFixURL(t *testing.T) {
t.Run(test.TestName, func(t *testing.T) {
b := newCommandsBuilder()
s := b.newServerCmd()
- v := config.New()
+ v := config.NewWithTestDefaults()
baseURL := test.CLIBaseURL
v.Set("baseURL", test.CfgBaseURL)
s.serverAppend = test.AppendPort
diff --git a/commands/static_syncer.go b/commands/static_syncer.go
index 2eb2b6662..b97c4df7a 100644
--- a/commands/static_syncer.go
+++ b/commands/static_syncer.go
@@ -40,11 +40,7 @@ func (s *staticSyncer) syncsStaticEvents(staticEvents []fsnotify.Event) error {
c := s.c
syncFn := func(sourceFs *filesystems.SourceFilesystem) (uint64, error) {
- publishDir := c.hugo().PathSpec.PublishDir
- // If root, remove the second '/'
- if publishDir == "//" {
- publishDir = helpers.FilePathSeparator
- }
+ publishDir := helpers.FilePathSeparator
if sourceFs.PublishFolder != "" {
publishDir = filepath.Join(publishDir, sourceFs.PublishFolder)
@@ -55,9 +51,9 @@ func (s *staticSyncer) syncsStaticEvents(staticEvents []fsnotify.Event) error {
syncer.NoChmod = c.Cfg.GetBool("noChmod")
syncer.ChmodFilter = chmodFilter
syncer.SrcFs = sourceFs.Fs
- syncer.DestFs = c.Fs.Destination
+ syncer.DestFs = c.Fs.PublishDir
if c.renderStaticToDisk {
- syncer.DestFs = c.Fs.DestinationStatic
+ syncer.DestFs = c.Fs.PublishDirStatic
}
// prevent spamming the log on changes
@@ -101,19 +97,14 @@ func (s *staticSyncer) syncsStaticEvents(staticEvents []fsnotify.Event) error {
if ev.Op&fsnotify.Rename == fsnotify.Rename || ev.Op&fsnotify.Remove == fsnotify.Remove {
if _, err := sourceFs.Fs.Stat(relPath); os.IsNotExist(err) {
// If file doesn't exist in any static dir, remove it
- toRemove := filepath.Join(publishDir, relPath)
+ logger.Println("File no longer exists in static dir, removing", relPath)
+ _ = c.Fs.PublishDirStatic.RemoveAll(relPath)
- logger.Println("File no longer exists in static dir, removing", toRemove)
- if c.renderStaticToDisk {
- _ = c.Fs.DestinationStatic.RemoveAll(toRemove)
- } else {
- _ = c.Fs.Destination.RemoveAll(toRemove)
- }
} else if err == nil {
// If file still exists, sync it
logger.Println("Syncing", relPath, "to", publishDir)
- if err := syncer.Sync(filepath.Join(publishDir, relPath), relPath); err != nil {
+ if err := syncer.Sync(relPath, relPath); err != nil {
c.logger.Errorln(err)
}
} else {