diff --git a/hugofs/fs.go b/hugofs/fs.go index 2c57fe8b5..54d962553 100644 --- a/hugofs/fs.go +++ b/hugofs/fs.go @@ -41,6 +41,7 @@ type Fs struct { // WorkingDir is a read-only file system // restricted to the project working dir. + // TODO(bep) get rid of this (se BaseFs) WorkingDir *afero.BasePathFs } diff --git a/hugolib/filesystems/basefs.go b/hugolib/filesystems/basefs.go index aae3613f2..04648c25f 100644 --- a/hugolib/filesystems/basefs.go +++ b/hugolib/filesystems/basefs.go @@ -68,6 +68,9 @@ type BaseFs struct { // This usually maps to /my-project/public. PublishFs afero.Fs + // A read-only filesystem from the project workDir (no theme here). + WorkDir afero.Fs + theBigFs *filesystemsCollector // Locks. @@ -202,7 +205,7 @@ type SourceFilesystems struct { // with any sub module's resource fs layered below. ResourcesCache afero.Fs - // The project folder. + // The work folder (may be a composite of project and theme components). Work afero.Fs // When in multihost we have one static filesystem per language. The sync @@ -435,9 +438,11 @@ func NewBase(p *paths.Paths, logger loggers.Logger, options ...func(*BaseFs) err publishFs := hugofs.NewBaseFileDecorator(afero.NewBasePathFs(fs.Destination, p.AbsPublishDir)) sourceFs := hugofs.NewBaseFileDecorator(afero.NewBasePathFs(fs.Source, p.WorkingDir)) + workDir := hugofs.NewBaseFileDecorator(afero.NewBasePathFs(afero.NewReadOnlyFs(fs.Source), p.WorkingDir)) b := &BaseFs{ SourceFs: sourceFs, + WorkDir: workDir, PublishFs: publishFs, buildMu: lockedfile.MutexAt(filepath.Join(p.WorkingDir, lockFileBuild)), } diff --git a/tpl/os/integration_test.go b/tpl/os/integration_test.go new file mode 100644 index 000000000..fe1bb3d6e --- /dev/null +++ b/tpl/os/integration_test.go @@ -0,0 +1,51 @@ +// Copyright 2022 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. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package os_test + +import ( + "testing" + + "github.com/gohugoio/hugo/hugolib" +) + +// Issue 9599 +func TestReadDirWorkDir(t *testing.T) { + t.Parallel() + + files := ` +-- config.toml -- +theme = "mytheme" +-- myproject.txt -- +Hello project! +-- themes/mytheme/mytheme.txt -- +Hello theme! +-- layouts/index.html -- +{{ $entries := (readDir ".") }} +START:|{{ range $entry := $entries }}{{ if not $entry.IsDir }}{{ $entry.Name }}|{{ end }}{{ end }}:END: + + + ` + + b := hugolib.NewIntegrationTestBuilder( + hugolib.IntegrationTestConfig{ + T: t, + TxtarString: files, + NeedsOsFS: true, + }, + ).Build() + + b.AssertFileContent("public/index.html", ` +START:|config.toml|myproject.txt|:END: +`) +} diff --git a/tpl/os/os.go b/tpl/os/os.go index 2da792ac1..5abc03c68 100644 --- a/tpl/os/os.go +++ b/tpl/os/os.go @@ -33,7 +33,8 @@ func New(d *deps.Deps) *Namespace { // The docshelper script does not have or need all the dependencies set up. if d.PathSpec != nil { readFileFs = afero.NewReadOnlyFs(afero.NewCopyOnWriteFs(d.PathSpec.BaseFs.Content.Fs, d.PathSpec.BaseFs.Work)) - workFs = d.PathSpec.BaseFs.Work + // See #9599 + workFs = d.PathSpec.BaseFs.WorkDir } return &Namespace{