mirror of
https://github.com/gohugoio/hugo.git
synced 2026-09-02 11:42:37 +00:00
Compare commits
15 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| bd1657c360 | |||
| 62567d3820 | |||
| e10915f80a | |||
| ec3890affe | |||
| 46cccb021b | |||
| cb6e27b32a | |||
| 5bbe95f9c5 | |||
| 31d19b505d | |||
| bfa2fd683e | |||
| 88d598a049 | |||
| 352be5ba87 | |||
| d37606d2c2 | |||
| f5e54d9c7d | |||
| 42f37b4e98 | |||
| e971b7d866 |
@@ -112,17 +112,17 @@ jobs:
|
|||||||
sass --version;
|
sass --version;
|
||||||
mage -v check;
|
mage -v check;
|
||||||
env:
|
env:
|
||||||
HUGO_BUILD_TAGS: extended
|
HUGO_BUILD_TAGS: extended,withdeploy
|
||||||
- if: matrix.os == 'windows-latest'
|
- if: matrix.os == 'windows-latest'
|
||||||
# See issue #11052. We limit the build to regular test (no -race flag) on Windows for now.
|
# See issue #11052. We limit the build to regular test (no -race flag) on Windows for now.
|
||||||
name: Test
|
name: Test
|
||||||
run: |
|
run: |
|
||||||
mage -v test;
|
mage -v test;
|
||||||
env:
|
env:
|
||||||
HUGO_BUILD_TAGS: extended
|
HUGO_BUILD_TAGS: extended,withdeploy
|
||||||
- name: Build tags
|
- name: Build tags
|
||||||
run: |
|
run: |
|
||||||
go install -tags extended,nodeploy
|
go install -tags extended
|
||||||
- if: matrix.os == 'ubuntu-latest'
|
- if: matrix.os == 'ubuntu-latest'
|
||||||
name: Build for dragonfly
|
name: Build for dragonfly
|
||||||
run: |
|
run: |
|
||||||
|
|||||||
+3
-1
@@ -1,3 +1,5 @@
|
|||||||
|
|
||||||
*.test
|
*.test
|
||||||
imports.*
|
imports.*
|
||||||
|
dist/
|
||||||
|
public/
|
||||||
|
|||||||
+4
-4
@@ -21,8 +21,8 @@ COPY --from=xx / /
|
|||||||
ARG TARGETPLATFORM
|
ARG TARGETPLATFORM
|
||||||
RUN xx-apk add musl-dev gcc g++
|
RUN xx-apk add musl-dev gcc g++
|
||||||
|
|
||||||
# Optionally set HUGO_BUILD_TAGS to "none" or "nodeploy" when building like so:
|
# Optionally set HUGO_BUILD_TAGS to "none" or "withdeploy" when building like so:
|
||||||
# docker build --build-arg HUGO_BUILD_TAGS=nodeploy .
|
# docker build --build-arg HUGO_BUILD_TAGS=withdeploy .
|
||||||
#
|
#
|
||||||
# We build the extended version by default.
|
# We build the extended version by default.
|
||||||
ARG HUGO_BUILD_TAGS="extended"
|
ARG HUGO_BUILD_TAGS="extended"
|
||||||
@@ -76,14 +76,14 @@ RUN mkdir -p /var/hugo/bin /cache && \
|
|||||||
# See https://github.com/gohugoio/hugo/issues/9810
|
# See https://github.com/gohugoio/hugo/issues/9810
|
||||||
runuser -u hugo -- git config --global core.quotepath false
|
runuser -u hugo -- git config --global core.quotepath false
|
||||||
|
|
||||||
|
USER hugo:hugo
|
||||||
VOLUME /project
|
VOLUME /project
|
||||||
WORKDIR /project
|
WORKDIR /project
|
||||||
USER hugo:hugo
|
|
||||||
ENV HUGO_CACHEDIR=/cache
|
ENV HUGO_CACHEDIR=/cache
|
||||||
ENV PATH="/var/hugo/bin:$PATH"
|
ENV PATH="/var/hugo/bin:$PATH"
|
||||||
|
|
||||||
COPY scripts/docker/entrypoint.sh /entrypoint.sh
|
COPY scripts/docker/entrypoint.sh /entrypoint.sh
|
||||||
COPY --link --from=dart-sass /out/dart-sass /var/hugo/bin/dart-sass
|
COPY --from=dart-sass /out/dart-sass /var/hugo/bin/dart-sass
|
||||||
|
|
||||||
# Update PATH to reflect the new dependencies.
|
# Update PATH to reflect the new dependencies.
|
||||||
# For more complex setups, we should probably find a way to
|
# For more complex setups, we should probably find a way to
|
||||||
|
|||||||
Vendored
+19
-6
@@ -430,12 +430,25 @@ func (p *Partition[K, V]) doGetOrCreateWitTimeout(key K, duration time.Duration,
|
|||||||
errch := make(chan error, 1)
|
errch := make(chan error, 1)
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
v, _, err := p.c.GetOrCreate(key, create)
|
var (
|
||||||
if err != nil {
|
v V
|
||||||
errch <- err
|
err error
|
||||||
return
|
)
|
||||||
}
|
defer func() {
|
||||||
resultch <- v
|
if r := recover(); r != nil {
|
||||||
|
if rerr, ok := r.(error); ok {
|
||||||
|
err = rerr
|
||||||
|
} else {
|
||||||
|
err = fmt.Errorf("panic: %v", r)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
errch <- err
|
||||||
|
} else {
|
||||||
|
resultch <- v
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
v, _, err = p.c.GetOrCreate(key, create)
|
||||||
}()
|
}()
|
||||||
|
|
||||||
select {
|
select {
|
||||||
|
|||||||
Vendored
+55
@@ -14,8 +14,11 @@
|
|||||||
package dynacache
|
package dynacache
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"testing"
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
qt "github.com/frankban/quicktest"
|
qt "github.com/frankban/quicktest"
|
||||||
"github.com/gohugoio/hugo/common/loggers"
|
"github.com/gohugoio/hugo/common/loggers"
|
||||||
@@ -165,6 +168,58 @@ func TestClear(t *testing.T) {
|
|||||||
cache.adjustCurrentMaxSize()
|
cache.adjustCurrentMaxSize()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestPanicInCreate(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
c := qt.New(t)
|
||||||
|
cache := newTestCache(t)
|
||||||
|
|
||||||
|
p1 := GetOrCreatePartition[string, testItem](cache, "/aaaa/bbbb", OptionsPartition{Weight: 30, ClearWhen: ClearOnRebuild})
|
||||||
|
|
||||||
|
willPanic := func(i int) func() {
|
||||||
|
return func() {
|
||||||
|
p1.GetOrCreate(fmt.Sprintf("panic-%d", i), func(key string) (testItem, error) {
|
||||||
|
panic(errors.New(key))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetOrCreateWitTimeout needs to recover from panics in the create func.
|
||||||
|
willErr := func(i int) error {
|
||||||
|
_, err := p1.GetOrCreateWitTimeout(fmt.Sprintf("error-%d", i), 10*time.Second, func(key string) (testItem, error) {
|
||||||
|
return testItem{}, errors.New(key)
|
||||||
|
})
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
for i := 0; i < 3; i++ {
|
||||||
|
for j := 0; j < 3; j++ {
|
||||||
|
c.Assert(willPanic(i), qt.PanicMatches, fmt.Sprintf("panic-%d", i))
|
||||||
|
c.Assert(willErr(i), qt.ErrorMatches, fmt.Sprintf("error-%d", i))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test the same keys again without the panic.
|
||||||
|
for i := 0; i < 3; i++ {
|
||||||
|
for j := 0; j < 3; j++ {
|
||||||
|
v, err := p1.GetOrCreate(fmt.Sprintf("panic-%d", i), func(key string) (testItem, error) {
|
||||||
|
return testItem{
|
||||||
|
name: key,
|
||||||
|
}, nil
|
||||||
|
})
|
||||||
|
c.Assert(err, qt.IsNil)
|
||||||
|
c.Assert(v.name, qt.Equals, fmt.Sprintf("panic-%d", i))
|
||||||
|
|
||||||
|
v, err = p1.GetOrCreateWitTimeout(fmt.Sprintf("error-%d", i), 10*time.Second, func(key string) (testItem, error) {
|
||||||
|
return testItem{
|
||||||
|
name: key,
|
||||||
|
}, nil
|
||||||
|
})
|
||||||
|
c.Assert(err, qt.IsNil)
|
||||||
|
c.Assert(v.name, qt.Equals, fmt.Sprintf("error-%d", i))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestAdjustCurrentMaxSize(t *testing.T) {
|
func TestAdjustCurrentMaxSize(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
c := qt.New(t)
|
c := qt.New(t)
|
||||||
|
|||||||
+20
-1
@@ -42,6 +42,7 @@ import (
|
|||||||
"github.com/gohugoio/hugo/common/hugo"
|
"github.com/gohugoio/hugo/common/hugo"
|
||||||
"github.com/gohugoio/hugo/common/loggers"
|
"github.com/gohugoio/hugo/common/loggers"
|
||||||
"github.com/gohugoio/hugo/common/paths"
|
"github.com/gohugoio/hugo/common/paths"
|
||||||
|
"github.com/gohugoio/hugo/common/types"
|
||||||
"github.com/gohugoio/hugo/config"
|
"github.com/gohugoio/hugo/config"
|
||||||
"github.com/gohugoio/hugo/config/allconfig"
|
"github.com/gohugoio/hugo/config/allconfig"
|
||||||
"github.com/gohugoio/hugo/deps"
|
"github.com/gohugoio/hugo/deps"
|
||||||
@@ -66,6 +67,12 @@ func Execute(args []string) error {
|
|||||||
}
|
}
|
||||||
args = mapLegacyArgs(args)
|
args = mapLegacyArgs(args)
|
||||||
cd, err := x.Execute(context.Background(), args)
|
cd, err := x.Execute(context.Background(), args)
|
||||||
|
if cd != nil {
|
||||||
|
if closer, ok := cd.Root.Command.(types.Closer); ok {
|
||||||
|
closer.Close()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if err == errHelp {
|
if err == errHelp {
|
||||||
cd.CobraCommand.Help()
|
cd.CobraCommand.Help()
|
||||||
@@ -149,6 +156,18 @@ func (r *rootCommand) isVerbose() bool {
|
|||||||
return r.logger.Level() <= logg.LevelInfo
|
return r.logger.Level() <= logg.LevelInfo
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (r *rootCommand) Close() error {
|
||||||
|
if r.hugoSites != nil {
|
||||||
|
r.hugoSites.DeleteFunc(func(key configKey, value *hugolib.HugoSites) bool {
|
||||||
|
if value != nil {
|
||||||
|
value.Close()
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func (r *rootCommand) Build(cd *simplecobra.Commandeer, bcfg hugolib.BuildCfg, cfg config.Provider) (*hugolib.HugoSites, error) {
|
func (r *rootCommand) Build(cd *simplecobra.Commandeer, bcfg hugolib.BuildCfg, cfg config.Provider) (*hugolib.HugoSites, error) {
|
||||||
h, err := r.Hugo(cfg)
|
h, err := r.Hugo(cfg)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -488,7 +507,7 @@ func (r *rootCommand) createLogger(running bool) (loggers.Logger, error) {
|
|||||||
return loggers.New(optsLogger), nil
|
return loggers.New(optsLogger), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *rootCommand) Reset() {
|
func (r *rootCommand) resetLogs() {
|
||||||
r.logger.Reset()
|
r.logger.Reset()
|
||||||
loggers.Log().Reset()
|
loggers.Log().Reset()
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-15
@@ -11,21 +11,8 @@
|
|||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
//go:build !nodeploy
|
//go:build withdeploy
|
||||||
// +build !nodeploy
|
// +build withdeploy
|
||||||
|
|
||||||
// Copyright 2024 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 commands
|
package commands
|
||||||
|
|
||||||
|
|||||||
@@ -11,8 +11,8 @@
|
|||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
//go:build nodeploy
|
//go:build !withdeploy
|
||||||
// +build nodeploy
|
// +build !withdeploy
|
||||||
|
|
||||||
// Copyright 2024 The Hugo Authors. All rights reserved.
|
// Copyright 2024 The Hugo Authors. All rights reserved.
|
||||||
//
|
//
|
||||||
@@ -31,6 +31,7 @@ package commands
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"errors"
|
||||||
|
|
||||||
"github.com/bep/simplecobra"
|
"github.com/bep/simplecobra"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
@@ -40,7 +41,7 @@ func newDeployCommand() simplecobra.Commander {
|
|||||||
return &simpleCommand{
|
return &simpleCommand{
|
||||||
name: "deploy",
|
name: "deploy",
|
||||||
run: func(ctx context.Context, cd *simplecobra.Commandeer, r *rootCommand, args []string) error {
|
run: func(ctx context.Context, cd *simplecobra.Commandeer, r *rootCommand, args []string) error {
|
||||||
return nil
|
return errors.New("deploy not supported in this version of Hugo; install a release with 'withdeploy' in the archive filename or build yourself with the 'withdeploy' build tag. Also see https://github.com/gohugoio/hugo/pull/12995")
|
||||||
},
|
},
|
||||||
withc: func(cmd *cobra.Command, r *rootCommand) {
|
withc: func(cmd *cobra.Command, r *rootCommand) {
|
||||||
cmd.Hidden = true
|
cmd.Hidden = true
|
||||||
|
|||||||
+34
-24
@@ -27,7 +27,6 @@ import (
|
|||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/bep/logg"
|
|
||||||
"github.com/bep/simplecobra"
|
"github.com/bep/simplecobra"
|
||||||
"github.com/fsnotify/fsnotify"
|
"github.com/fsnotify/fsnotify"
|
||||||
"github.com/gohugoio/hugo/common/herrors"
|
"github.com/gohugoio/hugo/common/herrors"
|
||||||
@@ -136,10 +135,6 @@ func (e *hugoBuilderErrState) wasErr() bool {
|
|||||||
return e.waserr
|
return e.waserr
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *hugoBuilder) errCount() int {
|
|
||||||
return c.r.logger.LoggCount(logg.LevelError) + loggers.Log().LoggCount(logg.LevelError)
|
|
||||||
}
|
|
||||||
|
|
||||||
// getDirList provides NewWatcher() with a list of directories to watch for changes.
|
// getDirList provides NewWatcher() with a list of directories to watch for changes.
|
||||||
func (c *hugoBuilder) getDirList() ([]string, error) {
|
func (c *hugoBuilder) getDirList() ([]string, error) {
|
||||||
h, err := c.hugo()
|
h, err := c.hugo()
|
||||||
@@ -345,7 +340,6 @@ func (c *hugoBuilder) newWatcher(pollIntervalStr string, dirList ...string) (*wa
|
|||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
case changes := <-c.r.changesFromBuild:
|
case changes := <-c.r.changesFromBuild:
|
||||||
c.errState.setBuildErr(nil)
|
|
||||||
unlock, err := h.LockBuild()
|
unlock, err := h.LockBuild()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.r.logger.Errorln("Failed to acquire a build lock: %s", err)
|
c.r.logger.Errorln("Failed to acquire a build lock: %s", err)
|
||||||
@@ -358,7 +352,7 @@ func (c *hugoBuilder) newWatcher(pollIntervalStr string, dirList ...string) (*wa
|
|||||||
}
|
}
|
||||||
if c.s != nil && c.s.doLiveReload {
|
if c.s != nil && c.s.doLiveReload {
|
||||||
doReload := c.changeDetector == nil || len(c.changeDetector.changed()) > 0
|
doReload := c.changeDetector == nil || len(c.changeDetector.changed()) > 0
|
||||||
doReload = doReload || c.showErrorInBrowser && c.errCount() > 0
|
doReload = doReload || c.showErrorInBrowser && c.errState.buildErr() != nil
|
||||||
if doReload {
|
if doReload {
|
||||||
livereload.ForceRefresh()
|
livereload.ForceRefresh()
|
||||||
}
|
}
|
||||||
@@ -372,7 +366,7 @@ func (c *hugoBuilder) newWatcher(pollIntervalStr string, dirList ...string) (*wa
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
c.handleEvents(watcher, staticSyncer, evs, configSet)
|
c.handleEvents(watcher, staticSyncer, evs, configSet)
|
||||||
if c.showErrorInBrowser && c.errCount() > 0 {
|
if c.showErrorInBrowser && c.errState.buildErr() != nil {
|
||||||
// Need to reload browser to show the error
|
// Need to reload browser to show the error
|
||||||
livereload.ForceRefresh()
|
livereload.ForceRefresh()
|
||||||
}
|
}
|
||||||
@@ -419,11 +413,17 @@ func (c *hugoBuilder) build() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *hugoBuilder) buildSites(noBuildLock bool) (err error) {
|
func (c *hugoBuilder) buildSites(noBuildLock bool) (err error) {
|
||||||
h, err := c.hugo()
|
defer func() {
|
||||||
|
c.errState.setBuildErr(err)
|
||||||
|
}()
|
||||||
|
|
||||||
|
var h *hugolib.HugoSites
|
||||||
|
h, err = c.hugo()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return
|
||||||
}
|
}
|
||||||
return h.Build(hugolib.BuildCfg{NoBuildLock: noBuildLock})
|
err = h.Build(hugolib.BuildCfg{NoBuildLock: noBuildLock})
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *hugoBuilder) copyStatic() (map[string]uint64, error) {
|
func (c *hugoBuilder) copyStatic() (map[string]uint64, error) {
|
||||||
@@ -619,6 +619,9 @@ func (c *hugoBuilder) fullRebuild(changeType string) {
|
|||||||
// Set the processing on pause until the state is recovered.
|
// Set the processing on pause until the state is recovered.
|
||||||
c.errState.setPaused(true)
|
c.errState.setPaused(true)
|
||||||
c.handleBuildErr(err, "Failed to reload config")
|
c.handleBuildErr(err, "Failed to reload config")
|
||||||
|
if c.s.doLiveReload {
|
||||||
|
livereload.ForceRefresh()
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
c.errState.setPaused(false)
|
c.errState.setPaused(false)
|
||||||
}
|
}
|
||||||
@@ -1081,37 +1084,44 @@ func (c *hugoBuilder) printChangeDetected(typ string) {
|
|||||||
c.r.logger.Println(htime.Now().Format(layout))
|
c.r.logger.Println(htime.Now().Format(layout))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *hugoBuilder) rebuildSites(events []fsnotify.Event) error {
|
func (c *hugoBuilder) rebuildSites(events []fsnotify.Event) (err error) {
|
||||||
|
defer func() {
|
||||||
|
c.errState.setBuildErr(err)
|
||||||
|
}()
|
||||||
if err := c.errState.buildErr(); err != nil {
|
if err := c.errState.buildErr(); err != nil {
|
||||||
ferrs := herrors.UnwrapFileErrorsWithErrorContext(err)
|
ferrs := herrors.UnwrapFileErrorsWithErrorContext(err)
|
||||||
for _, err := range ferrs {
|
for _, err := range ferrs {
|
||||||
events = append(events, fsnotify.Event{Name: err.Position().Filename, Op: fsnotify.Write})
|
events = append(events, fsnotify.Event{Name: err.Position().Filename, Op: fsnotify.Write})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
c.errState.setBuildErr(nil)
|
var h *hugolib.HugoSites
|
||||||
h, err := c.hugo()
|
h, err = c.hugo()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return
|
||||||
}
|
}
|
||||||
|
err = h.Build(hugolib.BuildCfg{NoBuildLock: true, RecentlyVisited: c.visitedURLs, ErrRecovery: c.errState.wasErr()}, events...)
|
||||||
return h.Build(hugolib.BuildCfg{NoBuildLock: true, RecentlyVisited: c.visitedURLs, ErrRecovery: c.errState.wasErr()}, events...)
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *hugoBuilder) rebuildSitesForChanges(ids []identity.Identity) error {
|
func (c *hugoBuilder) rebuildSitesForChanges(ids []identity.Identity) (err error) {
|
||||||
c.errState.setBuildErr(nil)
|
defer func() {
|
||||||
h, err := c.hugo()
|
c.errState.setBuildErr(err)
|
||||||
|
}()
|
||||||
|
|
||||||
|
var h *hugolib.HugoSites
|
||||||
|
h, err = c.hugo()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return
|
||||||
}
|
}
|
||||||
whatChanged := &hugolib.WhatChanged{}
|
whatChanged := &hugolib.WhatChanged{}
|
||||||
whatChanged.Add(ids...)
|
whatChanged.Add(ids...)
|
||||||
err = h.Build(hugolib.BuildCfg{NoBuildLock: true, WhatChanged: whatChanged, RecentlyVisited: c.visitedURLs, ErrRecovery: c.errState.wasErr()})
|
err = h.Build(hugolib.BuildCfg{NoBuildLock: true, WhatChanged: whatChanged, RecentlyVisited: c.visitedURLs, ErrRecovery: c.errState.wasErr()})
|
||||||
c.errState.setBuildErr(err)
|
|
||||||
return err
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *hugoBuilder) reloadConfig() error {
|
func (c *hugoBuilder) reloadConfig() error {
|
||||||
c.r.Reset()
|
c.r.resetLogs()
|
||||||
c.r.configVersionID.Add(1)
|
c.r.configVersionID.Add(1)
|
||||||
|
|
||||||
if err := c.withConfE(func(conf *commonConfig) error {
|
if err := c.withConfE(func(conf *commonConfig) error {
|
||||||
|
|||||||
+11
-13
@@ -648,9 +648,8 @@ func (c *serverCommand) setServerInfoInConfig() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *serverCommand) getErrorWithContext() any {
|
func (c *serverCommand) getErrorWithContext() any {
|
||||||
errCount := c.errCount()
|
buildErr := c.errState.buildErr()
|
||||||
|
if buildErr == nil {
|
||||||
if errCount == 0 {
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -659,7 +658,7 @@ func (c *serverCommand) getErrorWithContext() any {
|
|||||||
m["Error"] = cleanErrorLog(c.r.logger.Errors())
|
m["Error"] = cleanErrorLog(c.r.logger.Errors())
|
||||||
|
|
||||||
m["Version"] = hugo.BuildVersionString()
|
m["Version"] = hugo.BuildVersionString()
|
||||||
ferrors := herrors.UnwrapFileErrorsWithErrorContext(c.errState.buildErr())
|
ferrors := herrors.UnwrapFileErrorsWithErrorContext(buildErr)
|
||||||
m["Files"] = ferrors
|
m["Files"] = ferrors
|
||||||
|
|
||||||
return m
|
return m
|
||||||
@@ -830,22 +829,25 @@ func (c *serverCommand) fixURL(baseURLFromConfig, baseURLFromFlag string, port i
|
|||||||
return u.String(), nil
|
return u.String(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *serverCommand) partialReRender(urls ...string) error {
|
func (c *serverCommand) partialReRender(urls ...string) (err error) {
|
||||||
defer func() {
|
defer func() {
|
||||||
c.errState.setWasErr(false)
|
c.errState.setWasErr(false)
|
||||||
}()
|
}()
|
||||||
c.errState.setBuildErr(nil)
|
|
||||||
visited := types.NewEvictingStringQueue(len(urls))
|
visited := types.NewEvictingStringQueue(len(urls))
|
||||||
for _, url := range urls {
|
for _, url := range urls {
|
||||||
visited.Add(url)
|
visited.Add(url)
|
||||||
}
|
}
|
||||||
|
|
||||||
h, err := c.hugo()
|
var h *hugolib.HugoSites
|
||||||
|
h, err = c.hugo()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Note: We do not set NoBuildLock as the file lock is not acquired at this stage.
|
// Note: We do not set NoBuildLock as the file lock is not acquired at this stage.
|
||||||
return h.Build(hugolib.BuildCfg{NoBuildLock: false, RecentlyVisited: visited, PartialReRender: true, ErrRecovery: c.errState.wasErr()})
|
err = h.Build(hugolib.BuildCfg{NoBuildLock: false, RecentlyVisited: visited, PartialReRender: true, ErrRecovery: c.errState.wasErr()})
|
||||||
|
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *serverCommand) serve() error {
|
func (c *serverCommand) serve() error {
|
||||||
@@ -1012,10 +1014,6 @@ func (c *serverCommand) serve() error {
|
|||||||
c.r.Println("Error:", err)
|
c.r.Println("Error:", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if h := c.hugoTry(); h != nil {
|
|
||||||
h.Close()
|
|
||||||
}
|
|
||||||
|
|
||||||
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
|
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
|
||||||
defer cancel()
|
defer cancel()
|
||||||
wg2, ctx := errgroup.WithContext(ctx)
|
wg2, ctx := errgroup.WithContext(ctx)
|
||||||
|
|||||||
@@ -137,7 +137,7 @@ var nilPointerErrRe = regexp.MustCompile(`at <(.*)>: error calling (.*?): runtim
|
|||||||
|
|
||||||
const deferredPrefix = "__hdeferred/"
|
const deferredPrefix = "__hdeferred/"
|
||||||
|
|
||||||
var deferredStringToRemove = regexp.MustCompile(`executing "__hdeferred/.*" `)
|
var deferredStringToRemove = regexp.MustCompile(`executing "__hdeferred/.*?" `)
|
||||||
|
|
||||||
// ImproveRenderErr improves the error message for rendering errors.
|
// ImproveRenderErr improves the error message for rendering errors.
|
||||||
func ImproveRenderErr(inErr error) (outErr error) {
|
func ImproveRenderErr(inErr error) (outErr error) {
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ package hugo
|
|||||||
// This should be the only one.
|
// This should be the only one.
|
||||||
var CurrentVersion = Version{
|
var CurrentVersion = Version{
|
||||||
Major: 0,
|
Major: 0,
|
||||||
Minor: 136,
|
Minor: 137,
|
||||||
PatchLevel: 2,
|
PatchLevel: 0,
|
||||||
Suffix: "",
|
Suffix: "-DEV",
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,8 +11,8 @@
|
|||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
//go:build !nodeploy
|
//go:build withdeploy
|
||||||
// +build !nodeploy
|
// +build withdeploy
|
||||||
|
|
||||||
package deploy
|
package deploy
|
||||||
|
|
||||||
|
|||||||
+2
-2
@@ -11,8 +11,8 @@
|
|||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
//go:build !nodeploy
|
//go:build withdeploy
|
||||||
// +build !nodeploy
|
// +build withdeploy
|
||||||
|
|
||||||
package deploy
|
package deploy
|
||||||
|
|
||||||
|
|||||||
@@ -11,8 +11,8 @@
|
|||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
//go:build !solaris && !nodeploy
|
//go:build !solaris && withdeploy
|
||||||
// +build !solaris,!nodeploy
|
// +build !solaris,withdeploy
|
||||||
|
|
||||||
package deploy
|
package deploy
|
||||||
|
|
||||||
|
|||||||
@@ -11,8 +11,8 @@
|
|||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
//go:build !nodeploy
|
//go:build withdeploy
|
||||||
// +build !nodeploy
|
// +build withdeploy
|
||||||
|
|
||||||
package deploy
|
package deploy
|
||||||
|
|
||||||
|
|||||||
@@ -11,8 +11,8 @@
|
|||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
//go:build !nodeploy
|
//go:build withdeploy
|
||||||
// +build !nodeploy
|
// +build withdeploy
|
||||||
|
|
||||||
package deployconfig
|
package deployconfig
|
||||||
|
|
||||||
|
|||||||
+2
-2
@@ -11,8 +11,8 @@
|
|||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
//go:build !nodeploy
|
//go:build withdeploy
|
||||||
// +build !nodeploy
|
// +build withdeploy
|
||||||
|
|
||||||
package deploy
|
package deploy
|
||||||
|
|
||||||
|
|||||||
Vendored
+7
@@ -98,6 +98,8 @@ type Deps struct {
|
|||||||
// TODO(bep) rethink this re. a plugin setup, but this will have to do for now.
|
// TODO(bep) rethink this re. a plugin setup, but this will have to do for now.
|
||||||
WasmDispatchers *warpc.Dispatchers
|
WasmDispatchers *warpc.Dispatchers
|
||||||
|
|
||||||
|
isClosed bool
|
||||||
|
|
||||||
*globalErrHandler
|
*globalErrHandler
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -345,6 +347,11 @@ func (d *Deps) TextTmpl() tpl.TemplateParseFinder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (d *Deps) Close() error {
|
func (d *Deps) Close() error {
|
||||||
|
if d.isClosed {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
d.isClosed = true
|
||||||
|
|
||||||
if d.MemCache != nil {
|
if d.MemCache != nil {
|
||||||
d.MemCache.Stop()
|
d.MemCache.Stop()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ require (
|
|||||||
github.com/bep/gowebp v0.3.0
|
github.com/bep/gowebp v0.3.0
|
||||||
github.com/bep/helpers v0.5.0
|
github.com/bep/helpers v0.5.0
|
||||||
github.com/bep/imagemeta v0.8.1
|
github.com/bep/imagemeta v0.8.1
|
||||||
github.com/bep/lazycache v0.4.0
|
github.com/bep/lazycache v0.7.0
|
||||||
github.com/bep/logg v0.4.0
|
github.com/bep/logg v0.4.0
|
||||||
github.com/bep/mclib v1.20400.20402
|
github.com/bep/mclib v1.20400.20402
|
||||||
github.com/bep/overlayfs v0.9.2
|
github.com/bep/overlayfs v0.9.2
|
||||||
|
|||||||
@@ -143,6 +143,10 @@ github.com/bep/imagemeta v0.8.1 h1:tjZLPRftjxU7PTI87o5e5WKOFQ4S9S0engiP1OTpJTI=
|
|||||||
github.com/bep/imagemeta v0.8.1/go.mod h1:5piPAq5Qomh07m/dPPCLN3mDJyFusvUG7VwdRD/vX0s=
|
github.com/bep/imagemeta v0.8.1/go.mod h1:5piPAq5Qomh07m/dPPCLN3mDJyFusvUG7VwdRD/vX0s=
|
||||||
github.com/bep/lazycache v0.4.0 h1:X8yVyWNVupPd4e1jV7efi3zb7ZV/qcjKQgIQ5aPbkYI=
|
github.com/bep/lazycache v0.4.0 h1:X8yVyWNVupPd4e1jV7efi3zb7ZV/qcjKQgIQ5aPbkYI=
|
||||||
github.com/bep/lazycache v0.4.0/go.mod h1:NmRm7Dexh3pmR1EignYR8PjO2cWybFQ68+QgY3VMCSc=
|
github.com/bep/lazycache v0.4.0/go.mod h1:NmRm7Dexh3pmR1EignYR8PjO2cWybFQ68+QgY3VMCSc=
|
||||||
|
github.com/bep/lazycache v0.6.0 h1:0vCgFo7TBtMQpSx64jnH1sagmw0ZougIFRpsqPHTa5U=
|
||||||
|
github.com/bep/lazycache v0.6.0/go.mod h1:NmRm7Dexh3pmR1EignYR8PjO2cWybFQ68+QgY3VMCSc=
|
||||||
|
github.com/bep/lazycache v0.7.0 h1:VM257SkkjcR9z55eslXTkUIX8QMNKoqQRNKV/4xIkCY=
|
||||||
|
github.com/bep/lazycache v0.7.0/go.mod h1:NmRm7Dexh3pmR1EignYR8PjO2cWybFQ68+QgY3VMCSc=
|
||||||
github.com/bep/logg v0.4.0 h1:luAo5mO4ZkhA5M1iDVDqDqnBBnlHjmtZF6VAyTp+nCQ=
|
github.com/bep/logg v0.4.0 h1:luAo5mO4ZkhA5M1iDVDqDqnBBnlHjmtZF6VAyTp+nCQ=
|
||||||
github.com/bep/logg v0.4.0/go.mod h1:Ccp9yP3wbR1mm++Kpxet91hAZBEQgmWgFgnXX3GkIV0=
|
github.com/bep/logg v0.4.0/go.mod h1:Ccp9yP3wbR1mm++Kpxet91hAZBEQgmWgFgnXX3GkIV0=
|
||||||
github.com/bep/mclib v1.20400.20402 h1:olpCE2WSPpOAbFE1R4hnftSEmQ34+xzy2HRzd0m69rA=
|
github.com/bep/mclib v1.20400.20402 h1:olpCE2WSPpOAbFE1R4hnftSEmQ34+xzy2HRzd0m69rA=
|
||||||
|
|||||||
@@ -179,9 +179,6 @@ type hugoSitesInit struct {
|
|||||||
// Loads the data from all of the /data folders.
|
// Loads the data from all of the /data folders.
|
||||||
data *lazy.Init
|
data *lazy.Init
|
||||||
|
|
||||||
// Performs late initialization (before render) of the templates.
|
|
||||||
layouts *lazy.Init
|
|
||||||
|
|
||||||
// Loads the Git info and CODEOWNERS for all the pages if enabled.
|
// Loads the Git info and CODEOWNERS for all the pages if enabled.
|
||||||
gitInfo *lazy.Init
|
gitInfo *lazy.Init
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -250,10 +250,6 @@ func (h *HugoSites) process(ctx context.Context, l logg.LevelLogger, config *Bui
|
|||||||
l = l.WithField("step", "process")
|
l = l.WithField("step", "process")
|
||||||
defer loggers.TimeTrackf(l, time.Now(), nil, "")
|
defer loggers.TimeTrackf(l, time.Now(), nil, "")
|
||||||
|
|
||||||
if _, err := h.init.layouts.Do(ctx); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(events) > 0 {
|
if len(events) > 0 {
|
||||||
// This is a rebuild triggered from file events.
|
// This is a rebuild triggered from file events.
|
||||||
return h.processPartialFileEvents(ctx, l, config, init, events)
|
return h.processPartialFileEvents(ctx, l, config, init, events)
|
||||||
@@ -1067,8 +1063,6 @@ func (h *HugoSites) processPartialFileEvents(ctx context.Context, l logg.LevelLo
|
|||||||
}
|
}
|
||||||
|
|
||||||
if tmplChanged || i18nChanged {
|
if tmplChanged || i18nChanged {
|
||||||
// TODO(bep) we should split this, but currently the loading of i18n and layout files are tied together. See #12048.
|
|
||||||
h.init.layouts.Reset()
|
|
||||||
if err := loggers.TimeTrackfn(func() (logg.LevelLogger, error) {
|
if err := loggers.TimeTrackfn(func() (logg.LevelLogger, error) {
|
||||||
// TODO(bep) this could probably be optimized to somehow
|
// TODO(bep) this could probably be optimized to somehow
|
||||||
// only load the changed templates and its dependencies, but that is non-trivial.
|
// only load the changed templates and its dependencies, but that is non-trivial.
|
||||||
@@ -1141,10 +1135,6 @@ func (s *Site) handleContentAdapterChanges(bi pagesfromdata.BuildInfo, buildConf
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (h *HugoSites) processContentAdaptersOnRebuild(ctx context.Context, buildConfig *BuildCfg) error {
|
func (h *HugoSites) processContentAdaptersOnRebuild(ctx context.Context, buildConfig *BuildCfg) error {
|
||||||
// Make sure the layouts are initialized.
|
|
||||||
if _, err := h.init.layouts.Do(context.Background()); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
g := rungroup.Run[*pagesfromdata.PagesFromTemplate](ctx, rungroup.Config[*pagesfromdata.PagesFromTemplate]{
|
g := rungroup.Run[*pagesfromdata.PagesFromTemplate](ctx, rungroup.Config[*pagesfromdata.PagesFromTemplate]{
|
||||||
NumWorkers: h.numWorkers,
|
NumWorkers: h.numWorkers,
|
||||||
Handle: func(ctx context.Context, p *pagesfromdata.PagesFromTemplate) error {
|
Handle: func(ctx context.Context, p *pagesfromdata.PagesFromTemplate) error {
|
||||||
|
|||||||
@@ -246,11 +246,6 @@ func (s *IntegrationTestBuilder) AssertBuildCountGitInfo(count int) {
|
|||||||
s.Assert(s.H.init.gitInfo.InitCount(), qt.Equals, count)
|
s.Assert(s.H.init.gitInfo.InitCount(), qt.Equals, count)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *IntegrationTestBuilder) AssertBuildCountLayouts(count int) {
|
|
||||||
s.Helper()
|
|
||||||
s.Assert(s.H.init.layouts.InitCount(), qt.Equals, count)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *IntegrationTestBuilder) AssertFileCount(dirname string, expected int) {
|
func (s *IntegrationTestBuilder) AssertFileCount(dirname string, expected int) {
|
||||||
s.Helper()
|
s.Helper()
|
||||||
fs := s.fs.WorkingDirReadOnly
|
fs := s.fs.WorkingDirReadOnly
|
||||||
@@ -421,6 +416,12 @@ func (s *IntegrationTestBuilder) Build() *IntegrationTestBuilder {
|
|||||||
s.Assert(err, qt.IsNil)
|
s.Assert(err, qt.IsNil)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
s.Cleanup(func() {
|
||||||
|
if h := s.H; h != nil {
|
||||||
|
s.Assert(h.Close(), qt.IsNil)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -34,6 +34,15 @@ import (
|
|||||||
var pageIDCounter atomic.Uint64
|
var pageIDCounter atomic.Uint64
|
||||||
|
|
||||||
func (h *HugoSites) newPage(m *pageMeta) (*pageState, *paths.Path, error) {
|
func (h *HugoSites) newPage(m *pageMeta) (*pageState, *paths.Path, error) {
|
||||||
|
p, pth, err := h.doNewPage(m)
|
||||||
|
if err != nil {
|
||||||
|
// Make sure that any partially created page part is marked as stale.
|
||||||
|
m.MarkStale()
|
||||||
|
}
|
||||||
|
return p, pth, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *HugoSites) doNewPage(m *pageMeta) (*pageState, *paths.Path, error) {
|
||||||
m.Staler = &resources.AtomicStaler{}
|
m.Staler = &resources.AtomicStaler{}
|
||||||
if m.pageMetaParams == nil {
|
if m.pageMetaParams == nil {
|
||||||
m.pageMetaParams = &pageMetaParams{
|
m.pageMetaParams = &pageMetaParams{
|
||||||
@@ -231,10 +240,6 @@ func (h *HugoSites) newPage(m *pageMeta) (*pageState, *paths.Path, error) {
|
|||||||
}
|
}
|
||||||
return ps, nil
|
return ps, nil
|
||||||
}()
|
}()
|
||||||
// Make sure to evict any cached and now stale data.
|
|
||||||
if err != nil {
|
|
||||||
m.MarkStale()
|
|
||||||
}
|
|
||||||
|
|
||||||
if ps == nil {
|
if ps == nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
|
|||||||
@@ -344,7 +344,6 @@ func newHugoSites(cfg deps.DepsCfg, d *deps.Deps, pageTrees *pageTrees, sites []
|
|||||||
skipRebuildForFilenames: make(map[string]bool),
|
skipRebuildForFilenames: make(map[string]bool),
|
||||||
init: &hugoSitesInit{
|
init: &hugoSitesInit{
|
||||||
data: lazy.New(),
|
data: lazy.New(),
|
||||||
layouts: lazy.New(),
|
|
||||||
gitInfo: lazy.New(),
|
gitInfo: lazy.New(),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@@ -400,15 +399,6 @@ func newHugoSites(cfg deps.DepsCfg, d *deps.Deps, pageTrees *pageTrees, sites []
|
|||||||
return nil, nil
|
return nil, nil
|
||||||
})
|
})
|
||||||
|
|
||||||
h.init.layouts.Add(func(context.Context) (any, error) {
|
|
||||||
for _, s := range h.Sites {
|
|
||||||
if err := s.Tmpl().(tpl.TemplateManager).MarkReady(); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil, nil
|
|
||||||
})
|
|
||||||
|
|
||||||
h.init.gitInfo.Add(func(context.Context) (any, error) {
|
h.init.gitInfo.Add(func(context.Context) (any, error) {
|
||||||
err := h.loadGitInfo()
|
err := h.loadGitInfo()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
+5
-2
@@ -1,7 +1,10 @@
|
|||||||
# Release env.
|
# Release env.
|
||||||
# These will be replaced by script before release.
|
# These will be replaced by script before release.
|
||||||
HUGORELEASER_TAG=v0.136.1
|
HUGORELEASER_TAG=v0.136.5
|
||||||
HUGORELEASER_COMMITISH=64d1865c1e21c66feb96ffedda44a9eba2365af9
|
HUGORELEASER_COMMITISH=46cccb021bc6425455f4eec093f5cc4a32f1d12c
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -119,6 +119,24 @@ archive_alias_replacements = { "linux-amd64.tar.gz" = "Linux-64bit.tar.gz" }
|
|||||||
[[builds.os.archs]]
|
[[builds.os.archs]]
|
||||||
goarch = "amd64"
|
goarch = "amd64"
|
||||||
|
|
||||||
|
[[builds]]
|
||||||
|
path = "container1/unix/extended-withdeploy"
|
||||||
|
|
||||||
|
[builds.build_settings]
|
||||||
|
flags = ["-buildmode", "exe", "-tags", "extended,withdeploy"]
|
||||||
|
env = ["CGO_ENABLED=1"]
|
||||||
|
|
||||||
|
[[builds.os]]
|
||||||
|
goos = "darwin"
|
||||||
|
[builds.os.build_settings]
|
||||||
|
env = ["CGO_ENABLED=1", "CC=o64-clang", "CXX=o64-clang++"]
|
||||||
|
[[builds.os.archs]]
|
||||||
|
goarch = "universal"
|
||||||
|
[[builds.os]]
|
||||||
|
goos = "linux"
|
||||||
|
[[builds.os.archs]]
|
||||||
|
goarch = "amd64"
|
||||||
|
|
||||||
[[builds]]
|
[[builds]]
|
||||||
path = "container2/linux/extended"
|
path = "container2/linux/extended"
|
||||||
|
|
||||||
@@ -173,6 +191,10 @@ archive_alias_replacements = { "linux-amd64.tar.gz" = "Linux-64bit.tar.gz" }
|
|||||||
paths = ["builds/container1/unix/extended/**"]
|
paths = ["builds/container1/unix/extended/**"]
|
||||||
[archives.archive_settings]
|
[archives.archive_settings]
|
||||||
name_template = "{{ .Project }}_extended_{{ .Tag | trimPrefix `v` }}_{{ .Goos }}-{{ .Goarch }}"
|
name_template = "{{ .Project }}_extended_{{ .Tag | trimPrefix `v` }}_{{ .Goos }}-{{ .Goarch }}"
|
||||||
|
[[archives]]
|
||||||
|
paths = ["builds/container1/unix/extended-withdeploy/**"]
|
||||||
|
[archives.archive_settings]
|
||||||
|
name_template = "{{ .Project }}_extended_withdeploy_{{ .Tag | trimPrefix `v` }}_{{ .Goos }}-{{ .Goarch }}"
|
||||||
[[archives]]
|
[[archives]]
|
||||||
# Only extended builds in container2.
|
# Only extended builds in container2.
|
||||||
paths = ["builds/container2/**"]
|
paths = ["builds/container2/**"]
|
||||||
|
|||||||
+1
-1
@@ -334,7 +334,7 @@ func buildFlags() []string {
|
|||||||
func buildTags() string {
|
func buildTags() string {
|
||||||
// To build the extended Hugo SCSS/SASS enabled version, build with
|
// To build the extended Hugo SCSS/SASS enabled version, build with
|
||||||
// HUGO_BUILD_TAGS=extended mage install etc.
|
// HUGO_BUILD_TAGS=extended mage install etc.
|
||||||
// To build without `hugo deploy` for smaller binary, use HUGO_BUILD_TAGS=nodeploy
|
// To build with `hugo deploy`, use HUGO_BUILD_TAGS=withdeploy
|
||||||
if envtags := os.Getenv("HUGO_BUILD_TAGS"); envtags != "" {
|
if envtags := os.Getenv("HUGO_BUILD_TAGS"); envtags != "" {
|
||||||
return envtags
|
return envtags
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,29 @@
|
|||||||
|
// Copyright 2024 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.
|
||||||
|
|
||||||
|
//go:build withdeploy
|
||||||
|
// +build withdeploy
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/rogpeppe/go-internal/testscript"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestWithdeploy(t *testing.T) {
|
||||||
|
p := commonTestScriptsParam
|
||||||
|
p.Dir = "testscripts/withdeploy"
|
||||||
|
testscript.Run(t, p)
|
||||||
|
}
|
||||||
@@ -1,17 +1,12 @@
|
|||||||
# Test the gen commands.
|
# Test the gen commands.
|
||||||
# Note that adding new commands will require updating the NUM_COMMANDS value.
|
|
||||||
env NUM_COMMANDS=44
|
|
||||||
|
|
||||||
hugo gen -h
|
hugo gen -h
|
||||||
stdout 'Generate documentation for your project using Hugo''s documentation engine, including syntax highlighting for various programming languages\.'
|
stdout 'Generate documentation for your project using Hugo''s documentation engine, including syntax highlighting for various programming languages\.'
|
||||||
|
|
||||||
hugo gen doc --dir clidocs
|
hugo gen doc --dir clidocs
|
||||||
checkfilecount $NUM_COMMANDS clidocs
|
|
||||||
|
|
||||||
hugo gen man -h
|
hugo gen man -h
|
||||||
stdout 'up-to-date man pages'
|
stdout 'up-to-date man pages'
|
||||||
hugo gen man --dir manpages
|
hugo gen man --dir manpages
|
||||||
checkfilecount $NUM_COMMANDS manpages
|
|
||||||
|
|
||||||
hugo gen chromastyles -h
|
hugo gen chromastyles -h
|
||||||
stdout 'Generate CSS stylesheet for the Chroma code highlighter'
|
stdout 'Generate CSS stylesheet for the Chroma code highlighter'
|
||||||
|
|||||||
@@ -0,0 +1,42 @@
|
|||||||
|
# Test the hugo server command when adding an error to a config file
|
||||||
|
# and then fixing it.
|
||||||
|
|
||||||
|
hugo server &
|
||||||
|
|
||||||
|
waitServer
|
||||||
|
|
||||||
|
httpget ${HUGOTEST_BASEURL_0}p1/ 'Title: P1'
|
||||||
|
|
||||||
|
replace $WORK/hugo.toml 'title =' 'titlefoo'
|
||||||
|
httpget ${HUGOTEST_BASEURL_0}p1/ 'failed'
|
||||||
|
|
||||||
|
replace $WORK/hugo.toml 'titlefoo' 'title ='
|
||||||
|
httpget ${HUGOTEST_BASEURL_0}p1/ 'Title: P1'
|
||||||
|
|
||||||
|
stopServer
|
||||||
|
|
||||||
|
-- hugo.toml --
|
||||||
|
title = "Hugo Server Test"
|
||||||
|
baseURL = "https://example.org/"
|
||||||
|
disableKinds = ["taxonomy", "term", "sitemap"]
|
||||||
|
-- layouts/index.html --
|
||||||
|
Title: {{ .Title }}|BaseURL: {{ site.BaseURL }}|
|
||||||
|
-- layouts/_default/single.html --
|
||||||
|
Title: {{ .Title }}|BaseURL: {{ site.BaseURL }}|
|
||||||
|
-- content/_index.md --
|
||||||
|
---
|
||||||
|
title: Hugo Home
|
||||||
|
---
|
||||||
|
-- content/p1/index.md --
|
||||||
|
---
|
||||||
|
title: P1
|
||||||
|
---
|
||||||
|
-- content/p2/index.md --
|
||||||
|
---
|
||||||
|
title: P2
|
||||||
|
---
|
||||||
|
-- static/staticfiles/static.txt --
|
||||||
|
static
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
# Test the hugo server command when adding a front matter error to a content file
|
||||||
|
# and then fixing it.
|
||||||
|
|
||||||
|
hugo server &
|
||||||
|
|
||||||
|
waitServer
|
||||||
|
|
||||||
|
httpget ${HUGOTEST_BASEURL_0}p1/ 'Title: P1'
|
||||||
|
|
||||||
|
replace $WORK/content/p1/index.md 'title:' 'titlecolon'
|
||||||
|
httpget ${HUGOTEST_BASEURL_0}p1/ 'failed'
|
||||||
|
|
||||||
|
replace $WORK/content/p1/index.md 'titlecolon' 'title:'
|
||||||
|
httpget ${HUGOTEST_BASEURL_0}p1/ 'Title: P1'
|
||||||
|
|
||||||
|
stopServer
|
||||||
|
|
||||||
|
-- hugo.toml --
|
||||||
|
title = "Hugo Server Test"
|
||||||
|
baseURL = "https://example.org/"
|
||||||
|
disableKinds = ["taxonomy", "term", "sitemap"]
|
||||||
|
-- layouts/index.html --
|
||||||
|
Title: {{ .Title }}|BaseURL: {{ site.BaseURL }}|
|
||||||
|
-- layouts/_default/single.html --
|
||||||
|
Title: {{ .Title }}|BaseURL: {{ site.BaseURL }}|
|
||||||
|
-- content/_index.md --
|
||||||
|
---
|
||||||
|
title: Hugo Home
|
||||||
|
---
|
||||||
|
-- content/p1/index.md --
|
||||||
|
---
|
||||||
|
title: P1
|
||||||
|
---
|
||||||
|
-- content/p2/index.md --
|
||||||
|
---
|
||||||
|
title: P2
|
||||||
|
---
|
||||||
|
-- static/staticfiles/static.txt --
|
||||||
|
static
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -450,6 +450,17 @@ func (ns *Namespace) Trim(s, cutset any) (string, error) {
|
|||||||
return strings.Trim(ss, sc), nil
|
return strings.Trim(ss, sc), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TrimSpace returns the given string, removing leading and trailing whitespace
|
||||||
|
// as defined by Unicode.
|
||||||
|
func (ns *Namespace) TrimSpace(s any) (string, error) {
|
||||||
|
ss, err := cast.ToStringE(s)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
return strings.TrimSpace(ss), nil
|
||||||
|
}
|
||||||
|
|
||||||
// TrimLeft returns a slice of the string s with all leading characters
|
// TrimLeft returns a slice of the string s with all leading characters
|
||||||
// contained in cutset removed.
|
// contained in cutset removed.
|
||||||
func (ns *Namespace) TrimLeft(cutset, s any) (string, error) {
|
func (ns *Namespace) TrimLeft(cutset, s any) (string, error) {
|
||||||
|
|||||||
@@ -854,3 +854,30 @@ func TestDiff(t *testing.T) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestTrimSpace(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
c := qt.New(t)
|
||||||
|
|
||||||
|
for _, test := range []struct {
|
||||||
|
s any
|
||||||
|
expect any
|
||||||
|
}{
|
||||||
|
{"\n\r test \n\r", "test"},
|
||||||
|
{template.HTML("\n\r test \n\r"), "test"},
|
||||||
|
{[]byte("\n\r test \n\r"), "test"},
|
||||||
|
// errors
|
||||||
|
{tstNoStringer{}, false},
|
||||||
|
} {
|
||||||
|
|
||||||
|
result, err := ns.TrimSpace(test.s)
|
||||||
|
|
||||||
|
if b, ok := test.expect.(bool); ok && !b {
|
||||||
|
c.Assert(err, qt.Not(qt.IsNil))
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
c.Assert(err, qt.IsNil)
|
||||||
|
c.Assert(result, qt.Equals, test.expect)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -40,7 +40,6 @@ type TemplateManager interface {
|
|||||||
TemplateHandler
|
TemplateHandler
|
||||||
TemplateFuncGetter
|
TemplateFuncGetter
|
||||||
AddTemplate(name, tpl string) error
|
AddTemplate(name, tpl string) error
|
||||||
MarkReady() error
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// TemplateVariants describes the possible variants of a template.
|
// TemplateVariants describes the possible variants of a template.
|
||||||
|
|||||||
+4
-17
@@ -168,6 +168,10 @@ func newTemplateHandlers(d *deps.Deps) (*tpl.TemplateHandlers, error) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if err := h.main.createPrototypes(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
e := &templateExec{
|
e := &templateExec{
|
||||||
d: d,
|
d: d,
|
||||||
executor: exec,
|
executor: exec,
|
||||||
@@ -312,28 +316,11 @@ func (t *templateExec) GetFunc(name string) (reflect.Value, bool) {
|
|||||||
return v, found
|
return v, found
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *templateExec) MarkReady() error {
|
|
||||||
var err error
|
|
||||||
t.readyInit.Do(func() {
|
|
||||||
// We only need the clones if base templates are in use.
|
|
||||||
if len(t.needsBaseof) > 0 {
|
|
||||||
err = t.main.createPrototypes()
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
type templateHandler struct {
|
type templateHandler struct {
|
||||||
main *templateNamespace
|
main *templateNamespace
|
||||||
needsBaseof map[string]templateInfo
|
needsBaseof map[string]templateInfo
|
||||||
baseof map[string]templateInfo
|
baseof map[string]templateInfo
|
||||||
|
|
||||||
readyInit sync.Once
|
|
||||||
|
|
||||||
// This is the filesystem to load the templates from. All the templates are
|
// This is the filesystem to load the templates from. All the templates are
|
||||||
// stored in the root of this filesystem.
|
// stored in the root of this filesystem.
|
||||||
layoutsFs afero.Fs
|
layoutsFs afero.Fs
|
||||||
|
|||||||
@@ -248,7 +248,7 @@ func TestToMathMacros(t *testing.T) {
|
|||||||
-- hugo.toml --
|
-- hugo.toml --
|
||||||
disableKinds = ['page','rss','section','sitemap','taxonomy','term']
|
disableKinds = ['page','rss','section','sitemap','taxonomy','term']
|
||||||
-- layouts/index.html --
|
-- layouts/index.html --
|
||||||
{{ $macros := dict
|
{{ $macros := dict
|
||||||
"\\addBar" "\\bar{#1}"
|
"\\addBar" "\\bar{#1}"
|
||||||
"\\bold" "\\mathbf{#1}"
|
"\\bold" "\\mathbf{#1}"
|
||||||
}}
|
}}
|
||||||
@@ -261,3 +261,21 @@ disableKinds = ['page','rss','section','sitemap','taxonomy','term']
|
|||||||
<mi>y</mi>
|
<mi>y</mi>
|
||||||
`)
|
`)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Issue #12977
|
||||||
|
func TestUnmarshalWithIndentedYAML(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
files := `
|
||||||
|
-- hugo.toml --
|
||||||
|
disableKinds = ['page','rss','section','sitemap','taxonomy','term']
|
||||||
|
-- layouts/index.html --
|
||||||
|
{{ $yaml := "\n a:\n b: 1\n c:\n d: 2\n" }}
|
||||||
|
{{ $yaml | transform.Unmarshal | encoding.Jsonify }}
|
||||||
|
`
|
||||||
|
|
||||||
|
b := hugolib.Test(t, files)
|
||||||
|
|
||||||
|
b.AssertFileExists("public/index.html", true)
|
||||||
|
b.AssertFileContent("public/index.html", `{"a":{"b":1},"c":{"d":2}}`)
|
||||||
|
}
|
||||||
|
|||||||
@@ -113,8 +113,8 @@ func (ns *Namespace) Unmarshal(args ...any) (any, error) {
|
|||||||
return nil, fmt.Errorf("type %T not supported", data)
|
return nil, fmt.Errorf("type %T not supported", data)
|
||||||
}
|
}
|
||||||
|
|
||||||
if dataStr == "" {
|
if strings.TrimSpace(dataStr) == "" {
|
||||||
return nil, errors.New("no data to transform")
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
key := hashing.MD5FromStringHexEncoded(dataStr)
|
key := hashing.MD5FromStringHexEncoded(dataStr)
|
||||||
|
|||||||
@@ -139,6 +139,8 @@ func TestUnmarshal(t *testing.T) {
|
|||||||
a;b;c`, mime: media.Builtin.CSVType}, map[string]any{"DElimiter": ";", "Comment": "%"}, func(r [][]string) {
|
a;b;c`, mime: media.Builtin.CSVType}, map[string]any{"DElimiter": ";", "Comment": "%"}, func(r [][]string) {
|
||||||
b.Assert([][]string{{"a", "b", "c"}}, qt.DeepEquals, r)
|
b.Assert([][]string{{"a", "b", "c"}}, qt.DeepEquals, r)
|
||||||
}},
|
}},
|
||||||
|
{``, nil, nil},
|
||||||
|
{` `, nil, nil},
|
||||||
// errors
|
// errors
|
||||||
{"thisisnotavaliddataformat", nil, false},
|
{"thisisnotavaliddataformat", nil, false},
|
||||||
{testContentResource{key: "r1", content: `invalid&toml"`, mime: media.Builtin.TOMLType}, nil, false},
|
{testContentResource{key: "r1", content: `invalid&toml"`, mime: media.Builtin.TOMLType}, nil, false},
|
||||||
|
|||||||
Reference in New Issue
Block a user