mirror of
https://github.com/gohugoio/hugo.git
synced 2026-08-24 15:28:54 +00:00
Add importContext option to css.Build, js.Build, css.Sass and css.TailwindCSS
This allows @import statements to be resolved in a set of user provided resources (e.g. from resources.FromString or css.ChromaStyles) before the assets filesystem. The option also applies to css.PostCSS via the shared import inlining, and css.Sass requires the dartsass transpiler. The import context is part of the transformation cache key. Fixes #15103 Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
+31
-21
@@ -18,6 +18,7 @@ import (
|
||||
"crypto/md5"
|
||||
"encoding/hex"
|
||||
"io"
|
||||
"reflect"
|
||||
"strconv"
|
||||
"sync"
|
||||
|
||||
@@ -124,11 +125,38 @@ func HashStringHex(vs ...any) string {
|
||||
var hashOptsPool = sync.Pool{
|
||||
New: func() any {
|
||||
return &hashstructure.HashOptions{
|
||||
Hasher: xxhash.New(),
|
||||
Hasher: xxhash.New(),
|
||||
UnwrapFunc: unwrapForHashing,
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
// hashstructure only sees exported struct fields, so rewrite known identity types before hashing,
|
||||
// e.g. a Resource or Page nested in an options map hashes by its Key.
|
||||
func unwrapForHashing(v reflect.Value) (reflect.Value, error) {
|
||||
if v.Kind() != reflect.Struct {
|
||||
return v, nil
|
||||
}
|
||||
var in any
|
||||
if v.CanAddr() {
|
||||
// The common case; pointer receiver methods on a struct
|
||||
// reached through a pointer.
|
||||
in = v.Addr().Interface()
|
||||
} else {
|
||||
in = v.Interface()
|
||||
}
|
||||
switch t := in.(type) {
|
||||
case hashstructure.Hashable:
|
||||
// Let hashstructure handle it.
|
||||
return v, nil
|
||||
case keyer:
|
||||
return reflect.ValueOf(t.Key()), nil
|
||||
case identity.IdentityProvider:
|
||||
return reflect.ValueOf(t.GetIdentity()), nil
|
||||
}
|
||||
return v, nil
|
||||
}
|
||||
|
||||
func getHashOpts() *hashstructure.HashOptions {
|
||||
return hashOptsPool.Get().(*hashstructure.HashOptions)
|
||||
}
|
||||
@@ -145,15 +173,10 @@ func putHashOpts(opts *hashstructure.HashOptions) {
|
||||
func HashUint64(vs ...any) uint64 {
|
||||
var o any
|
||||
if len(vs) == 1 {
|
||||
o = toHashable(vs[0])
|
||||
o = vs[0]
|
||||
} else {
|
||||
elements := make([]any, len(vs))
|
||||
for i, e := range vs {
|
||||
elements[i] = toHashable(e)
|
||||
}
|
||||
o = elements
|
||||
o = vs
|
||||
}
|
||||
|
||||
hash, err := Hash(o)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
@@ -176,19 +199,6 @@ type keyer interface {
|
||||
Key() string
|
||||
}
|
||||
|
||||
// For structs, hashstructure.Hash only works on the exported fields,
|
||||
// so rewrite the input slice for known identity types.
|
||||
func toHashable(v any) any {
|
||||
switch t := v.(type) {
|
||||
case keyer:
|
||||
return t.Key()
|
||||
case identity.IdentityProvider:
|
||||
return t.GetIdentity()
|
||||
default:
|
||||
return v
|
||||
}
|
||||
}
|
||||
|
||||
type xxhashReadFrom struct {
|
||||
buff []byte
|
||||
*xxhash.Digest
|
||||
|
||||
Reference in New Issue
Block a user