Compare commits

...

51 commits

Author SHA1 Message Date
David Jones
dd6e2c8724
deploy: walkLocal worker pool for performance
Some checks are pending
Test / test (1.23.x, ubuntu-latest) (push) Waiting to run
Test / test (1.23.x, windows-latest) (push) Waiting to run
Test / test (1.24.x, ubuntu-latest) (push) Waiting to run
Test / test (1.24.x, windows-latest) (push) Waiting to run
2025-06-29 16:41:56 +02:00
hugoreleaser
762417617c releaser: Prepare repository for 0.148.0-DEV
[ci skip]
2025-06-23 08:38:21 +00:00
hugoreleaser
29bdbde19c releaser: Bump versions for release of 0.147.9
[ci skip]
2025-06-23 08:22:20 +00:00
Bjørn Erik Pedersen
6a4a3ab8f8 Remove WARN with false negatives
Fixes #13806
2025-06-22 16:55:43 +02:00
Bjørn Erik Pedersen
36f6f987a9 resources/page: Make sure a map is always initialized
Fixes #13810
2025-06-21 14:38:06 +02:00
Joe Mooring
18a9ca7d7a tpl/tplimpl: Copy embedded HTML table render hook to each output format
Closes #13351
2025-06-21 14:37:47 +02:00
Joe Mooring
b6c8dfa9dc
tpl/tplimpl: Change resources.GetRemote errors to suppressible warnings
Closes #13803
2025-06-17 07:35:14 -07:00
dependabot[bot]
621ea42f3c build(deps): bump google.golang.org/api from 0.221.0 to 0.237.0
Bumps [google.golang.org/api](https://github.com/googleapis/google-api-go-client) from 0.221.0 to 0.237.0.
- [Release notes](https://github.com/googleapis/google-api-go-client/releases)
- [Changelog](https://github.com/googleapis/google-api-go-client/blob/main/CHANGES.md)
- [Commits](https://github.com/googleapis/google-api-go-client/compare/v0.221.0...v0.237.0)

---
updated-dependencies:
- dependency-name: google.golang.org/api
  dependency-version: 0.237.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-06-13 13:53:25 +02:00
Bjørn Erik Pedersen
4ef5720141
hugolib: Remove test for deprecated future 2025-06-13 12:17:06 +02:00
dependabot[bot]
34e83789f7 build(deps): bump github.com/aws/aws-sdk-go-v2 from 1.36.1 to 1.36.4
Bumps [github.com/aws/aws-sdk-go-v2](https://github.com/aws/aws-sdk-go-v2) from 1.36.1 to 1.36.4.
- [Release notes](https://github.com/aws/aws-sdk-go-v2/releases)
- [Changelog](https://github.com/aws/aws-sdk-go-v2/blob/main/changelog-template.json)
- [Commits](https://github.com/aws/aws-sdk-go-v2/compare/v1.36.1...v1.36.4)

---
updated-dependencies:
- dependency-name: github.com/aws/aws-sdk-go-v2
  dependency-version: 1.36.4
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-06-13 11:25:11 +02:00
dependabot[bot]
4d3ebe4d21 build(deps): bump golang.org/x/image from 0.27.0 to 0.28.0
Bumps [golang.org/x/image](https://github.com/golang/image) from 0.27.0 to 0.28.0.
- [Commits](https://github.com/golang/image/compare/v0.27.0...v0.28.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2025-06-12 14:17:16 +02:00
Joe Mooring
b5c0383bda deps: Upgrade github.com/spf13/cast v1.8.0 => v1.9.2 2025-06-12 10:07:09 +02:00
Joe Mooring
4217fee4b0 common/terminal: Enable color output on windows
Closes #8209
2025-06-09 11:44:13 +02:00
hugoreleaser
fad57964aa releaser: Prepare repository for 0.148.0-DEV
[ci skip]
2025-06-07 13:13:56 +00:00
hugoreleaser
10da2bd765 releaser: Bump versions for release of 0.147.8
[ci skip]
2025-06-07 12:59:52 +00:00
Joe Mooring
01241d5dc9 hugolib: Emit ignorable warning when home page is a leaf bundle
Closes #13538
2025-06-07 13:02:28 +02:00
Bjørn Erik Pedersen
8e61f1fe12
dockerfile: Update Alpine
Closes #13783
2025-06-06 08:16:30 +02:00
Bjørn Erik Pedersen
f37412a575
dockerfile: Update Go version
FIxes #13780
2025-06-04 16:52:17 +02:00
dependabot[bot]
21a4a9acd7 build(deps): bump github.com/evanw/esbuild from 0.25.3 to 0.25.5
Bumps [github.com/evanw/esbuild](https://github.com/evanw/esbuild) from 0.25.3 to 0.25.5.
- [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.25.3...v0.25.5)

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

Signed-off-by: dependabot[bot] <support@github.com>
2025-06-03 11:27:57 +02:00
dependabot[bot]
7a4a4790e5 build(deps): bump github.com/niklasfasching/go-org from 1.7.0 to 1.8.0
Bumps [github.com/niklasfasching/go-org](https://github.com/niklasfasching/go-org) from 1.7.0 to 1.8.0.
- [Commits](https://github.com/niklasfasching/go-org/compare/v1.7.0...v1.8.0)

---
updated-dependencies:
- dependency-name: github.com/niklasfasching/go-org
  dependency-version: 1.8.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-06-03 11:26:51 +02:00
dependabot[bot]
54065b7ef8 build(deps): bump golang.org/x/net from 0.39.0 to 0.40.0
Bumps [golang.org/x/net](https://github.com/golang/net) from 0.39.0 to 0.40.0.
- [Commits](https://github.com/golang/net/compare/v0.39.0...v0.40.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2025-06-03 09:01:37 +02:00
dependabot[bot]
e333836f49 build(deps): bump github.com/yuin/goldmark from 1.7.11 to 1.7.12
Bumps [github.com/yuin/goldmark](https://github.com/yuin/goldmark) from 1.7.11 to 1.7.12.
- [Release notes](https://github.com/yuin/goldmark/releases)
- [Commits](https://github.com/yuin/goldmark/compare/v1.7.11...v1.7.12)

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

Signed-off-by: dependabot[bot] <support@github.com>
2025-06-02 18:18:44 +02:00
dependabot[bot]
cc7bfeea32 build(deps): bump github.com/tdewolff/minify/v2 from 2.23.5 to 2.23.8
Bumps [github.com/tdewolff/minify/v2](https://github.com/tdewolff/minify) from 2.23.5 to 2.23.8.
- [Release notes](https://github.com/tdewolff/minify/releases)
- [Commits](https://github.com/tdewolff/minify/compare/v2.23.5...v2.23.8)

---
updated-dependencies:
- dependency-name: github.com/tdewolff/minify/v2
  dependency-version: 2.23.8
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-06-02 18:18:24 +02:00
Bjørn Erik Pedersen
32eb1a8ad4 all: Replace _build with build in tests
_build is deprecated and now shows up as warning.
2025-06-02 16:35:37 +02:00
hugoreleaser
32af02cd3e releaser: Prepare repository for 0.148.0-DEV
[ci skip]
2025-05-31 12:55:24 +00:00
hugoreleaser
189453612e releaser: Bump versions for release of 0.147.7
[ci skip]
2025-05-31 12:41:12 +00:00
Bjørn Erik Pedersen
5273a884d4 Fix language handling in shortcode templates
Fixes #13767
2025-05-31 13:57:00 +02:00
Bjørn Erik Pedersen
6334948515
Handle KaTeX warnings (#13760)
Co-authored-by: Joe Mooring <joe.mooring@veriphor.com>

Fixes #13735
2025-05-30 20:57:54 +02:00
dependabot[bot]
75259636c8 build(deps): bump golang.org/x/image from 0.26.0 to 0.27.0
Bumps [golang.org/x/image](https://github.com/golang/image) from 0.26.0 to 0.27.0.
- [Commits](https://github.com/golang/image/compare/v0.26.0...v0.27.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2025-05-30 15:13:21 +02:00
dependabot[bot]
0df9f3510f build(deps): bump golang.org/x/text from 0.24.0 to 0.25.0
Bumps [golang.org/x/text](https://github.com/golang/text) from 0.24.0 to 0.25.0.
- [Release notes](https://github.com/golang/text/releases)
- [Commits](https://github.com/golang/text/compare/v0.24.0...v0.25.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2025-05-30 12:50:09 +02:00
dependabot[bot]
302e6a726b build(deps): bump github.com/spf13/cast from 1.7.1 to 1.8.0
Bumps [github.com/spf13/cast](https://github.com/spf13/cast) from 1.7.1 to 1.8.0.
- [Release notes](https://github.com/spf13/cast/releases)
- [Commits](https://github.com/spf13/cast/compare/v1.7.1...v1.8.0)

---
updated-dependencies:
- dependency-name: github.com/spf13/cast
  dependency-version: 1.8.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-05-30 08:34:09 +02:00
dependabot[bot]
202fe0d45c build(deps): bump github.com/alecthomas/chroma/v2 from 2.17.2 to 2.18.0
Bumps [github.com/alecthomas/chroma/v2](https://github.com/alecthomas/chroma) from 2.17.2 to 2.18.0.
- [Release notes](https://github.com/alecthomas/chroma/releases)
- [Changelog](https://github.com/alecthomas/chroma/blob/master/.goreleaser.yml)
- [Commits](https://github.com/alecthomas/chroma/compare/v2.17.2...v2.18.0)

---
updated-dependencies:
- dependency-name: github.com/alecthomas/chroma/v2
  dependency-version: 2.18.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-05-29 22:12:58 +02:00
Joe Mooring
843ffeb48d resources/page: Respect disablePathToLower for permalink tokens
Fixes #13755
2025-05-29 22:10:03 +02:00
Ruslan Semagin
bff5d19121 common/collections: Increase test coverage 2025-05-29 09:17:13 +02:00
Ruslan Semagin
da370d30de parser/pageparser: Add coverage for all IsX methods of Item
Added tests for all boolean methods on Item, increasing overall code coverage.
2025-05-28 21:53:17 +02:00
Bjørn Erik Pedersen
6bd328c584 resources: Remove unused interface 2025-05-28 19:32:28 +02:00
Bjørn Erik Pedersen
766a2e7868 Make sure that unreferenced but changed bundle resources gets republished
Fixes #13748
2025-05-28 19:32:28 +02:00
Bjørn Erik Pedersen
13e1617557 deps: Upgrade github.com/olekukonko/tablewriter v0.0.5 => v1.0.7 2025-05-28 18:07:14 +02:00
hugoreleaser
463e440c7a releaser: Prepare repository for 0.148.0-DEV
[ci skip]
2025-05-27 11:31:53 +00:00
hugoreleaser
0a5fd8ebb8 releaser: Bump versions for release of 0.147.6
[ci skip]
2025-05-27 11:17:16 +00:00
Andreas Deininger
e57dcd3795 Improve warning message on superfluous prefix when using function 'partials.Include' 2025-05-27 12:16:26 +02:00
Bjørn Erik Pedersen
eaf5ace30d Fix recent regression with cascading of params to content adapters
Fixes #13743
2025-05-26 21:26:19 +02:00
Bjørn Erik Pedersen
9ad26b69ad Fix it so e.g. de in layouts/_shortcodes/de.html is not interpreted as a language code
Fixes #13740
2025-05-26 20:26:56 +02:00
Bjørn Erik Pedersen
f47193669d commands: Make sure the browser gets refreshed on changes when --disableFastRender is set
Fixes #13727
2025-05-23 19:46:16 +02:00
Joe Mooring
013c8cfb25 tpl/transform: Expose the KaTeX strict option
Closes #13729
2025-05-23 19:21:38 +02:00
hugoreleaser
e25db38467 releaser: Prepare repository for 0.148.0-DEV
[ci skip]
2025-05-22 11:51:47 +00:00
hugoreleaser
7766fc6241 releaser: Bump versions for release of 0.147.5
[ci skip]
2025-05-22 11:37:19 +00:00
Bjørn Erik Pedersen
4a48facef4
Merge branch 'release-0.147.4' 2025-05-22 13:19:34 +02:00
Bjørn Erik Pedersen
0c7b1a3f26 Fix live reload when editing inline partials
Fixes #13723
2025-05-22 13:15:41 +02:00
dependabot[bot]
970b887ba1 build(deps): bump github.com/tdewolff/minify/v2 from 2.20.37 to 2.23.5
Bumps [github.com/tdewolff/minify/v2](https://github.com/tdewolff/minify) from 2.20.37 to 2.23.5.
- [Release notes](https://github.com/tdewolff/minify/releases)
- [Commits](https://github.com/tdewolff/minify/compare/v2.20.37...v2.23.5)

---
updated-dependencies:
- dependency-name: github.com/tdewolff/minify/v2
  dependency-version: 2.23.5
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-05-20 14:49:06 +02:00
hugoreleaser
b9b95e5aec releaser: Prepare repository for 0.148.0-DEV
[ci skip]
2025-05-20 10:55:43 +00:00
67 changed files with 1461 additions and 543 deletions

View file

@ -2,8 +2,8 @@
# Twitter: https://twitter.com/gohugoio # Twitter: https://twitter.com/gohugoio
# Website: https://gohugo.io/ # Website: https://gohugo.io/
ARG GO_VERSION="1.23.2" ARG GO_VERSION="1.24"
ARG ALPINE_VERSION="3.20" ARG ALPINE_VERSION="3.22"
ARG DART_SASS_VERSION="1.79.3" ARG DART_SASS_VERSION="1.79.3"
FROM --platform=$BUILDPLATFORM tonistiigi/xx:1.5.0 AS xx FROM --platform=$BUILDPLATFORM tonistiigi/xx:1.5.0 AS xx

View file

@ -972,6 +972,9 @@ func (c *hugoBuilder) handleEvents(watcher *watcher.Batcher,
lrl.Logf("force refresh") lrl.Logf("force refresh")
livereload.ForceRefresh() livereload.ForceRefresh()
} }
} else {
lrl.Logf("force refresh")
livereload.ForceRefresh()
} }
if len(cssChanges) > 0 { if len(cssChanges) > 0 {

View file

@ -15,6 +15,7 @@ package collections
import ( import (
"html/template" "html/template"
"reflect"
"testing" "testing"
qt "github.com/frankban/quicktest" qt "github.com/frankban/quicktest"
@ -77,6 +78,7 @@ func TestAppend(t *testing.T) {
{[]string{"a", "b"}, []any{nil}, []any{"a", "b", nil}}, {[]string{"a", "b"}, []any{nil}, []any{"a", "b", nil}},
{[]string{"a", "b"}, []any{nil, "d", nil}, []any{"a", "b", nil, "d", nil}}, {[]string{"a", "b"}, []any{nil, "d", nil}, []any{"a", "b", nil, "d", nil}},
{[]any{"a", nil, "c"}, []any{"d", nil, "f"}, []any{"a", nil, "c", "d", nil, "f"}}, {[]any{"a", nil, "c"}, []any{"d", nil, "f"}, []any{"a", nil, "c", "d", nil, "f"}},
{[]string{"a", "b"}, []any{}, []string{"a", "b"}},
} { } {
result, err := Append(test.start, test.addend...) result, err := Append(test.start, test.addend...)
@ -146,3 +148,66 @@ func TestAppendShouldMakeACopyOfTheInputSlice(t *testing.T) {
c.Assert(result, qt.DeepEquals, []string{"a", "b", "c"}) c.Assert(result, qt.DeepEquals, []string{"a", "b", "c"})
c.Assert(slice, qt.DeepEquals, []string{"d", "b"}) c.Assert(slice, qt.DeepEquals, []string{"d", "b"})
} }
func TestIndirect(t *testing.T) {
t.Parallel()
c := qt.New(t)
type testStruct struct {
Field string
}
var (
nilPtr *testStruct
nilIface interface{} = nil
nonNilIface interface{} = &testStruct{Field: "hello"}
)
tests := []struct {
name string
input any
wantKind reflect.Kind
wantNil bool
}{
{
name: "nil pointer",
input: nilPtr,
wantKind: reflect.Ptr,
wantNil: true,
},
{
name: "nil interface",
input: nilIface,
wantKind: reflect.Invalid,
wantNil: false,
},
{
name: "non-nil pointer to struct",
input: &testStruct{Field: "abc"},
wantKind: reflect.Struct,
wantNil: false,
},
{
name: "non-nil interface holding pointer",
input: nonNilIface,
wantKind: reflect.Struct,
wantNil: false,
},
{
name: "plain value",
input: testStruct{Field: "xyz"},
wantKind: reflect.Struct,
wantNil: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
v := reflect.ValueOf(tt.input)
got, isNil := indirect(v)
c.Assert(got.Kind(), qt.Equals, tt.wantKind)
c.Assert(isNil, qt.Equals, tt.wantNil)
})
}
}

View file

@ -136,3 +136,37 @@ func TestSortedStringSlice(t *testing.T) {
c.Assert(s.Count("z"), qt.Equals, 0) c.Assert(s.Count("z"), qt.Equals, 0)
c.Assert(s.Count("a"), qt.Equals, 1) c.Assert(s.Count("a"), qt.Equals, 1)
} }
func TestStringSliceToInterfaceSlice(t *testing.T) {
t.Parallel()
c := qt.New(t)
tests := []struct {
name string
in []string
want []any
}{
{
name: "empty slice",
in: []string{},
want: []any{},
},
{
name: "single element",
in: []string{"hello"},
want: []any{"hello"},
},
{
name: "multiple elements",
in: []string{"a", "b", "c"},
want: []any{"a", "b", "c"},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got := StringSliceToInterfaceSlice(tt.in)
c.Assert(got, qt.DeepEquals, tt.want)
})
}
}

View file

@ -0,0 +1,77 @@
package collections
import (
"testing"
qt "github.com/frankban/quicktest"
)
func TestNewStack(t *testing.T) {
t.Parallel()
c := qt.New(t)
s := NewStack[int]()
c.Assert(s, qt.IsNotNil)
}
func TestStackBasic(t *testing.T) {
t.Parallel()
c := qt.New(t)
s := NewStack[int]()
c.Assert(s.Len(), qt.Equals, 0)
s.Push(1)
s.Push(2)
s.Push(3)
c.Assert(s.Len(), qt.Equals, 3)
top, ok := s.Peek()
c.Assert(ok, qt.Equals, true)
c.Assert(top, qt.Equals, 3)
popped, ok := s.Pop()
c.Assert(ok, qt.Equals, true)
c.Assert(popped, qt.Equals, 3)
c.Assert(s.Len(), qt.Equals, 2)
_, _ = s.Pop()
_, _ = s.Pop()
_, ok = s.Pop()
c.Assert(ok, qt.Equals, false)
}
func TestStackDrain(t *testing.T) {
t.Parallel()
c := qt.New(t)
s := NewStack[string]()
s.Push("a")
s.Push("b")
got := s.Drain()
c.Assert(got, qt.DeepEquals, []string{"a", "b"})
c.Assert(s.Len(), qt.Equals, 0)
}
func TestStackDrainMatching(t *testing.T) {
t.Parallel()
c := qt.New(t)
s := NewStack[int]()
s.Push(1)
s.Push(2)
s.Push(3)
s.Push(4)
got := s.DrainMatching(func(v int) bool { return v%2 == 0 })
c.Assert(got, qt.DeepEquals, []int{4, 2})
c.Assert(s.Drain(), qt.DeepEquals, []int{1, 3})
}

View file

@ -24,6 +24,7 @@ const (
WarnRenderShortcodesInHTML = "warning-rendershortcodes-in-html" WarnRenderShortcodesInHTML = "warning-rendershortcodes-in-html"
WarnGoldmarkRawHTML = "warning-goldmark-raw-html" WarnGoldmarkRawHTML = "warning-goldmark-raw-html"
WarnPartialSuperfluousPrefix = "warning-partial-superfluous-prefix" WarnPartialSuperfluousPrefix = "warning-partial-superfluous-prefix"
WarnHomePageIsLeafBundle = "warning-home-page-is-leaf-bundle"
) )
// Field/method names with special meaning. // Field/method names with special meaning.

View file

@ -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: 147, Minor: 148,
PatchLevel: 4, PatchLevel: 0,
Suffix: "", Suffix: "-DEV",
} }

View file

@ -120,15 +120,20 @@ func (pp *PathParser) parse(component, s string) (*Path, error) {
return p, nil return p, nil
} }
func (pp *PathParser) parseIdentifier(component, s string, p *Path, i, lastDot int) { func (pp *PathParser) parseIdentifier(component, s string, p *Path, i, lastDot, numDots int, isLast bool) {
if p.posContainerHigh != -1 { if p.posContainerHigh != -1 {
return return
} }
mayHaveLang := p.posIdentifierLanguage == -1 && pp.LanguageIndex != nil mayHaveLang := numDots > 1 && p.posIdentifierLanguage == -1 && pp.LanguageIndex != nil
mayHaveLang = mayHaveLang && (component == files.ComponentFolderContent || component == files.ComponentFolderLayouts) mayHaveLang = mayHaveLang && (component == files.ComponentFolderContent || component == files.ComponentFolderLayouts)
mayHaveOutputFormat := component == files.ComponentFolderLayouts mayHaveOutputFormat := component == files.ComponentFolderLayouts
mayHaveKind := p.posIdentifierKind == -1 && mayHaveOutputFormat mayHaveKind := p.posIdentifierKind == -1 && mayHaveOutputFormat
mayHaveLayout := component == files.ComponentFolderLayouts var mayHaveLayout bool
if p.pathType == TypeShortcode {
mayHaveLayout = !isLast && component == files.ComponentFolderLayouts
} else {
mayHaveLayout = component == files.ComponentFolderLayouts
}
var found bool var found bool
var high int var high int
@ -167,7 +172,6 @@ func (pp *PathParser) parseIdentifier(component, s string, p *Path, i, lastDot i
if langFound { if langFound {
p.identifiersKnown = append(p.identifiersKnown, id) p.identifiersKnown = append(p.identifiersKnown, id)
p.posIdentifierLanguage = len(p.identifiersKnown) - 1 p.posIdentifierLanguage = len(p.identifiersKnown) - 1
} }
} }
@ -234,19 +238,24 @@ func (pp *PathParser) doParse(component, s string, p *Path) (*Path, error) {
p.s = s p.s = s
slashCount := 0 slashCount := 0
lastDot := 0 lastDot := 0
lastSlashIdx := strings.LastIndex(s, "/")
numDots := strings.Count(s[lastSlashIdx+1:], ".")
if strings.Contains(s, "/_shortcodes/") {
p.pathType = TypeShortcode
}
for i := len(s) - 1; i >= 0; i-- { for i := len(s) - 1; i >= 0; i-- {
c := s[i] c := s[i]
switch c { switch c {
case '.': case '.':
pp.parseIdentifier(component, s, p, i, lastDot) pp.parseIdentifier(component, s, p, i, lastDot, numDots, false)
lastDot = i lastDot = i
case '/': case '/':
slashCount++ slashCount++
if p.posContainerHigh == -1 { if p.posContainerHigh == -1 {
if lastDot > 0 { if lastDot > 0 {
pp.parseIdentifier(component, s, p, i, lastDot) pp.parseIdentifier(component, s, p, i, lastDot, numDots, true)
} }
p.posContainerHigh = i + 1 p.posContainerHigh = i + 1
} else if p.posContainerLow == -1 { } else if p.posContainerLow == -1 {
@ -282,10 +291,9 @@ func (pp *PathParser) doParse(component, s string, p *Path) (*Path, error) {
p.pathType = TypeContentData p.pathType = TypeContentData
} }
} }
} }
if component == files.ComponentFolderLayouts { if p.pathType < TypeMarkup && component == files.ComponentFolderLayouts {
if p.posIdentifierBaseof != -1 { if p.posIdentifierBaseof != -1 {
p.pathType = TypeBaseof p.pathType = TypeBaseof
} else { } else {
@ -301,12 +309,10 @@ func (pp *PathParser) doParse(component, s string, p *Path) (*Path, error) {
} }
if p.pathType == TypeShortcode && p.posIdentifierLayout != -1 { if p.pathType == TypeShortcode && p.posIdentifierLayout != -1 {
// myshortcode or myshortcode.html, no layout. id := p.identifiersKnown[p.posIdentifierLayout]
if len(p.identifiersKnown) <= 2 { if id.Low == p.posContainerHigh {
// First identifier is shortcode name.
p.posIdentifierLayout = -1 p.posIdentifierLayout = -1
} else {
// First is always the name.
p.posIdentifierLayout--
} }
} }

View file

@ -434,12 +434,12 @@ func TestParseLayouts(t *testing.T) {
}, },
{ {
"Layout multiple", "Layout multiple",
"/maylayout.list.section.no.html", "/mylayout.list.section.no.html",
func(c *qt.C, p *Path) { func(c *qt.C, p *Path) {
c.Assert(p.Layout(), qt.Equals, "maylayout") c.Assert(p.Layout(), qt.Equals, "mylayout")
c.Assert(p.Identifiers(), qt.DeepEquals, []string{"html", "no", "section", "list", "maylayout"}) c.Assert(p.Identifiers(), qt.DeepEquals, []string{"html", "no", "section", "list", "mylayout"})
c.Assert(p.IdentifiersUnknown(), qt.DeepEquals, []string{}) c.Assert(p.IdentifiersUnknown(), qt.DeepEquals, []string{})
c.Assert(p.Base(), qt.Equals, "/maylayout.html") c.Assert(p.Base(), qt.Equals, "/mylayout.html")
c.Assert(p.Lang(), qt.Equals, "no") c.Assert(p.Lang(), qt.Equals, "no")
}, },
}, },
@ -487,7 +487,8 @@ func TestParseLayouts(t *testing.T) {
func(c *qt.C, p *Path) { func(c *qt.C, p *Path) {
c.Assert(p.Base(), qt.Equals, "/_shortcodes/myshortcode.html") c.Assert(p.Base(), qt.Equals, "/_shortcodes/myshortcode.html")
c.Assert(p.Type(), qt.Equals, TypeShortcode) c.Assert(p.Type(), qt.Equals, TypeShortcode)
c.Assert(p.Identifiers(), qt.DeepEquals, []string{"html", "list", "myshortcode"}) c.Assert(p.Identifiers(), qt.DeepEquals, []string{"html", "list"})
c.Assert(p.Layout(), qt.Equals, "list")
c.Assert(p.PathNoIdentifier(), qt.Equals, "/_shortcodes/myshortcode") c.Assert(p.PathNoIdentifier(), qt.Equals, "/_shortcodes/myshortcode")
c.Assert(p.PathBeforeLangAndOutputFormatAndExt(), qt.Equals, "/_shortcodes/myshortcode.list") c.Assert(p.PathBeforeLangAndOutputFormatAndExt(), qt.Equals, "/_shortcodes/myshortcode.list")
c.Assert(p.Lang(), qt.Equals, "") c.Assert(p.Lang(), qt.Equals, "")
@ -563,11 +564,30 @@ func TestParseLayouts(t *testing.T) {
c.Assert(p.Type(), qt.Equals, TypePartial) c.Assert(p.Type(), qt.Equals, TypePartial)
}, },
}, },
{
"Shortcode lang in root",
"/_shortcodes/no.html",
func(c *qt.C, p *Path) {
c.Assert(p.Type(), qt.Equals, TypeShortcode)
c.Assert(p.Lang(), qt.Equals, "")
c.Assert(p.NameNoIdentifier(), qt.Equals, "no")
},
},
{
"Shortcode lang layout",
"/_shortcodes/myshortcode.no.html",
func(c *qt.C, p *Path) {
c.Assert(p.Type(), qt.Equals, TypeShortcode)
c.Assert(p.Lang(), qt.Equals, "no")
c.Assert(p.Layout(), qt.Equals, "")
c.Assert(p.NameNoIdentifier(), qt.Equals, "myshortcode")
},
},
} }
for _, test := range tests { for _, test := range tests {
c.Run(test.name, func(c *qt.C) { c.Run(test.name, func(c *qt.C) {
if test.name != "Baseof" { if test.name != "Shortcode lang layout" {
// return // return
} }
test.assert(c, testParser.Parse(files.ComponentFolderLayouts, test.path)) test.assert(c, testParser.Parse(files.ComponentFolderLayouts, test.path))

View file

@ -17,7 +17,6 @@ package terminal
import ( import (
"fmt" "fmt"
"os" "os"
"runtime"
"strings" "strings"
isatty "github.com/mattn/go-isatty" isatty "github.com/mattn/go-isatty"
@ -41,10 +40,6 @@ func PrintANSIColors(f *os.File) bool {
// IsTerminal return true if the file descriptor is terminal and the TERM // IsTerminal return true if the file descriptor is terminal and the TERM
// environment variable isn't a dumb one. // environment variable isn't a dumb one.
func IsTerminal(f *os.File) bool { func IsTerminal(f *os.File) bool {
if runtime.GOOS == "windows" {
return false
}
fd := f.Fd() fd := f.Fd()
return os.Getenv("TERM") != "dumb" && (isatty.IsTerminal(fd) || isatty.IsCygwinTerminal(fd)) return os.Getenv("TERM") != "dumb" && (isatty.IsTerminal(fd) || isatty.IsCygwinTerminal(fd))
} }

View file

@ -146,7 +146,7 @@ type Config struct {
// The cascade configuration section contains the top level front matter cascade configuration options, // The cascade configuration section contains the top level front matter cascade configuration options,
// a slice of page matcher and params to apply to those pages. // a slice of page matcher and params to apply to those pages.
Cascade *config.ConfigNamespace[[]page.PageMatcherParamsConfig, *maps.Ordered[page.PageMatcher, maps.Params]] `mapstructure:"-"` Cascade *config.ConfigNamespace[[]page.PageMatcherParamsConfig, *maps.Ordered[page.PageMatcher, page.PageMatcherParamsConfig]] `mapstructure:"-"`
// The segments defines segments for the site. Used for partial/segmented builds. // The segments defines segments for the site. Used for partial/segmented builds.
Segments *config.ConfigNamespace[map[string]segments.SegmentConfig, segments.Segments] `mapstructure:"-"` Segments *config.ConfigNamespace[map[string]segments.SegmentConfig, segments.Segments] `mapstructure:"-"`
@ -776,7 +776,7 @@ type Configs struct {
} }
func (c *Configs) Validate(logger loggers.Logger) error { func (c *Configs) Validate(logger loggers.Logger) error {
c.Base.Cascade.Config.Range(func(p page.PageMatcher, params maps.Params) bool { c.Base.Cascade.Config.Range(func(p page.PageMatcher, cfg page.PageMatcherParamsConfig) bool {
page.CheckCascadePattern(logger, p) page.CheckCascadePattern(logger, p)
return true return true
}) })

View file

@ -36,6 +36,7 @@ import (
"github.com/dustin/go-humanize" "github.com/dustin/go-humanize"
"github.com/gobwas/glob" "github.com/gobwas/glob"
"github.com/gohugoio/hugo/common/loggers" "github.com/gohugoio/hugo/common/loggers"
"github.com/gohugoio/hugo/common/para"
"github.com/gohugoio/hugo/config" "github.com/gohugoio/hugo/config"
"github.com/gohugoio/hugo/deploy/deployconfig" "github.com/gohugoio/hugo/deploy/deployconfig"
"github.com/gohugoio/hugo/media" "github.com/gohugoio/hugo/media"
@ -487,7 +488,12 @@ func knownHiddenDirectory(name string) bool {
// walkLocal walks the source directory and returns a flat list of files, // walkLocal walks the source directory and returns a flat list of files,
// using localFile.SlashPath as the map keys. // using localFile.SlashPath as the map keys.
func (d *Deployer) walkLocal(fs afero.Fs, matchers []*deployconfig.Matcher, include, exclude glob.Glob, mediaTypes media.Types, mappath func(string) string) (map[string]*localFile, error) { func (d *Deployer) walkLocal(fs afero.Fs, matchers []*deployconfig.Matcher, include, exclude glob.Glob, mediaTypes media.Types, mappath func(string) string) (map[string]*localFile, error) {
retval := map[string]*localFile{} retval := make(map[string]*localFile)
var mu sync.Mutex
workers := para.New(d.cfg.Workers)
g, _ := workers.Start(context.Background())
err := afero.Walk(fs, "", func(path string, info os.FileInfo, err error) error { err := afero.Walk(fs, "", func(path string, info os.FileInfo, err error) error {
if err != nil { if err != nil {
return err return err
@ -508,6 +514,8 @@ func (d *Deployer) walkLocal(fs afero.Fs, matchers []*deployconfig.Matcher, incl
return nil return nil
} }
// Process each file in a worker
g.Run(func() error {
// When a file system is HFS+, its filepath is in NFD form. // When a file system is HFS+, its filepath is in NFD form.
if runtime.GOOS == "darwin" { if runtime.GOOS == "darwin" {
path = norm.NFC.String(path) path = norm.NFC.String(path)
@ -541,12 +549,19 @@ func (d *Deployer) walkLocal(fs afero.Fs, matchers []*deployconfig.Matcher, incl
if err != nil { if err != nil {
return err return err
} }
mu.Lock()
retval[lf.SlashPath] = lf retval[lf.SlashPath] = lf
mu.Unlock()
return nil
})
return nil return nil
}) })
if err != nil { if err != nil {
return nil, err return nil, err
} }
if err := g.Wait(); err != nil {
return nil, err
}
return retval, nil return retval, nil
} }

View file

@ -623,7 +623,7 @@ func TestEndToEndSync(t *testing.T) {
localFs: test.fs, localFs: test.fs,
bucket: test.bucket, bucket: test.bucket,
mediaTypes: media.DefaultTypes, mediaTypes: media.DefaultTypes,
cfg: deployconfig.DeployConfig{MaxDeletes: -1}, cfg: deployconfig.DeployConfig{Workers: 2, MaxDeletes: -1},
} }
// Initial deployment should sync remote with local. // Initial deployment should sync remote with local.
@ -706,7 +706,7 @@ func TestMaxDeletes(t *testing.T) {
localFs: test.fs, localFs: test.fs,
bucket: test.bucket, bucket: test.bucket,
mediaTypes: media.DefaultTypes, mediaTypes: media.DefaultTypes,
cfg: deployconfig.DeployConfig{MaxDeletes: -1}, cfg: deployconfig.DeployConfig{Workers: 2, MaxDeletes: -1},
} }
// Sync remote with local. // Sync remote with local.
@ -836,7 +836,7 @@ func TestIncludeExclude(t *testing.T) {
} }
deployer := &Deployer{ deployer := &Deployer{
localFs: fsTest.fs, localFs: fsTest.fs,
cfg: deployconfig.DeployConfig{MaxDeletes: -1}, bucket: fsTest.bucket, cfg: deployconfig.DeployConfig{Workers: 2, MaxDeletes: -1}, bucket: fsTest.bucket,
target: tgt, target: tgt,
mediaTypes: media.DefaultTypes, mediaTypes: media.DefaultTypes,
} }
@ -893,7 +893,7 @@ func TestIncludeExcludeRemoteDelete(t *testing.T) {
} }
deployer := &Deployer{ deployer := &Deployer{
localFs: fsTest.fs, localFs: fsTest.fs,
cfg: deployconfig.DeployConfig{MaxDeletes: -1}, bucket: fsTest.bucket, cfg: deployconfig.DeployConfig{Workers: 2, MaxDeletes: -1}, bucket: fsTest.bucket,
mediaTypes: media.DefaultTypes, mediaTypes: media.DefaultTypes,
} }
@ -945,7 +945,7 @@ func TestCompression(t *testing.T) {
deployer := &Deployer{ deployer := &Deployer{
localFs: test.fs, localFs: test.fs,
bucket: test.bucket, bucket: test.bucket,
cfg: deployconfig.DeployConfig{MaxDeletes: -1, Matchers: []*deployconfig.Matcher{{Pattern: ".*", Gzip: true, Re: regexp.MustCompile(".*")}}}, cfg: deployconfig.DeployConfig{Workers: 2, MaxDeletes: -1, Matchers: []*deployconfig.Matcher{{Pattern: ".*", Gzip: true, Re: regexp.MustCompile(".*")}}},
mediaTypes: media.DefaultTypes, mediaTypes: media.DefaultTypes,
} }
@ -1000,7 +1000,7 @@ func TestMatching(t *testing.T) {
deployer := &Deployer{ deployer := &Deployer{
localFs: test.fs, localFs: test.fs,
bucket: test.bucket, bucket: test.bucket,
cfg: deployconfig.DeployConfig{MaxDeletes: -1, Matchers: []*deployconfig.Matcher{{Pattern: "^subdir/aaa$", Force: true, Re: regexp.MustCompile("^subdir/aaa$")}}}, cfg: deployconfig.DeployConfig{Workers: 2, MaxDeletes: -1, Matchers: []*deployconfig.Matcher{{Pattern: "^subdir/aaa$", Force: true, Re: regexp.MustCompile("^subdir/aaa$")}}},
mediaTypes: media.DefaultTypes, mediaTypes: media.DefaultTypes,
} }
@ -1097,5 +1097,6 @@ func verifyRemote(ctx context.Context, bucket *blob.Bucket, local []*fileData) (
func newDeployer() *Deployer { func newDeployer() *Deployer {
return &Deployer{ return &Deployer{
logger: loggers.NewDefault(), logger: loggers.NewDefault(),
cfg: deployconfig.DeployConfig{Workers: 2},
} }
} }

96
go.mod
View file

@ -2,9 +2,9 @@ module github.com/gohugoio/hugo
require ( require (
github.com/BurntSushi/locker v0.0.0-20171006230638-a6e239ea1c69 github.com/BurntSushi/locker v0.0.0-20171006230638-a6e239ea1c69
github.com/alecthomas/chroma/v2 v2.17.2 github.com/alecthomas/chroma/v2 v2.18.0
github.com/armon/go-radix v1.0.1-0.20221118154546-54df44f2176c github.com/armon/go-radix v1.0.1-0.20221118154546-54df44f2176c
github.com/aws/aws-sdk-go-v2 v1.36.1 github.com/aws/aws-sdk-go-v2 v1.36.4
github.com/aws/aws-sdk-go-v2/service/cloudfront v1.44.10 github.com/aws/aws-sdk-go-v2/service/cloudfront v1.44.10
github.com/bep/clocks v0.5.0 github.com/bep/clocks v0.5.0
github.com/bep/debounce v1.2.0 github.com/bep/debounce v1.2.0
@ -26,7 +26,7 @@ require (
github.com/clbanning/mxj/v2 v2.7.0 github.com/clbanning/mxj/v2 v2.7.0
github.com/disintegration/gift v1.2.1 github.com/disintegration/gift v1.2.1
github.com/dustin/go-humanize v1.0.1 github.com/dustin/go-humanize v1.0.1
github.com/evanw/esbuild v0.25.3 github.com/evanw/esbuild v0.25.5
github.com/fatih/color v1.18.0 github.com/fatih/color v1.18.0
github.com/fortytw2/leaktest v1.3.0 github.com/fortytw2/leaktest v1.3.0
github.com/frankban/quicktest v1.14.6 github.com/frankban/quicktest v1.14.6
@ -54,44 +54,46 @@ require (
github.com/mattn/go-isatty v0.0.20 github.com/mattn/go-isatty v0.0.20
github.com/mitchellh/mapstructure v1.5.1-0.20231216201459-8508981c8b6c github.com/mitchellh/mapstructure v1.5.1-0.20231216201459-8508981c8b6c
github.com/muesli/smartcrop v0.3.0 github.com/muesli/smartcrop v0.3.0
github.com/niklasfasching/go-org v1.7.0 github.com/niklasfasching/go-org v1.8.0
github.com/olekukonko/tablewriter v0.0.5 github.com/olekukonko/tablewriter v1.0.7
github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58 github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58
github.com/pelletier/go-toml/v2 v2.2.4 github.com/pelletier/go-toml/v2 v2.2.4
github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c
github.com/rogpeppe/go-internal v1.14.1 github.com/rogpeppe/go-internal v1.14.1
github.com/sanity-io/litter v1.5.8 github.com/sanity-io/litter v1.5.8
github.com/spf13/afero v1.14.0 github.com/spf13/afero v1.14.0
github.com/spf13/cast v1.7.1 github.com/spf13/cast v1.9.2
github.com/spf13/cobra v1.9.1 github.com/spf13/cobra v1.9.1
github.com/spf13/fsync v0.10.1 github.com/spf13/fsync v0.10.1
github.com/spf13/pflag v1.0.6 github.com/spf13/pflag v1.0.6
github.com/tdewolff/minify/v2 v2.20.37 github.com/tdewolff/minify/v2 v2.23.8
github.com/tdewolff/parse/v2 v2.7.15 github.com/tdewolff/parse/v2 v2.8.1
github.com/tetratelabs/wazero v1.9.0 github.com/tetratelabs/wazero v1.9.0
github.com/yuin/goldmark v1.7.11 github.com/yuin/goldmark v1.7.12
github.com/yuin/goldmark-emoji v1.0.6 github.com/yuin/goldmark-emoji v1.0.6
go.uber.org/automaxprocs v1.5.3 go.uber.org/automaxprocs v1.5.3
gocloud.dev v0.40.0 gocloud.dev v0.40.0
golang.org/x/exp v0.0.0-20221031165847-c99f073a8326 golang.org/x/exp v0.0.0-20221031165847-c99f073a8326
golang.org/x/image v0.26.0 golang.org/x/image v0.28.0
golang.org/x/mod v0.24.0 golang.org/x/mod v0.25.0
golang.org/x/net v0.39.0 golang.org/x/net v0.41.0
golang.org/x/sync v0.13.0 golang.org/x/sync v0.15.0
golang.org/x/text v0.24.0 golang.org/x/text v0.26.0
golang.org/x/tools v0.32.0 golang.org/x/tools v0.33.0
google.golang.org/api v0.221.0 google.golang.org/api v0.237.0
gopkg.in/yaml.v2 v2.4.0 gopkg.in/yaml.v2 v2.4.0
rsc.io/qr v0.2.0 rsc.io/qr v0.2.0
) )
require ( require (
cloud.google.com/go v0.116.0 // indirect cel.dev/expr v0.23.0 // indirect
cloud.google.com/go/auth v0.14.1 // indirect cloud.google.com/go v0.120.0 // indirect
cloud.google.com/go/auth/oauth2adapt v0.2.7 // indirect cloud.google.com/go/auth v0.16.2 // indirect
cloud.google.com/go/compute/metadata v0.6.0 // indirect cloud.google.com/go/auth/oauth2adapt v0.2.8 // indirect
cloud.google.com/go/iam v1.2.2 // indirect cloud.google.com/go/compute/metadata v0.7.0 // indirect
cloud.google.com/go/storage v1.43.0 // indirect cloud.google.com/go/iam v1.5.2 // indirect
cloud.google.com/go/monitoring v1.24.2 // indirect
cloud.google.com/go/storage v1.50.0 // indirect
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.14.0 // indirect github.com/Azure/azure-sdk-for-go/sdk/azcore v1.14.0 // indirect
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.7.0 // indirect github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.7.0 // indirect
github.com/Azure/azure-sdk-for-go/sdk/internal v1.10.0 // indirect github.com/Azure/azure-sdk-for-go/sdk/internal v1.10.0 // indirect
@ -99,6 +101,9 @@ require (
github.com/Azure/go-autorest v14.2.0+incompatible // indirect github.com/Azure/go-autorest v14.2.0+incompatible // indirect
github.com/Azure/go-autorest/autorest/to v0.4.0 // indirect github.com/Azure/go-autorest/autorest/to v0.4.0 // indirect
github.com/AzureAD/microsoft-authentication-library-for-go v1.2.2 // indirect github.com/AzureAD/microsoft-authentication-library-for-go v1.2.2 // indirect
github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.27.0 // indirect
github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric v0.50.0 // indirect
github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.50.0 // indirect
github.com/aws/aws-sdk-go v1.55.5 // indirect github.com/aws/aws-sdk-go v1.55.5 // indirect
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.3 // indirect github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.3 // indirect
github.com/aws/aws-sdk-go-v2/config v1.27.27 // indirect github.com/aws/aws-sdk-go-v2/config v1.27.27 // indirect
@ -118,9 +123,13 @@ require (
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.26.4 // indirect github.com/aws/aws-sdk-go-v2/service/ssooidc v1.26.4 // indirect
github.com/aws/aws-sdk-go-v2/service/sts v1.30.3 // indirect github.com/aws/aws-sdk-go-v2/service/sts v1.30.3 // indirect
github.com/aws/smithy-go v1.22.2 // indirect github.com/aws/smithy-go v1.22.2 // indirect
github.com/cncf/xds/go v0.0.0-20250326154945-ae57f3c0d45f // indirect
github.com/cpuguy83/go-md2man/v2 v2.0.6 // indirect github.com/cpuguy83/go-md2man/v2 v2.0.6 // indirect
github.com/dlclark/regexp2 v1.11.5 // indirect github.com/dlclark/regexp2 v1.11.5 // indirect
github.com/envoyproxy/go-control-plane/envoy v1.32.4 // indirect
github.com/envoyproxy/protoc-gen-validate v1.2.1 // indirect
github.com/felixge/httpsnoop v1.0.4 // indirect github.com/felixge/httpsnoop v1.0.4 // indirect
github.com/go-jose/go-jose/v4 v4.0.5 // indirect
github.com/go-logr/logr v1.4.2 // indirect github.com/go-logr/logr v1.4.2 // indirect
github.com/go-logr/stdr v1.2.2 // indirect github.com/go-logr/stdr v1.2.2 // indirect
github.com/go-openapi/jsonpointer v0.21.0 // indirect github.com/go-openapi/jsonpointer v0.21.0 // indirect
@ -130,8 +139,8 @@ require (
github.com/google/s2a-go v0.1.9 // indirect github.com/google/s2a-go v0.1.9 // indirect
github.com/google/uuid v1.6.0 // indirect github.com/google/uuid v1.6.0 // indirect
github.com/google/wire v0.6.0 // indirect github.com/google/wire v0.6.0 // indirect
github.com/googleapis/enterprise-certificate-proxy v0.3.4 // indirect github.com/googleapis/enterprise-certificate-proxy v0.3.6 // indirect
github.com/googleapis/gax-go/v2 v2.14.1 // indirect github.com/googleapis/gax-go/v2 v2.14.2 // indirect
github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect
github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/jmespath/go-jmespath v0.4.0 // indirect github.com/jmespath/go-jmespath v0.4.0 // indirect
@ -141,31 +150,40 @@ require (
github.com/kylelemons/godebug v1.1.0 // indirect github.com/kylelemons/godebug v1.1.0 // indirect
github.com/mailru/easyjson v0.7.7 // indirect github.com/mailru/easyjson v0.7.7 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-runewidth v0.0.9 // indirect github.com/mattn/go-runewidth v0.0.16 // indirect
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 // indirect github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 // indirect
github.com/oasdiff/yaml v0.0.0-20250309154309-f31be36b4037 // indirect github.com/oasdiff/yaml v0.0.0-20250309154309-f31be36b4037 // indirect
github.com/oasdiff/yaml3 v0.0.0-20250309153720-d2182401db90 // indirect github.com/oasdiff/yaml3 v0.0.0-20250309153720-d2182401db90 // indirect
github.com/olekukonko/errors v0.0.0-20250405072817-4e6d85265da6 // indirect
github.com/olekukonko/ll v0.0.8 // indirect
github.com/perimeterx/marshmallow v1.1.5 // indirect github.com/perimeterx/marshmallow v1.1.5 // indirect
github.com/pkg/errors v0.9.1 // indirect github.com/pkg/errors v0.9.1 // indirect
github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 // indirect
github.com/rivo/uniseg v0.2.0 // indirect
github.com/russross/blackfriday/v2 v2.1.0 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect
github.com/spiffe/go-spiffe/v2 v2.5.0 // indirect
github.com/zeebo/errs v1.4.0 // indirect
go.opencensus.io v0.24.0 // indirect go.opencensus.io v0.24.0 // indirect
go.opentelemetry.io/auto/sdk v1.1.0 // indirect go.opentelemetry.io/auto/sdk v1.1.0 // indirect
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.58.0 // indirect go.opentelemetry.io/contrib/detectors/gcp v1.35.0 // indirect
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.58.0 // indirect go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.61.0 // indirect
go.opentelemetry.io/otel v1.34.0 // indirect go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0 // indirect
go.opentelemetry.io/otel/metric v1.34.0 // indirect go.opentelemetry.io/otel v1.36.0 // indirect
go.opentelemetry.io/otel/trace v1.34.0 // indirect go.opentelemetry.io/otel/metric v1.36.0 // indirect
golang.org/x/crypto v0.37.0 // indirect go.opentelemetry.io/otel/sdk v1.36.0 // indirect
golang.org/x/oauth2 v0.26.0 // indirect go.opentelemetry.io/otel/sdk/metric v1.36.0 // indirect
golang.org/x/sys v0.32.0 // indirect go.opentelemetry.io/otel/trace v1.36.0 // indirect
golang.org/x/time v0.10.0 // indirect golang.org/x/crypto v0.39.0 // indirect
golang.org/x/oauth2 v0.30.0 // indirect
golang.org/x/sys v0.33.0 // indirect
golang.org/x/time v0.12.0 // indirect
golang.org/x/xerrors v0.0.0-20240716161551-93cc26a95ae9 // indirect golang.org/x/xerrors v0.0.0-20240716161551-93cc26a95ae9 // indirect
google.golang.org/genproto v0.0.0-20241104194629-dd2ea8efbc28 // indirect google.golang.org/genproto v0.0.0-20250505200425-f936aa4a68b2 // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20241209162323-e6fa225c2576 // indirect google.golang.org/genproto/googleapis/api v0.0.0-20250505200425-f936aa4a68b2 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20250207221924-e9438ea467c6 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20250603155806-513f23925822 // indirect
google.golang.org/grpc v1.70.0 // indirect google.golang.org/grpc v1.73.0 // indirect
google.golang.org/protobuf v1.36.5 // indirect google.golang.org/protobuf v1.36.6 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect
howett.net/plist v1.0.0 // indirect howett.net/plist v1.0.0 // indirect
software.sslmate.com/src/go-pkcs12 v0.2.0 // indirect software.sslmate.com/src/go-pkcs12 v0.2.0 // indirect

217
go.sum
View file

@ -1,3 +1,5 @@
cel.dev/expr v0.23.0 h1:wUb94w6OYQS4uXraxo9U+wUAs9jT47Xvl4iPgAwM2ss=
cel.dev/expr v0.23.0/go.mod h1:hLPLo1W4QUmuYdA72RBX06QTs6MXw941piREPl3Yfiw=
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU=
@ -17,26 +19,30 @@ cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHOb
cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI= cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI=
cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk= cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk=
cloud.google.com/go v0.75.0/go.mod h1:VGuuCn7PG0dwsd5XPVm2Mm3wlh3EL55/79EKB6hlPTY= cloud.google.com/go v0.75.0/go.mod h1:VGuuCn7PG0dwsd5XPVm2Mm3wlh3EL55/79EKB6hlPTY=
cloud.google.com/go v0.116.0 h1:B3fRrSDkLRt5qSHWe40ERJvhvnQwdZiHu0bJOpldweE= cloud.google.com/go v0.120.0 h1:wc6bgG9DHyKqF5/vQvX1CiZrtHnxJjBlKUyF9nP6meA=
cloud.google.com/go v0.116.0/go.mod h1:cEPSRWPzZEswwdr9BxE6ChEn01dWlTaF05LiC2Xs70U= cloud.google.com/go v0.120.0/go.mod h1:/beW32s8/pGRuj4IILWQNd4uuebeT4dkOhKmkfit64Q=
cloud.google.com/go/auth v0.14.1 h1:AwoJbzUdxA/whv1qj3TLKwh3XX5sikny2fc40wUl+h0= cloud.google.com/go/auth v0.16.2 h1:QvBAGFPLrDeoiNjyfVunhQ10HKNYuOwZ5noee0M5df4=
cloud.google.com/go/auth v0.14.1/go.mod h1:4JHUxlGXisL0AW8kXPtUF6ztuOksyfUQNFjfsOCXkPM= cloud.google.com/go/auth v0.16.2/go.mod h1:sRBas2Y1fB1vZTdurouM0AzuYQBMZinrUYL8EufhtEA=
cloud.google.com/go/auth/oauth2adapt v0.2.7 h1:/Lc7xODdqcEw8IrZ9SvwnlLX6j9FHQM74z6cBk9Rw6M= cloud.google.com/go/auth/oauth2adapt v0.2.8 h1:keo8NaayQZ6wimpNSmW5OPc283g65QNIiLpZnkHRbnc=
cloud.google.com/go/auth/oauth2adapt v0.2.7/go.mod h1:NTbTTzfvPl1Y3V1nPpOgl2w6d/FjO7NNUQaWSox6ZMc= cloud.google.com/go/auth/oauth2adapt v0.2.8/go.mod h1:XQ9y31RkqZCcwJWNSx2Xvric3RrU88hAYYbjDWYDL+c=
cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o=
cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE=
cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc=
cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg=
cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc=
cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ=
cloud.google.com/go/compute/metadata v0.6.0 h1:A6hENjEsCDtC1k8byVsgwvVcioamEHvZ4j01OwKxG9I= cloud.google.com/go/compute/metadata v0.7.0 h1:PBWF+iiAerVNe8UCHxdOt6eHLVc3ydFeOCw78U8ytSU=
cloud.google.com/go/compute/metadata v0.6.0/go.mod h1:FjyFAW1MW0C203CEOMDTu3Dk1FlqW3Rga40jzHL4hfg= cloud.google.com/go/compute/metadata v0.7.0/go.mod h1:j5MvL9PprKL39t166CoB1uVHfQMs4tFQZZcKwksXUjo=
cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE=
cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk=
cloud.google.com/go/iam v1.2.2 h1:ozUSofHUGf/F4tCNy/mu9tHLTaxZFLOUiKzjcgWHGIA= cloud.google.com/go/iam v1.5.2 h1:qgFRAGEmd8z6dJ/qyEchAuL9jpswyODjA2lS+w234g8=
cloud.google.com/go/iam v1.2.2/go.mod h1:0Ys8ccaZHdI1dEUilwzqng/6ps2YB6vRsjIe00/+6JY= cloud.google.com/go/iam v1.5.2/go.mod h1:SE1vg0N81zQqLzQEwxL2WI6yhetBdbNQuTvIKCSkUHE=
cloud.google.com/go/longrunning v0.6.2 h1:xjDfh1pQcWPEvnfjZmwjKQEcHnpz6lHjfy7Fo0MK+hc= cloud.google.com/go/logging v1.13.0 h1:7j0HgAp0B94o1YRDqiqm26w4q1rDMH7XNRU34lJXHYc=
cloud.google.com/go/longrunning v0.6.2/go.mod h1:k/vIs83RN4bE3YCswdXC5PFfWVILjm3hpEUlSko4PiI= cloud.google.com/go/logging v1.13.0/go.mod h1:36CoKh6KA/M0PbhPKMq6/qety2DCAErbhXT62TuXALA=
cloud.google.com/go/longrunning v0.6.7 h1:IGtfDWHhQCgCjwQjV9iiLnUta9LBCo8R9QmAFsS/PrE=
cloud.google.com/go/longrunning v0.6.7/go.mod h1:EAFV3IZAKmM56TyiE6VAP3VoTzhZzySwI/YI1s/nRsY=
cloud.google.com/go/monitoring v1.24.2 h1:5OTsoJ1dXYIiMiuL+sYscLc9BumrL3CarVLL7dd7lHM=
cloud.google.com/go/monitoring v1.24.2/go.mod h1:x7yzPWcgDRnPEv3sI+jJGBkwl5qINf+6qY4eq0I9B4U=
cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I=
cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw=
cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA=
@ -47,8 +53,10 @@ cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohl
cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs=
cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0=
cloud.google.com/go/storage v1.14.0/go.mod h1:GrKmX003DSIwi9o29oFT7YDnHYwZoctc3fOKtUw0Xmo= cloud.google.com/go/storage v1.14.0/go.mod h1:GrKmX003DSIwi9o29oFT7YDnHYwZoctc3fOKtUw0Xmo=
cloud.google.com/go/storage v1.43.0 h1:CcxnSohZwizt4LCzQHWvBf1/kvtHUn7gk9QERXPyXFs= cloud.google.com/go/storage v1.50.0 h1:3TbVkzTooBvnZsk7WaAQfOsNrdoM8QHusXA1cpk6QJs=
cloud.google.com/go/storage v1.43.0/go.mod h1:ajvxEa7WmZS1PxvKRq4bq0tFT3vMd502JwstCcYv0Q0= cloud.google.com/go/storage v1.50.0/go.mod h1:l7XeiD//vx5lfqE3RavfmU9yvk5Pp0Zhcv482poyafY=
cloud.google.com/go/trace v1.11.6 h1:2O2zjPzqPYAHrn3OKl029qlqG6W8ZdYaOWRyr8NgMT4=
cloud.google.com/go/trace v1.11.6/go.mod h1:GA855OeDEBiBMzcckLPE2kDunIpC72N+Pq8WFieFjnI=
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.14.0 h1:nyQWyZvwGTvunIMxi1Y9uXkcyr+I7TeNrr/foo4Kpk8= github.com/Azure/azure-sdk-for-go/sdk/azcore v1.14.0 h1:nyQWyZvwGTvunIMxi1Y9uXkcyr+I7TeNrr/foo4Kpk8=
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.14.0/go.mod h1:l38EPgmsp71HHLq9j7De57JcKOWPyhrsW1Awm1JS6K0= github.com/Azure/azure-sdk-for-go/sdk/azcore v1.14.0/go.mod h1:l38EPgmsp71HHLq9j7De57JcKOWPyhrsW1Awm1JS6K0=
@ -71,18 +79,26 @@ github.com/BurntSushi/locker v0.0.0-20171006230638-a6e239ea1c69/go.mod h1:L1AbZd
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.27.0 h1:ErKg/3iS1AKcTkf3yixlZ54f9U1rljCkQyEXWUnIUxc=
github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.27.0/go.mod h1:yAZHSGnqScoU556rBOVkwLze6WP5N+U11RHuWaGVxwY=
github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric v0.50.0 h1:5IT7xOdq17MtcdtL/vtl6mGfzhaq4m4vpollPRmlsBQ=
github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric v0.50.0/go.mod h1:ZV4VOm0/eHR06JLrXWe09068dHpr3TRpY9Uo7T+anuA=
github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/cloudmock v0.50.0 h1:nNMpRpnkWDAaqcpxMJvxa/Ud98gjbYwayJY4/9bdjiU=
github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/cloudmock v0.50.0/go.mod h1:SZiPHWGOOk3bl8tkevxkoiwPgsIl6CwrWcbwjfHZpdM=
github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.50.0 h1:ig/FpDD2JofP/NExKQUbn7uOSZzJAQqogfqluZK4ed4=
github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.50.0/go.mod h1:otE2jQekW/PqXk1Awf5lmfokJx4uwuqcj1ab5SpGeW0=
github.com/alecthomas/assert/v2 v2.11.0 h1:2Q9r3ki8+JYXvGsDyBXwH3LcJ+WK5D0gc5E8vS6K3D0= github.com/alecthomas/assert/v2 v2.11.0 h1:2Q9r3ki8+JYXvGsDyBXwH3LcJ+WK5D0gc5E8vS6K3D0=
github.com/alecthomas/assert/v2 v2.11.0/go.mod h1:Bze95FyfUr7x34QZrjL+XP+0qgp/zg8yS+TtBj1WA3k= github.com/alecthomas/assert/v2 v2.11.0/go.mod h1:Bze95FyfUr7x34QZrjL+XP+0qgp/zg8yS+TtBj1WA3k=
github.com/alecthomas/chroma/v2 v2.17.2 h1:Rm81SCZ2mPoH+Q8ZCc/9YvzPUN/E7HgPiPJD8SLV6GI= github.com/alecthomas/chroma/v2 v2.18.0 h1:6h53Q4hW83SuF+jcsp7CVhLsMozzvQvO8HBbKQW+gn4=
github.com/alecthomas/chroma/v2 v2.17.2/go.mod h1:RVX6AvYm4VfYe/zsk7mjHueLDZor3aWCNE14TFlepBk= github.com/alecthomas/chroma/v2 v2.18.0/go.mod h1:RVX6AvYm4VfYe/zsk7mjHueLDZor3aWCNE14TFlepBk=
github.com/alecthomas/repr v0.4.0 h1:GhI2A8MACjfegCPVq9f1FLvIBS+DrQ2KQBFZP1iFzXc= github.com/alecthomas/repr v0.4.0 h1:GhI2A8MACjfegCPVq9f1FLvIBS+DrQ2KQBFZP1iFzXc=
github.com/alecthomas/repr v0.4.0/go.mod h1:Fr0507jx4eOXV7AlPV6AVZLYrLIuIeSOWtW57eE/O/4= github.com/alecthomas/repr v0.4.0/go.mod h1:Fr0507jx4eOXV7AlPV6AVZLYrLIuIeSOWtW57eE/O/4=
github.com/armon/go-radix v1.0.1-0.20221118154546-54df44f2176c h1:651/eoCRnQ7YtSjAnSzRucrJz+3iGEFt+ysraELS81M= github.com/armon/go-radix v1.0.1-0.20221118154546-54df44f2176c h1:651/eoCRnQ7YtSjAnSzRucrJz+3iGEFt+ysraELS81M=
github.com/armon/go-radix v1.0.1-0.20221118154546-54df44f2176c/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= github.com/armon/go-radix v1.0.1-0.20221118154546-54df44f2176c/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
github.com/aws/aws-sdk-go v1.55.5 h1:KKUZBfBoyqy5d3swXyiC7Q76ic40rYcbqH7qjh59kzU= github.com/aws/aws-sdk-go v1.55.5 h1:KKUZBfBoyqy5d3swXyiC7Q76ic40rYcbqH7qjh59kzU=
github.com/aws/aws-sdk-go v1.55.5/go.mod h1:eRwEWoyTWFMVYVQzKMNHWP5/RV4xIUGMQfXQHfHkpNU= github.com/aws/aws-sdk-go v1.55.5/go.mod h1:eRwEWoyTWFMVYVQzKMNHWP5/RV4xIUGMQfXQHfHkpNU=
github.com/aws/aws-sdk-go-v2 v1.36.1 h1:iTDl5U6oAhkNPba0e1t1hrwAo02ZMqbrGq4k5JBWM5E= github.com/aws/aws-sdk-go-v2 v1.36.4 h1:GySzjhVvx0ERP6eyfAbAuAXLtAda5TEy19E5q5W8I9E=
github.com/aws/aws-sdk-go-v2 v1.36.1/go.mod h1:5PMILGVKiW32oDzjj6RU52yrNrDPUHcbZQYr1sM7qmM= github.com/aws/aws-sdk-go-v2 v1.36.4/go.mod h1:LLXuLpgzEbD766Z5ECcRmi8AzSwfZItDtmABVkRLGzg=
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.3 h1:tW1/Rkad38LA15X4UQtjXZXNKsCgkshC3EbmcUmghTg= github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.3 h1:tW1/Rkad38LA15X4UQtjXZXNKsCgkshC3EbmcUmghTg=
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.3/go.mod h1:UbnqO+zjqk3uIt9yCACHJ9IVNhyhOCnYk8yA19SAWrM= github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.3/go.mod h1:UbnqO+zjqk3uIt9yCACHJ9IVNhyhOCnYk8yA19SAWrM=
github.com/aws/aws-sdk-go-v2/config v1.27.27 h1:HdqgGt1OAP0HkEDDShEl0oSYa9ZZBSOmKpdpsDMdO90= github.com/aws/aws-sdk-go-v2/config v1.27.27 h1:HdqgGt1OAP0HkEDDShEl0oSYa9ZZBSOmKpdpsDMdO90=
@ -167,6 +183,8 @@ github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDk
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
github.com/cncf/xds/go v0.0.0-20250326154945-ae57f3c0d45f h1:C5bqEmzEPLsHm9Mv73lSE9e9bKV23aB1vxOsmZrkl3k=
github.com/cncf/xds/go v0.0.0-20250326154945-ae57f3c0d45f/go.mod h1:W+zGtBO5Y1IgJhy4+A9GOqVhqLpfZi+vwmdNXUehLA8=
github.com/cpuguy83/go-md2man/v2 v2.0.6 h1:XJtiaUW6dEEqVuZiMTn1ldk455QWwEIsMIJlo5vtkx0= github.com/cpuguy83/go-md2man/v2 v2.0.6 h1:XJtiaUW6dEEqVuZiMTn1ldk455QWwEIsMIJlo5vtkx0=
github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g= github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
@ -185,9 +203,17 @@ github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.m
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po= 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/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
github.com/envoyproxy/go-control-plane v0.13.4 h1:zEqyPVyku6IvWCFwux4x9RxkLOMUL+1vC9xUFv5l2/M=
github.com/envoyproxy/go-control-plane v0.13.4/go.mod h1:kDfuBlDVsSj2MjrLEtRWtHlsWIFcGyB2RMO44Dc5GZA=
github.com/envoyproxy/go-control-plane/envoy v1.32.4 h1:jb83lalDRZSpPWW2Z7Mck/8kXZ5CQAFYVjQcdVIr83A=
github.com/envoyproxy/go-control-plane/envoy v1.32.4/go.mod h1:Gzjc5k8JcJswLjAx1Zm+wSYE20UrLtt7JZMWiWQXQEw=
github.com/envoyproxy/go-control-plane/ratelimit v0.1.0 h1:/G9QYbddjL25KvtKTv3an9lx6VBE2cnb8wp1vEGNYGI=
github.com/envoyproxy/go-control-plane/ratelimit v0.1.0/go.mod h1:Wk+tMFAFbCXaJPzVVHnPgRKdUdwW/KdbRt94AzgRee4=
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
github.com/evanw/esbuild v0.25.3 h1:4JKyUsm/nHDhpxis4IyWXAi8GiyTwG1WdEp6OhGVE8U= github.com/envoyproxy/protoc-gen-validate v1.2.1 h1:DEo3O99U8j4hBFwbJfrz9VtgcDfUKS7KJ7spH3d86P8=
github.com/evanw/esbuild v0.25.3/go.mod h1:D2vIQZqV/vIf/VRHtViaUtViZmG7o+kKmlBfVQuRi48= github.com/envoyproxy/protoc-gen-validate v1.2.1/go.mod h1:d/C80l/jxXLdfEIhX1W2TmLfsJ31lvEjwamM4DxlWXU=
github.com/evanw/esbuild v0.25.5 h1:E+JpeY5S/1LFmnX1vtuZqUKT7qDVcfXdhzMhM3uIKFs=
github.com/evanw/esbuild v0.25.5/go.mod h1:D2vIQZqV/vIf/VRHtViaUtViZmG7o+kKmlBfVQuRi48=
github.com/fatih/color v1.18.0 h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM= github.com/fatih/color v1.18.0 h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM=
github.com/fatih/color v1.18.0/go.mod h1:4FelSpRwEGDpQ12mAdzqdOukCy4u8WUtOY6lkT/6HfU= github.com/fatih/color v1.18.0/go.mod h1:4FelSpRwEGDpQ12mAdzqdOukCy4u8WUtOY6lkT/6HfU=
github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg=
@ -208,6 +234,8 @@ github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeME
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
github.com/go-jose/go-jose/v4 v4.0.5 h1:M6T8+mKZl/+fNNuFHvGIzDz7BTLQPIounk/b9dw3AaE=
github.com/go-jose/go-jose/v4 v4.0.5/go.mod h1:s3P1lRrkT8igV8D9OjyL4WRyHvjB6a4JSllnOrmmBOA=
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY=
github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
@ -317,12 +345,12 @@ github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/wire v0.6.0 h1:HBkoIh4BdSxoyo9PveV8giw7ZsaBOvzWKfcg/6MrVwI= github.com/google/wire v0.6.0 h1:HBkoIh4BdSxoyo9PveV8giw7ZsaBOvzWKfcg/6MrVwI=
github.com/google/wire v0.6.0/go.mod h1:F4QhpQ9EDIdJ1Mbop/NZBRB+5yrR6qg3BnctaoUk6NA= github.com/google/wire v0.6.0/go.mod h1:F4QhpQ9EDIdJ1Mbop/NZBRB+5yrR6qg3BnctaoUk6NA=
github.com/googleapis/enterprise-certificate-proxy v0.3.4 h1:XYIDZApgAnrN1c855gTgghdIA6Stxb52D5RnLI1SLyw= github.com/googleapis/enterprise-certificate-proxy v0.3.6 h1:GW/XbdyBFQ8Qe+YAmFU9uHLo7OnF5tL52HFAgMmyrf4=
github.com/googleapis/enterprise-certificate-proxy v0.3.4/go.mod h1:YKe7cfqYXjKGpGvmSg28/fFvhNzinZQm8DGnaburhGA= github.com/googleapis/enterprise-certificate-proxy v0.3.6/go.mod h1:MkHOF77EYAE7qfSuSS9PU6g4Nt4e11cnsDUowfwewLA=
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
github.com/googleapis/gax-go/v2 v2.14.1 h1:hb0FFeiPaQskmvakKu5EbCbpntQn48jyHuvrkurSS/Q= github.com/googleapis/gax-go/v2 v2.14.2 h1:eBLnkZ9635krYIPD+ag1USrOAI0Nr0QYF3+/3GqO0k0=
github.com/googleapis/gax-go/v2 v2.14.1/go.mod h1:Hb/NubMaVM88SrNkvl8X/o8XWwDJEPqouaLeN2IUxoA= github.com/googleapis/gax-go/v2 v2.14.2/go.mod h1:ON64QhlJkhVtSqp4v1uaK92VyZ2gmvDQsweuyLV+8+w=
github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g= github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g=
github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg= github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg=
github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
@ -376,8 +404,8 @@ github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovk
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/mattn/go-runewidth v0.0.9 h1:Lm995f3rfxdpd6TSmuVCHVb/QhupuXlYr8sCI/QdE+0= github.com/mattn/go-runewidth v0.0.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6TULQc=
github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= github.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
github.com/mitchellh/mapstructure v1.5.1-0.20231216201459-8508981c8b6c h1:cqn374mizHuIWj+OSJCajGr/phAmuMug9qIX3l9CflE= github.com/mitchellh/mapstructure v1.5.1-0.20231216201459-8508981c8b6c h1:cqn374mizHuIWj+OSJCajGr/phAmuMug9qIX3l9CflE=
github.com/mitchellh/mapstructure v1.5.1-0.20231216201459-8508981c8b6c/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/mapstructure v1.5.1-0.20231216201459-8508981c8b6c/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 h1:RWengNIwukTxcDr9M+97sNutRR1RKhG96O6jWumTTnw= github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 h1:RWengNIwukTxcDr9M+97sNutRR1RKhG96O6jWumTTnw=
@ -388,14 +416,18 @@ github.com/muesli/smartcrop v0.3.0/go.mod h1:i2fCI/UorTfgEpPPLWiFBv4pye+YAG78Rwc
github.com/neurosnap/sentences v1.0.6/go.mod h1:pg1IapvYpWCJJm/Etxeh0+gtMf1rI1STY9S7eUCPbDc= github.com/neurosnap/sentences v1.0.6/go.mod h1:pg1IapvYpWCJJm/Etxeh0+gtMf1rI1STY9S7eUCPbDc=
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 h1:zYyBkD/k9seD2A7fsi6Oo2LfFZAehjjQMERAvZLEDnQ= github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 h1:zYyBkD/k9seD2A7fsi6Oo2LfFZAehjjQMERAvZLEDnQ=
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646/go.mod h1:jpp1/29i3P1S/RLdc7JQKbRpFeM1dOBd8T9ki5s+AY8= github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646/go.mod h1:jpp1/29i3P1S/RLdc7JQKbRpFeM1dOBd8T9ki5s+AY8=
github.com/niklasfasching/go-org v1.7.0 h1:vyMdcMWWTe/XmANk19F4k8XGBYg0GQ/gJGMimOjGMek= github.com/niklasfasching/go-org v1.8.0 h1:WyGLaajLLp8JbQzkmapZ1y0MOzKuKV47HkZRloi+HGY=
github.com/niklasfasching/go-org v1.7.0/go.mod h1:WuVm4d45oePiE0eX25GqTDQIt/qPW1T9DGkRscqLW5o= github.com/niklasfasching/go-org v1.8.0/go.mod h1:e2A9zJs7cdONrEGs3gvxCcaAEpwwPNPG7csDpXckMNg=
github.com/oasdiff/yaml v0.0.0-20250309154309-f31be36b4037 h1:G7ERwszslrBzRxj//JalHPu/3yz+De2J+4aLtSRlHiY= github.com/oasdiff/yaml v0.0.0-20250309154309-f31be36b4037 h1:G7ERwszslrBzRxj//JalHPu/3yz+De2J+4aLtSRlHiY=
github.com/oasdiff/yaml v0.0.0-20250309154309-f31be36b4037/go.mod h1:2bpvgLBZEtENV5scfDFEtB/5+1M4hkQhDQrccEJ/qGw= github.com/oasdiff/yaml v0.0.0-20250309154309-f31be36b4037/go.mod h1:2bpvgLBZEtENV5scfDFEtB/5+1M4hkQhDQrccEJ/qGw=
github.com/oasdiff/yaml3 v0.0.0-20250309153720-d2182401db90 h1:bQx3WeLcUWy+RletIKwUIt4x3t8n2SxavmoclizMb8c= github.com/oasdiff/yaml3 v0.0.0-20250309153720-d2182401db90 h1:bQx3WeLcUWy+RletIKwUIt4x3t8n2SxavmoclizMb8c=
github.com/oasdiff/yaml3 v0.0.0-20250309153720-d2182401db90/go.mod h1:y5+oSEHCPT/DGrS++Wc/479ERge0zTFxaF8PbGKcg2o= github.com/oasdiff/yaml3 v0.0.0-20250309153720-d2182401db90/go.mod h1:y5+oSEHCPT/DGrS++Wc/479ERge0zTFxaF8PbGKcg2o=
github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec= github.com/olekukonko/errors v0.0.0-20250405072817-4e6d85265da6 h1:r3FaAI0NZK3hSmtTDrBVREhKULp8oUeqLT5Eyl2mSPo=
github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= github.com/olekukonko/errors v0.0.0-20250405072817-4e6d85265da6/go.mod h1:ppzxA5jBKcO1vIpCXQ9ZqgDh8iwODz6OXIGKU8r5m4Y=
github.com/olekukonko/ll v0.0.8 h1:sbGZ1Fx4QxJXEqL/6IG8GEFnYojUSQ45dJVwN2FH2fc=
github.com/olekukonko/ll v0.0.8/go.mod h1:En+sEW0JNETl26+K8eZ6/W4UQ7CYSrrgg/EdIYT2H8g=
github.com/olekukonko/tablewriter v1.0.7 h1:HCC2e3MM+2g72M81ZcJU11uciw6z/p82aEnm4/ySDGw=
github.com/olekukonko/tablewriter v1.0.7/go.mod h1:H428M+HzoUXC6JU2Abj9IT9ooRmdq9CxuDmKMtrOCMs=
github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58 h1:onHthvaw9LFnH4t2DcNVpwGmV9E1BkGknEliJkfwQj0= github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58 h1:onHthvaw9LFnH4t2DcNVpwGmV9E1BkGknEliJkfwQj0=
github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58/go.mod h1:DXv8WO4yhMYhSNPKjeNKa5WY9YCIEBRbNzFFPJbWO6Y= github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58/go.mod h1:DXv8WO4yhMYhSNPKjeNKa5WY9YCIEBRbNzFFPJbWO6Y=
github.com/pelletier/go-toml/v2 v2.2.4 h1:mye9XuhQ6gvn5h28+VilKrrPoQVanw5PMw/TB0t5Ec4= github.com/pelletier/go-toml/v2 v2.2.4 h1:mye9XuhQ6gvn5h28+VilKrrPoQVanw5PMw/TB0t5Ec4=
@ -408,12 +440,16 @@ github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsK
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/sftp v1.13.1/go.mod h1:3HaPG6Dq1ILlpPZRO0HVMrsydcdLt6HRDccSgb87qRg= github.com/pkg/sftp v1.13.1/go.mod h1:3HaPG6Dq1ILlpPZRO0HVMrsydcdLt6HRDccSgb87qRg=
github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 h1:GFCKgmp0tecUJ0sJuv4pzYCqS9+RGSn52M3FUwPs+uo=
github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10/go.mod h1:t/avpk3KcrXxUnYOhZhMXJlSEyie6gQbtLq5NM3loB8=
github.com/pmezard/go-difflib v0.0.0-20151028094244-d8ed2627bdf0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v0.0.0-20151028094244-d8ed2627bdf0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/prashantv/gostub v1.1.0 h1:BTyx3RfQjRHnUWaGF9oQos79AlQ5k8WNktv7VGvVH4g= github.com/prashantv/gostub v1.1.0 h1:BTyx3RfQjRHnUWaGF9oQos79AlQ5k8WNktv7VGvVH4g=
github.com/prashantv/gostub v1.1.0/go.mod h1:A5zLQHz7ieHGG7is6LLXLz7I8+3LZzsrV0P1IAHhP5U= github.com/prashantv/gostub v1.1.0/go.mod h1:A5zLQHz7ieHGG7is6LLXLz7I8+3LZzsrV0P1IAHhP5U=
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY=
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ= github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ=
@ -428,14 +464,16 @@ github.com/shogo82148/go-shuffle v0.0.0-20180218125048-27e6095f230d/go.mod h1:2h
github.com/spf13/afero v1.9.2/go.mod h1:iUV7ddyEEZPO5gA3zD4fJt6iStLlL+Lg4m2cihcDf8Y= github.com/spf13/afero v1.9.2/go.mod h1:iUV7ddyEEZPO5gA3zD4fJt6iStLlL+Lg4m2cihcDf8Y=
github.com/spf13/afero v1.14.0 h1:9tH6MapGnn/j0eb0yIXiLjERO8RB6xIVZRDCX7PtqWA= github.com/spf13/afero v1.14.0 h1:9tH6MapGnn/j0eb0yIXiLjERO8RB6xIVZRDCX7PtqWA=
github.com/spf13/afero v1.14.0/go.mod h1:acJQ8t0ohCGuMN3O+Pv0V0hgMxNYDlvdk+VTfyZmbYo= github.com/spf13/afero v1.14.0/go.mod h1:acJQ8t0ohCGuMN3O+Pv0V0hgMxNYDlvdk+VTfyZmbYo=
github.com/spf13/cast v1.7.1 h1:cuNEagBQEHWN1FnbGEjCXL2szYEXqfJPbP2HNUaca9Y= github.com/spf13/cast v1.9.2 h1:SsGfm7M8QOFtEzumm7UZrZdLLquNdzFYfIbEXntcFbE=
github.com/spf13/cast v1.7.1/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo= github.com/spf13/cast v1.9.2/go.mod h1:jNfB8QC9IA6ZuY2ZjDp0KtFO2LZZlg4S/7bzP6qqeHo=
github.com/spf13/cobra v1.9.1 h1:CXSaggrXdbHK9CF+8ywj8Amf7PBRmPCOJugH954Nnlo= github.com/spf13/cobra v1.9.1 h1:CXSaggrXdbHK9CF+8ywj8Amf7PBRmPCOJugH954Nnlo=
github.com/spf13/cobra v1.9.1/go.mod h1:nDyEzZ8ogv936Cinf6g1RU9MRY64Ir93oCnqb9wxYW0= github.com/spf13/cobra v1.9.1/go.mod h1:nDyEzZ8ogv936Cinf6g1RU9MRY64Ir93oCnqb9wxYW0=
github.com/spf13/fsync v0.10.1 h1:JRnB7G72b+gIBaBcpn5ibJSd7ww1iEahXSX2B8G6dSE= github.com/spf13/fsync v0.10.1 h1:JRnB7G72b+gIBaBcpn5ibJSd7ww1iEahXSX2B8G6dSE=
github.com/spf13/fsync v0.10.1/go.mod h1:y+B41vYq5i6Boa3Z+BVoPbDeOvxVkNU5OBXhoT8i4TQ= github.com/spf13/fsync v0.10.1/go.mod h1:y+B41vYq5i6Boa3Z+BVoPbDeOvxVkNU5OBXhoT8i4TQ=
github.com/spf13/pflag v1.0.6 h1:jFzHGLGAlb3ruxLB8MhbI6A8+AQX/2eW4qeyNZXNp2o= github.com/spf13/pflag v1.0.6 h1:jFzHGLGAlb3ruxLB8MhbI6A8+AQX/2eW4qeyNZXNp2o=
github.com/spf13/pflag v1.0.6/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/spf13/pflag v1.0.6/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/spiffe/go-spiffe/v2 v2.5.0 h1:N2I01KCUkv1FAjZXJMwh95KK1ZIQLYbPfhaxw8WS0hE=
github.com/spiffe/go-spiffe/v2 v2.5.0/go.mod h1:P+NxobPc6wXhVtINNtFjNWGBTreew1GBUCwT2wPmb7g=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
@ -449,13 +487,12 @@ github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/tdewolff/minify/v2 v2.20.37 h1:Q97cx4STXCh1dlWDlNHZniE8BJ2EBL0+2b0n92BJQhw= github.com/tdewolff/minify/v2 v2.23.8 h1:tvjHzRer46kwOfpdCBCWsDblCw3QtnLJRd61pTVkyZ8=
github.com/tdewolff/minify/v2 v2.20.37/go.mod h1:L1VYef/jwKw6Wwyk5A+T0mBjjn3mMPgmjjA688RNsxU= github.com/tdewolff/minify/v2 v2.23.8/go.mod h1:VW3ISUd3gDOZuQ/jwZr4sCzsuX+Qvsx87FDMjk6Rvno=
github.com/tdewolff/parse/v2 v2.7.15 h1:hysDXtdGZIRF5UZXwpfn3ZWRbm+ru4l53/ajBRGpCTw= github.com/tdewolff/parse/v2 v2.8.1 h1:J5GSHru6o3jF1uLlEKVXkDxxcVx6yzOlIVIotK4w2po=
github.com/tdewolff/parse/v2 v2.7.15/go.mod h1:3FbJWZp3XT9OWVN3Hmfp0p/a08v4h8J9W1aghka0soA= github.com/tdewolff/parse/v2 v2.8.1/go.mod h1:Hwlni2tiVNKyzR1o6nUs4FOF07URA+JLBLd6dlIXYqo=
github.com/tdewolff/test v1.0.11-0.20231101010635-f1265d231d52/go.mod h1:6DAvZliBAAnD7rhVgwaM7DE5/d9NMOAJ09SqYqeK4QE= github.com/tdewolff/test v1.0.11 h1:FdLbwQVHxqG16SlkGveC0JVyrJN62COWTRyUFzfbtBE=
github.com/tdewolff/test v1.0.11-0.20240106005702-7de5f7df4739 h1:IkjBCtQOOjIn03u/dMQK9g+Iw9ewps4mCl1nB8Sscbo= github.com/tdewolff/test v1.0.11/go.mod h1:XPuWBzvdUzhCuxWO1ojpXsyzsA5bFoS3tO/Q3kFuTG8=
github.com/tdewolff/test v1.0.11-0.20240106005702-7de5f7df4739/go.mod h1:XPuWBzvdUzhCuxWO1ojpXsyzsA5bFoS3tO/Q3kFuTG8=
github.com/tetratelabs/wazero v1.9.0 h1:IcZ56OuxrtaEz8UYNRHBrUa9bYeX9oVY93KspZZBf/I= github.com/tetratelabs/wazero v1.9.0 h1:IcZ56OuxrtaEz8UYNRHBrUa9bYeX9oVY93KspZZBf/I=
github.com/tetratelabs/wazero v1.9.0/go.mod h1:TSbcXCfFP0L2FGkRPxHphadXPjo1T6W+CseNNY7EkjM= github.com/tetratelabs/wazero v1.9.0/go.mod h1:TSbcXCfFP0L2FGkRPxHphadXPjo1T6W+CseNNY7EkjM=
github.com/ugorji/go/codec v1.2.7 h1:YPXUKf7fYbp/y8xloBqZOw2qaVggbfwMlI8WM3wZUJ0= github.com/ugorji/go/codec v1.2.7 h1:YPXUKf7fYbp/y8xloBqZOw2qaVggbfwMlI8WM3wZUJ0=
@ -466,10 +503,12 @@ github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
github.com/yuin/goldmark v1.7.11 h1:ZCxLyDMtz0nT2HFfsYG8WZ47Trip2+JyLysKcMYE5bo= github.com/yuin/goldmark v1.7.12 h1:YwGP/rrea2/CnCtUHgjuolG/PnMxdQtPMO5PvaE2/nY=
github.com/yuin/goldmark v1.7.11/go.mod h1:ip/1k0VRfGynBgxOz0yCqHrbZXhcjxyuS66Brc7iBKg= github.com/yuin/goldmark v1.7.12/go.mod h1:ip/1k0VRfGynBgxOz0yCqHrbZXhcjxyuS66Brc7iBKg=
github.com/yuin/goldmark-emoji v1.0.6 h1:QWfF2FYaXwL74tfGOW5izeiZepUDroDJfWubQI9HTHs= github.com/yuin/goldmark-emoji v1.0.6 h1:QWfF2FYaXwL74tfGOW5izeiZepUDroDJfWubQI9HTHs=
github.com/yuin/goldmark-emoji v1.0.6/go.mod h1:ukxJDKFpdFb5x0a5HqbdlcKtebh086iJpI31LTKmWuA= github.com/yuin/goldmark-emoji v1.0.6/go.mod h1:ukxJDKFpdFb5x0a5HqbdlcKtebh086iJpI31LTKmWuA=
github.com/zeebo/errs v1.4.0 h1:XNdoD/RRMKP7HD0UhJnIzUy74ISdGGxURlYG8HSWSfM=
github.com/zeebo/errs v1.4.0/go.mod h1:sgbWHsvVuTPHcqJJGQ1WhI5KbWlHYz+2+2C/LSEtCw4=
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= 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.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
@ -480,20 +519,24 @@ go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0=
go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo=
go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA= go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA=
go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A= go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A=
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.58.0 h1:PS8wXpbyaDJQ2VDHHncMe9Vct0Zn1fEjpsjrLxGJoSc= go.opentelemetry.io/contrib/detectors/gcp v1.35.0 h1:bGvFt68+KTiAKFlacHW6AhA56GF2rS0bdD3aJYEnmzA=
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.58.0/go.mod h1:HDBUsEjOuRC0EzKZ1bSaRGZWUBAzo+MhAcUUORSr4D0= go.opentelemetry.io/contrib/detectors/gcp v1.35.0/go.mod h1:qGWP8/+ILwMRIUf9uIVLloR1uo5ZYAslM4O6OqUi1DA=
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.58.0 h1:yd02MEjBdJkG3uabWP9apV+OuWRIXGDuJEUJbOHmCFU= go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.61.0 h1:q4XOmH/0opmeuJtPsbFNivyl7bCt7yRBbeEm2sC/XtQ=
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.58.0/go.mod h1:umTcuxiv1n/s/S6/c2AT/g2CQ7u5C59sHDNmfSwgz7Q= go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.61.0/go.mod h1:snMWehoOh2wsEwnvvwtDyFCxVeDAODenXHtn5vzrKjo=
go.opentelemetry.io/otel v1.34.0 h1:zRLXxLCgL1WyKsPVrgbSdMN4c0FMkDAskSTQP+0hdUY= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0 h1:F7Jx+6hwnZ41NSFTO5q4LYDtJRXBf2PD0rNBkeB/lus=
go.opentelemetry.io/otel v1.34.0/go.mod h1:OWFPOQ+h4G8xpyjgqo4SxJYdDQ/qmRH+wivy7zzx9oI= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0/go.mod h1:UHB22Z8QsdRDrnAtX4PntOl36ajSxcdUMt1sF7Y6E7Q=
go.opentelemetry.io/otel/metric v1.34.0 h1:+eTR3U0MyfWjRDhmFMxe2SsW64QrZ84AOhvqS7Y+PoQ= go.opentelemetry.io/otel v1.36.0 h1:UumtzIklRBY6cI/lllNZlALOF5nNIzJVb16APdvgTXg=
go.opentelemetry.io/otel/metric v1.34.0/go.mod h1:CEDrp0fy2D0MvkXE+dPV7cMi8tWZwX3dmaIhwPOaqHE= go.opentelemetry.io/otel v1.36.0/go.mod h1:/TcFMXYjyRNh8khOAO9ybYkqaDBb/70aVwkNML4pP8E=
go.opentelemetry.io/otel/sdk v1.34.0 h1:95zS4k/2GOy069d321O8jWgYsW3MzVV+KuSPKp7Wr1A= go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.29.0 h1:WDdP9acbMYjbKIyJUhTvtzj601sVJOqgWdUxSdR/Ysc=
go.opentelemetry.io/otel/sdk v1.34.0/go.mod h1:0e/pNiaMAqaykJGKbi+tSjWfNNHMTxoC9qANsCzbyxU= go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.29.0/go.mod h1:BLbf7zbNIONBLPwvFnwNHGj4zge8uTCM/UPIVW1Mq2I=
go.opentelemetry.io/otel/sdk/metric v1.32.0 h1:rZvFnvmvawYb0alrYkjraqJq0Z4ZUJAiyYCU9snn1CU= go.opentelemetry.io/otel/metric v1.36.0 h1:MoWPKVhQvJ+eeXWHFBOPoBOi20jh6Iq2CcCREuTYufE=
go.opentelemetry.io/otel/sdk/metric v1.32.0/go.mod h1:PWeZlq0zt9YkYAp3gjKZ0eicRYvOh1Gd+X99x6GHpCQ= go.opentelemetry.io/otel/metric v1.36.0/go.mod h1:zC7Ks+yeyJt4xig9DEw9kuUFe5C3zLbVjV2PzT6qzbs=
go.opentelemetry.io/otel/trace v1.34.0 h1:+ouXS2V8Rd4hp4580a8q23bg0azF2nI8cqLYnC8mh/k= go.opentelemetry.io/otel/sdk v1.36.0 h1:b6SYIuLRs88ztox4EyrvRti80uXIFy+Sqzoh9kFULbs=
go.opentelemetry.io/otel/trace v1.34.0/go.mod h1:Svm7lSjQD7kG7KJ/MUHPVXSDGz2OX4h0M2jHBhmSfRE= go.opentelemetry.io/otel/sdk v1.36.0/go.mod h1:+lC+mTgD+MUWfjJubi2vvXWcVxyr9rmlshZni72pXeY=
go.opentelemetry.io/otel/sdk/metric v1.36.0 h1:r0ntwwGosWGaa0CrSt8cuNuTcccMXERFwHX4dThiPis=
go.opentelemetry.io/otel/sdk/metric v1.36.0/go.mod h1:qTNOhFDfKRwX0yXOqJYegL5WRaW376QbB7P4Pb0qva4=
go.opentelemetry.io/otel/trace v1.36.0 h1:ahxWNuqZjpdiFAyrIoQ4GIiAIhxAunQR6MUoKrsNd4w=
go.opentelemetry.io/otel/trace v1.36.0/go.mod h1:gQ+OnDZzrybY4k4seLzPAWNwVBBVlF2szhehOBB/tGA=
go.uber.org/automaxprocs v1.5.3 h1:kWazyxZUrS3Gs4qUpbwo5kEIMGe/DAvi5Z4tl2NW4j8= go.uber.org/automaxprocs v1.5.3 h1:kWazyxZUrS3Gs4qUpbwo5kEIMGe/DAvi5Z4tl2NW4j8=
go.uber.org/automaxprocs v1.5.3/go.mod h1:eRbA25aqJrxAbsLO0xy5jVwPt7FQnRgjW+efnwa1WM0= go.uber.org/automaxprocs v1.5.3/go.mod h1:eRbA25aqJrxAbsLO0xy5jVwPt7FQnRgjW+efnwa1WM0=
gocloud.dev v0.40.0 h1:f8LgP+4WDqOG/RXoUcyLpeIAGOcAbZrZbDQCUee10ng= gocloud.dev v0.40.0 h1:f8LgP+4WDqOG/RXoUcyLpeIAGOcAbZrZbDQCUee10ng=
@ -509,8 +552,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.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.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc=
golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg= golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg=
golang.org/x/crypto v0.37.0 h1:kJNSjF/Xp7kU0iB2Z+9viTPMW4EqqsrywMXLJOOsXSE= golang.org/x/crypto v0.39.0 h1:SHs+kF4LP+f+p14esP5jAoDpHU8Gu/v9lFRK6IT5imM=
golang.org/x/crypto v0.37.0/go.mod h1:vg+k43peMZ0pUMhYmVAWysMK35e6ioLh3wB8ZCAfbVc= golang.org/x/crypto v0.39.0/go.mod h1:L+Xg3Wf6HoL4Bn4238Z6ft6KfEpN0tJGo53AAPC632U=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= 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-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
@ -526,8 +569,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-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-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.0.0-20210220032944-ac19c3e999fb/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
golang.org/x/image v0.26.0 h1:4XjIFEZWQmCZi6Wv8BoxsDhRU3RVnLX04dToTDAEPlY= golang.org/x/image v0.28.0 h1:gdem5JW1OLS4FbkWgLO+7ZeFzYtL3xClb97GaUzYMFE=
golang.org/x/image v0.26.0/go.mod h1:lcxbMFAovzpnJxzXS3nyL83K27tmqtKzIJpctK8YO5c= golang.org/x/image v0.28.0/go.mod h1:GUJYXtnGKEUgggyzh+Vxt+AviiCcyiwpsl8iQ8MvwGY=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= 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-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
@ -554,8 +597,8 @@ golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/mod v0.14.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/mod v0.14.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
golang.org/x/mod v0.24.0 h1:ZfthKaKaT4NrhGVZHO1/WDTwGES4De8KtWO0SIbNJMU= golang.org/x/mod v0.25.0 h1:n7a+ZbQKQA/Ysbyb0/6IbB1H/X41mKgbhfv7AfG/44w=
golang.org/x/mod v0.24.0/go.mod h1:IXM97Txy2VM4PJ3gI61r1YEk/gAj6zAHN3AdZt6S9Ww= golang.org/x/mod v0.25.0/go.mod h1:IXM97Txy2VM4PJ3gI61r1YEk/gAj6zAHN3AdZt6S9Ww=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@ -595,8 +638,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.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk= 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.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY=
golang.org/x/net v0.39.0 h1:ZCu7HMWDxpXpaiKdhzIfaltL9Lp31x/3fCP11bc6/fY= golang.org/x/net v0.41.0 h1:vBTly1HeNPEn3wtREYfy4GZ/NECgw2Cnl+nK6Nz3uvw=
golang.org/x/net v0.39.0/go.mod h1:X7NRbYVEA+ewNkCNyJ513WmMdQ3BineSwVtN2zD/d+E= golang.org/x/net v0.41.0/go.mod h1:B/K4NNqkfmg07DQYrbwvSluqCJOOXwUjeb/5lOisjbA=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= 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-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
@ -606,8 +649,8 @@ golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ
golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
golang.org/x/oauth2 v0.26.0 h1:afQXWNNaeC4nvZ0Ed9XvCCzXM6UHJG7iCg0W4fPqSBE= golang.org/x/oauth2 v0.30.0 h1:dnDm7JmhM45NNpd8FDDeLhK6FwqbOf4MLCM9zb1BOHI=
golang.org/x/oauth2 v0.26.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= golang.org/x/oauth2 v0.30.0/go.mod h1:B++QgG3ZKulg6sRPGD/mqlHQs5rB3Ml9erfeDY7xKlU=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@ -623,8 +666,8 @@ golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJ
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y=
golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sync v0.13.0 h1:AauUjRAJ9OSnvULf/ARrrVywoJDy0YS2AwQ98I37610= golang.org/x/sync v0.15.0 h1:KWH3jNZsfyT6xfAfKiz6MRNmd46ByHDYaZ7KSkCtdW8=
golang.org/x/sync v0.13.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= golang.org/x/sync v0.15.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@ -672,8 +715,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.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.12.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.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.32.0 h1:s77OFDvIQeibCmezSnk/q6iAfkdiQaJi4VzroCFrN20= golang.org/x/sys v0.33.0 h1:q3i8TbbEz+JRD9ywIRlyRAQbM0qF7hu24q3teo2hbuw=
golang.org/x/sys v0.32.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= golang.org/x/sys v0.33.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= 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.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
@ -692,13 +735,13 @@ 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.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.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.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
golang.org/x/text v0.24.0 h1:dd5Bzh4yt5KYA8f9CJHCP4FB4D51c2c6JvN37xJJkJ0= golang.org/x/text v0.26.0 h1:P42AVeLghgTYr4+xUnTRKDMqpar+PtX7KWuNQL21L8M=
golang.org/x/text v0.24.0/go.mod h1:L8rBsPeo2pSS+xqN0d5u2ikmjtmoJbDBT1b7nHvFCdU= golang.org/x/text v0.26.0/go.mod h1:QK15LZJUUQVJxhz7wXgxSy/CJaTFjd0G+YLonydOVQA=
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= 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-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.10.0 h1:3usCWA8tQn0L8+hFJQNgzpWbd89begxN66o1Ojdn5L4= golang.org/x/time v0.12.0 h1:ScB/8o8olJvc+CQPWrK3fPZNfh7qgwCrY0zJmoEQLSE=
golang.org/x/time v0.10.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/time v0.12.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
@ -751,8 +794,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.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58= 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.17.0/go.mod h1:xsh6VxdV005rRVaS6SSAf9oiAqljS7UZUacMZ8Bnsps=
golang.org/x/tools v0.32.0 h1:Q7N1vhpkQv7ybVzLFtTjvQya2ewbwNDZzUgfXGqtMWU= golang.org/x/tools v0.33.0 h1:4qz2S3zmRxbGIhDIAgjxvFutSvH5EfnsYrRBj0UI0bc=
golang.org/x/tools v0.32.0/go.mod h1:ZxrU41P/wAbZD8EDa6dDCa6XfpkhJ7HFMjHJXfBDu8s= golang.org/x/tools v0.33.0/go.mod h1:CIJMaWEY88juyUfo7UbgPqbC8rU2OqfAV1h2Qp0oMYI=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 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-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
@ -778,8 +821,8 @@ google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz513
google.golang.org/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg= google.golang.org/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg=
google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34qYtE= google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34qYtE=
google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8= google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8=
google.golang.org/api v0.221.0 h1:qzaJfLhDsbMeFee8zBRdt/Nc+xmOuafD/dbdgGfutOU= google.golang.org/api v0.237.0 h1:MP7XVsGZesOsx3Q8WVa4sUdbrsTvDSOERd3Vh4xj/wc=
google.golang.org/api v0.221.0/go.mod h1:7sOU2+TL4TxUTdbi0gWgAIg7tH5qBXxoyhtL+9x3biQ= google.golang.org/api v0.237.0/go.mod h1:cOVEm2TpdAGHL2z+UwyS+kmlGr3bVWQQ6sYEqkKje50=
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
@ -823,12 +866,12 @@ google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6D
google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20210108203827-ffc7fda8c3d7/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210108203827-ffc7fda8c3d7/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20210226172003-ab064af71705/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210226172003-ab064af71705/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20241104194629-dd2ea8efbc28 h1:KJjNNclfpIkVqrZlTWcgOOaVQ00LdBnoEaRfkUx760s= google.golang.org/genproto v0.0.0-20250505200425-f936aa4a68b2 h1:1tXaIXCracvtsRxSBsYDiSBN0cuJvM7QYW+MrpIRY78=
google.golang.org/genproto v0.0.0-20241104194629-dd2ea8efbc28/go.mod h1:mt9/MofW7AWQ+Gy179ChOnvmJatV8YHUmrcedo9CIFI= google.golang.org/genproto v0.0.0-20250505200425-f936aa4a68b2/go.mod h1:49MsLSx0oWMOZqcpB3uL8ZOkAh1+TndpJ8ONoCBWiZk=
google.golang.org/genproto/googleapis/api v0.0.0-20241209162323-e6fa225c2576 h1:CkkIfIt50+lT6NHAVoRYEyAvQGFM7xEwXUUywFvEb3Q= google.golang.org/genproto/googleapis/api v0.0.0-20250505200425-f936aa4a68b2 h1:vPV0tzlsK6EzEDHNNH5sa7Hs9bd7iXR7B1tSiPepkV0=
google.golang.org/genproto/googleapis/api v0.0.0-20241209162323-e6fa225c2576/go.mod h1:1R3kvZ1dtP3+4p4d3G8uJ8rFk/fWlScl38vanWACI08= google.golang.org/genproto/googleapis/api v0.0.0-20250505200425-f936aa4a68b2/go.mod h1:pKLAc5OolXC3ViWGI62vvC0n10CpwAtRcTNCFwTKBEw=
google.golang.org/genproto/googleapis/rpc v0.0.0-20250207221924-e9438ea467c6 h1:2duwAxN2+k0xLNpjnHTXoMUgnv6VPSp5fiqTuwSxjmI= google.golang.org/genproto/googleapis/rpc v0.0.0-20250603155806-513f23925822 h1:fc6jSaCT0vBduLYZHYrBBNY4dsWuvgyff9noRNDdBeE=
google.golang.org/genproto/googleapis/rpc v0.0.0-20250207221924-e9438ea467c6/go.mod h1:8BS3B93F/U1juMFq9+EDk+qOT5CO1R9IzXxG3PTqiRk= google.golang.org/genproto/googleapis/rpc v0.0.0-20250603155806-513f23925822/go.mod h1:qQ0YXyHHx3XkvlzUtpXDkS29lDSafHMZBAZDc03LQ3A=
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
@ -845,8 +888,8 @@ google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM
google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc=
google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8= google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8=
google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
google.golang.org/grpc v1.70.0 h1:pWFv03aZoHzlRKHWicjsZytKAiYCtNS0dHbXnIdq7jQ= google.golang.org/grpc v1.73.0 h1:VIWSmpI2MegBtTuFt5/JWy2oXxtjJ/e89Z70ImfD2ok=
google.golang.org/grpc v1.70.0/go.mod h1:ofIJqVKDXx/JiXrwr2IG4/zwdH9txy3IlF40RmcJSQw= google.golang.org/grpc v1.73.0/go.mod h1:50sbHOUqWoCQGI8V2HQLJM0B+LMlIUjNSZmow7EVBQc=
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
@ -857,8 +900,8 @@ google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2
google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4=
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
google.golang.org/protobuf v1.36.5 h1:tPhr+woSbjfYvY6/GPufUoYizxw1cF/yFoxJ2fmpwlM= google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY=
google.golang.org/protobuf v1.36.5/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=

View file

@ -19,6 +19,8 @@ import (
"sync/atomic" "sync/atomic"
"github.com/olekukonko/tablewriter" "github.com/olekukonko/tablewriter"
"github.com/olekukonko/tablewriter/renderer"
"github.com/olekukonko/tablewriter/tw"
) )
// ProcessingStats represents statistics about a site build. // ProcessingStats represents statistics about a site build.
@ -66,23 +68,6 @@ func (s *ProcessingStats) Add(counter *uint64, amount int) {
atomic.AddUint64(counter, uint64(amount)) atomic.AddUint64(counter, uint64(amount))
} }
// Table writes a table-formatted representation of the stats in a
// ProcessingStats instance to w.
func (s *ProcessingStats) Table(w io.Writer) {
titleVals := s.toVals()
data := make([][]string, len(titleVals))
for i, tv := range titleVals {
data[i] = []string{tv.name, strconv.Itoa(int(tv.val))}
}
table := tablewriter.NewWriter(w)
table.AppendBulk(data)
table.SetHeader([]string{"", s.Name})
table.SetBorder(false)
table.Render()
}
// ProcessingStatsTable writes a table-formatted representation of stats to w. // ProcessingStatsTable writes a table-formatted representation of stats to w.
func ProcessingStatsTable(w io.Writer, stats ...*ProcessingStats) { func ProcessingStatsTable(w io.Writer, stats ...*ProcessingStats) {
names := make([]string, len(stats)+1) names := make([]string, len(stats)+1)
@ -106,13 +91,26 @@ func ProcessingStatsTable(w io.Writer, stats ...*ProcessingStats) {
data[j] = append(data[j], strconv.Itoa(int(tv.val))) data[j] = append(data[j], strconv.Itoa(int(tv.val)))
} }
} }
} }
table := tablewriter.NewWriter(w) table := tablewriter.NewTable(
w,
tablewriter.WithRenderer(renderer.NewBlueprint(tw.Rendition{
Borders: tw.BorderNone,
Symbols: tw.NewSymbols(tw.StyleLight),
Settings: tw.Settings{
Separators: tw.Separators{BetweenRows: tw.Off},
Lines: tw.Lines{ShowFooterLine: tw.On},
},
})),
tablewriter.WithConfig(
tablewriter.Config{
MaxWidth: 70,
Row: tw.CellConfig{Alignment: tw.CellAlignment{Global: tw.AlignRight, PerColumn: []tw.Align{tw.AlignLeft}}},
}),
)
table.AppendBulk(data) table.Bulk(data)
table.SetHeader(names) table.Header(names)
table.SetBorder(false)
table.Render() table.Render()
} }

View file

@ -892,7 +892,7 @@ disableKinds = ['home','rss','sitemap','taxonomy','term']
--- ---
title: s title: s
cascade: cascade:
_build: build:
render: never render: never
--- ---
-- content/s/p1.md -- -- content/s/p1.md --
@ -917,3 +917,51 @@ title: p2
b.AssertFileExists("public/sx/index.html", true) // failing b.AssertFileExists("public/sx/index.html", true) // failing
b.AssertFileExists("public/sx/p2/index.html", true) // failing b.AssertFileExists("public/sx/p2/index.html", true) // failing
} }
func TestCascadeGotmplIssue13743(t *testing.T) {
t.Parallel()
files := `
-- hugo.toml --
disableKinds = ['home','rss','section','sitemap','taxonomy','term']
[cascade.params]
foo = 'bar'
[cascade.target]
path = '/p1'
-- content/_content.gotmpl --
{{ .AddPage (dict "title" "p1" "path" "p1") }}
-- layouts/all.html --
{{ .Title }}|{{ .Params.foo }}
`
b := Test(t, files)
b.AssertFileContent("public/p1/index.html", "p1|bar") // actual content is "p1|"
}
func TestCascadeWarnOverrideIssue13806(t *testing.T) {
t.Parallel()
files := `
-- hugo.toml --
disableKinds = ['home','rss','section','sitemap','taxonomy','term']
[[cascade]]
[cascade.params]
searchable = true
[cascade.target]
kind = 'page'
-- content/something.md --
---
title: Something
params:
searchable: false
---
-- layouts/all.html --
All.
`
b := Test(t, files, TestOptWarn())
b.AssertLogContains("! WARN")
}

View file

@ -1406,7 +1406,7 @@ home = ["html"]
"home": {"html"}, "home": {"html"},
"page": {"html"}, "page": {"html"},
"rss": {"rss"}, "rss": {"rss"},
"section": nil, "section": {},
"taxonomy": {"html", "rss"}, "taxonomy": {"html", "rss"},
"term": {"html", "rss"}, "term": {"html", "rss"},
}) })

View file

@ -21,7 +21,6 @@ import (
"sort" "sort"
"strconv" "strconv"
"strings" "strings"
"sync"
"sync/atomic" "sync/atomic"
"time" "time"
@ -1310,7 +1309,6 @@ func (h *HugoSites) resolveAndResetDependententPageOutputs(ctx context.Context,
} }
po.renderState = 0 po.renderState = 0
po.p.resourcesPublishInit = &sync.Once{}
if r == identity.FinderFoundOneOfMany || po.f.Name == output.HTTPStatus404HTMLFormat.Name { if r == identity.FinderFoundOneOfMany || po.f.Name == output.HTTPStatus404HTMLFormat.Name {
// Will force a re-render even in fast render mode. // Will force a re-render even in fast render mode.
po.renderOnce = false po.renderOnce = false
@ -1412,7 +1410,7 @@ func (sa *sitePagesAssembler) applyAggregates() error {
} }
// Handle cascades first to get any default dates set. // Handle cascades first to get any default dates set.
var cascade *maps.Ordered[page.PageMatcher, maps.Params] var cascade *maps.Ordered[page.PageMatcher, page.PageMatcherParamsConfig]
if keyPage == "" { if keyPage == "" {
// Home page gets it's cascade from the site config. // Home page gets it's cascade from the site config.
cascade = sa.conf.Cascade.Config cascade = sa.conf.Cascade.Config
@ -1424,7 +1422,7 @@ func (sa *sitePagesAssembler) applyAggregates() error {
} else { } else {
_, data := pw.WalkContext.Data().LongestPrefix(paths.Dir(keyPage)) _, data := pw.WalkContext.Data().LongestPrefix(paths.Dir(keyPage))
if data != nil { if data != nil {
cascade = data.(*maps.Ordered[page.PageMatcher, maps.Params]) cascade = data.(*maps.Ordered[page.PageMatcher, page.PageMatcherParamsConfig])
} }
} }
@ -1506,11 +1504,11 @@ func (sa *sitePagesAssembler) applyAggregates() error {
pageResource := rs.r.(*pageState) pageResource := rs.r.(*pageState)
relPath := pageResource.m.pathInfo.BaseRel(pageBundle.m.pathInfo) relPath := pageResource.m.pathInfo.BaseRel(pageBundle.m.pathInfo)
pageResource.m.resourcePath = relPath pageResource.m.resourcePath = relPath
var cascade *maps.Ordered[page.PageMatcher, maps.Params] var cascade *maps.Ordered[page.PageMatcher, page.PageMatcherParamsConfig]
// Apply cascade (if set) to the page. // Apply cascade (if set) to the page.
_, data := pw.WalkContext.Data().LongestPrefix(resourceKey) _, data := pw.WalkContext.Data().LongestPrefix(resourceKey)
if data != nil { if data != nil {
cascade = data.(*maps.Ordered[page.PageMatcher, maps.Params]) cascade = data.(*maps.Ordered[page.PageMatcher, page.PageMatcherParamsConfig])
} }
if err := pageResource.setMetaPost(cascade); err != nil { if err := pageResource.setMetaPost(cascade); err != nil {
return false, err return false, err
@ -1574,10 +1572,10 @@ func (sa *sitePagesAssembler) applyAggregatesToTaxonomiesAndTerms() error {
const eventName = "dates" const eventName = "dates"
if p.Kind() == kinds.KindTerm { if p.Kind() == kinds.KindTerm {
var cascade *maps.Ordered[page.PageMatcher, maps.Params] var cascade *maps.Ordered[page.PageMatcher, page.PageMatcherParamsConfig]
_, data := pw.WalkContext.Data().LongestPrefix(s) _, data := pw.WalkContext.Data().LongestPrefix(s)
if data != nil { if data != nil {
cascade = data.(*maps.Ordered[page.PageMatcher, maps.Params]) cascade = data.(*maps.Ordered[page.PageMatcher, page.PageMatcherParamsConfig])
} }
if err := p.setMetaPost(cascade); err != nil { if err := p.setMetaPost(cascade); err != nil {
return false, err return false, err

View file

@ -44,14 +44,14 @@ tags: ["mytag"]
`, "sect/no-list.md", ` `, "sect/no-list.md", `
--- ---
title: No List title: No List
_build: build:
list: false list: false
--- ---
`, "sect/no-render.md", ` `, "sect/no-render.md", `
--- ---
title: No List title: No List
_build: build:
render: false render: false
--- ---
`, `,
@ -59,14 +59,14 @@ _build:
--- ---
title: No Render Link title: No Render Link
aliases: ["/link-alias"] aliases: ["/link-alias"]
_build: build:
render: link render: link
--- ---
`, `,
"sect/no-publishresources/index.md", ` "sect/no-publishresources/index.md", `
--- ---
title: No Publish Resources title: No Publish Resources
_build: build:
publishResources: false publishResources: false
--- ---
@ -81,7 +81,7 @@ headless: true
--- ---
title: Headless Local Lists title: Headless Local Lists
cascade: cascade:
_build: build:
render: false render: false
list: local list: local
publishResources: false publishResources: false
@ -365,7 +365,7 @@ Data1: {{ $data1.RelPermalink }}
`) `)
b.WithContent("section/bundle-false/index.md", `---\ntitle: BundleFalse b.WithContent("section/bundle-false/index.md", `---\ntitle: BundleFalse
_build: build:
publishResources: false publishResources: false
---`, ---`,
"section/bundle-false/data1.json", "Some data1", "section/bundle-false/data1.json", "Some data1",
@ -388,7 +388,7 @@ func TestNoRenderAndNoPublishResources(t *testing.T) {
noRenderPage := ` noRenderPage := `
--- ---
title: %s title: %s
_build: build:
render: false render: false
publishResources: false publishResources: false
--- ---

View file

@ -263,7 +263,7 @@ func (s *IntegrationTestBuilder) AssertLogContains(els ...string) {
} }
} }
// AssertLogNotContains asserts that the last build log does matches the given regular expressions. // AssertLogMatches asserts that the last build log matches the given regular expressions.
// The regular expressions can be negated with a "! " prefix. // The regular expressions can be negated with a "! " prefix.
func (s *IntegrationTestBuilder) AssertLogMatches(expression string) { func (s *IntegrationTestBuilder) AssertLogMatches(expression string) {
s.Helper() s.Helper()

View file

@ -19,7 +19,6 @@ import (
"path/filepath" "path/filepath"
"strconv" "strconv"
"strings" "strings"
"sync"
"sync/atomic" "sync/atomic"
"github.com/gohugoio/hugo/hugofs" "github.com/gohugoio/hugo/hugofs"
@ -29,6 +28,7 @@ import (
"github.com/gohugoio/hugo/media" "github.com/gohugoio/hugo/media"
"github.com/gohugoio/hugo/output" "github.com/gohugoio/hugo/output"
"github.com/gohugoio/hugo/related" "github.com/gohugoio/hugo/related"
"github.com/gohugoio/hugo/resources"
"github.com/gohugoio/hugo/tpl/tplimpl" "github.com/gohugoio/hugo/tpl/tplimpl"
"github.com/spf13/afero" "github.com/spf13/afero"
@ -111,7 +111,6 @@ type pageState struct {
resource.Staler resource.Staler
dependencyManager identity.Manager dependencyManager identity.Manager
resourcesPublishInit *sync.Once
} }
func (p *pageState) incrPageOutputTemplateVariation() { func (p *pageState) incrPageOutputTemplateVariation() {
@ -522,26 +521,23 @@ func (p *pageState) initPage() error {
} }
func (p *pageState) renderResources() error { func (p *pageState) renderResources() error {
var initErr error
p.resourcesPublishInit.Do(func() {
for _, r := range p.Resources() { for _, r := range p.Resources() {
if _, ok := r.(page.Page); ok { if _, ok := r.(page.Page); ok {
if p.s.h.buildCounter.Load() == 0 {
// Pages gets rendered with the owning page but we count them here. // Pages gets rendered with the owning page but we count them here.
p.s.PathSpec.ProcessingStats.Incr(&p.s.PathSpec.ProcessingStats.Pages) p.s.PathSpec.ProcessingStats.Incr(&p.s.PathSpec.ProcessingStats.Pages)
}
continue continue
} }
if _, isWrapper := r.(resource.ResourceWrapper); isWrapper { if resources.IsPublished(r) {
// Skip resources that are wrapped.
// These gets published on its own.
continue continue
} }
src, ok := r.(resource.Source) src, ok := r.(resource.Source)
if !ok { if !ok {
initErr = fmt.Errorf("resource %T does not support resource.Source", r) return fmt.Errorf("resource %T does not support resource.Source", r)
return
} }
if err := src.Publish(); err != nil { if err := src.Publish(); err != nil {
@ -552,9 +548,8 @@ func (p *pageState) renderResources() error {
p.s.PathSpec.ProcessingStats.Incr(&p.s.PathSpec.ProcessingStats.Files) p.s.PathSpec.ProcessingStats.Incr(&p.s.PathSpec.ProcessingStats.Files)
} }
} }
})
return initErr return nil
} }
func (p *pageState) AlternativeOutputFormats() page.OutputFormats { func (p *pageState) AlternativeOutputFormats() page.OutputFormats {

View file

@ -29,7 +29,6 @@ import (
"github.com/gohugoio/hugo/source" "github.com/gohugoio/hugo/source"
"github.com/gohugoio/hugo/common/constants"
"github.com/gohugoio/hugo/common/hashing" "github.com/gohugoio/hugo/common/hashing"
"github.com/gohugoio/hugo/common/hugo" "github.com/gohugoio/hugo/common/hugo"
"github.com/gohugoio/hugo/common/loggers" "github.com/gohugoio/hugo/common/loggers"
@ -84,7 +83,7 @@ type pageMetaParams struct {
// These are only set in watch mode. // These are only set in watch mode.
datesOriginal pagemeta.Dates datesOriginal pagemeta.Dates
paramsOriginal map[string]any // contains the original params as defined in the front matter. paramsOriginal map[string]any // contains the original params as defined in the front matter.
cascadeOriginal *maps.Ordered[page.PageMatcher, maps.Params] // contains the original cascade as defined in the front matter. cascadeOriginal *maps.Ordered[page.PageMatcher, page.PageMatcherParamsConfig] // contains the original cascade as defined in the front matter.
} }
func (m *pageMetaParams) init(preserveOriginal bool) { func (m *pageMetaParams) init(preserveOriginal bool) {
@ -291,7 +290,7 @@ func (p *pageMeta) setMetaPre(pi *contentParseInfo, logger loggers.Logger, conf
return nil return nil
} }
func (ps *pageState) setMetaPost(cascade *maps.Ordered[page.PageMatcher, maps.Params]) error { func (ps *pageState) setMetaPost(cascade *maps.Ordered[page.PageMatcher, page.PageMatcherParamsConfig]) error {
ps.m.setMetaPostCount++ ps.m.setMetaPostCount++
var cascadeHashPre uint64 var cascadeHashPre uint64
if ps.m.setMetaPostCount > 1 { if ps.m.setMetaPostCount > 1 {
@ -303,15 +302,20 @@ func (ps *pageState) setMetaPost(cascade *maps.Ordered[page.PageMatcher, maps.Pa
// Apply cascades first so they can be overridden later. // Apply cascades first so they can be overridden later.
if cascade != nil { if cascade != nil {
if ps.m.pageConfig.CascadeCompiled != nil { if ps.m.pageConfig.CascadeCompiled != nil {
cascade.Range(func(k page.PageMatcher, v maps.Params) bool { cascade.Range(func(k page.PageMatcher, v page.PageMatcherParamsConfig) bool {
vv, found := ps.m.pageConfig.CascadeCompiled.Get(k) vv, found := ps.m.pageConfig.CascadeCompiled.Get(k)
if !found { if !found {
ps.m.pageConfig.CascadeCompiled.Set(k, v) ps.m.pageConfig.CascadeCompiled.Set(k, v)
} else { } else {
// Merge // Merge
for ck, cv := range v { for ck, cv := range v.Params {
if _, found := vv[ck]; !found { if _, found := vv.Params[ck]; !found {
vv[ck] = cv vv.Params[ck] = cv
}
}
for ck, cv := range v.Fields {
if _, found := vv.Fields[ck]; !found {
vv.Fields[ck] = cv
} }
} }
} }
@ -341,11 +345,17 @@ func (ps *pageState) setMetaPost(cascade *maps.Ordered[page.PageMatcher, maps.Pa
// Cascade is also applied to itself. // Cascade is also applied to itself.
var err error var err error
cascade.Range(func(k page.PageMatcher, v maps.Params) bool { cascade.Range(func(k page.PageMatcher, v page.PageMatcherParamsConfig) bool {
if !k.Matches(ps) { if !k.Matches(ps) {
return true return true
} }
for kk, vv := range v { for kk, vv := range v.Params {
if _, found := ps.m.pageConfig.Params[kk]; !found {
ps.m.pageConfig.Params[kk] = vv
}
}
for kk, vv := range v.Fields {
if ps.m.pageConfig.IsFromContentAdapter { if ps.m.pageConfig.IsFromContentAdapter {
if _, found := ps.m.pageConfig.ContentAdapterData[kk]; !found { if _, found := ps.m.pageConfig.ContentAdapterData[kk]; !found {
ps.m.pageConfig.ContentAdapterData[kk] = vv ps.m.pageConfig.ContentAdapterData[kk] = vv
@ -636,9 +646,6 @@ params:
} }
for k, v := range userParams { for k, v := range userParams {
if _, found := params[k]; found {
p.s.Log.Warnidf(constants.WarnFrontMatterParamsOverrides, "Hugo front matter key %q is overridden in params section.", k)
}
params[strings.ToLower(k)] = v params[strings.ToLower(k)] = v
} }

View file

@ -16,12 +16,12 @@ package hugolib
import ( import (
"fmt" "fmt"
"strings" "strings"
"sync"
"sync/atomic" "sync/atomic"
"github.com/gohugoio/hugo/hugofs/files" "github.com/gohugoio/hugo/hugofs/files"
"github.com/gohugoio/hugo/resources" "github.com/gohugoio/hugo/resources"
"github.com/gohugoio/hugo/common/constants"
"github.com/gohugoio/hugo/common/maps" "github.com/gohugoio/hugo/common/maps"
"github.com/gohugoio/hugo/common/paths" "github.com/gohugoio/hugo/common/paths"
@ -40,6 +40,14 @@ func (h *HugoSites) newPage(m *pageMeta) (*pageState, *paths.Path, error) {
// Make sure that any partially created page part is marked as stale. // Make sure that any partially created page part is marked as stale.
m.MarkStale() m.MarkStale()
} }
if p != nil && pth != nil && p.IsHome() && pth.IsLeafBundle() {
msg := "Using %s in your content's root directory is usually incorrect for your home page. "
msg += "You should use %s instead. If you don't rename this file, your home page will be "
msg += "treated as a leaf bundle, meaning it won't be able to have any child pages or sections."
h.Log.Warnidf(constants.WarnHomePageIsLeafBundle, msg, pth.PathNoLeadingSlash(), strings.ReplaceAll(pth.PathNoLeadingSlash(), "index", "_index"))
}
return p, pth, err return p, pth, err
} }
@ -190,7 +198,6 @@ func (h *HugoSites) doNewPage(m *pageMeta) (*pageState, *paths.Path, error) {
pid: pid, pid: pid,
pageOutput: nopPageOutput, pageOutput: nopPageOutput,
pageOutputTemplateVariationsState: &atomic.Uint32{}, pageOutputTemplateVariationsState: &atomic.Uint32{},
resourcesPublishInit: &sync.Once{},
Staler: m, Staler: m,
dependencyManager: m.s.Conf.NewIdentityManager(m.Path()), dependencyManager: m.s.Conf.NewIdentityManager(m.Path()),
pageCommon: &pageCommon{ pageCommon: &pageCommon{

View file

@ -1968,3 +1968,35 @@ Title: {{ .Title }}
"deprecated: path in front matter was deprecated", "deprecated: path in front matter was deprecated",
) )
} }
// Issue 13538
func TestHomePageIsLeafBundle(t *testing.T) {
t.Parallel()
files := `
-- hugo.toml --
defaultContentLanguage = 'de'
defaultContentLanguageInSubdir = true
[languages.de]
weight = 1
[languages.en]
weight = 2
-- layouts/all.html --
{{ .Title }}
-- content/index.de.md --
---
title: home de
---
-- content/index.en.org --
---
title: home en
---
`
b := Test(t, files, TestOptWarn())
b.AssertFileContent("public/de/index.html", "home de")
b.AssertFileContent("public/en/index.html", "home en")
b.AssertLogContains("Using index.de.md in your content's root directory is usually incorrect for your home page. You should use _index.de.md instead.")
b.AssertLogContains("Using index.en.org in your content's root directory is usually incorrect for your home page. You should use _index.en.org instead.")
}

View file

@ -57,7 +57,7 @@ Summary: {{ .Summary }}|
) )
} }
func TestFrontMatterParamsKindPath(t *testing.T) { func TestFrontMatterParamsPath(t *testing.T) {
t.Parallel() t.Parallel()
files := ` files := `
@ -72,10 +72,9 @@ date: 2019-08-07
path: "/a/b/c" path: "/a/b/c"
slug: "s1" slug: "s1"
--- ---
-- content/mysection.md -- -- content/mysection/_index.md --
--- ---
title: "My Section" title: "My Section"
kind: "section"
date: 2022-08-07 date: 2022-08-07
path: "/a/b" path: "/a/b"
--- ---
@ -95,66 +94,6 @@ a/b pages: {{ range $ab.RegularPages }}{{ .Path }}|{{ .RelPermalink }}|{{ end }}
) )
} }
func TestFrontMatterParamsLang(t *testing.T) {
t.Parallel()
files := `
-- hugo.toml --
baseURL = "https://example.org/"
disableKinds = ["taxonomy", "term"]
defaultContentLanguage = "en"
defaultContentLanguageInSubdir = true
[languages]
[languages.en]
weight = 1
[languages.nn]
weight = 2
-- content/p1.md --
---
title: "P1 nn"
lang: "nn"
---
-- content/p2.md --
---
title: "P2"
---
-- layouts/index.html --
RegularPages: {{ range site.RegularPages }}{{ .Path }}|{{ .RelPermalink }}|{{ .Title }}|{{ end }}$
`
b := Test(t, files)
b.AssertFileContent("public/en/index.html",
"RegularPages: /p2|/en/p2/|P2|$",
)
b.AssertFileContent("public/nn/index.html",
"RegularPages: /p1|/nn/p1/|P1 nn|$",
)
}
func TestFrontMatterTitleOverrideWarn(t *testing.T) {
t.Parallel()
files := `
-- hugo.toml --
baseURL = "https://example.org/"
disableKinds = ["taxonomy", "term"]
-- content/p1.md --
---
title: "My title"
params:
title: "My title from params"
---
`
b := Test(t, files, TestOptWarn())
b.AssertLogContains("ARN Hugo front matter key \"title\" is overridden in params section", "You can suppress this warning")
}
func TestFrontMatterParamsLangNoCascade(t *testing.T) { func TestFrontMatterParamsLangNoCascade(t *testing.T) {
t.Parallel() t.Parallel()

View file

@ -1766,6 +1766,60 @@ MyTemplate: {{ partial "MyTemplate.html" . }}|
b.AssertFileContent("public/index.html", "MyTemplate: MyTemplate Edited") b.AssertFileContent("public/index.html", "MyTemplate: MyTemplate Edited")
} }
func TestRebuildEditInlinePartial13723(t *testing.T) {
t.Parallel()
files := `
-- hugo.toml --
baseURL = "https://example.com"
disableLiveReload = true
title = "Foo"
-- layouts/baseof.html --
{{ block "main" . }}Main.{{ end }}
{{ partial "myinlinepartialinbaseof.html" . }}|
{{- define "_partials/myinlinepartialinbaseof.html" }}
My inline partial in baseof.
{{ end }}
-- layouts/_partials/mypartial.html --
Mypartial.
{{ partial "myinlinepartial.html" . }}|
{{- define "_partials/myinlinepartial.html" }}
Mypartial Inline.|{{ .Title }}|
{{ end }}
-- layouts/_partials/myotherpartial.html --
Myotherpartial.
{{ partial "myotherinlinepartial.html" . }}|
{{- define "_partials/myotherinlinepartial.html" }}
Myotherpartial Inline.|{{ .Title }}|
{{ return "myotherinlinepartial" }}
{{ end }}
-- layouts/all.html --
{{ define "main" }}
{{ partial "mypartial.html" . }}|
{{ partial "myotherpartial.html" . }}|
{{ partial "myinlinepartialinall.html" . }}|
{{ end }}
{{- define "_partials/myinlinepartialinall.html" }}
My inline partial in all.
{{ end }}
`
b := TestRunning(t, files)
b.AssertFileContent("public/index.html", "Mypartial.", "Mypartial Inline.|Foo")
// Edit inline partial in partial.
b.EditFileReplaceAll("layouts/_partials/mypartial.html", "Mypartial Inline.", "Mypartial Inline Edited.").Build()
b.AssertFileContent("public/index.html", "Mypartial Inline Edited.|Foo")
// Edit inline partial in baseof.
b.EditFileReplaceAll("layouts/baseof.html", "My inline partial in baseof.", "My inline partial in baseof Edited.").Build()
b.AssertFileContent("public/index.html", "My inline partial in baseof Edited.")
// Edit inline partial in all.
b.EditFileReplaceAll("layouts/all.html", "My inline partial in all.", "My inline partial in all Edited.").Build()
b.AssertFileContent("public/index.html", "My inline partial in all Edited.")
}
func TestRebuildEditAsciidocContentFile(t *testing.T) { func TestRebuildEditAsciidocContentFile(t *testing.T) {
if !asciidocext.Supports() { if !asciidocext.Supports() {
t.Skip("skip asciidoc") t.Skip("skip asciidoc")
@ -1892,3 +1946,23 @@ tags: ["tag1"]
// But that is a harder problem to tackle. // But that is a harder problem to tackle.
b.AssertFileContent("public/tags/index.html", "All. Tag1|Tag2|") b.AssertFileContent("public/tags/index.html", "All. Tag1|Tag2|")
} }
func TestRebuildEditNonReferencedResourceIssue13748(t *testing.T) {
t.Parallel()
files := `
-- hugo.toml --
baseURL = "https://example.com"
disableLiveReload = true
-- content/mybundle/index.md --
-- content/mybundle/resource.txt --
This is a resource file.
-- layouts/all.html --
All.
`
b := TestRunning(t, files)
b.AssertFileContent("public/mybundle/resource.txt", "This is a resource file.")
b.EditFileReplaceAll("content/mybundle/resource.txt", "This is a resource file.", "This is an edited resource file.").Build()
b.AssertFileContent("public/mybundle/resource.txt", "This is an edited resource file.")
}

View file

@ -204,6 +204,7 @@ func NewHugoSites(cfg deps.DepsCfg) (*HugoSites, error) {
// Katex is relatively slow. // Katex is relatively slow.
PoolSize: 8, PoolSize: 8,
Infof: logger.InfoCommand("wasm").Logf, Infof: logger.InfoCommand("wasm").Logf,
Warnf: logger.WarnCommand("wasm").Logf,
}, },
), ),
} }

View file

@ -16,7 +16,6 @@ package hugolib
import ( import (
"bytes" "bytes"
"fmt" "fmt"
"io"
"testing" "testing"
"github.com/gohugoio/hugo/helpers" "github.com/gohugoio/hugo/helpers"
@ -89,14 +88,11 @@ aliases: [/Ali%d]
h.Sites[1].PathSpec.ProcessingStats, h.Sites[1].PathSpec.ProcessingStats,
} }
stats[0].Table(io.Discard)
stats[1].Table(io.Discard)
var buff bytes.Buffer var buff bytes.Buffer
helpers.ProcessingStatsTable(&buff, stats...) helpers.ProcessingStatsTable(&buff, stats...)
c.Assert(buff.String(), qt.Contains, "Pages | 21 | 7") c.Assert(buff.String(), qt.Contains, "Pages │ 21 │ 7")
} }
func TestSiteLastmod(t *testing.T) { func TestSiteLastmod(t *testing.T) {

View file

@ -615,7 +615,7 @@ var weightedPage5 = `+++
weight = "5" weight = "5"
title = "Five" title = "Five"
[_build] [build]
render = "never" render = "never"
+++ +++
Front Matter with Ordered Pages 5` Front Matter with Ordered Pages 5`

View file

@ -1,7 +1,13 @@
# Release env. # Release env.
# These will be replaced by script before release. # These will be replaced by script before release.
HUGORELEASER_TAG=v0.147.3 HUGORELEASER_TAG=v0.147.9
HUGORELEASER_COMMITISH=05417512bd001c0b2cc0042dcc584575825b89b3 HUGORELEASER_COMMITISH=29bdbde19c288d190e889294a862103c6efb70bf

View file

@ -4,6 +4,15 @@ export function readInput(handle) {
let currentLine = []; let currentLine = [];
const buffer = new Uint8Array(buffSize); const buffer = new Uint8Array(buffSize);
// These are not implemented by QuickJS.
console.warn = (value) => {
console.log(value);
};
console.error = (value) => {
throw new Error(value);
};
// Read all the available bytes // Read all the available bytes
while (true) { while (true) {
// Stdin file descriptor // Stdin file descriptor

View file

@ -1,2 +1,2 @@
(()=>{function l(r){let e=[],a=new Uint8Array(1024);for(;;){let n=0;try{n=Javy.IO.readSync(0,a)}catch(o){if(o.message.includes("os error 29"))break;throw new Error("Error reading from stdin")}if(n<0)throw new Error("Error reading from stdin");if(n===0)break;if(e=[...e,...a.subarray(0,n)],!e.includes(10))continue;let t=0;for(let o=0;t<e.length;t++)if(e[t]===10){let w=e.splice(o,t+1),f=new Uint8Array(w),c;try{c=JSON.parse(new TextDecoder().decode(f))}catch(d){throw new Error(`Error parsing JSON '${new TextDecoder().decode(f)}' from stdin: ${d.message}`)}try{r(c)}catch(d){let u=c.header;u.err=d.message,i({header:u})}o=t+1}e=e.slice(t)}}function i(r){let s=new TextEncoder().encode(JSON.stringify(r)+` (()=>{function w(r){let e=[],c=new Uint8Array(1024);for(console.warn=n=>{console.log(n)},console.error=n=>{throw new Error(n)};;){let o=0;try{o=Javy.IO.readSync(0,c)}catch(a){if(a.message.includes("os error 29"))break;throw new Error("Error reading from stdin")}if(o<0)throw new Error("Error reading from stdin");if(o===0)break;if(e=[...e,...c.subarray(0,o)],!e.includes(10))continue;let t=0;for(let a=0;t<e.length;t++)if(e[t]===10){let h=e.splice(a,t+1),l=new Uint8Array(h),d;try{d=JSON.parse(new TextDecoder().decode(l))}catch(s){throw new Error(`Error parsing JSON '${new TextDecoder().decode(l)}' from stdin: ${s.message}`)}try{r(d)}catch(s){let u=d.header;u.err=s.message,i({header:u})}a=t+1}e=e.slice(t)}}function i(r){let f=new TextEncoder().encode(JSON.stringify(r)+`
`),e=new Uint8Array(s);Javy.IO.writeSync(1,e)}var h=function(r){i({header:r.header,data:{greeting:"Hello "+r.data.name+"!"}})};console.log("Greet module loaded");l(h);})(); `),e=new Uint8Array(f);Javy.IO.writeSync(1,e)}var g=function(r){i({header:r.header,data:{greeting:"Hello "+r.data.name+"!"}})};console.log("Greet module loaded");w(g);})();

File diff suppressed because one or more lines are too long

View file

@ -7,6 +7,16 @@ const render = function (input) {
const expression = data.expression; const expression = data.expression;
const options = data.options; const options = data.options;
const header = input.header; const header = input.header;
header.warnings = [];
if (options.strict == 'warn') {
// By default, KaTeX will write to console.warn, that's a little hard to handle.
options.strict = (errorCode, errorMsg) => {
header.warnings.push(
`katex: LaTeX-incompatible input and strict mode is set to 'warn': ${errorMsg} [${errorCode}]`,
);
};
}
// Any error thrown here will be caught by the common.js readInput function. // Any error thrown here will be caught by the common.js readInput function.
const output = katex.renderToString(expression, options); const output = katex.renderToString(expression, options);
writeOutput({ header: header, data: { output: output } }); writeOutput({ header: header, data: { output: output } });

View file

@ -53,6 +53,22 @@ type KatexOptions struct {
// If true, KaTeX will throw a ParseError when it encounters an unsupported command. // If true, KaTeX will throw a ParseError when it encounters an unsupported command.
ThrowOnError bool `json:"throwOnError"` ThrowOnError bool `json:"throwOnError"`
// Controls how KaTeX handles LaTeX features that offer convenience but
// aren't officially supported, one of error (default), ignore, or warn.
//
// - error: Throws an error when convenient, unsupported LaTeX features
// are encountered.
// - ignore: Allows convenient, unsupported LaTeX features without any
// feedback.
// - warn: Emits a warning when convenient, unsupported LaTeX features are
// encountered.
//
// The "newLineInDisplayMode" error code, which flags the use of \\
// or \newline in display mode outside an array or tabular environment, is
// intentionally designed not to throw an error, despite this behavior
// being questionable.
Strict string `json:"strict"`
} }
type KatexOutput struct { type KatexOutput struct {

View file

@ -51,6 +51,9 @@ type Header struct {
// Set in the response if there was an error. // Set in the response if there was an error.
Err string `json:"err"` Err string `json:"err"`
// Warnings is a list of warnings that may be returned in the response.
Warnings []string `json:"warnings,omitempty"`
} }
type Message[T any] struct { type Message[T any] struct {
@ -155,6 +158,7 @@ func (p *dispatcherPool[Q, R]) Execute(ctx context.Context, q Message[Q]) (Messa
} }
resp, err := call.response, p.Err() resp, err := call.response, p.Err()
if err == nil && resp.Header.Err != "" { if err == nil && resp.Header.Err != "" {
err = errors.New(resp.Header.Err) err = errors.New(resp.Header.Err)
} }
@ -270,6 +274,8 @@ type Options struct {
Infof func(format string, v ...any) Infof func(format string, v ...any)
Warnf func(format string, v ...any)
// E.g. quickjs wasm. May be omitted if not needed. // E.g. quickjs wasm. May be omitted if not needed.
Runtime Binary Runtime Binary
@ -325,6 +331,7 @@ type dispatcherPool[Q, R any] struct {
counter atomic.Uint32 counter atomic.Uint32
dispatchers []*dispatcher[Q, R] dispatchers []*dispatcher[Q, R]
close func() error close func() error
opts Options
errc chan error errc chan error
donec chan struct{} donec chan struct{}
@ -355,6 +362,11 @@ func newDispatcher[Q, R any](opts Options) (*dispatcherPool[Q, R], error) {
// noop // noop
} }
} }
if opts.Warnf == nil {
opts.Warnf = func(format string, v ...any) {
// noop
}
}
if opts.Memory <= 0 { if opts.Memory <= 0 {
// 32 MiB // 32 MiB
@ -466,6 +478,7 @@ func newDispatcher[Q, R any](opts Options) (*dispatcherPool[Q, R], error) {
dp := &dispatcherPool[Q, R]{ dp := &dispatcherPool[Q, R]{
dispatchers: make([]*dispatcher[Q, R], len(inOuts)), dispatchers: make([]*dispatcher[Q, R], len(inOuts)),
opts: opts,
errc: make(chan error, 10), errc: make(chan error, 10),
donec: make(chan struct{}), donec: make(chan struct{}),

Binary file not shown.

Binary file not shown.

View file

@ -104,7 +104,7 @@ func (i Item) ValTyped(source []byte) any {
} }
func (i Item) IsText() bool { func (i Item) IsText() bool {
return i.Type == tText || i.Type == tIndentation return i.Type == tText || i.IsIndentation()
} }
func (i Item) IsIndentation() bool { func (i Item) IsIndentation() bool {
@ -152,7 +152,7 @@ func (i Item) IsFrontMatter() bool {
} }
func (i Item) IsDone() bool { func (i Item) IsDone() bool {
return i.Type == tError || i.Type == tEOF return i.IsError() || i.IsEOF()
} }
func (i Item) IsEOF() bool { func (i Item) IsEOF() bool {
@ -166,18 +166,19 @@ func (i Item) IsError() bool {
func (i Item) ToString(source []byte) string { func (i Item) ToString(source []byte) string {
val := i.Val(source) val := i.Val(source)
switch { switch {
case i.Type == tEOF: case i.IsEOF():
return "EOF" return "EOF"
case i.Type == tError: case i.IsError():
return string(val) return string(val)
case i.Type == tIndentation: case i.IsIndentation():
return fmt.Sprintf("%s:[%s]", i.Type, util.VisualizeSpaces(val)) return fmt.Sprintf("%s:[%s]", i.Type, util.VisualizeSpaces(val))
case i.Type > tKeywordMarker: case i.Type > tKeywordMarker:
return fmt.Sprintf("<%s>", val) return fmt.Sprintf("<%s>", val)
case len(val) > 50: case len(val) > 50:
return fmt.Sprintf("%v:%.20q...", i.Type, val) return fmt.Sprintf("%v:%.20q...", i.Type, val)
} default:
return fmt.Sprintf("%v:[%s]", i.Type, val) return fmt.Sprintf("%v:[%s]", i.Type, val)
}
} }
type ItemType int type ItemType int

View file

@ -47,3 +47,217 @@ func TestItemValTyped(t *testing.T) {
source = []byte("xtrue") source = []byte("xtrue")
c.Assert(Item{low: 0, high: len(source)}.ValTyped(source), qt.Equals, "xtrue") c.Assert(Item{low: 0, high: len(source)}.ValTyped(source), qt.Equals, "xtrue")
} }
func TestItemBoolMethods(t *testing.T) {
c := qt.New(t)
source := []byte(" shortcode ")
tests := []struct {
name string
item Item
source []byte
want bool
call func(Item, []byte) bool
}{
{
name: "IsText true",
item: Item{Type: tText},
call: func(i Item, _ []byte) bool { return i.IsText() },
want: true,
},
{
name: "IsIndentation false",
item: Item{Type: tText},
call: func(i Item, _ []byte) bool { return i.IsIndentation() },
want: false,
},
{
name: "IsShortcodeName",
item: Item{Type: tScName},
call: func(i Item, _ []byte) bool { return i.IsShortcodeName() },
want: true,
},
{
name: "IsNonWhitespace true",
item: Item{
Type: tText,
low: 2,
high: 11,
},
source: source,
call: func(i Item, src []byte) bool { return i.IsNonWhitespace(src) },
want: true,
},
{
name: "IsShortcodeParam false",
item: Item{Type: tScParamVal},
call: func(i Item, _ []byte) bool { return i.IsShortcodeParam() },
want: false,
},
{
name: "IsInlineShortcodeName",
item: Item{Type: tScNameInline},
call: func(i Item, _ []byte) bool { return i.IsInlineShortcodeName() },
want: true,
},
{
name: "IsLeftShortcodeDelim tLeftDelimScWithMarkup",
item: Item{Type: tLeftDelimScWithMarkup},
call: func(i Item, _ []byte) bool { return i.IsLeftShortcodeDelim() },
want: true,
},
{
name: "IsLeftShortcodeDelim tLeftDelimScNoMarkup",
item: Item{Type: tLeftDelimScNoMarkup},
call: func(i Item, _ []byte) bool { return i.IsLeftShortcodeDelim() },
want: true,
},
{
name: "IsRightShortcodeDelim tRightDelimScWithMarkup",
item: Item{Type: tRightDelimScWithMarkup},
call: func(i Item, _ []byte) bool { return i.IsRightShortcodeDelim() },
want: true,
},
{
name: "IsRightShortcodeDelim tRightDelimScNoMarkup",
item: Item{Type: tRightDelimScNoMarkup},
call: func(i Item, _ []byte) bool { return i.IsRightShortcodeDelim() },
want: true,
},
{
name: "IsShortcodeClose",
item: Item{Type: tScClose},
call: func(i Item, _ []byte) bool { return i.IsShortcodeClose() },
want: true,
},
{
name: "IsShortcodeParamVal",
item: Item{Type: tScParamVal},
call: func(i Item, _ []byte) bool { return i.IsShortcodeParamVal() },
want: true,
},
{
name: "IsShortcodeMarkupDelimiter tLeftDelimScWithMarkup",
item: Item{Type: tLeftDelimScWithMarkup},
call: func(i Item, _ []byte) bool { return i.IsShortcodeMarkupDelimiter() },
want: true,
},
{
name: "IsShortcodeMarkupDelimiter tRightDelimScWithMarkup",
item: Item{Type: tRightDelimScWithMarkup},
call: func(i Item, _ []byte) bool { return i.IsShortcodeMarkupDelimiter() },
want: true,
},
{
name: "IsFrontMatter TypeFrontMatterYAML",
item: Item{Type: TypeFrontMatterYAML},
call: func(i Item, _ []byte) bool { return i.IsFrontMatter() },
want: true,
},
{
name: "IsFrontMatter TypeFrontMatterTOML",
item: Item{Type: TypeFrontMatterTOML},
call: func(i Item, _ []byte) bool { return i.IsFrontMatter() },
want: true,
},
{
name: "IsFrontMatter TypeFrontMatterJSON",
item: Item{Type: TypeFrontMatterJSON},
call: func(i Item, _ []byte) bool { return i.IsFrontMatter() },
want: true,
},
{
name: "IsFrontMatter TypeFrontMatterORG",
item: Item{Type: TypeFrontMatterORG},
call: func(i Item, _ []byte) bool { return i.IsFrontMatter() },
want: true,
},
{
name: "IsDone tError",
item: Item{Type: tError},
call: func(i Item, _ []byte) bool { return i.IsDone() },
want: true,
},
{
name: "IsDone tEOF",
item: Item{Type: tEOF},
call: func(i Item, _ []byte) bool { return i.IsDone() },
want: true,
},
{
name: "IsEOF",
item: Item{Type: tEOF},
call: func(i Item, _ []byte) bool { return i.IsEOF() },
want: true,
},
{
name: "IsError",
item: Item{Type: tError},
call: func(i Item, _ []byte) bool { return i.IsError() },
want: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got := tt.call(tt.item, tt.source)
c.Assert(got, qt.Equals, tt.want)
})
}
}
func TestItem_ToString(t *testing.T) {
c := qt.New(t)
source := []byte("src")
long := make([]byte, 100)
for i := range long {
long[i] = byte(i)
}
tests := []struct {
name string
item Item
source []byte
want string
call func(Item, []byte) string
}{
{
name: "EOF",
item: Item{Type: tEOF},
call: func(i Item, _ []byte) string { return i.ToString(source) },
want: "EOF",
},
{
name: "Error",
item: Item{Type: tError},
call: func(i Item, _ []byte) string { return i.ToString(source) },
want: "",
},
{
name: "Indentation",
item: Item{Type: tIndentation},
call: func(i Item, _ []byte) string { return i.ToString(source) },
want: "tIndentation:[]",
},
{
name: "Long",
item: Item{Type: tKeywordMarker + 1, low: 0, high: 100},
call: func(i Item, _ []byte) string { return i.ToString(long) },
want: "<" + string(long) + ">",
},
{
name: "Empty",
item: Item{Type: tKeywordMarker + 1},
call: func(i Item, _ []byte) string { return i.ToString([]byte("")) },
want: "<>",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got := tt.call(tt.item, tt.source)
c.Assert(got, qt.Equals, tt.want)
})
}
}

View file

@ -105,9 +105,9 @@ func CheckCascadePattern(logger loggers.Logger, m PageMatcher) {
} }
} }
func DecodeCascadeConfig(logger loggers.Logger, handleLegacyFormat bool, in any) (*config.ConfigNamespace[[]PageMatcherParamsConfig, *maps.Ordered[PageMatcher, maps.Params]], error) { func DecodeCascadeConfig(logger loggers.Logger, handleLegacyFormat bool, in any) (*config.ConfigNamespace[[]PageMatcherParamsConfig, *maps.Ordered[PageMatcher, PageMatcherParamsConfig]], error) {
buildConfig := func(in any) (*maps.Ordered[PageMatcher, maps.Params], any, error) { buildConfig := func(in any) (*maps.Ordered[PageMatcher, PageMatcherParamsConfig], any, error) {
cascade := maps.NewOrdered[PageMatcher, maps.Params]() cascade := maps.NewOrdered[PageMatcher, PageMatcherParamsConfig]()
if in == nil { if in == nil {
return cascade, []map[string]any{}, nil return cascade, []map[string]any{}, nil
} }
@ -124,11 +124,7 @@ func DecodeCascadeConfig(logger loggers.Logger, handleLegacyFormat bool, in any)
c PageMatcherParamsConfig c PageMatcherParamsConfig
err error err error
) )
if handleLegacyFormat {
c, err = mapToPageMatcherParamsConfigLegacy(m)
} else {
c, err = mapToPageMatcherParamsConfig(m) c, err = mapToPageMatcherParamsConfig(m)
}
if err != nil { if err != nil {
return nil, nil, err return nil, nil, err
} }
@ -147,23 +143,28 @@ func DecodeCascadeConfig(logger loggers.Logger, handleLegacyFormat bool, in any)
if found { if found {
// Merge // Merge
for k, v := range cfg.Params { for k, v := range cfg.Params {
if _, found := c[k]; !found { if _, found := c.Params[k]; !found {
c[k] = v c.Params[k] = v
}
}
for k, v := range cfg.Fields {
if _, found := c.Fields[k]; !found {
c.Fields[k] = v
} }
} }
} else { } else {
cascade.Set(m, cfg.Params) cascade.Set(m, cfg)
} }
} }
return cascade, cfgs, nil return cascade, cfgs, nil
} }
return config.DecodeNamespace[[]PageMatcherParamsConfig, *maps.Ordered[PageMatcher, maps.Params]](in, buildConfig) return config.DecodeNamespace[[]PageMatcherParamsConfig, *maps.Ordered[PageMatcher, PageMatcherParamsConfig]](in, buildConfig)
} }
// DecodeCascade decodes in which could be either a map or a slice of maps. // DecodeCascade decodes in which could be either a map or a slice of maps.
func DecodeCascade(logger loggers.Logger, handleLegacyFormat bool, in any) (*maps.Ordered[PageMatcher, maps.Params], error) { func DecodeCascade(logger loggers.Logger, handleLegacyFormat bool, in any) (*maps.Ordered[PageMatcher, PageMatcherParamsConfig], error) {
conf, err := DecodeCascadeConfig(logger, handleLegacyFormat, in) conf, err := DecodeCascadeConfig(logger, handleLegacyFormat, in)
if err != nil { if err != nil {
return nil, err return nil, err
@ -173,6 +174,9 @@ func DecodeCascade(logger loggers.Logger, handleLegacyFormat bool, in any) (*map
func mapToPageMatcherParamsConfig(m map[string]any) (PageMatcherParamsConfig, error) { func mapToPageMatcherParamsConfig(m map[string]any) (PageMatcherParamsConfig, error) {
var pcfg PageMatcherParamsConfig var pcfg PageMatcherParamsConfig
if pcfg.Fields == nil {
pcfg.Fields = make(maps.Params)
}
for k, v := range m { for k, v := range m {
switch strings.ToLower(k) { switch strings.ToLower(k) {
case "_target", "target": case "_target", "target":
@ -181,47 +185,19 @@ func mapToPageMatcherParamsConfig(m map[string]any) (PageMatcherParamsConfig, er
return pcfg, err return pcfg, err
} }
pcfg.Target = target pcfg.Target = target
default: case "params":
if pcfg.Params == nil { if pcfg.Params == nil {
pcfg.Params = make(maps.Params) pcfg.Params = make(maps.Params)
} }
pcfg.Params[k] = v
}
}
return pcfg, pcfg.init()
}
func mapToPageMatcherParamsConfigLegacy(m map[string]any) (PageMatcherParamsConfig, error) {
var pcfg PageMatcherParamsConfig
for k, v := range m {
switch strings.ToLower(k) {
case "params":
// We simplified the structure of the cascade config in Hugo 0.111.0.
// There is a small chance that someone has used the old structure with the params keyword,
// those values will now be moved to the top level.
// This should be very unlikely as it would lead to constructs like .Params.params.foo,
// and most people see params as an Hugo internal keyword.
params := maps.ToStringMap(v) params := maps.ToStringMap(v)
if pcfg.Params == nil {
pcfg.Params = params
} else {
for k, v := range params { for k, v := range params {
if _, found := pcfg.Params[k]; !found { if _, found := pcfg.Params[k]; !found {
pcfg.Params[k] = v pcfg.Params[k] = v
} }
} }
}
case "_target", "target":
var target PageMatcher
if err := decodePageMatcher(v, &target); err != nil {
return pcfg, err
}
pcfg.Target = target
default: default:
if pcfg.Params == nil {
pcfg.Params = make(maps.Params) pcfg.Fields[k] = v
}
pcfg.Params[k] = v
} }
} }
return pcfg, pcfg.init() return pcfg, pcfg.init()
@ -250,10 +226,14 @@ func decodePageMatcher(m any, v *PageMatcher) error {
type PageMatcherParamsConfig struct { type PageMatcherParamsConfig struct {
// Apply Params to all Pages matching Target. // Apply Params to all Pages matching Target.
Params maps.Params Params maps.Params
// Fields holds all fields but Params.
Fields maps.Params
// Target is the PageMatcher that this config applies to.
Target PageMatcher Target PageMatcher
} }
func (p *PageMatcherParamsConfig) init() error { func (p *PageMatcherParamsConfig) init() error {
maps.PrepareParams(p.Params) maps.PrepareParams(p.Params)
maps.PrepareParams(p.Fields)
return nil return nil
} }

View file

@ -84,23 +84,22 @@ func TestPageMatcher(t *testing.T) {
c.Run("mapToPageMatcherParamsConfig", func(c *qt.C) { c.Run("mapToPageMatcherParamsConfig", func(c *qt.C) {
fn := func(m map[string]any) PageMatcherParamsConfig { fn := func(m map[string]any) PageMatcherParamsConfig {
v, err := mapToPageMatcherParamsConfigLegacy(m) v, err := mapToPageMatcherParamsConfig(m)
c.Assert(err, qt.IsNil) c.Assert(err, qt.IsNil)
return v return v
} }
// Legacy.
c.Assert(fn(map[string]any{"_target": map[string]any{"kind": "page"}, "foo": "bar"}), qt.DeepEquals, PageMatcherParamsConfig{ c.Assert(fn(map[string]any{"_target": map[string]any{"kind": "page"}, "foo": "bar"}), qt.DeepEquals, PageMatcherParamsConfig{
Params: maps.Params{ Fields: maps.Params{
"foo": "bar", "foo": "bar",
}, },
Target: PageMatcher{Path: "", Kind: "page", Lang: "", Environment: ""}, Target: PageMatcher{Path: "", Kind: "page", Lang: "", Environment: ""},
}) })
// Current format.
c.Assert(fn(map[string]any{"target": map[string]any{"kind": "page"}, "params": map[string]any{"foo": "bar"}}), qt.DeepEquals, PageMatcherParamsConfig{ c.Assert(fn(map[string]any{"target": map[string]any{"kind": "page"}, "params": map[string]any{"foo": "bar"}}), qt.DeepEquals, PageMatcherParamsConfig{
Params: maps.Params{ Params: maps.Params{
"foo": "bar", "foo": "bar",
}, },
Fields: maps.Params{},
Target: PageMatcher{Path: "", Kind: "page", Lang: "", Environment: ""}, Target: PageMatcher{Path: "", Kind: "page", Lang: "", Environment: ""},
}) })
}) })
@ -134,13 +133,14 @@ func TestDecodeCascadeConfig(t *testing.T) {
c.Assert(err, qt.IsNil) c.Assert(err, qt.IsNil)
c.Assert(got, qt.IsNotNil) c.Assert(got, qt.IsNotNil)
c.Assert(got.Config.Keys(), qt.DeepEquals, []PageMatcher{{Kind: "page", Environment: "production"}, {Kind: "page"}}) c.Assert(got.Config.Keys(), qt.DeepEquals, []PageMatcher{{Kind: "page", Environment: "production"}, {Kind: "page"}})
c.Assert(got.Config.Values(), qt.DeepEquals, []maps.Params{{"a": string("av")}, {"b": string("bv")}})
c.Assert(got.SourceStructure, qt.DeepEquals, []PageMatcherParamsConfig{ c.Assert(got.SourceStructure, qt.DeepEquals, []PageMatcherParamsConfig{
{ {
Params: maps.Params{"a": string("av")}, Params: maps.Params{"a": string("av")},
Fields: maps.Params{},
Target: PageMatcher{Kind: "page", Environment: "production"}, Target: PageMatcher{Kind: "page", Environment: "production"},
}, },
{Params: maps.Params{"b": string("bv")}, Target: PageMatcher{Kind: "page"}}, {Params: maps.Params{"b": string("bv")}, Fields: maps.Params{}, Target: PageMatcher{Kind: "page"}},
}) })
got, err = DecodeCascadeConfig(loggers.NewDefault(), true, nil) got, err = DecodeCascadeConfig(loggers.NewDefault(), true, nil)

View file

@ -125,7 +125,7 @@ type PageConfig struct {
ContentAdapterData map[string]any `mapstructure:"-" json:"-"` ContentAdapterData map[string]any `mapstructure:"-" json:"-"`
// Compiled values. // Compiled values.
CascadeCompiled *maps.Ordered[page.PageMatcher, maps.Params] `mapstructure:"-" json:"-"` CascadeCompiled *maps.Ordered[page.PageMatcher, page.PageMatcherParamsConfig] `mapstructure:"-" json:"-"`
ContentMediaType media.Type `mapstructure:"-" json:"-"` ContentMediaType media.Type `mapstructure:"-" json:"-"`
ConfiguredOutputFormats output.Formats `mapstructure:"-" json:"-"` ConfiguredOutputFormats output.Formats `mapstructure:"-" json:"-"`
IsFromContentAdapter bool `mapstructure:"-" json:"-"` IsFromContentAdapter bool `mapstructure:"-" json:"-"`

View file

@ -31,7 +31,7 @@ func TestDecodeBuildConfig(t *testing.T) {
c := qt.New(t) c := qt.New(t)
configTempl := ` configTempl := `
[_build] [build]
render = %s render = %s
list = %s list = %s
publishResources = true` publishResources = true`
@ -82,7 +82,7 @@ publishResources = true`
} { } {
cfg, err := config.FromConfigString(fmt.Sprintf(configTempl, test.args...), "toml") cfg, err := config.FromConfigString(fmt.Sprintf(configTempl, test.args...), "toml")
c.Assert(err, qt.IsNil) c.Assert(err, qt.IsNil)
bcfg, err := DecodeBuildConfig(cfg.Get("_build")) bcfg, err := DecodeBuildConfig(cfg.Get("build"))
c.Assert(err, qt.IsNil) c.Assert(err, qt.IsNil)
eq := qt.CmpEquals(hqt.DeepAllowUnexported(BuildConfig{})) eq := qt.CmpEquals(hqt.DeepAllowUnexported(BuildConfig{}))

View file

@ -311,7 +311,7 @@ func (l PermalinkExpander) pageToPermalinkSections(p Page, _ string) (string, er
// pageToPermalinkContentBaseName returns the URL-safe form of the content base name. // pageToPermalinkContentBaseName returns the URL-safe form of the content base name.
func (l PermalinkExpander) pageToPermalinkContentBaseName(p Page, _ string) (string, error) { func (l PermalinkExpander) pageToPermalinkContentBaseName(p Page, _ string) (string, error) {
return l.urlize(p.PathInfo().BaseNameNoIdentifier()), nil return l.urlize(p.PathInfo().Unnormalized().BaseNameNoIdentifier()), nil
} }
// pageToPermalinkSlugOrContentBaseName returns the URL-safe form of the slug, content base name. // pageToPermalinkSlugOrContentBaseName returns the URL-safe form of the slug, content base name.

View file

@ -14,6 +14,7 @@
package page_test package page_test
import ( import (
"strings"
"testing" "testing"
"github.com/bep/logg" "github.com/bep/logg"
@ -343,3 +344,29 @@ slug: "c2slug"
b.AssertFileContent("public/myc/c1/index.html", "C1|/myc/c1/|term|") b.AssertFileContent("public/myc/c1/index.html", "C1|/myc/c1/|term|")
b.AssertFileContent("public/myc/c2slug/index.html", "C2|/myc/c2slug/|term|") b.AssertFileContent("public/myc/c2slug/index.html", "C2|/myc/c2slug/|term|")
} }
func TestIssue13755(t *testing.T) {
t.Parallel()
files := `
-- hugo.toml --
disableKinds = ['home','rss','section','sitemap','taxonomy','term']
disablePathToLower = false
[permalinks.page]
s1 = "/:contentbasename"
-- content/s1/aBc.md --
---
title: aBc
---
-- layouts/all.html --
{{ .Title }}
`
b := hugolib.Test(t, files)
b.AssertFileExists("public/abc/index.html", true)
files = strings.ReplaceAll(files, "disablePathToLower = false", "disablePathToLower = true")
b = hugolib.Test(t, files)
b.AssertFileExists("public/aBc/index.html", true)
}

View file

@ -24,6 +24,7 @@ import (
"sync/atomic" "sync/atomic"
"github.com/gohugoio/hugo/identity" "github.com/gohugoio/hugo/identity"
"github.com/gohugoio/hugo/lazy"
"github.com/gohugoio/hugo/resources/internal" "github.com/gohugoio/hugo/resources/internal"
"github.com/gohugoio/hugo/common/hashing" "github.com/gohugoio/hugo/common/hashing"
@ -54,6 +55,7 @@ var (
_ identity.DependencyManagerProvider = (*genericResource)(nil) _ identity.DependencyManagerProvider = (*genericResource)(nil)
_ identity.Identity = (*genericResource)(nil) _ identity.Identity = (*genericResource)(nil)
_ fileInfo = (*genericResource)(nil) _ fileInfo = (*genericResource)(nil)
_ isPublishedProvider = (*genericResource)(nil)
) )
type ResourceSourceDescriptor struct { type ResourceSourceDescriptor struct {
@ -242,6 +244,7 @@ type baseResourceInternal interface {
fileInfo fileInfo
mediaTypeAssigner mediaTypeAssigner
targetPather targetPather
isPublishedProvider
ReadSeekCloser() (hugio.ReadSeekCloser, error) ReadSeekCloser() (hugio.ReadSeekCloser, error)
@ -355,7 +358,7 @@ func GetTestInfoForResource(r resource.Resource) GenericResourceTestInfo {
// genericResource represents a generic linkable resource. // genericResource represents a generic linkable resource.
type genericResource struct { type genericResource struct {
publishInit *sync.Once publishInit *lazy.OnceMore
key string key string
keyInit *sync.Once keyInit *sync.Once
@ -536,6 +539,10 @@ func (l *genericResource) Publish() error {
return err return err
} }
func (l *genericResource) isPublished() bool {
return l.publishInit.Done()
}
func (l *genericResource) RelPermalink() string { func (l *genericResource) RelPermalink() string {
return l.spec.PathSpec.GetBasePath(false) + paths.PathEscape(l.paths.TargetLink()) return l.spec.PathSpec.GetBasePath(false) + paths.PathEscape(l.paths.TargetLink())
} }
@ -629,7 +636,7 @@ func (rc *genericResource) cloneWithUpdates(u *transformationUpdate) (baseResour
} }
func (l genericResource) clone() *genericResource { func (l genericResource) clone() *genericResource {
l.publishInit = &sync.Once{} l.publishInit = &lazy.OnceMore{}
l.keyInit = &sync.Once{} l.keyInit = &sync.Once{}
return &l return &l
} }
@ -643,6 +650,10 @@ type targetPather interface {
TargetPath() string TargetPath() string
} }
type isPublishedProvider interface {
isPublished() bool
}
type resourceHash struct { type resourceHash struct {
value uint64 value uint64
size int64 size int64
@ -702,6 +713,11 @@ func InternalResourceSourcePathBestEffort(r resource.Resource) string {
return InternalResourceTargetPath(r) return InternalResourceTargetPath(r)
} }
// isPublished returns true if the resource is published.
func IsPublished(r resource.Resource) bool {
return r.(isPublishedProvider).isPublished()
}
type targetPathProvider interface { type targetPathProvider interface {
// targetPath is the relative path to this resource. // targetPath is the relative path to this resource.
// In most cases this will be the same as the RelPermalink(), // In most cases this will be the same as the RelPermalink(),

View file

@ -81,11 +81,6 @@ type ResourceWithoutMeta interface {
ResourceDataProvider ResourceDataProvider
} }
type ResourceWrapper interface {
UnwrappedResource() Resource
WrapResource(Resource) ResourceWrapper
}
type ResourceTypeProvider interface { type ResourceTypeProvider interface {
// ResourceType is the resource type. For most file types, this is the main // ResourceType is the resource type. For most file types, this is the main
// part of the MIME type, e.g. "image", "application", "text" etc. // part of the MIME type, e.g. "image", "application", "text" etc.

View file

@ -20,6 +20,7 @@ import (
"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/lazy"
"github.com/gohugoio/hugo/output" "github.com/gohugoio/hugo/output"
"github.com/gohugoio/hugo/resources/internal" "github.com/gohugoio/hugo/resources/internal"
"github.com/gohugoio/hugo/resources/jsconfig" "github.com/gohugoio/hugo/resources/jsconfig"
@ -189,7 +190,7 @@ func (r *Spec) NewResource(rd ResourceSourceDescriptor) (resource.Resource, erro
gr := &genericResource{ gr := &genericResource{
Staler: &AtomicStaler{}, Staler: &AtomicStaler{},
h: &resourceHash{}, h: &resourceHash{},
publishInit: &sync.Once{}, publishInit: &lazy.OnceMore{},
keyInit: &sync.Once{}, keyInit: &sync.Once{},
includeHashInKey: isImage, includeHashInKey: isImage,
paths: rp, paths: rp,

View file

@ -61,6 +61,7 @@ var (
_ identity.DependencyManagerProvider = (*resourceAdapter)(nil) _ identity.DependencyManagerProvider = (*resourceAdapter)(nil)
_ identity.IdentityGroupProvider = (*resourceAdapter)(nil) _ identity.IdentityGroupProvider = (*resourceAdapter)(nil)
_ resource.NameNormalizedProvider = (*resourceAdapter)(nil) _ resource.NameNormalizedProvider = (*resourceAdapter)(nil)
_ isPublishedProvider = (*resourceAdapter)(nil)
) )
// These are transformations that need special support in Hugo that may not // These are transformations that need special support in Hugo that may not
@ -325,6 +326,11 @@ func (r *resourceAdapter) Publish() error {
return r.target.Publish() return r.target.Publish()
} }
func (r *resourceAdapter) isPublished() bool {
r.init(false, false)
return r.target.isPublished()
}
func (r *resourceAdapter) ReadSeekCloser() (hugio.ReadSeekCloser, error) { func (r *resourceAdapter) ReadSeekCloser() (hugio.ReadSeekCloser, error) {
r.init(false, false) r.init(false, false)
return r.target.ReadSeekCloser() return r.target.ReadSeekCloser()

View file

@ -15,6 +15,7 @@ package template
import ( import (
"fmt" "fmt"
"iter"
"github.com/gohugoio/hugo/common/types" "github.com/gohugoio/hugo/common/types"
template "github.com/gohugoio/hugo/tpl/internal/go_templates/texttemplate" template "github.com/gohugoio/hugo/tpl/internal/go_templates/texttemplate"
@ -38,6 +39,19 @@ func (t *Template) Prepare() (*template.Template, error) {
return t.text, nil return t.text, nil
} }
func (t *Template) All() iter.Seq[*Template] {
return func(yield func(t *Template) bool) {
ns := t.nameSpace
ns.mu.Lock()
defer ns.mu.Unlock()
for _, v := range ns.set {
if !yield(v) {
return
}
}
}
}
// See https://github.com/golang/go/issues/5884 // See https://github.com/golang/go/issues/5884
func StripTags(html string) string { func StripTags(html string) string {
return stripTags(html) return stripTags(html)

View file

@ -17,6 +17,7 @@ import (
"context" "context"
"fmt" "fmt"
"io" "io"
"iter"
"reflect" "reflect"
"github.com/gohugoio/hugo/common/herrors" "github.com/gohugoio/hugo/common/herrors"
@ -433,3 +434,18 @@ func (s *state) evalCall(dot, fun reflect.Value, isBuiltin bool, node parse.Node
func isTrue(val reflect.Value) (truth, ok bool) { func isTrue(val reflect.Value) (truth, ok bool) {
return hreflect.IsTruthfulValue(val), true return hreflect.IsTruthfulValue(val), true
} }
func (t *Template) All() iter.Seq[*Template] {
return func(yield func(t *Template) bool) {
if t.common == nil {
return
}
t.muTmpl.RLock()
defer t.muTmpl.RUnlock()
for _, v := range t.tmpl {
if !yield(v) {
return
}
}
}
}

View file

@ -533,7 +533,7 @@ func (t *Tree) parseControl(context string) (pos Pos, line int, pipe *PipeNode,
t.rangeDepth-- t.rangeDepth--
} }
switch next.Type() { switch next.Type() {
case nodeEnd: //done case nodeEnd: // done
case nodeElse: case nodeElse:
// Special case for "else if" and "else with". // Special case for "else if" and "else with".
// If the "else" is followed immediately by an "if" or "with", // If the "else" is followed immediately by an "if" or "with",

View file

@ -258,7 +258,7 @@ func TestMod(t *testing.T) {
{int32(3), int32(2), int64(1)}, {int32(3), int32(2), int64(1)},
{int64(3), int64(2), int64(1)}, {int64(3), int64(2), int64(1)},
{"3", "2", int64(1)}, {"3", "2", int64(1)},
{"3.1", "2", false}, {"3.1", "2", int64(1)},
{"aaa", "0", false}, {"aaa", "0", false},
{"3", "aaa", false}, {"3", "aaa", false},
} { } {
@ -304,7 +304,7 @@ func TestModBool(t *testing.T) {
{int64(3), int64(2), false}, {int64(3), int64(2), false},
{"3", "3", true}, {"3", "3", true},
{"3", "2", false}, {"3", "2", false},
{"3.1", "2", nil}, {"3.1", "2", false},
{"aaa", "0", nil}, {"aaa", "0", nil},
{"3", "aaa", nil}, {"3", "aaa", nil},
} { } {

View file

@ -133,7 +133,7 @@ func (ns *Namespace) lookup(name string) (*tplimpl.TemplInfo, error) {
if strings.HasPrefix(name, "partials/") { if strings.HasPrefix(name, "partials/") {
// This is most likely not what the user intended. // This is most likely not what the user intended.
// This worked before Hugo 0.146.0. // This worked before Hugo 0.146.0.
ns.deps.Log.Warnidf(constants.WarnPartialSuperfluousPrefix, "Partial name %q starting with 'partials/' (as in {{ partial \"%s\"}}) is most likely not what you want. Before 0.146.0 we did a double lookup in this situation.", name, name) ns.deps.Log.Warnidf(constants.WarnPartialSuperfluousPrefix, "Doubtful use of partial function in {{ partial \"%s\"}}), this is most likely not what you want. Consider removing superfluous prefix \"partials/\" from template name given as first function argument.", name)
} }
v := ns.deps.TemplateStore.LookupPartial(name) v := ns.deps.TemplateStore.LookupPartial(name)
if v == nil { if v == nil {

View file

@ -20,7 +20,7 @@
{{- $request := printf "https://publish.twitter.com/oembed?%s" $query -}} {{- $request := printf "https://publish.twitter.com/oembed?%s" $query -}}
{{- with try (resources.GetRemote $request) -}} {{- with try (resources.GetRemote $request) -}}
{{- with .Err -}} {{- with .Err -}}
{{- errorf "%s" . -}} {{- warnidf "shortcode-twitter-getremote" "The %q shortcode was unable to retrieve the remote data: %s. See %s" $.ctx.Name . $.ctx.Position -}}
{{- else with .Value -}} {{- else with .Value -}}
{{- (. | transform.Unmarshal).html | safeHTML -}} {{- (. | transform.Unmarshal).html | safeHTML -}}
{{- else -}} {{- else -}}

View file

@ -16,7 +16,7 @@
{{- $request := printf "https://publish.twitter.com/oembed?%s" $query -}} {{- $request := printf "https://publish.twitter.com/oembed?%s" $query -}}
{{- with try (resources.GetRemote $request) -}} {{- with try (resources.GetRemote $request) -}}
{{- with .Err -}} {{- with .Err -}}
{{- errorf "%s" . -}} {{- warnidf "shortcode-twitter-simple-getremote" "The %q shortcode was unable to retrieve the remote data: %s. See %s" $.ctx.Name . $.ctx.Position -}}
{{- else with .Value -}} {{- else with .Value -}}
{{- if not site.Config.Services.Twitter.DisableInlineCSS }} {{- if not site.Config.Services.Twitter.DisableInlineCSS }}
{{- template "__h_simple_twitter_css" (dict "ctx" $.ctx) }} {{- template "__h_simple_twitter_css" (dict "ctx" $.ctx) }}

View file

@ -25,7 +25,7 @@
{{- $request := printf "https://vimeo.com/api/oembed.json?%s" $query -}} {{- $request := printf "https://vimeo.com/api/oembed.json?%s" $query -}}
{{- with try (resources.GetRemote $request) -}} {{- with try (resources.GetRemote $request) -}}
{{- with .Err -}} {{- with .Err -}}
{{- errorf "%s" . -}} {{- warnidf "shortcode-vimeo-simple" "The %q shortcode was unable to retrieve the remote data: %s. See %s" $.ctx.Name . $.ctx.Position -}}
{{- else with .Value -}} {{- else with .Value -}}
{{- with . | transform.Unmarshal -}} {{- with . | transform.Unmarshal -}}
{{- $class := printf "%s %s" "s_video_simple" "__h_video" -}} {{- $class := printf "%s %s" "s_video_simple" "__h_video" -}}

View file

@ -19,7 +19,7 @@
{{- $request := printf "https://publish.x.com/oembed?%s" $query -}} {{- $request := printf "https://publish.x.com/oembed?%s" $query -}}
{{- with try (resources.GetRemote $request) -}} {{- with try (resources.GetRemote $request) -}}
{{- with .Err -}} {{- with .Err -}}
{{- errorf "%s" . -}} {{- warnidf "shortcode-x-getremote" "The %q shortcode was unable to retrieve the remote data: %s. See %s" $.ctx.Name . $.ctx.Position -}}
{{- else with .Value -}} {{- else with .Value -}}
{{- (. | transform.Unmarshal).html | safeHTML -}} {{- (. | transform.Unmarshal).html | safeHTML -}}
{{- else -}} {{- else -}}

View file

@ -15,7 +15,7 @@
{{- $request := printf "https://publish.x.com/oembed?%s" $query -}} {{- $request := printf "https://publish.x.com/oembed?%s" $query -}}
{{- with try (resources.GetRemote $request) -}} {{- with try (resources.GetRemote $request) -}}
{{- with .Err -}} {{- with .Err -}}
{{- errorf "%s" . -}} {{- warnidf "shortcode-x-simple-getremote" "The %q shortcode was unable to retrieve the remote data: %s. See %s" $.ctx.Name . $.ctx.Position -}}
{{- else with .Value -}} {{- else with .Value -}}
{{- if not site.Config.Services.X.DisableInlineCSS }} {{- if not site.Config.Services.X.DisableInlineCSS }}
{{- template "__h_simple_x_css" (dict "ctx" $.ctx) }} {{- template "__h_simple_x_css" (dict "ctx" $.ctx) }}

View file

@ -730,16 +730,16 @@ SHORTCODE
b.Assert(err.Error(), qt.Contains, `no compatible template found for shortcode "mymarkdown" in [/_shortcodes/mymarkdown.md]; note that to use plain text template shortcodes in HTML you need to use the shortcode {{% delimiter`) b.Assert(err.Error(), qt.Contains, `no compatible template found for shortcode "mymarkdown" in [/_shortcodes/mymarkdown.md]; note that to use plain text template shortcodes in HTML you need to use the shortcode {{% delimiter`)
} }
func TestShortcodeOnlyLanguageInBaseIssue13699(t *testing.T) { func TestShortcodeOnlyLanguageInBaseIssue13699And13740(t *testing.T) {
t.Parallel() t.Parallel()
files := ` files := `
-- hugo.toml -- -- hugo.toml --
baseURL = 'https://example.org/' baseURL = 'https://example.org/'
disableLanguages = ['de']
[languages] [languages]
[languages.en] [languages.en]
weight = 1 weight = 1
disableLanguages = ['de']
[languages.de] [languages.de]
weight = 2 weight = 2
-- layouts/_shortcodes/de.html -- -- layouts/_shortcodes/de.html --
@ -757,3 +757,40 @@ title: home
b.AssertFileContent("public/index.html", "de.html") b.AssertFileContent("public/index.html", "de.html")
} }
func TestShortcodeLanguage13767(t *testing.T) {
t.Parallel()
files := `
-- hugo.toml --
defaultContentLanguage = 'pl'
defaultContentLanguageInSubdir = true
[languages.pl]
weight = 1
[languages.en]
weight = 2
-- content/_index.md --
---
title: dom
---
{{< myshortcode >}}
-- content/_index.en.md --
---
title: home
---
{{< myshortcode >}}
-- layouts/_shortcodes/myshortcode.html --
myshortcode.html
-- layouts/_shortcodes/myshortcode.en.html --
myshortcode.en.html
-- layouts/all.html --
{{ .Content }}
`
b := hugolib.Test(t, files)
b.AssertFileContent("public/pl/index.html", "myshortcode.html")
b.AssertFileContent("public/en/index.html", "myshortcode.en.html")
}

View file

@ -2,6 +2,7 @@ package tplimpl
import ( import (
"io" "io"
"iter"
"regexp" "regexp"
"strconv" "strconv"
"strings" "strings"
@ -44,16 +45,15 @@ var embeddedTemplatesAliases = map[string][]string{
"_shortcodes/twitter.html": {"_shortcodes/tweet.html"}, "_shortcodes/twitter.html": {"_shortcodes/tweet.html"},
} }
func (s *TemplateStore) parseTemplate(ti *TemplInfo) error { func (s *TemplateStore) parseTemplate(ti *TemplInfo, replace bool) error {
err := s.tns.doParseTemplate(ti) err := s.tns.doParseTemplate(ti, replace)
if err != nil { if err != nil {
return s.addFileContext(ti, "parse of template failed", err) return s.addFileContext(ti, "parse of template failed", err)
} }
return err return err
} }
func (t *templateNamespace) doParseTemplate(ti *TemplInfo) error { func (t *templateNamespace) doParseTemplate(ti *TemplInfo, replace bool) error {
if !ti.noBaseOf || ti.category == CategoryBaseof { if !ti.noBaseOf || ti.category == CategoryBaseof {
// Delay parsing until we have the base template. // Delay parsing until we have the base template.
return nil return nil
@ -68,7 +68,7 @@ func (t *templateNamespace) doParseTemplate(ti *TemplInfo) error {
if ti.D.IsPlainText { if ti.D.IsPlainText {
prototype := t.parseText prototype := t.parseText
if prototype.Lookup(name) != nil { if !replace && prototype.Lookup(name) != nil {
name += "-" + strconv.FormatUint(t.nameCounter.Add(1), 10) name += "-" + strconv.FormatUint(t.nameCounter.Add(1), 10)
} }
templ, err = prototype.New(name).Parse(ti.content) templ, err = prototype.New(name).Parse(ti.content)
@ -77,7 +77,7 @@ func (t *templateNamespace) doParseTemplate(ti *TemplInfo) error {
} }
} else { } else {
prototype := t.parseHTML prototype := t.parseHTML
if prototype.Lookup(name) != nil { if !replace && prototype.Lookup(name) != nil {
name += "-" + strconv.FormatUint(t.nameCounter.Add(1), 10) name += "-" + strconv.FormatUint(t.nameCounter.Add(1), 10)
} }
templ, err = prototype.New(name).Parse(ti.content) templ, err = prototype.New(name).Parse(ti.content)
@ -181,19 +181,24 @@ func (t *templateNamespace) applyBaseTemplate(overlay *TemplInfo, base keyTempla
return nil return nil
} }
func (t *templateNamespace) templatesIn(in tpl.Template) []tpl.Template { func (t *templateNamespace) templatesIn(in tpl.Template) iter.Seq[tpl.Template] {
var templs []tpl.Template return func(yield func(t tpl.Template) bool) {
if textt, ok := in.(*texttemplate.Template); ok { switch in := in.(type) {
for _, t := range textt.Templates() { case *htmltemplate.Template:
templs = append(templs, t) for t := range in.All() {
if !yield(t) {
return
}
}
case *texttemplate.Template:
for t := range in.All() {
if !yield(t) {
return
} }
} }
if htmlt, ok := in.(*htmltemplate.Template); ok {
for _, t := range htmlt.Templates() {
templs = append(templs, t)
} }
} }
return templs
} }
/* /*
@ -337,8 +342,6 @@ func (t *templateNamespace) createPrototypes(init bool) error {
t.prototypeHTML = htmltemplate.Must(t.parseHTML.Clone()) t.prototypeHTML = htmltemplate.Must(t.parseHTML.Clone())
t.prototypeText = texttemplate.Must(t.parseText.Clone()) t.prototypeText = texttemplate.Must(t.parseText.Clone())
} }
// t.execHTML = htmltemplate.Must(t.parseHTML.Clone())
// t.execText = texttemplate.Must(t.parseText.Clone())
return nil return nil
} }
@ -350,3 +353,14 @@ func newTemplateNamespace(funcs map[string]any) *templateNamespace {
standaloneText: texttemplate.New("").Funcs(funcs), standaloneText: texttemplate.New("").Funcs(funcs),
} }
} }
func isText(t tpl.Template) bool {
switch t.(type) {
case *texttemplate.Template:
return true
case *htmltemplate.Template:
return false
default:
panic("unknown template type")
}
}

View file

@ -125,6 +125,7 @@ func NewStore(opts StoreOptions, siteOpts SiteOptions) (*TemplateStore, error) {
templatesByPath: maps.NewCache[string, *TemplInfo](), templatesByPath: maps.NewCache[string, *TemplInfo](),
shortcodesByName: maps.NewCache[string, *TemplInfo](), shortcodesByName: maps.NewCache[string, *TemplInfo](),
cacheLookupPartials: maps.NewCache[string, *TemplInfo](), cacheLookupPartials: maps.NewCache[string, *TemplInfo](),
templatesSnapshotSet: maps.NewCache[*parse.Tree, struct{}](),
// Note that the funcs passed below is just for name validation. // Note that the funcs passed below is just for name validation.
tns: newTemplateNamespace(siteOpts.TemplateFuncs), tns: newTemplateNamespace(siteOpts.TemplateFuncs),
@ -143,10 +144,10 @@ func NewStore(opts StoreOptions, siteOpts SiteOptions) (*TemplateStore, error) {
if err := s.insertEmbedded(); err != nil { if err := s.insertEmbedded(); err != nil {
return nil, err return nil, err
} }
if err := s.parseTemplates(); err != nil { if err := s.parseTemplates(false); err != nil {
return nil, err return nil, err
} }
if err := s.extractInlinePartials(); err != nil { if err := s.extractInlinePartials(false); err != nil {
return nil, err return nil, err
} }
if err := s.transformTemplates(); err != nil { if err := s.transformTemplates(); err != nil {
@ -428,6 +429,7 @@ type TemplateStore struct {
treeShortcodes *doctree.SimpleTree[map[string]map[TemplateDescriptor]*TemplInfo] treeShortcodes *doctree.SimpleTree[map[string]map[TemplateDescriptor]*TemplInfo]
templatesByPath *maps.Cache[string, *TemplInfo] templatesByPath *maps.Cache[string, *TemplInfo]
shortcodesByName *maps.Cache[string, *TemplInfo] shortcodesByName *maps.Cache[string, *TemplInfo]
templatesSnapshotSet *maps.Cache[*parse.Tree, struct{}]
dh descriptorHandler dh descriptorHandler
@ -709,12 +711,16 @@ func (s *TemplateStore) RefreshFiles(include func(fi hugofs.FileMetaInfo) bool)
if err := s.insertTemplates(include, true); err != nil { if err := s.insertTemplates(include, true); err != nil {
return err return err
} }
if err := s.parseTemplates(); err != nil { if err := s.createTemplatesSnapshot(); err != nil {
return err return err
} }
if err := s.extractInlinePartials(); err != nil { if err := s.parseTemplates(true); err != nil {
return err return err
} }
if err := s.extractInlinePartials(true); err != nil {
return err
}
if err := s.transformTemplates(); err != nil { if err := s.transformTemplates(); err != nil {
return err return err
} }
@ -940,19 +946,21 @@ func (s *TemplateStore) extractIdentifiers(line string) []string {
return identifiers return identifiers
} }
func (s *TemplateStore) extractInlinePartials() error { func (s *TemplateStore) extractInlinePartials(rebuild bool) error {
isPartialName := func(s string) bool { isPartialName := func(s string) bool {
return strings.HasPrefix(s, "partials/") || strings.HasPrefix(s, "_partials/") return strings.HasPrefix(s, "partials/") || strings.HasPrefix(s, "_partials/")
} }
p := s.tns
// We may find both inline and external partials in the current template namespaces, // We may find both inline and external partials in the current template namespaces,
// so only add the ones we have not seen before. // so only add the ones we have not seen before.
addIfNotSeen := func(isText bool, templs ...tpl.Template) error { for templ := range s.allRawTemplates() {
for _, templ := range templs {
if templ.Name() == "" || !isPartialName(templ.Name()) { if templ.Name() == "" || !isPartialName(templ.Name()) {
continue continue
} }
if rebuild && s.templatesSnapshotSet.Contains(getParseTree(templ)) {
// This partial was not created during this build.
continue
}
name := templ.Name() name := templ.Name()
if !paths.HasExt(name) { if !paths.HasExt(name) {
// Assume HTML. This in line with how the lookup works. // Assume HTML. This in line with how the lookup works.
@ -962,7 +970,7 @@ func (s *TemplateStore) extractInlinePartials() error {
name = "_" + name name = "_" + name
} }
pi := s.opts.PathParser.Parse(files.ComponentFolderLayouts, name) pi := s.opts.PathParser.Parse(files.ComponentFolderLayouts, name)
ti, err := s.insertTemplate(pi, nil, false, s.treeMain) ti, err := s.insertTemplate(pi, nil, SubCategoryInline, false, s.treeMain)
if err != nil { if err != nil {
return err return err
} }
@ -971,30 +979,46 @@ func (s *TemplateStore) extractInlinePartials() error {
ti.Template = templ ti.Template = templ
ti.noBaseOf = true ti.noBaseOf = true
ti.subCategory = SubCategoryInline ti.subCategory = SubCategoryInline
ti.D.IsPlainText = isText ti.D.IsPlainText = isText(templ)
}
} }
}
return nil
}
addIfNotSeen(false, p.templatesIn(p.parseHTML)...)
addIfNotSeen(true, p.templatesIn(p.parseText)...)
for _, t := range p.baseofHtmlClones {
if err := addIfNotSeen(false, p.templatesIn(t)...); err != nil {
return err
}
}
for _, t := range p.baseofTextClones {
if err := addIfNotSeen(true, p.templatesIn(t)...); err != nil {
return err
}
}
return nil return nil
} }
func (s *TemplateStore) allRawTemplates() iter.Seq[tpl.Template] {
p := s.tns
return func(yield func(tpl.Template) bool) {
for t := range p.templatesIn(p.parseHTML) {
if !yield(t) {
return
}
}
for t := range p.templatesIn(p.parseText) {
if !yield(t) {
return
}
}
for _, tt := range p.baseofHtmlClones {
for t := range p.templatesIn(tt) {
if !yield(t) {
return
}
}
}
for _, tt := range p.baseofTextClones {
for t := range p.templatesIn(tt) {
if !yield(t) {
return
}
}
}
}
}
func (s *TemplateStore) insertEmbedded() error { func (s *TemplateStore) insertEmbedded() error {
return fs.WalkDir(embeddedTemplatesFs, ".", func(path string, d fs.DirEntry, err error) error { return fs.WalkDir(embeddedTemplatesFs, ".", func(tpath string, d fs.DirEntry, err error) error {
if err != nil { if err != nil {
return err return err
} }
@ -1002,7 +1026,7 @@ func (s *TemplateStore) insertEmbedded() error {
return nil return nil
} }
templb, err := embeddedTemplatesFs.ReadFile(path) templb, err := embeddedTemplatesFs.ReadFile(tpath)
if err != nil { if err != nil {
return err return err
} }
@ -1010,7 +1034,7 @@ func (s *TemplateStore) insertEmbedded() error {
// Get the newlines on Windows in line with how we had it back when we used Go Generate // Get the newlines on Windows in line with how we had it back when we used Go Generate
// to write the templates to Go files. // to write the templates to Go files.
templ := string(bytes.ReplaceAll(templb, []byte("\r\n"), []byte("\n"))) templ := string(bytes.ReplaceAll(templb, []byte("\r\n"), []byte("\n")))
name := strings.TrimPrefix(filepath.ToSlash(path), "embedded/templates/") name := strings.TrimPrefix(filepath.ToSlash(tpath), "embedded/templates/")
insertOne := func(name, content string) error { insertOne := func(name, content string) error {
pi := s.opts.PathParser.Parse(files.ComponentFolderLayouts, name) pi := s.opts.PathParser.Parse(files.ComponentFolderLayouts, name)
@ -1024,7 +1048,7 @@ func (s *TemplateStore) insertEmbedded() error {
return err return err
} }
} else { } else {
ti, err = s.insertTemplate(pi, nil, false, s.treeMain) ti, err = s.insertTemplate(pi, nil, SubCategoryEmbedded, false, s.treeMain)
if err != nil { if err != nil {
return err return err
} }
@ -1040,6 +1064,19 @@ func (s *TemplateStore) insertEmbedded() error {
return nil return nil
} }
// Copy the embedded HTML table render hook to each output format.
// See https://github.com/gohugoio/hugo/issues/13351.
if name == path.Join(containerMarkup, "render-table.html") {
for _, of := range s.opts.OutputFormats {
path := paths.TrimExt(name) + "." + of.Name + of.MediaType.FirstSuffix.FullSuffix
if err := insertOne(path, templ); err != nil {
return err
}
}
return nil
}
if err := insertOne(name, templ); err != nil { if err := insertOne(name, templ); err != nil {
return err return err
} }
@ -1105,7 +1142,7 @@ func (s *TemplateStore) insertShortcode(pi *paths.Path, fi hugofs.FileMetaInfo,
return ti, nil return ti, nil
} }
func (s *TemplateStore) insertTemplate(pi *paths.Path, fi hugofs.FileMetaInfo, replace bool, tree doctree.Tree[map[nodeKey]*TemplInfo]) (*TemplInfo, error) { func (s *TemplateStore) insertTemplate(pi *paths.Path, fi hugofs.FileMetaInfo, subCategory SubCategory, replace bool, tree doctree.Tree[map[nodeKey]*TemplInfo]) (*TemplInfo, error) {
key, _, category, d, err := s.toKeyCategoryAndDescriptor(pi) key, _, category, d, err := s.toKeyCategoryAndDescriptor(pi)
// See #13577. Warn for now. // See #13577. Warn for now.
if err != nil { if err != nil {
@ -1119,7 +1156,7 @@ func (s *TemplateStore) insertTemplate(pi *paths.Path, fi hugofs.FileMetaInfo, r
return nil, nil return nil, nil
} }
return s.insertTemplate2(pi, fi, key, category, d, replace, false, tree) return s.insertTemplate2(pi, fi, key, category, subCategory, d, replace, false, tree)
} }
func (s *TemplateStore) insertTemplate2( func (s *TemplateStore) insertTemplate2(
@ -1127,6 +1164,7 @@ func (s *TemplateStore) insertTemplate2(
fi hugofs.FileMetaInfo, fi hugofs.FileMetaInfo,
key string, key string,
category Category, category Category,
subCategory SubCategory,
d TemplateDescriptor, d TemplateDescriptor,
replace, isLegacyMapped bool, replace, isLegacyMapped bool,
tree doctree.Tree[map[nodeKey]*TemplInfo], tree doctree.Tree[map[nodeKey]*TemplInfo],
@ -1160,6 +1198,11 @@ func (s *TemplateStore) insertTemplate2(
replace = fi.Meta().ModuleOrdinal < nkExisting.Fi.Meta().ModuleOrdinal replace = fi.Meta().ModuleOrdinal < nkExisting.Fi.Meta().ModuleOrdinal
} }
if !replace && existingFound {
// Always replace inline partials to allow for reloading.
replace = subCategory == SubCategoryInline && nkExisting.subCategory == SubCategoryInline
}
if !replace && existingFound { if !replace && existingFound {
if len(pi.Identifiers()) >= len(nkExisting.PathInfo.Identifiers()) { if len(pi.Identifiers()) >= len(nkExisting.PathInfo.Identifiers()) {
// e.g. /pages/home.foo.html and /pages/home.html where foo may be a valid language name in another site. // e.g. /pages/home.foo.html and /pages/home.html where foo may be a valid language name in another site.
@ -1190,7 +1233,7 @@ func (s *TemplateStore) insertTemplate2(
return ti, nil return ti, nil
} }
func (s *TemplateStore) insertTemplates(include func(fi hugofs.FileMetaInfo) bool, replace bool) error { func (s *TemplateStore) insertTemplates(include func(fi hugofs.FileMetaInfo) bool, partialRebuild bool) error {
if include == nil { if include == nil {
include = func(fi hugofs.FileMetaInfo) bool { include = func(fi hugofs.FileMetaInfo) bool {
return true return true
@ -1372,7 +1415,7 @@ func (s *TemplateStore) insertTemplates(include func(fi hugofs.FileMetaInfo) boo
} }
if replace && pi.NameNoIdentifier() == baseNameBaseof { if partialRebuild && pi.NameNoIdentifier() == baseNameBaseof {
// A baseof file has changed. // A baseof file has changed.
resetBaseVariants = true resetBaseVariants = true
} }
@ -1380,12 +1423,12 @@ func (s *TemplateStore) insertTemplates(include func(fi hugofs.FileMetaInfo) boo
var ti *TemplInfo var ti *TemplInfo
var err error var err error
if pi.Type() == paths.TypeShortcode { if pi.Type() == paths.TypeShortcode {
ti, err = s.insertShortcode(pi, fi, replace, s.treeShortcodes) ti, err = s.insertShortcode(pi, fi, partialRebuild, s.treeShortcodes)
if err != nil || ti == nil { if err != nil || ti == nil {
return err return err
} }
} else { } else {
ti, err = s.insertTemplate(pi, fi, replace, s.treeMain) ti, err = s.insertTemplate(pi, fi, SubCategoryMain, partialRebuild, s.treeMain)
if err != nil || ti == nil { if err != nil || ti == nil {
return err return err
} }
@ -1419,7 +1462,7 @@ func (s *TemplateStore) insertTemplates(include func(fi hugofs.FileMetaInfo) boo
desc.IsPlainText = outputFormat.IsPlainText desc.IsPlainText = outputFormat.IsPlainText
desc.MediaType = mediaType.Type desc.MediaType = mediaType.Type
ti, err := s.insertTemplate2(pi, fi, targetPath, category, desc, true, true, s.treeMain) ti, err := s.insertTemplate2(pi, fi, targetPath, category, SubCategoryMain, desc, true, true, s.treeMain)
if err != nil { if err != nil {
return err return err
} }
@ -1430,6 +1473,7 @@ func (s *TemplateStore) insertTemplates(include func(fi hugofs.FileMetaInfo) boo
if err := s.tns.readTemplateInto(ti); err != nil { if err := s.tns.readTemplateInto(ti); err != nil {
return err return err
} }
} }
if resetBaseVariants { if resetBaseVariants {
@ -1456,7 +1500,15 @@ func (s *TemplateStore) key(dir string) string {
return paths.TrimTrailing(dir) return paths.TrimTrailing(dir)
} }
func (s *TemplateStore) parseTemplates() error { func (s *TemplateStore) createTemplatesSnapshot() error {
s.templatesSnapshotSet.Reset()
for t := range s.allRawTemplates() {
s.templatesSnapshotSet.Set(getParseTree(t), struct{}{})
}
return nil
}
func (s *TemplateStore) parseTemplates(replace bool) error {
if err := func() error { if err := func() error {
// Read and parse all templates. // Read and parse all templates.
for _, v := range s.treeMain.All() { for _, v := range s.treeMain.All() {
@ -1464,7 +1516,7 @@ func (s *TemplateStore) parseTemplates() error {
if vv.state == processingStateTransformed { if vv.state == processingStateTransformed {
continue continue
} }
if err := s.parseTemplate(vv); err != nil { if err := s.parseTemplate(vv, replace); err != nil {
return err return err
} }
} }
@ -1484,7 +1536,7 @@ func (s *TemplateStore) parseTemplates() error {
// The regular expression used to detect if a template needs a base template has some // The regular expression used to detect if a template needs a base template has some
// rare false positives. Assume we don't need one. // rare false positives. Assume we don't need one.
vv.noBaseOf = true vv.noBaseOf = true
if err := s.parseTemplate(vv); err != nil { if err := s.parseTemplate(vv, replace); err != nil {
return err return err
} }
continue continue
@ -1513,7 +1565,7 @@ func (s *TemplateStore) parseTemplates() error {
if vvv.state == processingStateTransformed { if vvv.state == processingStateTransformed {
continue continue
} }
if err := s.parseTemplate(vvv); err != nil { if err := s.parseTemplate(vvv, replace); err != nil {
return err return err
} }
} }

View file

@ -1508,3 +1508,43 @@ mytexts|safeHTML: {{ partial "mytext.txt" . | safeHTML }}
"mytexts|safeHTML: <div>mytext</div>", "mytexts|safeHTML: <div>mytext</div>",
) )
} }
func TestIssue13351(t *testing.T) {
t.Parallel()
files := `
-- hugo.toml --
disableKinds = ['page','rss','section','sitemap','taxonomy','term']
[outputs]
home = ['html','json']
[outputFormats.html]
weight = 1
[outputFormats.json]
weight = 2
-- content/_index.md --
---
title: home
---
a|b
:--|:--
1|2
-- layouts/index.html --
{{ .Content }}
-- layouts/index.json --
{{ .Content }}
`
b := hugolib.Test(t, files)
b.AssertFileContent("public/index.html", "<table>")
b.AssertFileContent("public/index.json", "<table>")
f := strings.ReplaceAll(files, "weight = 1", "weight = 0")
b = hugolib.Test(t, f)
b.AssertFileContent("public/index.html", "<table>")
b.AssertFileContent("public/index.json", "<table>")
f = strings.ReplaceAll(files, "weight = 1", "")
b = hugolib.Test(t, f)
b.AssertFileContent("public/index.html", "<table>")
b.AssertFileContent("public/index.json", "<table>")
}

View file

@ -17,8 +17,10 @@ package transform
import ( import (
"bytes" "bytes"
"context" "context"
"encoding/json"
"encoding/xml" "encoding/xml"
"errors" "errors"
"fmt"
"html" "html"
"html/template" "html/template"
"io" "io"
@ -234,6 +236,7 @@ func (ns *Namespace) ToMath(ctx context.Context, args ...any) (template.HTML, er
MinRuleThickness: 0.04, MinRuleThickness: 0.04,
ErrorColor: "#cc0000", ErrorColor: "#cc0000",
ThrowOnError: true, ThrowOnError: true,
Strict: "error",
}, },
} }
@ -243,8 +246,23 @@ func (ns *Namespace) ToMath(ctx context.Context, args ...any) (template.HTML, er
} }
} }
switch katexInput.Options.Strict {
case "error", "ignore", "warn":
// Valid strict mode, continue
default:
return "", fmt.Errorf("invalid strict mode; expected one of error, ignore, or warn; received %s", katexInput.Options.Strict)
}
type fileCacheEntry struct {
Version string `json:"version"`
Output string `json:"output"`
Warnings []string `json:"warnings,omitempty"`
}
const fileCacheEntryVersion = "v1" // Increment on incompatible changes.
s := hashing.HashString(args...) s := hashing.HashString(args...)
key := "tomath/" + s[:2] + "/" + s[2:] key := "tomath/" + fileCacheEntryVersion + "/" + s[:2] + "/" + s[2:]
fileCache := ns.deps.ResourceSpec.FileCaches.MiscCache() fileCache := ns.deps.ResourceSpec.FileCaches.MiscCache()
v, err := ns.cacheMath.GetOrCreate(key, func(string) (template.HTML, error) { v, err := ns.cacheMath.GetOrCreate(key, func(string) (template.HTML, error) {
@ -265,15 +283,35 @@ func (ns *Namespace) ToMath(ctx context.Context, args ...any) (template.HTML, er
if err != nil { if err != nil {
return nil, err return nil, err
} }
return hugio.NewReadSeekerNoOpCloserFromString(result.Data.Output), nil
e := fileCacheEntry{
Version: fileCacheEntryVersion,
Output: result.Data.Output,
Warnings: result.Header.Warnings,
}
buf := &bytes.Buffer{}
enc := json.NewEncoder(buf)
enc.SetEscapeHTML(false)
if err := enc.Encode(e); err != nil {
return nil, fmt.Errorf("failed to encode file cache entry: %w", err)
}
return hugio.NewReadSeekerNoOpCloserFromBytes(buf.Bytes()), nil
}) })
if err != nil { if err != nil {
return "", err return "", err
} }
s, err := hugio.ReadString(r) var e fileCacheEntry
if err := json.NewDecoder(r).Decode(&e); err != nil {
return "", fmt.Errorf("failed to decode file cache entry: %w", err)
}
return template.HTML(s), err for _, warning := range e.Warnings {
ns.deps.Log.Warnf("transform.ToMath: %s", warning)
}
return template.HTML(e.Output), err
}) })
if err != nil { if err != nil {
return "", err return "", err

View file

@ -495,3 +495,43 @@ DATA
} }
} }
} }
// Issue 13729
func TestToMathStrictMode(t *testing.T) {
t.Parallel()
files := `
-- hugo.toml --
disableKinds = ['page','rss','section','sitemap','taxonomy','term']
-- layouts/all.html --
{{ transform.ToMath "a %" dict }}
-- foo --
`
// strict mode: default
f := strings.ReplaceAll(files, "dict", "")
b, err := hugolib.TestE(t, f)
b.Assert(err.Error(), qt.Contains, "[commentAtEnd]")
// strict mode: error
f = strings.ReplaceAll(files, "dict", `(dict "strict" "error")`)
b, err = hugolib.TestE(t, f)
b.Assert(err.Error(), qt.Contains, "[commentAtEnd]")
// strict mode: ignore
f = strings.ReplaceAll(files, "dict", `(dict "strict" "ignore")`)
b = hugolib.Test(t, f, hugolib.TestOptWarn())
b.AssertLogMatches("")
b.AssertFileContent("public/index.html", `<annotation encoding="application/x-tex">a %</annotation>`)
// strict: warn
f = strings.ReplaceAll(files, "dict", `(dict "strict" "warn")`)
b = hugolib.Test(t, f, hugolib.TestOptWarn())
b.AssertLogMatches("[commentAtEnd]")
b.AssertFileContent("public/index.html", `<annotation encoding="application/x-tex">a %</annotation>`)
// strict mode: invalid value
f = strings.ReplaceAll(files, "dict", `(dict "strict" "foo")`)
b, err = hugolib.TestE(t, f)
b.Assert(err.Error(), qt.Contains, "invalid strict mode")
}