Skip to content

Commit

Permalink
Fix partial rebuilds for SCSS fetched with GetMatch and similar
Browse files Browse the repository at this point in the history
Fixes #12395
  • Loading branch information
bep committed Apr 20, 2024
1 parent faf9fed commit 46a600d
Show file tree
Hide file tree
Showing 5 changed files with 119 additions and 34 deletions.
20 changes: 17 additions & 3 deletions cache/dynacache/dynacache.go
Original file line number Diff line number Diff line change
Expand Up @@ -140,16 +140,25 @@ func (c *Cache) DrainEvictedIdentities() []identity.Identity {
}

// ClearMatching clears all partition for which the predicate returns true.
func (c *Cache) ClearMatching(predicate func(k, v any) bool) {
func (c *Cache) ClearMatching(predicatePartition func(k string, p PartitionManager) bool, predicateValue func(k, v any) bool) {
if predicatePartition == nil {
predicatePartition = func(k string, p PartitionManager) bool { return true }
}
if predicateValue == nil {
panic("nil predicateValue")
}
g := rungroup.Run[PartitionManager](context.Background(), rungroup.Config[PartitionManager]{
NumWorkers: len(c.partitions),
Handle: func(ctx context.Context, partition PartitionManager) error {
partition.clearMatching(predicate)
partition.clearMatching(predicateValue)
return nil
},
})

for _, p := range c.partitions {
for k, p := range c.partitions {
if !predicatePartition(k, p) {
continue
}
g.Enqueue(p)
}

Expand Down Expand Up @@ -536,6 +545,10 @@ func (p *Partition[K, V]) Clear() {
})
}

func (p *Partition[K, V]) ZeroV() any {
return p.zero
}

func (p *Partition[K, V]) Get(ctx context.Context, key K) (V, bool) {
return p.c.Get(key)
}
Expand All @@ -547,6 +560,7 @@ type PartitionManager interface {
clearOnRebuild(changeset ...identity.Identity)
clearMatching(predicate func(k, v any) bool)
clearStale()
ZeroV() any
}

const (
Expand Down
50 changes: 29 additions & 21 deletions commands/commandeer.go
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,7 @@ type rootCommand struct {
verbose bool
debug bool
quiet bool
devMode bool // Hidden flag.

renderToMemory bool

Expand Down Expand Up @@ -423,29 +424,33 @@ func (r *rootCommand) PreRun(cd, runner *simplecobra.Commandeer) error {
func (r *rootCommand) createLogger(running bool) (loggers.Logger, error) {
level := logg.LevelWarn

if r.logLevel != "" {
switch strings.ToLower(r.logLevel) {
case "debug":
level = logg.LevelDebug
case "info":
level = logg.LevelInfo
case "warn", "warning":
level = logg.LevelWarn
case "error":
level = logg.LevelError
default:
return nil, fmt.Errorf("invalid log level: %q, must be one of debug, warn, info or error", r.logLevel)
}
if r.devMode {
level = logg.LevelTrace
} else {
if r.verbose {
hugo.Deprecate("--verbose", "use --logLevel info", "v0.114.0")
hugo.Deprecate("--verbose", "use --logLevel info", "v0.114.0")
level = logg.LevelInfo
}
if r.logLevel != "" {
switch strings.ToLower(r.logLevel) {
case "debug":
level = logg.LevelDebug
case "info":
level = logg.LevelInfo
case "warn", "warning":
level = logg.LevelWarn
case "error":
level = logg.LevelError
default:
return nil, fmt.Errorf("invalid log level: %q, must be one of debug, warn, info or error", r.logLevel)
}
} else {
if r.verbose {
hugo.Deprecate("--verbose", "use --logLevel info", "v0.114.0")
hugo.Deprecate("--verbose", "use --logLevel info", "v0.114.0")
level = logg.LevelInfo
}

if r.debug {
hugo.Deprecate("--debug", "use --logLevel debug", "v0.114.0")
level = logg.LevelDebug
if r.debug {
hugo.Deprecate("--debug", "use --logLevel debug", "v0.114.0")
level = logg.LevelDebug
}
}
}

Expand Down Expand Up @@ -505,10 +510,13 @@ Complete documentation is available at https://gohugo.io/.`

cmd.PersistentFlags().BoolVarP(&r.verbose, "verbose", "v", false, "verbose output")
cmd.PersistentFlags().BoolVarP(&r.debug, "debug", "", false, "debug output")
cmd.PersistentFlags().BoolVarP(&r.devMode, "devMode", "", false, "only used for internal testing, flag hidden.")
cmd.PersistentFlags().StringVar(&r.logLevel, "logLevel", "", "log level (debug|info|warn|error)")
_ = cmd.RegisterFlagCompletionFunc("logLevel", cobra.FixedCompletions([]string{"debug", "info", "warn", "error"}, cobra.ShellCompDirectiveNoFileComp))
cmd.Flags().BoolVarP(&r.buildWatch, "watch", "w", false, "watch filesystem for changes and recreate as needed")

cmd.PersistentFlags().MarkHidden("devMode")

// Configure local flags
applyLocalFlagsBuild(cmd, r)

Expand Down
2 changes: 1 addition & 1 deletion hugolib/content_map_page.go
Original file line number Diff line number Diff line change
Expand Up @@ -1084,7 +1084,7 @@ func (h *HugoSites) resolveAndClearStateForIdentities(
return b
}

h.MemCache.ClearMatching(shouldDelete)
h.MemCache.ClearMatching(nil, shouldDelete)

return ll, nil
}); err != nil {
Expand Down
50 changes: 41 additions & 9 deletions hugolib/hugo_sites_build.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ import (
"github.com/gohugoio/hugo/resources/page"
"github.com/gohugoio/hugo/resources/page/siteidentities"
"github.com/gohugoio/hugo/resources/postpub"
"github.com/gohugoio/hugo/resources/resource"

"github.com/spf13/afero"

Expand Down Expand Up @@ -758,17 +759,48 @@ func (h *HugoSites) processPartial(ctx context.Context, l logg.LevelLogger, conf
}
}
case files.ComponentFolderAssets:
logger.Println("Asset changed", pathInfo.Path())
p := pathInfo.Path()
logger.Println("Asset changed", p)

var matches []any
h.MemCache.ClearMatching(
func(k string, pm dynacache.PartitionManager) bool {
switch pm.ZeroV().(type) {
case resource.Resources:
case resource.Resource:
default:
return false
}
return true
},
func(k, v any) bool {
if strings.Contains(k.(string), p) {
switch vv := v.(type) {
case resource.Resources:
// GetMatch/Match.
for _, r := range vv {
matches = append(matches, r)
}
return true
default:
matches = append(matches, vv)
return true

}
}
return false
})

var hasID bool
r, _ := h.ResourceSpec.ResourceCache.Get(context.Background(), dynacache.CleanKey(pathInfo.Base()))
identity.WalkIdentitiesShallow(r, func(level int, rid identity.Identity) bool {
hasID = true
changes = append(changes, rid)
return false
})
if !hasID {
changes = append(changes, pathInfo)
for _, r := range matches {
identity.WalkIdentitiesShallow(r, func(level int, rid identity.Identity) bool {
hasID = true
changes = append(changes, rid)
return false
})
if !hasID {
changes = append(changes, pathInfo)
}
}
case files.ComponentFolderData:
logger.Println("Data changed", pathInfo.Path())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -327,3 +327,34 @@ Styles: {{ $r.RelPermalink }}

b.AssertFileContent("public/index.html", "Styles: /scss/main.css")
}

func TestRebuildAssetGetMatch(t *testing.T) {
t.Parallel()
if !scss.Supports() {
t.Skip()
}

files := `
-- assets/scss/main.scss --
b {
color: red;
}
-- layouts/index.html --
{{ $r := resources.GetMatch "scss/main.scss" | toCSS }}
T1: {{ $r.Content }}
`

b := hugolib.NewIntegrationTestBuilder(
hugolib.IntegrationTestConfig{
T: t,
TxtarString: files,
NeedsOsFS: true,
Running: true,
}).Build()

b.AssertFileContent("public/index.html", `color: red`)

b.EditFiles("assets/scss/main.scss", `b { color: blue; }`).Build()

b.AssertFileContent("public/index.html", `color: blue`)
}

0 comments on commit 46a600d

Please sign in to comment.