mirror of
https://github.com/gohugoio/hugo.git
synced 2025-08-21 21:35:28 +02:00
@@ -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()
|
||||
}
|
||||
return c.transpiler.Close()
|
||||
if c.transpiler != nil {
|
||||
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)
|
||||
}
|
||||
|
@@ -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
|
||||
}
|
||||
|
Reference in New Issue
Block a user