mirror of
https://github.com/gohugoio/hugo.git
synced 2025-07-03 23:47:34 +00:00
Compare commits
No commits in common. "master" and "v0.147.1" have entirely different histories.
87 changed files with 679 additions and 2255 deletions
|
@ -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.24"
|
ARG GO_VERSION="1.23.2"
|
||||||
ARG ALPINE_VERSION="3.22"
|
ARG ALPINE_VERSION="3.20"
|
||||||
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
|
||||||
|
|
|
@ -65,11 +65,9 @@ See the [features] section of the documentation for a comprehensive summary of H
|
||||||
|
|
||||||
<p> </p>
|
<p> </p>
|
||||||
<p float="left">
|
<p float="left">
|
||||||
<a href="https://www.linode.com/?utm_campaign=hugosponsor&utm_medium=banner&utm_source=hugogithub" target="_blank"><img src="https://raw.githubusercontent.com/gohugoio/hugoDocs/master/assets/images/sponsors/linode-logo_standard_light_medium.png" width="200" alt="Linode"></a>
|
<a href="https://www.linode.com/?utm_campaign=hugosponsor&utm_medium=banner&utm_source=hugogithub" target="_blank"><img src="https://raw.githubusercontent.com/gohugoio/gohugoioTheme/master/assets/images/sponsors/linode-logo_standard_light_medium.png" width="200" alt="Linode"></a>
|
||||||
|
|
||||||
<a href="https://www.jetbrains.com/go/?utm_source=OSS&utm_medium=referral&utm_campaign=hugo" target="_blank"><img src="https://raw.githubusercontent.com/gohugoio/hugoDocs/master/assets/images/sponsors/goland.svg" width="200" alt="The complete IDE crafted for professional Go developers."></a>
|
<a href="https://www.jetbrains.com/go/?utm_source=OSS&utm_medium=referral&utm_campaign=hugo" target="_blank"><img src="https://raw.githubusercontent.com/gohugoio/gohugoioTheme/master/assets/images/sponsors/goland.svg" width="200" alt="The complete IDE crafted for professional Go developers."></a>
|
||||||
|
|
||||||
<a href="https://pinme.eth.limo/?s=hugo" target="_blank"><img src="https://raw.githubusercontent.com/gohugoio/hugoDocs/master/assets/images/sponsors/logo-pinme.svg" width="200" alt="PinMe."></a>
|
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
## Editions
|
## Editions
|
||||||
|
|
|
@ -972,9 +972,6 @@ 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 {
|
||||||
|
|
|
@ -76,8 +76,10 @@ Ensure you run this within the root directory of your site.`,
|
||||||
&simpleCommand{
|
&simpleCommand{
|
||||||
name: "site",
|
name: "site",
|
||||||
use: "site [path]",
|
use: "site [path]",
|
||||||
short: "Create a new site",
|
short: "Create a new site (skeleton)",
|
||||||
long: `Create a new site at the specified path.`,
|
long: `Create a new site in the provided directory.
|
||||||
|
The new site will have the correct structure, but no content or theme yet.
|
||||||
|
Use ` + "`hugo new [contentPath]`" + ` to create new content.`,
|
||||||
run: func(ctx context.Context, cd *simplecobra.Commandeer, r *rootCommand, args []string) error {
|
run: func(ctx context.Context, cd *simplecobra.Commandeer, r *rootCommand, args []string) error {
|
||||||
if len(args) < 1 {
|
if len(args) < 1 {
|
||||||
return newUserError("path needs to be provided")
|
return newUserError("path needs to be provided")
|
||||||
|
@ -122,9 +124,11 @@ Ensure you run this within the root directory of your site.`,
|
||||||
&simpleCommand{
|
&simpleCommand{
|
||||||
name: "theme",
|
name: "theme",
|
||||||
use: "theme [name]",
|
use: "theme [name]",
|
||||||
short: "Create a new theme",
|
short: "Create a new theme (skeleton)",
|
||||||
long: `Create a new theme with the specified name in the ./themes directory.
|
long: `Create a new theme (skeleton) called [name] in ./themes.
|
||||||
This generates a functional theme including template examples and sample content.`,
|
New theme is a skeleton. Please add content to the touched files. Add your
|
||||||
|
name to the copyright line in the license and adjust the theme.toml file
|
||||||
|
according to your needs.`,
|
||||||
run: func(ctx context.Context, cd *simplecobra.Commandeer, r *rootCommand, args []string) error {
|
run: func(ctx context.Context, cd *simplecobra.Commandeer, r *rootCommand, args []string) error {
|
||||||
if len(args) < 1 {
|
if len(args) < 1 {
|
||||||
return newUserError("theme name needs to be provided")
|
return newUserError("theme name needs to be provided")
|
||||||
|
|
|
@ -15,7 +15,6 @@ package collections
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"html/template"
|
"html/template"
|
||||||
"reflect"
|
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
qt "github.com/frankban/quicktest"
|
qt "github.com/frankban/quicktest"
|
||||||
|
@ -78,7 +77,6 @@ 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...)
|
||||||
|
@ -148,66 +146,3 @@ 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)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -136,37 +136,3 @@ 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)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,77 +0,0 @@
|
||||||
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})
|
|
||||||
}
|
|
|
@ -24,7 +24,6 @@ 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.
|
||||||
|
|
|
@ -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: 148,
|
Minor: 147,
|
||||||
PatchLevel: 0,
|
PatchLevel: 1,
|
||||||
Suffix: "-DEV",
|
Suffix: "",
|
||||||
}
|
}
|
||||||
|
|
|
@ -120,20 +120,15 @@ 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, numDots int, isLast bool) {
|
func (pp *PathParser) parseIdentifier(component, s string, p *Path, i, lastDot int) {
|
||||||
if p.posContainerHigh != -1 {
|
if p.posContainerHigh != -1 {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
mayHaveLang := numDots > 1 && p.posIdentifierLanguage == -1 && pp.LanguageIndex != nil
|
mayHaveLang := 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
|
||||||
var mayHaveLayout bool
|
mayHaveLayout := component == files.ComponentFolderLayouts
|
||||||
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
|
||||||
|
@ -172,6 +167,7 @@ func (pp *PathParser) parseIdentifier(component, s string, p *Path, i, lastDot,
|
||||||
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
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -238,24 +234,19 @@ 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, numDots, false)
|
pp.parseIdentifier(component, s, p, i, lastDot)
|
||||||
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, numDots, true)
|
pp.parseIdentifier(component, s, p, i, lastDot)
|
||||||
}
|
}
|
||||||
p.posContainerHigh = i + 1
|
p.posContainerHigh = i + 1
|
||||||
} else if p.posContainerLow == -1 {
|
} else if p.posContainerLow == -1 {
|
||||||
|
@ -291,9 +282,10 @@ func (pp *PathParser) doParse(component, s string, p *Path) (*Path, error) {
|
||||||
p.pathType = TypeContentData
|
p.pathType = TypeContentData
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if p.pathType < TypeMarkup && component == files.ComponentFolderLayouts {
|
if component == files.ComponentFolderLayouts {
|
||||||
if p.posIdentifierBaseof != -1 {
|
if p.posIdentifierBaseof != -1 {
|
||||||
p.pathType = TypeBaseof
|
p.pathType = TypeBaseof
|
||||||
} else {
|
} else {
|
||||||
|
@ -309,10 +301,12 @@ 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 {
|
||||||
id := p.identifiersKnown[p.posIdentifierLayout]
|
// myshortcode or myshortcode.html, no layout.
|
||||||
if id.Low == p.posContainerHigh {
|
if len(p.identifiersKnown) <= 2 {
|
||||||
// First identifier is shortcode name.
|
|
||||||
p.posIdentifierLayout = -1
|
p.posIdentifierLayout = -1
|
||||||
|
} else {
|
||||||
|
// First is always the name.
|
||||||
|
p.posIdentifierLayout--
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -640,7 +634,7 @@ func (p *Path) Base() string {
|
||||||
// For pages with Type set, we treat that as the section.
|
// For pages with Type set, we treat that as the section.
|
||||||
func (p *Path) BaseReTyped(typ string) (d string) {
|
func (p *Path) BaseReTyped(typ string) (d string) {
|
||||||
base := p.Base()
|
base := p.Base()
|
||||||
if p.Section() == typ {
|
if typ == "" || p.Section() == typ {
|
||||||
return base
|
return base
|
||||||
}
|
}
|
||||||
d = "/" + typ
|
d = "/" + typ
|
||||||
|
|
|
@ -434,12 +434,12 @@ func TestParseLayouts(t *testing.T) {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"Layout multiple",
|
"Layout multiple",
|
||||||
"/mylayout.list.section.no.html",
|
"/maylayout.list.section.no.html",
|
||||||
func(c *qt.C, p *Path) {
|
func(c *qt.C, p *Path) {
|
||||||
c.Assert(p.Layout(), qt.Equals, "mylayout")
|
c.Assert(p.Layout(), qt.Equals, "maylayout")
|
||||||
c.Assert(p.Identifiers(), qt.DeepEquals, []string{"html", "no", "section", "list", "mylayout"})
|
c.Assert(p.Identifiers(), qt.DeepEquals, []string{"html", "no", "section", "list", "maylayout"})
|
||||||
c.Assert(p.IdentifiersUnknown(), qt.DeepEquals, []string{})
|
c.Assert(p.IdentifiersUnknown(), qt.DeepEquals, []string{})
|
||||||
c.Assert(p.Base(), qt.Equals, "/mylayout.html")
|
c.Assert(p.Base(), qt.Equals, "/maylayout.html")
|
||||||
c.Assert(p.Lang(), qt.Equals, "no")
|
c.Assert(p.Lang(), qt.Equals, "no")
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -487,8 +487,7 @@ 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"})
|
c.Assert(p.Identifiers(), qt.DeepEquals, []string{"html", "list", "myshortcode"})
|
||||||
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, "")
|
||||||
|
@ -564,30 +563,11 @@ 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 != "Shortcode lang layout" {
|
if test.name != "Baseof" {
|
||||||
// return
|
// return
|
||||||
}
|
}
|
||||||
test.assert(c, testParser.Parse(files.ComponentFolderLayouts, test.path))
|
test.assert(c, testParser.Parse(files.ComponentFolderLayouts, test.path))
|
||||||
|
|
|
@ -17,6 +17,7 @@ package terminal
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
|
"runtime"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
isatty "github.com/mattn/go-isatty"
|
isatty "github.com/mattn/go-isatty"
|
||||||
|
@ -40,6 +41,10 @@ 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))
|
||||||
}
|
}
|
||||||
|
|
|
@ -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, page.PageMatcherParamsConfig]] `mapstructure:"-"`
|
Cascade *config.ConfigNamespace[[]page.PageMatcherParamsConfig, *maps.Ordered[page.PageMatcher, maps.Params]] `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, cfg page.PageMatcherParamsConfig) bool {
|
c.Base.Cascade.Config.Range(func(p page.PageMatcher, params maps.Params) bool {
|
||||||
page.CheckCascadePattern(logger, p)
|
page.CheckCascadePattern(logger, p)
|
||||||
return true
|
return true
|
||||||
})
|
})
|
||||||
|
|
|
@ -273,69 +273,6 @@ GA ID: {{ site.Config.Services.GoogleAnalytics.ID }}.
|
||||||
b.AssertFileContent("public/index.html", "GA ID: foo bar.")
|
b.AssertFileContent("public/index.html", "GA ID: foo bar.")
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestMergeDeepBuildStats(t *testing.T) {
|
|
||||||
t.Parallel()
|
|
||||||
|
|
||||||
files := `
|
|
||||||
-- hugo.toml --
|
|
||||||
baseURL = "https://example.com"
|
|
||||||
title = "Theme 1"
|
|
||||||
_merge = "deep"
|
|
||||||
[module]
|
|
||||||
[module.hugoVersion]
|
|
||||||
[[module.imports]]
|
|
||||||
path = "theme1"
|
|
||||||
-- themes/theme1/hugo.toml --
|
|
||||||
[build]
|
|
||||||
[build.buildStats]
|
|
||||||
disableIDs = true
|
|
||||||
enable = true
|
|
||||||
-- layouts/home.html --
|
|
||||||
Home.
|
|
||||||
|
|
||||||
`
|
|
||||||
|
|
||||||
b := hugolib.Test(t, files, hugolib.TestOptOsFs())
|
|
||||||
|
|
||||||
conf := b.H.Configs
|
|
||||||
base := conf.Base
|
|
||||||
|
|
||||||
b.Assert(base.Title, qt.Equals, "Theme 1")
|
|
||||||
b.Assert(len(base.Module.Imports), qt.Equals, 1)
|
|
||||||
b.Assert(base.Build.BuildStats.Enable, qt.Equals, true)
|
|
||||||
b.AssertFileExists("/hugo_stats.json", true)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestMergeDeepBuildStatsTheme(t *testing.T) {
|
|
||||||
t.Parallel()
|
|
||||||
|
|
||||||
files := `
|
|
||||||
-- hugo.toml --
|
|
||||||
baseURL = "https://example.com"
|
|
||||||
_merge = "deep"
|
|
||||||
theme = ["theme1"]
|
|
||||||
-- themes/theme1/hugo.toml --
|
|
||||||
title = "Theme 1"
|
|
||||||
[build]
|
|
||||||
[build.buildStats]
|
|
||||||
disableIDs = true
|
|
||||||
enable = true
|
|
||||||
-- layouts/home.html --
|
|
||||||
Home.
|
|
||||||
|
|
||||||
`
|
|
||||||
|
|
||||||
b := hugolib.Test(t, files, hugolib.TestOptOsFs())
|
|
||||||
|
|
||||||
conf := b.H.Configs
|
|
||||||
base := conf.Base
|
|
||||||
|
|
||||||
b.Assert(base.Title, qt.Equals, "Theme 1")
|
|
||||||
b.Assert(len(base.Module.Imports), qt.Equals, 1)
|
|
||||||
b.Assert(base.Build.BuildStats.Enable, qt.Equals, true)
|
|
||||||
b.AssertFileExists("/hugo_stats.json", true)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestDefaultConfigLanguageBlankWhenNoEnglishExists(t *testing.T) {
|
func TestDefaultConfigLanguageBlankWhenNoEnglishExists(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
|
@ -357,25 +294,3 @@ All.
|
||||||
|
|
||||||
b.Assert(b.H.Conf.DefaultContentLanguage(), qt.Equals, "sv")
|
b.Assert(b.H.Conf.DefaultContentLanguage(), qt.Equals, "sv")
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestDefaultConfigEnvDisableLanguagesIssue13707(t *testing.T) {
|
|
||||||
t.Parallel()
|
|
||||||
|
|
||||||
files := `
|
|
||||||
-- hugo.toml --
|
|
||||||
disableLanguages = []
|
|
||||||
[languages]
|
|
||||||
[languages.en]
|
|
||||||
weight = 1
|
|
||||||
[languages.nn]
|
|
||||||
weight = 2
|
|
||||||
[languages.sv]
|
|
||||||
weight = 3
|
|
||||||
`
|
|
||||||
|
|
||||||
b := hugolib.Test(t, files, hugolib.TestOptWithConfig(func(conf *hugolib.IntegrationTestConfig) {
|
|
||||||
conf.Environ = []string{`HUGO_DISABLELANGUAGES=sv nn`}
|
|
||||||
}))
|
|
||||||
|
|
||||||
b.Assert(len(b.H.Sites), qt.Equals, 1)
|
|
||||||
}
|
|
||||||
|
|
|
@ -330,7 +330,7 @@ var allDecoderSetups = map[string]decodeWeight{
|
||||||
key: "cascade",
|
key: "cascade",
|
||||||
decode: func(d decodeWeight, p decodeConfig) error {
|
decode: func(d decodeWeight, p decodeConfig) error {
|
||||||
var err error
|
var err error
|
||||||
p.c.Cascade, err = page.DecodeCascadeConfig(nil, true, p.p.Get(d.key))
|
p.c.Cascade, err = page.DecodeCascadeConfig(nil, p.p.Get(d.key))
|
||||||
return err
|
return err
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
@ -233,18 +233,17 @@ func (l configLoader) applyOsEnvOverrides(environ []string) error {
|
||||||
|
|
||||||
if existing != nil {
|
if existing != nil {
|
||||||
val, err := metadecoders.Default.UnmarshalStringTo(env.Value, existing)
|
val, err := metadecoders.Default.UnmarshalStringTo(env.Value, existing)
|
||||||
if err == nil {
|
if err != nil {
|
||||||
val = l.envValToVal(env.Key, val)
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
if owner != nil {
|
if owner != nil {
|
||||||
owner[nestedKey] = val
|
owner[nestedKey] = val
|
||||||
} else {
|
} else {
|
||||||
l.cfg.Set(env.Key, val)
|
l.cfg.Set(env.Key, val)
|
||||||
}
|
}
|
||||||
continue
|
} else {
|
||||||
}
|
if nestedKey != "" {
|
||||||
}
|
|
||||||
|
|
||||||
if owner != nil && nestedKey != "" {
|
|
||||||
owner[nestedKey] = env.Value
|
owner[nestedKey] = env.Value
|
||||||
} else {
|
} else {
|
||||||
var val any
|
var val any
|
||||||
|
@ -256,28 +255,18 @@ func (l configLoader) applyOsEnvOverrides(environ []string) error {
|
||||||
val = v
|
val = v
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if val == nil {
|
if val == nil {
|
||||||
// A string.
|
// A string.
|
||||||
val = l.envStringToVal(key, env.Value)
|
val = l.envStringToVal(key, env.Value)
|
||||||
}
|
}
|
||||||
l.cfg.Set(key, val)
|
l.cfg.Set(key, val)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *configLoader) envValToVal(k string, v any) any {
|
|
||||||
switch v := v.(type) {
|
|
||||||
case string:
|
|
||||||
return l.envStringToVal(k, v)
|
|
||||||
default:
|
|
||||||
return v
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (l *configLoader) envStringToVal(k, v string) any {
|
func (l *configLoader) envStringToVal(k, v string) any {
|
||||||
switch k {
|
switch k {
|
||||||
case "disablekinds", "disablelanguages":
|
case "disablekinds", "disablelanguages":
|
||||||
|
|
|
@ -36,7 +36,6 @@ 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"
|
||||||
|
@ -488,12 +487,7 @@ 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 := make(map[string]*localFile)
|
retval := 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
|
||||||
|
@ -514,8 +508,6 @@ 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)
|
||||||
|
@ -549,19 +541,12 @@ 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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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{Workers: 2, MaxDeletes: -1},
|
cfg: deployconfig.DeployConfig{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{Workers: 2, MaxDeletes: -1},
|
cfg: deployconfig.DeployConfig{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{Workers: 2, MaxDeletes: -1}, bucket: fsTest.bucket,
|
cfg: deployconfig.DeployConfig{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{Workers: 2, MaxDeletes: -1}, bucket: fsTest.bucket,
|
cfg: deployconfig.DeployConfig{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{Workers: 2, MaxDeletes: -1, Matchers: []*deployconfig.Matcher{{Pattern: ".*", Gzip: true, Re: regexp.MustCompile(".*")}}},
|
cfg: deployconfig.DeployConfig{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{Workers: 2, MaxDeletes: -1, Matchers: []*deployconfig.Matcher{{Pattern: "^subdir/aaa$", Force: true, Re: regexp.MustCompile("^subdir/aaa$")}}},
|
cfg: deployconfig.DeployConfig{MaxDeletes: -1, Matchers: []*deployconfig.Matcher{{Pattern: "^subdir/aaa$", Force: true, Re: regexp.MustCompile("^subdir/aaa$")}}},
|
||||||
mediaTypes: media.DefaultTypes,
|
mediaTypes: media.DefaultTypes,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1097,6 +1097,5 @@ 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
96
go.mod
|
@ -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.18.0
|
github.com/alecthomas/chroma/v2 v2.17.2
|
||||||
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.4
|
github.com/aws/aws-sdk-go-v2 v1.36.1
|
||||||
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.5
|
github.com/evanw/esbuild v0.25.3
|
||||||
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,46 +54,44 @@ 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.8.0
|
github.com/niklasfasching/go-org v1.7.0
|
||||||
github.com/olekukonko/tablewriter v1.0.7
|
github.com/olekukonko/tablewriter v0.0.5
|
||||||
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.9.2
|
github.com/spf13/cast v1.7.1
|
||||||
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.23.8
|
github.com/tdewolff/minify/v2 v2.20.37
|
||||||
github.com/tdewolff/parse/v2 v2.8.1
|
github.com/tdewolff/parse/v2 v2.7.15
|
||||||
github.com/tetratelabs/wazero v1.9.0
|
github.com/tetratelabs/wazero v1.9.0
|
||||||
github.com/yuin/goldmark v1.7.12
|
github.com/yuin/goldmark v1.7.11
|
||||||
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.28.0
|
golang.org/x/image v0.26.0
|
||||||
golang.org/x/mod v0.25.0
|
golang.org/x/mod v0.24.0
|
||||||
golang.org/x/net v0.41.0
|
golang.org/x/net v0.39.0
|
||||||
golang.org/x/sync v0.15.0
|
golang.org/x/sync v0.13.0
|
||||||
golang.org/x/text v0.26.0
|
golang.org/x/text v0.24.0
|
||||||
golang.org/x/tools v0.34.0
|
golang.org/x/tools v0.32.0
|
||||||
google.golang.org/api v0.237.0
|
google.golang.org/api v0.221.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 (
|
||||||
cel.dev/expr v0.23.0 // indirect
|
cloud.google.com/go v0.116.0 // indirect
|
||||||
cloud.google.com/go v0.120.0 // indirect
|
cloud.google.com/go/auth v0.14.1 // indirect
|
||||||
cloud.google.com/go/auth v0.16.2 // indirect
|
cloud.google.com/go/auth/oauth2adapt v0.2.7 // indirect
|
||||||
cloud.google.com/go/auth/oauth2adapt v0.2.8 // indirect
|
cloud.google.com/go/compute/metadata v0.6.0 // indirect
|
||||||
cloud.google.com/go/compute/metadata v0.7.0 // indirect
|
cloud.google.com/go/iam v1.2.2 // indirect
|
||||||
cloud.google.com/go/iam v1.5.2 // indirect
|
cloud.google.com/go/storage v1.43.0 // 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
|
||||||
|
@ -101,9 +99,6 @@ 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
|
||||||
|
@ -123,13 +118,9 @@ 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
|
||||||
|
@ -139,8 +130,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.6 // indirect
|
github.com/googleapis/enterprise-certificate-proxy v0.3.4 // indirect
|
||||||
github.com/googleapis/gax-go/v2 v2.14.2 // indirect
|
github.com/googleapis/gax-go/v2 v2.14.1 // 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
|
||||||
|
@ -150,40 +141,31 @@ 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.16 // indirect
|
github.com/mattn/go-runewidth v0.0.9 // 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/detectors/gcp v1.35.0 // indirect
|
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.58.0 // indirect
|
||||||
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.61.0 // indirect
|
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.58.0 // indirect
|
||||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0 // indirect
|
go.opentelemetry.io/otel v1.34.0 // indirect
|
||||||
go.opentelemetry.io/otel v1.36.0 // indirect
|
go.opentelemetry.io/otel/metric v1.34.0 // indirect
|
||||||
go.opentelemetry.io/otel/metric v1.36.0 // indirect
|
go.opentelemetry.io/otel/trace v1.34.0 // indirect
|
||||||
go.opentelemetry.io/otel/sdk v1.36.0 // indirect
|
golang.org/x/crypto v0.37.0 // indirect
|
||||||
go.opentelemetry.io/otel/sdk/metric v1.36.0 // indirect
|
golang.org/x/oauth2 v0.26.0 // indirect
|
||||||
go.opentelemetry.io/otel/trace v1.36.0 // indirect
|
golang.org/x/sys v0.32.0 // indirect
|
||||||
golang.org/x/crypto v0.39.0 // indirect
|
golang.org/x/time v0.10.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-20250505200425-f936aa4a68b2 // indirect
|
google.golang.org/genproto v0.0.0-20241104194629-dd2ea8efbc28 // indirect
|
||||||
google.golang.org/genproto/googleapis/api v0.0.0-20250505200425-f936aa4a68b2 // indirect
|
google.golang.org/genproto/googleapis/api v0.0.0-20241209162323-e6fa225c2576 // indirect
|
||||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250603155806-513f23925822 // indirect
|
google.golang.org/genproto/googleapis/rpc v0.0.0-20250207221924-e9438ea467c6 // indirect
|
||||||
google.golang.org/grpc v1.73.0 // indirect
|
google.golang.org/grpc v1.70.0 // indirect
|
||||||
google.golang.org/protobuf v1.36.6 // indirect
|
google.golang.org/protobuf v1.36.5 // 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
217
go.sum
|
@ -1,5 +1,3 @@
|
||||||
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=
|
||||||
|
@ -19,30 +17,26 @@ 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.120.0 h1:wc6bgG9DHyKqF5/vQvX1CiZrtHnxJjBlKUyF9nP6meA=
|
cloud.google.com/go v0.116.0 h1:B3fRrSDkLRt5qSHWe40ERJvhvnQwdZiHu0bJOpldweE=
|
||||||
cloud.google.com/go v0.120.0/go.mod h1:/beW32s8/pGRuj4IILWQNd4uuebeT4dkOhKmkfit64Q=
|
cloud.google.com/go v0.116.0/go.mod h1:cEPSRWPzZEswwdr9BxE6ChEn01dWlTaF05LiC2Xs70U=
|
||||||
cloud.google.com/go/auth v0.16.2 h1:QvBAGFPLrDeoiNjyfVunhQ10HKNYuOwZ5noee0M5df4=
|
cloud.google.com/go/auth v0.14.1 h1:AwoJbzUdxA/whv1qj3TLKwh3XX5sikny2fc40wUl+h0=
|
||||||
cloud.google.com/go/auth v0.16.2/go.mod h1:sRBas2Y1fB1vZTdurouM0AzuYQBMZinrUYL8EufhtEA=
|
cloud.google.com/go/auth v0.14.1/go.mod h1:4JHUxlGXisL0AW8kXPtUF6ztuOksyfUQNFjfsOCXkPM=
|
||||||
cloud.google.com/go/auth/oauth2adapt v0.2.8 h1:keo8NaayQZ6wimpNSmW5OPc283g65QNIiLpZnkHRbnc=
|
cloud.google.com/go/auth/oauth2adapt v0.2.7 h1:/Lc7xODdqcEw8IrZ9SvwnlLX6j9FHQM74z6cBk9Rw6M=
|
||||||
cloud.google.com/go/auth/oauth2adapt v0.2.8/go.mod h1:XQ9y31RkqZCcwJWNSx2Xvric3RrU88hAYYbjDWYDL+c=
|
cloud.google.com/go/auth/oauth2adapt v0.2.7/go.mod h1:NTbTTzfvPl1Y3V1nPpOgl2w6d/FjO7NNUQaWSox6ZMc=
|
||||||
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.7.0 h1:PBWF+iiAerVNe8UCHxdOt6eHLVc3ydFeOCw78U8ytSU=
|
cloud.google.com/go/compute/metadata v0.6.0 h1:A6hENjEsCDtC1k8byVsgwvVcioamEHvZ4j01OwKxG9I=
|
||||||
cloud.google.com/go/compute/metadata v0.7.0/go.mod h1:j5MvL9PprKL39t166CoB1uVHfQMs4tFQZZcKwksXUjo=
|
cloud.google.com/go/compute/metadata v0.6.0/go.mod h1:FjyFAW1MW0C203CEOMDTu3Dk1FlqW3Rga40jzHL4hfg=
|
||||||
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.5.2 h1:qgFRAGEmd8z6dJ/qyEchAuL9jpswyODjA2lS+w234g8=
|
cloud.google.com/go/iam v1.2.2 h1:ozUSofHUGf/F4tCNy/mu9tHLTaxZFLOUiKzjcgWHGIA=
|
||||||
cloud.google.com/go/iam v1.5.2/go.mod h1:SE1vg0N81zQqLzQEwxL2WI6yhetBdbNQuTvIKCSkUHE=
|
cloud.google.com/go/iam v1.2.2/go.mod h1:0Ys8ccaZHdI1dEUilwzqng/6ps2YB6vRsjIe00/+6JY=
|
||||||
cloud.google.com/go/logging v1.13.0 h1:7j0HgAp0B94o1YRDqiqm26w4q1rDMH7XNRU34lJXHYc=
|
cloud.google.com/go/longrunning v0.6.2 h1:xjDfh1pQcWPEvnfjZmwjKQEcHnpz6lHjfy7Fo0MK+hc=
|
||||||
cloud.google.com/go/logging v1.13.0/go.mod h1:36CoKh6KA/M0PbhPKMq6/qety2DCAErbhXT62TuXALA=
|
cloud.google.com/go/longrunning v0.6.2/go.mod h1:k/vIs83RN4bE3YCswdXC5PFfWVILjm3hpEUlSko4PiI=
|
||||||
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=
|
||||||
|
@ -53,10 +47,8 @@ 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.50.0 h1:3TbVkzTooBvnZsk7WaAQfOsNrdoM8QHusXA1cpk6QJs=
|
cloud.google.com/go/storage v1.43.0 h1:CcxnSohZwizt4LCzQHWvBf1/kvtHUn7gk9QERXPyXFs=
|
||||||
cloud.google.com/go/storage v1.50.0/go.mod h1:l7XeiD//vx5lfqE3RavfmU9yvk5Pp0Zhcv482poyafY=
|
cloud.google.com/go/storage v1.43.0/go.mod h1:ajvxEa7WmZS1PxvKRq4bq0tFT3vMd502JwstCcYv0Q0=
|
||||||
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=
|
||||||
|
@ -79,26 +71,18 @@ 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.18.0 h1:6h53Q4hW83SuF+jcsp7CVhLsMozzvQvO8HBbKQW+gn4=
|
github.com/alecthomas/chroma/v2 v2.17.2 h1:Rm81SCZ2mPoH+Q8ZCc/9YvzPUN/E7HgPiPJD8SLV6GI=
|
||||||
github.com/alecthomas/chroma/v2 v2.18.0/go.mod h1:RVX6AvYm4VfYe/zsk7mjHueLDZor3aWCNE14TFlepBk=
|
github.com/alecthomas/chroma/v2 v2.17.2/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.4 h1:GySzjhVvx0ERP6eyfAbAuAXLtAda5TEy19E5q5W8I9E=
|
github.com/aws/aws-sdk-go-v2 v1.36.1 h1:iTDl5U6oAhkNPba0e1t1hrwAo02ZMqbrGq4k5JBWM5E=
|
||||||
github.com/aws/aws-sdk-go-v2 v1.36.4/go.mod h1:LLXuLpgzEbD766Z5ECcRmi8AzSwfZItDtmABVkRLGzg=
|
github.com/aws/aws-sdk-go-v2 v1.36.1/go.mod h1:5PMILGVKiW32oDzjj6RU52yrNrDPUHcbZQYr1sM7qmM=
|
||||||
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=
|
||||||
|
@ -183,8 +167,6 @@ 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=
|
||||||
|
@ -203,17 +185,9 @@ 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/envoyproxy/protoc-gen-validate v1.2.1 h1:DEo3O99U8j4hBFwbJfrz9VtgcDfUKS7KJ7spH3d86P8=
|
github.com/evanw/esbuild v0.25.3 h1:4JKyUsm/nHDhpxis4IyWXAi8GiyTwG1WdEp6OhGVE8U=
|
||||||
github.com/envoyproxy/protoc-gen-validate v1.2.1/go.mod h1:d/C80l/jxXLdfEIhX1W2TmLfsJ31lvEjwamM4DxlWXU=
|
github.com/evanw/esbuild v0.25.3/go.mod h1:D2vIQZqV/vIf/VRHtViaUtViZmG7o+kKmlBfVQuRi48=
|
||||||
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=
|
||||||
|
@ -234,8 +208,6 @@ 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=
|
||||||
|
@ -345,12 +317,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.6 h1:GW/XbdyBFQ8Qe+YAmFU9uHLo7OnF5tL52HFAgMmyrf4=
|
github.com/googleapis/enterprise-certificate-proxy v0.3.4 h1:XYIDZApgAnrN1c855gTgghdIA6Stxb52D5RnLI1SLyw=
|
||||||
github.com/googleapis/enterprise-certificate-proxy v0.3.6/go.mod h1:MkHOF77EYAE7qfSuSS9PU6g4Nt4e11cnsDUowfwewLA=
|
github.com/googleapis/enterprise-certificate-proxy v0.3.4/go.mod h1:YKe7cfqYXjKGpGvmSg28/fFvhNzinZQm8DGnaburhGA=
|
||||||
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.2 h1:eBLnkZ9635krYIPD+ag1USrOAI0Nr0QYF3+/3GqO0k0=
|
github.com/googleapis/gax-go/v2 v2.14.1 h1:hb0FFeiPaQskmvakKu5EbCbpntQn48jyHuvrkurSS/Q=
|
||||||
github.com/googleapis/gax-go/v2 v2.14.2/go.mod h1:ON64QhlJkhVtSqp4v1uaK92VyZ2gmvDQsweuyLV+8+w=
|
github.com/googleapis/gax-go/v2 v2.14.1/go.mod h1:Hb/NubMaVM88SrNkvl8X/o8XWwDJEPqouaLeN2IUxoA=
|
||||||
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=
|
||||||
|
@ -404,8 +376,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.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6TULQc=
|
github.com/mattn/go-runewidth v0.0.9 h1:Lm995f3rfxdpd6TSmuVCHVb/QhupuXlYr8sCI/QdE+0=
|
||||||
github.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
|
github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
|
||||||
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=
|
||||||
|
@ -416,18 +388,14 @@ 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.8.0 h1:WyGLaajLLp8JbQzkmapZ1y0MOzKuKV47HkZRloi+HGY=
|
github.com/niklasfasching/go-org v1.7.0 h1:vyMdcMWWTe/XmANk19F4k8XGBYg0GQ/gJGMimOjGMek=
|
||||||
github.com/niklasfasching/go-org v1.8.0/go.mod h1:e2A9zJs7cdONrEGs3gvxCcaAEpwwPNPG7csDpXckMNg=
|
github.com/niklasfasching/go-org v1.7.0/go.mod h1:WuVm4d45oePiE0eX25GqTDQIt/qPW1T9DGkRscqLW5o=
|
||||||
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/errors v0.0.0-20250405072817-4e6d85265da6 h1:r3FaAI0NZK3hSmtTDrBVREhKULp8oUeqLT5Eyl2mSPo=
|
github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec=
|
||||||
github.com/olekukonko/errors v0.0.0-20250405072817-4e6d85265da6/go.mod h1:ppzxA5jBKcO1vIpCXQ9ZqgDh8iwODz6OXIGKU8r5m4Y=
|
github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY=
|
||||||
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=
|
||||||
|
@ -440,16 +408,12 @@ 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=
|
||||||
|
@ -464,16 +428,14 @@ 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.9.2 h1:SsGfm7M8QOFtEzumm7UZrZdLLquNdzFYfIbEXntcFbE=
|
github.com/spf13/cast v1.7.1 h1:cuNEagBQEHWN1FnbGEjCXL2szYEXqfJPbP2HNUaca9Y=
|
||||||
github.com/spf13/cast v1.9.2/go.mod h1:jNfB8QC9IA6ZuY2ZjDp0KtFO2LZZlg4S/7bzP6qqeHo=
|
github.com/spf13/cast v1.7.1/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo=
|
||||||
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=
|
||||||
|
@ -487,12 +449,13 @@ 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.23.8 h1:tvjHzRer46kwOfpdCBCWsDblCw3QtnLJRd61pTVkyZ8=
|
github.com/tdewolff/minify/v2 v2.20.37 h1:Q97cx4STXCh1dlWDlNHZniE8BJ2EBL0+2b0n92BJQhw=
|
||||||
github.com/tdewolff/minify/v2 v2.23.8/go.mod h1:VW3ISUd3gDOZuQ/jwZr4sCzsuX+Qvsx87FDMjk6Rvno=
|
github.com/tdewolff/minify/v2 v2.20.37/go.mod h1:L1VYef/jwKw6Wwyk5A+T0mBjjn3mMPgmjjA688RNsxU=
|
||||||
github.com/tdewolff/parse/v2 v2.8.1 h1:J5GSHru6o3jF1uLlEKVXkDxxcVx6yzOlIVIotK4w2po=
|
github.com/tdewolff/parse/v2 v2.7.15 h1:hysDXtdGZIRF5UZXwpfn3ZWRbm+ru4l53/ajBRGpCTw=
|
||||||
github.com/tdewolff/parse/v2 v2.8.1/go.mod h1:Hwlni2tiVNKyzR1o6nUs4FOF07URA+JLBLd6dlIXYqo=
|
github.com/tdewolff/parse/v2 v2.7.15/go.mod h1:3FbJWZp3XT9OWVN3Hmfp0p/a08v4h8J9W1aghka0soA=
|
||||||
github.com/tdewolff/test v1.0.11 h1:FdLbwQVHxqG16SlkGveC0JVyrJN62COWTRyUFzfbtBE=
|
github.com/tdewolff/test v1.0.11-0.20231101010635-f1265d231d52/go.mod h1:6DAvZliBAAnD7rhVgwaM7DE5/d9NMOAJ09SqYqeK4QE=
|
||||||
github.com/tdewolff/test v1.0.11/go.mod h1:XPuWBzvdUzhCuxWO1ojpXsyzsA5bFoS3tO/Q3kFuTG8=
|
github.com/tdewolff/test v1.0.11-0.20240106005702-7de5f7df4739 h1:IkjBCtQOOjIn03u/dMQK9g+Iw9ewps4mCl1nB8Sscbo=
|
||||||
|
github.com/tdewolff/test v1.0.11-0.20240106005702-7de5f7df4739/go.mod h1:XPuWBzvdUzhCuxWO1ojpXsyzsA5bFoS3tO/Q3kFuTG8=
|
||||||
github.com/tetratelabs/wazero v1.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=
|
||||||
|
@ -503,12 +466,10 @@ 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.12 h1:YwGP/rrea2/CnCtUHgjuolG/PnMxdQtPMO5PvaE2/nY=
|
github.com/yuin/goldmark v1.7.11 h1:ZCxLyDMtz0nT2HFfsYG8WZ47Trip2+JyLysKcMYE5bo=
|
||||||
github.com/yuin/goldmark v1.7.12/go.mod h1:ip/1k0VRfGynBgxOz0yCqHrbZXhcjxyuS66Brc7iBKg=
|
github.com/yuin/goldmark v1.7.11/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=
|
||||||
|
@ -519,24 +480,20 @@ 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/detectors/gcp v1.35.0 h1:bGvFt68+KTiAKFlacHW6AhA56GF2rS0bdD3aJYEnmzA=
|
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.58.0 h1:PS8wXpbyaDJQ2VDHHncMe9Vct0Zn1fEjpsjrLxGJoSc=
|
||||||
go.opentelemetry.io/contrib/detectors/gcp v1.35.0/go.mod h1:qGWP8/+ILwMRIUf9uIVLloR1uo5ZYAslM4O6OqUi1DA=
|
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.58.0/go.mod h1:HDBUsEjOuRC0EzKZ1bSaRGZWUBAzo+MhAcUUORSr4D0=
|
||||||
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 h1:yd02MEjBdJkG3uabWP9apV+OuWRIXGDuJEUJbOHmCFU=
|
||||||
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.61.0/go.mod h1:snMWehoOh2wsEwnvvwtDyFCxVeDAODenXHtn5vzrKjo=
|
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.58.0/go.mod h1:umTcuxiv1n/s/S6/c2AT/g2CQ7u5C59sHDNmfSwgz7Q=
|
||||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0 h1:F7Jx+6hwnZ41NSFTO5q4LYDtJRXBf2PD0rNBkeB/lus=
|
go.opentelemetry.io/otel v1.34.0 h1:zRLXxLCgL1WyKsPVrgbSdMN4c0FMkDAskSTQP+0hdUY=
|
||||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0/go.mod h1:UHB22Z8QsdRDrnAtX4PntOl36ajSxcdUMt1sF7Y6E7Q=
|
go.opentelemetry.io/otel v1.34.0/go.mod h1:OWFPOQ+h4G8xpyjgqo4SxJYdDQ/qmRH+wivy7zzx9oI=
|
||||||
go.opentelemetry.io/otel v1.36.0 h1:UumtzIklRBY6cI/lllNZlALOF5nNIzJVb16APdvgTXg=
|
go.opentelemetry.io/otel/metric v1.34.0 h1:+eTR3U0MyfWjRDhmFMxe2SsW64QrZ84AOhvqS7Y+PoQ=
|
||||||
go.opentelemetry.io/otel v1.36.0/go.mod h1:/TcFMXYjyRNh8khOAO9ybYkqaDBb/70aVwkNML4pP8E=
|
go.opentelemetry.io/otel/metric v1.34.0/go.mod h1:CEDrp0fy2D0MvkXE+dPV7cMi8tWZwX3dmaIhwPOaqHE=
|
||||||
go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.29.0 h1:WDdP9acbMYjbKIyJUhTvtzj601sVJOqgWdUxSdR/Ysc=
|
go.opentelemetry.io/otel/sdk v1.34.0 h1:95zS4k/2GOy069d321O8jWgYsW3MzVV+KuSPKp7Wr1A=
|
||||||
go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.29.0/go.mod h1:BLbf7zbNIONBLPwvFnwNHGj4zge8uTCM/UPIVW1Mq2I=
|
go.opentelemetry.io/otel/sdk v1.34.0/go.mod h1:0e/pNiaMAqaykJGKbi+tSjWfNNHMTxoC9qANsCzbyxU=
|
||||||
go.opentelemetry.io/otel/metric v1.36.0 h1:MoWPKVhQvJ+eeXWHFBOPoBOi20jh6Iq2CcCREuTYufE=
|
go.opentelemetry.io/otel/sdk/metric v1.32.0 h1:rZvFnvmvawYb0alrYkjraqJq0Z4ZUJAiyYCU9snn1CU=
|
||||||
go.opentelemetry.io/otel/metric v1.36.0/go.mod h1:zC7Ks+yeyJt4xig9DEw9kuUFe5C3zLbVjV2PzT6qzbs=
|
go.opentelemetry.io/otel/sdk/metric v1.32.0/go.mod h1:PWeZlq0zt9YkYAp3gjKZ0eicRYvOh1Gd+X99x6GHpCQ=
|
||||||
go.opentelemetry.io/otel/sdk v1.36.0 h1:b6SYIuLRs88ztox4EyrvRti80uXIFy+Sqzoh9kFULbs=
|
go.opentelemetry.io/otel/trace v1.34.0 h1:+ouXS2V8Rd4hp4580a8q23bg0azF2nI8cqLYnC8mh/k=
|
||||||
go.opentelemetry.io/otel/sdk v1.36.0/go.mod h1:+lC+mTgD+MUWfjJubi2vvXWcVxyr9rmlshZni72pXeY=
|
go.opentelemetry.io/otel/trace v1.34.0/go.mod h1:Svm7lSjQD7kG7KJ/MUHPVXSDGz2OX4h0M2jHBhmSfRE=
|
||||||
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=
|
||||||
|
@ -552,8 +509,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.39.0 h1:SHs+kF4LP+f+p14esP5jAoDpHU8Gu/v9lFRK6IT5imM=
|
golang.org/x/crypto v0.37.0 h1:kJNSjF/Xp7kU0iB2Z+9viTPMW4EqqsrywMXLJOOsXSE=
|
||||||
golang.org/x/crypto v0.39.0/go.mod h1:L+Xg3Wf6HoL4Bn4238Z6ft6KfEpN0tJGo53AAPC632U=
|
golang.org/x/crypto v0.37.0/go.mod h1:vg+k43peMZ0pUMhYmVAWysMK35e6ioLh3wB8ZCAfbVc=
|
||||||
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=
|
||||||
|
@ -569,8 +526,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.28.0 h1:gdem5JW1OLS4FbkWgLO+7ZeFzYtL3xClb97GaUzYMFE=
|
golang.org/x/image v0.26.0 h1:4XjIFEZWQmCZi6Wv8BoxsDhRU3RVnLX04dToTDAEPlY=
|
||||||
golang.org/x/image v0.28.0/go.mod h1:GUJYXtnGKEUgggyzh+Vxt+AviiCcyiwpsl8iQ8MvwGY=
|
golang.org/x/image v0.26.0/go.mod h1:lcxbMFAovzpnJxzXS3nyL83K27tmqtKzIJpctK8YO5c=
|
||||||
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=
|
||||||
|
@ -597,8 +554,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.25.0 h1:n7a+ZbQKQA/Ysbyb0/6IbB1H/X41mKgbhfv7AfG/44w=
|
golang.org/x/mod v0.24.0 h1:ZfthKaKaT4NrhGVZHO1/WDTwGES4De8KtWO0SIbNJMU=
|
||||||
golang.org/x/mod v0.25.0/go.mod h1:IXM97Txy2VM4PJ3gI61r1YEk/gAj6zAHN3AdZt6S9Ww=
|
golang.org/x/mod v0.24.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=
|
||||||
|
@ -638,8 +595,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.41.0 h1:vBTly1HeNPEn3wtREYfy4GZ/NECgw2Cnl+nK6Nz3uvw=
|
golang.org/x/net v0.39.0 h1:ZCu7HMWDxpXpaiKdhzIfaltL9Lp31x/3fCP11bc6/fY=
|
||||||
golang.org/x/net v0.41.0/go.mod h1:B/K4NNqkfmg07DQYrbwvSluqCJOOXwUjeb/5lOisjbA=
|
golang.org/x/net v0.39.0/go.mod h1:X7NRbYVEA+ewNkCNyJ513WmMdQ3BineSwVtN2zD/d+E=
|
||||||
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=
|
||||||
|
@ -649,8 +606,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.30.0 h1:dnDm7JmhM45NNpd8FDDeLhK6FwqbOf4MLCM9zb1BOHI=
|
golang.org/x/oauth2 v0.26.0 h1:afQXWNNaeC4nvZ0Ed9XvCCzXM6UHJG7iCg0W4fPqSBE=
|
||||||
golang.org/x/oauth2 v0.30.0/go.mod h1:B++QgG3ZKulg6sRPGD/mqlHQs5rB3Ml9erfeDY7xKlU=
|
golang.org/x/oauth2 v0.26.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI=
|
||||||
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=
|
||||||
|
@ -666,8 +623,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.15.0 h1:KWH3jNZsfyT6xfAfKiz6MRNmd46ByHDYaZ7KSkCtdW8=
|
golang.org/x/sync v0.13.0 h1:AauUjRAJ9OSnvULf/ARrrVywoJDy0YS2AwQ98I37610=
|
||||||
golang.org/x/sync v0.15.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
|
golang.org/x/sync v0.13.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=
|
||||||
|
@ -715,8 +672,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.33.0 h1:q3i8TbbEz+JRD9ywIRlyRAQbM0qF7hu24q3teo2hbuw=
|
golang.org/x/sys v0.32.0 h1:s77OFDvIQeibCmezSnk/q6iAfkdiQaJi4VzroCFrN20=
|
||||||
golang.org/x/sys v0.33.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
|
golang.org/x/sys v0.32.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=
|
||||||
|
@ -735,13 +692,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.26.0 h1:P42AVeLghgTYr4+xUnTRKDMqpar+PtX7KWuNQL21L8M=
|
golang.org/x/text v0.24.0 h1:dd5Bzh4yt5KYA8f9CJHCP4FB4D51c2c6JvN37xJJkJ0=
|
||||||
golang.org/x/text v0.26.0/go.mod h1:QK15LZJUUQVJxhz7wXgxSy/CJaTFjd0G+YLonydOVQA=
|
golang.org/x/text v0.24.0/go.mod h1:L8rBsPeo2pSS+xqN0d5u2ikmjtmoJbDBT1b7nHvFCdU=
|
||||||
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.12.0 h1:ScB/8o8olJvc+CQPWrK3fPZNfh7qgwCrY0zJmoEQLSE=
|
golang.org/x/time v0.10.0 h1:3usCWA8tQn0L8+hFJQNgzpWbd89begxN66o1Ojdn5L4=
|
||||||
golang.org/x/time v0.12.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg=
|
golang.org/x/time v0.10.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
|
||||||
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=
|
||||||
|
@ -794,8 +751,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.34.0 h1:qIpSLOxeCYGg9TrcJokLBG4KFA6d795g0xkBkiESGlo=
|
golang.org/x/tools v0.32.0 h1:Q7N1vhpkQv7ybVzLFtTjvQya2ewbwNDZzUgfXGqtMWU=
|
||||||
golang.org/x/tools v0.34.0/go.mod h1:pAP9OwEaY1CAW3HOmg3hLZC5Z0CCmzjAF2UQMSqNARg=
|
golang.org/x/tools v0.32.0/go.mod h1:ZxrU41P/wAbZD8EDa6dDCa6XfpkhJ7HFMjHJXfBDu8s=
|
||||||
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=
|
||||||
|
@ -821,8 +778,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.237.0 h1:MP7XVsGZesOsx3Q8WVa4sUdbrsTvDSOERd3Vh4xj/wc=
|
google.golang.org/api v0.221.0 h1:qzaJfLhDsbMeFee8zBRdt/Nc+xmOuafD/dbdgGfutOU=
|
||||||
google.golang.org/api v0.237.0/go.mod h1:cOVEm2TpdAGHL2z+UwyS+kmlGr3bVWQQ6sYEqkKje50=
|
google.golang.org/api v0.221.0/go.mod h1:7sOU2+TL4TxUTdbi0gWgAIg7tH5qBXxoyhtL+9x3biQ=
|
||||||
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=
|
||||||
|
@ -866,12 +823,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-20250505200425-f936aa4a68b2 h1:1tXaIXCracvtsRxSBsYDiSBN0cuJvM7QYW+MrpIRY78=
|
google.golang.org/genproto v0.0.0-20241104194629-dd2ea8efbc28 h1:KJjNNclfpIkVqrZlTWcgOOaVQ00LdBnoEaRfkUx760s=
|
||||||
google.golang.org/genproto v0.0.0-20250505200425-f936aa4a68b2/go.mod h1:49MsLSx0oWMOZqcpB3uL8ZOkAh1+TndpJ8ONoCBWiZk=
|
google.golang.org/genproto v0.0.0-20241104194629-dd2ea8efbc28/go.mod h1:mt9/MofW7AWQ+Gy179ChOnvmJatV8YHUmrcedo9CIFI=
|
||||||
google.golang.org/genproto/googleapis/api v0.0.0-20250505200425-f936aa4a68b2 h1:vPV0tzlsK6EzEDHNNH5sa7Hs9bd7iXR7B1tSiPepkV0=
|
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/go.mod h1:pKLAc5OolXC3ViWGI62vvC0n10CpwAtRcTNCFwTKBEw=
|
google.golang.org/genproto/googleapis/api v0.0.0-20241209162323-e6fa225c2576/go.mod h1:1R3kvZ1dtP3+4p4d3G8uJ8rFk/fWlScl38vanWACI08=
|
||||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250603155806-513f23925822 h1:fc6jSaCT0vBduLYZHYrBBNY4dsWuvgyff9noRNDdBeE=
|
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/go.mod h1:qQ0YXyHHx3XkvlzUtpXDkS29lDSafHMZBAZDc03LQ3A=
|
google.golang.org/genproto/googleapis/rpc v0.0.0-20250207221924-e9438ea467c6/go.mod h1:8BS3B93F/U1juMFq9+EDk+qOT5CO1R9IzXxG3PTqiRk=
|
||||||
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=
|
||||||
|
@ -888,8 +845,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.73.0 h1:VIWSmpI2MegBtTuFt5/JWy2oXxtjJ/e89Z70ImfD2ok=
|
google.golang.org/grpc v1.70.0 h1:pWFv03aZoHzlRKHWicjsZytKAiYCtNS0dHbXnIdq7jQ=
|
||||||
google.golang.org/grpc v1.73.0/go.mod h1:50sbHOUqWoCQGI8V2HQLJM0B+LMlIUjNSZmow7EVBQc=
|
google.golang.org/grpc v1.70.0/go.mod h1:ofIJqVKDXx/JiXrwr2IG4/zwdH9txy3IlF40RmcJSQw=
|
||||||
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=
|
||||||
|
@ -900,8 +857,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.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY=
|
google.golang.org/protobuf v1.36.5 h1:tPhr+woSbjfYvY6/GPufUoYizxw1cF/yFoxJ2fmpwlM=
|
||||||
google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY=
|
google.golang.org/protobuf v1.36.5/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
|
||||||
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=
|
||||||
|
|
|
@ -19,8 +19,6 @@ 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.
|
||||||
|
@ -68,6 +66,23 @@ 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)
|
||||||
|
@ -91,26 +106,13 @@ 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.NewTable(
|
table := tablewriter.NewWriter(w)
|
||||||
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.Bulk(data)
|
table.AppendBulk(data)
|
||||||
table.Header(names)
|
table.SetHeader(names)
|
||||||
|
table.SetBorder(false)
|
||||||
table.Render()
|
table.Render()
|
||||||
}
|
}
|
||||||
|
|
|
@ -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,51 +917,3 @@ 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")
|
|
||||||
}
|
|
||||||
|
|
|
@ -1406,7 +1406,7 @@ home = ["html"]
|
||||||
"home": {"html"},
|
"home": {"html"},
|
||||||
"page": {"html"},
|
"page": {"html"},
|
||||||
"rss": {"rss"},
|
"rss": {"rss"},
|
||||||
"section": {},
|
"section": nil,
|
||||||
"taxonomy": {"html", "rss"},
|
"taxonomy": {"html", "rss"},
|
||||||
"term": {"html", "rss"},
|
"term": {"html", "rss"},
|
||||||
})
|
})
|
||||||
|
|
|
@ -356,7 +356,7 @@ func (m *pageMap) addPagesFromGoTmplFi(fi hugofs.FileMetaInfo, buildConfig *Buil
|
||||||
Watching: s.Conf.Watching(),
|
Watching: s.Conf.Watching(),
|
||||||
HandlePage: func(pt *pagesfromdata.PagesFromTemplate, pc *pagemeta.PageConfig) error {
|
HandlePage: func(pt *pagesfromdata.PagesFromTemplate, pc *pagemeta.PageConfig) error {
|
||||||
s := pt.Site.(*Site)
|
s := pt.Site.(*Site)
|
||||||
if err := pc.CompileForPagesFromDataPre(pt.GoTmplFi.Meta().PathInfo.Base(), m.s.Log, s.conf.MediaTypes.Config); err != nil {
|
if err := pc.Compile(pt.GoTmplFi.Meta().PathInfo.Base(), true, "", s.Log, s.conf.MediaTypes.Config); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -21,6 +21,7 @@ import (
|
||||||
"sort"
|
"sort"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
"sync"
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
@ -1309,6 +1310,7 @@ 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
|
||||||
|
@ -1410,7 +1412,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, page.PageMatcherParamsConfig]
|
var cascade *maps.Ordered[page.PageMatcher, maps.Params]
|
||||||
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
|
||||||
|
@ -1422,7 +1424,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, page.PageMatcherParamsConfig])
|
cascade = data.(*maps.Ordered[page.PageMatcher, maps.Params])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1504,11 +1506,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, page.PageMatcherParamsConfig]
|
var cascade *maps.Ordered[page.PageMatcher, maps.Params]
|
||||||
// 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, page.PageMatcherParamsConfig])
|
cascade = data.(*maps.Ordered[page.PageMatcher, maps.Params])
|
||||||
}
|
}
|
||||||
if err := pageResource.setMetaPost(cascade); err != nil {
|
if err := pageResource.setMetaPost(cascade); err != nil {
|
||||||
return false, err
|
return false, err
|
||||||
|
@ -1572,10 +1574,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, page.PageMatcherParamsConfig]
|
var cascade *maps.Ordered[page.PageMatcher, maps.Params]
|
||||||
_, data := pw.WalkContext.Data().LongestPrefix(s)
|
_, data := pw.WalkContext.Data().LongestPrefix(s)
|
||||||
if data != nil {
|
if data != nil {
|
||||||
cascade = data.(*maps.Ordered[page.PageMatcher, page.PageMatcherParamsConfig])
|
cascade = data.(*maps.Ordered[page.PageMatcher, maps.Params])
|
||||||
}
|
}
|
||||||
if err := p.setMetaPost(cascade); err != nil {
|
if err := p.setMetaPost(cascade); err != nil {
|
||||||
return false, err
|
return false, err
|
||||||
|
@ -1693,11 +1695,9 @@ func (sa *sitePagesAssembler) assembleTermsAndTranslations() error {
|
||||||
pathInfo: pi,
|
pathInfo: pi,
|
||||||
pageMetaParams: &pageMetaParams{
|
pageMetaParams: &pageMetaParams{
|
||||||
pageConfig: &pagemeta.PageConfig{
|
pageConfig: &pagemeta.PageConfig{
|
||||||
PageConfigEarly: pagemeta.PageConfigEarly{
|
|
||||||
Kind: kinds.KindTerm,
|
Kind: kinds.KindTerm,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
|
||||||
}
|
}
|
||||||
n, pi, err := sa.h.newPage(m)
|
n, pi, err := sa.h.newPage(m)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -1956,11 +1956,9 @@ func (sa *sitePagesAssembler) addStandalonePages() error {
|
||||||
pathInfo: s.Conf.PathParser().Parse(files.ComponentFolderContent, key+f.MediaType.FirstSuffix.FullSuffix),
|
pathInfo: s.Conf.PathParser().Parse(files.ComponentFolderContent, key+f.MediaType.FirstSuffix.FullSuffix),
|
||||||
pageMetaParams: &pageMetaParams{
|
pageMetaParams: &pageMetaParams{
|
||||||
pageConfig: &pagemeta.PageConfig{
|
pageConfig: &pagemeta.PageConfig{
|
||||||
PageConfigEarly: pagemeta.PageConfigEarly{
|
|
||||||
Kind: kind,
|
Kind: kind,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
|
||||||
standaloneOutputFormat: f,
|
standaloneOutputFormat: f,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2084,11 +2082,9 @@ func (sa *sitePagesAssembler) addMissingRootSections() error {
|
||||||
pathInfo: p,
|
pathInfo: p,
|
||||||
pageMetaParams: &pageMetaParams{
|
pageMetaParams: &pageMetaParams{
|
||||||
pageConfig: &pagemeta.PageConfig{
|
pageConfig: &pagemeta.PageConfig{
|
||||||
PageConfigEarly: pagemeta.PageConfigEarly{
|
|
||||||
Kind: kinds.KindHome,
|
Kind: kinds.KindHome,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
|
||||||
}
|
}
|
||||||
n, p, err := sa.h.newPage(m)
|
n, p, err := sa.h.newPage(m)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -2119,11 +2115,9 @@ func (sa *sitePagesAssembler) addMissingTaxonomies() error {
|
||||||
pathInfo: sa.Conf.PathParser().Parse(files.ComponentFolderContent, key+"/_index.md"),
|
pathInfo: sa.Conf.PathParser().Parse(files.ComponentFolderContent, key+"/_index.md"),
|
||||||
pageMetaParams: &pageMetaParams{
|
pageMetaParams: &pageMetaParams{
|
||||||
pageConfig: &pagemeta.PageConfig{
|
pageConfig: &pagemeta.PageConfig{
|
||||||
PageConfigEarly: pagemeta.PageConfigEarly{
|
|
||||||
Kind: kinds.KindTaxonomy,
|
Kind: kinds.KindTaxonomy,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
|
||||||
singular: viewName.singular,
|
singular: viewName.singular,
|
||||||
}
|
}
|
||||||
p, _, _ := sa.h.newPage(m)
|
p, _, _ := sa.h.newPage(m)
|
||||||
|
|
|
@ -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
|
||||||
---
|
---
|
||||||
|
|
|
@ -263,7 +263,7 @@ func (s *IntegrationTestBuilder) AssertLogContains(els ...string) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// AssertLogMatches asserts that the last build log matches the given regular expressions.
|
// AssertLogNotContains asserts that the last build log does 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()
|
||||||
|
|
|
@ -19,6 +19,7 @@ import (
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
"sync"
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
|
|
||||||
"github.com/gohugoio/hugo/hugofs"
|
"github.com/gohugoio/hugo/hugofs"
|
||||||
|
@ -28,7 +29,6 @@ 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,6 +111,7 @@ type pageState struct {
|
||||||
|
|
||||||
resource.Staler
|
resource.Staler
|
||||||
dependencyManager identity.Manager
|
dependencyManager identity.Manager
|
||||||
|
resourcesPublishInit *sync.Once
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *pageState) incrPageOutputTemplateVariation() {
|
func (p *pageState) incrPageOutputTemplateVariation() {
|
||||||
|
@ -479,7 +480,7 @@ func (ps *pageState) initCommonProviders(pp pagePaths) error {
|
||||||
func (po *pageOutput) GetInternalTemplateBasePathAndDescriptor() (string, tplimpl.TemplateDescriptor) {
|
func (po *pageOutput) GetInternalTemplateBasePathAndDescriptor() (string, tplimpl.TemplateDescriptor) {
|
||||||
p := po.p
|
p := po.p
|
||||||
f := po.f
|
f := po.f
|
||||||
base := p.PathInfo().BaseReTyped(p.m.Type())
|
base := p.PathInfo().BaseReTyped(p.m.pageConfig.Type)
|
||||||
return base, tplimpl.TemplateDescriptor{
|
return base, tplimpl.TemplateDescriptor{
|
||||||
Kind: p.Kind(),
|
Kind: p.Kind(),
|
||||||
Lang: p.Language().Lang,
|
Lang: p.Language().Lang,
|
||||||
|
@ -521,23 +522,26 @@ func (p *pageState) initPage() error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *pageState) renderResources() error {
|
func (p *pageState) renderResources() error {
|
||||||
for _, r := range p.Resources() {
|
var initErr error
|
||||||
|
|
||||||
|
p.resourcesPublishInit.Do(func() {
|
||||||
|
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 resources.IsPublished(r) {
|
if _, isWrapper := r.(resource.ResourceWrapper); isWrapper {
|
||||||
|
// 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 {
|
||||||
return fmt.Errorf("resource %T does not support resource.Source", r)
|
initErr = fmt.Errorf("resource %T does not support resource.Source", r)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := src.Publish(); err != nil {
|
if err := src.Publish(); err != nil {
|
||||||
|
@ -548,8 +552,9 @@ 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 nil
|
return initErr
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *pageState) AlternativeOutputFormats() page.OutputFormats {
|
func (p *pageState) AlternativeOutputFormats() page.OutputFormats {
|
||||||
|
|
|
@ -29,6 +29,7 @@ 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"
|
||||||
|
@ -53,6 +54,7 @@ type pageMeta struct {
|
||||||
|
|
||||||
resource.Staler
|
resource.Staler
|
||||||
*pageMetaParams
|
*pageMetaParams
|
||||||
|
pageMetaFrontMatter
|
||||||
|
|
||||||
// Set for standalone pages, e.g. robotsTXT.
|
// Set for standalone pages, e.g. robotsTXT.
|
||||||
standaloneOutputFormat output.Format
|
standaloneOutputFormat output.Format
|
||||||
|
@ -71,7 +73,13 @@ type pageMeta struct {
|
||||||
// Prepare for a rebuild of the data passed in from front matter.
|
// Prepare for a rebuild of the data passed in from front matter.
|
||||||
func (m *pageMeta) setMetaPostPrepareRebuild() {
|
func (m *pageMeta) setMetaPostPrepareRebuild() {
|
||||||
params := xmaps.Clone(m.paramsOriginal)
|
params := xmaps.Clone(m.paramsOriginal)
|
||||||
m.pageMetaParams.pageConfig = pagemeta.ClonePageConfigForRebuild(m.pageMetaParams.pageConfig, params)
|
m.pageMetaParams.pageConfig = &pagemeta.PageConfig{
|
||||||
|
Kind: m.pageConfig.Kind,
|
||||||
|
Lang: m.pageConfig.Lang,
|
||||||
|
Path: m.pageConfig.Path,
|
||||||
|
Params: params,
|
||||||
|
}
|
||||||
|
m.pageMetaFrontMatter = pageMetaFrontMatter{}
|
||||||
}
|
}
|
||||||
|
|
||||||
type pageMetaParams struct {
|
type pageMetaParams struct {
|
||||||
|
@ -83,16 +91,17 @@ 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, page.PageMatcherParamsConfig] // contains the original cascade as defined in the front matter.
|
cascadeOriginal *maps.Ordered[page.PageMatcher, maps.Params] // contains the original cascade as defined in the front matter.
|
||||||
|
}
|
||||||
|
|
||||||
|
// From page front matter.
|
||||||
|
type pageMetaFrontMatter struct {
|
||||||
|
configuredOutputFormats output.Formats // outputs defined in front matter.
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *pageMetaParams) init(preserveOriginal bool) {
|
func (m *pageMetaParams) init(preserveOriginal bool) {
|
||||||
if preserveOriginal {
|
if preserveOriginal {
|
||||||
if m.pageConfig.IsFromContentAdapter {
|
m.paramsOriginal = xmaps.Clone[maps.Params](m.pageConfig.Params)
|
||||||
m.paramsOriginal = xmaps.Clone(m.pageConfig.ContentAdapterData)
|
|
||||||
} else {
|
|
||||||
m.paramsOriginal = xmaps.Clone(m.pageConfig.Params)
|
|
||||||
}
|
|
||||||
m.cascadeOriginal = m.pageConfig.CascadeCompiled.Clone()
|
m.cascadeOriginal = m.pageConfig.CascadeCompiled.Clone()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -252,7 +261,7 @@ func (p *pageMeta) setMetaPre(pi *contentParseInfo, logger loggers.Logger, conf
|
||||||
// Check for any cascade define on itself.
|
// Check for any cascade define on itself.
|
||||||
if cv, found := frontmatter["cascade"]; found {
|
if cv, found := frontmatter["cascade"]; found {
|
||||||
var err error
|
var err error
|
||||||
cascade, err := page.DecodeCascade(logger, true, cv)
|
cascade, err := page.DecodeCascade(logger, cv)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -290,7 +299,7 @@ func (p *pageMeta) setMetaPre(pi *contentParseInfo, logger loggers.Logger, conf
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ps *pageState) setMetaPost(cascade *maps.Ordered[page.PageMatcher, page.PageMatcherParamsConfig]) error {
|
func (ps *pageState) setMetaPost(cascade *maps.Ordered[page.PageMatcher, maps.Params]) error {
|
||||||
ps.m.setMetaPostCount++
|
ps.m.setMetaPostCount++
|
||||||
var cascadeHashPre uint64
|
var cascadeHashPre uint64
|
||||||
if ps.m.setMetaPostCount > 1 {
|
if ps.m.setMetaPostCount > 1 {
|
||||||
|
@ -302,20 +311,15 @@ func (ps *pageState) setMetaPost(cascade *maps.Ordered[page.PageMatcher, page.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 page.PageMatcherParamsConfig) bool {
|
cascade.Range(func(k page.PageMatcher, v maps.Params) 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.Params {
|
for ck, cv := range v {
|
||||||
if _, found := vv.Params[ck]; !found {
|
if _, found := vv[ck]; !found {
|
||||||
vv.Params[ck] = cv
|
vv[ck] = cv
|
||||||
}
|
|
||||||
}
|
|
||||||
for ck, cv := range v.Fields {
|
|
||||||
if _, found := vv.Fields[ck]; !found {
|
|
||||||
vv.Fields[ck] = cv
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -344,35 +348,18 @@ func (ps *pageState) setMetaPost(cascade *maps.Ordered[page.PageMatcher, page.Pa
|
||||||
}
|
}
|
||||||
|
|
||||||
// Cascade is also applied to itself.
|
// Cascade is also applied to itself.
|
||||||
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.Params {
|
for kk, vv := range v {
|
||||||
if _, found := ps.m.pageConfig.Params[kk]; !found {
|
if _, found := ps.m.pageConfig.Params[kk]; !found {
|
||||||
ps.m.pageConfig.Params[kk] = vv
|
ps.m.pageConfig.Params[kk] = vv
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for kk, vv := range v.Fields {
|
|
||||||
if ps.m.pageConfig.IsFromContentAdapter {
|
|
||||||
if _, found := ps.m.pageConfig.ContentAdapterData[kk]; !found {
|
|
||||||
ps.m.pageConfig.ContentAdapterData[kk] = vv
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if _, found := ps.m.pageConfig.Params[kk]; !found {
|
|
||||||
ps.m.pageConfig.Params[kk] = vv
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true
|
return true
|
||||||
})
|
})
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := ps.setMetaPostParams(); err != nil {
|
if err := ps.setMetaPostParams(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -418,12 +405,6 @@ func (p *pageState) setMetaPostParams() error {
|
||||||
PathOrTitle: p.pathOrTitle(),
|
PathOrTitle: p.pathOrTitle(),
|
||||||
}
|
}
|
||||||
|
|
||||||
if isContentAdapter {
|
|
||||||
if err := pm.pageConfig.Compile(ext, p.s.Log, p.s.conf.OutputFormats.Config, p.s.conf.MediaTypes.Config); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Handle the date separately
|
// Handle the date separately
|
||||||
// TODO(bep) we need to "do more" in this area so this can be split up and
|
// TODO(bep) we need to "do more" in this area so this can be split up and
|
||||||
// more easily tested without the Page, but the coupling is strong.
|
// more easily tested without the Page, but the coupling is strong.
|
||||||
|
@ -550,7 +531,16 @@ params:
|
||||||
for i, s := range o {
|
for i, s := range o {
|
||||||
o[i] = strings.ToLower(s)
|
o[i] = strings.ToLower(s)
|
||||||
}
|
}
|
||||||
pm.pageConfig.Outputs = o
|
if len(o) > 0 {
|
||||||
|
// Output formats are explicitly set in front matter, use those.
|
||||||
|
outFormats, err := p.s.conf.OutputFormats.Config.GetByNames(o...)
|
||||||
|
if err != nil {
|
||||||
|
p.s.Log.Errorf("Failed to resolve output formats: %s", err)
|
||||||
|
} else {
|
||||||
|
pm.configuredOutputFormats = outFormats
|
||||||
|
params[loki] = outFormats
|
||||||
|
}
|
||||||
|
}
|
||||||
case "draft":
|
case "draft":
|
||||||
draft = new(bool)
|
draft = new(bool)
|
||||||
*draft = cast.ToBool(v)
|
*draft = cast.ToBool(v)
|
||||||
|
@ -646,6 +636,9 @@ 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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -679,7 +672,7 @@ params:
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := pcfg.Compile(ext, p.s.Log, p.s.conf.OutputFormats.Config, p.s.conf.MediaTypes.Config); err != nil {
|
if err := pcfg.Compile("", false, ext, p.s.Log, p.s.conf.MediaTypes.Config); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -836,8 +829,8 @@ func (p *pageMeta) newContentConverter(ps *pageState, markup string) (converter.
|
||||||
|
|
||||||
// The output formats this page will be rendered to.
|
// The output formats this page will be rendered to.
|
||||||
func (m *pageMeta) outputFormats() output.Formats {
|
func (m *pageMeta) outputFormats() output.Formats {
|
||||||
if len(m.pageConfig.ConfiguredOutputFormats) > 0 {
|
if len(m.configuredOutputFormats) > 0 {
|
||||||
return m.pageConfig.ConfiguredOutputFormats
|
return m.configuredOutputFormats
|
||||||
}
|
}
|
||||||
return m.s.conf.C.KindOutputFormats[m.Kind()]
|
return m.s.conf.C.KindOutputFormats[m.Kind()]
|
||||||
}
|
}
|
||||||
|
|
|
@ -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,14 +40,6 @@ 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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -198,6 +190,7 @@ 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{
|
||||||
|
|
|
@ -1968,93 +1968,3 @@ 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.")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Issue 13826
|
|
||||||
func TestTemplateSelectionIssue13826(t *testing.T) {
|
|
||||||
t.Parallel()
|
|
||||||
|
|
||||||
files := `
|
|
||||||
-- hugo.toml --
|
|
||||||
disableKinds = ['home','rss','section','sitemap','taxonomy','term']
|
|
||||||
-- content/p1.md --
|
|
||||||
---
|
|
||||||
title: p1 (type implicitly set to page)
|
|
||||||
---
|
|
||||||
-- content/p2.md --
|
|
||||||
---
|
|
||||||
title: p2 (type explicitly set to page)
|
|
||||||
type: page
|
|
||||||
---
|
|
||||||
-- content/p3.md --
|
|
||||||
---
|
|
||||||
title: p3 (type explicitly set to foo)
|
|
||||||
type: foo
|
|
||||||
---
|
|
||||||
-- content/foo/p4.md --
|
|
||||||
---
|
|
||||||
title: p4 (type implicitly set to foo)
|
|
||||||
---
|
|
||||||
-- content/bar/p5.md --
|
|
||||||
---
|
|
||||||
title: p5 (type explicitly set to foo)
|
|
||||||
type: foo
|
|
||||||
---
|
|
||||||
-- layouts/page/page.html --
|
|
||||||
layouts/page/page.html
|
|
||||||
-- layouts/foo/page.html --
|
|
||||||
layouts/foo/page.html
|
|
||||||
-- layouts/page.html --
|
|
||||||
layouts/page.html
|
|
||||||
`
|
|
||||||
|
|
||||||
b := Test(t, files)
|
|
||||||
|
|
||||||
b.AssertFileContent("public/p1/index.html", "layouts/page/page.html")
|
|
||||||
b.AssertFileContent("public/p2/index.html", "layouts/page/page.html")
|
|
||||||
b.AssertFileContent("public/p3/index.html", "layouts/foo/page.html")
|
|
||||||
b.AssertFileContent("public/foo/p4/index.html", "layouts/foo/page.html")
|
|
||||||
b.AssertFileContent("public/bar/p5/index.html", "layouts/foo/page.html")
|
|
||||||
|
|
||||||
files = strings.ReplaceAll(files, "-- layouts/page/page.html --", "-- delete-me-1.txt --")
|
|
||||||
files = strings.ReplaceAll(files, "-- layouts/foo/page.html --", "-- delete-me-2.txt --")
|
|
||||||
|
|
||||||
b = Test(t, files)
|
|
||||||
|
|
||||||
b.AssertFileContent("public/p1/index.html", "layouts/page.html")
|
|
||||||
b.AssertFileContent("public/p2/index.html", "layouts/page.html")
|
|
||||||
b.AssertFileContent("public/p3/index.html", "layouts/page.html")
|
|
||||||
b.AssertFileContent("public/foo/p4/index.html", "layouts/page.html")
|
|
||||||
b.AssertFileContent("public/bar/p5/index.html", "layouts/page.html")
|
|
||||||
}
|
|
||||||
|
|
|
@ -91,20 +91,17 @@ func (p *pagesFromDataTemplateContext) AddPage(v any) (string, error) {
|
||||||
|
|
||||||
pd := pagemeta.DefaultPageConfig
|
pd := pagemeta.DefaultPageConfig
|
||||||
pd.IsFromContentAdapter = true
|
pd.IsFromContentAdapter = true
|
||||||
pd.ContentAdapterData = m
|
|
||||||
|
|
||||||
// The rest will be handled after the cascade is calculated and applied.
|
if err := mapstructure.WeakDecode(m, &pd); err != nil {
|
||||||
if err := mapstructure.WeakDecode(pd.ContentAdapterData, &pd.PageConfigEarly); err != nil {
|
return "", fmt.Errorf("failed to decode page map: %w", err)
|
||||||
err = fmt.Errorf("failed to decode page map: %w", err)
|
|
||||||
return "", err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
p.p.buildState.NumPagesAdded++
|
||||||
|
|
||||||
if err := pd.Validate(true); err != nil {
|
if err := pd.Validate(true); err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
p.p.buildState.NumPagesAdded++
|
|
||||||
|
|
||||||
return "", p.p.HandlePage(p.p, &pd)
|
return "", p.p.HandlePage(p.p, &pd)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -779,139 +779,3 @@ Single.
|
||||||
|
|
||||||
b.AssertFileContent("public/tags/index.html", "Terms: mytag: 1|§s")
|
b.AssertFileContent("public/tags/index.html", "Terms: mytag: 1|§s")
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestContentAdapterOutputsIssue13689(t *testing.T) {
|
|
||||||
t.Parallel()
|
|
||||||
|
|
||||||
files := `
|
|
||||||
-- hugo.toml --
|
|
||||||
disableKinds = ['home','rss','section','sitemap','taxonomy','term']
|
|
||||||
[outputs]
|
|
||||||
page = ['html','json']
|
|
||||||
-- layouts/page.html --
|
|
||||||
html: {{ .Title }}
|
|
||||||
-- layouts/page.json --
|
|
||||||
json: {{ .Title }}
|
|
||||||
-- content/p1.md --
|
|
||||||
---
|
|
||||||
title: p1
|
|
||||||
---
|
|
||||||
-- content/p2.md --
|
|
||||||
---
|
|
||||||
title: p2
|
|
||||||
outputs:
|
|
||||||
- html
|
|
||||||
---
|
|
||||||
-- content/_content.gotmpl --
|
|
||||||
{{ $page := dict "path" "p3" "title" "p3" }}
|
|
||||||
{{ $.AddPage $page }}
|
|
||||||
|
|
||||||
{{ $page := dict "path" "p4" "title" "p4" "outputs" (slice "html") }}
|
|
||||||
{{ $.AddPage $page }}
|
|
||||||
`
|
|
||||||
|
|
||||||
b := hugolib.Test(t, files)
|
|
||||||
|
|
||||||
b.AssertFileExists("public/p1/index.html", true)
|
|
||||||
b.AssertFileExists("public/p1/index.json", true)
|
|
||||||
b.AssertFileExists("public/p2/index.html", true)
|
|
||||||
b.AssertFileExists("public/p2/index.json", false)
|
|
||||||
b.AssertFileExists("public/p3/index.html", true)
|
|
||||||
b.AssertFileExists("public/p3/index.json", true)
|
|
||||||
b.AssertFileExists("public/p4/index.html", true)
|
|
||||||
b.AssertFileExists("public/p4/index.json", false) // currently returns true
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestContentAdapterOutputsIssue13692(t *testing.T) {
|
|
||||||
t.Parallel()
|
|
||||||
|
|
||||||
files := `
|
|
||||||
-- hugo.toml --
|
|
||||||
disableKinds = ['page','home','sitemap','taxonomy','term']
|
|
||||||
[[cascade]]
|
|
||||||
outputs = ['html','json']
|
|
||||||
[cascade.target]
|
|
||||||
path = '{/s2,/s4}'
|
|
||||||
-- layouts/section.html --
|
|
||||||
html: {{ .Title }}
|
|
||||||
-- layouts/section.json --
|
|
||||||
json: {{ .Title }}
|
|
||||||
-- content/s1/_index.md --
|
|
||||||
---
|
|
||||||
title: s1
|
|
||||||
---
|
|
||||||
-- content/s2/_index.md --
|
|
||||||
---
|
|
||||||
title: s2
|
|
||||||
---
|
|
||||||
-- content/_content.gotmpl --
|
|
||||||
{{ $page := dict "path" "s3" "title" "s3" "kind" "section" }}
|
|
||||||
{{ $.AddPage $page }}
|
|
||||||
|
|
||||||
{{ $page := dict "path" "s4" "title" "s4" "kind" "section" }}
|
|
||||||
{{ $.AddPage $page }}
|
|
||||||
|
|
||||||
{{ $page := dict "path" "s5" "title" "s5" "kind" "section" "outputs" (slice "html") }}
|
|
||||||
{{ $.AddPage $page }}
|
|
||||||
`
|
|
||||||
|
|
||||||
b := hugolib.Test(t, files)
|
|
||||||
|
|
||||||
b.AssertFileExists("public/s1/index.html", true)
|
|
||||||
b.AssertFileExists("public/s1/index.json", false)
|
|
||||||
b.AssertFileExists("public/s1/index.xml", true)
|
|
||||||
|
|
||||||
b.AssertFileExists("public/s2/index.html", true)
|
|
||||||
b.AssertFileExists("public/s2/index.json", true)
|
|
||||||
b.AssertFileExists("public/s2/index.xml", false)
|
|
||||||
|
|
||||||
b.AssertFileExists("public/s3/index.html", true)
|
|
||||||
b.AssertFileExists("public/s3/index.json", false)
|
|
||||||
b.AssertFileExists("public/s3/index.xml", true)
|
|
||||||
|
|
||||||
b.AssertFileExists("public/s4/index.html", true)
|
|
||||||
b.AssertFileExists("public/s4/index.json", true)
|
|
||||||
b.AssertFileExists("public/s4/index.xml", false)
|
|
||||||
|
|
||||||
b.AssertFileExists("public/s5/index.html", true)
|
|
||||||
b.AssertFileExists("public/s5/index.json", false)
|
|
||||||
b.AssertFileExists("public/s5/index.xml", false)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestContentAdapterCascadeBasic(t *testing.T) {
|
|
||||||
t.Parallel()
|
|
||||||
|
|
||||||
files := `
|
|
||||||
-- hugo.toml --
|
|
||||||
disableLiveReload = true
|
|
||||||
-- content/_index.md --
|
|
||||||
---
|
|
||||||
cascade:
|
|
||||||
- title: foo
|
|
||||||
target:
|
|
||||||
path: "**"
|
|
||||||
---
|
|
||||||
-- layouts/all.html --
|
|
||||||
Title: {{ .Title }}|Content: {{ .Content }}|
|
|
||||||
-- content/_content.gotmpl --
|
|
||||||
{{ $content := dict
|
|
||||||
"mediaType" "text/markdown"
|
|
||||||
"value" "The _Hunchback of Notre Dame_ was written by Victor Hugo."
|
|
||||||
}}
|
|
||||||
|
|
||||||
{{ $page := dict "path" "s1" "kind" "page" }}
|
|
||||||
{{ $.AddPage $page }}
|
|
||||||
{{ $page := dict "path" "s2" "kind" "page" "title" "bar" "content" $content }}
|
|
||||||
{{ $.AddPage $page }}
|
|
||||||
|
|
||||||
`
|
|
||||||
|
|
||||||
b := hugolib.TestRunning(t, files)
|
|
||||||
|
|
||||||
b.AssertFileContent("public/s1/index.html", "Title: foo|")
|
|
||||||
b.AssertFileContent("public/s2/index.html", "Title: bar|", "Content: <p>The <em>Hunchback of Notre Dame</em> was written by Victor Hugo.</p>")
|
|
||||||
|
|
||||||
b.EditFileReplaceAll("content/_index.md", "foo", "baz").Build()
|
|
||||||
|
|
||||||
b.AssertFileContent("public/s1/index.html", "Title: baz|")
|
|
||||||
}
|
|
||||||
|
|
|
@ -57,7 +57,7 @@ Summary: {{ .Summary }}|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestFrontMatterParamsPath(t *testing.T) {
|
func TestFrontMatterParamsKindPath(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
files := `
|
files := `
|
||||||
|
@ -72,9 +72,10 @@ date: 2019-08-07
|
||||||
path: "/a/b/c"
|
path: "/a/b/c"
|
||||||
slug: "s1"
|
slug: "s1"
|
||||||
---
|
---
|
||||||
-- content/mysection/_index.md --
|
-- content/mysection.md --
|
||||||
---
|
---
|
||||||
title: "My Section"
|
title: "My Section"
|
||||||
|
kind: "section"
|
||||||
date: 2022-08-07
|
date: 2022-08-07
|
||||||
path: "/a/b"
|
path: "/a/b"
|
||||||
---
|
---
|
||||||
|
@ -94,6 +95,66 @@ 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()
|
||||||
|
|
||||||
|
|
|
@ -1766,60 +1766,6 @@ 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")
|
||||||
|
@ -1946,23 +1892,3 @@ 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.")
|
|
||||||
}
|
|
||||||
|
|
|
@ -398,10 +398,6 @@ func doRenderShortcode(
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
base, layoutDescriptor := po.GetInternalTemplateBasePathAndDescriptor()
|
base, layoutDescriptor := po.GetInternalTemplateBasePathAndDescriptor()
|
||||||
|
|
||||||
// With shortcodes/mymarkdown.md (only), this allows {{% mymarkdown %}} when rendering HTML,
|
|
||||||
// but will not resolve any template when doing {{< mymarkdown >}}.
|
|
||||||
layoutDescriptor.AlwaysAllowPlainText = sc.doMarkup
|
|
||||||
q := tplimpl.TemplateQuery{
|
q := tplimpl.TemplateQuery{
|
||||||
Path: base,
|
Path: base,
|
||||||
Name: sc.name,
|
Name: sc.name,
|
||||||
|
@ -409,9 +405,10 @@ func doRenderShortcode(
|
||||||
Desc: layoutDescriptor,
|
Desc: layoutDescriptor,
|
||||||
Consider: include,
|
Consider: include,
|
||||||
}
|
}
|
||||||
v, err := s.TemplateStore.LookupShortcode(q)
|
v := s.TemplateStore.LookupShortcode(q)
|
||||||
if v == nil {
|
if v == nil {
|
||||||
return zeroShortcode, err
|
s.Log.Errorf("Unable to locate template for shortcode %q in page %q", sc.name, p.File().Path())
|
||||||
|
return zeroShortcode, nil
|
||||||
}
|
}
|
||||||
tmpl = v
|
tmpl = v
|
||||||
hasVariants = hasVariants || len(ofCount) > 1
|
hasVariants = hasVariants || len(ofCount) > 1
|
||||||
|
|
|
@ -918,7 +918,7 @@ func TestShortcodeMarkdownOutputFormat(t *testing.T) {
|
||||||
---
|
---
|
||||||
title: "p1"
|
title: "p1"
|
||||||
---
|
---
|
||||||
{{% foo %}}
|
{{< foo >}}
|
||||||
# The below would have failed using the HTML template parser.
|
# The below would have failed using the HTML template parser.
|
||||||
-- layouts/shortcodes/foo.md --
|
-- layouts/shortcodes/foo.md --
|
||||||
§§§
|
§§§
|
||||||
|
@ -930,7 +930,9 @@ title: "p1"
|
||||||
|
|
||||||
b := Test(t, files)
|
b := Test(t, files)
|
||||||
|
|
||||||
b.AssertFileContent("public/p1/index.html", "<code><x")
|
b.AssertFileContent("public/p1/index.html", `
|
||||||
|
<x
|
||||||
|
`)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestShortcodePreserveIndentation(t *testing.T) {
|
func TestShortcodePreserveIndentation(t *testing.T) {
|
||||||
|
|
|
@ -204,7 +204,6 @@ 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,
|
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
|
@ -805,7 +804,7 @@ func (s *Site) initRenderFormats() {
|
||||||
Tree: s.pageMap.treePages,
|
Tree: s.pageMap.treePages,
|
||||||
Handle: func(key string, n contentNodeI, match doctree.DimensionFlag) (bool, error) {
|
Handle: func(key string, n contentNodeI, match doctree.DimensionFlag) (bool, error) {
|
||||||
if p, ok := n.(*pageState); ok {
|
if p, ok := n.(*pageState); ok {
|
||||||
for _, f := range p.m.pageConfig.ConfiguredOutputFormats {
|
for _, f := range p.m.configuredOutputFormats {
|
||||||
if !formatSet[f.Name] {
|
if !formatSet[f.Name] {
|
||||||
formats = append(formats, f)
|
formats = append(formats, f)
|
||||||
formatSet[f.Name] = true
|
formatSet[f.Name] = true
|
||||||
|
|
|
@ -16,6 +16,7 @@ package hugolib
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"io"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/gohugoio/hugo/helpers"
|
"github.com/gohugoio/hugo/helpers"
|
||||||
|
@ -88,11 +89,14 @@ 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) {
|
||||||
|
|
|
@ -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`
|
||||||
|
|
|
@ -1,16 +1,7 @@
|
||||||
# Release env.
|
# Release env.
|
||||||
# These will be replaced by script before release.
|
# These will be replaced by script before release.
|
||||||
HUGORELEASER_TAG=v0.147.9
|
HUGORELEASER_TAG=v0.147.0
|
||||||
HUGORELEASER_COMMITISH=29bdbde19c288d190e889294a862103c6efb70bf
|
HUGORELEASER_COMMITISH=7d0039b86ddd6397816cc3383cb0cfa481b15f32
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -4,15 +4,6 @@ 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
|
||||||
|
|
|
@ -1,2 +1,2 @@
|
||||||
(()=>{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)+`
|
(()=>{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)+`
|
||||||
`),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);})();
|
`),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);})();
|
||||||
|
|
File diff suppressed because one or more lines are too long
|
@ -7,16 +7,6 @@ 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 } });
|
||||||
|
|
|
@ -53,22 +53,6 @@ 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 {
|
||||||
|
|
|
@ -51,9 +51,6 @@ 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 {
|
||||||
|
@ -158,7 +155,6 @@ 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)
|
||||||
}
|
}
|
||||||
|
@ -274,8 +270,6 @@ 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
|
||||||
|
|
||||||
|
@ -331,7 +325,6 @@ 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{}
|
||||||
|
@ -362,11 +355,6 @@ 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
|
||||||
|
@ -478,7 +466,6 @@ 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.
|
@ -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.IsIndentation()
|
return i.Type == tText || i.Type == tIndentation
|
||||||
}
|
}
|
||||||
|
|
||||||
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.IsError() || i.IsEOF()
|
return i.Type == tError || i.Type == tEOF
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i Item) IsEOF() bool {
|
func (i Item) IsEOF() bool {
|
||||||
|
@ -166,19 +166,18 @@ 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.IsEOF():
|
case i.Type == tEOF:
|
||||||
return "EOF"
|
return "EOF"
|
||||||
case i.IsError():
|
case i.Type == tError:
|
||||||
return string(val)
|
return string(val)
|
||||||
case i.IsIndentation():
|
case i.Type == tIndentation:
|
||||||
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
|
||||||
|
|
|
@ -47,217 +47,3 @@ 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)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -16,7 +16,6 @@ package page
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"slices"
|
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/gohugoio/hugo/common/loggers"
|
"github.com/gohugoio/hugo/common/loggers"
|
||||||
|
@ -25,6 +24,7 @@ import (
|
||||||
"github.com/gohugoio/hugo/hugofs/glob"
|
"github.com/gohugoio/hugo/hugofs/glob"
|
||||||
"github.com/gohugoio/hugo/resources/kinds"
|
"github.com/gohugoio/hugo/resources/kinds"
|
||||||
"github.com/mitchellh/mapstructure"
|
"github.com/mitchellh/mapstructure"
|
||||||
|
"slices"
|
||||||
)
|
)
|
||||||
|
|
||||||
// A PageMatcher can be used to match a Page with Glob patterns.
|
// A PageMatcher can be used to match a Page with Glob patterns.
|
||||||
|
@ -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, PageMatcherParamsConfig]], error) {
|
func DecodeCascadeConfig(logger loggers.Logger, in any) (*config.ConfigNamespace[[]PageMatcherParamsConfig, *maps.Ordered[PageMatcher, maps.Params]], error) {
|
||||||
buildConfig := func(in any) (*maps.Ordered[PageMatcher, PageMatcherParamsConfig], any, error) {
|
buildConfig := func(in any) (*maps.Ordered[PageMatcher, maps.Params], any, error) {
|
||||||
cascade := maps.NewOrdered[PageMatcher, PageMatcherParamsConfig]()
|
cascade := maps.NewOrdered[PageMatcher, maps.Params]()
|
||||||
if in == nil {
|
if in == nil {
|
||||||
return cascade, []map[string]any{}, nil
|
return cascade, []map[string]any{}, nil
|
||||||
}
|
}
|
||||||
|
@ -120,11 +120,7 @@ func DecodeCascadeConfig(logger loggers.Logger, handleLegacyFormat bool, in any)
|
||||||
|
|
||||||
for _, m := range ms {
|
for _, m := range ms {
|
||||||
m = maps.CleanConfigStringMap(m)
|
m = maps.CleanConfigStringMap(m)
|
||||||
var (
|
c, err := mapToPageMatcherParamsConfig(m)
|
||||||
c PageMatcherParamsConfig
|
|
||||||
err error
|
|
||||||
)
|
|
||||||
c, err = mapToPageMatcherParamsConfig(m)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
|
@ -143,29 +139,24 @@ 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.Params[k]; !found {
|
if _, found := c[k]; !found {
|
||||||
c.Params[k] = v
|
c[k] = v
|
||||||
}
|
|
||||||
}
|
|
||||||
for k, v := range cfg.Fields {
|
|
||||||
if _, found := c.Fields[k]; !found {
|
|
||||||
c.Fields[k] = v
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
cascade.Set(m, cfg)
|
cascade.Set(m, cfg.Params)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return cascade, cfgs, nil
|
return cascade, cfgs, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return config.DecodeNamespace[[]PageMatcherParamsConfig, *maps.Ordered[PageMatcher, PageMatcherParamsConfig]](in, buildConfig)
|
return config.DecodeNamespace[[]PageMatcherParamsConfig, *maps.Ordered[PageMatcher, maps.Params]](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, PageMatcherParamsConfig], error) {
|
func DecodeCascade(logger loggers.Logger, in any) (*maps.Ordered[PageMatcher, maps.Params], error) {
|
||||||
conf, err := DecodeCascadeConfig(logger, handleLegacyFormat, in)
|
conf, err := DecodeCascadeConfig(logger, in)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -174,32 +165,38 @@ 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 "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)
|
||||||
|
if pcfg.Params == nil {
|
||||||
|
pcfg.Params = params
|
||||||
|
} else {
|
||||||
|
for k, v := range params {
|
||||||
|
if _, found := pcfg.Params[k]; !found {
|
||||||
|
pcfg.Params[k] = v
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
case "_target", "target":
|
case "_target", "target":
|
||||||
var target PageMatcher
|
var target PageMatcher
|
||||||
if err := decodePageMatcher(v, &target); err != nil {
|
if err := decodePageMatcher(v, &target); err != nil {
|
||||||
return pcfg, err
|
return pcfg, err
|
||||||
}
|
}
|
||||||
pcfg.Target = target
|
pcfg.Target = target
|
||||||
case "params":
|
default:
|
||||||
|
// Legacy config.
|
||||||
if pcfg.Params == nil {
|
if pcfg.Params == nil {
|
||||||
pcfg.Params = make(maps.Params)
|
pcfg.Params = make(maps.Params)
|
||||||
}
|
}
|
||||||
params := maps.ToStringMap(v)
|
|
||||||
for k, v := range params {
|
|
||||||
if _, found := pcfg.Params[k]; !found {
|
|
||||||
pcfg.Params[k] = v
|
pcfg.Params[k] = v
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
default:
|
|
||||||
|
|
||||||
pcfg.Fields[k] = v
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return pcfg, pcfg.init()
|
return pcfg, pcfg.init()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -226,14 +223,10 @@ 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
|
||||||
}
|
}
|
||||||
|
|
|
@ -88,18 +88,19 @@ func TestPageMatcher(t *testing.T) {
|
||||||
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{
|
||||||
Fields: maps.Params{
|
Params: 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: ""},
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
@ -128,22 +129,21 @@ func TestDecodeCascadeConfig(t *testing.T) {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
got, err := DecodeCascadeConfig(loggers.NewDefault(), true, in)
|
got, err := DecodeCascadeConfig(loggers.NewDefault(), in)
|
||||||
|
|
||||||
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")}, Fields: maps.Params{}, Target: PageMatcher{Kind: "page"}},
|
{Params: maps.Params{"b": string("bv")}, Target: PageMatcher{Kind: "page"}},
|
||||||
})
|
})
|
||||||
|
|
||||||
got, err = DecodeCascadeConfig(loggers.NewDefault(), true, nil)
|
got, err = DecodeCascadeConfig(loggers.NewDefault(), nil)
|
||||||
c.Assert(err, qt.IsNil)
|
c.Assert(err, qt.IsNil)
|
||||||
c.Assert(got, qt.IsNotNil)
|
c.Assert(got, qt.IsNotNil)
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,11 +29,9 @@ import (
|
||||||
"github.com/gohugoio/hugo/hugofs/files"
|
"github.com/gohugoio/hugo/hugofs/files"
|
||||||
"github.com/gohugoio/hugo/markup"
|
"github.com/gohugoio/hugo/markup"
|
||||||
"github.com/gohugoio/hugo/media"
|
"github.com/gohugoio/hugo/media"
|
||||||
"github.com/gohugoio/hugo/output"
|
|
||||||
"github.com/gohugoio/hugo/resources/kinds"
|
"github.com/gohugoio/hugo/resources/kinds"
|
||||||
"github.com/gohugoio/hugo/resources/page"
|
"github.com/gohugoio/hugo/resources/page"
|
||||||
"github.com/gohugoio/hugo/resources/resource"
|
"github.com/gohugoio/hugo/resources/resource"
|
||||||
"github.com/mitchellh/mapstructure"
|
|
||||||
|
|
||||||
"github.com/gohugoio/hugo/helpers"
|
"github.com/gohugoio/hugo/helpers"
|
||||||
|
|
||||||
|
@ -76,29 +74,20 @@ func (d Dates) IsAllDatesZero() bool {
|
||||||
return d.Date.IsZero() && d.Lastmod.IsZero() && d.PublishDate.IsZero() && d.ExpiryDate.IsZero()
|
return d.Date.IsZero() && d.Lastmod.IsZero() && d.PublishDate.IsZero() && d.ExpiryDate.IsZero()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Page config that needs to be set early. These cannot be modified by cascade.
|
|
||||||
type PageConfigEarly struct {
|
|
||||||
Kind string // The kind of page, e.g. "page", "section", "home" etc. This is usually derived from the content path.
|
|
||||||
Path string // The canonical path to the page, e.g. /sect/mypage. Note: Leading slash, no trailing slash, no extensions or language identifiers.
|
|
||||||
Lang string // The language code for this page. This is usually derived from the module mount or filename.
|
|
||||||
Cascade []map[string]any
|
|
||||||
|
|
||||||
// Content holds the content for this page.
|
|
||||||
Content Source
|
|
||||||
}
|
|
||||||
|
|
||||||
// PageConfig configures a Page, typically from front matter.
|
// PageConfig configures a Page, typically from front matter.
|
||||||
// Note that all the top level fields are reserved Hugo keywords.
|
// Note that all the top level fields are reserved Hugo keywords.
|
||||||
// Any custom configuration needs to be set in the Params map.
|
// Any custom configuration needs to be set in the Params map.
|
||||||
type PageConfig struct {
|
type PageConfig struct {
|
||||||
Dates Dates `json:"-"` // Dates holds the four core dates for this page.
|
Dates Dates `json:"-"` // Dates holds the four core dates for this page.
|
||||||
DatesStrings
|
DatesStrings
|
||||||
PageConfigEarly `mapstructure:",squash"`
|
|
||||||
Title string // The title of the page.
|
Title string // The title of the page.
|
||||||
LinkTitle string // The link title of the page.
|
LinkTitle string // The link title of the page.
|
||||||
Type string // The content type of the page.
|
Type string // The content type of the page.
|
||||||
Layout string // The layout to use for to render this page.
|
Layout string // The layout to use for to render this page.
|
||||||
Weight int // The weight of the page, used in sorting if set to a non-zero value.
|
Weight int // The weight of the page, used in sorting if set to a non-zero value.
|
||||||
|
Kind string // The kind of page, e.g. "page", "section", "home" etc. This is usually derived from the content path.
|
||||||
|
Path string // The canonical path to the page, e.g. /sect/mypage. Note: Leading slash, no trailing slash, no extensions or language identifiers.
|
||||||
|
Lang string // The language code for this page. This is usually derived from the module mount or filename.
|
||||||
URL string // The URL to the rendered page, e.g. /sect/mypage.html.
|
URL string // The URL to the rendered page, e.g. /sect/mypage.html.
|
||||||
Slug string // The slug for this page.
|
Slug string // The slug for this page.
|
||||||
Description string // The description for this page.
|
Description string // The description for this page.
|
||||||
|
@ -113,6 +102,7 @@ type PageConfig struct {
|
||||||
|
|
||||||
FrontMatterOnlyValues `mapstructure:"-" json:"-"`
|
FrontMatterOnlyValues `mapstructure:"-" json:"-"`
|
||||||
|
|
||||||
|
Cascade []map[string]any
|
||||||
Sitemap config.SitemapConfig
|
Sitemap config.SitemapConfig
|
||||||
Build BuildConfig
|
Build BuildConfig
|
||||||
Menus any // Can be a string, []string or map[string]any.
|
Menus any // Can be a string, []string or map[string]any.
|
||||||
|
@ -120,31 +110,15 @@ type PageConfig struct {
|
||||||
// User defined params.
|
// User defined params.
|
||||||
Params maps.Params
|
Params maps.Params
|
||||||
|
|
||||||
// The raw data from the content adapter.
|
// Content holds the content for this page.
|
||||||
// TODO(bep) clean up the ContentAdapterData vs Params.
|
Content Source
|
||||||
ContentAdapterData map[string]any `mapstructure:"-" json:"-"`
|
|
||||||
|
|
||||||
// Compiled values.
|
// Compiled values.
|
||||||
CascadeCompiled *maps.Ordered[page.PageMatcher, page.PageMatcherParamsConfig] `mapstructure:"-" json:"-"`
|
CascadeCompiled *maps.Ordered[page.PageMatcher, maps.Params] `mapstructure:"-" json:"-"`
|
||||||
ContentMediaType media.Type `mapstructure:"-" json:"-"`
|
ContentMediaType media.Type `mapstructure:"-" json:"-"`
|
||||||
ConfiguredOutputFormats output.Formats `mapstructure:"-" json:"-"`
|
|
||||||
IsFromContentAdapter bool `mapstructure:"-" json:"-"`
|
IsFromContentAdapter bool `mapstructure:"-" json:"-"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func ClonePageConfigForRebuild(p *PageConfig, params map[string]any) *PageConfig {
|
|
||||||
pp := &PageConfig{
|
|
||||||
PageConfigEarly: p.PageConfigEarly,
|
|
||||||
IsFromContentAdapter: p.IsFromContentAdapter,
|
|
||||||
}
|
|
||||||
if pp.IsFromContentAdapter {
|
|
||||||
pp.ContentAdapterData = params
|
|
||||||
} else {
|
|
||||||
pp.Params = params
|
|
||||||
}
|
|
||||||
|
|
||||||
return pp
|
|
||||||
}
|
|
||||||
|
|
||||||
var DefaultPageConfig = PageConfig{
|
var DefaultPageConfig = PageConfig{
|
||||||
Build: DefaultBuildConfig,
|
Build: DefaultBuildConfig,
|
||||||
}
|
}
|
||||||
|
@ -175,7 +149,8 @@ func (p *PageConfig) Validate(pagesFromData bool) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *PageConfig) CompileForPagesFromDataPre(basePath string, logger loggers.Logger, mediaTypes media.Types) error {
|
// Compile sets up the page configuration after all fields have been set.
|
||||||
|
func (p *PageConfig) Compile(basePath string, pagesFromData bool, ext string, logger loggers.Logger, mediaTypes media.Types) error {
|
||||||
// In content adapters, we always get relative paths.
|
// In content adapters, we always get relative paths.
|
||||||
if basePath != "" {
|
if basePath != "" {
|
||||||
p.Path = path.Join(basePath, p.Path)
|
p.Path = path.Join(basePath, p.Path)
|
||||||
|
@ -183,32 +158,12 @@ func (p *PageConfig) CompileForPagesFromDataPre(basePath string, logger loggers.
|
||||||
|
|
||||||
if p.Params == nil {
|
if p.Params == nil {
|
||||||
p.Params = make(maps.Params)
|
p.Params = make(maps.Params)
|
||||||
} else {
|
} else if pagesFromData {
|
||||||
p.Params = maps.PrepareParamsClone(p.Params)
|
p.Params = maps.PrepareParamsClone(p.Params)
|
||||||
|
} else {
|
||||||
|
maps.PrepareParams(p.Params)
|
||||||
}
|
}
|
||||||
|
|
||||||
if p.Kind == "" {
|
|
||||||
p.Kind = kinds.KindPage
|
|
||||||
}
|
|
||||||
|
|
||||||
if p.Cascade != nil {
|
|
||||||
cascade, err := page.DecodeCascade(logger, false, p.Cascade)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("failed to decode cascade: %w", err)
|
|
||||||
}
|
|
||||||
p.CascadeCompiled = cascade
|
|
||||||
}
|
|
||||||
|
|
||||||
// Note that NormalizePathStringBasic will make sure that we don't preserve the unnormalized path.
|
|
||||||
// We do that when we create pages from the file system; mostly for backward compatibility,
|
|
||||||
// but also because people tend to use use the filename to name their resources (with spaces and all),
|
|
||||||
// and this isn't relevant when creating resources from an API where it's easy to add textual meta data.
|
|
||||||
p.Path = paths.NormalizePathStringBasic(p.Path)
|
|
||||||
|
|
||||||
return p.compilePrePost("", mediaTypes)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *PageConfig) compilePrePost(ext string, mediaTypes media.Types) error {
|
|
||||||
if p.Content.Markup == "" && p.Content.MediaType == "" {
|
if p.Content.Markup == "" && p.Content.MediaType == "" {
|
||||||
if ext == "" {
|
if ext == "" {
|
||||||
ext = "md"
|
ext = "md"
|
||||||
|
@ -239,37 +194,25 @@ func (p *PageConfig) compilePrePost(ext string, mediaTypes media.Types) error {
|
||||||
if p.Content.Markup == "" {
|
if p.Content.Markup == "" {
|
||||||
p.Content.Markup = p.ContentMediaType.SubType
|
p.Content.Markup = p.ContentMediaType.SubType
|
||||||
}
|
}
|
||||||
return nil
|
|
||||||
|
if pagesFromData {
|
||||||
|
if p.Kind == "" {
|
||||||
|
p.Kind = kinds.KindPage
|
||||||
}
|
}
|
||||||
|
|
||||||
// Compile sets up the page configuration after all fields have been set.
|
// Note that NormalizePathStringBasic will make sure that we don't preserve the unnormalized path.
|
||||||
func (p *PageConfig) Compile(ext string, logger loggers.Logger, outputFormats output.Formats, mediaTypes media.Types) error {
|
// We do that when we create pages from the file system; mostly for backward compatibility,
|
||||||
if p.IsFromContentAdapter {
|
// but also because people tend to use use the filename to name their resources (with spaces and all),
|
||||||
if err := mapstructure.WeakDecode(p.ContentAdapterData, p); err != nil {
|
// and this isn't relevant when creating resources from an API where it's easy to add textual meta data.
|
||||||
err = fmt.Errorf("failed to decode page map: %w", err)
|
p.Path = paths.NormalizePathStringBasic(p.Path)
|
||||||
return err
|
|
||||||
}
|
|
||||||
// Not needed anymore.
|
|
||||||
p.ContentAdapterData = nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if p.Params == nil {
|
if p.Cascade != nil {
|
||||||
p.Params = make(maps.Params)
|
cascade, err := page.DecodeCascade(logger, p.Cascade)
|
||||||
} else {
|
|
||||||
maps.PrepareParams(p.Params)
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := p.compilePrePost(ext, mediaTypes); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(p.Outputs) > 0 {
|
|
||||||
outFormats, err := outputFormats.GetByNames(p.Outputs...)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to resolve output formats %v: %w", p.Outputs, err)
|
return fmt.Errorf("failed to decode cascade: %w", err)
|
||||||
} else {
|
|
||||||
p.ConfiguredOutputFormats = outFormats
|
|
||||||
}
|
}
|
||||||
|
p.CascadeCompiled = cascade
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
|
|
@ -22,7 +22,6 @@ import (
|
||||||
"github.com/gohugoio/hugo/config"
|
"github.com/gohugoio/hugo/config"
|
||||||
"github.com/gohugoio/hugo/config/testconfig"
|
"github.com/gohugoio/hugo/config/testconfig"
|
||||||
"github.com/gohugoio/hugo/media"
|
"github.com/gohugoio/hugo/media"
|
||||||
"github.com/gohugoio/hugo/output"
|
|
||||||
|
|
||||||
"github.com/gohugoio/hugo/resources/page/pagemeta"
|
"github.com/gohugoio/hugo/resources/page/pagemeta"
|
||||||
|
|
||||||
|
@ -176,7 +175,7 @@ func TestContentMediaTypeFromMarkup(t *testing.T) {
|
||||||
} {
|
} {
|
||||||
var pc pagemeta.PageConfig
|
var pc pagemeta.PageConfig
|
||||||
pc.Content.Markup = test.in
|
pc.Content.Markup = test.in
|
||||||
c.Assert(pc.Compile("", logger, output.DefaultFormats, media.DefaultTypes), qt.IsNil)
|
c.Assert(pc.Compile("", true, "", logger, media.DefaultTypes), qt.IsNil)
|
||||||
c.Assert(pc.ContentMediaType.Type, qt.Equals, test.expected)
|
c.Assert(pc.ContentMediaType.Type, qt.Equals, test.expected)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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{}))
|
||||||
|
|
|
@ -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().Unnormalized().BaseNameNoIdentifier()), nil
|
return l.urlize(p.PathInfo().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.
|
||||||
|
|
|
@ -14,7 +14,6 @@
|
||||||
package page_test
|
package page_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"strings"
|
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/bep/logg"
|
"github.com/bep/logg"
|
||||||
|
@ -344,29 +343,3 @@ 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)
|
|
||||||
}
|
|
||||||
|
|
|
@ -24,7 +24,6 @@ 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"
|
||||||
|
@ -55,7 +54,6 @@ 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 {
|
||||||
|
@ -244,7 +242,6 @@ type baseResourceInternal interface {
|
||||||
fileInfo
|
fileInfo
|
||||||
mediaTypeAssigner
|
mediaTypeAssigner
|
||||||
targetPather
|
targetPather
|
||||||
isPublishedProvider
|
|
||||||
|
|
||||||
ReadSeekCloser() (hugio.ReadSeekCloser, error)
|
ReadSeekCloser() (hugio.ReadSeekCloser, error)
|
||||||
|
|
||||||
|
@ -358,7 +355,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 *lazy.OnceMore
|
publishInit *sync.Once
|
||||||
|
|
||||||
key string
|
key string
|
||||||
keyInit *sync.Once
|
keyInit *sync.Once
|
||||||
|
@ -539,10 +536,6 @@ 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())
|
||||||
}
|
}
|
||||||
|
@ -636,7 +629,7 @@ func (rc *genericResource) cloneWithUpdates(u *transformationUpdate) (baseResour
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l genericResource) clone() *genericResource {
|
func (l genericResource) clone() *genericResource {
|
||||||
l.publishInit = &lazy.OnceMore{}
|
l.publishInit = &sync.Once{}
|
||||||
l.keyInit = &sync.Once{}
|
l.keyInit = &sync.Once{}
|
||||||
return &l
|
return &l
|
||||||
}
|
}
|
||||||
|
@ -650,10 +643,6 @@ 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
|
||||||
|
@ -713,11 +702,6 @@ 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(),
|
||||||
|
|
|
@ -81,6 +81,11 @@ 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.
|
||||||
|
|
|
@ -20,7 +20,6 @@ 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"
|
||||||
|
@ -190,7 +189,7 @@ func (r *Spec) NewResource(rd ResourceSourceDescriptor) (resource.Resource, erro
|
||||||
gr := &genericResource{
|
gr := &genericResource{
|
||||||
Staler: &AtomicStaler{},
|
Staler: &AtomicStaler{},
|
||||||
h: &resourceHash{},
|
h: &resourceHash{},
|
||||||
publishInit: &lazy.OnceMore{},
|
publishInit: &sync.Once{},
|
||||||
keyInit: &sync.Once{},
|
keyInit: &sync.Once{},
|
||||||
includeHashInKey: isImage,
|
includeHashInKey: isImage,
|
||||||
paths: rp,
|
paths: rp,
|
||||||
|
|
|
@ -69,6 +69,7 @@ func (c *PostCSSClient) Process(res resources.ResourceTransformer, options map[s
|
||||||
}
|
}
|
||||||
|
|
||||||
type InlineImports struct {
|
type InlineImports struct {
|
||||||
|
// Service `mapstructure:",squash"`
|
||||||
// Enable inlining of @import statements.
|
// Enable inlining of @import statements.
|
||||||
// Does so recursively, but currently once only per file;
|
// Does so recursively, but currently once only per file;
|
||||||
// that is, it's not possible to import the same file in
|
// that is, it's not possible to import the same file in
|
||||||
|
@ -77,11 +78,6 @@ type InlineImports struct {
|
||||||
// so you can have @import anywhere in the file.
|
// so you can have @import anywhere in the file.
|
||||||
InlineImports bool
|
InlineImports bool
|
||||||
|
|
||||||
// See issue https://github.com/gohugoio/hugo/issues/13719
|
|
||||||
// Disable inlining of @import statements
|
|
||||||
// This is currenty only used for css.TailwindCSS.
|
|
||||||
DisableInlineImports bool
|
|
||||||
|
|
||||||
// When InlineImports is enabled, we fail the build if an import cannot be resolved.
|
// When InlineImports is enabled, we fail the build if an import cannot be resolved.
|
||||||
// You can enable this to allow the build to continue and leave the import statement in place.
|
// You can enable this to allow the build to continue and leave the import statement in place.
|
||||||
// Note that the inline importer does not process url location or imports with media queries,
|
// Note that the inline importer does not process url location or imports with media queries,
|
||||||
|
|
|
@ -129,12 +129,10 @@ func (t *tailwindcssTransformation) Transform(ctx *resources.ResourceTransformat
|
||||||
t.rs.Assets.Fs, t.rs.Logger, ctx.DependencyManager,
|
t.rs.Assets.Fs, t.rs.Logger, ctx.DependencyManager,
|
||||||
)
|
)
|
||||||
|
|
||||||
if !options.InlineImports.DisableInlineImports {
|
|
||||||
src, err = imp.resolve()
|
src, err = imp.resolve()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
defer stdin.Close()
|
defer stdin.Close()
|
||||||
|
@ -148,11 +146,7 @@ func (t *tailwindcssTransformation) Transform(ctx *resources.ResourceTransformat
|
||||||
Cause: err,
|
Cause: err,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
s := errBuf.String()
|
return imp.toFileError(errBuf.String())
|
||||||
if options.InlineImports.DisableInlineImports && strings.Contains(s, "Can't resolve") {
|
|
||||||
s += "You may want to set the 'disableInlineImports' option to false to inline imports, see https://gohugo.io/functions/css/tailwindcss/#disableinlineimports"
|
|
||||||
}
|
|
||||||
return imp.toFileError(s)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
|
|
@ -17,7 +17,6 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/bep/logg"
|
"github.com/bep/logg"
|
||||||
qt "github.com/frankban/quicktest"
|
|
||||||
"github.com/gohugoio/hugo/htesting"
|
"github.com/gohugoio/hugo/htesting"
|
||||||
"github.com/gohugoio/hugo/hugolib"
|
"github.com/gohugoio/hugo/hugolib"
|
||||||
)
|
)
|
||||||
|
@ -71,66 +70,3 @@ CSS: {{ $css.Content | safeCSS }}|
|
||||||
|
|
||||||
b.AssertFileContent("public/index.html", "/*! tailwindcss v4.")
|
b.AssertFileContent("public/index.html", "/*! tailwindcss v4.")
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestTailwindCSSNoInlineImportsIssue13719(t *testing.T) {
|
|
||||||
t.Parallel()
|
|
||||||
|
|
||||||
files := `
|
|
||||||
-- hugo.toml --
|
|
||||||
disableKinds = ['page','rss','section','sitemap','taxonomy','term']
|
|
||||||
theme = 'my-theme'
|
|
||||||
|
|
||||||
[[module.mounts]]
|
|
||||||
source = 'assets'
|
|
||||||
target = 'assets'
|
|
||||||
|
|
||||||
[[module.mounts]]
|
|
||||||
source = 'other'
|
|
||||||
target = 'assets/css'
|
|
||||||
-- assets/css/main.css --
|
|
||||||
@import "tailwindcss";
|
|
||||||
|
|
||||||
@import "colors/red.css";
|
|
||||||
@import "colors/blue.css";
|
|
||||||
@import "colors/purple.css";
|
|
||||||
-- assets/css/colors/red.css --
|
|
||||||
@import "green.css";
|
|
||||||
|
|
||||||
.red {color: red;}
|
|
||||||
-- assets/css/colors/green.css --
|
|
||||||
.green {color: green;}
|
|
||||||
-- themes/my-theme/assets/css/colors/blue.css --
|
|
||||||
.blue {color: blue;}
|
|
||||||
-- other/colors/purple.css --
|
|
||||||
.purple {color: purple;}
|
|
||||||
-- layouts/home.html --
|
|
||||||
{{ with (templates.Defer (dict "key" "global")) }}
|
|
||||||
{{ with resources.Get "css/main.css" }}
|
|
||||||
{{ $opts := dict "disableInlineImports" true }}
|
|
||||||
{{ with . | css.TailwindCSS $opts }}
|
|
||||||
<link rel="stylesheet" href="{{ .RelPermalink }}">
|
|
||||||
{{ end }}
|
|
||||||
{{ end }}
|
|
||||||
{{ end }}
|
|
||||||
-- package.json --
|
|
||||||
{
|
|
||||||
"devDependencies": {
|
|
||||||
"@tailwindcss/cli": "^4.1.7",
|
|
||||||
"tailwindcss": "^4.1.7"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
`
|
|
||||||
|
|
||||||
b, err := hugolib.NewIntegrationTestBuilder(
|
|
||||||
hugolib.IntegrationTestConfig{
|
|
||||||
T: t,
|
|
||||||
TxtarString: files,
|
|
||||||
NeedsOsFS: true,
|
|
||||||
NeedsNpmInstall: true,
|
|
||||||
LogLevel: logg.LevelInfo,
|
|
||||||
}).BuildE()
|
|
||||||
|
|
||||||
b.Assert(err, qt.IsNotNil)
|
|
||||||
b.Assert(err.Error(), qt.Contains, "Can't resolve 'colors/red.css'")
|
|
||||||
b.Assert(err.Error(), qt.Contains, "You may want to set the 'disableInlineImports' option to false")
|
|
||||||
}
|
|
||||||
|
|
|
@ -61,7 +61,6 @@ 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
|
||||||
|
@ -326,11 +325,6 @@ 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()
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
# Test the new command.
|
# Test the new command.
|
||||||
|
|
||||||
hugo new site -h
|
hugo new site -h
|
||||||
stdout 'Create a new site at the specified path.'
|
stdout 'Create a new site in the provided directory'
|
||||||
hugo new site my-yaml-site --format yml
|
hugo new site my-yaml-site --format yml
|
||||||
checkfile my-yaml-site/hugo.yml
|
checkfile my-yaml-site/hugo.yml
|
||||||
hugo new site mysite -f
|
hugo new site mysite -f
|
||||||
|
@ -19,7 +19,7 @@ exists themes
|
||||||
! exists resources
|
! exists resources
|
||||||
|
|
||||||
hugo new theme -h
|
hugo new theme -h
|
||||||
stdout 'Create a new theme with the specified name in the ./themes directory.'
|
stdout 'Create a new theme \(skeleton\) called \[name\] in ./themes'
|
||||||
hugo new theme mytheme --format yml
|
hugo new theme mytheme --format yml
|
||||||
stdout 'Creating new theme'
|
stdout 'Creating new theme'
|
||||||
! exists resources
|
! exists resources
|
||||||
|
|
|
@ -15,7 +15,6 @@ 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"
|
||||||
|
@ -39,19 +38,6 @@ 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)
|
||||||
|
|
|
@ -17,7 +17,6 @@ import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"iter"
|
|
||||||
"reflect"
|
"reflect"
|
||||||
|
|
||||||
"github.com/gohugoio/hugo/common/herrors"
|
"github.com/gohugoio/hugo/common/herrors"
|
||||||
|
@ -434,18 +433,3 @@ 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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -115,13 +115,6 @@ func init() {
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
ns.AddMethodMapping(ctx.MaxInt64,
|
|
||||||
nil,
|
|
||||||
[][2]string{
|
|
||||||
{"{{ math.MaxInt64 }}", "9223372036854775807"},
|
|
||||||
},
|
|
||||||
)
|
|
||||||
|
|
||||||
ns.AddMethodMapping(ctx.Min,
|
ns.AddMethodMapping(ctx.Min,
|
||||||
nil,
|
nil,
|
||||||
[][2]string{
|
[][2]string{
|
||||||
|
|
|
@ -147,11 +147,6 @@ func (ns *Namespace) Max(inputs ...any) (maximum float64, err error) {
|
||||||
return ns.applyOpToScalarsOrSlices("Max", math.Max, inputs...)
|
return ns.applyOpToScalarsOrSlices("Max", math.Max, inputs...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// MaxInt64 returns the maximum value for a signed 64-bit integer.
|
|
||||||
func (ns *Namespace) MaxInt64() int64 {
|
|
||||||
return math.MaxInt64
|
|
||||||
}
|
|
||||||
|
|
||||||
// Min returns the smaller of all numbers in inputs. Any slices in inputs are flattened.
|
// Min returns the smaller of all numbers in inputs. Any slices in inputs are flattened.
|
||||||
func (ns *Namespace) Min(inputs ...any) (minimum float64, err error) {
|
func (ns *Namespace) Min(inputs ...any) (minimum float64, err error) {
|
||||||
return ns.applyOpToScalarsOrSlices("Min", math.Min, inputs...)
|
return ns.applyOpToScalarsOrSlices("Min", math.Min, inputs...)
|
||||||
|
|
|
@ -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", int64(1)},
|
{"3.1", "2", false},
|
||||||
{"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", false},
|
{"3.1", "2", nil},
|
||||||
{"aaa", "0", nil},
|
{"aaa", "0", nil},
|
||||||
{"3", "aaa", nil},
|
{"3", "aaa", nil},
|
||||||
} {
|
} {
|
||||||
|
@ -879,14 +879,3 @@ func TestToRadians(t *testing.T) {
|
||||||
c.Assert(result, qt.Equals, test.expect)
|
c.Assert(result, qt.Equals, test.expect)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestMaxInt64(t *testing.T) {
|
|
||||||
t.Parallel()
|
|
||||||
ns := New(nil)
|
|
||||||
|
|
||||||
var want int64 = 9223372036854775807
|
|
||||||
got := ns.MaxInt64()
|
|
||||||
if want != got {
|
|
||||||
t.Errorf("want %d, got %d", want, got)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -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, "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)
|
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)
|
||||||
}
|
}
|
||||||
v := ns.deps.TemplateStore.LookupPartial(name)
|
v := ns.deps.TemplateStore.LookupPartial(name)
|
||||||
if v == nil {
|
if v == nil {
|
||||||
|
|
|
@ -299,19 +299,3 @@ P2.
|
||||||
b := hugolib.Test(t, files)
|
b := hugolib.Test(t, files)
|
||||||
b.AssertFileContent("public/index.html", "P1: P1.\nP2: foo bar")
|
b.AssertFileContent("public/index.html", "P1: P1.\nP2: foo bar")
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestTemplateExistsCaseIssue13684(t *testing.T) {
|
|
||||||
t.Parallel()
|
|
||||||
|
|
||||||
files := `
|
|
||||||
-- hugo.toml --
|
|
||||||
-- layouts/home.html --
|
|
||||||
P1: {{ templates.Exists "_partials/MyPartial.html" }}|P1: {{ templates.Exists "_partials/mypartial.html" }}|
|
|
||||||
-- layouts/_partials/MyPartial.html --
|
|
||||||
MyPartial.
|
|
||||||
|
|
||||||
`
|
|
||||||
|
|
||||||
b := hugolib.Test(t, files)
|
|
||||||
b.AssertFileContent("public/index.html", "P1: true|P1: true|")
|
|
||||||
}
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
{{- $pc := site.Config.Privacy.Twitter -}}
|
{{- $pc := site.Config.Privacy.Twitter -}}
|
||||||
{{- if not $pc.Disable -}}
|
{{- if not $pc.Disable -}}
|
||||||
{{- if $pc.Simple -}}
|
{{- if $pc.Simple -}}
|
||||||
{{- template "_shortcodes/twitter_simple.html" . -}}
|
{{- template "_internal/shortcodes/twitter_simple.html" . -}}
|
||||||
{{- else -}}
|
{{- else -}}
|
||||||
{{- $id := or (.Get "id") "" -}}
|
{{- $id := or (.Get "id") "" -}}
|
||||||
{{- $user := or (.Get "user") "" -}}
|
{{- $user := or (.Get "user") "" -}}
|
||||||
|
@ -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 -}}
|
||||||
{{- warnidf "shortcode-twitter-getremote" "The %q shortcode was unable to retrieve the remote data: %s. See %s" $.ctx.Name . $.ctx.Position -}}
|
{{- errorf "%s" . -}}
|
||||||
{{- else with .Value -}}
|
{{- else with .Value -}}
|
||||||
{{- (. | transform.Unmarshal).html | safeHTML -}}
|
{{- (. | transform.Unmarshal).html | safeHTML -}}
|
||||||
{{- else -}}
|
{{- else -}}
|
||||||
|
|
|
@ -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 -}}
|
||||||
{{- warnidf "shortcode-twitter-simple-getremote" "The %q shortcode was unable to retrieve the remote data: %s. See %s" $.ctx.Name . $.ctx.Position -}}
|
{{- errorf "%s" . -}}
|
||||||
{{- 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) }}
|
||||||
|
|
|
@ -18,7 +18,7 @@ title, then loading.
|
||||||
{{- $pc := site.Config.Privacy.Vimeo }}
|
{{- $pc := site.Config.Privacy.Vimeo }}
|
||||||
{{- if not $pc.Disable }}
|
{{- if not $pc.Disable }}
|
||||||
{{- if $pc.Simple }}
|
{{- if $pc.Simple }}
|
||||||
{{- template "_shortcodes/vimeo_simple.html" . }}
|
{{- template "_internal/shortcodes/vimeo_simple.html" . }}
|
||||||
{{- else }}
|
{{- else }}
|
||||||
{{- $dnt := cond $pc.EnableDNT 1 0 }}
|
{{- $dnt := cond $pc.EnableDNT 1 0 }}
|
||||||
|
|
||||||
|
|
|
@ -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 -}}
|
||||||
{{- warnidf "shortcode-vimeo-simple" "The %q shortcode was unable to retrieve the remote data: %s. See %s" $.ctx.Name . $.ctx.Position -}}
|
{{- errorf "%s" . -}}
|
||||||
{{- 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" -}}
|
||||||
|
@ -37,7 +37,7 @@
|
||||||
{{- $thumbnail := .thumbnail_url -}}
|
{{- $thumbnail := .thumbnail_url -}}
|
||||||
{{- $original := $thumbnail | replaceRE "(_.*\\.)" "." -}}
|
{{- $original := $thumbnail | replaceRE "(_.*\\.)" "." -}}
|
||||||
<div class="{{ $class }}">
|
<div class="{{ $class }}">
|
||||||
<a href="{{ .provider_url }}{{ .video_id | string }}" rel="noopener" target="_blank">
|
<a href="{{ .provider_url }}{{ .video_id }}" rel="noopener" target="_blank">
|
||||||
<img src="{{ $thumbnail }}" srcset="{{ $thumbnail }} 1x, {{ $original }} 2x" alt="{{ .title }}">
|
<img src="{{ $thumbnail }}" srcset="{{ $thumbnail }} 1x, {{ $original }} 2x" alt="{{ .title }}">
|
||||||
<div class="play">
|
<div class="play">
|
||||||
{{ template "__h_simple_icon_play" $.ctx.Page }}
|
{{ template "__h_simple_icon_play" $.ctx.Page }}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
{{- $pc := site.Config.Privacy.X -}}
|
{{- $pc := site.Config.Privacy.X -}}
|
||||||
{{- if not $pc.Disable -}}
|
{{- if not $pc.Disable -}}
|
||||||
{{- if $pc.Simple -}}
|
{{- if $pc.Simple -}}
|
||||||
{{- template "_shortcodes/x_simple.html" . -}}
|
{{- template "_internal/shortcodes/x_simple.html" . -}}
|
||||||
{{- else -}}
|
{{- else -}}
|
||||||
{{- $id := or (.Get "id") "" -}}
|
{{- $id := or (.Get "id") "" -}}
|
||||||
{{- $user := or (.Get "user") "" -}}
|
{{- $user := or (.Get "user") "" -}}
|
||||||
|
@ -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 -}}
|
||||||
{{- warnidf "shortcode-x-getremote" "The %q shortcode was unable to retrieve the remote data: %s. See %s" $.ctx.Name . $.ctx.Position -}}
|
{{- errorf "%s" . -}}
|
||||||
{{- else with .Value -}}
|
{{- else with .Value -}}
|
||||||
{{- (. | transform.Unmarshal).html | safeHTML -}}
|
{{- (. | transform.Unmarshal).html | safeHTML -}}
|
||||||
{{- else -}}
|
{{- else -}}
|
||||||
|
|
|
@ -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 -}}
|
||||||
{{- warnidf "shortcode-x-simple-getremote" "The %q shortcode was unable to retrieve the remote data: %s. See %s" $.ctx.Name . $.ctx.Position -}}
|
{{- errorf "%s" . -}}
|
||||||
{{- 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) }}
|
||||||
|
|
|
@ -17,7 +17,6 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
qt "github.com/frankban/quicktest"
|
|
||||||
"github.com/gohugoio/hugo/htesting/hqt"
|
"github.com/gohugoio/hugo/htesting/hqt"
|
||||||
"github.com/gohugoio/hugo/hugolib"
|
"github.com/gohugoio/hugo/hugolib"
|
||||||
)
|
)
|
||||||
|
@ -496,7 +495,7 @@ Content: {{ .Content }}
|
||||||
// Simple mode
|
// Simple mode
|
||||||
files = strings.ReplaceAll(files, "privacy.vimeo.simple = false", "privacy.vimeo.simple = true")
|
files = strings.ReplaceAll(files, "privacy.vimeo.simple = false", "privacy.vimeo.simple = true")
|
||||||
b = hugolib.Test(t, files)
|
b = hugolib.Test(t, files)
|
||||||
b.AssertFileContent("public/p1/index.html", "04d861fc957ee638")
|
b.AssertFileContent("public/p1/index.html", "c5bf16d87e2a370b")
|
||||||
|
|
||||||
// Simple mode with non-existent id
|
// Simple mode with non-existent id
|
||||||
files = strings.ReplaceAll(files, "{{< vimeo 55073825 >}}", "{{< vimeo __id_does_not_exist__ >}}")
|
files = strings.ReplaceAll(files, "{{< vimeo 55073825 >}}", "{{< vimeo __id_does_not_exist__ >}}")
|
||||||
|
@ -697,100 +696,3 @@ title: p2
|
||||||
b.AssertFileContent("public/p1/index.html", "78eb19b5c6f3768f")
|
b.AssertFileContent("public/p1/index.html", "78eb19b5c6f3768f")
|
||||||
b.AssertFileContent("public/p2/index.html", "a6db910a9cf54bc1")
|
b.AssertFileContent("public/p2/index.html", "a6db910a9cf54bc1")
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestShortcodePlainTextVsHTMLTemplateIssue13698(t *testing.T) {
|
|
||||||
t.Parallel()
|
|
||||||
|
|
||||||
filesTemplate := `
|
|
||||||
-- hugo.toml --
|
|
||||||
markup.goldmark.renderer.unsafe = true
|
|
||||||
-- layouts/all.html --
|
|
||||||
Content: {{ .Content }}|
|
|
||||||
-- layouts/_shortcodes/mymarkdown.md --
|
|
||||||
<div>Foo bar</div>
|
|
||||||
-- content/p1.md --
|
|
||||||
---
|
|
||||||
title: p1
|
|
||||||
---
|
|
||||||
## A shortcode
|
|
||||||
|
|
||||||
SHORTCODE
|
|
||||||
|
|
||||||
`
|
|
||||||
|
|
||||||
files := strings.ReplaceAll(filesTemplate, "SHORTCODE", "{{% mymarkdown %}}")
|
|
||||||
b := hugolib.Test(t, files)
|
|
||||||
b.AssertFileContent("public/p1/index.html", "<div>Foo bar</div>")
|
|
||||||
|
|
||||||
files = strings.ReplaceAll(filesTemplate, "SHORTCODE", "{{< mymarkdown >}}")
|
|
||||||
|
|
||||||
var err error
|
|
||||||
b, err = hugolib.TestE(t, files)
|
|
||||||
b.Assert(err, qt.IsNotNil)
|
|
||||||
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 TestShortcodeOnlyLanguageInBaseIssue13699And13740(t *testing.T) {
|
|
||||||
t.Parallel()
|
|
||||||
|
|
||||||
files := `
|
|
||||||
-- hugo.toml --
|
|
||||||
baseURL = 'https://example.org/'
|
|
||||||
disableLanguages = ['de']
|
|
||||||
[languages]
|
|
||||||
[languages.en]
|
|
||||||
weight = 1
|
|
||||||
[languages.de]
|
|
||||||
weight = 2
|
|
||||||
-- layouts/_shortcodes/de.html --
|
|
||||||
de.html
|
|
||||||
-- layouts/all.html --
|
|
||||||
{{ .Content }}
|
|
||||||
-- content/_index.md --
|
|
||||||
---
|
|
||||||
title: home
|
|
||||||
---
|
|
||||||
{{< de >}}
|
|
||||||
|
|
||||||
`
|
|
||||||
b := hugolib.Test(t, files)
|
|
||||||
|
|
||||||
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")
|
|
||||||
}
|
|
||||||
|
|
|
@ -37,7 +37,6 @@ type TemplateDescriptor struct {
|
||||||
// Misc.
|
// Misc.
|
||||||
LayoutFromUserMustMatch bool // If set, we only look for the exact layout.
|
LayoutFromUserMustMatch bool // If set, we only look for the exact layout.
|
||||||
IsPlainText bool // Whether this is a plain text template.
|
IsPlainText bool // Whether this is a plain text template.
|
||||||
AlwaysAllowPlainText bool // Whether to e.g. allow plain text templates to be rendered in HTML.
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *TemplateDescriptor) normalizeFromFile() {
|
func (d *TemplateDescriptor) normalizeFromFile() {
|
||||||
|
@ -65,7 +64,7 @@ func (s descriptorHandler) compareDescriptors(category Category, isEmbedded bool
|
||||||
return weightNoMatch
|
return weightNoMatch
|
||||||
}
|
}
|
||||||
|
|
||||||
w := this.doCompare(category, s.opts.DefaultContentLanguage, other)
|
w := this.doCompare(category, isEmbedded, s.opts.DefaultContentLanguage, other)
|
||||||
|
|
||||||
if w.w1 <= 0 {
|
if w.w1 <= 0 {
|
||||||
if category == CategoryMarkup && (this.Variant1 == other.Variant1) && (this.Variant2 == other.Variant2 || this.Variant2 != "" && other.Variant2 == "") {
|
if category == CategoryMarkup && (this.Variant1 == other.Variant1) && (this.Variant2 == other.Variant2 || this.Variant2 != "" && other.Variant2 == "") {
|
||||||
|
@ -75,12 +74,7 @@ func (s descriptorHandler) compareDescriptors(category Category, isEmbedded bool
|
||||||
}
|
}
|
||||||
|
|
||||||
w.w1 = 1
|
w.w1 = 1
|
||||||
}
|
return w
|
||||||
|
|
||||||
if category == CategoryShortcode {
|
|
||||||
if (this.IsPlainText == other.IsPlainText || !other.IsPlainText) || this.AlwaysAllowPlainText {
|
|
||||||
w.w1 = 1
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -88,16 +82,13 @@ func (s descriptorHandler) compareDescriptors(category Category, isEmbedded bool
|
||||||
}
|
}
|
||||||
|
|
||||||
//lint:ignore ST1006 this vs other makes it easier to reason about.
|
//lint:ignore ST1006 this vs other makes it easier to reason about.
|
||||||
func (this TemplateDescriptor) doCompare(category Category, defaultContentLanguage string, other TemplateDescriptor) weight {
|
func (this TemplateDescriptor) doCompare(category Category, isEmbedded bool, defaultContentLanguage string, other TemplateDescriptor) weight {
|
||||||
w := weightNoMatch
|
w := weightNoMatch
|
||||||
|
|
||||||
if !this.AlwaysAllowPlainText {
|
|
||||||
// HTML in plain text is OK, but not the other way around.
|
// HTML in plain text is OK, but not the other way around.
|
||||||
if other.IsPlainText && !this.IsPlainText {
|
if other.IsPlainText && !this.IsPlainText {
|
||||||
return w
|
return w
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if other.Kind != "" && other.Kind != this.Kind {
|
if other.Kind != "" && other.Kind != this.Kind {
|
||||||
return w
|
return w
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,6 @@ package tplimpl
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"io"
|
"io"
|
||||||
"iter"
|
|
||||||
"regexp"
|
"regexp"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
@ -45,15 +44,16 @@ var embeddedTemplatesAliases = map[string][]string{
|
||||||
"_shortcodes/twitter.html": {"_shortcodes/tweet.html"},
|
"_shortcodes/twitter.html": {"_shortcodes/tweet.html"},
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *TemplateStore) parseTemplate(ti *TemplInfo, replace bool) error {
|
func (s *TemplateStore) parseTemplate(ti *TemplInfo) error {
|
||||||
err := s.tns.doParseTemplate(ti, replace)
|
err := s.tns.doParseTemplate(ti)
|
||||||
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, replace bool) error {
|
func (t *templateNamespace) doParseTemplate(ti *TemplInfo) 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, replace bool) error {
|
||||||
|
|
||||||
if ti.D.IsPlainText {
|
if ti.D.IsPlainText {
|
||||||
prototype := t.parseText
|
prototype := t.parseText
|
||||||
if !replace && prototype.Lookup(name) != nil {
|
if 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, replace bool) error {
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
prototype := t.parseHTML
|
prototype := t.parseHTML
|
||||||
if !replace && prototype.Lookup(name) != nil {
|
if 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,24 +181,19 @@ func (t *templateNamespace) applyBaseTemplate(overlay *TemplInfo, base keyTempla
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *templateNamespace) templatesIn(in tpl.Template) iter.Seq[tpl.Template] {
|
func (t *templateNamespace) templatesIn(in tpl.Template) []tpl.Template {
|
||||||
return func(yield func(t tpl.Template) bool) {
|
var templs []tpl.Template
|
||||||
switch in := in.(type) {
|
if textt, ok := in.(*texttemplate.Template); ok {
|
||||||
case *htmltemplate.Template:
|
for _, t := range textt.Templates() {
|
||||||
for t := range in.All() {
|
templs = append(templs, t)
|
||||||
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
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -342,6 +337,8 @@ 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
|
||||||
}
|
}
|
||||||
|
@ -353,14 +350,3 @@ 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")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -19,7 +19,6 @@ import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"context"
|
"context"
|
||||||
"embed"
|
"embed"
|
||||||
"errors"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"io/fs"
|
"io/fs"
|
||||||
|
@ -125,7 +124,6 @@ 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),
|
||||||
|
@ -144,10 +142,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(false); err != nil {
|
if err := s.parseTemplates(); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if err := s.extractInlinePartials(false); err != nil {
|
if err := s.extractInlinePartials(); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if err := s.transformTemplates(); err != nil {
|
if err := s.transformTemplates(); err != nil {
|
||||||
|
@ -429,7 +427,6 @@ 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
|
||||||
|
|
||||||
|
@ -611,7 +608,7 @@ func (s *TemplateStore) LookupShortcodeByName(name string) *TemplInfo {
|
||||||
return ti
|
return ti
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *TemplateStore) LookupShortcode(q TemplateQuery) (*TemplInfo, error) {
|
func (s *TemplateStore) LookupShortcode(q TemplateQuery) *TemplInfo {
|
||||||
q.init()
|
q.init()
|
||||||
k1 := s.key(q.Path)
|
k1 := s.key(q.Path)
|
||||||
|
|
||||||
|
@ -633,15 +630,13 @@ func (s *TemplateStore) LookupShortcode(q TemplateQuery) (*TemplInfo, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for k, vv := range v {
|
for k, vv := range v {
|
||||||
best.candidates = append(best.candidates, vv)
|
|
||||||
if !q.Consider(vv) {
|
if !q.Consider(vv) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
weight := s.dh.compareDescriptors(q.Category, vv.subCategory == SubCategoryEmbedded, q.Desc, k)
|
weight := s.dh.compareDescriptors(q.Category, vv.subCategory == SubCategoryEmbedded, q.Desc, k)
|
||||||
weight.distance = distance
|
weight.distance = distance
|
||||||
isBetter := best.isBetter(weight, vv)
|
if best.isBetter(weight, vv) {
|
||||||
if isBetter {
|
|
||||||
best.updateValues(weight, k2, k, vv)
|
best.updateValues(weight, k2, k, vv)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -649,21 +644,8 @@ func (s *TemplateStore) LookupShortcode(q TemplateQuery) (*TemplInfo, error) {
|
||||||
return false, nil
|
return false, nil
|
||||||
})
|
})
|
||||||
|
|
||||||
if best.w.w1 <= 0 {
|
// Any match will do.
|
||||||
var err error
|
return best.templ
|
||||||
if s := best.candidatesAsStringSlice(); s != nil {
|
|
||||||
msg := fmt.Sprintf("no compatible template found for shortcode %q in %s", q.Name, s)
|
|
||||||
if !q.Desc.IsPlainText {
|
|
||||||
msg += "; note that to use plain text template shortcodes in HTML you need to use the shortcode {{% delimiter"
|
|
||||||
}
|
|
||||||
err = errors.New(msg)
|
|
||||||
} else {
|
|
||||||
err = fmt.Errorf("no template found for shortcode %q", q.Name)
|
|
||||||
}
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return best.templ, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// PrintDebug is for testing/debugging only.
|
// PrintDebug is for testing/debugging only.
|
||||||
|
@ -711,16 +693,12 @@ 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.createTemplatesSnapshot(); err != nil {
|
if err := s.parseTemplates(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if err := s.parseTemplates(true); err != nil {
|
if err := s.extractInlinePartials(); 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
|
||||||
}
|
}
|
||||||
|
@ -734,7 +712,6 @@ func (s *TemplateStore) RefreshFiles(include func(fi hugofs.FileMetaInfo) bool)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *TemplateStore) HasTemplate(templatePath string) bool {
|
func (s *TemplateStore) HasTemplate(templatePath string) bool {
|
||||||
templatePath = strings.ToLower(templatePath)
|
|
||||||
templatePath = paths.AddLeadingSlash(templatePath)
|
templatePath = paths.AddLeadingSlash(templatePath)
|
||||||
return s.templatesByPath.Contains(templatePath)
|
return s.templatesByPath.Contains(templatePath)
|
||||||
}
|
}
|
||||||
|
@ -946,21 +923,19 @@ func (s *TemplateStore) extractIdentifiers(line string) []string {
|
||||||
return identifiers
|
return identifiers
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *TemplateStore) extractInlinePartials(rebuild bool) error {
|
func (s *TemplateStore) extractInlinePartials() 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.
|
||||||
for templ := range s.allRawTemplates() {
|
addIfNotSeen := func(isText bool, templs ...tpl.Template) error {
|
||||||
|
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.
|
||||||
|
@ -970,7 +945,7 @@ func (s *TemplateStore) extractInlinePartials(rebuild bool) 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, SubCategoryInline, false, s.treeMain)
|
ti, err := s.insertTemplate(pi, nil, false, s.treeMain)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -979,46 +954,30 @@ func (s *TemplateStore) extractInlinePartials(rebuild bool) error {
|
||||||
ti.Template = templ
|
ti.Template = templ
|
||||||
ti.noBaseOf = true
|
ti.noBaseOf = true
|
||||||
ti.subCategory = SubCategoryInline
|
ti.subCategory = SubCategoryInline
|
||||||
ti.D.IsPlainText = isText(templ)
|
ti.D.IsPlainText = isText
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
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(tpath string, d fs.DirEntry, err error) error {
|
return fs.WalkDir(embeddedTemplatesFs, ".", func(path string, d fs.DirEntry, err error) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -1026,7 +985,7 @@ func (s *TemplateStore) insertEmbedded() error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
templb, err := embeddedTemplatesFs.ReadFile(tpath)
|
templb, err := embeddedTemplatesFs.ReadFile(path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -1034,7 +993,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(tpath), "embedded/templates/")
|
name := strings.TrimPrefix(filepath.ToSlash(path), "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)
|
||||||
|
@ -1048,7 +1007,7 @@ func (s *TemplateStore) insertEmbedded() error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
ti, err = s.insertTemplate(pi, nil, SubCategoryEmbedded, false, s.treeMain)
|
ti, err = s.insertTemplate(pi, nil, false, s.treeMain)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -1064,19 +1023,6 @@ 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
|
||||||
}
|
}
|
||||||
|
@ -1142,7 +1088,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, subCategory SubCategory, replace bool, tree doctree.Tree[map[nodeKey]*TemplInfo]) (*TemplInfo, error) {
|
func (s *TemplateStore) insertTemplate(pi *paths.Path, fi hugofs.FileMetaInfo, 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 {
|
||||||
|
@ -1156,7 +1102,7 @@ func (s *TemplateStore) insertTemplate(pi *paths.Path, fi hugofs.FileMetaInfo, s
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return s.insertTemplate2(pi, fi, key, category, subCategory, d, replace, false, tree)
|
return s.insertTemplate2(pi, fi, key, category, d, replace, false, tree)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *TemplateStore) insertTemplate2(
|
func (s *TemplateStore) insertTemplate2(
|
||||||
|
@ -1164,7 +1110,6 @@ 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],
|
||||||
|
@ -1187,28 +1132,14 @@ func (s *TemplateStore) insertTemplate2(
|
||||||
tree.Insert(key, m)
|
tree.Insert(key, m)
|
||||||
}
|
}
|
||||||
|
|
||||||
nkExisting, existingFound := m[nk]
|
if !replace {
|
||||||
if !replace && existingFound && fi != nil && nkExisting.Fi != nil {
|
if v, found := m[nk]; found {
|
||||||
// See issue #13715.
|
if len(pi.Identifiers()) >= len(v.PathInfo.Identifiers()) {
|
||||||
// We do the merge on the file system level, but from Hugo v0.146.0 we have a situation where
|
|
||||||
// the project may well have a different layouts layout compared to the theme(s) it uses.
|
|
||||||
// We could possibly have fixed that on a lower (file system) level, but since this is just
|
|
||||||
// a temporary situation (until all projects are updated),
|
|
||||||
// do a replace here if the file comes from higher up in the module chain.
|
|
||||||
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 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.
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ti := &TemplInfo{
|
ti := &TemplInfo{
|
||||||
PathInfo: pi,
|
PathInfo: pi,
|
||||||
|
@ -1233,7 +1164,7 @@ func (s *TemplateStore) insertTemplate2(
|
||||||
return ti, nil
|
return ti, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *TemplateStore) insertTemplates(include func(fi hugofs.FileMetaInfo) bool, partialRebuild bool) error {
|
func (s *TemplateStore) insertTemplates(include func(fi hugofs.FileMetaInfo) bool, replace bool) error {
|
||||||
if include == nil {
|
if include == nil {
|
||||||
include = func(fi hugofs.FileMetaInfo) bool {
|
include = func(fi hugofs.FileMetaInfo) bool {
|
||||||
return true
|
return true
|
||||||
|
@ -1415,7 +1346,7 @@ func (s *TemplateStore) insertTemplates(include func(fi hugofs.FileMetaInfo) boo
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if partialRebuild && pi.NameNoIdentifier() == baseNameBaseof {
|
if replace && pi.NameNoIdentifier() == baseNameBaseof {
|
||||||
// A baseof file has changed.
|
// A baseof file has changed.
|
||||||
resetBaseVariants = true
|
resetBaseVariants = true
|
||||||
}
|
}
|
||||||
|
@ -1423,12 +1354,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, partialRebuild, s.treeShortcodes)
|
ti, err = s.insertShortcode(pi, fi, replace, s.treeShortcodes)
|
||||||
if err != nil || ti == nil {
|
if err != nil || ti == nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
ti, err = s.insertTemplate(pi, fi, SubCategoryMain, partialRebuild, s.treeMain)
|
ti, err = s.insertTemplate(pi, fi, replace, s.treeMain)
|
||||||
if err != nil || ti == nil {
|
if err != nil || ti == nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -1462,7 +1393,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, SubCategoryMain, desc, true, true, s.treeMain)
|
ti, err := s.insertTemplate2(pi, fi, targetPath, category, desc, true, true, s.treeMain)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -1473,7 +1404,6 @@ 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 {
|
||||||
|
@ -1500,15 +1430,7 @@ func (s *TemplateStore) key(dir string) string {
|
||||||
return paths.TrimTrailing(dir)
|
return paths.TrimTrailing(dir)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *TemplateStore) createTemplatesSnapshot() error {
|
func (s *TemplateStore) parseTemplates() 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() {
|
||||||
|
@ -1516,7 +1438,7 @@ func (s *TemplateStore) parseTemplates(replace bool) error {
|
||||||
if vv.state == processingStateTransformed {
|
if vv.state == processingStateTransformed {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if err := s.parseTemplate(vv, replace); err != nil {
|
if err := s.parseTemplate(vv); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1536,7 +1458,7 @@ func (s *TemplateStore) parseTemplates(replace bool) 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, replace); err != nil {
|
if err := s.parseTemplate(vv); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
continue
|
continue
|
||||||
|
@ -1565,7 +1487,7 @@ func (s *TemplateStore) parseTemplates(replace bool) error {
|
||||||
if vvv.state == processingStateTransformed {
|
if vvv.state == processingStateTransformed {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if err := s.parseTemplate(vvv, replace); err != nil {
|
if err := s.parseTemplate(vvv); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1889,7 +1811,6 @@ type bestMatch struct {
|
||||||
desc TemplateDescriptor
|
desc TemplateDescriptor
|
||||||
w weight
|
w weight
|
||||||
key string
|
key string
|
||||||
candidates []*TemplInfo
|
|
||||||
|
|
||||||
// settings.
|
// settings.
|
||||||
defaultOutputformat string
|
defaultOutputformat string
|
||||||
|
@ -1900,18 +1821,6 @@ func (best *bestMatch) reset() {
|
||||||
best.w = weight{}
|
best.w = weight{}
|
||||||
best.desc = TemplateDescriptor{}
|
best.desc = TemplateDescriptor{}
|
||||||
best.key = ""
|
best.key = ""
|
||||||
best.candidates = nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (best *bestMatch) candidatesAsStringSlice() []string {
|
|
||||||
if len(best.candidates) == 0 {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
candidates := make([]string, len(best.candidates))
|
|
||||||
for i, v := range best.candidates {
|
|
||||||
candidates[i] = v.PathInfo.Path()
|
|
||||||
}
|
|
||||||
return candidates
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (best *bestMatch) isBetter(w weight, ti *TemplInfo) bool {
|
func (best *bestMatch) isBetter(w weight, ti *TemplInfo) bool {
|
||||||
|
@ -1921,6 +1830,7 @@ func (best *bestMatch) isBetter(w weight, ti *TemplInfo) bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
if w.w1 <= 0 {
|
if w.w1 <= 0 {
|
||||||
|
|
||||||
if best.w.w1 <= 0 {
|
if best.w.w1 <= 0 {
|
||||||
return ti.PathInfo.Path() < best.templ.PathInfo.Path()
|
return ti.PathInfo.Path() < best.templ.PathInfo.Path()
|
||||||
}
|
}
|
||||||
|
|
|
@ -920,26 +920,6 @@ func TestPartialHTML(t *testing.T) {
|
||||||
b.AssertFileContent("public/index.html", "<link rel=\"stylesheet\" href=\"/css/style.css\">")
|
b.AssertFileContent("public/index.html", "<link rel=\"stylesheet\" href=\"/css/style.css\">")
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestPartialPlainTextInHTML(t *testing.T) {
|
|
||||||
t.Parallel()
|
|
||||||
|
|
||||||
files := `
|
|
||||||
-- hugo.toml --
|
|
||||||
-- layouts/all.html --
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
{{ partial "mypartial.txt" . }}
|
|
||||||
</head>
|
|
||||||
</html>
|
|
||||||
-- layouts/partials/mypartial.txt --
|
|
||||||
My <div>partial</div>.
|
|
||||||
`
|
|
||||||
|
|
||||||
b := hugolib.Test(t, files)
|
|
||||||
|
|
||||||
b.AssertFileContent("public/index.html", "My <div>partial</div>.")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Issue #13593.
|
// Issue #13593.
|
||||||
func TestGoatAndNoGoat(t *testing.T) {
|
func TestGoatAndNoGoat(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
@ -1123,35 +1103,6 @@ All.
|
||||||
b.AssertLogContains("unrecognized render hook")
|
b.AssertLogContains("unrecognized render hook")
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestLayoutNotFound(t *testing.T) {
|
|
||||||
t.Parallel()
|
|
||||||
|
|
||||||
files := `
|
|
||||||
-- hugo.toml --
|
|
||||||
-- layouts/single.html --
|
|
||||||
Single.
|
|
||||||
`
|
|
||||||
b := hugolib.Test(t, files, hugolib.TestOptWarn())
|
|
||||||
b.AssertLogContains("WARN found no layout file for \"html\" for kind \"home\"")
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestLayoutOverrideThemeWhenThemeOnOldFormatIssue13715(t *testing.T) {
|
|
||||||
t.Parallel()
|
|
||||||
|
|
||||||
files := `
|
|
||||||
-- hugo.toml --
|
|
||||||
theme = "mytheme"
|
|
||||||
-- layouts/list.html --
|
|
||||||
layouts/list.html
|
|
||||||
-- themes/mytheme/layouts/_default/list.html --
|
|
||||||
mytheme/layouts/_default/list.html
|
|
||||||
|
|
||||||
`
|
|
||||||
|
|
||||||
b := hugolib.Test(t, files)
|
|
||||||
b.AssertFileContent("public/index.html", "layouts/list.html")
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkExecuteWithContext(b *testing.B) {
|
func BenchmarkExecuteWithContext(b *testing.B) {
|
||||||
files := `
|
files := `
|
||||||
-- hugo.toml --
|
-- hugo.toml --
|
||||||
|
@ -1246,8 +1197,8 @@ s2.
|
||||||
Category: tplimpl.CategoryShortcode,
|
Category: tplimpl.CategoryShortcode,
|
||||||
Desc: desc,
|
Desc: desc,
|
||||||
}
|
}
|
||||||
v, err := store.LookupShortcode(q)
|
v := store.LookupShortcode(q)
|
||||||
if v == nil || err != nil {
|
if v == nil {
|
||||||
b.Fatal("not found")
|
b.Fatal("not found")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1508,43 +1459,3 @@ 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>")
|
|
||||||
}
|
|
||||||
|
|
|
@ -17,10 +17,8 @@ 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"
|
||||||
|
@ -236,7 +234,6 @@ 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",
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -246,23 +243,8 @@ 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/" + fileCacheEntryVersion + "/" + s[:2] + "/" + s[2:]
|
key := "tomath/" + 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) {
|
||||||
|
@ -283,35 +265,15 @@ 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
|
||||||
}
|
}
|
||||||
|
|
||||||
var e fileCacheEntry
|
s, err := hugio.ReadString(r)
|
||||||
if err := json.NewDecoder(r).Decode(&e); err != nil {
|
|
||||||
return "", fmt.Errorf("failed to decode file cache entry: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, warning := range e.Warnings {
|
return template.HTML(s), err
|
||||||
ns.deps.Log.Warnf("transform.ToMath: %s", warning)
|
|
||||||
}
|
|
||||||
|
|
||||||
return template.HTML(e.Output), err
|
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
|
|
|
@ -495,43 +495,3 @@ 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")
|
|
||||||
}
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue