]> git.maquefel.me Git - brevno-suite/hugo/commitdiff
resources: Address Dart Sass deprecation of global built-in functions
authorJoe Mooring <joe.mooring@veriphor.com>
Fri, 18 Oct 2024 23:10:46 +0000 (16:10 -0700)
committerBjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>
Fri, 1 Nov 2024 13:05:27 +0000 (14:05 +0100)
See https://github.com/sass/dart-sass/releases/tag/1.80.0

Fixes #12961

resources/resource_transformers/tocss/dartsass/transform.go
resources/resource_transformers/tocss/internal/sass/helpers.go [deleted file]
resources/resource_transformers/tocss/internal/sass/helpers_test.go [deleted file]
resources/resource_transformers/tocss/sass/helpers.go [new file with mode: 0644]
resources/resource_transformers/tocss/sass/helpers_test.go [new file with mode: 0644]
resources/resource_transformers/tocss/scss/tocss.go
tpl/css/css.go
tpl/resources/resources_integration_test.go

index f0bd6634af58a5c36a5f9d804d06d2e6477a6cdf..d8b6ae5b42c1f225207bdfeec744c8614b8121e2 100644 (file)
@@ -29,7 +29,7 @@ import (
        "github.com/gohugoio/hugo/resources"
 
        "github.com/gohugoio/hugo/resources/internal"
-       "github.com/gohugoio/hugo/resources/resource_transformers/tocss/internal/sass"
+       "github.com/gohugoio/hugo/resources/resource_transformers/tocss/sass"
 
        "github.com/spf13/afero"
 
@@ -85,7 +85,7 @@ func (t *transform) Transform(ctx *resources.ResourceTransformationCtx) error {
                        c:                 t.c,
                        dependencyManager: ctx.DependencyManager,
 
-                       varsStylesheet: godartsass.Import{Content: sass.CreateVarsStyleSheet(opts.Vars)},
+                       varsStylesheet: godartsass.Import{Content: sass.CreateVarsStyleSheet(sass.TranspilerDart, opts.Vars)},
                },
                OutputStyle:             godartsass.ParseOutputStyle(opts.OutputStyle),
                EnableSourceMap:         opts.EnableSourceMap,
diff --git a/resources/resource_transformers/tocss/internal/sass/helpers.go b/resources/resource_transformers/tocss/internal/sass/helpers.go
deleted file mode 100644 (file)
index c1cef14..0000000
+++ /dev/null
@@ -1,87 +0,0 @@
-// Copyright 2024 The Hugo Authors. All rights reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package sass
-
-import (
-       "fmt"
-       "regexp"
-       "sort"
-       "strings"
-
-       "github.com/gohugoio/hugo/common/types/css"
-)
-
-const (
-       HugoVarsNamespace = "hugo:vars"
-)
-
-func CreateVarsStyleSheet(vars map[string]any) string {
-       if vars == nil {
-               return ""
-       }
-       var varsStylesheet string
-
-       var varsSlice []string
-       for k, v := range vars {
-               var prefix string
-               if !strings.HasPrefix(k, "$") {
-                       prefix = "$"
-               }
-
-               switch v.(type) {
-               case css.QuotedString:
-                       // Marked by the user as a string that needs to be quoted.
-                       varsSlice = append(varsSlice, fmt.Sprintf("%s%s: %q;", prefix, k, v))
-               default:
-                       if isTypedCSSValue(v) {
-                               // E.g. 24px, 1.5rem, 10%, hsl(0, 0%, 100%), calc(24px + 36px), #fff, #ffffff.
-                               varsSlice = append(varsSlice, fmt.Sprintf("%s%s: %v;", prefix, k, v))
-                       } else {
-                               // unquote will preserve quotes around URLs etc. if needed.
-                               varsSlice = append(varsSlice, fmt.Sprintf("%s%s: unquote(%q);", prefix, k, v))
-                       }
-               }
-       }
-       sort.Strings(varsSlice)
-       varsStylesheet = strings.Join(varsSlice, "\n")
-       return varsStylesheet
-}
-
-var (
-       isCSSColor = regexp.MustCompile(`^#[0-9a-fA-F]{3,6}$`)
-       isCSSFunc  = regexp.MustCompile(`^([a-zA-Z-]+)\(`)
-       isCSSUnit  = regexp.MustCompile(`^([0-9]+)(\.[0-9]+)?([a-zA-Z-%]+)$`)
-)
-
-// isTypedCSSValue returns true if the given string is a CSS value that
-// we should preserve the type of, as in: Not wrap it in quotes.
-func isTypedCSSValue(v any) bool {
-       switch s := v.(type) {
-       case int, int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64, float32, float64, css.UnquotedString:
-               return true
-       case string:
-               if isCSSColor.MatchString(s) {
-                       return true
-               }
-               if isCSSFunc.MatchString(s) {
-                       return true
-               }
-               if isCSSUnit.MatchString(s) {
-                       return true
-               }
-
-       }
-
-       return false
-}
diff --git a/resources/resource_transformers/tocss/internal/sass/helpers_test.go b/resources/resource_transformers/tocss/internal/sass/helpers_test.go
deleted file mode 100644 (file)
index ef31fdd..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-// Copyright 2024 The Hugo Authors. All rights reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package sass
-
-import (
-       "testing"
-
-       qt "github.com/frankban/quicktest"
-)
-
-func TestIsUnquotedCSSValue(t *testing.T) {
-       c := qt.New(t)
-
-       for _, test := range []struct {
-               in  any
-               out bool
-       }{
-               {"24px", true},
-               {"1.5rem", true},
-               {"10%", true},
-               {"hsl(0, 0%, 100%)", true},
-               {"calc(24px + 36px)", true},
-               {"24xxx", true}, // a false positive.
-               {123, true},
-               {123.12, true},
-               {"#fff", true},
-               {"#ffffff", true},
-               {"#ffffffff", false},
-       } {
-               c.Assert(isTypedCSSValue(test.in), qt.Equals, test.out)
-       }
-}
diff --git a/resources/resource_transformers/tocss/sass/helpers.go b/resources/resource_transformers/tocss/sass/helpers.go
new file mode 100644 (file)
index 0000000..d4091a3
--- /dev/null
@@ -0,0 +1,102 @@
+// Copyright 2024 The Hugo Authors. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package sass
+
+import (
+       "fmt"
+       "regexp"
+       "sort"
+       "strings"
+
+       "github.com/gohugoio/hugo/common/types/css"
+)
+
+const (
+       HugoVarsNamespace = "hugo:vars"
+       // Transpiler implementation can be controlled from the client by
+       // setting the 'transpiler' option.
+       // Default is currently 'libsass', but that may change.
+       TranspilerDart    = "dartsass"
+       TranspilerLibSass = "libsass"
+)
+
+func CreateVarsStyleSheet(transpiler string, vars map[string]any) string {
+       if vars == nil {
+               return ""
+       }
+       var varsStylesheet string
+
+       var varsSlice []string
+       for k, v := range vars {
+               var prefix string
+               if !strings.HasPrefix(k, "$") {
+                       prefix = "$"
+               }
+
+               switch v.(type) {
+               case css.QuotedString:
+                       // Marked by the user as a string that needs to be quoted.
+                       varsSlice = append(varsSlice, fmt.Sprintf("%s%s: %q;", prefix, k, v))
+               default:
+                       if isTypedCSSValue(v) {
+                               // E.g. 24px, 1.5rem, 10%, hsl(0, 0%, 100%), calc(24px + 36px), #fff, #ffffff.
+                               varsSlice = append(varsSlice, fmt.Sprintf("%s%s: %v;", prefix, k, v))
+                       } else {
+                               // unquote will preserve quotes around URLs etc. if needed.
+                               if transpiler == TranspilerDart {
+                                       varsSlice = append(varsSlice, fmt.Sprintf("%s%s: string.unquote(%q);", prefix, k, v))
+                               } else {
+                                       varsSlice = append(varsSlice, fmt.Sprintf("%s%s: unquote(%q);", prefix, k, v))
+                               }
+                       }
+               }
+       }
+       sort.Strings(varsSlice)
+
+       if transpiler == TranspilerDart {
+               varsStylesheet = `@use "sass:string";` + "\n" + strings.Join(varsSlice, "\n")
+       } else {
+               varsStylesheet = strings.Join(varsSlice, "\n")
+       }
+
+       return varsStylesheet
+}
+
+var (
+       isCSSColor = regexp.MustCompile(`^#[0-9a-fA-F]{3,6}$`)
+       isCSSFunc  = regexp.MustCompile(`^([a-zA-Z-]+)\(`)
+       isCSSUnit  = regexp.MustCompile(`^([0-9]+)(\.[0-9]+)?([a-zA-Z-%]+)$`)
+)
+
+// isTypedCSSValue returns true if the given string is a CSS value that
+// we should preserve the type of, as in: Not wrap it in quotes.
+func isTypedCSSValue(v any) bool {
+       switch s := v.(type) {
+       case int, int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64, float32, float64, css.UnquotedString:
+               return true
+       case string:
+               if isCSSColor.MatchString(s) {
+                       return true
+               }
+               if isCSSFunc.MatchString(s) {
+                       return true
+               }
+               if isCSSUnit.MatchString(s) {
+                       return true
+               }
+
+       }
+
+       return false
+}
diff --git a/resources/resource_transformers/tocss/sass/helpers_test.go b/resources/resource_transformers/tocss/sass/helpers_test.go
new file mode 100644 (file)
index 0000000..ef31fdd
--- /dev/null
@@ -0,0 +1,43 @@
+// Copyright 2024 The Hugo Authors. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package sass
+
+import (
+       "testing"
+
+       qt "github.com/frankban/quicktest"
+)
+
+func TestIsUnquotedCSSValue(t *testing.T) {
+       c := qt.New(t)
+
+       for _, test := range []struct {
+               in  any
+               out bool
+       }{
+               {"24px", true},
+               {"1.5rem", true},
+               {"10%", true},
+               {"hsl(0, 0%, 100%)", true},
+               {"calc(24px + 36px)", true},
+               {"24xxx", true}, // a false positive.
+               {123, true},
+               {123.12, true},
+               {"#fff", true},
+               {"#ffffff", true},
+               {"#ffffffff", false},
+       } {
+               c.Assert(isTypedCSSValue(test.in), qt.Equals, test.out)
+       }
+}
index 36ef2a77db4975ea49ceffbd853535efef339415..4b9c51ce05f135288e32f65b42e0514acc36e6dd 100644 (file)
@@ -31,7 +31,7 @@ import (
        "github.com/gohugoio/hugo/identity"
        "github.com/gohugoio/hugo/media"
        "github.com/gohugoio/hugo/resources"
-       "github.com/gohugoio/hugo/resources/resource_transformers/tocss/internal/sass"
+       "github.com/gohugoio/hugo/resources/resource_transformers/tocss/sass"
 )
 
 // Used in tests. This feature requires Hugo to be built with the extended tag.
@@ -64,7 +64,7 @@ func (t *toCSSTransformation) Transform(ctx *resources.ResourceTransformationCtx
                }
        }
 
-       varsStylesheet := sass.CreateVarsStyleSheet(options.from.Vars)
+       varsStylesheet := sass.CreateVarsStyleSheet(sass.TranspilerLibSass, options.from.Vars)
 
        // To allow for overrides of SCSS files anywhere in the project/theme hierarchy, we need
        // to help libsass revolve the filename by looking in the composite filesystem first.
index 48a526c1722d25fce7aa4bbaa8f7d373a2608f29..199deda6902562191a2f87e67058febbf8ba0fa8 100644 (file)
@@ -15,6 +15,7 @@ import (
        "github.com/gohugoio/hugo/resources/resource_transformers/babel"
        "github.com/gohugoio/hugo/resources/resource_transformers/cssjs"
        "github.com/gohugoio/hugo/resources/resource_transformers/tocss/dartsass"
+       "github.com/gohugoio/hugo/resources/resource_transformers/tocss/sass"
        "github.com/gohugoio/hugo/resources/resource_transformers/tocss/scss"
        "github.com/gohugoio/hugo/tpl/internal"
        "github.com/gohugoio/hugo/tpl/internal/resourcehelpers"
@@ -84,21 +85,13 @@ func (ns *Namespace) Sass(args ...any) (resource.Resource, error) {
                return nil, errors.New("must not provide more arguments than resource object and options")
        }
 
-       const (
-               // Transpiler implementation can be controlled from the client by
-               // setting the 'transpiler' option.
-               // Default is currently 'libsass', but that may change.
-               transpilerDart    = "dartsass"
-               transpilerLibSass = "libsass"
-       )
-
        var (
                r          resources.ResourceTransformer
                m          map[string]any
                targetPath string
                err        error
                ok         bool
-               transpiler = transpilerLibSass
+               transpiler = sass.TranspilerLibSass
        )
 
        r, targetPath, ok = resourcehelpers.ResolveIfFirstArgIsString(args)
@@ -113,15 +106,15 @@ func (ns *Namespace) Sass(args ...any) (resource.Resource, error) {
        if m != nil {
                if t, _, found := maps.LookupEqualFold(m, "transpiler"); found {
                        switch t {
-                       case transpilerDart, transpilerLibSass:
+                       case sass.TranspilerDart, sass.TranspilerLibSass:
                                transpiler = cast.ToString(t)
                        default:
-                               return nil, fmt.Errorf("unsupported transpiler %q; valid values are %q or %q", t, transpilerLibSass, transpilerDart)
+                               return nil, fmt.Errorf("unsupported transpiler %q; valid values are %q or %q", t, sass.TranspilerLibSass, sass.TranspilerDart)
                        }
                }
        }
 
-       if transpiler == transpilerLibSass {
+       if transpiler == sass.TranspilerLibSass {
                var options scss.Options
                if targetPath != "" {
                        options.TargetPath = paths.ToSlashTrimLeading(targetPath)
index cfd03dc735e06a207f45cea9072bbf0fed5b7926..563b3c45582e392398c9bd3fcbf6a4b4cdae039f 100644 (file)
@@ -18,6 +18,8 @@ import (
 
        qt "github.com/frankban/quicktest"
        "github.com/gohugoio/hugo/hugolib"
+       "github.com/gohugoio/hugo/resources/resource_transformers/tocss/dartsass"
+       "github.com/gohugoio/hugo/resources/resource_transformers/tocss/scss"
 )
 
 func TestCopy(t *testing.T) {
@@ -238,3 +240,45 @@ match /files/C*: 2|
        b.AssertFileContent("public/files/b.txt", "I am b.txt")
        b.AssertFileContent("public/files/C.txt", "I am C.txt")
 }
+
+// Issue #12961
+func TestDartSassVars(t *testing.T) {
+       t.Parallel()
+
+       if !scss.Supports() || !dartsass.Supports() {
+               t.Skip()
+       }
+
+       files := `
+-- hugo.toml --
+disableKinds = ['page','section','rss','sitemap','taxonomy','term']
+-- layouts/index.html --
+{{ $opts := dict "transpiler" "dartsass" "outputStyle" "compressed" "vars" (dict "color" "red") }}
+{{ with resources.Get "dartsass.scss" | css.Sass $opts }}
+  {{ .Content }}
+{{ end }}
+
+{{ $opts := dict "transpiler" "libsass" "outputStyle" "compressed" "vars" (dict "color" "blue") }}
+{{ with resources.Get "libsass.scss" | css.Sass $opts }}
+  {{ .Content }}
+{{ end }}
+-- assets/dartsass.scss --
+@use "hugo:vars" as v;
+.dartsass {
+  color: v.$color;
+}
+-- assets/libsass.scss --
+@import "hugo:vars";
+.libsass {
+  color: $color;
+}
+`
+
+       b := hugolib.Test(t, files, hugolib.TestOptWarn())
+
+       b.AssertFileContent("public/index.html",
+               ".dartsass{color:red}",
+               ".libsass{color:blue}",
+       )
+       b.AssertLogContains("! WARN  Dart Sass: hugo:vars")
+}