mirror of
https://github.com/gohugoio/hugo.git
synced 2024-11-21 20:46:30 -05:00
parent
03b93bb988
commit
1a8af7d4f0
4 changed files with 143 additions and 2 deletions
|
@ -87,6 +87,69 @@ T1: {{ $r.Content }}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestSCSSWithRegularCSSImport(t *testing.T) {
|
||||||
|
if !scss.Supports() {
|
||||||
|
t.Skip("Skip SCSS")
|
||||||
|
}
|
||||||
|
c := qt.New(t)
|
||||||
|
workDir, clean, err := htesting.CreateTempDir(hugofs.Os, "hugo-scss-include")
|
||||||
|
c.Assert(err, qt.IsNil)
|
||||||
|
defer clean()
|
||||||
|
|
||||||
|
v := viper.New()
|
||||||
|
v.Set("workingDir", workDir)
|
||||||
|
b := newTestSitesBuilder(t).WithLogger(loggers.NewErrorLogger())
|
||||||
|
// Need to use OS fs for this.
|
||||||
|
b.Fs = hugofs.NewDefault(v)
|
||||||
|
b.WithWorkingDir(workDir)
|
||||||
|
b.WithViper(v)
|
||||||
|
|
||||||
|
scssDir := filepath.Join(workDir, "assets", "scss")
|
||||||
|
c.Assert(os.MkdirAll(filepath.Join(workDir, "content", "sect"), 0777), qt.IsNil)
|
||||||
|
c.Assert(os.MkdirAll(filepath.Join(workDir, "data"), 0777), qt.IsNil)
|
||||||
|
c.Assert(os.MkdirAll(filepath.Join(workDir, "i18n"), 0777), qt.IsNil)
|
||||||
|
c.Assert(os.MkdirAll(filepath.Join(workDir, "layouts", "shortcodes"), 0777), qt.IsNil)
|
||||||
|
c.Assert(os.MkdirAll(filepath.Join(workDir, "layouts", "_default"), 0777), qt.IsNil)
|
||||||
|
c.Assert(os.MkdirAll(filepath.Join(scssDir), 0777), qt.IsNil)
|
||||||
|
|
||||||
|
b.WithSourceFile(filepath.Join(scssDir, "_moo.scss"), `
|
||||||
|
$moolor: #fff;
|
||||||
|
|
||||||
|
moo {
|
||||||
|
color: $moolor;
|
||||||
|
}
|
||||||
|
`)
|
||||||
|
|
||||||
|
b.WithSourceFile(filepath.Join(scssDir, "main.scss"), `
|
||||||
|
@import "moo";
|
||||||
|
@import "regular.css";
|
||||||
|
@import "moo";
|
||||||
|
@import "another.css";
|
||||||
|
|
||||||
|
/* foo */
|
||||||
|
`)
|
||||||
|
|
||||||
|
b.WithTemplatesAdded("index.html", `
|
||||||
|
{{ $r := resources.Get "scss/main.scss" | toCSS }}
|
||||||
|
T1: {{ $r.Content | safeHTML }}
|
||||||
|
`)
|
||||||
|
b.Build(BuildCfg{})
|
||||||
|
|
||||||
|
b.AssertFileContent(filepath.Join(workDir, "public/index.html"), `
|
||||||
|
T1: moo {
|
||||||
|
color: #fff; }
|
||||||
|
|
||||||
|
@import "regular.css";
|
||||||
|
moo {
|
||||||
|
color: #fff; }
|
||||||
|
|
||||||
|
@import "another.css";
|
||||||
|
/* foo */
|
||||||
|
|
||||||
|
`)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
func TestSCSSWithThemeOverrides(t *testing.T) {
|
func TestSCSSWithThemeOverrides(t *testing.T) {
|
||||||
if !scss.Supports() {
|
if !scss.Supports() {
|
||||||
t.Skip("Skip SCSS")
|
t.Skip("Skip SCSS")
|
||||||
|
|
|
@ -14,6 +14,8 @@
|
||||||
package scss
|
package scss
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"regexp"
|
||||||
|
|
||||||
"github.com/gohugoio/hugo/helpers"
|
"github.com/gohugoio/hugo/helpers"
|
||||||
"github.com/gohugoio/hugo/hugolib/filesystems"
|
"github.com/gohugoio/hugo/hugolib/filesystems"
|
||||||
"github.com/gohugoio/hugo/resources"
|
"github.com/gohugoio/hugo/resources"
|
||||||
|
@ -72,3 +74,17 @@ func DecodeOptions(m map[string]interface{}) (opts Options, err error) {
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
regularCSSImportTo = regexp.MustCompile(`.*(@import "(.*.css)";).*`)
|
||||||
|
regularCSSImportFrom = regexp.MustCompile(`.*(\/\* HUGO_IMPORT_START (.*) HUGO_IMPORT_END \*\/).*`)
|
||||||
|
)
|
||||||
|
|
||||||
|
func replaceRegularImportsIn(s string) (string, bool) {
|
||||||
|
replaced := regularCSSImportTo.ReplaceAllString(s, "/* HUGO_IMPORT_START $2 HUGO_IMPORT_END */")
|
||||||
|
return replaced, s != replaced
|
||||||
|
}
|
||||||
|
|
||||||
|
func replaceRegularImportsOut(s string) string {
|
||||||
|
return regularCSSImportFrom.ReplaceAllString(s, "@import \"$2\";")
|
||||||
|
}
|
||||||
|
|
49
resources/resource_transformers/tocss/scss/client_test.go
Normal file
49
resources/resource_transformers/tocss/scss/client_test.go
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
// Copyright 2020 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 scss
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
qt "github.com/frankban/quicktest"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestReplaceRegularCSSImports(t *testing.T) {
|
||||||
|
c := qt.New(t)
|
||||||
|
|
||||||
|
scssWithImport := `
|
||||||
|
|
||||||
|
@import "moo";
|
||||||
|
@import "regular.css";
|
||||||
|
@import "moo";
|
||||||
|
@import "another.css";
|
||||||
|
|
||||||
|
/* foo */`
|
||||||
|
|
||||||
|
scssWithoutImport := `
|
||||||
|
@import "moo";
|
||||||
|
/* foo */`
|
||||||
|
|
||||||
|
res, replaced := replaceRegularImportsIn(scssWithImport)
|
||||||
|
c.Assert(replaced, qt.Equals, true)
|
||||||
|
c.Assert(res, qt.Equals, "\n\t\n@import \"moo\";\n/* HUGO_IMPORT_START regular.css HUGO_IMPORT_END */\n@import \"moo\";\n/* HUGO_IMPORT_START another.css HUGO_IMPORT_END */\n\n/* foo */")
|
||||||
|
|
||||||
|
res2, replaced2 := replaceRegularImportsIn(scssWithoutImport)
|
||||||
|
c.Assert(replaced2, qt.Equals, false)
|
||||||
|
c.Assert(res2, qt.Equals, scssWithoutImport)
|
||||||
|
|
||||||
|
reverted := replaceRegularImportsOut(res)
|
||||||
|
c.Assert(reverted, qt.Equals, scssWithImport)
|
||||||
|
|
||||||
|
}
|
|
@ -65,7 +65,6 @@ func (t *toCSSTransformation) Transform(ctx *resources.ResourceTransformationCtx
|
||||||
// We add the entry directories for both project and themes to the include paths list, but
|
// We add the entry directories for both project and themes to the include paths list, but
|
||||||
// that only work for overrides on the top level.
|
// that only work for overrides on the top level.
|
||||||
options.to.ImportResolver = func(url string, prev string) (newUrl string, body string, resolved bool) {
|
options.to.ImportResolver = func(url string, prev string) (newUrl string, body string, resolved bool) {
|
||||||
|
|
||||||
// We get URL paths from LibSASS, but we need file paths.
|
// We get URL paths from LibSASS, but we need file paths.
|
||||||
url = filepath.FromSlash(url)
|
url = filepath.FromSlash(url)
|
||||||
prev = filepath.FromSlash(prev)
|
prev = filepath.FromSlash(prev)
|
||||||
|
@ -170,12 +169,26 @@ func (c *Client) toCSS(options libsass.Options, dst io.Writer, src io.Reader) (l
|
||||||
}
|
}
|
||||||
|
|
||||||
in := helpers.ReaderToString(src)
|
in := helpers.ReaderToString(src)
|
||||||
|
|
||||||
|
// See https://github.com/gohugoio/hugo/issues/7059
|
||||||
|
// We need to preserver the regular CSS imports. This is by far
|
||||||
|
// a perfect solution, and only works for the main entry file, but
|
||||||
|
// that should cover many use cases, e.g. using SCSS as a preprocessor
|
||||||
|
// for Tailwind.
|
||||||
|
var importsReplaced bool
|
||||||
|
in, importsReplaced = replaceRegularImportsIn(in)
|
||||||
|
|
||||||
res, err = transpiler.Execute(in)
|
res, err = transpiler.Execute(in)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return res, errors.Wrap(err, "SCSS processing failed")
|
return res, errors.Wrap(err, "SCSS processing failed")
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = io.WriteString(dst, res.CSS)
|
out := res.CSS
|
||||||
|
if importsReplaced {
|
||||||
|
out = replaceRegularImportsOut(out)
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = io.WriteString(dst, out)
|
||||||
|
|
||||||
return res, err
|
return res, err
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue