]> git.maquefel.me Git - brevno-suite/hugo/commitdiff
Upgrade to v2 of the Dart Sass Embedded Protocol
authorBjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>
Thu, 8 Jun 2023 14:29:04 +0000 (16:29 +0200)
committerBjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>
Mon, 12 Jun 2023 11:47:38 +0000 (13:47 +0200)
Fixes #11059

.github/workflows/test-dart-sass-v1.yml [new file with mode: 0644]
.github/workflows/test.yml
common/herrors/file_error.go
common/hugo/hugo.go
config/security/securityConfig.go
config/security/securityConfig_test.go
go.mod
go.sum
hugolib/securitypolicies_test.go
resources/resource_transformers/tocss/dartsass/client.go
resources/resource_transformers/tocss/dartsass/transform.go

diff --git a/.github/workflows/test-dart-sass-v1.yml b/.github/workflows/test-dart-sass-v1.yml
new file mode 100644 (file)
index 0000000..ff6f6a0
--- /dev/null
@@ -0,0 +1,73 @@
+on:
+  push:
+    branches: [ master ]
+  pull_request:
+name: TestDartSassV1
+env:
+    GOPROXY: https://proxy.golang.org
+    GO111MODULE: on
+    DART_SASS_VERSION: 1.62.1
+    DART_SASS_SHA_LINUX: 3574da75a7322a539034648b8ff84ff2cca162eb924d72b663d718cd3936f075
+permissions:
+  contents: read
+jobs:
+  test:
+    strategy:
+      matrix:
+        go-version: [1.20.x]
+        os: [ubuntu-latest]
+    runs-on: ${{ matrix.os }}
+    steps:
+    - name: Checkout code
+      uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab
+    - name: Install Go
+      uses: actions/setup-go@fac708d6674e30b6ba41289acaab6d4b75aa0753
+      with:
+        go-version: ${{ matrix.go-version }}
+        check-latest: true
+        cache: true
+        cache-dependency-path: |
+          **/go.sum
+          **/go.mod
+    - name: Install Ruby
+      uses: ruby/setup-ruby@ee2113536afb7f793eed4ce60e8d3b26db912da4
+      with:
+        ruby-version: '2.7' 
+        bundler-cache: true #
+    - name: Install Python
+      uses: actions/setup-python@3105fb18c05ddd93efea5f9e0bef7a03a6e9e7df
+      with:
+        python-version: '3.x'
+    - name: Install Mage
+      run: go install github.com/magefile/mage@v1.15.0
+    - name: Install asciidoctor
+      uses: reitzig/actions-asciidoctor@7570212ae20b63653481675fb1ff62d1073632b0
+    - name: Install docutils
+      run: |
+        pip install docutils
+        rst2html.py --version
+    - if: matrix.os == 'ubuntu-latest'
+      name: Install pandoc on Linux
+      run: |
+          sudo apt-get update -y
+          sudo apt-get install -y pandoc
+    - if: matrix.os == 'macos-latest'
+      run: |
+        brew install pandoc
+    - if: matrix.os == 'windows-latest'
+      run: |
+        Choco-Install -PackageName pandoc
+    - run: pandoc -v
+    - name: Install dart-sass-embedded Linux
+      run: |
+        echo "Install Dart Sass version ${DART_SASS_VERSION} ..."
+        curl -LJO "https://github.com/sass/dart-sass-embedded/releases/download/${DART_SASS_VERSION}/sass_embedded-${DART_SASS_VERSION}-linux-x64.tar.gz";
+        echo "${DART_SASS_SHA_LINUX}  sass_embedded-${DART_SASS_VERSION}-linux-x64.tar.gz" | sha256sum -c;
+        tar -xvf "sass_embedded-${DART_SASS_VERSION}-linux-x64.tar.gz";
+        echo "$GITHUB_WORKSPACE/sass_embedded/" >> $GITHUB_PATH
+    - name: Check
+      run: |
+        dart-sass-embedded --version
+        mage -v check;
+      env:
+        HUGO_BUILD_TAGS: extended
index f23dde8031ea70ab61f08bd442354b101dbbb092..fd3847e598ab98a065169c8a9ae8a5cf31aed808 100644 (file)
@@ -6,17 +6,17 @@ name: Test
 env:
     GOPROXY: https://proxy.golang.org
     GO111MODULE: on
-    DART_SASS_VERSION: 1.56.2
-    DART_SASS_SHA_LINUX: 9e4f455f7b8619959d7878af2862383be58392eb963a14ff87cc512c03701e2a
-    DART_SASS_SHA_MACOS: 5992e979e2c30ec363f8e338822bb2b4443c74232b3340501a76180f5652cb09
-    DART_SASS_SHA_WINDOWS: 8d3d9117c54840e3e6a4919e43acf75ea52f28a64fc87a8e29d80ec72ee36cfb
+    SASS_VERSION: 1.63.2
+    DART_SASS_SHA_LINUX: 3ea33c95ad5c35fda6e9a0956199eef38a398f496cfb8750e02479d7d1dd42af
+    DART_SASS_SHA_MACOS: 11c70f259836b250b44a9cb57fed70e030f21f45069b467d371685855f1eb4f0
+    DART_SASS_SHA_WINDOWS: cd8cd36a619dd8e27f93d3186c52d70eb7d69472aa6c85f5094b29693e773f64
 permissions:
   contents: read
 jobs:
   test:
     strategy:
       matrix:
-        go-version: [1.19.x, 1.20.x]
+        go-version: [1.19.x,1.20.x]
         os: [ubuntu-latest, macos-latest, windows-latest]
     runs-on: ${{ matrix.os }}
     steps:
@@ -66,29 +66,31 @@ jobs:
     - if: matrix.os == 'ubuntu-latest'
       name: Install dart-sass-embedded Linux
       run: |
-        echo "Install Dart Sass version ${DART_SASS_VERSION} ..."
-        curl -LJO "https://github.com/sass/dart-sass-embedded/releases/download/${DART_SASS_VERSION}/sass_embedded-${DART_SASS_VERSION}-linux-x64.tar.gz";
-        echo "${DART_SASS_SHA_LINUX}  sass_embedded-${DART_SASS_VERSION}-linux-x64.tar.gz" | sha256sum -c;
-        tar -xvf "sass_embedded-${DART_SASS_VERSION}-linux-x64.tar.gz";
-        echo "$GITHUB_WORKSPACE/sass_embedded/" >> $GITHUB_PATH
+        echo "Install Dart Sass version ${SASS_VERSION} ..."
+        curl -LJO "https://github.com/sass/dart-sass/releases/download/${SASS_VERSION}/dart-sass-${SASS_VERSION}-linux-x64.tar.gz";
+        echo "${DART_SASS_SHA_LINUX}  dart-sass-${SASS_VERSION}-linux-x64.tar.gz" | sha256sum -c;
+        tar -xvf "dart-sass-${SASS_VERSION}-linux-x64.tar.gz";
+        echo "$GOBIN"
+        echo "$GITHUB_WORKSPACE/dart-sass/" >> $GITHUB_PATH
     - if: matrix.os == 'macos-latest'
       name: Install dart-sass-embedded MacOS
       run: |
-        echo "Install Dart Sass version ${DART_SASS_VERSION} ..."
-        curl -LJO "https://github.com/sass/dart-sass-embedded/releases/download/${DART_SASS_VERSION}/sass_embedded-${DART_SASS_VERSION}-macos-x64.tar.gz";
-        echo "${DART_SASS_SHA_MACOS}  sass_embedded-${DART_SASS_VERSION}-macos-x64.tar.gz" | shasum -a 256 -c;
-        tar -xvf "sass_embedded-${DART_SASS_VERSION}-macos-x64.tar.gz";
-        echo "$GITHUB_WORKSPACE/sass_embedded/" >> $GITHUB_PATH
+        echo "Install Dart Sass version ${SASS_VERSION} ..."
+        curl -LJO "https://github.com/sass/dart-sass/releases/download/${SASS_VERSION}/dart-sass-${SASS_VERSION}-macos-x64.tar.gz";
+        echo "${DART_SASS_SHA_MACOS}  dart-sass-${SASS_VERSION}-macos-x64.tar.gz" | shasum -a 256 -c;
+        tar -xvf "dart-sass-${SASS_VERSION}-macos-x64.tar.gz";
+        echo "$GITHUB_WORKSPACE/dart-sass/" >> $GITHUB_PATH
     - if: matrix.os == 'windows-latest'
       name: Install dart-sass-embedded Windows
       run: |
-        echo "Install Dart Sass version ${env:DART_SASS_VERSION} ..."
-        curl -LJO "https://github.com/sass/dart-sass-embedded/releases/download/${env:DART_SASS_VERSION}/sass_embedded-${env:DART_SASS_VERSION}-windows-x64.zip";
-        Expand-Archive -Path "sass_embedded-${env:DART_SASS_VERSION}-windows-x64.zip" -DestinationPath .;
-        echo  "$env:GITHUB_WORKSPACE/sass_embedded/" | Out-File -FilePath $Env:GITHUB_PATH -Encoding utf-8 -Append
+        echo "Install Dart Sass version ${env:SASS_VERSION} ..."
+        curl -LJO "https://github.com/sass/dart-sass/releases/download/${env:SASS_VERSION}/dart-sass-${env:SASS_VERSION}-windows-x64.zip";
+        Expand-Archive -Path "dart-sass-${env:SASS_VERSION}-windows-x64.zip" -DestinationPath .;
+        echo  "$env:GITHUB_WORKSPACE/dart-sass/" | Out-File -FilePath $Env:GITHUB_PATH -Encoding utf-8 -Append
     - if: matrix.os != 'windows-latest'
       name: Check
       run: |
+        sass --version;
         mage -v check;
       env:
         HUGO_BUILD_TAGS: extended
index 30417897f6a6ea6e6338fe833ae8b59830f6256c..ae86a700cb5201ee0e5c6f81462ef8f287c74f84 100644 (file)
@@ -15,11 +15,14 @@ package herrors
 
 import (
        "encoding/json"
+
+       godartsassv1 "github.com/bep/godartsass"
+
        "fmt"
        "io"
        "path/filepath"
 
-       "github.com/bep/godartsass"
+       "github.com/bep/godartsass/v2"
        "github.com/bep/golibsass/libsass/libsasserrors"
        "github.com/gohugoio/hugo/common/paths"
        "github.com/gohugoio/hugo/common/text"
@@ -145,6 +148,8 @@ func (e *fileError) causeString() string {
        // Avoid repeating the file info in the error message.
        case godartsass.SassError:
                return v.Message
+       case godartsassv1.SassError:
+               return v.Message
        case libsasserrors.Error:
                return v.Message
        default:
@@ -385,6 +390,13 @@ func extractPosition(e error) (pos text.Position) {
                pos.Filename = filename
                pos.Offset = start.Offset
                pos.ColumnNumber = start.Column
+       case godartsassv1.SassError:
+               span := v.Span
+               start := span.Start
+               filename, _ := paths.UrlToFilename(span.Url)
+               pos.Filename = filename
+               pos.Offset = start.Offset
+               pos.ColumnNumber = start.Column
        case libsasserrors.Error:
                pos.Filename = v.File
                pos.LineNumber = v.Line
index 4769852a096c72088fe7782b35d3774c49851cda..c28dd0b5308ca70a878aa08cd49eb95c31b0ba0a 100644 (file)
@@ -22,9 +22,13 @@ import (
        "sort"
        "strings"
        "sync"
+
+       godartsassv1 "github.com/bep/godartsass"
+       "github.com/mitchellh/mapstructure"
+
        "time"
 
-       "github.com/bep/godartsass"
+       "github.com/bep/godartsass/v2"
        "github.com/gohugoio/hugo/common/hexec"
        "github.com/gohugoio/hugo/hugofs/files"
 
@@ -238,7 +242,10 @@ func GetDependencyListNonGo() []string {
        }
 
        if dartSass := dartSassVersion(); dartSass.ProtocolVersion != "" {
-               const dartSassPath = "github.com/sass/dart-sass-embedded"
+               var dartSassPath = "github.com/sass/dart-sass-embedded"
+               if IsDartSassV2() {
+                       dartSassPath = "github.com/sass/dart-sass"
+               }
                deps = append(deps,
                        formatDep(dartSassPath+"/protocol", dartSass.ProtocolVersion),
                        formatDep(dartSassPath+"/compiler", dartSass.CompilerVersion),
@@ -283,11 +290,46 @@ type Dependency struct {
 }
 
 func dartSassVersion() godartsass.DartSassVersion {
-       // This is also duplicated in the dartsass package.
-       const dartSassEmbeddedBinaryName = "dart-sass-embedded"
-       if !hexec.InPath(dartSassEmbeddedBinaryName) {
+       if DartSassBinaryName == "" {
                return godartsass.DartSassVersion{}
        }
-       v, _ := godartsass.Version(dartSassEmbeddedBinaryName)
-       return v
+       if IsDartSassV2() {
+               v, _ := godartsass.Version(DartSassBinaryName)
+               return v
+       }
+
+       v, _ := godartsassv1.Version(DartSassBinaryName)
+       var vv godartsass.DartSassVersion
+       mapstructure.WeakDecode(v, &vv)
+       return vv
+}
+
+// DartSassBinaryName is the name of the Dart Sass binary to use.
+// TODO(beop) find a better place for this.
+var DartSassBinaryName string
+
+func init() {
+       DartSassBinaryName = os.Getenv("DART_SASS_BINARY")
+       if DartSassBinaryName == "" {
+               for _, name := range dartSassBinaryNamesV2 {
+                       if hexec.InPath(name) {
+                               DartSassBinaryName = name
+                               break
+                       }
+               }
+               if DartSassBinaryName == "" {
+                       if hexec.InPath(dartSassBinaryNameV1) {
+                               DartSassBinaryName = dartSassBinaryNameV1
+                       }
+               }
+       }
+}
+
+var (
+       dartSassBinaryNameV1  = "dart-sass-embedded"
+       dartSassBinaryNamesV2 = []string{"dart-sass", "sass"}
+)
+
+func IsDartSassV2() bool {
+       return !strings.Contains(DartSassBinaryName, "embedded")
 }
index f7d2beac8bf71a5c4cf1706f344efbb0f58db656..8bd12af4b773463b3a5c4adf2ca90a807fae3342 100644 (file)
@@ -35,9 +35,9 @@ const securityConfigKey = "security"
 var DefaultConfig = Config{
        Exec: Exec{
                Allow: NewWhitelist(
-                       "^dart-sass-embedded$",
-                       "^go$",  // for Go Modules
-                       "^npx$", // used by all Node tools (Babel, PostCSS).
+                       "^(dart-)?sass(-embedded)?$", // sass, dart-sass, dart-sass-embedded.
+                       "^go$",                       // for Go Modules
+                       "^npx$",                      // used by all Node tools (Babel, PostCSS).
                        "^postcss$",
                ),
                // These have been tested to work with Hugo's external programs
index edc1737e34a5bba9d4a900113ef01fcc78a89c2c..3bfd59ce33b9ec7bb5851524c538550781f58a43 100644 (file)
@@ -140,7 +140,7 @@ func TestToTOML(t *testing.T) {
        got := DefaultConfig.ToTOML()
 
        c.Assert(got, qt.Equals,
-               "[security]\n  enableInlineShortcodes = false\n\n  [security.exec]\n    allow = ['^dart-sass-embedded$', '^go$', '^npx$', '^postcss$']\n    osEnv = ['(?i)^((HTTPS?|NO)_PROXY|PATH(EXT)?|APPDATA|TE?MP|TERM|GO\\w+)$']\n\n  [security.funcs]\n    getenv = ['^HUGO_', '^CI$']\n\n  [security.http]\n    methods = ['(?i)GET|POST']\n    urls = ['.*']",
+               "[security]\n  enableInlineShortcodes = false\n\n  [security.exec]\n    allow = ['^(dart-)?sass(-embedded)?$', '^go$', '^npx$', '^postcss$']\n    osEnv = ['(?i)^((HTTPS?|NO)_PROXY|PATH(EXT)?|APPDATA|TE?MP|TERM|GO\\w+)$']\n\n  [security.funcs]\n    getenv = ['^HUGO_', '^CI$']\n\n  [security.http]\n    methods = ['(?i)GET|POST']\n    urls = ['.*']",
        )
 }
 
diff --git a/go.mod b/go.mod
index 0144c0959f47549cecb6c28333ce0824851c12c2..8531dcfe61b80a9ea9862e9bf5bdb948760eb7a4 100644 (file)
--- a/go.mod
+++ b/go.mod
@@ -10,7 +10,8 @@ require (
        github.com/bep/debounce v1.2.0
        github.com/bep/gitmap v1.1.2
        github.com/bep/goat v0.5.0
-       github.com/bep/godartsass v1.1.0
+       github.com/bep/godartsass v1.2.0
+       github.com/bep/godartsass/v2 v2.0.0
        github.com/bep/golibsass v1.1.1
        github.com/bep/gowebp v0.2.0
        github.com/bep/helpers v0.4.0
diff --git a/go.sum b/go.sum
index 2a672cc1915e1ceadb8b524bcb90a9c67e695d02..f97bb7a747dd27d3038b17630ca029115a0a4e1c 100644 (file)
--- a/go.sum
+++ b/go.sum
@@ -168,12 +168,10 @@ github.com/bep/gitmap v1.1.2 h1:zk04w1qc1COTZPPYWDQHvns3y1afOsdRfraFQ3qI840=
 github.com/bep/gitmap v1.1.2/go.mod h1:g9VRETxFUXNWzMiuxOwcudo6DfZkW9jOsOW0Ft4kYaY=
 github.com/bep/goat v0.5.0 h1:S8jLXHCVy/EHIoCY+btKkmcxcXFd34a0Q63/0D4TKeA=
 github.com/bep/goat v0.5.0/go.mod h1:Md9x7gRxiWKs85yHlVTvHQw9rg86Bm+Y4SuYE8CTH7c=
-github.com/bep/godartsass v0.16.0 h1:nTpenrZBQjVSjLkCw3AgnYmBB2czauTJa4BLLv448qg=
-github.com/bep/godartsass v0.16.0/go.mod h1:6LvK9RftsXMxGfsA0LDV12AGc4Jylnu6NgHL+Q5/pE8=
-github.com/bep/godartsass v1.0.0 h1:vL5TTtPkpEAZowsXydfJ3M1BatR9fH513FP3but9TEM=
-github.com/bep/godartsass v1.0.0/go.mod h1:6LvK9RftsXMxGfsA0LDV12AGc4Jylnu6NgHL+Q5/pE8=
-github.com/bep/godartsass v1.1.0 h1:MYNXVQMFoohxue9sCbHi+bWp4AeykvH40gQj1fd9q1c=
-github.com/bep/godartsass v1.1.0/go.mod h1:6LvK9RftsXMxGfsA0LDV12AGc4Jylnu6NgHL+Q5/pE8=
+github.com/bep/godartsass v1.2.0 h1:E2VvQrxAHAFwbjyOIExAMmogTItSKodoKuijNrGm5yU=
+github.com/bep/godartsass v1.2.0/go.mod h1:6LvK9RftsXMxGfsA0LDV12AGc4Jylnu6NgHL+Q5/pE8=
+github.com/bep/godartsass/v2 v2.0.0 h1:Ruht+BpBWkpmW+yAM2dkp7RSSeN0VLaTobyW0CiSP3Y=
+github.com/bep/godartsass/v2 v2.0.0/go.mod h1:AcP8QgC+OwOXEq6im0WgDRYK7scDsmZCEW62o1prQLo=
 github.com/bep/golibsass v1.1.1 h1:xkaet75ygImMYjM+FnHIT3xJn7H0xBA9UxSOJjk8Khw=
 github.com/bep/golibsass v1.1.1/go.mod h1:DL87K8Un/+pWUS75ggYv41bliGiolxzDKWJAq3eJ1MA=
 github.com/bep/gowebp v0.2.0 h1:ZVfK8i9PpZqKHEmthQSt3qCnnHycbLzBPEsVtk2ch2Q=
index 5b9267b591d9bf33f13f342446f32a6d2c0ddb06..60ef9a7e27de3373e2e4700e66fd8b218ca86fdc 100644 (file)
@@ -42,7 +42,6 @@ func TestSecurityPolicies(t *testing.T) {
                } else {
                        b.Build(BuildCfg{})
                }
-
        }
 
        httpTestVariant := func(c *qt.C, templ, expectErr string, withBuilder func(b *sitesBuilder)) {
@@ -145,7 +144,7 @@ allow="none"
                        `)
                        b.WithTemplatesAdded("index.html", `{{ $scss := "body { color: #333; }" | resources.FromString "foo.scss"  | resources.ToCSS (dict "transpiler" "dartsass") }}`)
                }
-               testVariant(c, cb, `(?s).*"dart-sass-embedded" is not whitelisted in policy "security\.exec\.allow".*`)
+               testVariant(c, cb, `(?s).*sass(-embedded)?" is not whitelisted in policy "security\.exec\.allow".*`)
        })
 
        c.Run("resources.GetRemote, OK", func(c *qt.C) {
index f358b93e5f254086c075b8ae587395ba4cc87f7c..9ae3178869d22ba5fafcd66f8a32142a00f53c8b 100644 (file)
@@ -20,7 +20,10 @@ import (
        "io"
        "strings"
 
+       godartsassv1 "github.com/bep/godartsass"
+       "github.com/bep/godartsass/v2"
        "github.com/gohugoio/hugo/common/herrors"
+       "github.com/gohugoio/hugo/common/hugo"
        "github.com/gohugoio/hugo/helpers"
        "github.com/gohugoio/hugo/hugofs"
        "github.com/gohugoio/hugo/hugolib/filesystems"
@@ -28,7 +31,6 @@ import (
        "github.com/gohugoio/hugo/resources/resource"
        "github.com/spf13/afero"
 
-       "github.com/bep/godartsass"
        "github.com/mitchellh/mapstructure"
 )
 
@@ -44,27 +46,57 @@ func New(fs *filesystems.SourceFilesystem, rs *resources.Spec) (*Client, error)
                return &Client{dartSassNotAvailable: true}, nil
        }
 
-       if err := rs.ExecHelper.Sec().CheckAllowedExec(dartSassEmbeddedBinaryName); err != nil {
+       if hugo.DartSassBinaryName == "" {
+               return nil, fmt.Errorf("no Dart Sass binary found in $PATH")
+       }
+
+       if err := rs.ExecHelper.Sec().CheckAllowedExec(hugo.DartSassBinaryName); err != nil {
                return nil, err
        }
 
-       transpiler, err := godartsass.Start(godartsass.Options{
-               LogEventHandler: func(event godartsass.LogEvent) {
-                       message := strings.ReplaceAll(event.Message, dartSassStdinPrefix, "")
-                       switch event.Type {
-                       case godartsass.LogEventTypeDebug:
-                               // Log as Info for now, we may adjust this if it gets too chatty.
-                               rs.Logger.Infof("Dart Sass: %s", message)
-                       default:
-                               // The rest are either deprecations or @warn statements.
-                               rs.Logger.Warnf("Dart Sass: %s", message)
-                       }
-               },
-       })
+       var (
+               transpiler   *godartsass.Transpiler
+               transpilerv1 *godartsassv1.Transpiler
+               err          error
+       )
+
+       if hugo.IsDartSassV2() {
+               transpiler, err = godartsass.Start(godartsass.Options{
+                       DartSassEmbeddedFilename: hugo.DartSassBinaryName,
+                       LogEventHandler: func(event godartsass.LogEvent) {
+                               message := strings.ReplaceAll(event.Message, dartSassStdinPrefix, "")
+                               switch event.Type {
+                               case godartsass.LogEventTypeDebug:
+                                       // Log as Info for now, we may adjust this if it gets too chatty.
+                                       rs.Logger.Infof("Dart Sass: %s", message)
+                               default:
+                                       // The rest are either deprecations or @warn statements.
+                                       rs.Logger.Warnf("Dart Sass: %s", message)
+                               }
+                       },
+               })
+
+       } else {
+               transpilerv1, err = godartsassv1.Start(godartsassv1.Options{
+                       DartSassEmbeddedFilename: hugo.DartSassBinaryName,
+                       LogEventHandler: func(event godartsassv1.LogEvent) {
+                               message := strings.ReplaceAll(event.Message, dartSassStdinPrefix, "")
+                               switch event.Type {
+                               case godartsassv1.LogEventTypeDebug:
+                                       // Log as Info for now, we may adjust this if it gets too chatty.
+                                       rs.Logger.Infof("Dart Sass: %s", message)
+                               default:
+                                       // The rest are either deprecations or @warn statements.
+                                       rs.Logger.Warnf("Dart Sass: %s", message)
+                               }
+                       },
+               })
+       }
+
        if err != nil {
                return nil, err
        }
-       return &Client{sfs: fs, workFs: rs.BaseFs.Work, rs: rs, transpiler: transpiler}, nil
+       return &Client{sfs: fs, workFs: rs.BaseFs.Work, rs: rs, transpiler: transpiler, transpilerV1: transpilerv1}, nil
 }
 
 type Client struct {
@@ -72,7 +104,10 @@ type Client struct {
        rs                   *resources.Spec
        sfs                  *filesystems.SourceFilesystem
        workFs               afero.Fs
-       transpiler           *godartsass.Transpiler
+
+       // One of these are non-nil.
+       transpiler   *godartsass.Transpiler
+       transpilerV1 *godartsassv1.Transpiler
 }
 
 func (c *Client) ToCSS(res resources.ResourceTransformer, args map[string]any) (resource.Resource, error) {
@@ -83,23 +118,44 @@ func (c *Client) ToCSS(res resources.ResourceTransformer, args map[string]any) (
 }
 
 func (c *Client) Close() error {
-       if c.transpiler == nil {
-               return nil
+       if c.transpilerV1 != nil {
+               return c.transpilerV1.Close()
+       }
+       if c.transpiler != nil {
+               return c.transpiler.Close()
        }
-       return c.transpiler.Close()
+       return nil
 }
 
 func (c *Client) toCSS(args godartsass.Args, src io.Reader) (godartsass.Result, error) {
-       var res godartsass.Result
-
        in := helpers.ReaderToString(src)
 
        args.Source = in
 
-       res, err := c.transpiler.Execute(args)
+       var (
+               err error
+               res godartsass.Result
+       )
+
+       if c.transpilerV1 != nil {
+               var resv1 godartsassv1.Result
+               var argsv1 godartsassv1.Args
+               mapstructure.Decode(args, &argsv1)
+               if args.ImportResolver != nil {
+                       argsv1.ImportResolver = importResolverV1{args.ImportResolver}
+               }
+               resv1, err = c.transpilerV1.Execute(argsv1)
+               if err == nil {
+                       mapstructure.Decode(resv1, &res)
+               }
+       } else {
+               res, err = c.transpiler.Execute(args)
+
+       }
+
        if err != nil {
                if err.Error() == "unexpected EOF" {
-                       return res, fmt.Errorf("got unexpected EOF when executing %q. The user running hugo must have read and execute permissions on this program. With execute permissions only, this error is thrown.", dartSassEmbeddedBinaryName)
+                       return res, fmt.Errorf("got unexpected EOF when executing %q. The user running hugo must have read and execute permissions on this program. With execute permissions only, this error is thrown.", hugo.DartSassBinaryName)
                }
                return res, herrors.NewFileErrorFromFileInErr(err, hugofs.Os, herrors.OffsetMatcher)
        }
index 95dfd5944920a6e4ca5b447f1d2d2427f024ce6c..32855e1c553d0202252eae7970ff6a6c90aa185c 100644 (file)
@@ -20,7 +20,7 @@ import (
        "path/filepath"
        "strings"
 
-       "github.com/gohugoio/hugo/common/hexec"
+       "github.com/gohugoio/hugo/common/hugo"
        "github.com/gohugoio/hugo/common/paths"
        "github.com/gohugoio/hugo/htesting"
        "github.com/gohugoio/hugo/media"
@@ -34,11 +34,8 @@ import (
 
        "github.com/gohugoio/hugo/hugofs"
 
-       "github.com/bep/godartsass"
-)
-
-const (
-       dartSassEmbeddedBinaryName = "dart-sass-embedded"
+       godartsassv1 "github.com/bep/godartsass"
+       "github.com/bep/godartsass/v2"
 )
 
 // Supports returns whether dart-sass-embedded is found in $PATH.
@@ -46,7 +43,7 @@ func Supports() bool {
        if htesting.SupportsAll() {
                return true
        }
-       return hexec.InPath(dartSassEmbeddedBinaryName)
+       return hugo.DartSassBinaryName != ""
 }
 
 type transform struct {
@@ -201,3 +198,12 @@ func (t importResolver) Load(url string) (godartsass.Import, error) {
        return godartsass.Import{Content: string(b), SourceSyntax: sourceSyntax}, err
 
 }
+
+type importResolverV1 struct {
+       godartsass.ImportResolver
+}
+
+func (t importResolverV1) Load(url string) (godartsassv1.Import, error) {
+       res, err := t.ImportResolver.Load(url)
+       return godartsassv1.Import{Content: res.Content, SourceSyntax: godartsassv1.SourceSyntax(res.SourceSyntax)}, err
+}