diff options
Diffstat (limited to 'resources/resource_transformers/postcss/postcss.go')
-rw-r--r-- | resources/resource_transformers/postcss/postcss.go | 42 |
1 files changed, 32 insertions, 10 deletions
diff --git a/resources/resource_transformers/postcss/postcss.go b/resources/resource_transformers/postcss/postcss.go index a5c86df6f..325dc1ec2 100644 --- a/resources/resource_transformers/postcss/postcss.go +++ b/resources/resource_transformers/postcss/postcss.go @@ -28,6 +28,7 @@ import ( "github.com/gohugoio/hugo/common/collections" "github.com/gohugoio/hugo/common/hexec" + "github.com/gohugoio/hugo/common/text" "github.com/gohugoio/hugo/hugofs" "github.com/gohugoio/hugo/common/hugo" @@ -49,9 +50,10 @@ import ( const importIdentifier = "@import" -var cssSyntaxErrorRe = regexp.MustCompile(`> (\d+) \|`) - -var shouldImportRe = regexp.MustCompile(`^@import ["'].*["'];?\s*(/\*.*\*/)?$`) +var ( + cssSyntaxErrorRe = regexp.MustCompile(`> (\d+) \|`) + shouldImportRe = regexp.MustCompile(`^@import ["'].*["'];?\s*(/\*.*\*/)?$`) +) // New creates a new Client with the given specification. func New(rs *resources.Spec) *Client { @@ -100,6 +102,12 @@ type Options struct { // so you can have @import anywhere in the file. InlineImports bool + // When InlineImports is enabled, we fail the build if an import cannot be resolved. + // You can enable this to allow the build to continue and leave the import statement in place. + // Note that the inline importer does not process url location or imports with media queries, + // so those will be left as-is even without enabling this option. + SkipInlineImportsNotFound bool + // Options for when not using a config file Use string // List of postcss plugins to use Parser string // Custom postcss parser @@ -204,6 +212,7 @@ func (t *postcssTransformation) Transform(ctx *resources.ResourceTransformationC imp := newImportResolver( ctx.From, ctx.InPath, + t.options, t.rs.Assets.Fs, t.rs.Logger, ) @@ -239,6 +248,7 @@ type fileOffset struct { type importResolver struct { r io.Reader inPath string + opts Options contentSeen map[string]bool linemap map[int]fileOffset @@ -246,12 +256,13 @@ type importResolver struct { logger loggers.Logger } -func newImportResolver(r io.Reader, inPath string, fs afero.Fs, logger loggers.Logger) *importResolver { +func newImportResolver(r io.Reader, inPath string, opts Options, fs afero.Fs, logger loggers.Logger) *importResolver { return &importResolver{ r: r, inPath: inPath, fs: fs, logger: logger, linemap: make(map[int]fileOffset), contentSeen: make(map[string]bool), + opts: opts, } } @@ -282,21 +293,32 @@ func (imp *importResolver) importRecursive( i := 0 for offset, line := range lines { i++ - line = strings.TrimSpace(line) + lineTrimmed := strings.TrimSpace(line) + column := strings.Index(line, lineTrimmed) + line = lineTrimmed if !imp.shouldImport(line) { trackLine(i, offset, line) } else { - i-- path := strings.Trim(strings.TrimPrefix(line, importIdentifier), " \"';") filename := filepath.Join(basePath, path) importContent, hash := imp.contentHash(filename) + if importContent == nil { - trackLine(i, offset, "ERROR") - imp.logger.Warnf("postcss: Failed to resolve CSS @import in %q for path %q", inPath, filename) - continue + if imp.opts.SkipInlineImportsNotFound { + trackLine(i, offset, line) + continue + } + pos := text.Position{ + Filename: inPath, + LineNumber: offset + 1, + ColumnNumber: column + 1, + } + return 0, "", herrors.NewFileErrorFromFileInPos(fmt.Errorf("failed to resolve CSS @import %q", filename), pos, imp.fs, nil) } + i-- + if imp.contentSeen[hash] { i++ // Just replace the line with an empty string. @@ -399,7 +421,7 @@ func (imp *importResolver) toFileError(output string) error { } defer f.Close() - ferr := herrors.NewFileError(realFilename, inErr) + ferr := herrors.NewFileError(inErr, realFilename) pos := ferr.Position() pos.LineNumber = file.Offset + 1 return ferr.UpdatePosition(pos).UpdateContent(f, nil) |