Skip to content

Commit

Permalink
Upgrade to v2 of the Dart Sass Embedded Protocol
Browse files Browse the repository at this point in the history
  • Loading branch information
bep committed Jun 9, 2023
1 parent 21b3145 commit 53b6a4b
Show file tree
Hide file tree
Showing 10 changed files with 75 additions and 54 deletions.
40 changes: 20 additions & 20 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,18 @@ 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]
os: [ubuntu-latest, macos-latest, windows-latest]
go-version: [1.20.x] # 1.19.x,
os: [ubuntu-latest] # , macos-latest, windows-latest
runs-on: ${{ matrix.os }}
steps:
- name: Checkout code
Expand Down Expand Up @@ -66,26 +66,26 @@ 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 "DART_SASS_BINARY=$GITHUB_WORKSPACE/dart-sass/sass" >> $GITHUB_ENV
- 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 "DART_SASS_BINARY=$GITHUB_WORKSPACE/dart-sass/sass" >> $GITHUB_ENV
- 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 "DART_SASS_BINARY=$env:GITHUB_WORKSPACE/dart-sass/sass.bat" | Out-File -FilePath $Env:GITHUB_ENV -Encoding utf-8 -Append
- if: matrix.os != 'windows-latest'
name: Check
run: |
Expand Down
2 changes: 1 addition & 1 deletion common/herrors/file_error.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import (
"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"
Expand Down
38 changes: 33 additions & 5 deletions common/hugo/hugo.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import (
"sync"
"time"

"github.com/bep/godartsass"
"github.com/bep/godartsass/v2"
"github.com/gohugoio/hugo/common/hexec"
"github.com/gohugoio/hugo/hugofs/files"

Expand Down Expand Up @@ -283,11 +283,39 @@ 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)
v, _ := godartsass.Version(DartSassBinaryName)
return v
}

// 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")
}
6 changes: 3 additions & 3 deletions config/security/securityConfig.go
Original file line number Diff line number Diff line change
Expand Up @@ -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. Note that this can be provided as a full path in DART_SASS_BINARY.
"^go$", // for Go Modules
"^npx$", // used by all Node tools (Babel, PostCSS).
"^postcss$",
),
// These have been tested to work with Hugo's external programs
Expand Down
2 changes: 1 addition & 1 deletion config/security/securityConfig_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 = ['.*']",
)
}

Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ 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/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
Expand Down
13 changes: 2 additions & 11 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -168,12 +168,8 @@ 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/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=
Expand Down Expand Up @@ -202,7 +198,6 @@ github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5P
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
github.com/clbanning/mxj/v2 v2.5.7 h1:7q5lvUpaPF/WOkqgIDiwjBJaznaLCCBd78pi8ZyAnE0=
github.com/clbanning/mxj/v2 v2.5.7/go.mod h1:hNiWqW14h+kc+MdF9C6/YoRfjEJoR3ou6tn/Qo+ve2s=
github.com/cli/safeexec v1.0.0/go.mod h1:Z/D4tTN8Vs5gXYHDCbaM1S/anmEDnJb1iW0+EJ5zx3Q=
github.com/cli/safeexec v1.0.1 h1:e/C79PbXF4yYTN/wauC4tviMxEV13BwljGj0N9j+N00=
github.com/cli/safeexec v1.0.1/go.mod h1:Z/D4tTN8Vs5gXYHDCbaM1S/anmEDnJb1iW0+EJ5zx3Q=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
Expand Down Expand Up @@ -252,7 +247,6 @@ github.com/fortytw2/leaktest v1.3.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHqu
github.com/frankban/quicktest v1.4.1/go.mod h1:36zfPVQyHxymz4cH7wlDmVwDrJuljRB60qkgn7rorfQ=
github.com/frankban/quicktest v1.7.2/go.mod h1:jaStnuzAqU1AJdCO0l53JDCJrVDKcS03DbaAcR7Ks/o=
github.com/frankban/quicktest v1.13.0/go.mod h1:qLE0fzW0VuyUAJgPU19zByoIr0HtCHN/r/VLSOOIySU=
github.com/frankban/quicktest v1.14.2/go.mod h1:mgiwOwqx65TmIk1wJ6Q7wvnVMocbUorkibMOrVTHZps=
github.com/frankban/quicktest v1.14.4 h1:g2rn0vABPOOXmZUj+vbmUp0lPoXEMuhTpIluN0XL9UY=
github.com/frankban/quicktest v1.14.4/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0=
github.com/fsnotify/fsnotify v1.5.1/go.mod h1:T3375wBYaZdLLcVNkcVbzGHY7f1l/uK5T5Ai1i3InKU=
Expand Down Expand Up @@ -347,7 +341,6 @@ github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE=
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/go-replayers/grpcreplay v1.1.0 h1:S5+I3zYyZ+GQz68OfbURDdt/+cSMqCK1wrvNx7WBzTE=
Expand Down Expand Up @@ -435,7 +428,6 @@ github.com/klauspost/compress v1.13.5/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47e
github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk=
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
Expand Down Expand Up @@ -502,7 +494,6 @@ github.com/prashantv/gostub v1.1.0 h1:BTyx3RfQjRHnUWaGF9oQos79AlQ5k8WNktv7VGvVH4
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
github.com/rogpeppe/go-internal v1.10.1-0.20230508101108-a4f6fabd84c5 h1:Tb1D114RozKzV2dDfarvSZn8lVYvjcGSCDaMQ+b4I+E=
github.com/rogpeppe/go-internal v1.10.1-0.20230508101108-a4f6fabd84c5/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA=
Expand Down
3 changes: 1 addition & 2 deletions hugolib/securitypolicies_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)) {
Expand Down Expand Up @@ -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" is not whitelisted in policy "security\.exec\.allow".*`)
})

c.Run("resources.GetRemote, OK", func(c *qt.C) {
Expand Down
13 changes: 10 additions & 3 deletions resources/resource_transformers/tocss/dartsass/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,16 @@ import (
"strings"

"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"
"github.com/gohugoio/hugo/resources"
"github.com/gohugoio/hugo/resources/resource"
"github.com/spf13/afero"

"github.com/bep/godartsass"
"github.com/bep/godartsass/v2"

"github.com/mitchellh/mapstructure"
)

Expand All @@ -44,11 +46,16 @@ 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{
DartSassEmbeddedFilename: hugo.DartSassBinaryName,
LogEventHandler: func(event godartsass.LogEvent) {
message := strings.ReplaceAll(event.Message, dartSassStdinPrefix, "")
switch event.Type {
Expand Down Expand Up @@ -99,7 +106,7 @@ func (c *Client) toCSS(args godartsass.Args, src io.Reader) (godartsass.Result,
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)
}
Expand Down
10 changes: 3 additions & 7 deletions resources/resource_transformers/tocss/dartsass/transform.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand All @@ -34,19 +34,15 @@ import (

"github.com/gohugoio/hugo/hugofs"

"github.com/bep/godartsass"
)

const (
dartSassEmbeddedBinaryName = "dart-sass-embedded"
"github.com/bep/godartsass/v2"
)

// Supports returns whether dart-sass-embedded is found in $PATH.
func Supports() bool {
if htesting.SupportsAll() {
return true
}
return hexec.InPath(dartSassEmbeddedBinaryName)
return hugo.DartSassBinaryName != ""
}

type transform struct {
Expand Down

0 comments on commit 53b6a4b

Please sign in to comment.