Compare commits

...

40 Commits

Author SHA1 Message Date
Bjørn Erik Pedersen 21e9cb7b79 dynacache: Fix potential deadlocks on panics in GetOrCreate 2024-10-26 18:26:11 +02:00
hugoreleaser ec3890affe releaser: Prepare repository for 0.137.0-DEV
[ci skip]
2024-10-24 12:41:02 +00:00
hugoreleaser 46cccb021b releaser: Bump versions for release of 0.136.5
[ci skip]
2024-10-24 12:26:27 +00:00
Bjørn Erik Pedersen cb6e27b32a hugolib/commands: Fix stuck server error issues
Fixes #11378
2024-10-24 13:34:11 +02:00
Joe Mooring 5bbe95f9c5 tpl/transform: Revert unmarshal whitespace removal
Fixes #12977
2024-10-22 09:42:40 +02:00
hugoreleaser 31d19b505d releaser: Prepare repository for 0.137.0-DEV
[ci skip]
2024-10-21 13:46:41 +00:00
hugoreleaser bfa2fd683e releaser: Bump versions for release of 0.136.3
[ci skip]
2024-10-21 13:31:54 +00:00
David Karlsson 88d598a049 docker: Fix permission issues in Dockerfile
Closes #12971
Closes #12970
2024-10-21 15:28:36 +02:00
Bjørn Erik Pedersen 352be5ba87 Make sure that HugoSites is always closed when done
Including all the integration tests.
2024-10-20 13:04:58 +02:00
Joe Mooring d37606d2c2 tpl/strings: Add TrimSpace function
Closes #12962
2024-10-19 21:10:00 +02:00
Bjørn Erik Pedersen f5e54d9c7d common/herrors: Fix the deferred error message cleaner regexp
Make it less gready.
2024-10-19 10:00:01 +02:00
Bjørn Erik Pedersen 42f37b4e98 tpl/transform: Don't fail on "no data to transform"
Fixes #12964
2024-10-18 10:30:36 +02:00
hugoreleaser e971b7d866 releaser: Prepare repository for 0.137.0-DEV
[ci skip]
2024-10-17 14:44:10 +00:00
hugoreleaser ad985550a4 releaser: Bump versions for release of 0.136.2
[ci skip]
2024-10-17 14:30:05 +00:00
David Karlsson b5852d0e68 docker: Fix Dart Sass ARM64 arch mismatch, /cache permissions
Also improve the final build step.

Closes #12956
Closes #12957
Closes #12960
2024-10-17 15:42:41 +02:00
hugoreleaser b5801d8b6a releaser: Prepare repository for 0.137.0-DEV
[ci skip]
2024-10-16 16:18:44 +00:00
hugoreleaser 64d1865c1e releaser: Bump versions for release of 0.136.1
[ci skip]
2024-10-16 16:05:18 +00:00
Bjørn Erik Pedersen e4ad0c5271 Never sanitize when url set in front matter
Fixes #12954
2024-10-16 18:01:11 +02:00
Bjørn Erik Pedersen a2f666b586 Remove erroneously permalink validation
Fixes #12948
2024-10-16 10:14:48 +02:00
Joe Mooring b1b3bbcdbd create/skeletons: Add delimiters to archetype front matter
Fixes #12945
2024-10-15 21:37:26 +02:00
hugoreleaser 1cfe9741b9 releaser: Prepare repository for 0.137.0-DEV
[ci skip]
2024-10-15 13:31:16 +00:00
hugoreleaser 2939270a3b releaser: Bump versions for release of 0.136.0
[ci skip]
2024-10-15 13:17:24 +00:00
Bjørn Erik Pedersen 5db27b19c1 circleci: Use default docker image 2024-10-15 15:15:12 +02:00
Bjørn Erik Pedersen b7d62d76c5 docs: Regen CLI docs 2024-10-15 10:30:35 +02:00
Bjørn Erik Pedersen 6e1c5b61b3 resources/page: Adjust the permalinks colon implementation a little
Mostly to get back to an attribute regexp that's reasonably simle to read/understand.

Updates #12918
2024-10-15 10:28:00 +02:00
n1xx1 e7d0757f95 resources/page: Allow colons in permalinks to be escaped
Updates #12918
2024-10-15 10:28:00 +02:00
Rohan Hasabe 6b5e117a12 commands: Use consistent style when describing subcommands
Closes #12897

Change-Id: Ib27a4a7b540d45243e6252db769d4b9fb7447718
Signed-off-by: Rohan Hasabe <rohanhasabe8@gmail.com>
2024-10-15 08:51:53 +02:00
dependabot[bot] 4985be1a4a build(deps): bump github.com/tetratelabs/wazero from 1.8.0 to 1.8.1
Bumps [github.com/tetratelabs/wazero](https://github.com/tetratelabs/wazero) from 1.8.0 to 1.8.1.
- [Release notes](https://github.com/tetratelabs/wazero/releases)
- [Commits](https://github.com/tetratelabs/wazero/compare/v1.8.0...v1.8.1)

---
updated-dependencies:
- dependency-name: github.com/tetratelabs/wazero
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-10-14 15:54:41 +02:00
dependabot[bot] db653a8485 build(deps): bump golang.org/x/image from 0.20.0 to 0.21.0
Bumps [golang.org/x/image](https://github.com/golang/image) from 0.20.0 to 0.21.0.
- [Commits](https://github.com/golang/image/compare/v0.20.0...v0.21.0)

---
updated-dependencies:
- dependency-name: golang.org/x/image
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-10-14 14:53:06 +02:00
dependabot[bot] 05bbd2c515 build(deps): bump github.com/yuin/goldmark-emoji from 1.0.3 to 1.0.4
Bumps [github.com/yuin/goldmark-emoji](https://github.com/yuin/goldmark-emoji) from 1.0.3 to 1.0.4.
- [Release notes](https://github.com/yuin/goldmark-emoji/releases)
- [Commits](https://github.com/yuin/goldmark-emoji/compare/v1.0.3...v1.0.4)

---
updated-dependencies:
- dependency-name: github.com/yuin/goldmark-emoji
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-10-14 14:52:12 +02:00
Bjørn Erik Pedersen 21366e0411 config: Imrove uglyurls section test
Updates #12926
2024-10-14 10:03:44 +02:00
Akkuman ea633dd809 config: Fix uglyurls map parse
Fixes #12926
2024-10-14 10:03:44 +02:00
Joe Mooring 57151a5e91 create/skeletons: Honor --format flag when creating default archetype
Closes #12666
2024-10-14 09:54:29 +02:00
Julia Evans 5bb22b6b4e hugolib: Make .Site.Author deprecation warning clearer
Fixes #12269
2024-10-14 09:16:11 +02:00
Bjørn Erik Pedersen 41f69a7255 Upgrade to latest Go version + Some Docker image improvements (note)
* Rename /site to /project
* Add ldflags
* Add go and node to the default image
* Add Dart Sass to the default image
* Build the extended version by default
* Add "npm i" install support with custom entry script override
* Adjust cache logic to speed up CGO rebuilds

Closes #12920
See #12885
2024-10-13 20:01:37 +02:00
David Karlsson 4a79956276 ci: Build multi-platform image with cross-compilation
The previous build workflow used emulation to build the Docker image,
which results in a somewhat complicated push-by-digest and merge
workflow to create a multi-platform image.

This commit changes the Docker build to use cross-compilation instead,
resulting in a faster and more straightforward build.

Signed-off-by: David Karlsson <35727626+dvdksn@users.noreply.github.com>
2024-10-13 20:01:37 +02:00
Patrice Chalin 039845804f tpl/tplimpl: Trim descriptions rather than just chomp 2024-10-12 22:41:42 +02:00
dependabot[bot] 9b635522e2 build(deps): bump golang.org/x/tools from 0.23.0 to 0.26.0
Bumps [golang.org/x/tools](https://github.com/golang/tools) from 0.23.0 to 0.26.0.
- [Release notes](https://github.com/golang/tools/releases)
- [Commits](https://github.com/golang/tools/compare/v0.23.0...v0.26.0)

---
updated-dependencies:
- dependency-name: golang.org/x/tools
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-10-11 15:41:03 +02:00
dependabot[bot] 3223a65c9b build(deps): bump github.com/rogpeppe/go-internal from 1.12.0 to 1.13.1
Bumps [github.com/rogpeppe/go-internal](https://github.com/rogpeppe/go-internal) from 1.12.0 to 1.13.1.
- [Release notes](https://github.com/rogpeppe/go-internal/releases)
- [Commits](https://github.com/rogpeppe/go-internal/compare/v1.12.0...v1.13.1)

---
updated-dependencies:
- dependency-name: github.com/rogpeppe/go-internal
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-10-11 15:39:22 +02:00
dependabot[bot] bc6fc47727 build(deps): bump github.com/evanw/esbuild from 0.23.1 to 0.24.0
Bumps [github.com/evanw/esbuild](https://github.com/evanw/esbuild) from 0.23.1 to 0.24.0.
- [Release notes](https://github.com/evanw/esbuild/releases)
- [Changelog](https://github.com/evanw/esbuild/blob/main/CHANGELOG.md)
- [Commits](https://github.com/evanw/esbuild/compare/v0.23.1...v0.24.0)

---
updated-dependencies:
- dependency-name: github.com/evanw/esbuild
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-10-11 15:36:02 +02:00
93 changed files with 684 additions and 389 deletions
+3 -5
View File
@@ -4,7 +4,7 @@ parameters:
defaults: &defaults
resource_class: large
docker:
- image: bepsays/ci-hugoreleaser:1.22300.20000
- image: bepsays/ci-hugoreleaser:1.22300.20200
environment: &buildenv
GOMODCACHE: /root/project/gomodcache
version: 2
@@ -14,9 +14,7 @@ jobs:
environment: &buildenv
GOMODCACHE: /root/project/gomodcache
steps:
- &remote-docker
setup_remote_docker:
version: 20.10.14
- setup_remote_docker
- checkout:
path: hugo
- &git-config
@@ -60,7 +58,7 @@ jobs:
environment:
<<: [*buildenv]
docker:
- image: bepsays/ci-hugoreleaser-linux-arm64:1.22300.20000
- image: bepsays/ci-hugoreleaser-linux-arm64:1.22300.20200
steps:
- *restore-cache
- &attach-workspace
+8 -75
View File
@@ -3,6 +3,7 @@ name: Build Docker image
on:
release:
types: [published]
pull_request:
permissions:
packages: write
@@ -12,18 +13,8 @@ env:
jobs:
build:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
platform:
- linux/amd64
- linux/arm64
steps:
- name: Prepare
run: |
platform=${{ matrix.platform }}
echo "PLATFORM_PAIR=${platform//\//-}" >> $GITHUB_ENV
steps:
- name: Checkout
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
@@ -33,9 +24,6 @@ jobs:
with:
images: ${{ env.REGISTRY_IMAGE }}
- name: Set up QEMU
uses: docker/setup-qemu-action@49b3bc8e6bdd4a60e6116a5414239cba5943d3cf # v3.2.0
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@988b5a0280414f521da01fcc63a27aeeb4b104db # v3.6.1
@@ -47,69 +35,14 @@ jobs:
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Build and push by digest
- name: Build and push
id: build
uses: docker/build-push-action@16ebe778df0e7752d2cfcbd924afdbbd89c1a755 # v6.6.1
with:
context: .
push: ${{ startsWith(github.ref, 'refs/tags') }}
platforms: ${{ matrix.platform }}
provenance: mode=max
sbom: true
push: ${{ github.event_name != 'pull_request' }}
platforms: linux/amd64,linux/arm64
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
outputs: type=image,name=${{ env.REGISTRY_IMAGE }},push-by-digest=true,name-canonical=true,push=true
- name: Export digest
run: |
mkdir -p /tmp/digests
digest="${{ steps.build.outputs.digest }}"
touch "/tmp/digests/${digest#sha256:}"
- name: Upload digest
uses: actions/upload-artifact@834a144ee995460fba8ed112a2fc961b36a5ec5a # v4.3.6
with:
name: digests-${{ env.PLATFORM_PAIR }}
path: /tmp/digests/*
if-no-files-found: error
retention-days: 1
merge:
runs-on: ubuntu-latest
needs:
- build
steps:
- name: Download digests
uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 # v4.1.8
with:
path: /tmp/digests
pattern: digests-*
merge-multiple: true
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@988b5a0280414f521da01fcc63a27aeeb4b104db # v3.6.1
- name: Docker meta
id: meta
uses: docker/metadata-action@8e5442c4ef9f78752691e2d8f8d19755c6f78e81 # v5.5.1
with:
images: ${{ env.REGISTRY_IMAGE }}
flavor: |
latest=false
- name: Login to GHCR
uses: docker/login-action@9780b0c442fbb1117ed29e0efdff1e18412f7567 # v3.3.0
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Create manifest list and push
if: ${{ startsWith(github.ref, 'refs/tags') }}
working-directory: /tmp/digests
run: |
docker buildx imagetools create $(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON") \
$(printf '${{ env.REGISTRY_IMAGE }}@sha256:%s ' *)
- name: Inspect image
if: ${{ startsWith(github.ref, 'refs/tags') }}
run: |
docker buildx imagetools inspect ${{ env.REGISTRY_IMAGE }}:${{ steps.meta.outputs.version }}
+78 -24
View File
@@ -2,44 +2,98 @@
# Twitter: https://twitter.com/gohugoio
# Website: https://gohugo.io/
FROM golang:1.22.6-alpine AS build
ARG GO_VERSION="1.23.2"
ARG ALPINE_VERSION="3.20"
ARG DART_SASS_VERSION="1.79.3"
# Optionally set HUGO_BUILD_TAGS to "extended" or "nodeploy" when building like so:
# docker build --build-arg HUGO_BUILD_TAGS=extended .
ARG HUGO_BUILD_TAGS
FROM --platform=$BUILDPLATFORM tonistiigi/xx:1.5.0 AS xx
FROM --platform=$BUILDPLATFORM golang:${GO_VERSION}-alpine${ALPINE_VERSION} AS gobuild
FROM golang:${GO_VERSION}-alpine${ALPINE_VERSION} AS gorun
ARG CGO=1
ENV CGO_ENABLED=${CGO}
ENV GOOS=linux
ENV GO111MODULE=on
FROM gobuild AS build
RUN apk add clang lld
# Set up cross-compilation helpers
COPY --from=xx / /
ARG TARGETPLATFORM
RUN xx-apk add musl-dev gcc g++
# Optionally set HUGO_BUILD_TAGS to "none" or "nodeploy" when building like so:
# docker build --build-arg HUGO_BUILD_TAGS=nodeploy .
#
# We build the extended version by default.
ARG HUGO_BUILD_TAGS="extended"
ENV CGO_ENABLED=1
ENV GOPROXY=https://proxy.golang.org
ENV GOCACHE=/root/.cache/go-build
ENV GOMODCACHE=/go/pkg/mod
ARG TARGETPLATFORM
WORKDIR /go/src/github.com/gohugoio/hugo
COPY . /go/src/github.com/gohugoio/hugo/
# For --mount=type=cache the value of target is the default cache id, so
# for the go mod cache it would be good if we could share it with other Go images using the same setup,
# but the go build cache needs to be per platform.
# See this comment: https://github.com/moby/buildkit/issues/1706#issuecomment-702238282
RUN --mount=target=. \
--mount=type=cache,target=/go/pkg/mod \
--mount=type=cache,target=/root/.cache/go-build,id=go-build-$TARGETPLATFORM <<EOT
set -ex
xx-go build -tags "$HUGO_BUILD_TAGS" -ldflags "-s -w -X github.com/gohugoio/hugo/common/hugo.vendorInfo=docker" -o /usr/bin/hugo
xx-verify /usr/bin/hugo
EOT
# gcc/g++ are required to build SASS libraries for extended version
RUN apk update && \
apk add --no-cache gcc g++ musl-dev git && \
go install github.com/magefile/mage
# dart-sass downloads the dart-sass runtime dependency
FROM alpine:${ALPINE_VERSION} AS dart-sass
ARG TARGETARCH
ARG DART_SASS_VERSION
ARG DART_ARCH=${TARGETARCH/amd64/x64}
WORKDIR /out
ADD https://github.com/sass/dart-sass/releases/download/${DART_SASS_VERSION}/dart-sass-${DART_SASS_VERSION}-linux-${DART_ARCH}.tar.gz .
RUN tar -xf dart-sass-${DART_SASS_VERSION}-linux-${DART_ARCH}.tar.gz
RUN mage hugo && mage install
FROM gorun AS final
# ---
COPY --from=build /usr/bin/hugo /usr/bin/hugo
FROM alpine:3.18
# libc6-compat are required for extended libraries (libsass, libwebp).
RUN apk add --no-cache \
libc6-compat \
git \
runuser \
nodejs \
npm
COPY --from=build /go/bin/hugo /usr/bin/hugo
RUN mkdir -p /var/hugo/bin /cache && \
addgroup -Sg 1000 hugo && \
adduser -Sg hugo -u 1000 -h /var/hugo hugo && \
chown -R hugo: /var/hugo /cache && \
# For the Hugo's Git integration to work.
runuser -u hugo -- git config --global --add safe.directory /project && \
# See https://github.com/gohugoio/hugo/issues/9810
runuser -u hugo -- git config --global core.quotepath false
# libc6-compat & libstdc++ are required for extended SASS libraries
# ca-certificates are required to fetch outside resources (like Twitter oEmbeds)
RUN apk update && \
apk add --no-cache ca-certificates libc6-compat libstdc++ git
USER hugo:hugo
VOLUME /project
WORKDIR /project
ENV HUGO_CACHEDIR=/cache
ENV PATH="/var/hugo/bin:$PATH"
VOLUME /site
WORKDIR /site
COPY scripts/docker/entrypoint.sh /entrypoint.sh
COPY --from=dart-sass /out/dart-sass /var/hugo/bin/dart-sass
# Update PATH to reflect the new dependencies.
# For more complex setups, we should probably find a way to
# delegate this to the script itself, but this will have to do for now.
# Also, the dart-sass binary is a little special, other binaries can be put/linked
# directly in /var/hugo/bin.
ENV PATH="/var/hugo/bin/dart-sass:$PATH"
# Expose port for live server
EXPOSE 1313
ENTRYPOINT ["hugo"]
ENTRYPOINT ["/entrypoint.sh"]
CMD ["--help"]
+25
View File
@@ -14,8 +14,10 @@
package dynacache
import (
"fmt"
"path/filepath"
"testing"
"time"
qt "github.com/frankban/quicktest"
"github.com/gohugoio/hugo/common/loggers"
@@ -165,6 +167,29 @@ func TestClear(t *testing.T) {
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})
for i := 0; i < 3; i++ {
for j := 0; j < 3; j++ {
_, err := p1.GetOrCreate(fmt.Sprintf("panic1-%d", i), func(string) (testItem, error) {
panic("failed")
})
c.Assert(err, qt.Not(qt.IsNil))
_, err = p1.GetOrCreateWitTimeout(fmt.Sprintf("panic2-%d", i), 10*time.Second, func(string) (testItem, error) {
panic("failed")
})
c.Assert(err, qt.Not(qt.IsNil))
}
}
}
func TestAdjustCurrentMaxSize(t *testing.T) {
t.Parallel()
c := qt.New(t)
+21 -2
View File
@@ -42,6 +42,7 @@ import (
"github.com/gohugoio/hugo/common/hugo"
"github.com/gohugoio/hugo/common/loggers"
"github.com/gohugoio/hugo/common/paths"
"github.com/gohugoio/hugo/common/types"
"github.com/gohugoio/hugo/config"
"github.com/gohugoio/hugo/config/allconfig"
"github.com/gohugoio/hugo/deps"
@@ -66,6 +67,12 @@ func Execute(args []string) error {
}
args = mapLegacyArgs(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 == errHelp {
cd.CobraCommand.Help()
@@ -149,6 +156,18 @@ func (r *rootCommand) isVerbose() bool {
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) {
h, err := r.Hugo(cfg)
if err != nil {
@@ -488,7 +507,7 @@ func (r *rootCommand) createLogger(running bool) (loggers.Logger, error) {
return loggers.New(optsLogger), nil
}
func (r *rootCommand) Reset() {
func (r *rootCommand) resetLogs() {
r.logger.Reset()
loggers.Log().Reset()
}
@@ -509,7 +528,7 @@ func (r *rootCommand) initRootCommand(subCommandName string, cd *simplecobra.Com
commandName = subCommandName
}
cmd.Use = fmt.Sprintf("%s [flags]", commandName)
cmd.Short = fmt.Sprintf("%s builds your site", commandName)
cmd.Short = "Build your site"
cmd.Long = `COMMAND_NAME is the main command, used to build your Hugo site.
Hugo is a Fast and Flexible Static Site Generator
+2 -2
View File
@@ -110,8 +110,8 @@ func (c *configCommand) Run(ctx context.Context, cd *simplecobra.Commandeer, arg
func (c *configCommand) Init(cd *simplecobra.Commandeer) error {
c.r = cd.Root.Command.(*rootCommand)
cmd := cd.CobraCommand
cmd.Short = "Print the site configuration"
cmd.Long = `Print the site configuration, both default and custom settings.`
cmd.Short = "Display site configuration"
cmd.Long = `Display site configuration, both default and custom settings.`
cmd.Flags().StringVar(&c.format, "format", "toml", "preferred file format (toml, yaml or json)")
_ = cmd.RegisterFlagCompletionFunc("format", cobra.FixedCompletions([]string{"toml", "yaml", "json"}, cobra.ShellCompDirectiveNoFileComp))
cmd.Flags().StringVar(&c.lang, "lang", "", "the language to display config for. Defaults to the first language defined.")
+2 -2
View File
@@ -105,8 +105,8 @@ func (c *convertCommand) Run(ctx context.Context, cd *simplecobra.Commandeer, ar
func (c *convertCommand) Init(cd *simplecobra.Commandeer) error {
cmd := cd.CobraCommand
cmd.Short = "Convert your content to different formats"
cmd.Long = `Convert your content (e.g. front matter) to different formats.
cmd.Short = "Convert front matter to another format"
cmd.Long = `Convert front matter to another format.
See convert's subcommands toJSON, toTOML and toYAML for more information.`
+2 -2
View File
@@ -42,8 +42,8 @@ import (
func newDeployCommand() simplecobra.Commander {
return &simpleCommand{
name: "deploy",
short: "Deploy your site to a Cloud provider.",
long: `Deploy your site to a Cloud provider.
short: "Deploy your site to a cloud provider",
long: `Deploy your site to a cloud provider
See https://gohugo.io/hosting-and-deployment/hugo-deploy/ for detailed
documentation.
+4 -4
View File
@@ -25,8 +25,8 @@ import (
func newEnvCommand() simplecobra.Commander {
return &simpleCommand{
name: "env",
short: "Print Hugo version and environment info",
long: "Print Hugo version and environment info. This is useful in Hugo bug reports",
short: "Display version and environment info",
long: "Display version and environment info. This is useful in Hugo bug reports",
run: func(ctx context.Context, cd *simplecobra.Commandeer, r *rootCommand, args []string) error {
r.Printf("%s\n", hugo.BuildVersionString())
r.Printf("GOOS=%q\n", runtime.GOOS)
@@ -61,8 +61,8 @@ func newVersionCmd() simplecobra.Commander {
r.Println(hugo.BuildVersionString())
return nil
},
short: "Print Hugo version and environment info",
long: "Print Hugo version and environment info. This is useful in Hugo bug reports.",
short: "Display version",
long: "Display version and environment info. This is useful in Hugo bug reports.",
withc: func(cmd *cobra.Command, r *rootCommand) {
cmd.ValidArgsFunction = cobra.NoFileCompletions
},
+2 -1
View File
@@ -273,7 +273,8 @@ func (c *genCommand) Run(ctx context.Context, cd *simplecobra.Commandeer, args [
func (c *genCommand) Init(cd *simplecobra.Commandeer) error {
cmd := cd.CobraCommand
cmd.Short = "A collection of several useful generators."
cmd.Short = "Generate documentation and syntax highlighting styles"
cmd.Long = "Generate documentation for your project using Hugo's documentation engine, including syntax highlighting for various programming languages."
cmd.RunE = nil
return nil
+34 -24
View File
@@ -27,7 +27,6 @@ import (
"sync/atomic"
"time"
"github.com/bep/logg"
"github.com/bep/simplecobra"
"github.com/fsnotify/fsnotify"
"github.com/gohugoio/hugo/common/herrors"
@@ -136,10 +135,6 @@ func (e *hugoBuilderErrState) wasErr() bool {
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.
func (c *hugoBuilder) getDirList() ([]string, error) {
h, err := c.hugo()
@@ -345,7 +340,6 @@ func (c *hugoBuilder) newWatcher(pollIntervalStr string, dirList ...string) (*wa
for {
select {
case changes := <-c.r.changesFromBuild:
c.errState.setBuildErr(nil)
unlock, err := h.LockBuild()
if err != nil {
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 {
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 {
livereload.ForceRefresh()
}
@@ -372,7 +366,7 @@ func (c *hugoBuilder) newWatcher(pollIntervalStr string, dirList ...string) (*wa
return
}
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
livereload.ForceRefresh()
}
@@ -419,11 +413,17 @@ func (c *hugoBuilder) build() 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 {
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) {
@@ -619,6 +619,9 @@ func (c *hugoBuilder) fullRebuild(changeType string) {
// Set the processing on pause until the state is recovered.
c.errState.setPaused(true)
c.handleBuildErr(err, "Failed to reload config")
if c.s.doLiveReload {
livereload.ForceRefresh()
}
} else {
c.errState.setPaused(false)
}
@@ -1081,37 +1084,44 @@ func (c *hugoBuilder) printChangeDetected(typ string) {
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 {
ferrs := herrors.UnwrapFileErrorsWithErrorContext(err)
for _, err := range ferrs {
events = append(events, fsnotify.Event{Name: err.Position().Filename, Op: fsnotify.Write})
}
}
c.errState.setBuildErr(nil)
h, err := c.hugo()
var h *hugolib.HugoSites
h, err = c.hugo()
if err != nil {
return err
return
}
return h.Build(hugolib.BuildCfg{NoBuildLock: true, RecentlyVisited: c.visitedURLs, ErrRecovery: c.errState.wasErr()}, events...)
err = h.Build(hugolib.BuildCfg{NoBuildLock: true, RecentlyVisited: c.visitedURLs, ErrRecovery: c.errState.wasErr()}, events...)
return
}
func (c *hugoBuilder) rebuildSitesForChanges(ids []identity.Identity) error {
c.errState.setBuildErr(nil)
h, err := c.hugo()
func (c *hugoBuilder) rebuildSitesForChanges(ids []identity.Identity) (err error) {
defer func() {
c.errState.setBuildErr(err)
}()
var h *hugolib.HugoSites
h, err = c.hugo()
if err != nil {
return err
return
}
whatChanged := &hugolib.WhatChanged{}
whatChanged.Add(ids...)
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 {
c.r.Reset()
c.r.resetLogs()
c.r.configVersionID.Add(1)
if err := c.withConfE(func(conf *commonConfig) error {
+2 -2
View File
@@ -90,8 +90,8 @@ func (c *importCommand) Run(ctx context.Context, cd *simplecobra.Commandeer, arg
func (c *importCommand) Init(cd *simplecobra.Commandeer) error {
cmd := cd.CobraCommand
cmd.Short = "Import your site from others."
cmd.Long = `Import your site from other web site generators like Jekyll.
cmd.Short = "Import a site from another system"
cmd.Long = `Import a site from another system.
Import requires a subcommand, e.g. ` + "`hugo import jekyll jekyll_root_path target_path`."
+2 -2
View File
@@ -199,8 +199,8 @@ func (c *listCommand) Run(ctx context.Context, cd *simplecobra.Commandeer, args
func (c *listCommand) Init(cd *simplecobra.Commandeer) error {
cmd := cd.CobraCommand
cmd.Short = "Listing out various types of content"
cmd.Long = `Listing out various types of content.
cmd.Short = "List content"
cmd.Long = `List content.
List requires a subcommand, e.g. hugo list drafts`
+1 -1
View File
@@ -328,7 +328,7 @@ func (c *modCommands) Run(ctx context.Context, cd *simplecobra.Commandeer, args
func (c *modCommands) Init(cd *simplecobra.Commandeer) error {
cmd := cd.CobraCommand
cmd.Short = "Various Hugo Modules helpers."
cmd.Short = "Manage modules"
cmd.Long = `Various helpers to help manage the modules in your project's dependency graph.
Most operations here requires a Go version installed on your system (>= Go 1.12) and the relevant VCS client (typically Git).
This is not needed if you only operate on modules inside /themes or if you have vendored them via "hugo mod vendor".
+2 -2
View File
@@ -40,7 +40,7 @@ func newNewCommand() *newCommand {
&simpleCommand{
name: "content",
use: "content [path]",
short: "Create new content for your site",
short: "Create new content",
long: `Create a new content file and automatically set the date and title.
It will guess which kind of file to create based on the path provided.
@@ -181,7 +181,7 @@ func (c *newCommand) Run(ctx context.Context, cd *simplecobra.Commandeer, args [
func (c *newCommand) Init(cd *simplecobra.Commandeer) error {
cmd := cd.CobraCommand
cmd.Short = "Create new content for your site"
cmd.Short = "Create new content"
cmd.Long = `Create a new content file and automatically set the date and title.
It will guess which kind of file to create based on the path provided.
+12 -14
View File
@@ -508,7 +508,7 @@ func (c *serverCommand) Run(ctx context.Context, cd *simplecobra.Commandeer, arg
func (c *serverCommand) Init(cd *simplecobra.Commandeer) error {
cmd := cd.CobraCommand
cmd.Short = "A high performance webserver"
cmd.Short = "Start the embedded web server"
cmd.Long = `Hugo provides its own webserver which builds and serves the site.
While hugo server is high performance, it is a webserver with limited options.
@@ -648,9 +648,8 @@ func (c *serverCommand) setServerInfoInConfig() error {
}
func (c *serverCommand) getErrorWithContext() any {
errCount := c.errCount()
if errCount == 0 {
buildErr := c.errState.buildErr()
if buildErr == nil {
return nil
}
@@ -659,7 +658,7 @@ func (c *serverCommand) getErrorWithContext() any {
m["Error"] = cleanErrorLog(c.r.logger.Errors())
m["Version"] = hugo.BuildVersionString()
ferrors := herrors.UnwrapFileErrorsWithErrorContext(c.errState.buildErr())
ferrors := herrors.UnwrapFileErrorsWithErrorContext(buildErr)
m["Files"] = ferrors
return m
@@ -830,22 +829,25 @@ func (c *serverCommand) fixURL(baseURLFromConfig, baseURLFromFlag string, port i
return u.String(), nil
}
func (c *serverCommand) partialReRender(urls ...string) error {
func (c *serverCommand) partialReRender(urls ...string) (err error) {
defer func() {
c.errState.setWasErr(false)
}()
c.errState.setBuildErr(nil)
visited := types.NewEvictingStringQueue(len(urls))
for _, url := range urls {
visited.Add(url)
}
h, err := c.hugo()
var h *hugolib.HugoSites
h, err = c.hugo()
if err != nil {
return err
return
}
// 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 {
@@ -1012,10 +1014,6 @@ func (c *serverCommand) serve() error {
c.r.Println("Error:", err)
}
if h := c.hugoTry(); h != nil {
h.Close()
}
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
wg2, ctx := errgroup.WithContext(ctx)
+1 -1
View File
@@ -137,7 +137,7 @@ var nilPointerErrRe = regexp.MustCompile(`at <(.*)>: error calling (.*?): runtim
const deferredPrefix = "__hdeferred/"
var deferredStringToRemove = regexp.MustCompile(`executing "__hdeferred/.*" `)
var deferredStringToRemove = regexp.MustCompile(`executing "__hdeferred/.*?" `)
// ImproveRenderErr improves the error message for rendering errors.
func ImproveRenderErr(inErr error) (outErr error) {
+1 -1
View File
@@ -17,7 +17,7 @@ package hugo
// This should be the only one.
var CurrentVersion = Version{
Major: 0,
Minor: 136,
Minor: 137,
PatchLevel: 0,
Suffix: "-DEV",
}
@@ -160,3 +160,18 @@ title: "p3"
b.AssertFileExists("public/page/1/index.html", false)
b.AssertFileContent("public/page/2/index.html", "pagination-default")
}
func TestMapUglyURLs(t *testing.T) {
files := `
-- hugo.toml --
[uglyurls]
posts = true
`
b := hugolib.Test(t, files)
c := b.H.Configs.Base
b.Assert(c.C.IsUglyURLSection("posts"), qt.IsTrue)
b.Assert(c.C.IsUglyURLSection("blog"), qt.IsFalse)
}
+2
View File
@@ -419,6 +419,8 @@ var allDecoderSetups = map[string]decodeWeight{
p.c.UglyURLs = vv
case string:
p.c.UglyURLs = vv == "true"
case maps.Params:
p.c.UglyURLs = cast.ToStringMapBool(maps.CleanConfigStringMap(vv))
default:
p.c.UglyURLs = cast.ToStringMapBool(v)
}
@@ -1,5 +0,0 @@
+++
title = '{{ replace .File.ContentBaseName "-" " " | title }}'
date = {{ .Date }}
draft = true
+++
+21
View File
@@ -76,6 +76,11 @@ func CreateSite(createpath string, sourceFs afero.Fs, force bool, format string)
return err
}
err = newSiteCreateArchetype(sourceFs, createpath, format)
if err != nil {
return err
}
return copyFiles(createpath, sourceFs, siteFs)
}
@@ -109,3 +114,19 @@ func newSiteCreateConfig(fs afero.Fs, createpath string, format string) (err err
return helpers.WriteToDisk(filepath.Join(createpath, "hugo."+format), &buf, fs)
}
func newSiteCreateArchetype(fs afero.Fs, createpath string, format string) (err error) {
in := map[string]any{
"title": "{{ replace .File.ContentBaseName \"-\" \" \" | title }}",
"date": "{{ .Date }}",
"draft": true,
}
var buf bytes.Buffer
err = parser.InterfaceToFrontMatter(in, metadecoders.FormatFromString(format), &buf)
if err != nil {
return err
}
return helpers.WriteToDisk(filepath.Join(createpath, "archetypes", "default.md"), &buf, fs)
}
+7
View File
@@ -98,6 +98,8 @@ type Deps struct {
// TODO(bep) rethink this re. a plugin setup, but this will have to do for now.
WasmDispatchers *warpc.Dispatchers
isClosed bool
*globalErrHandler
}
@@ -345,6 +347,11 @@ func (d *Deps) TextTmpl() tpl.TemplateParseFinder {
}
func (d *Deps) Close() error {
if d.isClosed {
return nil
}
d.isClosed = true
if d.MemCache != nil {
d.MemCache.Stop()
}
+13 -13
View File
@@ -5,7 +5,7 @@ url: /commands/hugo/
---
## hugo
hugo builds your site
Build your site
### Synopsis
@@ -70,17 +70,17 @@ hugo [flags]
### SEE ALSO
* [hugo build](/commands/hugo_build/) - build builds your site
* [hugo build](/commands/hugo_build/) - Build your site
* [hugo completion](/commands/hugo_completion/) - Generate the autocompletion script for the specified shell
* [hugo config](/commands/hugo_config/) - Print the site configuration
* [hugo convert](/commands/hugo_convert/) - Convert your content to different formats
* [hugo deploy](/commands/hugo_deploy/) - Deploy your site to a Cloud provider.
* [hugo env](/commands/hugo_env/) - Print Hugo version and environment info
* [hugo gen](/commands/hugo_gen/) - A collection of several useful generators.
* [hugo import](/commands/hugo_import/) - Import your site from others.
* [hugo list](/commands/hugo_list/) - Listing out various types of content
* [hugo mod](/commands/hugo_mod/) - Various Hugo Modules helpers.
* [hugo new](/commands/hugo_new/) - Create new content for your site
* [hugo server](/commands/hugo_server/) - A high performance webserver
* [hugo version](/commands/hugo_version/) - Print Hugo version and environment info
* [hugo config](/commands/hugo_config/) - Display site configuration
* [hugo convert](/commands/hugo_convert/) - Convert front matter to another format
* [hugo deploy](/commands/hugo_deploy/) - Deploy your site to a cloud provider
* [hugo env](/commands/hugo_env/) - Display version and environment info
* [hugo gen](/commands/hugo_gen/) - Generate documentation and syntax highlighting styles
* [hugo import](/commands/hugo_import/) - Import a site from another system
* [hugo list](/commands/hugo_list/) - List content
* [hugo mod](/commands/hugo_mod/) - Manage modules
* [hugo new](/commands/hugo_new/) - Create new content
* [hugo server](/commands/hugo_server/) - Start the embedded web server
* [hugo version](/commands/hugo_version/) - Display version
+2 -2
View File
@@ -5,7 +5,7 @@ url: /commands/hugo_build/
---
## hugo build
build builds your site
Build your site
### Synopsis
@@ -70,5 +70,5 @@ hugo build [flags]
### SEE ALSO
* [hugo](/commands/hugo/) - hugo builds your site
* [hugo](/commands/hugo/) - Build your site
+1 -1
View File
@@ -39,7 +39,7 @@ See each sub-command's help for details on how to use the generated script.
### SEE ALSO
* [hugo](/commands/hugo/) - hugo builds your site
* [hugo](/commands/hugo/) - Build your site
* [hugo completion bash](/commands/hugo_completion_bash/) - Generate the autocompletion script for bash
* [hugo completion fish](/commands/hugo_completion_fish/) - Generate the autocompletion script for fish
* [hugo completion powershell](/commands/hugo_completion_powershell/) - Generate the autocompletion script for powershell
+3 -3
View File
@@ -5,11 +5,11 @@ url: /commands/hugo_config/
---
## hugo config
Print the site configuration
Display site configuration
### Synopsis
Print the site configuration, both default and custom settings.
Display site configuration, both default and custom settings.
```
hugo config [command] [flags]
@@ -48,6 +48,6 @@ hugo config [command] [flags]
### SEE ALSO
* [hugo](/commands/hugo/) - hugo builds your site
* [hugo](/commands/hugo/) - Build your site
* [hugo config mounts](/commands/hugo_config_mounts/) - Print the configured file mounts
@@ -42,5 +42,5 @@ hugo config mounts [flags] [args]
### SEE ALSO
* [hugo config](/commands/hugo_config/) - Print the site configuration
* [hugo config](/commands/hugo_config/) - Display site configuration
+3 -3
View File
@@ -5,11 +5,11 @@ url: /commands/hugo_convert/
---
## hugo convert
Convert your content to different formats
Convert front matter to another format
### Synopsis
Convert your content (e.g. front matter) to different formats.
Convert front matter to another format.
See convert's subcommands toJSON, toTOML and toYAML for more information.
@@ -41,7 +41,7 @@ See convert's subcommands toJSON, toTOML and toYAML for more information.
### SEE ALSO
* [hugo](/commands/hugo/) - hugo builds your site
* [hugo](/commands/hugo/) - Build your site
* [hugo convert toJSON](/commands/hugo_convert_tojson/) - Convert front matter to JSON
* [hugo convert toTOML](/commands/hugo_convert_totoml/) - Convert front matter to TOML
* [hugo convert toYAML](/commands/hugo_convert_toyaml/) - Convert front matter to YAML
@@ -44,5 +44,5 @@ hugo convert toJSON [flags] [args]
### SEE ALSO
* [hugo convert](/commands/hugo_convert/) - Convert your content to different formats
* [hugo convert](/commands/hugo_convert/) - Convert front matter to another format
@@ -44,5 +44,5 @@ hugo convert toTOML [flags] [args]
### SEE ALSO
* [hugo convert](/commands/hugo_convert/) - Convert your content to different formats
* [hugo convert](/commands/hugo_convert/) - Convert front matter to another format
@@ -44,5 +44,5 @@ hugo convert toYAML [flags] [args]
### SEE ALSO
* [hugo convert](/commands/hugo_convert/) - Convert your content to different formats
* [hugo convert](/commands/hugo_convert/) - Convert front matter to another format
+3 -3
View File
@@ -5,11 +5,11 @@ url: /commands/hugo_deploy/
---
## hugo deploy
Deploy your site to a Cloud provider.
Deploy your site to a cloud provider
### Synopsis
Deploy your site to a Cloud provider.
Deploy your site to a cloud provider
See https://gohugo.io/hosting-and-deployment/hugo-deploy/ for detailed
documentation.
@@ -52,5 +52,5 @@ hugo deploy [flags] [args]
### SEE ALSO
* [hugo](/commands/hugo/) - hugo builds your site
* [hugo](/commands/hugo/) - Build your site
+3 -3
View File
@@ -5,11 +5,11 @@ url: /commands/hugo_env/
---
## hugo env
Print Hugo version and environment info
Display version and environment info
### Synopsis
Print Hugo version and environment info. This is useful in Hugo bug reports
Display version and environment info. This is useful in Hugo bug reports
```
hugo env [flags] [args]
@@ -41,5 +41,5 @@ hugo env [flags] [args]
### SEE ALSO
* [hugo](/commands/hugo/) - hugo builds your site
* [hugo](/commands/hugo/) - Build your site
+6 -2
View File
@@ -5,7 +5,11 @@ url: /commands/hugo_gen/
---
## hugo gen
A collection of several useful generators.
Generate documentation and syntax highlighting styles
### Synopsis
Generate documentation for your project using Hugo's documentation engine, including syntax highlighting for various programming languages.
### Options
@@ -33,7 +37,7 @@ A collection of several useful generators.
### SEE ALSO
* [hugo](/commands/hugo/) - hugo builds your site
* [hugo](/commands/hugo/) - Build your site
* [hugo gen chromastyles](/commands/hugo_gen_chromastyles/) - Generate CSS stylesheet for the Chroma code highlighter
* [hugo gen doc](/commands/hugo_gen_doc/) - Generate Markdown documentation for the Hugo CLI.
* [hugo gen man](/commands/hugo_gen_man/) - Generate man pages for the Hugo CLI
@@ -47,5 +47,5 @@ hugo gen chromastyles [flags] [args]
### SEE ALSO
* [hugo gen](/commands/hugo_gen/) - A collection of several useful generators.
* [hugo gen](/commands/hugo_gen/) - Generate documentation and syntax highlighting styles
+1 -1
View File
@@ -47,5 +47,5 @@ hugo gen doc [flags] [args]
### SEE ALSO
* [hugo gen](/commands/hugo_gen/) - A collection of several useful generators.
* [hugo gen](/commands/hugo_gen/) - Generate documentation and syntax highlighting styles
+1 -1
View File
@@ -44,5 +44,5 @@ hugo gen man [flags] [args]
### SEE ALSO
* [hugo gen](/commands/hugo_gen/) - A collection of several useful generators.
* [hugo gen](/commands/hugo_gen/) - Generate documentation and syntax highlighting styles
+3 -3
View File
@@ -5,11 +5,11 @@ url: /commands/hugo_import/
---
## hugo import
Import your site from others.
Import a site from another system
### Synopsis
Import your site from other web site generators like Jekyll.
Import a site from another system.
Import requires a subcommand, e.g. `hugo import jekyll jekyll_root_path target_path`.
@@ -39,6 +39,6 @@ Import requires a subcommand, e.g. `hugo import jekyll jekyll_root_path target_p
### SEE ALSO
* [hugo](/commands/hugo/) - hugo builds your site
* [hugo](/commands/hugo/) - Build your site
* [hugo import jekyll](/commands/hugo_import_jekyll/) - hugo import from Jekyll
@@ -44,5 +44,5 @@ hugo import jekyll [flags] [args]
### SEE ALSO
* [hugo import](/commands/hugo_import/) - Import your site from others.
* [hugo import](/commands/hugo_import/) - Import a site from another system
+3 -3
View File
@@ -5,11 +5,11 @@ url: /commands/hugo_list/
---
## hugo list
Listing out various types of content
List content
### Synopsis
Listing out various types of content.
List content.
List requires a subcommand, e.g. hugo list drafts
@@ -39,7 +39,7 @@ List requires a subcommand, e.g. hugo list drafts
### SEE ALSO
* [hugo](/commands/hugo/) - hugo builds your site
* [hugo](/commands/hugo/) - Build your site
* [hugo list all](/commands/hugo_list_all/) - List all content
* [hugo list drafts](/commands/hugo_list_drafts/) - List draft content
* [hugo list expired](/commands/hugo_list_expired/) - List expired content
+1 -1
View File
@@ -41,5 +41,5 @@ hugo list all [flags] [args]
### SEE ALSO
* [hugo list](/commands/hugo_list/) - Listing out various types of content
* [hugo list](/commands/hugo_list/) - List content
+1 -1
View File
@@ -41,5 +41,5 @@ hugo list drafts [flags] [args]
### SEE ALSO
* [hugo list](/commands/hugo_list/) - Listing out various types of content
* [hugo list](/commands/hugo_list/) - List content
@@ -41,5 +41,5 @@ hugo list expired [flags] [args]
### SEE ALSO
* [hugo list](/commands/hugo_list/) - Listing out various types of content
* [hugo list](/commands/hugo_list/) - List content
+1 -1
View File
@@ -41,5 +41,5 @@ hugo list future [flags] [args]
### SEE ALSO
* [hugo list](/commands/hugo_list/) - Listing out various types of content
* [hugo list](/commands/hugo_list/) - List content
@@ -41,5 +41,5 @@ hugo list published [flags] [args]
### SEE ALSO
* [hugo list](/commands/hugo_list/) - Listing out various types of content
* [hugo list](/commands/hugo_list/) - List content
+2 -2
View File
@@ -5,7 +5,7 @@ url: /commands/hugo_mod/
---
## hugo mod
Various Hugo Modules helpers.
Manage modules
### Synopsis
@@ -48,7 +48,7 @@ See https://gohugo.io/hugo-modules/ for more information.
### SEE ALSO
* [hugo](/commands/hugo/) - hugo builds your site
* [hugo](/commands/hugo/) - Build your site
* [hugo mod clean](/commands/hugo_mod_clean/) - Delete the Hugo Module cache for the current project.
* [hugo mod get](/commands/hugo_mod_get/) - Resolves dependencies in your current Hugo Project.
* [hugo mod graph](/commands/hugo_mod_graph/) - Print a module dependency graph.
+1 -1
View File
@@ -48,5 +48,5 @@ hugo mod clean [flags] [args]
### SEE ALSO
* [hugo mod](/commands/hugo_mod/) - Various Hugo Modules helpers.
* [hugo mod](/commands/hugo_mod/) - Manage modules
+1 -1
View File
@@ -72,5 +72,5 @@ hugo mod get [flags] [args]
### SEE ALSO
* [hugo mod](/commands/hugo_mod/) - Various Hugo Modules helpers.
* [hugo mod](/commands/hugo_mod/) - Manage modules
+1 -1
View File
@@ -49,5 +49,5 @@ hugo mod graph [flags] [args]
### SEE ALSO
* [hugo mod](/commands/hugo_mod/) - Various Hugo Modules helpers.
* [hugo mod](/commands/hugo_mod/) - Manage modules
+1 -1
View File
@@ -53,5 +53,5 @@ hugo mod init [flags] [args]
### SEE ALSO
* [hugo mod](/commands/hugo_mod/) - Various Hugo Modules helpers.
* [hugo mod](/commands/hugo_mod/) - Manage modules
+1 -1
View File
@@ -41,6 +41,6 @@ hugo mod npm [command] [flags]
### SEE ALSO
* [hugo mod](/commands/hugo_mod/) - Various Hugo Modules helpers.
* [hugo mod](/commands/hugo_mod/) - Manage modules
* [hugo mod npm pack](/commands/hugo_mod_npm_pack/) - Experimental: Prepares and writes a composite package.json file for your project.
+1 -1
View File
@@ -42,5 +42,5 @@ hugo mod tidy [flags] [args]
### SEE ALSO
* [hugo mod](/commands/hugo_mod/) - Various Hugo Modules helpers.
* [hugo mod](/commands/hugo_mod/) - Manage modules
+1 -1
View File
@@ -48,5 +48,5 @@ hugo mod vendor [flags] [args]
### SEE ALSO
* [hugo mod](/commands/hugo_mod/) - Various Hugo Modules helpers.
* [hugo mod](/commands/hugo_mod/) - Manage modules
+1 -1
View File
@@ -47,5 +47,5 @@ hugo mod verify [flags] [args]
### SEE ALSO
* [hugo mod](/commands/hugo_mod/) - Various Hugo Modules helpers.
* [hugo mod](/commands/hugo_mod/) - Manage modules
+3 -3
View File
@@ -5,7 +5,7 @@ url: /commands/hugo_new/
---
## hugo new
Create new content for your site
Create new content
### Synopsis
@@ -44,8 +44,8 @@ Ensure you run this within the root directory of your site.
### SEE ALSO
* [hugo](/commands/hugo/) - hugo builds your site
* [hugo new content](/commands/hugo_new_content/) - Create new content for your site
* [hugo](/commands/hugo/) - Build your site
* [hugo new content](/commands/hugo_new_content/) - Create new content
* [hugo new site](/commands/hugo_new_site/) - Create a new site (skeleton)
* [hugo new theme](/commands/hugo_new_theme/) - Create a new theme (skeleton)
+2 -2
View File
@@ -5,7 +5,7 @@ url: /commands/hugo_new_content/
---
## hugo new content
Create new content for your site
Create new content
### Synopsis
@@ -56,5 +56,5 @@ hugo new content [path] [flags]
### SEE ALSO
* [hugo new](/commands/hugo_new/) - Create new content for your site
* [hugo new](/commands/hugo_new/) - Create new content
+1 -1
View File
@@ -45,5 +45,5 @@ hugo new site [path] [flags]
### SEE ALSO
* [hugo new](/commands/hugo_new/) - Create new content for your site
* [hugo new](/commands/hugo_new/) - Create new content
+1 -1
View File
@@ -44,5 +44,5 @@ hugo new theme [name] [flags]
### SEE ALSO
* [hugo new](/commands/hugo_new/) - Create new content for your site
* [hugo new](/commands/hugo_new/) - Create new content
+2 -2
View File
@@ -5,7 +5,7 @@ url: /commands/hugo_server/
---
## hugo server
A high performance webserver
Start the embedded web server
### Synopsis
@@ -94,6 +94,6 @@ hugo server [command] [flags]
### SEE ALSO
* [hugo](/commands/hugo/) - hugo builds your site
* [hugo](/commands/hugo/) - Build your site
* [hugo server trust](/commands/hugo_server_trust/) - Install the local CA in the system trust store.
@@ -38,5 +38,5 @@ hugo server trust [flags] [args]
### SEE ALSO
* [hugo server](/commands/hugo_server/) - A high performance webserver
* [hugo server](/commands/hugo_server/) - Start the embedded web server
+3 -3
View File
@@ -5,11 +5,11 @@ url: /commands/hugo_version/
---
## hugo version
Print Hugo version and environment info
Display version
### Synopsis
Print Hugo version and environment info. This is useful in Hugo bug reports.
Display version and environment info. This is useful in Hugo bug reports.
```
hugo version [flags] [args]
@@ -41,5 +41,5 @@ hugo version [flags] [args]
### SEE ALSO
* [hugo](/commands/hugo/) - hugo builds your site
* [hugo](/commands/hugo/) - Build your site
+11 -11
View File
@@ -16,7 +16,7 @@ require (
github.com/bep/gowebp v0.3.0
github.com/bep/helpers v0.5.0
github.com/bep/imagemeta v0.8.1
github.com/bep/lazycache v0.4.0
github.com/bep/lazycache v0.6.0
github.com/bep/logg v0.4.0
github.com/bep/mclib v1.20400.20402
github.com/bep/overlayfs v0.9.2
@@ -27,7 +27,7 @@ require (
github.com/cli/safeexec v1.0.1
github.com/disintegration/gift v1.2.1
github.com/dustin/go-humanize v1.0.1
github.com/evanw/esbuild v0.23.1
github.com/evanw/esbuild v0.24.0
github.com/fatih/color v1.17.0
github.com/fortytw2/leaktest v1.3.0
github.com/frankban/quicktest v1.14.6
@@ -60,7 +60,7 @@ require (
github.com/olekukonko/tablewriter v0.0.5
github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58
github.com/pelletier/go-toml/v2 v2.2.3
github.com/rogpeppe/go-internal v1.12.0
github.com/rogpeppe/go-internal v1.13.1
github.com/sanity-io/litter v1.5.5
github.com/spf13/afero v1.11.0
github.com/spf13/cast v1.7.0
@@ -69,18 +69,18 @@ require (
github.com/spf13/pflag v1.0.5
github.com/tdewolff/minify/v2 v2.20.37
github.com/tdewolff/parse/v2 v2.7.15
github.com/tetratelabs/wazero v1.8.0
github.com/tetratelabs/wazero v1.8.1
github.com/yuin/goldmark v1.7.4
github.com/yuin/goldmark-emoji v1.0.3
github.com/yuin/goldmark-emoji v1.0.4
go.uber.org/automaxprocs v1.5.3
gocloud.dev v0.39.0
golang.org/x/exp v0.0.0-20221031165847-c99f073a8326
golang.org/x/image v0.20.0
golang.org/x/image v0.21.0
golang.org/x/mod v0.21.0
golang.org/x/net v0.29.0
golang.org/x/net v0.30.0
golang.org/x/sync v0.8.0
golang.org/x/text v0.18.0
golang.org/x/tools v0.23.0
golang.org/x/text v0.19.0
golang.org/x/tools v0.26.0
google.golang.org/api v0.191.0
gopkg.in/yaml.v2 v2.4.0
)
@@ -154,9 +154,9 @@ require (
go.opentelemetry.io/otel v1.28.0 // indirect
go.opentelemetry.io/otel/metric v1.28.0 // indirect
go.opentelemetry.io/otel/trace v1.28.0 // indirect
golang.org/x/crypto v0.27.0 // indirect
golang.org/x/crypto v0.28.0 // indirect
golang.org/x/oauth2 v0.22.0 // indirect
golang.org/x/sys v0.25.0 // indirect
golang.org/x/sys v0.26.0 // indirect
golang.org/x/time v0.6.0 // indirect
golang.org/x/xerrors v0.0.0-20240716161551-93cc26a95ae9 // indirect
google.golang.org/genproto v0.0.0-20240812133136-8ffd90a71988 // indirect
+22 -20
View File
@@ -143,6 +143,8 @@ 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/lazycache v0.4.0 h1:X8yVyWNVupPd4e1jV7efi3zb7ZV/qcjKQgIQ5aPbkYI=
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/logg v0.4.0 h1:luAo5mO4ZkhA5M1iDVDqDqnBBnlHjmtZF6VAyTp+nCQ=
github.com/bep/logg v0.4.0/go.mod h1:Ccp9yP3wbR1mm++Kpxet91hAZBEQgmWgFgnXX3GkIV0=
github.com/bep/mclib v1.20400.20402 h1:olpCE2WSPpOAbFE1R4hnftSEmQ34+xzy2HRzd0m69rA=
@@ -189,8 +191,8 @@ github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1m
github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po=
github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
github.com/evanw/esbuild v0.23.1 h1:ociewhY6arjTarKLdrXfDTgy25oxhTZmzP8pfuBTfTA=
github.com/evanw/esbuild v0.23.1/go.mod h1:D2vIQZqV/vIf/VRHtViaUtViZmG7o+kKmlBfVQuRi48=
github.com/evanw/esbuild v0.24.0 h1:GZ78naTLp7FKr+K7eNuM/SLs5maeiHYRPsTg6kmdsSE=
github.com/evanw/esbuild v0.24.0/go.mod h1:D2vIQZqV/vIf/VRHtViaUtViZmG7o+kKmlBfVQuRi48=
github.com/fatih/color v1.17.0 h1:GlRw1BRJxkpqUCBKzKOw098ed57fEsKeNjpTe3cSjK4=
github.com/fatih/color v1.17.0/go.mod h1:YZ7TlrGPkiz6ku9fK3TLD/pl3CpsiFyu8N92HLgmosI=
github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg=
@@ -419,8 +421,8 @@ github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8=
github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4=
github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII=
github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o=
github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk=
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/rwcarlsen/goexif v0.0.0-20190401172101-9e8deecbddbd h1:CmH9+J6ZSsIjUK3dcGsnCnO41eRBOnY12zwkn5qVwgc=
@@ -459,8 +461,8 @@ github.com/tdewolff/parse/v2 v2.7.15/go.mod h1:3FbJWZp3XT9OWVN3Hmfp0p/a08v4h8J9W
github.com/tdewolff/test v1.0.11-0.20231101010635-f1265d231d52/go.mod h1:6DAvZliBAAnD7rhVgwaM7DE5/d9NMOAJ09SqYqeK4QE=
github.com/tdewolff/test v1.0.11-0.20240106005702-7de5f7df4739 h1:IkjBCtQOOjIn03u/dMQK9g+Iw9ewps4mCl1nB8Sscbo=
github.com/tdewolff/test v1.0.11-0.20240106005702-7de5f7df4739/go.mod h1:XPuWBzvdUzhCuxWO1ojpXsyzsA5bFoS3tO/Q3kFuTG8=
github.com/tetratelabs/wazero v1.8.0 h1:iEKu0d4c2Pd+QSRieYbnQC9yiFlMS9D+Jr0LsRmcF4g=
github.com/tetratelabs/wazero v1.8.0/go.mod h1:yAI0XTsMBhREkM/YDAK/zNou3GoiAce1P6+rp/wQhjs=
github.com/tetratelabs/wazero v1.8.1 h1:NrcgVbWfkWvVc4UtT4LRLDf91PsOzDzefMdwhLfA550=
github.com/tetratelabs/wazero v1.8.1/go.mod h1:yAI0XTsMBhREkM/YDAK/zNou3GoiAce1P6+rp/wQhjs=
github.com/ugorji/go/codec v1.2.7 h1:YPXUKf7fYbp/y8xloBqZOw2qaVggbfwMlI8WM3wZUJ0=
github.com/ugorji/go/codec v1.2.7/go.mod h1:WGN1fab3R1fzQlVQTkfxVtIBhWDRqOviHU95kRgeqEY=
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
@@ -472,8 +474,8 @@ github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5t
github.com/yuin/goldmark v1.7.1/go.mod h1:uzxRWxtg69N339t3louHJ7+O03ezfj6PlliRlaOzY1E=
github.com/yuin/goldmark v1.7.4 h1:BDXOHExt+A7gwPCJgPIIq7ENvceR7we7rOS9TNoLZeg=
github.com/yuin/goldmark v1.7.4/go.mod h1:uzxRWxtg69N339t3louHJ7+O03ezfj6PlliRlaOzY1E=
github.com/yuin/goldmark-emoji v1.0.3 h1:aLRkLHOuBR2czCY4R8olwMjID+tENfhyFDMCRhbIQY4=
github.com/yuin/goldmark-emoji v1.0.3/go.mod h1:tTkZEbwu5wkPmgTcitqddVxY9osFZiavD+r4AzQrh1U=
github.com/yuin/goldmark-emoji v1.0.4 h1:vCwMkPZSNefSUnOW2ZKRUjBSD5Ok3W78IXhGxxAEF90=
github.com/yuin/goldmark-emoji v1.0.4/go.mod h1:tTkZEbwu5wkPmgTcitqddVxY9osFZiavD+r4AzQrh1U=
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
@@ -509,8 +511,8 @@ golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5y
golang.org/x/crypto v0.0.0-20220331220935-ae2d96664a29/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc=
golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg=
golang.org/x/crypto v0.27.0 h1:GXm2NjJrPaiv/h1tb2UH8QfgC/hOf/+z0p6PT8o1w7A=
golang.org/x/crypto v0.27.0/go.mod h1:1Xngt8kV6Dvbssa53Ziq6Eqn0HqbZi5Z6R0ZpwQzt70=
golang.org/x/crypto v0.28.0 h1:GBDwsMXVQi34v5CCYUm2jkJvu4cbtru2U4TN2PSyQnw=
golang.org/x/crypto v0.28.0/go.mod h1:rmgy+3RHxRZMyY0jjAJShp2zgEdOqj2AO7U0pYmeQ7U=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
@@ -526,8 +528,8 @@ golang.org/x/exp v0.0.0-20221031165847-c99f073a8326/go.mod h1:CxIveKay+FTh1D0yPZ
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
golang.org/x/image v0.0.0-20210220032944-ac19c3e999fb/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
golang.org/x/image v0.20.0 h1:7cVCUjQwfL18gyBJOmYvptfSHS8Fb3YUDtfLIZ7Nbpw=
golang.org/x/image v0.20.0/go.mod h1:0a88To4CYVBAHp5FXJm8o7QbUl37Vd85ply1vyD8auM=
golang.org/x/image v0.21.0 h1:c5qV36ajHpdj4Qi0GnE0jUc/yuo33OLFaa0d+crTD5s=
golang.org/x/image v0.21.0/go.mod h1:vUbsLavqK/W303ZroQQVKQ+Af3Yl6Uz1Ppu5J/cLz78=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
@@ -595,8 +597,8 @@ golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk=
golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY=
golang.org/x/net v0.29.0 h1:5ORfpBpCs4HzDYoodCDBbwHzdR5UrLBZ3sOnUJmFoHo=
golang.org/x/net v0.29.0/go.mod h1:gLkgy8jTGERgjzMic6DS9+SP0ajcu6Xu3Orq/SpETg0=
golang.org/x/net v0.30.0 h1:AcW1SDZMkb8IpzCdQUaIq2sP4sZ4zw+55h6ynffypl4=
golang.org/x/net v0.30.0/go.mod h1:2wGyMJ5iFasEhkwi13ChkO/t1ECNC4X4eBKkVFyYFlU=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
@@ -672,8 +674,8 @@ golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34=
golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.26.0 h1:KHjCJyddX0LoSTb3J+vWpupP9p0oznkqVk/IfjymZbo=
golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
@@ -692,8 +694,8 @@ golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
golang.org/x/text v0.18.0 h1:XvMDiNzPAl0jr17s6W9lcaIhGUfUORdGCNsuLmPG224=
golang.org/x/text v0.18.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
golang.org/x/text v0.19.0 h1:kTxAhCbGbxhK0IwgSKiMO5awPoDQ0RpfiVYBfK860YM=
golang.org/x/text v0.19.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
@@ -751,8 +753,8 @@ golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58=
golang.org/x/tools v0.17.0/go.mod h1:xsh6VxdV005rRVaS6SSAf9oiAqljS7UZUacMZ8Bnsps=
golang.org/x/tools v0.23.0 h1:SGsXPZ+2l4JsgaCKkx+FQ9YZ5XEtA1GZYuoDjenLjvg=
golang.org/x/tools v0.23.0/go.mod h1:pnu6ufv6vQkll6szChhK3C3L/ruaIv5eBeztNG8wtsI=
golang.org/x/tools v0.26.0 h1:v/60pFQmzmT9ExmjDv2gGIfi3OqfKoEP6I5+umXlbnQ=
golang.org/x/tools v0.26.0/go.mod h1:TPVVj70c7JJ3WCazhD8OdXcZg/og+b9+tH/KxylGwH0=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
-3
View File
@@ -179,9 +179,6 @@ type hugoSitesInit struct {
// Loads the data from all of the /data folders.
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.
gitInfo *lazy.Init
}
-10
View File
@@ -250,10 +250,6 @@ func (h *HugoSites) process(ctx context.Context, l logg.LevelLogger, config *Bui
l = l.WithField("step", "process")
defer loggers.TimeTrackf(l, time.Now(), nil, "")
if _, err := h.init.layouts.Do(ctx); err != nil {
return err
}
if len(events) > 0 {
// This is a rebuild triggered from file 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 {
// 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) {
// TODO(bep) this could probably be optimized to somehow
// 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 {
// 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]{
NumWorkers: h.numWorkers,
Handle: func(ctx context.Context, p *pagesfromdata.PagesFromTemplate) error {
+6 -5
View File
@@ -246,11 +246,6 @@ func (s *IntegrationTestBuilder) AssertBuildCountGitInfo(count int) {
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) {
s.Helper()
fs := s.fs.WorkingDirReadOnly
@@ -421,6 +416,12 @@ func (s *IntegrationTestBuilder) Build() *IntegrationTestBuilder {
s.Assert(err, qt.IsNil)
}
s.Cleanup(func() {
if h := s.H; h != nil {
s.Assert(h.Close(), qt.IsNil)
}
})
return s
}
+9 -4
View File
@@ -34,6 +34,15 @@ import (
var pageIDCounter atomic.Uint64
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{}
if m.pageMetaParams == nil {
m.pageMetaParams = &pageMetaParams{
@@ -231,10 +240,6 @@ func (h *HugoSites) newPage(m *pageMeta) (*pageState, *paths.Path, error) {
}
return ps, nil
}()
// Make sure to evict any cached and now stale data.
if err != nil {
m.MarkStale()
}
if ps == nil {
return nil, nil, err
+3 -13
View File
@@ -344,7 +344,6 @@ func newHugoSites(cfg deps.DepsCfg, d *deps.Deps, pageTrees *pageTrees, sites []
skipRebuildForFilenames: make(map[string]bool),
init: &hugoSitesInit{
data: lazy.New(),
layouts: lazy.New(),
gitInfo: lazy.New(),
},
}
@@ -400,15 +399,6 @@ func newHugoSites(cfg deps.DepsCfg, d *deps.Deps, pageTrees *pageTrees, sites []
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) {
err := h.loadGitInfo()
if err != nil {
@@ -511,20 +501,20 @@ func (s *Site) Params() maps.Params {
// Deprecated: Use taxonomies instead.
func (s *Site) Author() map[string]any {
if len(s.conf.Author) != 0 {
hugo.Deprecate(".Site.Author", "Use taxonomies instead.", "v0.124.0")
hugo.Deprecate(".Site.Author", "Implement taxonomy 'author' or use .Site.Params.Author instead.", "v0.124.0")
}
return s.conf.Author
}
// Deprecated: Use taxonomies instead.
func (s *Site) Authors() page.AuthorList {
hugo.Deprecate(".Site.Authors", "Use taxonomies instead.", "v0.124.0")
hugo.Deprecate(".Site.Authors", "Implement taxonomy 'authors' or use .Site.Params.Author instead.", "v0.124.0")
return page.AuthorList{}
}
// Deprecated: Use .Site.Params instead.
func (s *Site) Social() map[string]string {
hugo.Deprecate(".Site.Social", "Use .Site.Params instead.", "v0.124.0")
hugo.Deprecate(".Site.Social", "Implement taxonomy 'social' or use .Site.Params.Social instead.", "v0.124.0")
return s.conf.Social
}
+7 -2
View File
@@ -1,7 +1,12 @@
# Release env.
# These will be replaced by script before release.
HUGORELEASER_TAG=v0.135.0
HUGORELEASER_COMMITISH=f30603c47f5205e30ef83c70419f57d7eb7175ab
HUGORELEASER_TAG=v0.136.5
HUGORELEASER_COMMITISH=46cccb021bc6425455f4eec093f5cc4a32f1d12c
+1 -1
View File
@@ -254,7 +254,7 @@ func CreateTargetPaths(d TargetPathDescriptor) (tp TargetPaths) {
// if page URL is explicitly set in frontmatter,
// preserve its value without sanitization
if d.Kind != kinds.KindPage || d.URL == "" {
if d.URL == "" {
// Note: MakePathSanitized will lower case the path if
// disablePathToLower isn't set.
pb.Sanitize()
+31 -46
View File
@@ -107,27 +107,37 @@ func NewPermalinkExpander(urlize func(uri string) string, patterns map[string]ma
return p, nil
}
// Escape sequence for colons in permalink patterns.
const escapePlaceholderColon = "\x00"
func (l PermalinkExpander) normalizeEscapeSequencesIn(s string) (string, bool) {
s2 := strings.ReplaceAll(s, "\\:", escapePlaceholderColon)
return s2, s2 != s
}
func (l PermalinkExpander) normalizeEscapeSequencesOut(result string) string {
return strings.ReplaceAll(result, escapePlaceholderColon, ":")
}
// ExpandPattern expands the path in p with the specified expand pattern.
func (l PermalinkExpander) ExpandPattern(pattern string, p Page) (string, error) {
expander, err := l.getOrParsePattern(pattern)
expand, err := l.getOrParsePattern(pattern)
if err != nil {
return "", err
}
return expander(p)
return expand(p)
}
// Expand expands the path in p according to the rules defined for the given key.
// If no rules are found for the given key, an empty string is returned.
func (l PermalinkExpander) Expand(key string, p Page) (string, error) {
expanders, found := l.expanders[p.Kind()]
if !found {
return "", nil
}
expand, found := expanders[key]
if !found {
return "", nil
}
@@ -146,10 +156,19 @@ func init() {
func (l PermalinkExpander) getOrParsePattern(pattern string) (func(Page) (string, error), error) {
return l.patternCache.GetOrCreate(pattern, func() (func(Page) (string, error), error) {
if !l.validate(pattern) {
return nil, &permalinkExpandError{pattern: pattern, err: errPermalinkIllFormed}
}
var normalized bool
pattern, normalized = l.normalizeEscapeSequencesIn(pattern)
matches := attributeRegexp.FindAllStringSubmatch(pattern, -1)
if matches == nil {
result := pattern
if normalized {
result = l.normalizeEscapeSequencesOut(result)
}
return func(p Page) (string, error) {
return result, nil
}, nil
}
callbacks := make([]pageToPermaAttribute, len(matches))
replacements := make([]string, len(matches))
@@ -167,10 +186,6 @@ func (l PermalinkExpander) getOrParsePattern(pattern string) (func(Page) (string
}
return func(p Page) (string, error) {
if matches == nil {
return pattern, nil
}
newField := pattern
for i, replacement := range replacements {
@@ -184,6 +199,10 @@ func (l PermalinkExpander) getOrParsePattern(pattern string) (func(Page) (string
newField = strings.Replace(newField, replacement, newAttr, 1)
}
if normalized {
newField = l.normalizeEscapeSequencesOut(newField)
}
return newField, nil
}, nil
})
@@ -212,37 +231,6 @@ type pageToPermaAttribute func(Page, string) (string, error)
var attributeRegexp = regexp.MustCompile(`:\w+(\[.+?\])?`)
// validate determines if a PathPattern is well-formed
func (l PermalinkExpander) validate(pp string) bool {
if len(pp) == 0 {
return false
}
fragments := strings.Split(pp[1:], "/")
bail := false
for i := range fragments {
if bail {
return false
}
if len(fragments[i]) == 0 {
bail = true
continue
}
matches := attributeRegexp.FindAllStringSubmatch(fragments[i], -1)
if matches == nil {
continue
}
for _, match := range matches {
k := match[0][1:]
if _, ok := l.callback(k); !ok {
return false
}
}
}
return true
}
type permalinkExpandError struct {
pattern string
err error
@@ -252,10 +240,7 @@ func (pee *permalinkExpandError) Error() string {
return fmt.Sprintf("error expanding %q: %s", pee.pattern, pee.err)
}
var (
errPermalinkIllFormed = errors.New("permalink ill-formed")
errPermalinkAttributeUnknown = errors.New("permalink attribute not recognised")
)
var errPermalinkAttributeUnknown = errors.New("permalink attribute not recognised")
func (l PermalinkExpander) pageToPermalinkDate(p Page, dateField string) (string, error) {
// a Page contains a Node which provides a field Date, time.Time
@@ -18,6 +18,7 @@ import (
"github.com/bep/logg"
qt "github.com/frankban/quicktest"
"github.com/gohugoio/hugo/htesting"
"github.com/gohugoio/hugo/hugolib"
)
@@ -232,3 +233,47 @@ slug: custom-recipe-2
b.AssertFileContent("public/delicious-recipe/recipe-1/index.html", "Single|page|/delicious-recipe/recipe-1/")
b.AssertFileContent("public/delicious-recipe/custom-recipe-2/index.html", "Single|page|/delicious-recipe/custom-recipe-2/")
}
// Issue 12948.
// Issue 12954.
func TestPermalinksWithEscapedColons(t *testing.T) {
t.Parallel()
if htesting.IsWindows() {
t.Skip("Windows does not support colons in paths")
}
files := `
-- hugo.toml --
disableKinds = ['home','rss','sitemap','taxonomy','term']
[permalinks.page]
s2 = "/c\\:d/:slug/"
-- content/s1/_index.md --
---
title: s1
url: "/a\\:b/:slug/"
---
-- content/s1/p1.md --
---
title: p1
url: "/a\\:b/:slug/"
---
-- content/s2/p2.md --
---
title: p2
---
-- layouts/_default/single.html --
{{ .Title }}
-- layouts/_default/list.html --
{{ .Title }}
`
b := hugolib.Test(t, files)
b.AssertFileExists("public/a:b/p1/index.html", true)
b.AssertFileExists("public/a:b/s1/index.html", true)
// The above URLs come from the URL front matter field where everything is allowed.
// We strip colons from paths constructed by Hugo (they are not supported on Windows).
b.AssertFileExists("public/cd/p2/index.html", true)
}
+11
View File
@@ -44,6 +44,8 @@ var testdataPermalinks = []struct {
{"/:sections/", true, "/a/b/c/"}, // Sections
{"/:sections[last]/", true, "/c/"}, // Sections
{"/:sections[0]/:sections[last]/", true, "/a/c/"}, // Sections
{"/\\:filename", true, "/:filename"}, // Escape sequence
{"/special\\::slug/", true, "/special:the-slug/"}, // Escape sequence
// Failures
{"/blog/:fred", false, ""},
@@ -90,6 +92,10 @@ func TestPermalinkExpansion(t *testing.T) {
expanded, err := expander.Expand("posts", page)
c.Assert(err, qt.IsNil)
c.Assert(expanded, qt.Equals, item.expandsTo)
expanded, err = expander.ExpandPattern(item.spec, page)
c.Assert(err, qt.IsNil)
c.Assert(expanded, qt.Equals, item.expandsTo)
})
}
@@ -117,6 +123,7 @@ func TestPermalinkExpansionMultiSection(t *testing.T) {
"posts": "/:slug",
"blog": "/:section/:year",
"recipes": "/:slugorfilename",
"special": "/special\\::slug",
},
}
expander, err := NewPermalinkExpander(urlize, permalinksConfig)
@@ -137,6 +144,10 @@ func TestPermalinkExpansionMultiSection(t *testing.T) {
expanded, err = expander.Expand("recipes", page_slug_fallback)
c.Assert(err, qt.IsNil)
c.Assert(expanded, qt.Equals, "/page-filename")
expanded, err = expander.Expand("special", page)
c.Assert(err, qt.IsNil)
c.Assert(expanded, qt.Equals, "/special:the-slug")
}
func TestPermalinkExpansionConcurrent(t *testing.T) {
+21
View File
@@ -0,0 +1,21 @@
#!/bin/sh
# Check if a custom hugo-docker-entrypoint.sh file exists.
if [ -f hugo-docker-entrypoint.sh ]; then
# Execute the custom entrypoint file.
sh hugo-docker-entrypoint.sh "$@"
exit $?
fi
# Check if a package.json file exists.
if [ -f package.json ]; then
# Check if node_modules exists.
if [ ! -d node_modules ]; then
# Install npm packages.
# Note that we deliberately do not use `npm ci` here, as it would fail if the package-lock.json file is not up-to-date,
# which would be the case if you run the container with a different OS or architecture than the one used to create the package-lock.json file.
npm i
fi
fi
exec "hugo" "$@"
+1 -1
View File
@@ -1,7 +1,7 @@
# Test the config command.
hugo config -h
stdout 'Print the site configuration'
stdout 'Display site configuration'
hugo config
+1 -1
View File
@@ -1,7 +1,7 @@
# Test the convert commands.
hugo convert -h
stdout 'Convert your content'
stdout 'Convert front matter to another format'
hugo convert toJSON -h
stdout 'to use JSON for the front matter'
hugo convert toTOML -h
+1 -1
View File
@@ -1,7 +1,7 @@
# Test the deploy command.
hugo deploy -h
stdout 'Deploy your site to a Cloud provider\.'
stdout 'Deploy your site to a cloud provider'
mkdir mybucket
hugo deploy --target mydeployment --invalidateCDN=false
grep 'hello' mybucket/index.html
+1 -1
View File
@@ -3,7 +3,7 @@
env NUM_COMMANDS=44
hugo gen -h
stdout 'A collection of several useful generators\.'
stdout 'Generate documentation for your project using Hugo''s documentation engine, including syntax highlighting for various programming languages\.'
hugo gen doc --dir clidocs
checkfilecount $NUM_COMMANDS clidocs
+2 -2
View File
@@ -1,7 +1,7 @@
# Test the import jekyll command.
# Test the import + import jekyll command.
hugo import -h
stdout 'Import your site from other web site generators like Jekyll\.'
stdout 'Import a site from another system'
hugo import jekyll -h
stdout 'hugo import from Jekyll\.'
+33
View File
@@ -65,6 +65,20 @@ cd myexistingsite
hugo new post/foo.md -t mytheme
grep 'Dummy content' content/post/foo.md
cd $WORK
# In the three archetype format tests below, skip Windows testing to avoid
# newline differences when comparing to golden.
hugo new site json-site --format json
[!windows] cmp json-site/archetypes/default.md archetype-golden-json.md
hugo new site toml-site --format toml
[!windows] cmp toml-site/archetypes/default.md archetype-golden-toml.md
hugo new site yaml-site --format yaml
[!windows] cmp yaml-site/archetypes/default.md archetype-golden-yaml.md
-- myexistingsite/hugo.toml --
theme = "mytheme"
-- myexistingsite/content/p1.md --
@@ -80,3 +94,22 @@ draft: true
---
Dummy content.
-- archetype-golden-json.md --
{
"date": "{{ .Date }}",
"draft": true,
"title": "{{ replace .File.ContentBaseName \"-\" \" \" | title }}"
}
-- archetype-golden-toml.md --
+++
date = '{{ .Date }}'
draft = true
title = '{{ replace .File.ContentBaseName "-" " " | title }}'
+++
-- archetype-golden-yaml.md --
---
date: '{{ .Date }}'
draft: true
title: '{{ replace .File.ContentBaseName "-" " " | title }}'
---
@@ -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
+11
View File
@@ -450,6 +450,17 @@ func (ns *Namespace) Trim(s, cutset any) (string, error) {
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
// contained in cutset removed.
func (ns *Namespace) TrimLeft(cutset, s any) (string, error) {
+27
View File
@@ -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)
}
}
-1
View File
@@ -40,7 +40,6 @@ type TemplateManager interface {
TemplateHandler
TemplateFuncGetter
AddTemplate(name, tpl string) error
MarkReady() error
}
// TemplateVariants describes the possible variants of a template.
@@ -8,8 +8,8 @@
<meta property="og:title" content="{{ . }}">
{{- end }}
{{- with or .Description .Summary site.Params.description | plainify | htmlUnescape | chomp }}
<meta property="og:description" content="{{ . }}">
{{- with or .Description .Summary site.Params.description | plainify | htmlUnescape }}
<meta property="og:description" content="{{ trim . "\n\r\t " }}">
{{- end }}
{{- with or .Params.locale site.Language.LanguageCode }}
+2 -2
View File
@@ -2,8 +2,8 @@
<meta itemprop="name" content="{{ . }}">
{{- end }}
{{- with or .Description .Summary site.Params.description | plainify | htmlUnescape | chomp }}
<meta itemprop="description" content="{{ . }}">
{{- with or .Description .Summary site.Params.description | plainify | htmlUnescape }}
<meta itemprop="description" content="{{ trim . "\n\r\t " }}">
{{- end }}
{{- $ISO8601 := "2006-01-02T15:04:05-07:00" }}
@@ -10,8 +10,8 @@
<meta name="twitter:title" content="{{ . }}">
{{- end }}
{{- with or .Description .Summary site.Params.description | plainify | htmlUnescape | chomp }}
<meta name="twitter:description" content="{{ . }}">
{{- with or .Description .Summary site.Params.description | plainify | htmlUnescape }}
<meta name="twitter:description" content="{{ trim . "\n\r\t " }}">
{{- end }}
{{- $twitterSite := "" }}
+4 -17
View File
@@ -168,6 +168,10 @@ func newTemplateHandlers(d *deps.Deps) (*tpl.TemplateHandlers, error) {
return nil, err
}
if err := h.main.createPrototypes(); err != nil {
return nil, err
}
e := &templateExec{
d: d,
executor: exec,
@@ -312,28 +316,11 @@ func (t *templateExec) GetFunc(name string) (reflect.Value, bool) {
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 {
main *templateNamespace
needsBaseof map[string]templateInfo
baseof map[string]templateInfo
readyInit sync.Once
// This is the filesystem to load the templates from. All the templates are
// stored in the root of this filesystem.
layoutsFs afero.Fs
+19 -1
View File
@@ -248,7 +248,7 @@ func TestToMathMacros(t *testing.T) {
-- hugo.toml --
disableKinds = ['page','rss','section','sitemap','taxonomy','term']
-- layouts/index.html --
{{ $macros := dict
{{ $macros := dict
"\\addBar" "\\bar{#1}"
"\\bold" "\\mathbf{#1}"
}}
@@ -261,3 +261,21 @@ disableKinds = ['page','rss','section','sitemap','taxonomy','term']
<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}}`)
}
+2 -2
View File
@@ -113,8 +113,8 @@ func (ns *Namespace) Unmarshal(args ...any) (any, error) {
return nil, fmt.Errorf("type %T not supported", data)
}
if dataStr == "" {
return nil, errors.New("no data to transform")
if strings.TrimSpace(dataStr) == "" {
return nil, nil
}
key := hashing.MD5FromStringHexEncoded(dataStr)
+2
View File
@@ -139,6 +139,8 @@ func TestUnmarshal(t *testing.T) {
a;b;c`, mime: media.Builtin.CSVType}, map[string]any{"DElimiter": ";", "Comment": "%"}, func(r [][]string) {
b.Assert([][]string{{"a", "b", "c"}}, qt.DeepEquals, r)
}},
{``, nil, nil},
{` `, nil, nil},
// errors
{"thisisnotavaliddataformat", nil, false},
{testContentResource{key: "r1", content: `invalid&toml"`, mime: media.Builtin.TOMLType}, nil, false},