Fix PostProcess regression for hugo server

Fixes #9788
This commit is contained in:
Bjørn Erik Pedersen 2022-04-16 17:50:50 +02:00
parent 397fce5603
commit 4deb5c6066
4 changed files with 66 additions and 38 deletions

View file

@ -395,23 +395,23 @@ func (c *commandeer) loadConfig() error {
} }
c.fsCreate.Do(func() { c.fsCreate.Do(func() {
fs := hugofs.NewFrom(sourceFs, config) // Assume both source and destination are using same filesystem.
fs := hugofs.NewFromSourceAndDestination(sourceFs, sourceFs, config)
if c.publishDirFs != nil { if c.publishDirFs != nil {
// Need to reuse the destination on server rebuilds. // Need to reuse the destination on server rebuilds.
fs.PublishDir = c.publishDirFs fs.PublishDir = c.publishDirFs
fs.PublishDirServer = c.publishDirServerFs fs.PublishDirServer = c.publishDirServerFs
} else { } else {
publishDir := config.GetString("publishDir")
publishDirStatic := config.GetString("publishDirStatic")
workingDir := config.GetString("workingDir")
absPublishDir := paths.AbsPathify(workingDir, publishDir)
absPublishDirStatic := paths.AbsPathify(workingDir, publishDirStatic)
if c.renderStaticToDisk { if c.renderStaticToDisk {
// Writes the dynamic output oton memory, publishDirStatic := config.GetString("publishDirStatic")
workingDir := config.GetString("workingDir")
absPublishDirStatic := paths.AbsPathify(workingDir, publishDirStatic)
fs = hugofs.NewFromSourceAndDestination(sourceFs, afero.NewMemMapFs(), config)
// Writes the dynamic output to memory,
// while serve others directly from /public on disk. // while serve others directly from /public on disk.
dynamicFs := afero.NewMemMapFs() dynamicFs := fs.PublishDir
staticFs := afero.NewBasePathFs(afero.NewOsFs(), absPublishDirStatic) staticFs := afero.NewBasePathFs(afero.NewOsFs(), absPublishDirStatic)
// Serve from both the static and dynamic fs, // Serve from both the static and dynamic fs,
@ -427,18 +427,10 @@ func (c *commandeer) loadConfig() error {
}, },
}, },
) )
fs.PublishDir = dynamicFs
fs.PublishDirStatic = staticFs fs.PublishDirStatic = staticFs
} else if createMemFs { } else if createMemFs {
// Hugo writes the output to memory instead of the disk. // Hugo writes the output to memory instead of the disk.
fs.PublishDir = new(afero.MemMapFs) fs = hugofs.NewFromSourceAndDestination(sourceFs, afero.NewMemMapFs(), config)
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
} }
} }

View file

@ -375,6 +375,10 @@ Single: {{ .Title }}
List: {{ .Title }} List: {{ .Title }}
Environment: {{ hugo.Environment }} Environment: {{ hugo.Environment }}
For issue 9788:
{{ $foo :="abc" | resources.FromString "foo.css" | minify | resources.PostProcess }}
PostProcess: {{ $foo.RelPermalink }}
`) `)
return dir return dir

View file

@ -31,16 +31,6 @@ import (
qt "github.com/frankban/quicktest" qt "github.com/frankban/quicktest"
) )
func TestServer(t *testing.T) {
c := qt.New(t)
r := runServerTest(c, true, "")
c.Assert(r.err, qt.IsNil)
c.Assert(r.homeContent, qt.Contains, "List: Hugo Commands")
c.Assert(r.homeContent, qt.Contains, "Environment: development")
}
// Issue 9518 // Issue 9518
func TestServerPanicOnConfigError(t *testing.T) { func TestServerPanicOnConfigError(t *testing.T) {
c := qt.New(t) c := qt.New(t)
@ -101,6 +91,42 @@ baseURL="https://example.org"
} }
func TestServerBugs(t *testing.T) {
c := qt.New(t)
for _, test := range []struct {
name string
flag string
assert func(c *qt.C, r serverTestResult)
}{
// Issue 9788
{"PostProcess, memory", "", func(c *qt.C, r serverTestResult) {
c.Assert(r.err, qt.IsNil)
c.Assert(r.homeContent, qt.Contains, "PostProcess: /foo.min.css")
}},
{"PostProcess, disk", "--renderToDisk", func(c *qt.C, r serverTestResult) {
c.Assert(r.err, qt.IsNil)
c.Assert(r.homeContent, qt.Contains, "PostProcess: /foo.min.css")
}},
} {
c.Run(test.name, func(c *qt.C) {
config := `
baseURL="https://example.org"
`
var args []string
if test.flag != "" {
args = strings.Split(test.flag, "=")
}
r := runServerTest(c, true, config, args...)
test.assert(c, r)
})
}
}
type serverTestResult struct { type serverTestResult struct {
err error err error
homeContent string homeContent string

View file

@ -65,7 +65,7 @@ type Fs struct {
// as source and destination file systems. // as source and destination file systems.
func NewDefault(cfg config.Provider) *Fs { func NewDefault(cfg config.Provider) *Fs {
fs := Os fs := Os
return newFs(fs, cfg) return newFs(fs, fs, cfg)
} }
// NewMem creates a new Fs with the MemMapFs // NewMem creates a new Fs with the MemMapFs
@ -73,17 +73,23 @@ func NewDefault(cfg config.Provider) *Fs {
// Useful for testing. // Useful for testing.
func NewMem(cfg config.Provider) *Fs { func NewMem(cfg config.Provider) *Fs {
fs := &afero.MemMapFs{} fs := &afero.MemMapFs{}
return newFs(fs, cfg) return newFs(fs, fs, cfg)
} }
// NewFrom creates a new Fs based on the provided Afero Fs // NewFrom creates a new Fs based on the provided Afero Fs
// as source and destination file systems. // as source and destination file systems.
// Useful for testing. // Useful for testing.
func NewFrom(fs afero.Fs, cfg config.Provider) *Fs { func NewFrom(fs afero.Fs, cfg config.Provider) *Fs {
return newFs(fs, cfg) return newFs(fs, fs, cfg)
} }
func newFs(base afero.Fs, cfg config.Provider) *Fs { // NewFrom creates a new Fs based on the provided Afero Fss
// as the source and destination file systems.
func NewFromSourceAndDestination(source, destination afero.Fs, cfg config.Provider) *Fs {
return newFs(source, destination, cfg)
}
func newFs(source, destination afero.Fs, cfg config.Provider) *Fs {
workingDir := cfg.GetString("workingDir") workingDir := cfg.GetString("workingDir")
publishDir := cfg.GetString("publishDir") publishDir := cfg.GetString("publishDir")
if publishDir == "" { if publishDir == "" {
@ -91,27 +97,27 @@ func newFs(base afero.Fs, cfg config.Provider) *Fs {
} }
// Sanity check // Sanity check
if IsOsFs(base) && len(workingDir) < 2 { if IsOsFs(source) && len(workingDir) < 2 {
panic("workingDir is too short") panic("workingDir is too short")
} }
absPublishDir := paths.AbsPathify(workingDir, publishDir) absPublishDir := paths.AbsPathify(workingDir, publishDir)
// Make sure we always have the /public folder ready to use. // Make sure we always have the /public folder ready to use.
if err := base.MkdirAll(absPublishDir, 0777); err != nil && !os.IsExist(err) { if err := source.MkdirAll(absPublishDir, 0777); err != nil && !os.IsExist(err) {
panic(err) panic(err)
} }
pubFs := afero.NewBasePathFs(base, absPublishDir) pubFs := afero.NewBasePathFs(destination, absPublishDir)
return &Fs{ return &Fs{
Source: base, Source: source,
PublishDir: pubFs, PublishDir: pubFs,
PublishDirServer: pubFs, PublishDirServer: pubFs,
PublishDirStatic: pubFs, PublishDirStatic: pubFs,
Os: &afero.OsFs{}, Os: &afero.OsFs{},
WorkingDirReadOnly: getWorkingDirFsReadOnly(base, workingDir), WorkingDirReadOnly: getWorkingDirFsReadOnly(source, workingDir),
WorkingDirWritable: getWorkingDirFsWritable(base, workingDir), WorkingDirWritable: getWorkingDirFsWritable(source, workingDir),
} }
} }