postcss: Make the resource cache key more stable

By using the input map as the basis, which means the hash will not change if we add/rename/remove options.

This happened in Hugo 0.99, as we added a new options. This is unortunate.

Unfortunately this means that the cache keys for PostCSS will change one more time in 0.100, but will be stable going forward.

Note that we have implemented this pattern in all the other resource transformers.

Updates #9787
This commit is contained in:
Bjørn Erik Pedersen 2022-05-27 17:01:35 +02:00
parent 653ab2cc1f
commit 46a2ea6d0d
3 changed files with 25 additions and 23 deletions

View file

@ -60,7 +60,7 @@ func New(rs *resources.Spec) *Client {
return &Client{rs: rs} return &Client{rs: rs}
} }
func DecodeOptions(m map[string]any) (opts Options, err error) { func decodeOptions(m map[string]any) (opts Options, err error) {
if m == nil { if m == nil {
return return
} }
@ -82,8 +82,8 @@ type Client struct {
} }
// Process transforms the given Resource with the PostCSS processor. // Process transforms the given Resource with the PostCSS processor.
func (c *Client) Process(res resources.ResourceTransformer, options Options) (resource.Resource, error) { func (c *Client) Process(res resources.ResourceTransformer, options map[string]any) (resource.Resource, error) {
return res.Transform(&postcssTransformation{rs: c.rs, options: options}) return res.Transform(&postcssTransformation{rs: c.rs, optionsm: options})
} }
// Some of the options from https://github.com/postcss/postcss-cli // Some of the options from https://github.com/postcss/postcss-cli
@ -137,12 +137,12 @@ func (opts Options) toArgs() []string {
} }
type postcssTransformation struct { type postcssTransformation struct {
options Options optionsm map[string]any
rs *resources.Spec rs *resources.Spec
} }
func (t *postcssTransformation) Key() internal.ResourceTransformationKey { func (t *postcssTransformation) Key() internal.ResourceTransformationKey {
return internal.NewResourceTransformationKey("postcss", t.options) return internal.NewResourceTransformationKey("postcss", t.optionsm)
} }
// Transform shells out to postcss-cli to do the heavy lifting. // Transform shells out to postcss-cli to do the heavy lifting.
@ -157,8 +157,17 @@ func (t *postcssTransformation) Transform(ctx *resources.ResourceTransformationC
var configFile string var configFile string
logger := t.rs.Logger logger := t.rs.Logger
if t.options.Config != "" { var options Options
configFile = t.options.Config if t.optionsm != nil {
var err error
options, err = decodeOptions(t.optionsm)
if err != nil {
return err
}
}
if options.Config != "" {
configFile = options.Config
} else { } else {
configFile = "postcss.config.js" configFile = "postcss.config.js"
} }
@ -168,9 +177,9 @@ func (t *postcssTransformation) Transform(ctx *resources.ResourceTransformationC
// We need an absolute filename to the config file. // We need an absolute filename to the config file.
if !filepath.IsAbs(configFile) { if !filepath.IsAbs(configFile) {
configFile = t.rs.BaseFs.ResolveJSConfigFile(configFile) configFile = t.rs.BaseFs.ResolveJSConfigFile(configFile)
if configFile == "" && t.options.Config != "" { if configFile == "" && options.Config != "" {
// Only fail if the user specified config file is not found. // Only fail if the user specified config file is not found.
return fmt.Errorf("postcss config %q not found:", t.options.Config) return fmt.Errorf("postcss config %q not found:", options.Config)
} }
} }
@ -181,7 +190,7 @@ func (t *postcssTransformation) Transform(ctx *resources.ResourceTransformationC
cmdArgs = []any{"--config", configFile} cmdArgs = []any{"--config", configFile}
} }
if optArgs := t.options.toArgs(); len(optArgs) > 0 { if optArgs := options.toArgs(); len(optArgs) > 0 {
cmdArgs = append(cmdArgs, collections.StringSliceToInterfaceSlice(optArgs)...) cmdArgs = append(cmdArgs, collections.StringSliceToInterfaceSlice(optArgs)...)
} }
@ -212,11 +221,11 @@ func (t *postcssTransformation) Transform(ctx *resources.ResourceTransformationC
imp := newImportResolver( imp := newImportResolver(
ctx.From, ctx.From,
ctx.InPath, ctx.InPath,
t.options, options,
t.rs.Assets.Fs, t.rs.Logger, t.rs.Assets.Fs, t.rs.Logger,
) )
if t.options.InlineImports { if options.InlineImports {
var err error var err error
src, err = imp.resolve() src, err = imp.resolve()
if err != nil { if err != nil {

View file

@ -31,14 +31,14 @@ import (
// Issue 6166 // Issue 6166
func TestDecodeOptions(t *testing.T) { func TestDecodeOptions(t *testing.T) {
c := qt.New(t) c := qt.New(t)
opts1, err := DecodeOptions(map[string]any{ opts1, err := decodeOptions(map[string]any{
"no-map": true, "no-map": true,
}) })
c.Assert(err, qt.IsNil) c.Assert(err, qt.IsNil)
c.Assert(opts1.NoMap, qt.Equals, true) c.Assert(opts1.NoMap, qt.Equals, true)
opts2, err := DecodeOptions(map[string]any{ opts2, err := decodeOptions(map[string]any{
"noMap": true, "noMap": true,
}) })

View file

@ -405,15 +405,8 @@ func (ns *Namespace) PostCSS(args ...any) (resource.Resource, error) {
if err != nil { if err != nil {
return nil, err return nil, err
} }
var options postcss.Options
if m != nil {
options, err = postcss.DecodeOptions(m)
if err != nil {
return nil, err
}
}
return ns.postcssClient.Process(r, options) return ns.postcssClient.Process(r, m)
} }
func (ns *Namespace) PostProcess(r resource.Resource) (postpub.PostPublishedResource, error) { func (ns *Namespace) PostProcess(r resource.Resource) (postpub.PostPublishedResource, error) {