mirror of
https://github.com/gohugoio/hugo.git
synced 2024-11-21 20:46:30 -05:00
Delay the creation of cache directories until they're used
Fixes #11390
This commit is contained in:
parent
c3f273b2d7
commit
94fbab2a88
3 changed files with 46 additions and 4 deletions
37
cache/filecache/filecache.go
vendored
37
cache/filecache/filecache.go
vendored
|
@ -51,6 +51,9 @@ type Cache struct {
|
||||||
pruneAllRootDir string
|
pruneAllRootDir string
|
||||||
|
|
||||||
nlocker *lockTracker
|
nlocker *lockTracker
|
||||||
|
|
||||||
|
initOnce sync.Once
|
||||||
|
initErr error
|
||||||
}
|
}
|
||||||
|
|
||||||
type lockTracker struct {
|
type lockTracker struct {
|
||||||
|
@ -103,9 +106,23 @@ func (l *lockedFile) Close() error {
|
||||||
return l.File.Close()
|
return l.File.Close()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *Cache) init() error {
|
||||||
|
c.initOnce.Do(func() {
|
||||||
|
// Create the base dir if it does not exist.
|
||||||
|
if err := c.Fs.MkdirAll("", 0777); err != nil && !os.IsExist(err) {
|
||||||
|
c.initErr = err
|
||||||
|
}
|
||||||
|
})
|
||||||
|
return c.initErr
|
||||||
|
}
|
||||||
|
|
||||||
// WriteCloser returns a transactional writer into the cache.
|
// WriteCloser returns a transactional writer into the cache.
|
||||||
// It's important that it's closed when done.
|
// It's important that it's closed when done.
|
||||||
func (c *Cache) WriteCloser(id string) (ItemInfo, io.WriteCloser, error) {
|
func (c *Cache) WriteCloser(id string) (ItemInfo, io.WriteCloser, error) {
|
||||||
|
if err := c.init(); err != nil {
|
||||||
|
return ItemInfo{}, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
id = cleanID(id)
|
id = cleanID(id)
|
||||||
c.nlocker.Lock(id)
|
c.nlocker.Lock(id)
|
||||||
|
|
||||||
|
@ -130,6 +147,10 @@ func (c *Cache) WriteCloser(id string) (ItemInfo, io.WriteCloser, error) {
|
||||||
func (c *Cache) ReadOrCreate(id string,
|
func (c *Cache) ReadOrCreate(id string,
|
||||||
read func(info ItemInfo, r io.ReadSeeker) error,
|
read func(info ItemInfo, r io.ReadSeeker) error,
|
||||||
create func(info ItemInfo, w io.WriteCloser) error) (info ItemInfo, err error) {
|
create func(info ItemInfo, w io.WriteCloser) error) (info ItemInfo, err error) {
|
||||||
|
if err := c.init(); err != nil {
|
||||||
|
return ItemInfo{}, err
|
||||||
|
}
|
||||||
|
|
||||||
id = cleanID(id)
|
id = cleanID(id)
|
||||||
|
|
||||||
c.nlocker.Lock(id)
|
c.nlocker.Lock(id)
|
||||||
|
@ -163,6 +184,9 @@ func (c *Cache) ReadOrCreate(id string,
|
||||||
// be invoked and the result cached.
|
// be invoked and the result cached.
|
||||||
// This method is protected by a named lock using the given id as identifier.
|
// This method is protected by a named lock using the given id as identifier.
|
||||||
func (c *Cache) GetOrCreate(id string, create func() (io.ReadCloser, error)) (ItemInfo, io.ReadCloser, error) {
|
func (c *Cache) GetOrCreate(id string, create func() (io.ReadCloser, error)) (ItemInfo, io.ReadCloser, error) {
|
||||||
|
if err := c.init(); err != nil {
|
||||||
|
return ItemInfo{}, nil, err
|
||||||
|
}
|
||||||
id = cleanID(id)
|
id = cleanID(id)
|
||||||
|
|
||||||
c.nlocker.Lock(id)
|
c.nlocker.Lock(id)
|
||||||
|
@ -197,6 +221,9 @@ func (c *Cache) GetOrCreate(id string, create func() (io.ReadCloser, error)) (It
|
||||||
|
|
||||||
// GetOrCreateBytes is the same as GetOrCreate, but produces a byte slice.
|
// GetOrCreateBytes is the same as GetOrCreate, but produces a byte slice.
|
||||||
func (c *Cache) GetOrCreateBytes(id string, create func() ([]byte, error)) (ItemInfo, []byte, error) {
|
func (c *Cache) GetOrCreateBytes(id string, create func() ([]byte, error)) (ItemInfo, []byte, error) {
|
||||||
|
if err := c.init(); err != nil {
|
||||||
|
return ItemInfo{}, nil, err
|
||||||
|
}
|
||||||
id = cleanID(id)
|
id = cleanID(id)
|
||||||
|
|
||||||
c.nlocker.Lock(id)
|
c.nlocker.Lock(id)
|
||||||
|
@ -232,6 +259,9 @@ func (c *Cache) GetOrCreateBytes(id string, create func() ([]byte, error)) (Item
|
||||||
|
|
||||||
// GetBytes gets the file content with the given id from the cache, nil if none found.
|
// GetBytes gets the file content with the given id from the cache, nil if none found.
|
||||||
func (c *Cache) GetBytes(id string) (ItemInfo, []byte, error) {
|
func (c *Cache) GetBytes(id string) (ItemInfo, []byte, error) {
|
||||||
|
if err := c.init(); err != nil {
|
||||||
|
return ItemInfo{}, nil, err
|
||||||
|
}
|
||||||
id = cleanID(id)
|
id = cleanID(id)
|
||||||
|
|
||||||
c.nlocker.Lock(id)
|
c.nlocker.Lock(id)
|
||||||
|
@ -250,6 +280,9 @@ func (c *Cache) GetBytes(id string) (ItemInfo, []byte, error) {
|
||||||
|
|
||||||
// Get gets the file with the given id from the cache, nil if none found.
|
// Get gets the file with the given id from the cache, nil if none found.
|
||||||
func (c *Cache) Get(id string) (ItemInfo, io.ReadCloser, error) {
|
func (c *Cache) Get(id string) (ItemInfo, io.ReadCloser, error) {
|
||||||
|
if err := c.init(); err != nil {
|
||||||
|
return ItemInfo{}, nil, err
|
||||||
|
}
|
||||||
id = cleanID(id)
|
id = cleanID(id)
|
||||||
|
|
||||||
c.nlocker.Lock(id)
|
c.nlocker.Lock(id)
|
||||||
|
@ -347,10 +380,6 @@ func NewCaches(p *helpers.PathSpec) (Caches, error) {
|
||||||
|
|
||||||
baseDir := v.DirCompiled
|
baseDir := v.DirCompiled
|
||||||
|
|
||||||
if err := cfs.MkdirAll(baseDir, 0777); err != nil && !os.IsExist(err) {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
bfs := afero.NewBasePathFs(cfs, baseDir)
|
bfs := afero.NewBasePathFs(cfs, baseDir)
|
||||||
|
|
||||||
var pruneAllRootDir string
|
var pruneAllRootDir string
|
||||||
|
|
6
cache/filecache/filecache_pruner.go
vendored
6
cache/filecache/filecache_pruner.go
vendored
|
@ -53,6 +53,9 @@ func (c *Cache) Prune(force bool) (int, error) {
|
||||||
if c.pruneAllRootDir != "" {
|
if c.pruneAllRootDir != "" {
|
||||||
return c.pruneRootDir(force)
|
return c.pruneRootDir(force)
|
||||||
}
|
}
|
||||||
|
if err := c.init(); err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
|
||||||
counter := 0
|
counter := 0
|
||||||
|
|
||||||
|
@ -117,6 +120,9 @@ func (c *Cache) Prune(force bool) (int, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Cache) pruneRootDir(force bool) (int, error) {
|
func (c *Cache) pruneRootDir(force bool) (int, error) {
|
||||||
|
if err := c.init(); err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
info, err := c.Fs.Stat(c.pruneAllRootDir)
|
info, err := c.Fs.Stat(c.pruneAllRootDir)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if herrors.IsNotExist(err) {
|
if herrors.IsNotExist(err) {
|
||||||
|
|
7
testscripts/commands/new_content.txt
Normal file
7
testscripts/commands/new_content.txt
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
hugo new site myblog
|
||||||
|
cd myblog
|
||||||
|
hugo new content --kind post post/first-post.md
|
||||||
|
! exists resources
|
||||||
|
grep 'draft = true' content/post/first-post.md
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue