Rework the build.writeStats struct

Mostly to make it easier to toggle on/off this feature from the env.

See #11191
This commit is contained in:
Bjørn Erik Pedersen 2023-07-02 11:02:47 +02:00
parent c1eac616d5
commit 5afc89f2bf
6 changed files with 40 additions and 59 deletions

View file

@ -82,7 +82,7 @@ type LoadConfigResult struct {
var defaultBuild = BuildConfig{ var defaultBuild = BuildConfig{
UseResourceCacheWhen: "fallback", UseResourceCacheWhen: "fallback",
WriteStats: WriteStats{}, BuildStats: BuildStats{},
CacheBusters: []CacheBuster{ CacheBusters: []CacheBuster{
{ {
@ -112,7 +112,7 @@ type BuildConfig struct {
// When enabled, will collect and write a hugo_stats.json with some build // When enabled, will collect and write a hugo_stats.json with some build
// related aggregated data (e.g. CSS class names). // related aggregated data (e.g. CSS class names).
// Note that this was a bool <= v0.115.0. // Note that this was a bool <= v0.115.0.
WriteStats WriteStats BuildStats BuildStats
// Can be used to toggle off writing of the IntelliSense /assets/jsconfig.js // Can be used to toggle off writing of the IntelliSense /assets/jsconfig.js
// file. // file.
@ -122,15 +122,19 @@ type BuildConfig struct {
CacheBusters []CacheBuster CacheBusters []CacheBuster
} }
// WriteStats configures what to write to the hugo_stats.json file. // BuildStats configures if and what to write to the hugo_stats.json file.
type WriteStats struct { type BuildStats struct {
Tags bool Enable bool
Classes bool DisableTags bool
IDs bool DisableClasses bool
DisableIDs bool
} }
func (w WriteStats) Enabled() bool { func (w BuildStats) Enabled() bool {
return w.Tags || w.Classes || w.IDs if !w.Enable {
return false
}
return !w.DisableTags || !w.DisableClasses || !w.DisableIDs
} }
func (b BuildConfig) clone() BuildConfig { func (b BuildConfig) clone() BuildConfig {
@ -192,11 +196,7 @@ func DecodeBuildConfig(cfg Provider) BuildConfig {
// writeStats was a bool <= v0.115.0. // writeStats was a bool <= v0.115.0.
if writeStats, ok := m["writestats"]; ok { if writeStats, ok := m["writestats"]; ok {
if bb, ok := writeStats.(bool); ok { if bb, ok := writeStats.(bool); ok {
m["writestats"] = WriteStats{ m["buildstats"] = BuildStats{Enable: bb}
Tags: bb,
Classes: bb,
IDs: bb,
}
} }
} }

View file

@ -475,7 +475,7 @@ func (h *HugoSites) writeBuildStats() error {
if h.ResourceSpec == nil { if h.ResourceSpec == nil {
panic("h.ResourceSpec is nil") panic("h.ResourceSpec is nil")
} }
if !h.ResourceSpec.BuildConfig().WriteStats.Enabled() { if !h.ResourceSpec.BuildConfig().BuildStats.Enabled() {
return nil return nil
} }

View file

@ -1200,46 +1200,39 @@ writeStats = false
b.AssertDestinationExists("hugo_stats.json", false) b.AssertDestinationExists("hugo_stats.json", false)
b = r(` b = r(`
[build.writeStats] [build.buildStats]
tags = true enable = true
classes = true `)
ids = true
`)
b.AssertFileContent("hugo_stats.json", "myclass", "div", "myid") b.AssertFileContent("hugo_stats.json", "myclass", "div", "myid")
b = r(` b = r(`
[build.writeStats] [build.buildStats]
tags = true enable = true
classes = true disableids = true
ids = false
`) `)
b.AssertFileContent("hugo_stats.json", "myclass", "div", "! myid") b.AssertFileContent("hugo_stats.json", "myclass", "div", "! myid")
b = r(` b = r(`
[build.writeStats] [build.buildStats]
tags = true enable = true
classes = false disableclasses = true
ids = true
`) `)
b.AssertFileContent("hugo_stats.json", "! myclass", "div", "myid") b.AssertFileContent("hugo_stats.json", "! myclass", "div", "myid")
b = r(` b = r(`
[build.writeStats] [build.buildStats]
tags = false enable = true
classes = true disabletags = true
ids = true
`) `)
b.AssertFileContent("hugo_stats.json", "myclass", "! div", "myid") b.AssertFileContent("hugo_stats.json", "myclass", "! div", "myid")
b = r(` b = r(`
[build.writeStats] [build.buildStats]
tags = false enable = false
classes = false
ids = false
`) `)
b.AssertDestinationExists("hugo_stats.json", false) b.AssertDestinationExists("hugo_stats.json", false)

View file

@ -47,7 +47,7 @@ var (
} }
) )
func newHTMLElementsCollector(conf config.WriteStats) *htmlElementsCollector { func newHTMLElementsCollector(conf config.BuildStats) *htmlElementsCollector {
return &htmlElementsCollector{ return &htmlElementsCollector{
conf: conf, conf: conf,
elementSet: make(map[string]bool), elementSet: make(map[string]bool),
@ -95,7 +95,7 @@ type htmlElement struct {
} }
type htmlElementsCollector struct { type htmlElementsCollector struct {
conf config.WriteStats conf config.BuildStats
// Contains the raw HTML string. We will get the same element // Contains the raw HTML string. We will get the same element
// several times, and want to avoid costly reparsing when this // several times, and want to avoid costly reparsing when this
@ -117,7 +117,7 @@ func (c *htmlElementsCollector) getHTMLElements() HTMLElements {
for _, el := range c.elements { for _, el := range c.elements {
classes = append(classes, el.Classes...) classes = append(classes, el.Classes...)
ids = append(ids, el.IDs...) ids = append(ids, el.IDs...)
if c.conf.Tags { if !c.conf.DisableTags {
tags = append(tags, el.Tag) tags = append(tags, el.Tag)
} }
} }
@ -372,7 +372,7 @@ func htmlLexToEndOfComment(w *htmlElementsCollectorWriter) htmlCollectorStateFun
func (w *htmlElementsCollectorWriter) parseHTMLElement(elStr string) (el htmlElement, err error) { func (w *htmlElementsCollectorWriter) parseHTMLElement(elStr string) (el htmlElement, err error) {
conf := w.collector.conf conf := w.collector.conf
if !conf.IDs && !conf.Classes { if conf.DisableTags && conf.DisableClasses {
// Nothing to do. // Nothing to do.
return return
} }
@ -402,11 +402,11 @@ func (w *htmlElementsCollectorWriter) parseHTMLElement(elStr string) (el htmlEle
switch { switch {
case strings.EqualFold(a.Key, "id"): case strings.EqualFold(a.Key, "id"):
// There should be only one, but one never knows... // There should be only one, but one never knows...
if conf.IDs { if !conf.DisableIDs {
el.IDs = append(el.IDs, a.Val) el.IDs = append(el.IDs, a.Val)
} }
default: default:
if !conf.Classes { if conf.DisableClasses {
continue continue
} }
if classAttrRe.MatchString(a.Key) { if classAttrRe.MatchString(a.Key) {

View file

@ -138,11 +138,7 @@ func TestClassCollector(t *testing.T) {
c.Run(fmt.Sprintf("%s--minify-%t", test.name, variant.minify), func(c *qt.C) { c.Run(fmt.Sprintf("%s--minify-%t", test.name, variant.minify), func(c *qt.C) {
w := newHTMLElementsCollectorWriter(newHTMLElementsCollector( w := newHTMLElementsCollectorWriter(newHTMLElementsCollector(
config.WriteStats{ config.BuildStats{Enable: true},
Tags: true,
Classes: true,
IDs: true,
},
)) ))
if variant.minify { if variant.minify {
if skipMinifyTest[test.name] { if skipMinifyTest[test.name] {
@ -248,11 +244,7 @@ func BenchmarkElementsCollectorWriter(b *testing.B) {
` `
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
w := newHTMLElementsCollectorWriter(newHTMLElementsCollector( w := newHTMLElementsCollectorWriter(newHTMLElementsCollector(
config.WriteStats{ config.BuildStats{Enable: true},
Tags: true,
Classes: true,
IDs: true,
},
)) ))
fmt.Fprint(w, benchHTML) fmt.Fprint(w, benchHTML)
@ -276,11 +268,7 @@ func BenchmarkElementsCollectorWriterPre(b *testing.B) {
` `
w := newHTMLElementsCollectorWriter(newHTMLElementsCollector( w := newHTMLElementsCollectorWriter(newHTMLElementsCollector(
config.WriteStats{ config.BuildStats{Enable: true},
Tags: true,
Classes: true,
IDs: true,
},
)) ))
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
fmt.Fprint(w, benchHTML) fmt.Fprint(w, benchHTML)

View file

@ -81,8 +81,8 @@ func NewDestinationPublisher(rs *resources.Spec, outputFormats output.Formats, m
fs := rs.BaseFs.PublishFs fs := rs.BaseFs.PublishFs
cfg := rs.Cfg cfg := rs.Cfg
var classCollector *htmlElementsCollector var classCollector *htmlElementsCollector
if rs.BuildConfig().WriteStats.Enabled() { if rs.BuildConfig().BuildStats.Enabled() {
classCollector = newHTMLElementsCollector(rs.BuildConfig().WriteStats) classCollector = newHTMLElementsCollector(rs.BuildConfig().BuildStats)
} }
pub = DestinationPublisher{fs: fs, htmlElementsCollector: classCollector} pub = DestinationPublisher{fs: fs, htmlElementsCollector: classCollector}
pub.min, err = minifiers.New(mediaTypes, outputFormats, cfg) pub.min, err = minifiers.New(mediaTypes, outputFormats, cfg)