Compare commits

...

16 Commits

Author SHA1 Message Date
Bjørn Erik Pedersen ace564e362 Add titleCaseStyle none and firstupper
Fixes #11204
2023-07-05 19:32:57 +02:00
Anthony Fok bf7ee8a91a Bump github.com/bep/clock v0.3.0 to renamed github.com/bep/clocks v0.5.0 2023-07-04 09:14:48 +02:00
hugoreleaser d912491f2d releaser: Prepare repository for 0.116.0-DEV
[ci skip]
2023-07-03 17:39:56 +00:00
hugoreleaser 857374e693 releaser: Bump versions for release of 0.115.1
[ci skip]
2023-07-03 17:28:25 +00:00
Bjørn Erik Pedersen c27639b9a0 docs: Regen docs helper 2023-07-03 19:25:27 +02:00
Bjørn Erik Pedersen ceb486f98c Fix buildStats when tags and classes are disabled
Fixes #11202
2023-07-03 09:58:33 +02:00
Bjørn Erik Pedersen 5afc89f2bf Rework the build.writeStats struct
Mostly to make it easier to toggle on/off this feature from the env.

See #11191
2023-07-02 13:04:11 +02:00
Joe Mooring c1eac616d5 snap: Explicitly set security.exec.osenv during build
Fixes #11199
2023-07-01 17:55:23 -07:00
Joe Mooring 3c8256a137 snap: Restore security.exec.osenv whitelist
Fixes #11195
2023-07-01 14:55:57 -07:00
Bjørn Erik Pedersen 19d76ae96b github: Build for Dragonfly in CI build
To discover upstream issues before we release.
2023-07-01 18:53:48 +02:00
Bjørn Erik Pedersen 11ecea6106 Make build.writeStats a struct
So you can do

```toml
[build.writeStats]
  tags = true
  classes = true
  ids = false
```

Fixes #11191
2023-07-01 15:38:32 +02:00
dependabot[bot] da98724bc8 build(deps): bump github.com/evanw/esbuild from 0.18.10 to 0.18.11
Bumps [github.com/evanw/esbuild](https://github.com/evanw/esbuild) from 0.18.10 to 0.18.11.
- [Release notes](https://github.com/evanw/esbuild/releases)
- [Changelog](https://github.com/evanw/esbuild/blob/main/CHANGELOG.md)
- [Commits](https://github.com/evanw/esbuild/compare/v0.18.10...v0.18.11)

---
updated-dependencies:
- dependency-name: github.com/evanw/esbuild
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-07-01 15:33:24 +02:00
dependabot[bot] 4d470bb732 build(deps): bump github.com/alecthomas/chroma/v2 from 2.7.0 to 2.8.0
Bumps [github.com/alecthomas/chroma/v2](https://github.com/alecthomas/chroma) from 2.7.0 to 2.8.0.
- [Release notes](https://github.com/alecthomas/chroma/releases)
- [Changelog](https://github.com/alecthomas/chroma/blob/master/.goreleaser.yml)
- [Commits](https://github.com/alecthomas/chroma/compare/v2.7.0...v2.8.0)

---
updated-dependencies:
- dependency-name: github.com/alecthomas/chroma/v2
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-07-01 10:33:49 +02:00
Bjørn Erik Pedersen 0ff8e13c1c commands: Fix index out of range in hugo mod get
Fixes #11190
2023-06-30 15:57:46 +02:00
Bjørn Erik Pedersen ffd37d4f75 Only print the path warnings once
We could reset and rerun it on server rebuilds, but that report needs a full build to make sense.

Also clean up the config vs flags in this area: Make all config settings match the flags e.g. `printPathWarnings`, but set up aliases for the
old.

Fixes #11187
2023-06-30 10:24:28 +02:00
Bjørn Erik Pedersen b4b65245b2 Update README.md 2023-06-30 08:01:25 +02:00
30 changed files with 325 additions and 94 deletions
+7
View File
@@ -104,3 +104,10 @@ jobs:
- name: Build tags
run: |
go install -tags extended,nodeploy
- if: matrix.os == 'ubuntu-latest'
name: Build for dragonfly
run: |
go install
env:
GOARCH: amd64
GOOS: dragonfly
+1 -2
View File
@@ -63,7 +63,7 @@ And with [Hugo Modules], you can share content, assets, data, translations, them
<p>&nbsp;</p>
<p float="left">
<a href="https://www.linode.com/?utm_campaign=hugosponsor&utm_medium=banner&utm_source=hugogithub" target="_blank"><img src="https://raw.githubusercontent.com/gohugoio/gohugoioTheme/master/assets/images/sponsors/linode-logo_standard_light_medium.png" width="200" alt="Linode"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<a href="https://cloudcannon.com/?utm_campaign=HugoSponsorship&utm_source=sponsor&utm_content=gohugo" target="_blank"><img src="https://raw.githubusercontent.com/gohugoio/gohugoioTheme/master/assets/images/sponsors/cloudcannon-blue.svg" width="220" alt="CloudCannon"></a>
<a href="https://cloudcannon.com/hugo-cms/?utm_campaign=HugoSponsorship&utm_source=sponsor&utm_content=gohugo" target="_blank"><img src="https://raw.githubusercontent.com/gohugoio/gohugoioTheme/master/assets/images/sponsors/cloudcannon-blue.svg" width="220" alt="CloudCannon"></a>
<p>&nbsp;</p>
## Installation
@@ -176,7 +176,6 @@ github.com/aws/aws-sdk-go-v2/service/sts="v1.19.2"
github.com/aws/aws-sdk-go-v2="v1.18.1"
github.com/aws/aws-sdk-go="v1.44.284"
github.com/aws/smithy-go="v1.13.5"
github.com/bep/clock="v0.3.0"
github.com/bep/clocks="v0.5.0"
github.com/bep/debounce="v1.2.0"
github.com/bep/gitmap="v1.1.2"
+10 -12
View File
@@ -30,7 +30,7 @@ import (
"go.uber.org/automaxprocs/maxprocs"
"github.com/bep/clock"
"github.com/bep/clocks"
"github.com/bep/lazycache"
"github.com/bep/logg"
"github.com/bep/overlayfs"
@@ -110,12 +110,10 @@ type rootCommand struct {
environment string
// Common build flags.
baseURL string
gc bool
poll string
forceSyncStatic bool
printPathWarnings bool
printUnusedTemplates bool
baseURL string
gc bool
poll string
forceSyncStatic bool
// Profile flags (for debugging of performance problems)
cpuprofile string
@@ -175,7 +173,7 @@ func (r *rootCommand) ConfigFromConfig(key int32, oldConf *commonConfig) (*commo
if !configs.Base.C.Clock.IsZero() {
// TODO(bep) find a better place for this.
htime.Clock = clock.Start(configs.Base.C.Clock)
htime.Clock = clocks.Start(configs.Base.C.Clock)
}
return &commonConfig{
@@ -285,10 +283,10 @@ func (r *rootCommand) ConfigFromProvider(key int32, cfg config.Provider) (*commo
if !base.C.Clock.IsZero() {
// TODO(bep) find a better place for this.
htime.Clock = clock.Start(configs.Base.C.Clock)
htime.Clock = clocks.Start(configs.Base.C.Clock)
}
if base.LogPathWarnings {
if base.PrintPathWarnings {
// Note that we only care about the "dynamic creates" here,
// so skip the static fs.
fs.PublishDir = hugofs.NewCreateCountingFs(fs.PublishDir)
@@ -544,8 +542,8 @@ func applyLocalFlagsBuild(cmd *cobra.Command, r *rootCommand) {
cmd.Flags().BoolP("noChmod", "", false, "don't sync permission mode of files")
cmd.Flags().BoolP("noBuildLock", "", false, "don't create .hugo_build.lock file")
cmd.Flags().BoolP("printI18nWarnings", "", false, "print missing translations")
cmd.Flags().BoolVarP(&r.printPathWarnings, "printPathWarnings", "", false, "print warnings on duplicate target paths etc.")
cmd.Flags().BoolVarP(&r.printUnusedTemplates, "printUnusedTemplates", "", false, "print warnings on unused templates.")
cmd.Flags().BoolP("printPathWarnings", "", false, "print warnings on duplicate target paths etc.")
cmd.Flags().BoolP("printUnusedTemplates", "", false, "print warnings on unused templates.")
cmd.Flags().StringVarP(&r.cpuprofile, "profile-cpu", "", "", "write cpu profile to `file`")
cmd.Flags().StringVarP(&r.memprofile, "profile-mem", "", "", "write memory profile to `file`")
cmd.Flags().BoolVarP(&r.printm, "printMemoryUsage", "", false, "print memory usage to screen at intervals")
+3 -5
View File
@@ -79,11 +79,9 @@ func flagsToCfgWithAdditionalConfigBase(cd *simplecobra.Commandeer, cfg config.P
// Flags with a different name in the config.
keyMap := map[string]string{
"minify": "minifyOutput",
"destination": "publishDir",
"printI18nWarnings": "logI18nWarnings",
"printPathWarnings": "logPathWarnings",
"editor": "newContentEditor",
"minify": "minifyOutput",
"destination": "publishDir",
"editor": "newContentEditor",
}
// Flags that we for some reason don't want to expose in the site config.
-8
View File
@@ -43,7 +43,6 @@ import (
"github.com/gohugoio/hugo/hugolib/filesystems"
"github.com/gohugoio/hugo/livereload"
"github.com/gohugoio/hugo/resources/page"
"github.com/gohugoio/hugo/tpl"
"github.com/gohugoio/hugo/watcher"
"github.com/spf13/fsync"
"golang.org/x/sync/errgroup"
@@ -418,13 +417,6 @@ func (c *hugoBuilder) build() error {
return err
}
if c.r.printUnusedTemplates {
unusedTemplates := h.Tmpl().(tpl.UnusedTemplatesProvider).UnusedTemplates()
for _, unusedTemplate := range unusedTemplates {
c.r.logger.Warnf("Template %s is unused, source file %s", unusedTemplate.Name(), unusedTemplate.Filename())
}
}
h.PrintProcessingStats(os.Stdout)
c.r.Println()
}
+1 -1
View File
@@ -224,7 +224,7 @@ Run "go help get" for more information. All flags available for "go get" is also
run: func(ctx context.Context, cd *simplecobra.Commandeer, r *rootCommand, args []string) error {
// We currently just pass on the flags we get to Go and
// need to do the flag handling manually.
if len(args) == 1 && args[0] == "-h" || args[0] == "--help" {
if len(args) == 1 && (args[0] == "-h" || args[0] == "--help") {
return errHelp
}
+2 -2
View File
@@ -18,7 +18,7 @@ import (
"strings"
"time"
"github.com/bep/clock"
"github.com/bep/clocks"
"github.com/spf13/cast"
"github.com/gohugoio/locales"
@@ -75,7 +75,7 @@ var (
"December",
}
Clock = clock.System()
Clock = clocks.System()
)
func NewTimeFormatter(ltr locales.Translator) TimeFormatter {
+6 -6
View File
@@ -484,12 +484,6 @@ type RootConfig struct {
// Enable to print greppable placeholders (on the form "[i18n] TRANSLATIONID") for missing translation strings.
EnableMissingTranslationPlaceholders bool
// Enable to print warnings for missing translation strings.
LogI18nWarnings bool
// ENable to print warnings for multiple files published to the same destination.
LogPathWarnings bool
// Enable to panic on warning log entries. This may make it easier to detect the source.
PanicOnWarning bool
@@ -525,6 +519,12 @@ type RootConfig struct {
// Whether to track and print unused templates during the build.
PrintUnusedTemplates bool
// Enable to print warnings for missing translation strings.
PrintI18nWarnings bool
// ENable to print warnings for multiple files published to the same destination.
PrintPathWarnings bool
// URL to be used as a placeholder when a page reference cannot be found in ref or relref. Is used as-is.
RefLinksNotFoundURL string
+2 -2
View File
@@ -199,8 +199,8 @@ func (c ConfigLanguage) EnableMissingTranslationPlaceholders() bool {
return c.config.EnableMissingTranslationPlaceholders
}
func (c ConfigLanguage) LogI18nWarnings() bool {
return c.config.LogI18nWarnings
func (c ConfigLanguage) PrintI18nWarnings() bool {
return c.config.PrintI18nWarnings
}
func (c ConfigLanguage) CreateTitle(s string) string {
+18
View File
@@ -69,3 +69,21 @@ Title: {{ .Title }}
b.Assert(modConf.Mounts[1].Lang, qt.Equals, "sv")
}
func TestConfigAliases(t *testing.T) {
files := `
-- hugo.toml --
baseURL = "https://example.com"
logI18nWarnings = true
logPathWarnings = true
`
b := hugolib.NewIntegrationTestBuilder(
hugolib.IntegrationTestConfig{T: t, TxtarString: files},
).Build()
conf := b.H.Configs.Base
b.Assert(conf.PrintI18nWarnings, qt.Equals, true)
b.Assert(conf.PrintPathWarnings, qt.Equals, true)
}
+5 -1
View File
@@ -139,7 +139,11 @@ type configLoader struct {
// Handle some legacy values.
func (l configLoader) applyConfigAliases() error {
aliases := []types.KeyValueStr{{Key: "taxonomies", Value: "indexes"}}
aliases := []types.KeyValueStr{
{Key: "indexes", Value: "taxonomies"},
{Key: "logI18nWarnings", Value: "printI18nWarnings"},
{Key: "logPathWarnings", Value: "printPathWarnings"},
}
for _, alias := range aliases {
if l.cfg.IsSet(alias.Key) {
+27 -3
View File
@@ -82,7 +82,7 @@ type LoadConfigResult struct {
var defaultBuild = BuildConfig{
UseResourceCacheWhen: "fallback",
WriteStats: false,
BuildStats: BuildStats{},
CacheBusters: []CacheBuster{
{
@@ -111,7 +111,8 @@ type BuildConfig struct {
// When enabled, will collect and write a hugo_stats.json with some build
// related aggregated data (e.g. CSS class names).
WriteStats bool
// Note that this was a bool <= v0.115.0.
BuildStats BuildStats
// Can be used to toggle off writing of the IntelliSense /assets/jsconfig.js
// file.
@@ -121,6 +122,21 @@ type BuildConfig struct {
CacheBusters []CacheBuster
}
// BuildStats configures if and what to write to the hugo_stats.json file.
type BuildStats struct {
Enable bool
DisableTags bool
DisableClasses bool
DisableIDs bool
}
func (w BuildStats) Enabled() bool {
if !w.Enable {
return false
}
return !w.DisableTags || !w.DisableClasses || !w.DisableIDs
}
func (b BuildConfig) clone() BuildConfig {
b.CacheBusters = append([]CacheBuster{}, b.CacheBusters...)
return b
@@ -171,14 +187,22 @@ func (b *BuildConfig) CompileConfig(logger loggers.Logger) error {
func DecodeBuildConfig(cfg Provider) BuildConfig {
m := cfg.GetStringMap("build")
b := defaultBuild.clone()
if m == nil {
return b
}
// writeStats was a bool <= v0.115.0.
if writeStats, ok := m["writestats"]; ok {
if bb, ok := writeStats.(bool); ok {
m["buildstats"] = BuildStats{Enable: bb}
}
}
err := mapstructure.WeakDecode(m, &b)
if err != nil {
return defaultBuild
return b
}
b.UseResourceCacheWhen = strings.ToLower(b.UseResourceCacheWhen)
+1 -1
View File
@@ -57,7 +57,7 @@ type AllProvider interface {
EnableMissingTranslationPlaceholders() bool
TemplateMetrics() bool
TemplateMetricsHints() bool
LogI18nWarnings() bool
PrintI18nWarnings() bool
CreateTitle(s string) string
IgnoreFile(s string) bool
NewContentEditor() string
@@ -623,7 +623,13 @@ status = 404
Set `titleCaseStyle` to specify the title style used by the [title](/functions/title/) template function and the automatic section titles in Hugo.
By default, Hugo adheres to the capitalization rules in the [Associated Press (AP) Stylebook]. Set `titleCaseStyle` to `chicago` if you would prefer to follow the [Chicago Manual of Style], or set if to `go` to use Go's convention of capitalizing every word.
Can be one of:
* `ap` (default), the capitalization rules in the [Associated Press (AP) Stylebook]
* `chicago`, the [Chicago Manual of Style]
* `go`, Go's convention of capitalizing every word.
* `firstupper`, capitalize the first letter of the first word.
* `none`, no capitalization.
[Associated Press (AP) Stylebook]: https://www.apstylebook.com/
[Chicago Manual of Style]: https://www.chicagomanualofstyle.org/home.html
+44 -1
View File
@@ -73,6 +73,12 @@
"applescript"
]
},
{
"Name": "ArangoDB AQL",
"Aliases": [
"aql"
]
},
{
"Name": "Arduino",
"Aliases": [
@@ -85,6 +91,19 @@
"armasm"
]
},
{
"Name": "AutoHotkey",
"Aliases": [
"autohotkey",
"ahk"
]
},
{
"Name": "AutoIt",
"Aliases": [
"autoit"
]
},
{
"Name": "Awk",
"Aliases": [
@@ -666,6 +685,12 @@
"io"
]
},
{
"Name": "ISCdhcpd",
"Aliases": [
"iscdhcpd"
]
},
{
"Name": "J",
"Aliases": [
@@ -1230,6 +1255,12 @@
"sieve"
]
},
{
"Name": "Smali",
"Aliases": [
"smali"
]
},
{
"Name": "Smalltalk",
"Aliases": [
@@ -1324,6 +1355,13 @@
"tablegen"
]
},
{
"Name": "Tal",
"Aliases": [
"tal",
"uxntal"
]
},
{
"Name": "TASM",
"Aliases": [
@@ -1505,6 +1543,12 @@
"Name": "WDTE",
"Aliases": null
},
{
"Name": "WebGPU Shading Language",
"Aliases": [
"wgsl"
]
},
{
"Name": "Whiley",
"Aliases": [
@@ -1723,7 +1767,6 @@
"js": {
"precision": 0,
"keepVarNames": false,
"noNullishOperator": false,
"version": 2022
},
"json": {
+3 -4
View File
@@ -3,10 +3,10 @@ module github.com/gohugoio/hugo
require (
github.com/BurntSushi/locker v0.0.0-20171006230638-a6e239ea1c69
github.com/PuerkitoBio/purell v1.1.1
github.com/alecthomas/chroma/v2 v2.7.0
github.com/alecthomas/chroma/v2 v2.8.0
github.com/armon/go-radix v1.0.0
github.com/aws/aws-sdk-go v1.43.5
github.com/bep/clock v0.3.0
github.com/bep/clocks v0.5.0
github.com/bep/debounce v1.2.0
github.com/bep/gitmap v1.1.2
github.com/bep/goat v0.5.0
@@ -25,7 +25,7 @@ require (
github.com/cli/safeexec v1.0.1
github.com/disintegration/gift v1.2.1
github.com/dustin/go-humanize v1.0.1
github.com/evanw/esbuild v0.18.10
github.com/evanw/esbuild v0.18.11
github.com/fatih/color v1.15.0
github.com/fortytw2/leaktest v1.3.0
github.com/frankban/quicktest v1.14.5
@@ -104,7 +104,6 @@ require (
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.14.1 // indirect
github.com/aws/aws-sdk-go-v2/service/sts v1.18.3 // indirect
github.com/aws/smithy-go v1.13.5 // indirect
github.com/bep/clocks v0.5.0 // indirect
github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect
github.com/dlclark/regexp2 v1.10.0 // indirect
github.com/go-openapi/jsonpointer v0.19.5 // indirect
+4 -6
View File
@@ -126,8 +126,8 @@ github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbt
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 h1:d+Bc7a5rLufV/sSk/8dngufqelfh6jnri85riMAaF/M=
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
github.com/alecthomas/assert/v2 v2.2.1 h1:XivOgYcduV98QCahG8T5XTezV5bylXe+lBxLG2K2ink=
github.com/alecthomas/chroma/v2 v2.7.0 h1:hm1rY6c/Ob4eGclpQ7X/A3yhqBOZNUTk9q+yhyLIViI=
github.com/alecthomas/chroma/v2 v2.7.0/go.mod h1:yrkMI9807G1ROx13fhe1v6PN2DDeaR73L3d+1nmYQtw=
github.com/alecthomas/chroma/v2 v2.8.0 h1:w9WJUjFFmHHB2e8mRpL9jjy3alYDlU0QLDezj1xE264=
github.com/alecthomas/chroma/v2 v2.8.0/go.mod h1:yrkMI9807G1ROx13fhe1v6PN2DDeaR73L3d+1nmYQtw=
github.com/alecthomas/repr v0.2.0 h1:HAzS41CIzNW5syS8Mf9UwXhNH1J9aix/BvDRf1Ml2Yk=
github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
github.com/armon/go-radix v1.0.0 h1:F4z6KzEeeQIMeLFa97iZU6vupzoecKdU5TX24SNppXI=
@@ -174,8 +174,6 @@ github.com/aws/smithy-go v1.8.0/go.mod h1:SObp3lf9smib00L/v3U2eAKG8FyQ7iLrJnQiAm
github.com/aws/smithy-go v1.13.5 h1:hgz0X/DX0dGqTYpGALqXJoRKRj5oQ7150i5FdTePzO8=
github.com/aws/smithy-go v1.13.5/go.mod h1:Tg+OJXh4MB2R/uN61Ko2f6hTZwB/ZYGOtib8J3gBHzA=
github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
github.com/bep/clock v0.3.0 h1:vfOA6+wVb6pPQEiXow9f/too92vNTLe9MuwO13PfI0M=
github.com/bep/clock v0.3.0/go.mod h1:6Gz2lapnJ9vxpvPxQ2u6FcXFRoj4kkiqQ6pm0ERZlwk=
github.com/bep/clocks v0.5.0 h1:hhvKVGLPQWRVsBP/UB7ErrHYIO42gINVbvqxvYTPVps=
github.com/bep/clocks v0.5.0/go.mod h1:SUq3q+OOq41y2lRQqH5fsOoxN8GbxSiT6jvoVVLCVhU=
github.com/bep/debounce v1.2.0 h1:wXds8Kq8qRfwAOpAxHrJDbCXgC5aHSzgQb/0gKsHQqo=
@@ -260,8 +258,8 @@ github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.m
github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ=
github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0=
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
github.com/evanw/esbuild v0.18.10 h1:QPpRUR5aOMQ4LQQDA9zZFpSuyT8+luBoyvPqVy8Vuv0=
github.com/evanw/esbuild v0.18.10/go.mod h1:iINY06rn799hi48UqEnaQvVfZWe6W9bET78LbvN8VWk=
github.com/evanw/esbuild v0.18.11 h1:Mb0qb9KyJQraob0Y7LA0DOdD8ijJs2TxhqgqrDeGq4w=
github.com/evanw/esbuild v0.18.11/go.mod h1:iINY06rn799hi48UqEnaQvVfZWe6W9bET78LbvN8VWk=
github.com/fatih/color v1.15.0 h1:kOqh6YHBtK8aywxGerMG2Eq3H6Qgoqeo13Bk2Mv/nBs=
github.com/fatih/color v1.15.0/go.mod h1:0h5ZqXfHYED7Bhv2ZJamyIOUej9KtShiJESRwBDUSsw=
github.com/form3tech-oss/jwt-go v3.2.2+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k=
+6
View File
@@ -205,6 +205,8 @@ func ReaderContains(r io.Reader, subslice []byte) bool {
// - "Go" (strings.Title)
// - "AP" (see https://www.apstylebook.com/)
// - "Chicago" (see http://www.chicagomanualofstyle.org/home.html)
// - "FirstUpper" (only the first character is upper case)
// - "None" (no transformation)
//
// If an unknown or empty style is provided, AP style is what you get.
func GetTitleFunc(style string) func(s string) string {
@@ -214,6 +216,10 @@ func GetTitleFunc(style string) func(s string) string {
case "chicago":
tc := transform.NewTitleConverter(transform.ChicagoStyle)
return tc.Title
case "none":
return func(s string) string { return s }
case "firstupper":
return FirstUpper
default:
tc := transform.NewTitleConverter(transform.APStyle)
return tc.Title
+3 -1
View File
@@ -203,7 +203,7 @@ func TestReaderContains(t *testing.T) {
}
func TestGetTitleFunc(t *testing.T) {
title := "somewhere over the rainbow"
title := "somewhere over the Rainbow"
c := qt.New(t)
c.Assert(helpers.GetTitleFunc("go")(title), qt.Equals, "Somewhere Over The Rainbow")
@@ -213,6 +213,8 @@ func TestGetTitleFunc(t *testing.T) {
c.Assert(helpers.GetTitleFunc("ap")(title), qt.Equals, "Somewhere Over the Rainbow")
c.Assert(helpers.GetTitleFunc("")(title), qt.Equals, "Somewhere Over the Rainbow")
c.Assert(helpers.GetTitleFunc("unknown")(title), qt.Equals, "Somewhere Over the Rainbow")
c.Assert(helpers.GetTitleFunc("none")(title), qt.Equals, title)
c.Assert(helpers.GetTitleFunc("firstupper")(title), qt.Equals, "Somewhere over the Rainbow")
}
func BenchmarkReaderContains(b *testing.B) {
+2
View File
@@ -77,6 +77,8 @@ type HugoSites struct {
contentInit sync.Once
content *pageMaps
postRenderInit sync.Once
// Keeps track of bundle directories and symlinks to enable partial rebuilding.
ContentChanges *contentChangeMap
+32 -13
View File
@@ -25,6 +25,7 @@ import (
"github.com/bep/logg"
"github.com/gohugoio/hugo/langs"
"github.com/gohugoio/hugo/publisher"
"github.com/gohugoio/hugo/tpl"
"github.com/gohugoio/hugo/hugofs"
@@ -144,18 +145,8 @@ func (h *HugoSites) Build(config BuildCfg, events ...fsnotify.Event) error {
h.SendError(fmt.Errorf("render: %w", err))
}
if h.Configs.Base.LogPathWarnings {
// We need to do this before any post processing, as that may write to the same files twice
// and create false positives.
hugofs.WalkFilesystems(h.Fs.PublishDir, func(fs afero.Fs) bool {
if dfs, ok := fs.(hugofs.DuplicatesReporter); ok {
dupes := dfs.ReportDuplicates()
if dupes != "" {
h.Log.Warnln("Duplicate target paths:", dupes)
}
}
return false
})
if err := h.postRenderOnce(); err != nil {
h.SendError(fmt.Errorf("postRenderOnce: %w", err))
}
if err := h.postProcess(infol); err != nil {
@@ -329,6 +320,34 @@ func (h *HugoSites) render(l logg.LevelLogger, config *BuildCfg) error {
return nil
}
func (h *HugoSites) postRenderOnce() error {
h.postRenderInit.Do(func() {
conf := h.Configs.Base
if conf.PrintPathWarnings {
// We need to do this before any post processing, as that may write to the same files twice
// and create false positives.
hugofs.WalkFilesystems(h.Fs.PublishDir, func(fs afero.Fs) bool {
if dfs, ok := fs.(hugofs.DuplicatesReporter); ok {
dupes := dfs.ReportDuplicates()
if dupes != "" {
h.Log.Warnln("Duplicate target paths:", dupes)
}
}
return false
})
}
if conf.PrintUnusedTemplates {
unusedTemplates := h.Tmpl().(tpl.UnusedTemplatesProvider).UnusedTemplates()
for _, unusedTemplate := range unusedTemplates {
h.Log.Warnf("Template %s is unused, source file %s", unusedTemplate.Name(), unusedTemplate.Filename())
}
}
})
return nil
}
func (h *HugoSites) postProcess(l logg.LevelLogger) error {
defer h.timeTrack(l, time.Now(), "postProcess")
@@ -456,7 +475,7 @@ func (h *HugoSites) writeBuildStats() error {
if h.ResourceSpec == nil {
panic("h.ResourceSpec is nil")
}
if !h.ResourceSpec.BuildConfig().WriteStats {
if !h.ResourceSpec.BuildConfig().BuildStats.Enabled() {
return nil
}
+9
View File
@@ -147,6 +147,15 @@ func (s *IntegrationTestBuilder) AssertFileContent(filename string, matches ...s
if match == "" || strings.HasPrefix(match, "#") {
continue
}
var negate bool
if strings.HasPrefix(match, "! ") {
negate = true
match = strings.TrimPrefix(match, "! ")
}
if negate {
s.Assert(content, qt.Not(qt.Contains), match, qt.Commentf(m))
continue
}
s.Assert(content, qt.Contains, match, qt.Commentf(m))
}
}
+3 -3
View File
@@ -22,7 +22,7 @@ import (
"testing"
"time"
"github.com/bep/clock"
"github.com/bep/clocks"
"github.com/gohugoio/hugo/identity"
"github.com/gohugoio/hugo/markup/asciidocext"
"github.com/gohugoio/hugo/markup/rst"
@@ -1502,8 +1502,8 @@ func TestShouldBuild(t *testing.T) {
}
func TestShouldBuildWithClock(t *testing.T) {
htime.Clock = clock.Start(time.Date(2021, 11, 17, 20, 34, 58, 651387237, time.UTC))
t.Cleanup(func() { htime.Clock = clock.System() })
htime.Clock = clocks.Start(time.Date(2021, 11, 17, 20, 34, 58, 651387237, time.UTC))
t.Cleanup(func() { htime.Clock = clocks.System() })
past := time.Date(2009, 11, 17, 20, 34, 58, 651387237, time.UTC)
future := time.Date(2037, 11, 17, 20, 34, 58, 651387237, time.UTC)
zero := time.Time{}
+85
View File
@@ -1162,6 +1162,91 @@ Some text.
}
}
func TestClassCollectorConfigWriteStats(t *testing.T) {
r := func(writeStatsConfig string) *IntegrationTestBuilder {
files := `
-- hugo.toml --
WRITE_STATS_CONFIG
-- layouts/_default/list.html --
<div id="myid" class="myclass">Foo</div>
`
files = strings.Replace(files, "WRITE_STATS_CONFIG", writeStatsConfig, 1)
b := NewIntegrationTestBuilder(
IntegrationTestConfig{
T: t,
TxtarString: files,
NeedsOsFS: true,
},
).Build()
return b
}
// Legacy config.
b := r(`
[build]
writeStats = true
`)
b.AssertFileContent("hugo_stats.json", "myclass", "div", "myid")
b = r(`
[build]
writeStats = false
`)
b.AssertDestinationExists("hugo_stats.json", false)
b = r(`
[build.buildStats]
enable = true
`)
b.AssertFileContent("hugo_stats.json", "myclass", "div", "myid")
b = r(`
[build.buildStats]
enable = true
disableids = true
`)
b.AssertFileContent("hugo_stats.json", "myclass", "div", "! myid")
b = r(`
[build.buildStats]
enable = true
disableclasses = true
`)
b.AssertFileContent("hugo_stats.json", "! myclass", "div", "myid")
b = r(`
[build.buildStats]
enable = true
disabletags = true
`)
b.AssertFileContent("hugo_stats.json", "myclass", "! div", "myid")
b = r(`
[build.buildStats]
enable = true
disabletags = true
disableclasses = true
`)
b.AssertFileContent("hugo_stats.json", "! myclass", "! div", "myid")
b = r(`
[build.buildStats]
enable = false
`)
b.AssertDestinationExists("hugo_stats.json", false)
}
func TestClassCollectorStress(t *testing.T) {
statsFilename := "hugo_stats.json"
defer os.Remove(statsFilename)
+3 -2
View File
@@ -1,7 +1,8 @@
# Release env.
# These will be replaced by script before release.
HUGORELEASER_TAG=v0.115.0
HUGORELEASER_COMMITISH=67caf50698783d3b3d78559ac81483d83e5e1a35
HUGORELEASER_TAG=v0.115.1
HUGORELEASER_COMMITISH=857374e69358f788bd31ddc55255c5c8e3dcfd80
+1 -1
View File
@@ -119,7 +119,7 @@ func (t Translator) initFuncs(bndl *i18n.Bundle) {
t.logger.Warnf("Failed to get translated string for language %q and ID %q: %s", currentLangStr, translationID, err)
}
if t.cfg.LogI18nWarnings() {
if t.cfg.PrintI18nWarnings() {
t.logger.Warnf("i18n|MISSING_TRANSLATION|%s|%s", currentLangStr, translationID)
}
+17 -5
View File
@@ -24,6 +24,7 @@ import (
"golang.org/x/net/html"
"github.com/gohugoio/hugo/config"
"github.com/gohugoio/hugo/helpers"
)
@@ -46,8 +47,9 @@ var (
}
)
func newHTMLElementsCollector() *htmlElementsCollector {
func newHTMLElementsCollector(conf config.BuildStats) *htmlElementsCollector {
return &htmlElementsCollector{
conf: conf,
elementSet: make(map[string]bool),
}
}
@@ -93,6 +95,8 @@ type htmlElement struct {
}
type htmlElementsCollector struct {
conf config.BuildStats
// Contains the raw HTML string. We will get the same element
// several times, and want to avoid costly reparsing when this
// is used for aggregated data only.
@@ -113,7 +117,9 @@ func (c *htmlElementsCollector) getHTMLElements() HTMLElements {
for _, el := range c.elements {
classes = append(classes, el.Classes...)
ids = append(ids, el.IDs...)
tags = append(tags, el.Tag)
if !c.conf.DisableTags {
tags = append(tags, el.Tag)
}
}
classes = helpers.UniqueStringsSorted(classes)
@@ -246,7 +252,7 @@ func (w *htmlElementsCollectorWriter) lexElementInside(resolve htmlCollectorStat
}
// Parse each collected element.
el, err := parseHTMLElement(s)
el, err := w.parseHTMLElement(s)
if err != nil {
w.err = err
return resolve
@@ -363,7 +369,8 @@ func htmlLexToEndOfComment(w *htmlElementsCollectorWriter) htmlCollectorStateFun
return htmlLexToEndOfComment
}
func parseHTMLElement(elStr string) (el htmlElement, err error) {
func (w *htmlElementsCollectorWriter) parseHTMLElement(elStr string) (el htmlElement, err error) {
conf := w.collector.conf
tagName := parseStartTag(elStr)
@@ -390,8 +397,13 @@ func parseHTMLElement(elStr string) (el htmlElement, err error) {
switch {
case strings.EqualFold(a.Key, "id"):
// There should be only one, but one never knows...
el.IDs = append(el.IDs, a.Val)
if !conf.DisableIDs {
el.IDs = append(el.IDs, a.Val)
}
default:
if conf.DisableClasses {
continue
}
if classAttrRe.MatchString(a.Key) {
el.Classes = append(el.Classes, strings.Fields(a.Val)...)
} else {
+10 -3
View File
@@ -22,6 +22,7 @@ import (
"testing"
"time"
"github.com/gohugoio/hugo/config"
"github.com/gohugoio/hugo/config/testconfig"
"github.com/gohugoio/hugo/media"
"github.com/gohugoio/hugo/minifiers"
@@ -136,7 +137,9 @@ func TestClassCollector(t *testing.T) {
} {
c.Run(fmt.Sprintf("%s--minify-%t", test.name, variant.minify), func(c *qt.C) {
w := newHTMLElementsCollectorWriter(newHTMLElementsCollector())
w := newHTMLElementsCollectorWriter(newHTMLElementsCollector(
config.BuildStats{Enable: true},
))
if variant.minify {
if skipMinifyTest[test.name] {
c.Skip("skip minify test")
@@ -240,7 +243,9 @@ func BenchmarkElementsCollectorWriter(b *testing.B) {
</html>
`
for i := 0; i < b.N; i++ {
w := newHTMLElementsCollectorWriter(newHTMLElementsCollector())
w := newHTMLElementsCollectorWriter(newHTMLElementsCollector(
config.BuildStats{Enable: true},
))
fmt.Fprint(w, benchHTML)
}
@@ -262,7 +267,9 @@ func BenchmarkElementsCollectorWriterPre(b *testing.B) {
<div class="foo"></div>
`
w := newHTMLElementsCollectorWriter(newHTMLElementsCollector())
w := newHTMLElementsCollectorWriter(newHTMLElementsCollector(
config.BuildStats{Enable: true},
))
for i := 0; i < b.N; i++ {
fmt.Fprint(w, benchHTML)
+2 -2
View File
@@ -81,8 +81,8 @@ func NewDestinationPublisher(rs *resources.Spec, outputFormats output.Formats, m
fs := rs.BaseFs.PublishFs
cfg := rs.Cfg
var classCollector *htmlElementsCollector
if rs.BuildConfig().WriteStats {
classCollector = newHTMLElementsCollector()
if rs.BuildConfig().BuildStats.Enabled() {
classCollector = newHTMLElementsCollector(rs.BuildConfig().BuildStats)
}
pub = DestinationPublisher{fs: fs, htmlElementsCollector: classCollector}
pub.min, err = minifiers.New(mediaTypes, outputFormats, cfg)
+11 -9
View File
@@ -41,6 +41,17 @@ environment:
pandoc_datadir: $SNAP/usr/share/pandoc
PYTHONHOME: /usr:$SNAP/usr
RUBYLIB: $SNAP/usr/lib/ruby/vendor_ruby/2.7.0:$SNAP/usr/lib/$SNAPCRAFT_ARCH_TRIPLET/ruby/vendor_ruby/2.7.0:$SNAP/usr/lib/ruby/vendor_ruby:$SNAP/usr/lib/ruby/2.7.0:$SNAP/usr/lib/$SNAPCRAFT_ARCH_TRIPLET/ruby/2.7.0
# HUGO_SECURITY_EXEC_OSENV
#
# Default value:
# (?i)^((HTTPS?|NO)_PROXY|PATH(EXT)?|APPDATA|TE?MP|TERM|GO\w+)$
# Bundled applications require additional access:
# git: GIT_EXEC_PATH and LD_LIBRARY_PATH
# npx: npm_config_{cache,init_module,userconfig}
# pandoc: pandoc_datadir
# rst2html: PYTHONHOME and SNAP
# asciidoctor: RUBYLIB
HUGO_SECURITY_EXEC_OSENV: (?i)^((HTTPS?|NO)_PROXY|PATH(EXT)?|APPDATA|TE?MP|TERM|GO\w+|GIT_EXEC_PATH|LD_LIBRARY_PATH|npm_config_(cache|init_module|userconfig)|pandoc_datadir|PYTHONHOME|SNAP|RUBYLIB)$
apps:
hugo:
@@ -92,15 +103,6 @@ parts:
export GOPATH=$(realpath ../go)
export PATH=$GOPATH/bin:$PATH
echo " * Patch securityConfig.go to allow"
echo " - GIT_EXEC_PATH and LD_LIBRARY_PATH to be passed to git"
echo " - npm_config_{cache,init_module,userconfig} to be passed to npx"
echo " - pandoc_datadir to be passed to pandoc"
echo " - PYTHONHOME and SNAP to be passed to rst2html"
echo " - RUBYLIB to be passed to asciidoctor"
sed -i '/OsEnv: NewWhitelist/s/)\$/|GIT_EXEC_PATH|LD_LIBRARY_PATH|npm_config_(cache|init_module|userconfig)|pandoc_datadir|PYTHONHOME|RUBYLIB|SNAP&/' config/security/securityConfig.go
git diff config/security/securityConfig.go
HUGO_BUILD_TAGS="extended"
echo " * Building hugo (HUGO_BUILD_TAGS=\"$HUGO_BUILD_TAGS\")..."
go build -v -ldflags "-X github.com/gohugoio/hugo/common/hugo.vendorInfo=snap:$(git describe --tags --always --match 'v[0-9]*' | sed 's/^v//; s/-/+git/; s/-g/./')" -tags "$HUGO_BUILD_TAGS"