Compare commits

...

721 Commits

Author SHA1 Message Date
hugoreleaser 1798bd3fd1 releaser: Bump versions for release of 0.91.2
[ci skip]
2021-12-23 15:33:33 +00:00
hugoreleaser f0b55a68ee releaser: Add release notes for 0.91.2
[ci skip]
2021-12-23 15:33:33 +00:00
Bjørn Erik Pedersen 623dda7174 Revert "config/security: Add HOME to default exec env var whitelist"
There have been one report in the wild suggesting that this needs to be tested better before doing:

https://discourse.gohugo.io/t/hugo-mod-failing-in-v0-91-1-but-works-in-v0-91-0/36180/5

This reverts commit fca266ebbb.
2021-12-23 16:23:15 +01:00
Bjørn Erik Pedersen aee9e11a40 Make sure we always create the /public folder
* Before this commit, when you had static files in the root of /content and no /public folder, that folder would not be created unless the /static syncer had already run.
* So, with a common pattern doing `rm -rf public && hugo` would the fail now and then because /static and /content are processed in parallel (unless you have cleanDestinationDir=true)
* This was even worse before commit 0b918e131f – a frozen build.

Closes #8166
2021-12-23 15:09:27 +01:00
Bjørn Erik Pedersen bd63c1aa56 Fix "stuck on build" in error situations in content processing
Updates #8166
2021-12-23 15:09:27 +01:00
Bjørn Erik Pedersen 9eb05807c6 deps: Run "go mod tidy" 2021-12-23 10:19:10 +01:00
Bjørn Erik Pedersen 654f513a4c deps: Upgrade github.com/evanw/esbuild v0.14.7 => v0.14.8 2021-12-23 10:19:10 +01:00
hugoreleaser 759cdf3fc8 releaser: Prepare repository for 0.92.0-DEV
[ci skip]
2021-12-22 16:07:34 +00:00
hugoreleaser f423505746 releaser: Bump versions for release of 0.91.1
[ci skip]
2021-12-22 15:31:05 +00:00
hugoreleaser af165d5b6d releaser: Add release notes for 0.91.1
[ci skip]
2021-12-22 15:31:05 +00:00
Bjørn Erik Pedersen 6779117f72 media: Also consider extension in FromContent
As used in `resources.GetRemote`.

This will now reject image files with text and text files with images.
2021-12-22 11:35:53 +01:00
Bjørn Erik Pedersen ce04011096 media: Add missing BMP and GIF to the default MediaTypes list 2021-12-22 11:35:53 +01:00
Bjørn Erik Pedersen cdc73526a8 media: Add PDF MIME type 2021-12-22 11:35:53 +01:00
Bjørn Erik Pedersen 425c7d90f0 deps: Update github.com/evanw/esbuild v0.14.5 => v0.14.7 2021-12-22 11:34:21 +01:00
Bjørn Erik Pedersen fca266ebbb config/security: Add HOME to default exec env var whitelist
See #9309
2021-12-22 11:33:59 +01:00
Bjørn Erik Pedersen 0016e21cd6 modules: Set GOCACHE env var
This was introduced in Go 1.15. We do set the GOPATH, which should be enough, but #9309 indicate that's not the case on every platform (GitHub Actions).

Closes #9309
2021-12-22 11:33:59 +01:00
hugoreleaser 728feaecf0 releaser: Prepare repository for 0.92.0-DEV
[ci skip]
2021-12-17 10:31:22 +00:00
hugoreleaser d1dc0e9a54 releaser: Bump versions for release of 0.91.0
[ci skip]
2021-12-17 09:50:19 +00:00
hugoreleaser 072bca69d8 releaser: Add release notes for 0.91.0
[ci skip]
2021-12-17 09:50:19 +00:00
Bjørn Erik Pedersen e26e13fbb7 releaser: Drop running tests as part of the release 2021-12-17 10:44:10 +01:00
Bjørn Erik Pedersen 6df2f080c9 docs: Regen docs helper 2021-12-17 10:31:08 +01:00
Bjørn Erik Pedersen b84745d497 tpl/resources: Add empty method mapping for GetRemote
To get auto generated documentation for it.
2021-12-17 10:30:10 +01:00
Bjørn Erik Pedersen 44954497bc Always use content to resolve content type in resources.GetRemote
This is a security hardening measure; don't trust the URL extension or any `Content-Type`/`Content-Disposition` header on its own, always look at the file content using Go's `http.DetectContentType`.

This commit also adds ttf and otf media type definitions to Hugo.

Fixes #9302
Fixes #9301
2021-12-17 09:50:28 +01:00
Bjørn Erik Pedersen 22ef5da20d Add resources.GetRemote
In Hugo 0.89 we added remote support to `resources.Get`.

In hindsight that was not a great idea, as a poll from many Hugo users showed. See Issue #9285 for more details.

After this commit `resources.Get` only supports local resource lookups. If you want to support both, you need to use a construct similar to:

Also improve some option case handling.

```
{{ resource := "" }}
{{ if (urls.Parse $url).IsAbs }}
{{ $resource = resources.GetRemote $url }}
{{ else }}
{{ $resource = resources.Get $url }}
{{ end }}
```

Fixes #9285
Fixes #9296
2021-12-17 09:33:51 +01:00
Paul Gottschling 5758c370ea Allow for return partials with falsy arguments (#9298)
Partials with returns values are parsed, then inserted into a
partial return wrapper via wrapInPartialReturnWrapper in order
to assign the return value via *contextWrapper.Set. The
predefined wrapper template for partials inserts a partial's nodes
into a "with" template action in order to set dot to a
*contextWrapper within the partial. However, because "with" is
skipped if its argument is falsy, partials with falsy arguments
were not being evaluated.

This replaces the "with" action in the partial wrapper with a
"range" action that isn't skipped if .Arg is falsy.

Fixes #7528
2021-12-17 08:35:21 +01:00
Bjørn Erik Pedersen 8ee6de6d96 deps: Upgrade github.com/evanw/esbuild v0.14.2 => v0.14.5 2021-12-17 08:26:45 +01:00
Joachim Ansorg a4b9f1a92c don't use path.Join, because it cleans the final path 2021-12-16 21:14:33 +01:00
Bjørn Erik Pedersen f4389e48ce Add some basic security policies with sensible defaults
This ommmit contains some security hardening measures for the Hugo build runtime.

There are some rarely used features in Hugo that would be good to have disabled by default. One example would be the "external helpers".

For `asciidoctor` and some others we use Go's `os/exec` package to start a new process.

These are a predefined set of binary names, all loaded from `PATH` and with a predefined set of arguments. Still, if you don't use `asciidoctor` in your project, you might as well have it turned off.

You can configure your own in the new `security` configuration section, but the defaults are configured to create a minimal amount of site breakage. And if that do happen, you will get clear instructions in the loa about what to do.

The default configuration is listed below. Note that almost all of these options are regular expression _whitelists_ (a string or a slice); the value `none` will block all.

```toml
[security]
  enableInlineShortcodes = false
  [security.exec]
    allow = ['^dart-sass-embedded$', '^go$', '^npx$', '^postcss$']
    osEnv = ['(?i)^(PATH|PATHEXT|APPDATA|TMP|TEMP|TERM)$']

  [security.funcs]
    getenv = ['^HUGO_']

  [security.http]
    methods = ['(?i)GET|POST']
    urls = ['.*']
```
2021-12-16 09:40:22 +01:00
Bjørn Erik Pedersen 803f572e66 Simplify Babel test assertions
To make the tests pass on my grand old Windows 8 VM.
2021-12-14 07:26:53 +01:00
Bjørn Erik Pedersen 6183184b96 Merge commit '45e6fdb315d113ba13e20a633ed0c67e3f25170d' 2021-12-13 21:05:10 +01:00
Bjørn Erik Pedersen 45e6fdb315 Squashed 'docs/' changes from 316cec249..4eb10c1a9
4eb10c1a9 Set a sensible maxAge on the image cache
2c37f4f89 Update lists.md
8690c018f Update introduction.md
0458c3d88 Update index.md
150982f5e Update index.md
50dc0b6b9 Update multilingual.md
648598090 Configure image cache to use :cacheDir/images
4dfb523c3 Update introduction.md
b94d42e6f Add text to social images
d3253d2aa Add resources/_gen/images/ to .gitignore
8a56e1dfd Delete resources/_gen/images
1521e79b6 Update introduction.md
c7110a597 Update introduction.md
f7c4d220f Update introduction.md
c14ecf1ff Update introduction.md
c4b388c20 Fix shortcode in hugo-pipes/introduction (#1605)
d9876bd68 Update introduction.md
a39a532d5 Update introduction.md
fa8758122 netlify: Hugo 0.90.1
50cc40570 Update Contribute to Hugo Development
fc98fc82c Add .vscode dir to .gitignore (#1602)
8f8bcdefc Add frontmatter param to code-toggle shortcode (#1601)
f3b432c7c Add markdownlint configuration file (#1597)
7ea3aea92 netlify: Bump to 0.90.0
e2b6f990b docs: Regenerate docs helper
c02259e33 Merge commit '8d9511a08f14260cbfb73119e4afae50e5a9966d'
2e3573899 Add custom font support to images.Text
3186e6458 images: Text filter that draws text with the given options (#9239)
424f219eb tpl/transform: Optional options for highlight func
7993f17d0 Implement XML data support
1eb9d34cf Make resources.Get use a file cache for remote resources
8a0fffd56 Add remote support to resources.Get

git-subtree-dir: docs
git-subtree-split: 4eb10c1a96
2021-12-13 21:04:12 +01:00
Joe Mooring a037be774d Improve handling of remote image/jpeg resources (#9278)
Add jpe, jif, and jfif to image/jpeg extensions.
For remote image/jpeg without extension, always use jpg extension.

Closes #9275
2021-12-13 08:55:15 +01:00
hitzhangjie 8a005538db Fix Dockerfile
Mage uses git, so we should install git before run mage.

Closes #9261
2021-12-12 14:45:08 +01:00
Joe Mooring 657d0272e3 Remove debug statement 2021-12-11 22:59:36 +01:00
Bjørn Erik Pedersen 159120cddd Fix deprecation notice
Asterisks needs to be quoted on command line.
2021-12-11 11:54:28 +01:00
hugoreleaser 3f0d49e502 releaser: Prepare repository for 0.91.0-DEV
[ci skip]
2021-12-10 11:42:18 +00:00
hugoreleaser 4890788974 releaser: Bump versions for release of 0.90.1
[ci skip]
2021-12-10 10:56:40 +00:00
hugoreleaser 3075eaa3b0 releaser: Add release notes for 0.90.1
[ci skip]
2021-12-10 10:56:40 +00:00
Bjørn Erik Pedersen 3bc6830411 Remove the retries on error in remote resources.Get
Fixes #9271
See  #9259
2021-12-10 11:10:41 +01:00
Bjørn Erik Pedersen e4d6ec94b5 Allow user to handle/ignore errors in resources.Get
In Hugo 0.90.0 we introduced remote support in `resources.Get`.

But with remote resources comes with a higher chance of failing a build (network issues, remote server down etc.).

Before this commit we always failed the build on any unexpected error.

This commit allows the user to check for any error (and potentially fall back to a default local resource):

```htmlbars
{{ $result := resources.Get "https://gohugo.io/img/hugo-logo.png" }}
{{ with $result }}
        {{ if .Err }}
        {{/* log the error, insert a default image etc. *}}
        {{ else }}
        <img src="{{ .RelPermalink }}" width="{{ .Width }}" height="{{ .Height }}" alt="">
        {{ end }}
{{ end }}
```

Note that the default behaviour is still to fail the build, but we will delay that error until you start using the `Resource`.

Fixes #9529
2021-12-10 11:10:41 +01:00
Bjørn Erik Pedersen 6260455ba7 Make resource.Get return nil on 404 not found
This is in line with the interface declaration and also how local lookups work.

Fixes #9267
2021-12-10 11:10:41 +01:00
Bjørn Erik Pedersen c397975af8 Update to Go 1.17.5
Fixes #9269
2021-12-10 10:36:02 +01:00
Bjørn Erik Pedersen 965a6cbff9 Update to Go 1.17.4 and remove timeout in resources.Get
Fixes #9265
2021-12-09 13:33:30 +01:00
hugoreleaser 34a96290fa releaser: Prepare repository for 0.91.0-DEV
[ci skip]
2021-12-08 10:11:31 +00:00
hugoreleaser dd0d3fdbbe releaser: Bump versions for release of 0.90.0
[ci skip]
2021-12-08 09:33:46 +00:00
hugoreleaser b921752331 releaser: Add release notes for 0.90.0
[ci skip]
2021-12-08 09:33:46 +00:00
Bjørn Erik Pedersen 0fa40ce58f releaser: Simplify the release process
Make it into a one step even for major releases.
2021-12-08 09:38:15 +01:00
Bjørn Erik Pedersen bf537f1c6d releaser: Remove unused code 2021-12-08 09:02:45 +01:00
Bjørn Erik Pedersen e86b331138 docs: Regenerate docs helper 2021-12-08 08:56:16 +01:00
Bjørn Erik Pedersen 6c841a691e Merge commit '8d9511a08f14260cbfb73119e4afae50e5a9966d' 2021-12-08 08:54:25 +01:00
Bjørn Erik Pedersen 8d9511a08f Squashed 'docs/' changes from 39a7fac34..316cec249
316cec249 Update future events template example (#1595)
3bde7d489 Install mage outside module (#1592)
762e27eff Clarify ignoreFiles regex matching
4d0032051 Add id attribute to h2 elements (#1590)
8262b077c Improve inline resource examples (#1587)
2eae7c7ec fix disqus example name (#1588)
a772f4804 Added install instructions for openSUSE Tumbleweed (#1459)
7ad1c301b Remove screen capture from Hosting on GitHub page (#1586)
a58541f49 add more details on about gh-pages and baseURL on hosting-on-github.md (#1346)
3bd0b46dc Update configuration page (#1585)
4cf1f013e Update OS functions
2c45a95c2 Remove getting-started/code-toggle/
40fdff598 Describe artificial language private use subtags (#1577)
91011d210 Remove google_news from list of internal templates (#1576)
36c7879e4 Update the .Unix function
731063488 Remove a showcase
818c371a0 Update index.md
3136d39d9 netlify: Hugo 0.89.4
092bc9278 Merge branch 'tempv0.89.4'
18e01f105 releaser: Add release notes to /docs for release of 0.89.4
79135281f Correct and sort list of target image formats (#1574)
af4170c7e netlify: Hugo 0.89.3
7f5444251 Merge branch 'tempv0.89.3'
a32e4a6c2 releaser: Add release notes to /docs for release of 0.89.3
6dd3dc3f9 Update configuration.md
5fbe741d7 Update index.md (#1570)
37a69496f netlify: Bump to Hugo 0.89.2
3b293f1f4 Merge branch 'tempv0.89.2'
64c934e7a releaser: Add release notes to /docs for release of 0.89.2
919c51c7d Update index.md
13dd463b1 netlify: Hugo 0.89.1
d8cda1474 releaser: Add release notes to /docs for release of 0.89.1
a2adf7742 releaser: Add release notes to /docs for release of 0.89.1
c3088c4fc Add code toggle to menus page (#1568)
2d0f38978 Remove blank lines from code-toggle output (#1564)
7cf058bfd Add localization examples (#1563)
cf8627c2e Fixing typos, fixing incomplete link (#1561)
c78cc014b Document the removePathAccents setting
70beddaf4 Make corrections to 0.89.0 release notes (#1560)
1917195f0 Update index.md
7fb8e070c Run hugo --gc
1772d45fb Release 0.89.0
d9006179b Merge branch 'tempv0.89.0'
8db86b61e releaser: Add release notes to /docs for release of 0.89.0
abf268571 docs: Regen CLI docs
fbbdb0ab1 Update the timeout default
9cbd1c15a Fix description of lang.FormatNumberCustom
6043b54cc Remove "render" keyword from Host on Render page
f8ea8e84f Clarify description of front matter url (#1557)
91a0c9954 Update Twitter shortcode oEmbed endpoint
79a7405b8 Merge commit 'aa5ac36a3eb68b86c803caec703869efefc8447e'
57667bae6 hugofs: Add includeFiles and excludeFiles to mount configuration
0c9ee0a04 Allow multiple plugins in the PostCSS options map
155799e6b docs: Create path.Clean documentation

git-subtree-dir: docs
git-subtree-split: 316cec2494
2021-12-08 08:42:31 +01:00
Bjørn Erik Pedersen e71d715b9b Add custom font support to images.Text
Fixes #9253
2021-12-07 16:53:02 +01:00
Bjørn Erik Pedersen e61cdf335f images: Fix cache busting of image text filter
See #9238
2021-12-07 16:53:02 +01:00
dependabot[bot] 6c3bc5ebad build(deps): bump github.com/getkin/kin-openapi from 0.80.0 to 0.85.0
Bumps [github.com/getkin/kin-openapi](https://github.com/getkin/kin-openapi) from 0.80.0 to 0.85.0.
- [Release notes](https://github.com/getkin/kin-openapi/releases)
- [Commits](https://github.com/getkin/kin-openapi/compare/v0.80.0...v0.85.0)

---
updated-dependencies:
- dependency-name: github.com/getkin/kin-openapi
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-12-07 13:12:42 +01:00
Paul van Brouwershaven 283394a4fd images: Text filter that draws text with the given options (#9239)
Fixes #9238
2021-12-07 11:29:55 +01:00
Joe Mooring 5538507e90 tpl/transform: Optional options for highlight func
Closes #9249
Fixes gohugoio/hugoDocs#63
2021-12-07 11:26:56 +01:00
Bjørn Erik Pedersen b4f27ef8e7 deps: Upgrade github.com/evanw/esbuild v0.13.12 => v0.14.2 (note)
Note: ESBuild v0.14.0 contains backwards-incompatible changes, see https://github.com/evanw/esbuild/releases/tag/v0.14.0

Fixes #9244
2021-12-04 16:28:50 +01:00
Bjørn Erik Pedersen 3473e31eb1 releaser: Add "note" to Note regexp 2021-12-04 16:27:56 +01:00
dependabot[bot] fa0da004a9 build(deps): bump github.com/mitchellh/mapstructure from 1.4.2 to 1.4.3
Bumps [github.com/mitchellh/mapstructure](https://github.com/mitchellh/mapstructure) from 1.4.2 to 1.4.3.
- [Release notes](https://github.com/mitchellh/mapstructure/releases)
- [Changelog](https://github.com/mitchellh/mapstructure/blob/master/CHANGELOG.md)
- [Commits](https://github.com/mitchellh/mapstructure/compare/v1.4.2...v1.4.3)

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

Signed-off-by: dependabot[bot] <support@github.com>
2021-12-03 18:16:50 +01:00
Bjørn Erik Pedersen 24a893cf83 releaser: Rework and simplify to use GitHub only for release notes 2021-12-03 17:02:20 +01:00
dependabot[bot] bf1564bd2c build(deps): bump google.golang.org/api from 0.51.0 to 0.61.0
Bumps [google.golang.org/api](https://github.com/googleapis/google-api-go-client) from 0.51.0 to 0.61.0.
- [Release notes](https://github.com/googleapis/google-api-go-client/releases)
- [Changelog](https://github.com/googleapis/google-api-go-client/blob/main/CHANGES.md)
- [Commits](https://github.com/googleapis/google-api-go-client/compare/v0.51.0...v0.61.0)

---
updated-dependencies:
- dependency-name: google.golang.org/api
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-12-03 17:01:37 +01:00
Paul van Brouwershaven cd44d409ba media: Add rss suffix for application/rss+xml
Closes #9233
2021-12-03 12:45:49 +01:00
Bjørn Erik Pedersen 9a326d5636 parser: Add a test case in format resolution
See #9233
2021-12-03 10:34:34 +01:00
Bjørn Erik Pedersen b10381fbe0 lazy: Reset error in Reset
To prevent sticky errors on server rebuilds.

Fixes #7043
Closes #9194
2021-12-02 18:06:19 +01:00
Paul van Brouwershaven 0eaaa8fee3 Implement XML data support
Example:

```
{{ with resources.Get "https://example.com/rss.xml" | transform.Unmarshal }}
    {{ range .channel.item }}
        <strong>{{ .title | plainify | htmlUnescape }}</strong><br />
        <p>{{ .description | plainify | htmlUnescape }}</p>
        {{ $link := .link | plainify | htmlUnescape }}
        <a href="{{ $link }}">{{ $link }}</a><br />
        <hr>
    {{ end }}
{{ end }}
```

Closes #4470
2021-12-02 17:30:36 +01:00
Joe Mooring 58adbeef88 Validate private use language tags
Fixes #9119
2021-12-02 16:30:53 +01:00
Bjørn Erik Pedersen 93572e5318 resources: Add timeout to the HTTP request in Get
Workaround for https://github.com/golang/go/issues/49366
2021-12-02 16:11:14 +01:00
Bjørn Erik Pedersen 94f149b21e Add a remote retry for resources.Get 2021-12-02 16:11:14 +01:00
Paul van Brouwershaven 66753416b5 Make resources.Get use a file cache for remote resources
Closes #9228
2021-12-02 12:56:25 +01:00
Joe Mooring 133e4bfbee Remove empty href element from pagination template
Closes #9149
2021-12-02 09:14:30 +01:00
Joe Mooring f122771fb1 Check for empty deployment targets and matchers
Fixes #9220
2021-12-01 10:17:42 +01:00
Bjørn Erik Pedersen 08a863e1e8 resources: Adjust the remote Get cache so it does not get evicted on restarts
We fill improve this, soon.
2021-11-30 16:54:01 +01:00
Paul van Brouwershaven 8aa7257f65 Add remote support to resources.Get
Closes #5255
Supports #9044
2021-11-30 11:49:51 +01:00
Joe Mooring 75a823a36a Add deprecation warning to google_news template
Closes #9172
2021-11-21 11:25:17 +01:00
Bjørn Erik Pedersen 5e0947c5b5 helpers: Make UniqueStringsReuse allocation free
This should be faster for all of our use cases (small string slices), but more important, it makes UniqueStringsReuse allocation free.

```bash
name                                 old time/op    new time/op    delta
UniqueStrings/Safe-16                   776ns ± 0%     305ns ± 0%   -60.68%  (p=0.029 n=4+4)
UniqueStrings/Reuse_slice-16            621ns ± 3%     174ns ± 0%   -72.01%  (p=0.029 n=4+4)
UniqueStrings/Reuse_slice_sorted-16     319ns ± 4%     313ns ± 0%    -2.01%  (p=0.029 n=4+4)

name                                 old alloc/op   new alloc/op   delta
UniqueStrings/Safe-16                    224B ± 0%      128B ± 0%   -42.86%  (p=0.029 n=4+4)
UniqueStrings/Reuse_slice-16            96.0B ± 0%      0.0B       -100.00%  (p=0.029 n=4+4)
UniqueStrings/Reuse_slice_sorted-16     24.0B ± 0%     24.0B ± 0%      ~     (all equal)

name                                 old allocs/op  new allocs/op  delta
UniqueStrings/Safe-16                    7.00 ± 0%      1.00 ± 0%   -85.71%  (p=0.029 n=4+4)
UniqueStrings/Reuse_slice-16             6.00 ± 0%      0.00       -100.00%  (p=0.029 n=4+4)
UniqueStrings/Reuse_slice_sorted-16      1.00 ± 0%      1.00 ± 0%      ~     (all equal)
```
2021-11-17 10:44:03 +01:00
hugoreleaser 0b70b46aad releaser: Prepare repository for 0.90.0-DEV
[ci skip]
2021-11-17 09:05:38 +00:00
hugoreleaser ab01ba6e7e releaser: Add release notes to /docs for release of 0.89.4
[ci skip]
2021-11-17 08:24:08 +00:00
hugoreleaser cc08c09592 releaser: Bump versions for release of 0.89.4
[ci skip]
2021-11-17 08:24:08 +00:00
hugoreleaser f97da9eca9 releaser: Add release notes for 0.89.4
[ci skip]
2021-11-17 08:24:08 +00:00
Bjørn Erik Pedersen 2e70f61fb0 Fix content dir resolution when main project is a Hugo Module
Fixes #9177
2021-11-16 20:42:34 +01:00
hugoreleaser 1ed8069a3a releaser: Prepare repository for 0.90.0-DEV
[ci skip]
2021-11-15 12:56:41 +00:00
hugoreleaser c88cdb5610 releaser: Add release notes to /docs for release of 0.89.3
[ci skip]
2021-11-15 12:17:45 +00:00
hugoreleaser e1064d2195 releaser: Bump versions for release of 0.89.3
[ci skip]
2021-11-15 12:17:45 +00:00
hugoreleaser bf489b96d3 releaser: Add release notes for 0.89.3
[ci skip]
2021-11-15 12:17:45 +00:00
Bjørn Erik Pedersen b8155452ac Improve error when we cannot determine content directory in "hugo new"
See #9166
2021-11-15 11:21:39 +01:00
Joe Mooring 08552a7a4c deps: Upgrade github.com/yuin/goldmark v1.4.3 => v1.4.4
Fixes #9159
2021-11-15 09:43:24 +01:00
Bjørn Erik Pedersen fdad91fd96 commands: Make sure pollInterval is always set
Fixes #9165
2021-11-13 21:45:51 +01:00
Bjørn Erik Pedersen 5f3f60898c create: Improve archetype directory discovery and tests
Updates #9146
2021-11-12 12:05:31 +01:00
Bjørn Erik Pedersen 057d02de25 create: Add a log statement when archetype is a directory
See #9157
2021-11-12 12:05:31 +01:00
Bjørn Erik Pedersen 43ac59da85 create: Always print "Content ... created"
This indeliberately changed to INFO level in Hugo 0.89.0.

Fixes #9157
2021-11-12 12:05:31 +01:00
Bjørn Erik Pedersen ab5c6990a5 commands: Fix missing file locking in server partial render
Fixes #9162
2021-11-12 09:29:04 +01:00
Patrick Kollitsch 9369d13e59 modules: Improve error message 2021-11-10 09:32:17 +01:00
hugoreleaser 805c24c32c releaser: Prepare repository for 0.90.0-DEV
[ci skip]
2021-11-08 15:56:14 +00:00
hugoreleaser 63e3a5ebb2 releaser: Add release notes to /docs for release of 0.89.2
[ci skip]
2021-11-08 15:22:23 +00:00
hugoreleaser eaa6c96a79 releaser: Bump versions for release of 0.89.2
[ci skip]
2021-11-08 15:22:23 +00:00
hugoreleaser cf3eb580bf releaser: Add release notes for 0.89.2
[ci skip]
2021-11-08 15:22:23 +00:00
Bjørn Erik Pedersen 2b01c85d14 Fix path resolution in hugo new
With theme and project with content directories and command on the form `hugo new posts/test.md`.

Fixes #9129
2021-11-08 14:10:46 +01:00
Bjørn Erik Pedersen c09f5c5fd3 deps: Upgrade github.com/yuin/goldmark v1.4.2 => v1.4.3
Fixes #9137
2021-11-08 11:54:51 +01:00
hugoreleaser 9232e28446 releaser: Prepare repository for 0.90.0-DEV
[ci skip]
2021-11-05 16:24:06 +00:00
hugoreleaser b6a4ae4ad5 releaser: Add release notes to /docs for release of 0.89.1
[ci skip]
2021-11-05 15:44:32 +00:00
hugoreleaser 84de0c3255 releaser: Bump versions for release of 0.89.1
[ci skip]
2021-11-05 15:44:32 +00:00
hugoreleaser a074102262 releaser: Add release notes for 0.89.1
[ci skip]
2021-11-05 15:44:32 +00:00
Bjørn Erik Pedersen da4406ea50 Revert "releaser: Fat MacOS binaries"
This had some side effect that I'm not prepared to fix today ...

This reverts commit 3a977485eb.

Updates #9131
Updates #9128
2021-11-05 16:31:19 +01:00
Bjørn Erik Pedersen 166862a096 create: Make sure the build lock is released before we open editor
Fixes #9121
2021-11-04 15:40:02 +01:00
Andreas Deininger 82c33c7105 readme: Update dependency list 2021-11-03 17:15:33 +01:00
hugoreleaser 41e9e9fe14 releaser: Prepare repository for 0.90.0-DEV
[ci skip]
2021-11-02 10:40:00 +00:00
hugoreleaser ade966b84b releaser: Add release notes to /docs for release of 0.89.0
[ci skip]
2021-11-02 10:00:17 +00:00
hugoreleaser a93d4ba64e releaser: Bump versions for release of 0.89.0
[ci skip]
2021-11-02 10:00:17 +00:00
hugoreleaser 110512a65c releaser: Add release notes for 0.89.0 2021-11-02 10:47:54 +01:00
Bjørn Erik Pedersen f503b63957 docs: Regen CLI docs 2021-11-02 09:01:26 +01:00
Bjørn Erik Pedersen 30aba7fb09 source: Make ContentBaseName() return the directory for branch bundles
Fixes #9112
2021-11-01 21:06:39 +01:00
Joe Mooring 04a3b45db4 Fix description of lang.FormatNumberCustom
It currently refers to itself as a simple alternative, when it should
refer to lang.FormatNumber.
2021-11-01 18:54:43 +01:00
Joe Mooring 0cc39af682 Update Twitter shortcode oEmbed endpoint
The existing endpoint will be retired and removed on November 23, 2021.
References:

- https://twittercommunity.com/t/consolidating-the-oembed-functionality/154690
- https://developer.twitter.com/en/docs/twitter-for-websites/oembed-api#Embedded

This is a backward compatible change.

The existing endpoint requires a single parameter: the id of the tweet.

The new endpoint requires two parameters: the id of the tweet, and the
user with whom it is associated. For the moment, if you supply the wrong
user, the request will be redirected (with a small delay) to the correct
user/id pair. This behavior is undocumented, but we will take advantage
of it as Hugo site authors transition to the new syntax.

{{< tweet 1453110110599868418 >}} --> works, throws warning, deprecate at some point

{{< tweet user="SanDiegoZoo" id="1453110110599868418" >}} --> new syntax

Fixes #8130
2021-11-01 15:51:00 +01:00
Bjørn Erik Pedersen ed6fd26ce8 common/htime: Fix time.Format with Go layouts
Fixes #9107
2021-11-01 15:45:59 +01:00
dependabot[bot] 7fa66425aa build(deps): bump github.com/evanw/esbuild from 0.13.10 to 0.13.12
Bumps [github.com/evanw/esbuild](https://github.com/evanw/esbuild) from 0.13.10 to 0.13.12.
- [Release notes](https://github.com/evanw/esbuild/releases)
- [Changelog](https://github.com/evanw/esbuild/blob/master/CHANGELOG.md)
- [Commits](https://github.com/evanw/esbuild/compare/v0.13.10...v0.13.12)

---
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>
2021-11-01 15:44:19 +01:00
dependabot[bot] 69210cfdf3 build(deps): bump github.com/yuin/goldmark from 1.4.1 to 1.4.2
Bumps [github.com/yuin/goldmark](https://github.com/yuin/goldmark) from 1.4.1 to 1.4.2.
- [Release notes](https://github.com/yuin/goldmark/releases)
- [Commits](https://github.com/yuin/goldmark/compare/v1.4.1...v1.4.2)

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

Signed-off-by: dependabot[bot] <support@github.com>
2021-11-01 15:43:42 +01:00
Bjørn Erik Pedersen 4b36498a85 Merge commit 'aa5ac36a3eb68b86c803caec703869efefc8447e' 2021-10-31 13:53:55 +01:00
Bjørn Erik Pedersen aa5ac36a3e Squashed 'docs/' changes from 327003421..39a7fac34
39a7fac34 Add .hugo_build.lock to .gitignore
920c716a4 fix a typo: to -> two (#1545)
6f0ba9593 Remove godocref from front matter (#1543)
8ec3d5948 remove link to wercker (#1544)
b56008719 Delete deployment-with-wercker.md (#1542)
e33d29b02 Fix broken links (#1538)
29e9d4c21 Sort commenting systems (#1541)
0b7ea60a7 Delete the news page "HTTP/2 Server Push in Hugo"
6e1515857 Fix quick-start.md (#1525)
62168ab35 Update comments.md (#1535)
d92191512 Small typo (#1539)
129c8834a Correct the PostCSS noMap default value (#1534)
6a5b29fcc Add example to index function (#1536)
e3dd8c507 Update output-formats.md
0c9321ca0 Remove reference to using LiveReload in production environment
4072d6776 Mod testing
09fabf7d6 Fix typo (#1524)
2fce813c8 Fix grammatical error in quick-start.md (#1523)
45230ab4a Hugo Mod testing
2dd4cd9e7 Update index.md
2c3ed62fd netlify: Bump to 0.88.1
648e2a007 Merge branch 'tempv0.88.1'
f216eade1 releaser: Add release notes to /docs for release of 0.88.1
8a7b64d4b Fix typographical errors in 0.88.0 release notes
a4bf86300 Release 0.88
738bb8f38 releaser: Add release notes to /docs for release of 0.88.0
8fcf2c55d highlight: Remove some pygments references
f2b173de2 HTTPS link
c88881c8e Adding link to nginx documentation
6b0a74fe0 Fix typos in docs (#1516)
498b8f0f1 Fix typos in time.Format (#1515)
28723fad6 Fix taxonomy and term examples (#1514)
3ffd00e12 Update front-matter.md
7cc1da82e Fix grammar in 0.86.1 release notes (#1510)
0009c51c3 Update docs helper
7e2f430f4 Update index.md
7857eae7e releaser: Add release notes to /docs for release of 0.87.0
1f08b684b releaser: Add release notes to /docs for release of 0.87.0
36a9e701c docs: Adjust config docs
0f588438e docs: Regen CLI docs
1b4682cd8 docs: Regen docs helper
bc8bbaae9 Merge commit 'bd77f6e1c99e04a476f0b1bb4e44569134e02399' into release-0.87.0
6f2480643 docs: Adjust time zone docs

git-subtree-dir: docs
git-subtree-split: 39a7fac343
2021-10-31 13:51:51 +01:00
Bjørn Erik Pedersen 3a977485eb releaser: Fat MacOS binaries
Fixes #9035
2021-10-31 11:30:12 +01:00
Bjørn Erik Pedersen 0f248606d5 releaser: Only build amd64 binary for freebsd, netbsd, openbsd, dragonfly
Fixes #9102
2021-10-31 10:04:01 +01:00
Bjørn Erik Pedersen e82cbd746f tpl/time: Use configured location when date passed to Format is string
Updates #9084
2021-10-30 16:09:38 +02:00
dependabot[bot] 3339c2bb61 build(deps): bump github.com/aws/aws-sdk-go from 1.40.8 to 1.41.14
Bumps [github.com/aws/aws-sdk-go](https://github.com/aws/aws-sdk-go) from 1.40.8 to 1.41.14.
- [Release notes](https://github.com/aws/aws-sdk-go/releases)
- [Changelog](https://github.com/aws/aws-sdk-go/blob/main/CHANGELOG.md)
- [Commits](https://github.com/aws/aws-sdk-go/compare/v1.40.8...v1.41.14)

---
updated-dependencies:
- dependency-name: github.com/aws/aws-sdk-go
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-10-30 11:17:12 +02:00
dependabot[bot] 03bbdba8be build(deps): bump github.com/getkin/kin-openapi from 0.79.0 to 0.80.0
Bumps [github.com/getkin/kin-openapi](https://github.com/getkin/kin-openapi) from 0.79.0 to 0.80.0.
- [Release notes](https://github.com/getkin/kin-openapi/releases)
- [Commits](https://github.com/getkin/kin-openapi/compare/v0.79.0...v0.80.0)

---
updated-dependencies:
- dependency-name: github.com/getkin/kin-openapi
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-10-30 11:16:46 +02:00
dependabot[bot] a772b8fc38 build(deps): bump github.com/evanw/esbuild from 0.13.8 to 0.13.10
Bumps [github.com/evanw/esbuild](https://github.com/evanw/esbuild) from 0.13.8 to 0.13.10.
- [Release notes](https://github.com/evanw/esbuild/releases)
- [Changelog](https://github.com/evanw/esbuild/blob/master/CHANGELOG.md)
- [Commits](https://github.com/evanw/esbuild/compare/v0.13.8...v0.13.10)

---
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>
2021-10-30 09:35:06 +02:00
Anthony Fok dce49d1333 resources: Rename excepted filenames for image golden testdata
As documented in commit 30eea3915b,
some filenames have changed due to cache busting of PNG and Webp images.

This resolves recent TestImageOperationsGolden failure on arm64, ppc64le
and s390x.

See #6387 and #8729
2021-10-30 08:47:22 +02:00
dependabot[bot] 61c5b7a2e6 build(deps): bump github.com/frankban/quicktest from 1.13.1 to 1.14.0
Bumps [github.com/frankban/quicktest](https://github.com/frankban/quicktest) from 1.13.1 to 1.14.0.
- [Release notes](https://github.com/frankban/quicktest/releases)
- [Commits](https://github.com/frankban/quicktest/compare/v1.13.1...v1.14.0)

---
updated-dependencies:
- dependency-name: github.com/frankban/quicktest
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-10-27 14:30:23 +02:00
Joe Mooring 1d60bd1efa Fix typo in error message 2021-10-26 12:59:15 +02:00
Bjørn Erik Pedersen 75c9b893d9 create: Validate the target path in hugo new
Fixes #9072
2021-10-25 19:50:18 +02:00
Bjørn Erik Pedersen 64e1613fb3 Fix panic when specifying multiple excludeFiles directives
Fixes #9076
2021-10-25 19:50:18 +02:00
satotake b959ecbc81 htime: Set zone of datetime from from go-toml
`go-toml/v2`'s unmarshaler does not specify zone name even if value has
offset explicitly.
To make time-formatting behaviour consistent, convert them into string
in hugo.

Close #8895
2021-10-25 19:49:44 +02:00
Sergio Garcia 70e454812e Added nodesource apt repository to snap package 2021-10-22 16:26:07 -06:00
Anthony Fok 355ff83e74 config: Set HUGO_ENABLEGITINFO=false override in Set_in_string
This allows TestLoadConfigWithOsEnvOverrides/Set_in_string to PASS
even if there is no .git directory, e.g. during Debian package build.
2021-10-22 19:40:18 +02:00
Bjørn Erik Pedersen 471ed91c60 hugofs: Add includeFiles and excludeFiles to mount configuration
Fixes #9042
2021-10-20 05:00:17 +02:00
dependabot[bot] 94a5bac5b2 build(deps): bump github.com/mitchellh/mapstructure from 1.4.1 to 1.4.2
Bumps [github.com/mitchellh/mapstructure](https://github.com/mitchellh/mapstructure) from 1.4.1 to 1.4.2.
- [Release notes](https://github.com/mitchellh/mapstructure/releases)
- [Changelog](https://github.com/mitchellh/mapstructure/blob/master/CHANGELOG.md)
- [Commits](https://github.com/mitchellh/mapstructure/compare/v1.4.1...v1.4.2)

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

Signed-off-by: dependabot[bot] <support@github.com>
2021-10-20 04:17:44 +02:00
Bjørn Erik Pedersen 9830ca9e31 resources: Always preserve the original transform error 2021-10-19 20:38:38 +02:00
itsAftabAlam b64fd0577b readme: Add hyperlink to the banner 2021-10-19 15:59:12 +02:00
dependabot[bot] 2706437a7d build(deps): bump github.com/getkin/kin-openapi from 0.78.0 to 0.79.0
Bumps [github.com/getkin/kin-openapi](https://github.com/getkin/kin-openapi) from 0.78.0 to 0.79.0.
- [Release notes](https://github.com/getkin/kin-openapi/releases)
- [Commits](https://github.com/getkin/kin-openapi/compare/v0.78.0...v0.79.0)

---
updated-dependencies:
- dependency-name: github.com/getkin/kin-openapi
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-10-19 15:35:31 +02:00
Bjørn Erik Pedersen ec7c993cfe deps: github.com/evanw/esbuild v0.13.5 => v0.13.8 2021-10-19 15:33:29 +02:00
Bjørn Erik Pedersen 32c6f656d9 create: Return error on no content dirs
Closes #9056
2021-10-19 08:08:21 +02:00
Bjørn Erik Pedersen e02e0727e5 Fix file permissions in new archetype implementation
Closes #9057
2021-10-18 19:08:19 +02:00
Bjørn Erik Pedersen 096f5e1921 Fix the "page picker" logic in --navigateToChanged
Fixes #9051
2021-10-18 12:13:13 +02:00
Bjørn Erik Pedersen ba35e69856 Add a cross process build lock and use it in the archetype content builder
Fixes #9048
2021-10-18 12:13:13 +02:00
nabbisen c7957c90e8 readme: Fix a typo on OpenBSD 2021-10-17 21:23:01 +02:00
Bjørn Erik Pedersen bb05377033 deps: github.com/alecthomas/chroma v0.9.2 => v0.9.4
Fixes #8532
2021-10-17 17:14:03 +02:00
Bjørn Erik Pedersen 9185e11eff Reimplement archetypes
The old implementation had some issues, mostly related to the context (e.g. name, file paths) passed to the template.

This new implementation is using the exact same code path for evaluating the pages as in a regular build.

This also makes it more robust and easier to reason about in a multilingual setup.

Now, if you are explicit about the target path, Hugo will now always pick the correct mount and language:

```bash
hugo new content/en/posts/my-first-post.md
```

Fixes #9032
Fixes #7589
Fixes #9043
Fixes #9046
Fixes #9047
2021-10-16 15:22:03 +02:00
dependabot[bot] 168a3aab46 build(deps): bump github.com/tdewolff/minify/v2 from 2.9.21 to 2.9.22
Bumps [github.com/tdewolff/minify/v2](https://github.com/tdewolff/minify) from 2.9.21 to 2.9.22.
- [Release notes](https://github.com/tdewolff/minify/releases)
- [Commits](https://github.com/tdewolff/minify/compare/v2.9.21...v2.9.22)

---
updated-dependencies:
- dependency-name: github.com/tdewolff/minify/v2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-10-14 10:40:23 +02:00
Bjørn Erik Pedersen 8bcfa3bdf6 deps: Update github.com/evanw/esbuild v0.13.5 2021-10-14 10:25:42 +02:00
Iskander (Alex) Sharipov d7331aaa7e releaser: Fix regexp
Original regexp used a char class which caused the regexp to only
check 1 symbol instead of a substring like "See" and "Closes".
So it would match `e #x` instead of `See #x` and many other
weird combinations.

Tests were passing as they never checked against an input that
would confuse that regexp.

Found with go-critic static analyzer, `badRegexp` checker.
2021-10-12 11:32:09 +02:00
dependabot[bot] cd4e67af18 build(deps): bump github.com/mattn/go-isatty from 0.0.13 to 0.0.14
Bumps [github.com/mattn/go-isatty](https://github.com/mattn/go-isatty) from 0.0.13 to 0.0.14.
- [Release notes](https://github.com/mattn/go-isatty/releases)
- [Commits](https://github.com/mattn/go-isatty/compare/v0.0.13...v0.0.14)

---
updated-dependencies:
- dependency-name: github.com/mattn/go-isatty
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-10-10 20:45:38 +02:00
dependabot[bot] e6ad1f0e76 build(deps): bump github.com/getkin/kin-openapi from 0.75.0 to 0.78.0
Bumps [github.com/getkin/kin-openapi](https://github.com/getkin/kin-openapi) from 0.75.0 to 0.78.0.
- [Release notes](https://github.com/getkin/kin-openapi/releases)
- [Commits](https://github.com/getkin/kin-openapi/compare/v0.75.0...v0.78.0)

---
updated-dependencies:
- dependency-name: github.com/getkin/kin-openapi
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-10-10 20:30:52 +02:00
Bjørn Erik Pedersen 625d2c257a releaser: Update to Go go1.17.2
* This now uses the `golang:1.17.2-buster` Docker image which runs GLIBC 2.28-10.
* Also added a build hook to warn us if this happens again in the future.

Fixes #8955
2021-10-10 16:53:44 +02:00
Joe Mooring e6e44b7c41 Fix value of useResourceCacheWhen in TestResourceChainPostCSS 2021-10-10 11:12:01 +02:00
Joe Mooring 64abc83fc4 Allow multiple plugins in the PostCSS options map
Usage:
{{ $options := dict "use" "autoprefixer postcss-color-alpha" }}
{{ $style := resources.Get "main.css" | resources.PostCSS $options }}

Fixes #9015
2021-10-10 11:11:43 +02:00
Joe Mooring f8d132d731 docs: Create path.Clean documentation
Related to #9005
2021-10-09 20:36:57 +02:00
Bjørn Erik Pedersen 26f1919ae0 Skip a test assertion on CI
Need to investigate later, but got to get the tests green.
2021-10-09 20:36:32 +02:00
Brad e55466ce70 tpl/path: Add path.Clean
Fixes #8885
2021-10-05 16:15:10 +02:00
Shalabh Kamboj ecf025f006 readme: Remove tracking image
The server for the tracking image for analytics is currently down,
therefore I found it convenient to remove the link in order to maintain our readme
2021-10-05 15:09:11 +02:00
digitalcraftsman fab1e43de5 Revert "Remove credit from release notes"
See b2eaf4c8c2
2021-09-23 14:02:00 +02:00
Paul Gottschling e03f82eef2 Pass minification errors to the user
Previously, *minifyTransformation.Transform suppressed the
error returned by t.m.Minify. This meant that when minification
returned an error, the error would not reach the user. Instead,
minification would silently fail. For example, if a JavaScript
file included a call to the Date constructor with:

new Date(2020, 04, 02)

The package that the minification library uses to parse JS files,
github.com/tdewolff/parse would return an error, since "04" would
be parsed as a legacy octal. However, the JS file would remain
un-minified with no error.

Fixing this is not as simple as replacing "_" with an "err" in
*minifyTransformation.Transform, however (though this is
necessary). If we only returned this error from Transform,
then hugolib.TestResourceMinifyDisabled would fail. Instead of
being a no-op, as TestResourceMinifyDisabled expects, using the
"minify" template function with a "disableXML=true" config
setting instead returns the error, "minifier does not exist for
mimetype."

The "minifier does not exist" error is returned because of the
way minifiers.New works. If the user's config disables
minification for a particular MIME type, minifiers.New does
not add it to the resulting Client's *minify.M. However, this
also means that when the "minify" template function is executed,
 a *resourceAdapter's transformations still add a minification.
When it comes time to call the minify.Minifier for a specific
MIME type via *M.MinifyMimetype, the github.com/tdewolff/minify
library throws the "does not exist" error for the missing MIME
type.

The solution was to change minifiers.New so, instead of skipping
a minifier for each disabled MIME type, it adds  a NoOpMinifier,
which simply copies the source to the destination without
minification. This means that when the "minify" template
function is used for a particular resource, and that resource's
MIME type has minification disabled, minification is genuinely
skipped, and does not result in an error.

In order to add this, I've fixed a possibly unwanted interaction
between minifiers.TestConfigureMinify and
hugolib.TestResourceMinifyDisabled. The latter disables
minification and expects minification to be a no-op. The former
disables minification and expects it to result in an error. The
only reason hugolib.TestResourceMinifyDisabled passes in the
original code is that the "does not exist" error is suppressed.
However, we shouldn't suppress minification errors, since they
can leave users perplexed. I've changed the test assertion in
minifiers.TestConfigureMinify to expect no errors and a no-op
if minification is disabled for a particular MIME type.

Fixes #8954
2021-09-22 20:54:40 +02:00
Paul Gottschling a864ffe9ac Clarify "precision" in currency format functions
The documentation of the FormatAccounting and FormatCurrency
functions could be clearer in terms of how the precision param
works. This commit makes it more explicit that adding a precision
of < 2 will not format the return values to include fewer decimals.

Resolves #8858
2021-09-22 20:00:30 +02:00
dependabot[bot] b49da33280 build(deps): bump github.com/evanw/esbuild from 0.12.24 to 0.12.29
Bumps [github.com/evanw/esbuild](https://github.com/evanw/esbuild) from 0.12.24 to 0.12.29.
- [Release notes](https://github.com/evanw/esbuild/releases)
- [Changelog](https://github.com/evanw/esbuild/blob/master/CHANGELOG.md)
- [Commits](https://github.com/evanw/esbuild/compare/v0.12.24...v0.12.29)

---
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>
2021-09-22 20:00:05 +02:00
Emmanuel T Odeke 7c21eca74f resources: Use default math/rand.Source for concurrency safety
The source from NewSource is documented not to be safe for
concurrency, and instead use the eefault source which is documented
as safe.

Fixes #8981
2021-09-19 12:18:30 +02:00
Bjørn Erik Pedersen 13ad8408fc commands: Make the error handling for the mod commands more lenient
So it at least is possible to do a `hugo mod clean --all` if the cache is in a funky state.
2021-09-17 17:16:34 +02:00
Bjørn Erik Pedersen 1cabf61ddf modules: Add some help text to the 'unknown revision' error
I had a head scratching moment with this myself, so it's safe to say that others will.

See #6825
2021-09-17 09:34:35 +02:00
Joe Mooring 268e3069f3 deps: Update github.com/yuin/goldmark v1.4.0 => v1.4.1
Fixes #8855
2021-09-12 21:55:37 +02:00
hugoreleaser 3efc2e2af8 releaser: Prepare repository for 0.89.0-DEV
[ci skip]
2021-09-04 10:33:09 +00:00
hugoreleaser 5bc547389a releaser: Add release notes to /docs for release of 0.88.1
[ci skip]
2021-09-04 09:39:19 +00:00
hugoreleaser bb3254385a releaser: Bump versions for release of 0.88.1
[ci skip]
2021-09-04 09:39:19 +00:00
hugoreleaser 9b1d6d7e30 releaser: Add release notes for 0.88.1
[ci skip]
2021-09-04 09:39:19 +00:00
Bjørn Erik Pedersen e1ead4dbca Bump down again to Go 1.16.7 for the release builds
Note that this commit has nothing to do with "Hugo not working with Go 1.17", but this is the simplest fix of some build related issues in Hugo 0.88.0.

Updates #8952
Updates #8955
2021-09-04 11:22:51 +02:00
hugoreleaser 5b59b9c171 releaser: Prepare repository for 0.89.0-DEV
[ci skip]
2021-09-02 09:57:36 +00:00
hugoreleaser acc5eb5b51 releaser: Add release notes to /docs for release of 0.88.0
[ci skip]
2021-09-02 09:27:27 +00:00
hugoreleaser 6cacfa329c releaser: Bump versions for release of 0.88.0
[ci skip]
2021-09-02 09:27:27 +00:00
Bjørn Erik Pedersen 4d03cd780e Release 0.88.0 2021-09-02 11:11:08 +02:00
Bjørn Erik Pedersen 8b14fdbf89 Update 0.88.0-relnotes.md
[ci skip]
2021-09-02 11:10:40 +02:00
hugoreleaser fc21b63b46 releaser: Add release notes for 0.88.0
Rename to *-ready.md to continue.
[ci skip]
2021-09-02 08:09:25 +00:00
Bjørn Erik Pedersen 6631c9c7e0 Run go mod tidy 2021-09-01 10:48:13 +02:00
Bjørn Erik Pedersen cf73cc2ece js: Fix import order for ./foo when both ./foo.js and ./foo/index.js exists
This is in line with how both Node and ESBuild's native import resolver does it.

The ambiguous situations above were discovered trying to build AlpineJS v3.

Note that the above was never an issue if you used `./foo.js` and similar to import the component.

Fixes #8945
2021-09-01 10:47:41 +02:00
Bjørn Erik Pedersen 7d1f806ecb commands: Don't fail on template errors on go mod graph etc.
Fixes #8942
2021-08-31 22:16:12 +02:00
dependabot[bot] 04b5959961 build(deps): bump github.com/getkin/kin-openapi from 0.74.0 to 0.75.0
Bumps [github.com/getkin/kin-openapi](https://github.com/getkin/kin-openapi) from 0.74.0 to 0.75.0.
- [Release notes](https://github.com/getkin/kin-openapi/releases)
- [Commits](https://github.com/getkin/kin-openapi/compare/v0.74.0...v0.75.0)

---
updated-dependencies:
- dependency-name: github.com/getkin/kin-openapi
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-08-31 12:11:39 +02:00
dependabot[bot] c278b6e45d build(deps): bump github.com/frankban/quicktest from 1.13.0 to 1.13.1
Bumps [github.com/frankban/quicktest](https://github.com/frankban/quicktest) from 1.13.0 to 1.13.1.
- [Release notes](https://github.com/frankban/quicktest/releases)
- [Commits](https://github.com/frankban/quicktest/compare/v1.13.0...v1.13.1)

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

Signed-off-by: dependabot[bot] <support@github.com>
2021-08-31 12:11:08 +02:00
dependabot[bot] 107c86febb build(deps): bump github.com/evanw/esbuild from 0.12.22 to 0.12.24
Bumps [github.com/evanw/esbuild](https://github.com/evanw/esbuild) from 0.12.22 to 0.12.24.
- [Release notes](https://github.com/evanw/esbuild/releases)
- [Changelog](https://github.com/evanw/esbuild/blob/master/CHANGELOG.md)
- [Commits](https://github.com/evanw/esbuild/compare/v0.12.22...v0.12.24)

---
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>
2021-08-31 12:10:32 +02:00
Bjørn Erik Pedersen a0489c2dfd Avoid failing with "module not found" for hugo mod init and similar
Fixes #8940
2021-08-31 12:08:11 +02:00
Bjørn Erik Pedersen 0fc2ce9e4b Update to Go 1.17
Go 1.17 now lazy-loads dependencies when `go.mod` is version `go17`. This does not work for us for new projects started with `hugo mod init`.

Before this commit, starting a project with Go 1.17 with `hugo mod init` and then start adding dependencies with transitive dependenies to `config.toml` would treat the transitive dependencies as new, and you would potentially get a too recent version of those.

Note that this does not effect existing projects, where all dependencies are already recorded in `go.mod`.

Fixes #8930
2021-08-31 11:19:51 +02:00
Anthony Fok 32569285c1 Remove Pygments from snapcraft.yml
Pygments support was removed in Hugo v0.60.0
2021-08-25 10:43:32 -06:00
Bjørn Erik Pedersen 5a46eefbc6 Revert "build(deps): bump github.com/fsnotify/fsnotify from 1.4.9 to 1.5.0"
This reverts commit f70165242b.

Closes #8920
2021-08-23 18:20:29 +02:00
Helder Pereira 7a15edafe2 highlight: Add tabindex when code is not highlighted 2021-08-23 12:28:45 +02:00
dependabot[bot] 2f0945bafe build(deps): bump github.com/evanw/esbuild from 0.12.17 to 0.12.22
Bumps [github.com/evanw/esbuild](https://github.com/evanw/esbuild) from 0.12.17 to 0.12.22.
- [Release notes](https://github.com/evanw/esbuild/releases)
- [Changelog](https://github.com/evanw/esbuild/blob/master/CHANGELOG.md)
- [Commits](https://github.com/evanw/esbuild/compare/v0.12.17...v0.12.22)

---
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>
2021-08-22 13:58:10 +02:00
Bjørn Erik Pedersen f4ffeea71d Fix it so disableKinds etc. does not get merged in from theme
Unless the merge strategy is set up to do so.

For `disableKinds` the current workaround is to make sure the project config has an entry, even if is empty:

```
disableKinds = []
```

Note that this issue only touches root, non-map config-values that either is not set in project config or in Hugo's defaults.

Fixes #8866
2021-08-22 13:25:20 +02:00
dependabot[bot] 7ba3f3d201 build(deps): bump golang.org/x/text from 0.3.6 to 0.3.7
Bumps [golang.org/x/text](https://github.com/golang/text) from 0.3.6 to 0.3.7.
- [Release notes](https://github.com/golang/text/releases)
- [Commits](https://github.com/golang/text/compare/v0.3.6...v0.3.7)

---
updated-dependencies:
- dependency-name: golang.org/x/text
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-08-22 12:52:31 +02:00
dependabot[bot] f70165242b build(deps): bump github.com/fsnotify/fsnotify from 1.4.9 to 1.5.0
Bumps [github.com/fsnotify/fsnotify](https://github.com/fsnotify/fsnotify) from 1.4.9 to 1.5.0.
- [Release notes](https://github.com/fsnotify/fsnotify/releases)
- [Changelog](https://github.com/fsnotify/fsnotify/blob/master/CHANGELOG.md)
- [Commits](https://github.com/fsnotify/fsnotify/compare/v1.4.9...v1.5.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2021-08-22 12:52:04 +02:00
Bjørn Erik Pedersen bc0743ed8e Prevent minifier from removing quoutes around post-processed attributes
Fixes #8884
2021-08-22 12:47:47 +02:00
Bjørn Erik Pedersen ffa2fe6117 Revert "commands: Avoid too many watch file handles causing the server to fail to start"
This reverts commit 3f38c785b7.
2021-08-21 16:32:20 +02:00
Helder Pereira d966f5d08d highlight: Remove some pygments references 2021-08-21 15:50:49 +02:00
Shiming Zhang 3f38c785b7 commands: Avoid too many watch file handles causing the server to fail to start
Fixes #8904
2021-08-19 11:04:09 +02:00
dependabot[bot] 24589c0814 build(deps): bump github.com/getkin/kin-openapi from 0.68.0 to 0.74.0
Bumps [github.com/getkin/kin-openapi](https://github.com/getkin/kin-openapi) from 0.68.0 to 0.74.0.
- [Release notes](https://github.com/getkin/kin-openapi/releases)
- [Commits](https://github.com/getkin/kin-openapi/compare/v0.68.0...v0.74.0)

---
updated-dependencies:
- dependency-name: github.com/getkin/kin-openapi
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-08-17 10:50:10 +02:00
Bjørn Erik Pedersen efebd756eb deps: Update github.com/spf13/cast v1.4.0 => v1.4.1
Closes #8891
2021-08-16 09:16:41 +02:00
Bjørn Erik Pedersen 58b6742cfe Import time/tzdata on Windows
Updates #8892
2021-08-14 12:09:41 +02:00
Bjørn Erik Pedersen 32ead4b1e7 releaser: Bump to Go 1.16.7 2021-08-10 14:00:49 +02:00
Bjørn Erik Pedersen abd969a670 Revert "tpl/time: Handle nil values in time.AsTime"
This reverts commit 3e11072892.
2021-08-10 13:21:49 +02:00
Bjørn Erik Pedersen 3e11072892 tpl/time: Handle nil values in time.AsTime
Closes #8865
2021-08-09 18:44:35 +02:00
Bjørn Erik Pedersen 9bba9a3a98 parser: Indent TOML tables
Fixes #8850
2021-08-04 11:39:16 +02:00
Salim B d6c8cd7718 Fix lang.FormatPercent description
Successor PR for https://github.com/gohugoio/hugoDocs/pull/1504
2021-08-03 16:56:06 +02:00
hugoreleaser dfe54d3216 releaser: Prepare repository for 0.88.0-DEV
[ci skip]
2021-08-03 12:11:56 +00:00
hugoreleaser b0c541e496 releaser: Add release notes to /docs for release of 0.87.0
[ci skip]
2021-08-03 10:57:26 +00:00
hugoreleaser 2ed7be295c releaser: Bump versions for release of 0.87.0
[ci skip]
2021-08-03 10:57:26 +00:00
Bjørn Erik Pedersen d9d1ef8b07 Release 0.87 2021-08-03 12:42:22 +02:00
Bjørn Erik Pedersen ec1c1c3459 Merge branch 'b087' into release-0.87.0 2021-08-03 12:38:58 +02:00
Bjørn Erik Pedersen c7fd134625 Update 0.87.0-relnotes.md
[ci skip]
2021-08-03 12:31:41 +02:00
Bjørn Erik Pedersen a5d2632ebb Update 0.87.0-relnotes.md
[ci skip]
2021-08-03 12:30:42 +02:00
Bjørn Erik Pedersen 494f284be3 docs: Adjust config docs 2021-08-03 12:22:02 +02:00
Bjørn Erik Pedersen bf738d2f43 docs: Regen CLI docs 2021-08-03 11:55:02 +02:00
Bjørn Erik Pedersen 8d19850e2d docs: Regen docs helper 2021-08-03 11:53:34 +02:00
Bjørn Erik Pedersen 0934983529 Merge commit 'bd77f6e1c99e04a476f0b1bb4e44569134e02399' into release-0.87.0 2021-08-03 11:52:57 +02:00
Bjørn Erik Pedersen bd77f6e1c9 Squashed 'docs/' changes from 60a58d123..327003421
327003421 Update index.md
cafdccc13 Hugo 0.86.1
467a89a02 Merge branch 'v0861'
a22c37bc9 Merge branch 'release-0.86.1'
276da91a8 releaser: Add release notes to /docs for release of 0.86.1
198cdf8f0 tpl/lang: Add new localized versions of lang.FormatNumber etc.
93f986ecc Add timezone support for front matter dates without one
b30b876bb Localize time.Format
950fdab90 Fix AddDate documentation
78d7b52b6 Document config.cascade
fd1e1e4b7 Fix grammar and spelling (#1497)
05bf3aa32 Fix grammar / typos in news
32060a3b4 One more try
f6e24ddfa PNG to JPG for the rel notes image
9ec5bdfad Update index.md
5f5d7f69d Release Hugo 0.86.0
2dd60bb71 releaser: Add release notes to /docs for release of 0.86.0
6445fb36c Merge commit '53a352795a69a9d4a373f50ec62138595948c6ea'
cb57ca73a Simplify "active menu" logic for section menus

git-subtree-dir: docs
git-subtree-split: 327003421d
2021-08-03 11:51:36 +02:00
Bjørn Erik Pedersen 1c5b025dd0 docs: Adjust time zone docs 2021-08-03 11:51:28 +02:00
hugoreleaser c13d33dd5e releaser: Add release notes for 0.87.0
Rename to *-ready.md to continue.
[ci skip]
2021-08-03 08:45:16 +00:00
Bjørn Erik Pedersen d70c485707 Make sure module config loading errors have file positioning info
Fixes #8845
2021-08-03 09:57:14 +02:00
Bjørn Erik Pedersen 9ff17c3324 tpl/time: Adjust tests to handle matching local time zones
Closes #8843
2021-08-03 08:54:45 +02:00
Bjørn Erik Pedersen 7aaaf7e33a mod: Remove superflous replace statement 2021-08-02 20:33:13 +02:00
Bjørn Erik Pedersen 3a96655592 Reduce binary size vs locale, update to CLDR v36.1
Test building with `go build -ldflags="-s -w"`

Hugo 0.86.2: 46MB
Before this commit: 77MB
After this commit: 54MB

Fixes #8839
Fixes #8841
2021-08-02 19:40:32 +02:00
Joe Mooring 9a7383caf3 deps: Update github.com/tdewolff/minify/v2 v2.9.20 => v2.9.21
Closes #8831
2021-08-02 17:27:07 +02:00
Bjørn Erik Pedersen 6c70e1f22f Fix error handling for the time func alias
Fixes #8835
2021-08-01 13:39:30 +02:00
Bjørn Erik Pedersen 4d221ce468 Fail on invalid time zone
Fixes #8832
2021-08-01 13:39:30 +02:00
Bjørn Erik Pedersen e3dc5240f0 Improve handling of <nil> Params
Fixes #8825
2021-07-30 21:07:52 +02:00
Bjørn Erik Pedersen 268065cb2d Merge branch 'release-0.86.1' 2021-07-30 12:58:26 +02:00
hugoreleaser e0304c06ed releaser: Add release notes for 0.86.1
[ci skip]
2021-07-30 12:58:03 +02:00
hugoreleaser 7aa8b1cd7d releaser: Prepare repository for 0.87.0-DEV
[ci skip]
2021-07-30 10:54:50 +00:00
hugoreleaser f6821b88ab releaser: Add release notes to /docs for release of 0.86.1
[ci skip]
2021-07-30 10:13:32 +00:00
hugoreleaser 580d320a66 releaser: Bump versions for release of 0.86.1
[ci skip]
2021-07-30 10:13:32 +00:00
hugoreleaser b75d4526e4 releaser: Add release notes for 0.86.1
[ci skip]
2021-07-30 10:13:32 +00:00
Bjørn Erik Pedersen 94b616bdfa config: Fix a potential deadlock in config reading
Note that the deadlock has not been seen earlier, in tests on in real Hugo sites.

Fixes #8791
2021-07-30 11:53:27 +02:00
dependabot[bot] e90b3591a1 build(deps): bump github.com/evanw/esbuild from 0.12.16 to 0.12.17
Bumps [github.com/evanw/esbuild](https://github.com/evanw/esbuild) from 0.12.16 to 0.12.17.
- [Release notes](https://github.com/evanw/esbuild/releases)
- [Changelog](https://github.com/evanw/esbuild/blob/master/CHANGELOG.md)
- [Commits](https://github.com/evanw/esbuild/compare/v0.12.16...v0.12.17)

---
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>
2021-07-30 11:11:10 +02:00
dependabot[bot] 4b7da6a9d7 build(deps): bump github.com/getkin/kin-openapi from 0.67.0 to 0.68.0
Bumps [github.com/getkin/kin-openapi](https://github.com/getkin/kin-openapi) from 0.67.0 to 0.68.0.
- [Release notes](https://github.com/getkin/kin-openapi/releases)
- [Commits](https://github.com/getkin/kin-openapi/compare/v0.67.0...v0.68.0)

---
updated-dependencies:
- dependency-name: github.com/getkin/kin-openapi
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-07-30 11:10:45 +02:00
Bjørn Erik Pedersen 7907d24ba1 tpl/lang: Add new localized versions of lang.FormatNumber etc.
Fixes #8820
2021-07-29 16:40:06 +02:00
Bjørn Erik Pedersen 726fe9c3c9 Go back to WARNING for Page deprecations
Do that in the next release, let's reduce the noise, we have enough changes as it is.
2021-07-29 16:18:38 +02:00
Bjørn Erik Pedersen b5de37ee79 Handle toml.LocalDate and toml.LocalDateTime in front matter
See #8801
2021-07-28 18:02:42 +02:00
Bjørn Erik Pedersen bf301daf15 deps: Upgrade github.com/pelletier/go-toml/v2 v2.0.0-beta.3 => v2.0.0-beta.3.0.20210727221244-fa0796069526 2021-07-28 17:27:31 +02:00
Bjørn Erik Pedersen a3701e0931 Switch to go-toml v2
We have been using `go-toml` for language files only. This commit makes it the only TOML library.

It's spec compliant and very fast.

A benchark building a site with 200 pages with TOML front matter:

```bash
name                                  old time/op    new time/op    delta
SiteNew/Regular_TOML_front_matter-16    48.5ms ± 1%    47.1ms ± 1%  -2.85%  (p=0.029 n=4+4)

name                                  old alloc/op   new alloc/op   delta
SiteNew/Regular_TOML_front_matter-16    16.9MB ± 0%    16.7MB ± 0%  -1.56%  (p=0.029 n=4+4)

name                                  old allocs/op  new allocs/op  delta
SiteNew/Regular_TOML_front_matter-16      302k ± 0%      296k ± 0%  -2.20%  (p=0.029 n=4+4)
```

Note that the front matter unmarshaling is only a small part of building a site, so the above is very good.

Fixes #8801
2021-07-28 11:51:13 +02:00
dependabot[bot] 40b6016cf3 build(deps): bump github.com/tdewolff/minify/v2 from 2.9.19 to 2.9.20
Bumps [github.com/tdewolff/minify/v2](https://github.com/tdewolff/minify) from 2.9.19 to 2.9.20.
- [Release notes](https://github.com/tdewolff/minify/releases)
- [Commits](https://github.com/tdewolff/minify/compare/v2.9.19...v2.9.20)

---
updated-dependencies:
- dependency-name: github.com/tdewolff/minify/v2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-07-28 11:21:50 +02:00
Bjørn Erik Pedersen 7e1305710f Add a TOML front matter benchmark 2021-07-27 19:27:54 +02:00
Bjørn Erik Pedersen efa5760db5 Add timezone support for front matter dates without one
Fixes #8810
2021-07-27 19:02:48 +02:00
Bjørn Erik Pedersen a57dda854b Localize time.Format
Fixes #8797
2021-07-27 19:02:48 +02:00
dependabot[bot] f9afba9335 build(deps): bump github.com/getkin/kin-openapi from 0.61.0 to 0.67.0
Bumps [github.com/getkin/kin-openapi](https://github.com/getkin/kin-openapi) from 0.61.0 to 0.67.0.
- [Release notes](https://github.com/getkin/kin-openapi/releases)
- [Commits](https://github.com/getkin/kin-openapi/compare/v0.61.0...v0.67.0)

---
updated-dependencies:
- dependency-name: github.com/getkin/kin-openapi
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-07-27 16:25:09 +02:00
dependabot[bot] a5d2ba429d build(deps): bump github.com/spf13/cast from 1.3.1 to 1.4.0
Bumps [github.com/spf13/cast](https://github.com/spf13/cast) from 1.3.1 to 1.4.0.
- [Release notes](https://github.com/spf13/cast/releases)
- [Commits](https://github.com/spf13/cast/compare/v1.3.1...v1.4.0)

---
updated-dependencies:
- dependency-name: github.com/spf13/cast
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-07-27 15:37:30 +02:00
dependabot[bot] 31972f3647 build(deps): bump google.golang.org/api from 0.45.0 to 0.51.0
Bumps [google.golang.org/api](https://github.com/googleapis/google-api-go-client) from 0.45.0 to 0.51.0.
- [Release notes](https://github.com/googleapis/google-api-go-client/releases)
- [Changelog](https://github.com/googleapis/google-api-go-client/blob/master/CHANGES.md)
- [Commits](https://github.com/googleapis/google-api-go-client/compare/v0.45.0...v0.51.0)

---
updated-dependencies:
- dependency-name: google.golang.org/api
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-07-27 15:04:20 +02:00
dependabot[bot] 2e58782f96 build(deps): bump github.com/sanity-io/litter from 1.5.0 to 1.5.1
Bumps [github.com/sanity-io/litter](https://github.com/sanity-io/litter) from 1.5.0 to 1.5.1.
- [Release notes](https://github.com/sanity-io/litter/releases)
- [Changelog](https://github.com/sanity-io/litter/blob/main/CHANGELOG.md)
- [Commits](https://github.com/sanity-io/litter/compare/v1.5.0...v1.5.1)

---
updated-dependencies:
- dependency-name: github.com/sanity-io/litter
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-07-27 15:01:24 +02:00
dependabot[bot] 7b68f6524d build(deps): bump github.com/mattn/go-isatty from 0.0.12 to 0.0.13
Bumps [github.com/mattn/go-isatty](https://github.com/mattn/go-isatty) from 0.0.12 to 0.0.13.
- [Release notes](https://github.com/mattn/go-isatty/releases)
- [Commits](https://github.com/mattn/go-isatty/compare/v0.0.12...v0.0.13)

---
updated-dependencies:
- dependency-name: github.com/mattn/go-isatty
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-07-27 14:58:39 +02:00
dependabot[bot] 81265af2cc build(deps): bump github.com/spf13/cobra from 1.1.3 to 1.2.1
Bumps [github.com/spf13/cobra](https://github.com/spf13/cobra) from 1.1.3 to 1.2.1.
- [Release notes](https://github.com/spf13/cobra/releases)
- [Changelog](https://github.com/spf13/cobra/blob/master/CHANGELOG.md)
- [Commits](https://github.com/spf13/cobra/compare/v1.1.3...v1.2.1)

---
updated-dependencies:
- dependency-name: github.com/spf13/cobra
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-07-27 14:05:28 +02:00
dependabot[bot] c102c9719b build(deps): bump github.com/mitchellh/mapstructure from 1.3.3 to 1.4.1
Bumps [github.com/mitchellh/mapstructure](https://github.com/mitchellh/mapstructure) from 1.3.3 to 1.4.1.
- [Release notes](https://github.com/mitchellh/mapstructure/releases)
- [Changelog](https://github.com/mitchellh/mapstructure/blob/master/CHANGELOG.md)
- [Commits](https://github.com/mitchellh/mapstructure/compare/v1.3.3...v1.4.1)

Signed-off-by: dependabot[bot] <support@github.com>
2021-07-27 13:16:44 +02:00
dependabot[bot] 7c0f904f29 build(deps): bump github.com/google/go-cmp from 0.5.5 to 0.5.6
Bumps [github.com/google/go-cmp](https://github.com/google/go-cmp) from 0.5.5 to 0.5.6.
- [Release notes](https://github.com/google/go-cmp/releases)
- [Commits](https://github.com/google/go-cmp/compare/v0.5.5...v0.5.6)

---
updated-dependencies:
- dependency-name: github.com/google/go-cmp
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-07-27 12:42:16 +02:00
dependabot[bot] b2fbd4d13a build(deps): bump github.com/mitchellh/hashstructure from 1.0.0 to 1.1.0
Bumps [github.com/mitchellh/hashstructure](https://github.com/mitchellh/hashstructure) from 1.0.0 to 1.1.0.
- [Release notes](https://github.com/mitchellh/hashstructure/releases)
- [Commits](https://github.com/mitchellh/hashstructure/compare/v1.0.0...v1.1.0)

Signed-off-by: dependabot[bot] <support@github.com>
2021-07-27 12:36:11 +02:00
dependabot[bot] 90041d1b6d build(deps): bump github.com/gobuffalo/flect from 0.2.2 to 0.2.3
Bumps [github.com/gobuffalo/flect](https://github.com/gobuffalo/flect) from 0.2.2 to 0.2.3.
- [Release notes](https://github.com/gobuffalo/flect/releases)
- [Commits](https://github.com/gobuffalo/flect/compare/v0.2.2...v0.2.3)

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

Signed-off-by: dependabot[bot] <support@github.com>
2021-07-27 10:07:34 +02:00
dependabot[bot] 05047096f5 build(deps): bump github.com/pelletier/go-toml from 1.9.0 to 1.9.3
Bumps [github.com/pelletier/go-toml](https://github.com/pelletier/go-toml) from 1.9.0 to 1.9.3.
- [Release notes](https://github.com/pelletier/go-toml/releases)
- [Commits](https://github.com/pelletier/go-toml/compare/v1.9.0...v1.9.3)

---
updated-dependencies:
- dependency-name: github.com/pelletier/go-toml
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-07-27 09:37:05 +02:00
dependabot[bot] a469156ea4 build(deps): bump github.com/aws/aws-sdk-go from 1.38.23 to 1.40.8
Bumps [github.com/aws/aws-sdk-go](https://github.com/aws/aws-sdk-go) from 1.38.23 to 1.40.8.
- [Release notes](https://github.com/aws/aws-sdk-go/releases)
- [Changelog](https://github.com/aws/aws-sdk-go/blob/main/CHANGELOG.md)
- [Commits](https://github.com/aws/aws-sdk-go/compare/v1.38.23...v1.40.8)

---
updated-dependencies:
- dependency-name: github.com/aws/aws-sdk-go
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-07-26 21:21:26 +02:00
dependabot[bot] 18fdd85bcc build(deps): bump github.com/tdewolff/minify/v2 from 2.9.18 to 2.9.19
Bumps [github.com/tdewolff/minify/v2](https://github.com/tdewolff/minify) from 2.9.18 to 2.9.19.
- [Release notes](https://github.com/tdewolff/minify/releases)
- [Commits](https://github.com/tdewolff/minify/compare/v2.9.18...v2.9.19)

---
updated-dependencies:
- dependency-name: github.com/tdewolff/minify/v2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-07-26 20:23:32 +02:00
Bjørn Erik Pedersen aeb1935d44 deps: Update github.com/evanw/esbuild v0.11.16 => v0.12.16 2021-07-26 20:23:00 +02:00
Bjørn Erik Pedersen c7252224c4 Deprecate Blackfriday and fix a potential deadlock in config
Note that the deadlock has not been seen earlier, in tests on in real Hugo sites.

Fixes #8792
Fixes #8791
2021-07-26 16:28:16 +02:00
Bjørn Erik Pedersen e09d7882c8 deps: Update github.com/yuin/goldmark v1.3.9 => v1.4.0 2021-07-26 14:54:56 +02:00
dependabot[bot] 15c0eed048 build(deps): bump github.com/frankban/quicktest from 1.12.0 to 1.13.0
Bumps [github.com/frankban/quicktest](https://github.com/frankban/quicktest) from 1.12.0 to 1.13.0.
- [Release notes](https://github.com/frankban/quicktest/releases)
- [Commits](https://github.com/frankban/quicktest/compare/v1.12.0...v1.13.0)

Signed-off-by: dependabot[bot] <support@github.com>
2021-07-26 11:31:33 +02:00
Bjørn Erik Pedersen 91cbb96302 Bump all long-living deprecations to ERRORs 2021-07-25 17:17:21 +02:00
Digitalcraftsman a352d19d88 Fix theme count in release notes 2021-07-21 16:35:38 +02:00
hugoreleaser 11bb67dcfd releaser: Prepare repository for 0.87.0-DEV
[ci skip]
2021-07-21 11:13:04 +00:00
hugoreleaser 41c6c52ead releaser: Add release notes to /docs for release of 0.86.0
[ci skip]
2021-07-21 09:53:11 +00:00
hugoreleaser d270eaf4fc releaser: Bump versions for release of 0.86.0
[ci skip]
2021-07-21 09:53:11 +00:00
Bjørn Erik Pedersen b2e67505f8 Release 0.86.0 2021-07-21 11:37:16 +02:00
Bjørn Erik Pedersen 32508045d3 navigation: Check Page first in URL()
In Hugo #8776 we added `pageRef`, a way to connect menu items in site config to pages.

This means that you now can have both a Page and a configured URL.

Having the configured URL as a fallback if the Page isn't found is obviously more useful, especially in multilingual sites.

See #8776
2021-07-21 11:36:15 +02:00
Bjørn Erik Pedersen e521c9a36d Update 0.86.0-relnotes.md
[ci skip]
2021-07-21 11:28:32 +02:00
hugoreleaser dfb1cc4315 releaser: Add release notes for 0.86.0
Rename to *-ready.md to continue.
[ci skip]
2021-07-21 09:04:02 +00:00
Bjørn Erik Pedersen 0294a4a4f8 Merge commit '53a352795a69a9d4a373f50ec62138595948c6ea' 2021-07-21 10:45:53 +02:00
Bjørn Erik Pedersen 53a352795a Squashed 'docs/' changes from 6ebb5dad9..60a58d123
60a58d123 Remove outdated references in scss-sass.md
225a03834 Revert "Update menus.md"
7d149dd1e Update menus.md
3694ecafc Fix theme submission process/repository
0277c202c Update index.md - fix typo (#1490)
8921f0462 Fix link to theme components in 0.42 release notes (#1489)
c948bd519 Release 0.85.0
ee5bc5be9 releaser: Add release notes to /docs for release of 0.85.0
f2f692c32 commands: Make the --poll flag a duration
13070337a docs: Regen CLI docs

git-subtree-dir: docs
git-subtree-split: 60a58d123d
2021-07-21 10:45:05 +02:00
Bjørn Erik Pedersen 351ed0f569 commands: Fix panic on invalid config in "hugo mod get" and similar
Fixes #8773
2021-07-20 18:23:09 +02:00
Bjørn Erik Pedersen d831d2fce8 Simplify "active menu" logic for section menus
Fixes #8776
2021-07-20 17:50:59 +02:00
Bjørn Erik Pedersen 634481ba8c Fix Params case handling for menu items defined in site config
Fixes #8775
2021-07-20 17:50:59 +02:00
Bjørn Erik Pedersen c19f65f956 minifiers: Make keepWhitespace = true default for HTML
Fixes #8771
2021-07-19 23:35:20 +02:00
Bjørn Erik Pedersen 022c479551 hugofs: Make FileMeta a struct
This commit started out investigating a `concurrent map read write` issue, ending by replacing the map with a struct.

This is easier to reason about, and it's more effective:

```
name                                  old time/op    new time/op    delta
SiteNew/Regular_Deep_content_tree-16    71.5ms ± 3%    69.4ms ± 5%    ~     (p=0.200 n=4+4)

name                                  old alloc/op   new alloc/op   delta
SiteNew/Regular_Deep_content_tree-16    29.7MB ± 0%    27.9MB ± 0%  -5.82%  (p=0.029 n=4+4)

name                                  old allocs/op  new allocs/op  delta
SiteNew/Regular_Deep_content_tree-16      313k ± 0%      303k ± 0%  -3.35%  (p=0.029 n=4+4)
```

See #8749
2021-07-15 17:14:26 +02:00
rhymes f27e542442 markup: Add tabindex="0" to default <pre> wrapper
Currently the generated `<pre>` element isn't fully accessible as it can't be focused by keyboard users.
To make this fully accessible, the attribute `tabindex="0"` should be added to the `<pre>` tag.

Closes #7194
2021-07-15 16:48:39 +02:00
Bjørn Erik Pedersen ae6cf93c84 Fix default values when loading from config dir
By waiting until we've loaded the config dir config before applying the default values.

Fixes #8763
2021-07-15 16:15:32 +02:00
Bjørn Erik Pedersen a70da2b74a Fix the deprecation error/warn log levels 2021-07-15 12:24:20 +02:00
Bjørn Erik Pedersen 805664818d markup/goldmark: Rename/reorder the hook methods
To make them easier to follow.

See #8755
2021-07-15 10:14:52 +02:00
Bjørn Erik Pedersen ee3d2bb1d3 markup/goldmark: Support auto links in render hook
Fixes #8755
2021-07-15 10:14:52 +02:00
Bjørn Erik Pedersen eb2a500367 Adjust a test helper 2021-07-14 21:47:26 +02:00
Bjørn Erik Pedersen 5cb52c2315 Add config.cascade
This commit adds support for using the `cascade` keyword in your configuration file(s), e.g. `config.toml`.

Note that

* Every feature of `cascade` is available, e.g. `_target` to target specific page sets.
* Pages, e.g. the home page, can overwrite the cascade defined in config.

Fixes #8741
2021-07-10 11:13:41 +02:00
Bjørn Erik Pedersen 30eea3915b resources: Regenerate image golden testdata
Keep this as a separate commit as this isn't because the files have changed. The filenames have changed due to cache busting of PNG and Webp images.

See #8729
2021-07-07 17:25:14 +02:00
Bjørn Erik Pedersen 8f40f34cd1 Fix transparency problem when converting 32-bit images to WebP
Fixes #8729
2021-07-07 17:25:14 +02:00
hugoreleaser 8ddbc95466 releaser: Prepare repository for 0.86.0-DEV
[ci skip]
2021-07-05 11:37:38 +00:00
hugoreleaser 724d5db580 releaser: Add release notes to /docs for release of 0.85.0
[ci skip]
2021-07-05 10:46:25 +00:00
hugoreleaser 875fe4050c releaser: Bump versions for release of 0.85.0
[ci skip]
2021-07-05 10:46:25 +00:00
Bjørn Erik Pedersen 56362e4bc7 Update 0.85.0-relnotes.md 2021-07-05 12:38:14 +02:00
hugoreleaser f5cfb9e251 releaser: Add release notes for 0.85.0
Rename to *-ready.md to continue.
[ci skip]
2021-07-05 10:27:32 +00:00
John Hollowell 04dc469fbd commands: Move time notification to after any build errors
This allows error parsers (VSCode problemMatchers) to use the time notification as bounds for detecting errors.

Closes #8403
2021-07-05 10:38:54 +02:00
Brandon Woodford 07919d1ccb exif: Log warning for metadata decode error
see #8519
2021-07-05 10:31:35 +02:00
Raoul f75f90079a Fix tab selection of disabled items in internal pagination template 2021-07-05 10:30:59 +02:00
Bjørn Erik Pedersen e31b1d1946 commands: Make the --poll flag a duration
So you can do:

```
hugo server --poll 700ms
```

See #8720
2021-07-05 10:23:29 +02:00
Bjørn Erik Pedersen 43a23239b2 docs: Regen CLI docs 2021-07-04 16:35:21 +02:00
Bjørn Erik Pedersen 4479f09c9c Merge commit '7eb0e10a80708c638554b8221a3120dc1168566c' 2021-07-04 16:34:53 +02:00
Bjørn Erik Pedersen 7eb0e10a80 Squashed 'docs/' changes from 710856e5a..6ebb5dad9
6ebb5dad9 Remove file
27cc23ef4 Hugo 0.84.4
94dccbfa4 Merge branch 'tempv0.84.4'
e9d8b61fb releaser: Add release notes to /docs for release of 0.84.4
51e472005 Improve readability of examples on shortcode templates page
0aef26479 Fix lookup order typos (#1484)
534a527fe Fix two typos (#1483)
394aabd5a Higo "0.84.3
03ee92c1c Merge branch 'tempv0.84.3'
96a8be0f1 releaser: Add release notes to /docs for release of 0.84.3
9a770323f Update index.md
7f65cfcbe Hugo 0.84.2
444422515 releaser: Add release notes to /docs for release of 0.84.2
a2f29c5d8 modules: Add module.import.noMounts config
e00e4a7e7 releaser: Add release notes to /docs for release of 0.84.2
af04b53b3 modules: Add module.import.noMounts config
f7d5669c7 Remove Appernetic (#1481)
14f8d4029 Clarify interaction of sections and top-level leaf bundles
d140b6a62 Update lookup-order.md
399904959 Update shortcode-templates.md
e78aa4865 Hugo 0.84.1
35d7c1c22 Merge branch 'tempv0.84.1'
a6be65b0d releaser: Add release notes to /docs for release of 0.84.1
7b3b3ca45 Hugo 0.84.0 News Grammar fixes
cbc23bf5a Remove trailing newlines
69349198d Fix erroridf docs
dbc1157c1 Fix missing deep

git-subtree-dir: docs
git-subtree-split: 6ebb5dad9a
2021-07-04 16:34:26 +02:00
Bjørn Erik Pedersen 24ce98b6d1 Add polling as a fallback to native filesystem events in server watch
Fixes #8720
Fixes #6849
Fixes #7930
2021-07-04 16:12:28 +02:00
Bjørn Erik Pedersen 0019d60f67 deps: Bump github.com/yuin/goldmark v1.3.9
Closes #8727
2021-07-04 15:48:33 +02:00
Bjørn Erik Pedersen e451b984cf Fix panic when theme has permalinks config
Fixes #8724
2021-07-03 15:53:21 +02:00
hugoreleaser b4d60b3db1 releaser: Prepare repository for 0.85.0-DEV
[ci skip]
2021-07-01 12:59:47 +00:00
hugoreleaser 020e4acee4 releaser: Add release notes to /docs for release of 0.84.4
[ci skip]
2021-07-01 11:51:53 +00:00
hugoreleaser 4c34faf426 releaser: Bump versions for release of 0.84.4
[ci skip]
2021-07-01 11:51:53 +00:00
hugoreleaser a339f62664 releaser: Add release notes for 0.84.4
[ci skip]
2021-07-01 11:51:53 +00:00
Bjørn Erik Pedersen 4c8552b114 Fix Cloudflare vs Netlify cache dir issue
Re-add the additional environment checks to determine if its Netlify. Seems that Cloudflare also sets `NETLIFY=true`.

This makes it look, basically, like a variant of the conditional we had before we started fixing this, but I have checked this logic on Netlify now and it should work.

Fixes #8714
2021-06-30 12:58:43 +02:00
Joe Mooring 34e4742f0c Fix date format in schema and opengraph templates
Fixes #8671
2021-06-29 20:20:38 +02:00
hugoreleaser bffa2a2a98 releaser: Prepare repository for 0.85.0-DEV
[ci skip]
2021-06-29 12:27:15 +00:00
hugoreleaser a1b0353ccb releaser: Add release notes to /docs for release of 0.84.3
[ci skip]
2021-06-29 11:40:19 +00:00
hugoreleaser bc6f84c581 releaser: Bump versions for release of 0.84.3
[ci skip]
2021-06-29 11:40:19 +00:00
hugoreleaser 80410257e3 releaser: Add release notes for 0.84.3
[ci skip]
2021-06-29 11:40:19 +00:00
Bjørn Erik Pedersen 6c8c0c8b6a config: Fix Netlify default cache dir logic
Fixes #8710
2021-06-29 09:51:09 +02:00
Bjørn Erik Pedersen 49fedbc51c config: Fix handling of invalid OS env config overrides
Fixes #8709
2021-06-29 09:38:05 +02:00
hugoreleaser 8290720107 releaser: Prepare repository for 0.85.0-DEV
[ci skip]
2021-06-28 11:41:38 +00:00
hugoreleaser e0c67958f1 releaser: Add release notes to /docs for release of 0.84.2
[ci skip]
2021-06-28 10:59:18 +00:00
hugoreleaser f6b9ce6ebd releaser: Bump versions for release of 0.84.2
[ci skip]
2021-06-28 10:59:18 +00:00
hugoreleaser 4b03399b78 releaser: Add release notes for 0.84.2
[ci skip]
2021-06-28 10:59:18 +00:00
Bjørn Erik Pedersen 40dfdd0952 modules: Add module.import.noMounts config
Fixes #8708
2021-06-28 10:39:52 +02:00
Bjørn Erik Pedersen 3a6dc6d3f4 modules: Use value type for module.Time
Which is in line with how we do it elsewhere.
2021-06-27 18:06:52 +02:00
Bjørn Erik Pedersen 6cd2110ab2 commands: Add version time to "hugo config mounts" 2021-06-27 18:00:20 +02:00
Bjørn Erik Pedersen 6a365c2712 commands: Add some more info to "hugo config mounts"
* Add owner path and version.
* Also add thme meta info and Hugo version when run with -v flag
2021-06-27 16:08:28 +02:00
Bjørn Erik Pedersen 19aa95fc7f Fix config handling with empty config entries after merge
Fixes #8701
2021-06-27 15:01:56 +02:00
Bjørn Erik Pedersen 923dd9d1c1 Fix config loading for "hugo mod init"
We have some commands that will continue even if the config loading fails (e.g. because a module can not be found). In Hugo 0.84.0 we introduced a new `_merge` flag that we removed once the configuration was loaded. But we did not do that in error situations, leading to failures in some situations.

This commit fixes that by making sure the configuration is always cleaned before return, even in error situations.

Fixes #8697
2021-06-27 12:03:43 +02:00
Bjørn Erik Pedersen d9bdd37d35 deps: Update to Minify v2.9.18
Closes #8693
2021-06-26 17:15:55 +02:00
digitalcraftsman b2eaf4c8c2 Remove credit from release notes 2021-06-25 21:14:11 +02:00
hugoreleaser efb6ee6c1c releaser: Prepare repository for 0.85.0-DEV
[ci skip]
2021-06-24 12:33:45 +00:00
hugoreleaser 4bd65e224f releaser: Add release notes to /docs for release of 0.84.1
[ci skip]
2021-06-24 11:44:21 +00:00
hugoreleaser ff2266300a releaser: Bump versions for release of 0.84.1
[ci skip]
2021-06-24 11:44:21 +00:00
hugoreleaser 8677cfb04f releaser: Add release notes for 0.84.1
[ci skip]
2021-06-24 11:44:21 +00:00
Bjørn Erik Pedersen 093dacab29 Fix language menu config regression
Fixes #8672
2021-06-24 13:03:09 +02:00
Bjørn Erik Pedersen 4a9d408fe0 config: Fix merge of config with map[string]string values.
Fixes #8679
2021-06-22 21:38:28 +02:00
Bjørn Erik Pedersen 9312059888 releaser: Bump to Goreleaser v0.171.0
Closes #8665
2021-06-21 16:12:18 +02:00
Bjørn Erik Pedersen a7e3da242f markup: Rename Header(s) to Heading(s) in ToC struct
Because that is what it is.
2021-06-19 18:19:46 +02:00
Bjørn Erik Pedersen b70a12ec45 Merge commit '4dd90050f154c91373329a5d7e348289c40be12f' 2021-06-18 17:50:27 +02:00
Bjørn Erik Pedersen 4dd90050f1 Squashed 'docs/' changes from 3a923e155..710856e5a
710856e5a Release 0.84.0
362f4ea7b releaser: Add release notes to /docs for release of 0.84.0
6bb8800f7 docs: Regenerate docs helper
00a522e6a docs: Regenerate docshelper
bc171954b Merge commit '92405e5b0adc5d8c3dfde88d6a8b67eb09169190'
ef73ffc3b Misc config loading fixes
0b4117f7f docs: Regenerate docs helper
9b9452b9c Merge commit '32ba623541d74ee0b7ae4efb1b8326dc49af28b8'
9c4413dd9 tpl/fmt: Add erroridf template func
e1875742e tpl/data: Misc header improvements, tests, allow multiple headers of same key
e4560893c Add math.Max and math.Min
7dc282eaf common/maps: Add Scratch.DeleteInMap
b9cd77171 docs: Update querify function description and examples

git-subtree-dir: docs
git-subtree-split: 710856e5a6
2021-06-18 17:49:54 +02:00
hugoreleaser 3d544c9ae4 releaser: Prepare repository for 0.85.0-DEV
[ci skip]
2021-06-18 15:36:43 +00:00
hugoreleaser 2c4689f7b8 releaser: Add release notes to /docs for release of 0.84.0
[ci skip]
2021-06-18 14:55:51 +00:00
hugoreleaser 9c0860f749 releaser: Bump versions for release of 0.84.0
[ci skip]
2021-06-18 14:55:51 +00:00
Bjørn Erik Pedersen a1694b06af releaser: Increase timeout 2021-06-18 16:44:12 +02:00
hugoreleaser 219ec38007 releaser: Add release notes for 0.84.0 2021-06-18 14:42:14 +02:00
Bjørn Erik Pedersen be6b901cf7 docs: Regenerate docs helper 2021-06-18 13:21:10 +02:00
Bjørn Erik Pedersen 643b671931 output: Make WebAppManifestFormat NotAlternative=true
Updates #8624
2021-06-18 13:19:37 +02:00
Bjørn Erik Pedersen ab4e1dfa4e media: Adjust test assertion
Closes #8625
2021-06-18 13:15:00 +02:00
Rohan Kumar 02f31897b4 media: support application/manifest+json
The standard file extension for Web App Manifest files is
".webmanifest". This commit allows Hugo to recognize .webmanifest files
as "application/manifest+json" files and to minify them using its
JSON minifier.

The .webmanifest file extension is recommended in the w3c spec to
simplify media type registration:
https://www.w3.org/TR/appmanifest/#media-type-registration

Webhint docs are also relevant:
https://webhint.io/docs/user-guide/hints/hint-manifest-file-extension/

Closes #8624
2021-06-18 13:11:44 +02:00
Bjørn Erik Pedersen 402da3f8f3 docs: Regenerate docshelper 2021-06-18 12:58:07 +02:00
Bjørn Erik Pedersen 92405e5b0a Squashed 'docs/' changes from 4c81c6c2a..3a923e155
3a923e155 Update configuration.md

git-subtree-dir: docs
git-subtree-split: 3a923e1550
2021-06-18 12:57:19 +02:00
Bjørn Erik Pedersen a074f758b0 Merge commit '92405e5b0adc5d8c3dfde88d6a8b67eb09169190' 2021-06-18 12:57:19 +02:00
Bjørn Erik Pedersen bb2aa08709 Implement configuration in a directory for modules
Fixes #8654
2021-06-18 12:54:30 +02:00
Bjørn Erik Pedersen 9096842b04 tpl: Rename err-missing-instagram-accesstoken => error-missing-instagram-accesstoken
To get it in line with the other.
2021-06-18 12:27:37 +02:00
Bjørn Erik Pedersen 3aa7f0b27f deps: Update github.com/alecthomas/chroma v0.9.1 => v0.9.2
Closes #8658
2021-06-18 12:14:52 +02:00
Bjørn Erik Pedersen 9b870aa788 deps: Run go mod tidy 2021-06-18 12:13:17 +02:00
Bjørn Erik Pedersen 93aad3c543 Split out the puthe path/filepath functions into common/paths
So they can be used from the config package without cyclic troubles.

Updates #8654
2021-06-18 10:55:00 +02:00
Bjørn Erik Pedersen 5af045ebab resources/image: Fix fill with smartcrop sometimes returning 0 bytes images
Fixes #7955
2021-06-17 23:52:27 +02:00
Joe Mooring 8eafe0845d deps: Update to Goldmark v1.3.8
Fixes #8648
2021-06-17 19:34:26 +02:00
Bjørn Erik Pedersen 31fb29fb3f Do not read config from os.Environ when running tests
Fixes #8655
2021-06-16 18:58:40 +02:00
Bjørn Erik Pedersen d392893cd7 Misc config loading fixes
The main motivation behind this is simplicity and correctnes, but the new small config library is also faster:

```
BenchmarkDefaultConfigProvider/Viper-16         	  252418	      4546 ns/op	    2720 B/op	      30 allocs/op
BenchmarkDefaultConfigProvider/Custom-16        	  450756	      2651 ns/op	    1008 B/op	       6 allocs/op
```

Fixes #8633
Fixes #8618
Fixes #8630
Updates #8591
Closes #6680
Closes #5192
2021-06-14 17:00:32 +02:00
Bjørn Erik Pedersen a886dd53b8 github: Set a dummy Instagram token
For now, need to debug why this fails.
2021-06-13 11:09:50 +02:00
Bjørn Erik Pedersen a91cd7652f docs: Regenerate docs helper 2021-06-08 18:52:38 +02:00
Bjørn Erik Pedersen 162f41d0ef Merge commit '32ba623541d74ee0b7ae4efb1b8326dc49af28b8' 2021-06-08 18:47:53 +02:00
Bjørn Erik Pedersen 32ba623541 Squashed 'docs/' changes from bcc4f9324..4c81c6c2a
4c81c6c2a live reload: add section about `--navigateToChanged`
271014257 Update netify hugo version to 0.83.1
14199cff1 Add pull_request event
0c33b05de Hosting on GitHub: Little wording fixes and update Ubuntu runner in example workflow to 20.04 (#1457)
e47b6c33a Hugo Modules plural typo (#1266)
0f2bbacdd Add node_modules to .gitignore
1d645d79f Overhaul scratch.md (#1451)
572766889 Add link to golang regex syntax, change modified date
21b0c7459 Add info about contentType config
de7d96fa2 Document Go template's multiline support
0c8f2dcb1 Avoid scratch usage
696fa92e1 Rename scratch var
44193f267 Update usage instructions
4230f8fa5 Rename and refactor shortcode
e9953751e Strip leading whitespaces
d61a58010 Add `insertpages` shortcode
04d30677d Mention WebP under 'Target Format' (#1431)
946784508 Update lookup-order.md (#1443)
a7b587988 Update index.md
27907f7ea netlify: Hugo 0.83.1
044d37e57 Merge branch 'tempv0.83.1'
b81aedb03 Fix page `.Kind`
fcf7775ad releaser: Add release notes to /docs for release of 0.83.1
9b39c77c8 fix typo in 0.83 release notes
1c38993ce Update index.md
45b8aefa6 Update index.md
43902dfaa Update index.md
3d959c7ae Merge branch 'tempv0.83.0'
6c22dc327 Fix URL
497ea3224 Use Hugo version badge shortcode
a182d10dd releaser: Add release notes to /docs for release of 0.83.0
287fd9ac0 docs: Fix shortcode
e789c879a docs: Regenerate docs helper
1666c7f31 docs: Regenerate CLI docs
117de1d12 Merge commit 'c239c643fee10bfa217cb108755b798f8f5f3b10'
a6bf3f7d9 docs: Regen docs helper

git-subtree-dir: docs
git-subtree-split: 4c81c6c2ac
2021-06-08 18:46:58 +02:00
Bjørn Erik Pedersen 552cef5c57 Update to Go 1.16.5, Goreleaser 0.169.0
Fixes #8619
Fixes #8263
2021-06-08 18:46:35 +02:00
Joe Mooring 73483d0f9e tpl: Add a terse pagination template variant to improve performance
These calls are equivalent:

{{ template "_internal/pagination.html" . }}
{{ template "_internal/pagination.html" (dict "page" .) }}
{{ template "_internal/pagination.html" (dict "page" . "format" "default") }}

To use an alternate format:

{{ template "_internal/pagination.html" (dict "page" . "format" "terse") }}

Fixes #8599
2021-06-08 10:41:21 +02:00
Bjørn Erik Pedersen 9b5debe4b8 Upgrade Instagram shortcode
Fixes #7879
2021-06-08 10:30:45 +02:00
Bjørn Erik Pedersen 12530519d8 Fix nested OS env config override when parent does not exist
Fixes #8618
2021-06-08 09:57:18 +02:00
Bjørn Erik Pedersen f55d2f4376 tpl/fmt: Add erroridf template func
Fixes #8613
2021-06-07 19:11:03 +02:00
Bjørn Erik Pedersen 282f1aa3db tpl/data: Print response body on HTTP errors
Which makes it easier to debug.
2021-06-07 12:06:27 +02:00
Bjørn Erik Pedersen fcd63de3a5 tpl/data: Misc header improvements, tests, allow multiple headers of same key
Closes #5617
2021-06-06 13:32:12 +02:00
Paul Chamberlain 150d75738b tpl/data: Allows user-defined HTTP headers with getJSON and getCSV
Updates #5617
2021-06-06 13:32:12 +02:00
Bjørn Erik Pedersen 06d295427f hugofs: Set modTime at creation time
As `ModTime()` should return the same value on each invocation.

See #6161
2021-06-05 11:45:56 +02:00
Anthony Fok 26ae12c0c6 Fix invalid timestamp of the "public" folder
Special thanks to both Richard Mortimer (@oldelvet) and
Joshua M. Clulow (@jclulow) for their analysis and suggested fix:

 * https://github.com/gohugoio/hugo/issues/6161#issuecomment-574336088
 * https://github.com/gohugoio/hugo/issues/6161#issuecomment-596805273

Fixes #6161
2021-06-04 14:50:30 -06:00
卜木 ee733085b7 config: Fix env split to allow = character in values
Fixes #8589
2021-05-30 20:25:37 +02:00
Joe Mooring 01758f99b9 Add math.Max and math.Min
Closes #8583
2021-05-28 20:38:45 +02:00
satotake 845a7ba4fc Catch incomplete shortcode error
Currently, no name shortcodes (`{{< >}}`) enter unexpected branch and
throw `BUG: template info not set`. This patch checks if shortcode has
name or not earlier and throws specific error.

Closes #6866
2021-05-24 14:59:02 +02:00
Joe Mooring 10f60de89a Use SPDX license identifier
See <https://spdx.org/licenses/>
Fixes #8555
2021-05-24 11:54:46 +02:00
satotake 785a31b5b8 navigation: Cache and copy Menu for sorting
.Site.Menus is mutated when it is sorted for now and this causes concurrency problem (#7594)
In this patch, each related sort function copies Menu before sorting to prevent
race condition.

Pages already have such a sort and cache logic and this patch is identical to it.

Closes #7594
2021-05-23 10:42:01 +02:00
Bjørn Erik Pedersen bc1e05286a deps: Update to LibSASS 3.6.5
See https://github.com/sass/libsass/releases/tag/3.6.5
2021-05-23 10:33:56 +02:00
Bjørn Erik Pedersen f518b4f71e publisher: Make the HTML element collector more robust
Fixes #8530
2021-05-19 20:43:49 +02:00
Bjørn Erik Pedersen dc6b7a75ff Revert "publisher: Make the HTML element collector more robust"
This reverts commit ef0f1a7269.
2021-05-19 03:45:36 +02:00
Bjørn Erik Pedersen 3f515f0e33 Revert "publisher: Get the collector in line with the io.Writer interface"
This reverts commit a9bcd38181.
2021-05-19 03:45:30 +02:00
Bjørn Erik Pedersen a9bcd38181 publisher: Get the collector in line with the io.Writer interface
As in: Do not retain the input slice.
2021-05-17 19:39:40 +02:00
Bjørn Erik Pedersen ef0f1a7269 publisher: Make the HTML element collector more robust
Fixes #8530
2021-05-17 17:15:32 +02:00
meehawk abbc99d4c6 common/maps: Add Scratch.DeleteInMap
Add Scratch.DeleteInMap method. This method works similar to Scratch.SetInMap. It takes in two string parameters, key and mapKey and deletes the value mapped to mapKey in key

Closes #8504
2021-05-17 15:45:33 +02:00
Joe Mooring 76c95f55a5 Display version when building site (#8533)
Closes #8531
2021-05-14 16:45:13 +02:00
Joe Mooring 2c7f5b62f6 docs: Update querify function description and examples
The querify function now accepts a slice per #8305.
2021-05-10 17:18:37 +02:00
Ujjwal Goyal c46fc838a9 tpl: Allow 'Querify' to take lone slice/interface argument
Querify can now take a lone string/interface slice (with string
keys) as a parameter, or multiple string parameters, to build
URL queries.

Querify earlier used 'Dictionary' to add key/value pairs to a
map to build URL queries. Changed to dynamically generate ordered
key/value pairs. Cannot take string slice as key (earlier
possible due to Dictionary).

Added tests and benchmarks for querify.

Closes #6735
2021-05-09 13:14:14 +02:00
Shohei Ueda 504c78da4b modules/npm: Change SetEscapeHTML to false
Closes #8512
2021-05-09 00:20:28 +02:00
Bjørn Erik Pedersen b660ea8d54 Add a benchmark 2021-05-04 17:59:04 +02:00
Bjørn Erik Pedersen 64f88f3011 readme: Update dependency list 2021-05-03 15:55:28 +02:00
Julien Midedji 7a2c10ae60 tpl: Fix countwords to handle special chars
Fixes #8479
2021-05-03 09:10:06 +02:00
hugoreleaser e1c328df25 releaser: Prepare repository for 0.84.0-DEV
[ci skip]
2021-05-02 15:28:40 +00:00
hugoreleaser 5afe0a57d0 releaser: Add release notes to /docs for release of 0.83.1
[ci skip]
2021-05-02 14:38:02 +00:00
hugoreleaser 8900e33918 releaser: Bump versions for release of 0.83.1
[ci skip]
2021-05-02 14:38:02 +00:00
hugoreleaser 9753e1b9c5 releaser: Add release notes for 0.83.1
[ci skip]
2021-05-02 14:38:02 +00:00
Bjørn Erik Pedersen ececd1b122 langs/i18n: Fix warning regression in i18n
Fix this by

1. Making sure that only numerical values are treated as plural counts
2. Making sure that `i18n.pluralFormNotFoundError` is not logged as a warning if `other` resolved.

Note that 2. isn't a new problem, but became visible because of the plural improvements in Hugo `0.83.0`.

Fixes #8492
2021-05-02 16:27:22 +02:00
hugoreleaser b0ca723eb2 releaser: Prepare repository for 0.84.0-DEV
[ci skip]
2021-05-01 12:56:59 +00:00
hugoreleaser 4c65ceccc7 releaser: Add release notes to /docs for release of 0.83.0
[ci skip]
2021-05-01 12:10:05 +00:00
hugoreleaser 57a471a0db releaser: Bump versions for release of 0.83.0
[ci skip]
2021-05-01 12:10:05 +00:00
Bjørn Erik Pedersen 9b63af55bd Update 0.83.0-relnotes.md 2021-05-01 13:53:25 +02:00
Bjørn Erik Pedersen 23fc65832c docs: Fix shortcode 2021-05-01 13:01:23 +02:00
hugoreleaser e7b5e36e04 releaser: Add release notes for 0.83.0
Rename to *-ready.md to continue.
[ci skip]
2021-05-01 10:23:21 +00:00
Bjørn Erik Pedersen a9b52b4175 docs: Regenerate docs helper 2021-05-01 12:06:24 +02:00
Bjørn Erik Pedersen b073a1c972 docs: Regenerate CLI docs 2021-05-01 12:05:31 +02:00
Bjørn Erik Pedersen 4227cc1bd3 commands: Remove all dates from gendoc
It creates lots of diffs even if there are no changes.
2021-05-01 12:03:56 +02:00
Bjørn Erik Pedersen c239c643fe Squashed 'docs/' changes from fb551cc75..bcc4f9324
bcc4f9324 Add transparent background in rgba for search field
fce835fea Trim newlines from .Inner in the 'code' shortcode
9117f54b3 Remove code toggle from netlify.toml
babbb9090 fix version number - 404 error
d28cf15e1 The input search is not displayed correctly in Safari because of the one declaration CSS background property. Safari needs the no-repeat to be after position and size property. Adjusting the search icon to be vertically on center.
f4ef4c146 Repairing link from issue 131 using jamesrhea's comment https://github.com/gohugoio/hugoDocs/issues/131#issuecomment-324083739
7f73f5685 Update related.md (#1436)
41d24297c Mention `not` (#1432)

git-subtree-dir: docs
git-subtree-split: bcc4f93242
2021-05-01 11:45:45 +02:00
Bjørn Erik Pedersen d7b22aee46 Merge commit 'c239c643fee10bfa217cb108755b798f8f5f3b10' 2021-05-01 11:45:45 +02:00
Bjørn Erik Pedersen 3cc4fdd6f3 deps: Update getkin/kin-openapi v0.60.0 => v0.61. 2021-04-30 14:27:21 +02:00
Bjørn Erik Pedersen 7eb80a9e6f langs/i18n: Fix multiple unknown language codes
This fixes a bug upstream by temporarily using a patched version of go-i18n.

Closes #7838
2021-04-30 14:26:49 +02:00
Bjørn Erik Pedersen 78c1a6a7c6 deps: Update github.com/evanw/esbuild v0.11.14 => v0.11.16 2021-04-30 12:43:39 +02:00
Joe Mooring f6745ad358 Remove .Site.Authors from embedded templates
Closes #4458
2021-04-29 17:07:05 +02:00
Robert van Gent f523e9f0fd deploy: Don't treat a NotFound response for Delete as a fatal error. 2021-04-29 07:07:01 +02:00
Anthony Fok 63cd05ce5a snap: Switch to deb packages of nodejs and python3-pygments
node/14/stable snap package is not available on ppc64el and s390x.

nodejs deb package currently at 10.19.0~dfsg-3ubuntu1
in Ubuntu 20.04 LTS (base: core20)
2021-04-27 09:04:24 -06:00
Anthony Fok 902535ef11 snapcraft.yaml: Install bin/node from node/14/stable
Resolves regression introduced in my previous commit 243951e.
Special thanks to @jmooring for reporting the issue!

TODO: Strip the bin/node binary?
2021-04-26 10:17:44 -06:00
dependabot[bot] 70aebba04d build(deps): bump github.com/getkin/kin-openapi from 0.55.0 to 0.60.0
Bumps [github.com/getkin/kin-openapi](https://github.com/getkin/kin-openapi) from 0.55.0 to 0.60.0.
- [Release notes](https://github.com/getkin/kin-openapi/releases)
- [Commits](https://github.com/getkin/kin-openapi/compare/v0.55.0...v0.60.0)

Signed-off-by: dependabot[bot] <support@github.com>
2021-04-26 10:56:48 +02:00
dependabot[bot] 3e3b7d4474 build(deps): bump github.com/evanw/esbuild from 0.11.13 to 0.11.14
Bumps [github.com/evanw/esbuild](https://github.com/evanw/esbuild) from 0.11.13 to 0.11.14.
- [Release notes](https://github.com/evanw/esbuild/releases)
- [Changelog](https://github.com/evanw/esbuild/blob/master/CHANGELOG.md)
- [Commits](https://github.com/evanw/esbuild/compare/v0.11.13...v0.11.14)

Signed-off-by: dependabot[bot] <support@github.com>
2021-04-26 10:56:03 +02:00
Bjørn Erik Pedersen c13d368746 resources/page: Fix permalinks pattern detection for some of the sections variants
See #8363
2021-04-25 16:57:09 +02:00
Carlos Alexandro Becker 048418ba74 deps: Update to Chroma v0.9.1 2021-04-25 11:14:25 +02:00
Bjørn Erik Pedersen eebde0c2ac langs/i18n: Improve plural handling of floats
The go-i18n library expects plural counts with floats to be represented as strings.

Fixes #8464
2021-04-25 11:12:30 +02:00
Bjørn Erik Pedersen e4dc9a82b5 tpl/collections: Fix where on type mismatches
Fixes #8353
2021-04-23 18:06:49 +02:00
Bjørn Erik Pedersen 0d86a32d8f Make the shortcode template lookup for output formats stable
Fixes #7774
2021-04-23 15:04:35 +02:00
dependabot[bot] 65c502cc81 build(deps): bump github.com/evanw/esbuild from 0.11.12 to 0.11.13
Bumps [github.com/evanw/esbuild](https://github.com/evanw/esbuild) from 0.11.12 to 0.11.13.
- [Release notes](https://github.com/evanw/esbuild/releases)
- [Changelog](https://github.com/evanw/esbuild/blob/master/CHANGELOG.md)
- [Commits](https://github.com/evanw/esbuild/compare/v0.11.12...v0.11.13)

Signed-off-by: dependabot[bot] <support@github.com>
2021-04-23 09:03:16 +02:00
Bjørn Erik Pedersen 537c905ec1 langs/i18n: Revise the plural implementation
There were some issues introduced with the plural counting when we upgraded from v1 to v2 of go-i18n.

This commit improves that situation given the following rules:

* A single integer argument is used as plural count and passed to the i18n template as a int type with a `.Count` method. The latter is to preserve compability with v1.
* Else the plural count is either fetched from the `Count`/`count` field/method/map or from the value itself.
* Any data type is accepted, if it can be converted to an integer, that value is used.

The above means that you can now do pass a single integer and both of the below will work:

```
{{ . }} minutes to read
{{ .Count }} minutes to read
```

Fixes #8454
Closes #7822
See https://github.com/gohugoio/hugoDocs/issues/1410
2021-04-23 07:39:59 +02:00
Anthony Fok 243951ebe9 snapcraft.yaml: Update to "base: core20"
That is, switch to using Ubuntu 20.04 LTS as base,
leveraging new features in Snapcraft 4.x, etc.

It is far from complete, with npm temporarily disabled (hence no PostCSS)
and with Pandoc probably not working yet, but would hopefully get our
Hugo Snap build, which stopped working shortly after v0.80.0, working again.
2021-04-22 09:57:40 -06:00
dependabot[bot] fe2ee02802 build(deps): bump github.com/frankban/quicktest from 1.11.3 to 1.12.0
Bumps [github.com/frankban/quicktest](https://github.com/frankban/quicktest) from 1.11.3 to 1.12.0.
- [Release notes](https://github.com/frankban/quicktest/releases)
- [Commits](https://github.com/frankban/quicktest/compare/v1.11.3...v1.12.0)

Signed-off-by: dependabot[bot] <support@github.com>
2021-04-22 15:24:15 +02:00
dependabot[bot] 316d65cd70 build(deps): bump google.golang.org/api from 0.44.0 to 0.45.0
Bumps [google.golang.org/api](https://github.com/googleapis/google-api-go-client) from 0.44.0 to 0.45.0.
- [Release notes](https://github.com/googleapis/google-api-go-client/releases)
- [Changelog](https://github.com/googleapis/google-api-go-client/blob/master/CHANGES.md)
- [Commits](https://github.com/googleapis/google-api-go-client/compare/v0.44.0...v0.45.0)

Signed-off-by: dependabot[bot] <support@github.com>
2021-04-22 13:43:11 +02:00
dependabot[bot] b95229ab49 build(deps): bump github.com/aws/aws-sdk-go from 1.37.11 to 1.38.23
Bumps [github.com/aws/aws-sdk-go](https://github.com/aws/aws-sdk-go) from 1.37.11 to 1.38.23.
- [Release notes](https://github.com/aws/aws-sdk-go/releases)
- [Changelog](https://github.com/aws/aws-sdk-go/blob/main/CHANGELOG.md)
- [Commits](https://github.com/aws/aws-sdk-go/compare/v1.37.11...v1.38.23)

Signed-off-by: dependabot[bot] <support@github.com>
2021-04-22 13:42:15 +02:00
Santiago De la Cruz 0551df090e Correct function name in comment
IsInt to IsNumber
2021-04-22 12:24:12 +02:00
Bjørn Erik Pedersen bca40cf0c9 Fix Params case handling in where with slices of structs (e.g. Pages)
Fixes #7009
2021-04-21 19:28:18 +02:00
Bjørn Erik Pedersen 057e5a22af deps: Upgraded github.com/evanw/esbuild v0.11.0 => v0.11.12 2021-04-21 13:07:16 +02:00
Bjørn Erik Pedersen fd96f65a3d docs: Regen docs helper 2021-04-20 20:23:36 +02:00
Bjørn Erik Pedersen 8f7891e70c Merge commit '07b8d9466dfb59c429c1b470a0443337bc0aeefe' 2021-04-20 20:22:53 +02:00
Bjørn Erik Pedersen 07b8d9466d Squashed 'docs/' changes from 9cece6640..fb551cc75
fb551cc75 Update index.md
7af894857 Update index.md
d235753ea Hugo 0.82.1
e03e72deb Merge branch 'temp0821'
e62648961 Merge branch 'release-0.82.1'
e1ab0f6eb releaser: Add release notes to /docs for release of 0.82.1
5d354c38d Replaced ``` code blocks with Code Toggler
c9d065c20 Remove duplicate YAML keys (#1420)
8ae31e701 Add webp image encoding support
848f2af26 Update internal.md (#1407)
c103a86a4 Fix `ref` shortcode example output (#1409)
9f8ba56dc Remove leading dot from where function KEY (#1419)
363251a51 Improve presentation of template lookup order (#1382)
b73da986d Improve description of Page Resources (#1381)
4e0bb96d5 Rework robots.txt page (#1405)
edf893e6f Update migrations.md (#1412)
450f1580b Add link to `site` function doc (#1417)
cfffa6e6f Added one extension to the list (#1414)
05f1665a0 Update theme
5de0b1c6a Update theme
250e20552 Add hugo.IsExtended
dea5e1fd7 Fix typo on merge function page (#1408)
1bbed2cf3 Update configuration.md
be0b64a46 Omit ISO
cbb5b8367 Fix `dateFormat` documentation
698f15466 Regenerate the docshelper
f9a8a7cb6 Update multilingual.md
a22dc6267 Fix grammar (#1398)
eb98b0997 Fix pretty URL example (#1397)
f4c4153dc Mention date var complementation in post scheduling (#1396)
17fae284c Fix resources.ExecuteAsTemplate argument order (#1394)
97e2c2abb Use code-toggle shortcode in `multilingual.md` (#1388)
3a84929bb Harmonize capitalization (#1393)
17f15daa6 fix file naming used in example (#1392)
5d97b6a18 Add slice syntax to sections permalinks config
00665b97b Improve description of `site.md`
edcf5e3fc Fix example in `merge.md`
f275ab778 Update postprocess.md
9593e3991 Fix file name
59bd9656f Update postprocess.md
1172fb6d0 Update to theNewDynamic repository (#1263)
f5b5c1d2c Update Hugo container image
4f2e92f2a Adapt anchorize.md to Goldmark
98aa19073 Directly link to `highlight` shortcode (#1384)
4c75c2422 Fix header level
f15c06f23 markdownify: add note about render-hooks and .RenderString (#1281)
69c82eb68 Remove Blackfriday reference from shortcode desc (#1380)
36de478df Update description of ignoreFiles config setting (#1377)
6337699d8 Remove "Authors" page from documentation (#1371)
35e73ca90 fix indent in example (#1372)
d3f01f19a Remove opening body tag from header example (#1376)
341a5a7d8 Update index.md
c9bfdbee6 Release 0.82.0
119644949 releaser: Add release notes to /docs for release of 0.82.0
32efaed78 docs: Regenerate docs helper
dea5449a2 docs: Regen CLI docs
eeab18fce Merge commit '81689af79901f0cdaff765cda6322dd4a9a7ccb3'
d508a1259 Attributes for code fences should be placed after the lang indicator only
c80905cef deps: Update to esbuild v0.9.0
95350eb79 Add support for Google Analytics v4
02d36f9bc Allow markdown attribute lists to be used in title render hooks
7df220a64 Merge commit '9d31f650da964a52f05fc27b7fb99cf3e09778cf'
d80bf61b7 Fixes #7698.

git-subtree-dir: docs
git-subtree-split: fb551cc750
2021-04-20 20:21:45 +02:00
dependabot[bot] d3a64708f4 build(deps): bump github.com/tdewolff/minify/v2 from 2.9.15 to 2.9.16
Bumps [github.com/tdewolff/minify/v2](https://github.com/tdewolff/minify) from 2.9.15 to 2.9.16.
- [Release notes](https://github.com/tdewolff/minify/releases)
- [Commits](https://github.com/tdewolff/minify/compare/v2.9.15...v2.9.16)

Signed-off-by: dependabot[bot] <support@github.com>
2021-04-20 19:19:07 +02:00
dependabot[bot] 3b56244f42 build(deps): bump golang.org/x/text from 0.3.5 to 0.3.6
Bumps [golang.org/x/text](https://github.com/golang/text) from 0.3.5 to 0.3.6.
- [Release notes](https://github.com/golang/text/releases)
- [Commits](https://github.com/golang/text/compare/v0.3.5...v0.3.6)

Signed-off-by: dependabot[bot] <support@github.com>
2021-04-20 18:06:30 +02:00
Bjørn Erik Pedersen f5d3d635e6 publisher: Remove some unreachable code 2021-04-20 17:47:09 +02:00
dependabot[bot] 0d3c42da56 build(deps): bump github.com/getkin/kin-openapi from 0.39.0 to 0.55.0
Bumps [github.com/getkin/kin-openapi](https://github.com/getkin/kin-openapi) from 0.39.0 to 0.55.0.
- [Release notes](https://github.com/getkin/kin-openapi/releases)
- [Commits](https://github.com/getkin/kin-openapi/compare/v0.39.0...v0.55.0)

Signed-off-by: dependabot[bot] <support@github.com>
2021-04-20 17:34:05 +02:00
Bjørn Erik Pedersen ef34dd8f0e publisher: Some performance tweaks for the HTML elements collector 2021-04-20 17:24:17 +02:00
Dirk Olbrich bc80022e03 publisher: Exclude comment and doctype elements from writeStats
- Reorder code blocks
- Rename cssClassCollectorWriter to htmlElementCollectorWriter, as it just collect html element information
- Expand benchmark to test for minified and unminified content

Fixes #8396
Fixes #8417
2021-04-20 17:24:17 +02:00
Bjørn Erik Pedersen 2bb9496ce2 Merge branch 'release-0.82.1' 2021-04-20 13:48:04 +02:00
hugoreleaser fda3c4d1ed releaser: Prepare repository for 0.83.0-DEV
[ci skip]
2021-04-20 11:44:34 +00:00
hugoreleaser 60618210b8 releaser: Add release notes to /docs for release of 0.82.1
[ci skip]
2021-04-20 11:02:48 +00:00
hugoreleaser f8b064f3c0 releaser: Bump versions for release of 0.82.1
[ci skip]
2021-04-20 11:02:48 +00:00
hugoreleaser 4713e509b6 releaser: Add release notes for 0.82.1
[ci skip]
2021-04-20 11:02:48 +00:00
Bjørn Erik Pedersen 6e9d2bf0c9 Regression in media type suffix lookup
Introduced in Hugo 0.82.0.

Fixes #8406
2021-04-20 12:52:30 +02:00
Bjørn Erik Pedersen e73f7a770d Regression in media type suffix lookup
Introduced in Hugo 0.82.0.

Fixes #8406
2021-04-20 12:51:11 +02:00
Joe Mooring 3ddffd064d build(deps): bump github.com/yuin/goldmark from 1.3.2 to 1.3.5
Updated test per <https://github.com/yuin/goldmark/pull/205>.

Fixes #8377
2021-04-16 09:12:28 +02:00
Joe Mooring 6fc52d185a Remove duplicate references from release notes
Closes #8360
2021-04-15 21:15:20 +02:00
dependabot[bot] 73c3ae818a build(deps): bump github.com/spf13/afero from 1.5.1 to 1.6.0
Bumps [github.com/spf13/afero](https://github.com/spf13/afero) from 1.5.1 to 1.6.0.
- [Release notes](https://github.com/spf13/afero/releases)
- [Commits](https://github.com/spf13/afero/compare/v1.5.1...v1.6.0)

Signed-off-by: dependabot[bot] <support@github.com>
2021-04-15 21:08:33 +02:00
dependabot[bot] 7ca118fdfd build(deps): bump github.com/pelletier/go-toml from 1.8.1 to 1.9.0
Bumps [github.com/pelletier/go-toml](https://github.com/pelletier/go-toml) from 1.8.1 to 1.9.0.
- [Release notes](https://github.com/pelletier/go-toml/releases)
- [Commits](https://github.com/pelletier/go-toml/compare/v1.8.1...v1.9.0)

Signed-off-by: dependabot[bot] <support@github.com>
2021-04-15 21:05:43 +02:00
Bjørn Erik Pedersen 33d5f80592 Add webp image encoding support
Fixes #5924
2021-04-15 17:22:55 +02:00
dependabot[bot] 509d39fa6d build(deps): bump google.golang.org/api from 0.40.0 to 0.44.0
Bumps [google.golang.org/api](https://github.com/googleapis/google-api-go-client) from 0.40.0 to 0.44.0.
- [Release notes](https://github.com/googleapis/google-api-go-client/releases)
- [Changelog](https://github.com/googleapis/google-api-go-client/blob/master/CHANGES.md)
- [Commits](https://github.com/googleapis/google-api-go-client/compare/v0.40.0...v0.44.0)

Signed-off-by: dependabot[bot] <support@github.com>
2021-04-15 16:13:49 +02:00
dependabot[bot] 7725c41d40 build(deps): bump github.com/nicksnyder/go-i18n/v2 from 2.1.1 to 2.1.2
Bumps [github.com/nicksnyder/go-i18n/v2](https://github.com/nicksnyder/go-i18n) from 2.1.1 to 2.1.2.
- [Release notes](https://github.com/nicksnyder/go-i18n/releases)
- [Changelog](https://github.com/nicksnyder/go-i18n/blob/main/CHANGELOG.md)
- [Commits](https://github.com/nicksnyder/go-i18n/compare/v2.1.1...v2.1.2)

Signed-off-by: dependabot[bot] <support@github.com>
2021-04-15 16:13:26 +02:00
dependabot[bot] 5d36d80153 build(deps): bump github.com/rogpeppe/go-internal from 1.6.2 to 1.8.0
Bumps [github.com/rogpeppe/go-internal](https://github.com/rogpeppe/go-internal) from 1.6.2 to 1.8.0.
- [Release notes](https://github.com/rogpeppe/go-internal/releases)
- [Commits](https://github.com/rogpeppe/go-internal/compare/v1.6.2...v1.8.0)

Signed-off-by: dependabot[bot] <support@github.com>
2021-04-15 14:44:37 +02:00
Joe Mooring 9b34d42bb2 Remove extraneous space from figure shortcode
Fixes #8401
2021-04-15 14:43:32 +02:00
dependabot[bot] c2d8f87cfc build(deps): bump github.com/magefile/mage from 1.10.0 to 1.11.0
Bumps [github.com/magefile/mage](https://github.com/magefile/mage) from 1.10.0 to 1.11.0.
- [Release notes](https://github.com/magefile/mage/releases)
- [Changelog](https://github.com/magefile/mage/blob/master/.goreleaser.yml)
- [Commits](https://github.com/magefile/mage/compare/v1.10.0...v1.11.0)

Signed-off-by: dependabot[bot] <support@github.com>
2021-04-14 11:55:38 +02:00
dependabot[bot] cbc246616e build(deps): bump github.com/google/go-cmp from 0.5.4 to 0.5.5
Bumps [github.com/google/go-cmp](https://github.com/google/go-cmp) from 0.5.4 to 0.5.5.
- [Release notes](https://github.com/google/go-cmp/releases)
- [Commits](https://github.com/google/go-cmp/compare/v0.5.4...v0.5.5)

Signed-off-by: dependabot[bot] <support@github.com>
2021-04-14 11:55:18 +02:00
Niklas Fasching fa432b17b3 org: Disable broken pretty relative links feature
go-org PrettyRelativeLinks rewrites relative org links by
- adding `../` in front
- removing any `.org` suffix

This was meant to play well with hugo pretty urls (which pretty much renders
posts in a subdirectory without the file suffix) and allow use of normal org
file links to reference other posts.

There's a lot of edge cases I didn't consider and multiple bug reports in
go-org [1] later I don't think the complexity of handling those edge cases is
worth it - so let's disable it.

[1]
- https://github.com/niklasfasching/go-org/issues/53
- https://github.com/niklasfasching/go-org/commit/5dadf8c4c2924cbb3b93be45f96e1147596ca6f2 (comment)
- https://github.com/niklasfasching/go-org/issues/51
2021-04-12 08:08:53 +02:00
Niklas Fasching 0cd55c66d3 deps: Update go-org to v1.5.0 2021-04-12 08:08:53 +02:00
dependabot[bot] 0d5cf256e4 build(deps): bump github.com/jdkato/prose from 1.2.0 to 1.2.1
Bumps [github.com/jdkato/prose](https://github.com/jdkato/prose) from 1.2.0 to 1.2.1.
- [Release notes](https://github.com/jdkato/prose/releases)
- [Commits](https://github.com/jdkato/prose/compare/v1.2.0...v1.2.1)

Signed-off-by: dependabot[bot] <support@github.com>
2021-04-11 13:54:16 +02:00
dependabot[bot] 36527576b3 build(deps): bump github.com/spf13/cobra from 1.1.1 to 1.1.3
Bumps [github.com/spf13/cobra](https://github.com/spf13/cobra) from 1.1.1 to 1.1.3.
- [Release notes](https://github.com/spf13/cobra/releases)
- [Changelog](https://github.com/spf13/cobra/blob/master/CHANGELOG.md)
- [Commits](https://github.com/spf13/cobra/compare/v1.1.1...v1.1.3)

Signed-off-by: dependabot[bot] <support@github.com>
2021-04-11 13:53:45 +02:00
Bjørn Erik Pedersen 9b83f45b6d Add complete dependency list in "hugo env -v"
Fixes #8400
2021-04-09 08:07:22 +02:00
Bjørn Erik Pedersen 7fdd2b95e2 Add hugo.IsExtended
Fixes #8399
2021-04-09 07:28:27 +02:00
Bjørn Erik Pedersen 3d5dbdcb1a publisher: Also test minified HTML in the element collector
Updates #7567
2021-04-07 16:40:15 +02:00
Bjørn Erik Pedersen 8a308944e4 publisher: Skip script, pre and textarea content when looking for HTML elements
Updates #7567
2021-04-07 00:26:02 +02:00
Bjørn Erik Pedersen 7b4ade56dd output: Only output mediaType once in docshelper JSON
Fixes #8379
2021-04-01 19:05:33 +02:00
Joe Mooring 7c7974b711 Fix typo in docshelper.go
Fixes #8380
2021-04-01 18:44:39 +02:00
Bjørn Erik Pedersen 5656a908d8 tpl: Remove the FuzzMarkdownify func for now
It has gotten us nothing but "build fails" mail and work we don't have time to follow up on.
2021-03-30 20:57:31 +02:00
Bjørn Erik Pedersen 2dc222cec4 Add slice syntax to sections permalinks config
Fixes #8363
2021-03-30 07:55:24 +02:00
Bjørn Erik Pedersen 4d22ad580e deps: Upgrade github.com/evanw/esbuild v0.9.6 => v0.11.0 2021-03-29 12:00:47 +02:00
Bjørn Erik Pedersen 5e2f128911 Try to fix the fuzz build 2021-03-28 21:42:44 +02:00
hugoreleaser 97934779ed releaser: Prepare repository for 0.83.0-DEV
[ci skip]
2021-03-21 18:12:42 +00:00
hugoreleaser 9d96078439 releaser: Add release notes to /docs for release of 0.82.0
[ci skip]
2021-03-21 17:28:02 +00:00
hugoreleaser 1efd93c097 releaser: Bump versions for release of 0.82.0
[ci skip]
2021-03-21 17:28:02 +00:00
hugoreleaser 584a9b3e2e releaser: Add release notes for 0.82.0 2021-03-21 18:16:55 +01:00
Bjørn Erik Pedersen 86b4fd35e7 docs: Regenerate docs helper 2021-03-21 13:33:26 +01:00
Bjørn Erik Pedersen 195d108da7 docs: Regen CLI docs 2021-03-21 13:32:12 +01:00
Bjørn Erik Pedersen 81689af799 Squashed 'docs/' changes from bb15e9804..9cece6640
9cece6640 Function sort: fix example labels (#1344)
84444120f Revert "Fix sample data for sort function (#1363)" (#1364)
05c8619f4 Fix sample data for sort function (#1363)
2beb1c0ed Fix "Configure taxonomies" title (#1361)
cd777b9fb Fix sitemap configuration link (#1360)
52251fb42 Update the 'Customize Dates' example to not error (#1357)
1a14cc08a Update quick-start.md
17bb98a94 Add note about image metadata removal
ec4f7bfff Update 404.md
cebfb7a90 explaination that `weight` key is used for sorting
83190ff12 fix typo: "advance settings" → "advanced settings"
75743968c Update quick-start.md
f1c64cd5a Improved documentation.
8af3b236c Update theme

git-subtree-dir: docs
git-subtree-split: 9cece66400
2021-03-21 13:31:17 +01:00
Bjørn Erik Pedersen c94aa5cf46 Merge commit '81689af79901f0cdaff765cda6322dd4a9a7ccb3' 2021-03-21 13:31:17 +01:00
Bjørn Erik Pedersen df8bb8812f Simplify some config loading code 2021-03-21 13:29:11 +01:00
Bjørn Erik Pedersen 57d8d208ed deps: Update github.com/evanw/esbuild v0.9.0 => v0.9.6 2021-03-21 11:24:43 +01:00
Bjørn Erik Pedersen fc06e85082 Apply OS env overrides twice
The recent fix for #8346 had an unfortunate side-effect, as it prevented overrides of config options used in the module collector, e.g. `HUGO_MODULE_REPLACEMENTS`.

This commit fixes that by applying the overrides twice.
2021-03-21 10:54:30 +01:00
Bjørn Erik Pedersen b725253f9e Attributes for code fences should be placed after the lang indicator only
Fixes #8313
2021-03-20 19:15:11 +01:00
Bjørn Erik Pedersen 35dedf15c0 deps: Bump github.com/tdewolff/minify/v2 v2.9.15
Fixes #8332
2021-03-20 15:51:20 +01:00
Bjørn Erik Pedersen 7ed56c6941 Fix OS env override for nested config param only available in theme
Fixes #8346
2021-03-20 13:34:51 +01:00
Avinash Sonawane 24c716cac3 Fix new theme command description
`hugo new theme foo` creates theme `foo` in `./themes` and not in current directory.
2021-03-14 18:47:23 +01:00
Patrick Kollitsch 137d2dab32 github: More explicit support link to discourse 2021-03-14 18:27:15 +01:00
Bjørn Erik Pedersen ba1d0051b4 media: Make Type comparable
So we can use it and output.Format as map key etc.

This commit also fixes the media.Type implementation so it does not need to mutate itself to handle different suffixes for the same MIME type, e.g. jpg vs. jpeg.

This means that there are no Suffix or FullSuffix on media.Type anymore.

Fixes #8317
Fixes #8324
2021-03-14 15:21:54 +01:00
Bjørn Erik Pedersen 1b1dcf586e deps: Update to esbuild v0.9.0 2021-03-14 11:51:25 +01:00
Cameron Moore f6612d8bd8 exif: Fix handling of utf8 runes in nullString() 2021-03-13 21:20:10 +01:00
Cameron Moore 0a2ab3f8fe exif: Allow more spacing characters in strings
The root cause of issue #8079 was a non-breaking space (U+0160).
`unicode.IsPrint` only allows the ASCII space (U+0020).  Be more lenient
by using `unicode.IsGraphic` instead.

Fixes #8079
2021-03-13 21:20:10 +01:00
Bjørn Erik Pedersen 4d24e2a326 media: Add a basic benchmark 2021-03-11 10:08:51 +01:00
Bjørn Erik Pedersen 18074d0c23 Fix output format handling for render hooks
Fixes #8176
2021-03-09 13:26:39 +01:00
Bjørn Erik Pedersen 35bfb66222 Rename a test 2021-03-04 13:46:31 +01:00
Bjørn Erik Pedersen 6d21559fb5 Add a debug helper 2021-03-03 20:16:58 +01:00
Daniel Atwood ba16a14c6e Add support for Google Analytics v4 2021-03-03 13:30:06 +01:00
Bjørn Erik Pedersen 782c79ae61 Bump go.mod to Go 1.16
Fixes #8294
2021-03-03 09:17:57 +01:00
Systemkern 5afcae7e0b #8210 Upgrade golang version for Dockerfile
https://github.com/gohugoio/hugo/issues/8210
relates to: #8210
2021-02-28 14:14:06 +01:00
Bjørn Erik Pedersen 60469f429e Update CONTRIBUTING.md 2021-02-25 11:50:08 +01:00
Bjørn Erik Pedersen aed7df62a8 markup: Handle attribute lists in code fences
Fixes #8278
2021-02-24 11:16:06 +01:00
Bjørn Erik Pedersen cd0c5d7ef3 Allow markdown attribute lists to be used in title render hooks
Fixes #8270
2021-02-23 18:08:39 +01:00
Bjørn Erik Pedersen e7e194435b Merge commit '9d31f650da964a52f05fc27b7fb99cf3e09778cf' 2021-02-23 17:41:05 +01:00
Bjørn Erik Pedersen 9d31f650da Squashed 'docs/' changes from d343ebf71..bb15e9804
bb15e9804 Update index.md (#1339)
ffb2f21d1 Update index.md
fc154ac02 Regenerate CLI docs
a0a687738 Update index.md
d0e35a844 Update index.md
86d0cc042 Update index.md
bdaf7e022 Release 0.81.0
b51017445 releaser: Add release notes to /docs for release of 0.81.0
888dd8fcc docs: Regen CLI docs
8c3e8b270 docs: Regen docs helper
79e3e1ebc Merge commit 'acb9109df778fa4a51c0d8b29b3212b12988908f'
31f70af7e modules: Add config option modules.vendorClosest
2631df94e markup/goldmark: Add attributes support for blocks (tables etc.)
19dee04ad Update to Dart Sass Protocol beta6
e507721fe Refactor: Write to stdout by default
d204bf160 Refactor: Remove powershell support
91bea48f5 Feat: Add zsh, fish and powershell completion support
9c915ea27 docs: Remove mention of a file size limit for readFile
5acc8b6c7 js: Add Inject config option
45321989e js: Add Shims option

git-subtree-dir: docs
git-subtree-split: bb15e9804a
2021-02-23 17:39:59 +01:00
dependabot[bot] 88a85dcea9 build(deps): bump github.com/kyokomi/emoji/v2 from 2.2.7 to 2.2.8
Bumps [github.com/kyokomi/emoji/v2](https://github.com/kyokomi/emoji) from 2.2.7 to 2.2.8.
- [Release notes](https://github.com/kyokomi/emoji/releases)
- [Commits](https://github.com/kyokomi/emoji/compare/v2.2.7...v2.2.8)

Signed-off-by: dependabot[bot] <support@github.com>
2021-02-23 10:55:29 +01:00
Bjørn Erik Pedersen 7f8530039a tpl: Add method mappings for strings.Contains, strings.ContainsAny
Just to confirm/document the function signature.
2021-02-23 09:36:43 +01:00
gzagatti 01dd7c16af Fixes #7698.
markup: Allow installed arbitrary Asciidoc extension via path validation.
2021-02-22 13:52:04 +01:00
Bjørn Erik Pedersen c8f45d1d86 commands: Fix autocomplete docs 2021-02-20 14:08:51 +01:00
hugoreleaser b3504a0ee8 releaser: Prepare repository for 0.82.0-DEV
[ci skip]
2021-02-19 17:55:53 +00:00
hugoreleaser 59d15c97d8 releaser: Add release notes to /docs for release of 0.81.0
[ci skip]
2021-02-19 17:07:09 +00:00
hugoreleaser 9e2d086ca7 releaser: Bump versions for release of 0.81.0
[ci skip]
2021-02-19 17:07:09 +00:00
Bjørn Erik Pedersen b65518ac63 releaser: Increase build timeout 2021-02-19 17:57:24 +01:00
hugoreleaser 0e9cd8128d releaser: Add release notes for 0.81.0 2021-02-19 16:52:22 +01:00
Bjørn Erik Pedersen fe77f7434b tpl: Make the build green again 2021-02-18 18:17:43 +01:00
Bjørn Erik Pedersen 9e99950c6e docs: Regen CLI docs 2021-02-18 17:55:38 +01:00
Bjørn Erik Pedersen 1b364b003f docs: Regen docs helper 2021-02-18 17:54:25 +01:00
Bjørn Erik Pedersen acb9109df7 Squashed 'docs/' changes from ef9c4913c..d343ebf71
d343ebf71 Document ignoreImports
f912ea1cc Fix the github workflow (#1332)
617894052 Add site function
f3be651f9 Minor typo/markdown fixes (#1328)
7a95e9db5 Fix a formatting error for Github Actions (#1323)
260106669 Fix #1120 Use Github Action
d8847a144 docs: Fix HTML code in .RenderString description being stripped out (#1320)
7a67c38c4 Correct sitemap version (#1318)
6a163f53a Removed noise. (#1317)
b02902121 Fix a minor typo (#1314)
399c74acd Revert "js: Update shims setup"
77def8a8c Revert "Update js.md"
13aeb2c73 Update js.md
704987dc1 js: Update shims setup

git-subtree-dir: docs
git-subtree-split: d343ebf718
2021-02-18 17:52:49 +01:00
Bjørn Erik Pedersen 7d0a261981 Merge commit 'acb9109df778fa4a51c0d8b29b3212b12988908f' 2021-02-18 17:52:49 +01:00
Bjørn Erik Pedersen c60806550a tpl: Regenerate internal templates 2021-02-18 17:52:32 +01:00
Daniel Atwood ffd9dac421 tpl: Update date logic of opengraph and schema internal templates
* Fix: updated date logic in opengraph template

* Updated date logic in schema template

* Reformatted opengraph and schema

* Wrapped PublishDate and Lastmod in with
2021-02-18 17:51:32 +01:00
Bjørn Erik Pedersen 88b93a09dc Run go mod tidy 2021-02-18 14:22:25 +01:00
Bjørn Erik Pedersen 29fb456c9e build: Add arm64 to Darwinextended build and add vendorInfo
Closes #8003
2021-02-18 14:11:48 +01:00
Bjørn Erik Pedersen 718fba7d63 Update Travis, GitHub, CircleCI and Snap to Go 1.16 (only) 2021-02-18 14:11:48 +01:00
Bjørn Erik Pedersen 9650e56841 tpl: Add temporary patch to fix template data race
Keep this as a separate commit so we can reapply it if needed.

Fixes #7293
2021-02-18 14:11:48 +01:00
Bjørn Erik Pedersen e77b2e3aa0 Pull in latest Go 1.16 template source 2021-02-18 14:11:48 +01:00
Bjørn Erik Pedersen b5485aeae7 Add breaking tests for "map read and map write in templates"
The fix upstream in Go was reverted, so we apply a temporary patch for this in Hugo.

Updates #7293
2021-02-18 14:11:48 +01:00
Bjørn Erik Pedersen ccb822eb5a Pull in latest Go template source 2021-02-18 14:11:48 +01:00
Bjørn Erik Pedersen 21e9eb18ac Expand template newline testcase to commands 2021-02-18 14:11:48 +01:00
Bjørn Erik Pedersen ae57ba6a9d Add a test case for Go 1.16 template action newlines 2021-02-18 14:11:48 +01:00
Bjørn Erik Pedersen cf3e077da3 tpl/internal: Synch Go templates fork with Go 1.16dev 2021-02-18 14:11:48 +01:00
Bjørn Erik Pedersen 66beac99c6 deps: Update github.com/tdewolff/minify/v2 v2.6.2 => v2.9.13
Fixes #8258
2021-02-18 10:19:22 +01:00
dependabot[bot] 968dd7a711 build(deps): bump github.com/frankban/quicktest from 1.11.2 to 1.11.3
Bumps [github.com/frankban/quicktest](https://github.com/frankban/quicktest) from 1.11.2 to 1.11.3.
- [Release notes](https://github.com/frankban/quicktest/releases)
- [Commits](https://github.com/frankban/quicktest/compare/v1.11.2...v1.11.3)

Signed-off-by: dependabot[bot] <support@github.com>
2021-02-16 22:10:33 +01:00
dependabot[bot] 38f29e817f build(deps): bump github.com/getkin/kin-openapi from 0.32.0 to 0.39.0
Bumps [github.com/getkin/kin-openapi](https://github.com/getkin/kin-openapi) from 0.32.0 to 0.39.0.
- [Release notes](https://github.com/getkin/kin-openapi/releases)
- [Commits](https://github.com/getkin/kin-openapi/compare/v0.32.0...v0.39.0)

Signed-off-by: dependabot[bot] <support@github.com>
2021-02-16 21:18:35 +01:00
dependabot[bot] cd87813aa0 build(deps): bump github.com/aws/aws-sdk-go from 1.36.33 to 1.37.11
Bumps [github.com/aws/aws-sdk-go](https://github.com/aws/aws-sdk-go) from 1.36.33 to 1.37.11.
- [Release notes](https://github.com/aws/aws-sdk-go/releases)
- [Changelog](https://github.com/aws/aws-sdk-go/blob/master/CHANGELOG.md)
- [Commits](https://github.com/aws/aws-sdk-go/compare/v1.36.33...v1.37.11)

Signed-off-by: dependabot[bot] <support@github.com>
2021-02-16 18:43:30 +01:00
dependabot[bot] 4e815b063e build(deps): bump github.com/sanity-io/litter from 1.3.0 to 1.5.0
Bumps [github.com/sanity-io/litter](https://github.com/sanity-io/litter) from 1.3.0 to 1.5.0.
- [Release notes](https://github.com/sanity-io/litter/releases)
- [Changelog](https://github.com/sanity-io/litter/blob/master/CHANGELOG.md)
- [Commits](https://github.com/sanity-io/litter/compare/v1.3.0...v1.5.0)

Signed-off-by: dependabot[bot] <support@github.com>
2021-02-16 18:42:55 +01:00
dependabot[bot] 652a59d385 build(deps): bump github.com/olekukonko/tablewriter from 0.0.4 to 0.0.5
Bumps [github.com/olekukonko/tablewriter](https://github.com/olekukonko/tablewriter) from 0.0.4 to 0.0.5.
- [Release notes](https://github.com/olekukonko/tablewriter/releases)
- [Commits](https://github.com/olekukonko/tablewriter/compare/v0.0.4...v0.0.5)

Signed-off-by: dependabot[bot] <support@github.com>
2021-02-16 18:39:44 +01:00
Bjørn Erik Pedersen 84f0ec7f80 deps: Update to esbuild v0.8.46 2021-02-16 18:37:30 +01:00
Bjørn Erik Pedersen bdfbcf6f4b modules: Add config option modules.vendorClosest
Fixes #8235
Fixes #8242
2021-02-16 16:30:01 +01:00
Bjørn Erik Pedersen b60e9279ab js: Fix potential path issue on Windows 2021-02-16 16:10:46 +01:00
dependabot[bot] a9b0fea6a3 build(deps): bump google.golang.org/api from 0.26.0 to 0.40.0
Bumps [google.golang.org/api](https://github.com/googleapis/google-api-go-client) from 0.26.0 to 0.40.0.
- [Release notes](https://github.com/googleapis/google-api-go-client/releases)
- [Changelog](https://github.com/googleapis/google-api-go-client/blob/master/CHANGES.md)
- [Commits](https://github.com/googleapis/google-api-go-client/compare/v0.26.0...v0.40.0)

Signed-off-by: dependabot[bot] <support@github.com>
2021-02-16 16:10:12 +01:00
Anthony Fok e8df097745 Change version string format and add VendorInfo to help with issue triaging
* Change version string format as proposed by @moorereason

 1. shorten program name
 2. make version string semver compliant with +extended.
    The slash is not allowed in semver.
 3. Use key=value pairs for BuildDate etc.

* Add optional vendorInfo to version string

to help with issue triaging, e.g. VendorInfo=debian:0.80.0-7
2021-02-16 16:08:24 +01:00
Bjørn Erik Pedersen 3a5ee0d2d6 modules: Allow absolute paths for any modules resolved via project replacement
Fixes #8240
2021-02-15 11:11:34 +01:00
Bjørn Erik Pedersen 4ffaeaf155 modules: Throw an error running hugo mod vendor on mountless module 2021-02-15 10:47:32 +01:00
susiwen8 bf55afd71f Fix some humanize issues
Fixes #7912
2021-02-14 18:30:59 +01:00
Anthony Fok 5f621df257 commands: Add PowerShell completion support
Revert "Refactor: Remove powershell support" with fixes

Thanks to Ben Mezger (@benmezger) for the original code.
See #8122

This reverts commit a7c515e1b5.
2021-02-09 13:37:36 -07:00
Anthony Fok 7118f89cf3 Refer to mage instead of make in comment regarding commitHash 2021-02-09 09:57:18 -07:00
Bjørn Erik Pedersen e6dd312812 markup/goldmark: Fix handling of legacy attribute config
See #7548
2021-02-09 09:23:18 +01:00
Bjørn Erik Pedersen 2681633db8 markup/goldmark: Add attributes support for blocks (tables etc.)
E.g.:

```
> foo
> bar
{.myclass}
```

There are some current limitations: For tables you can currently only apply it to the full table, and for lists the ul/ol-nodes only, e.g.:

```
* Fruit
  * Apple
  * Orange
  * Banana
  {.fruits}
* Dairy
  * Milk
  * Cheese
  {.dairies}
{.list}
```

Fixes #7548
2021-02-08 19:52:55 +01:00
Bjørn Erik Pedersen 1b24728256 deps: Update to Goldmark v1.3.2
Closes #8143
2021-02-08 12:16:21 +01:00
Bjørn Erik Pedersen 441b11beec Update to Dart Sass Protocol beta6
Note that this version is not backwards compatible, so you have to update the protocol binary.
2021-02-06 18:34:19 +01:00
Jeremy Epstein 4867cd1dea tpl/embedded: Exclude pages without Permalink from sitemap 2021-02-06 18:30:09 +01:00
Bjørn Erik Pedersen 92c6c40419 langs/i18n: Support translation files with suffix *.yml
Fixes #8212
2021-02-06 18:12:54 +01:00
Ben Mezger d36fd5b3ee Refactor: Write to stdout by default 2021-02-04 15:32:51 -07:00
Ben Mezger a7c515e1b5 Refactor: Remove powershell support 2021-02-04 15:32:51 -07:00
Ben Mezger 216b00f358 Feat: Add zsh, fish and powershell completion support
See issue #4296
2021-02-04 15:32:51 -07:00
Bjørn Erik Pedersen 144943798c github: Enable NPM tests on Windows
Fixes #8196
2021-02-01 11:32:17 +01:00
Bjørn Erik Pedersen 440fdb0eb9 deps: Update to esbuild v0.8.39
Fixes #8189
2021-02-01 11:28:12 +01:00
Pavlo Matiash b2a48dce58 Trim whitespace in elements written to hugo_stats.json
Fixes #7958
2021-02-01 09:32:39 +01:00
Baris Ceviz 35def0ae45 tpl/data: Add default user-agent header for getJSON requests 2021-02-01 09:31:02 +01:00
dependabot[bot] 2f9dadae40 build(deps): bump github.com/aws/aws-sdk-go from 1.35.0 to 1.36.33
Bumps [github.com/aws/aws-sdk-go](https://github.com/aws/aws-sdk-go) from 1.35.0 to 1.36.33.
- [Release notes](https://github.com/aws/aws-sdk-go/releases)
- [Changelog](https://github.com/aws/aws-sdk-go/blob/master/CHANGELOG.md)
- [Commits](https://github.com/aws/aws-sdk-go/compare/v1.35.0...v1.36.33)

Signed-off-by: dependabot[bot] <support@github.com>
2021-01-28 22:20:00 +01:00
Aleksandr Demakin ed3071b753 docs: Remove mention of a file size limit for readFile
The limit itself was removed in this PR: https://github.com/gohugoio/hugo/pull/8172.
2021-01-23 14:14:51 +01:00
Aleksandr Demakin ee9c136763 tpl/os: remove 1mb limit for readFile. 2021-01-23 00:39:14 +01:00
Bjørn Erik Pedersen 32b86076ee js: Add Inject config option
Fixes #8164
2021-01-22 23:43:44 +01:00
Cameron Moore 241b7483ea tpl: Fix race condition in text template baseof
Copy most of the htmltemplate cloning to the textemplate implementation
in the same function.
2021-01-22 19:25:45 +01:00
Bjørn Erik Pedersen e19a046c4b js: Add Shims option
This commit adds a new `shims` option to `js.Build` that allows swapping out a component with another.

Fixes #8165
2021-01-22 09:03:24 +01:00
Bjørn Erik Pedersen a1fe552fc9 Fix nilpointer in js.Build error handling
Fixes #8162
2021-01-21 10:09:33 +01:00
Bjørn Erik Pedersen a1a9f088b1 Merge commit 'e48ffb763572814a3788780bb9653dfa2daeae22' 2021-01-20 12:48:39 +01:00
Bjørn Erik Pedersen e48ffb7635 Squashed 'docs/' changes from 1de7a358c..ef9c4913c
ef9c4913c Clean up and removal of outdated examples
46122c9aa add godot tutorials to showcase
06d1d1ea2 Update scss-sass.md
1fc63c100 Spelling fix in 0.79.1 release notes
ad2f50e3d Update plainwords description (#1296)
33021d451 Update substr examples (#1304)
6b1cc59bb Release 0.80.0
521db8c6d Merge branch 'tempv0.80.0'
58626c2b3 releaser: Add release notes to /docs for release of 0.80.0
f81d118af dartsass: Dart Sass only supports `expanded` and `compressed`
7da6f54be Add Dart Sass support
b1f2661bb Replace jsconfig.js with jsconfig.json
38de0c1a4 Update index.md
223ceae80 Update index.md
f7ac0e59d Release v0.79.1
2d4583d43 Merge branch 'temp791-2'
1d34e609b releaser: Add release notes to /docs for release of 0.79.1
e26769988 Merge branch 'temp791'
75694d904 Fix Resource.ResourceType so it always returns MIME's main type
0f65d7783 Typo s/adds/add (#1298)
0b896b2c0 images: Add images.Overlay filter
0d4257dcd Clarify documentation on shimming
fcf601ddf Update index.html
6bf9bc1c1 Update index.html
1ce76bf3a Update index.html
e7d976eec Update index.html
db2996e64 Update index.html
245e5bfc9 news: Add post about Apple M1
3ad4115ed tpl: Add title parameter to YouTube shortcode
76ed976f8 Added two useful extensions to the list (#1243)
e5a30dd11 Update related.md
25cf8f48b Improve substr examples
e16e57e9a Update path.Split.md
2749b88fd Update path.Split.md
d76cad3ff Release 0.79.0
f5ccfbe98 releaser: Add release notes to /docs for release of 0.79.0
ebf1b87b0 Merge commit '9f1265fde4b9ef186148337c99f08601633b6056'
1f1e8f39c Allow setting the delimiter used for setting config via OS env, e.g. HUGO_
e9b1414dd deps: Update to github.com/evanw/esbuild 0.8.11 to 0.8.14
0f76cf66c docs: Regen docshelper
1ada5d47e Add menu params
1c120aef0 Revert "docs: Regenerate docshelper"
7b60b5624 docs: Regenerate docshelper

git-subtree-dir: docs
git-subtree-split: ef9c4913cd
2021-01-20 12:47:49 +01:00
Robert-André Mauchin 07ad283f68 build(deps): bump github.com/spf13/afero from 1.4.1 to 1.5.1
Signed-off-by: Robert-André Mauchin <zebob.m@gmail.com>
2021-01-19 17:25:20 +01:00
Andreas Richter 2c8b5d9165 pipes: Add external source map support to js.Build and Babel
Fixes #8132
2021-01-18 10:38:09 +01:00
Cameron Moore 0004a733c8 tpl: Fix metrics hint tracking
When tracking for cache hints, track the same template name as the call
to MeasureSince in Execute.  When referencing a partial "foo", the value
of `n` does not match `templ.Name()` (`partials/foo` versus
`partials/foo.html`).  This was causing hints to go untracked since
there was no existing metric to append the hint to.

Fixes #8125
2021-01-08 20:01:11 +01:00
Cameron Moore 8a26ab0bc5 tpl: Do not return errors in substr for out-of-bounds cases
Most other substr implementations don't error out in out-of-bounds cases
but simply return an empty string (or a value that's printed as an empty
string). We'll follow their lead and not exit template execution.  Allow
the user decide what to do with the empty result.

Fixes #8113
2021-01-08 10:13:10 +01:00
Cameron Moore 788e50ad3a tpl: Add missing test scenario for strings.Substr 2021-01-08 10:13:10 +01:00
Bjørn Erik Pedersen 4d2b6fc4c0 Run go mod tidy 2021-01-03 18:48:35 +01:00
Niklas Fasching 212e5e5542 deps: Update go-org to v1.4.0
- Add support for pretty urls [1]. Rewrite file links:
  1. replace the `.org` extension with `/` (`/foo.org` -> `/foo/`)
  2. prefix unrooted links with `../` as relative links start in the fake
  subdirectory `/foo/` rather than `/`
- Fix case-sensitivity of org drawer `🔚`

[1] https://gohugo.io/content-management/urls/#pretty-urls
2021-01-02 22:29:06 +01:00
Bjørn Erik Pedersen 4fdec67b11 rst: Adjust log level 2021-01-01 11:50:13 +01:00
hugoreleaser 9b681ecfbd releaser: Prepare repository for 0.81.0-DEV
[ci skip]
2020-12-31 13:49:02 +00:00
hugoreleaser 792ef0f41a releaser: Add release notes to /docs for release of 0.80.0
[ci skip]
2020-12-31 13:36:35 +00:00
hugoreleaser 5b3fc1c673 releaser: Bump versions for release of 0.80.0
[ci skip]
2020-12-31 13:36:35 +00:00
Bjørn Erik Pedersen 63a33afee7 Update 0.80.0-relnotes.md 2020-12-31 14:26:00 +01:00
hugoreleaser 69aa3d4599 releaser: Add release notes for 0.80.0
Rename to *-ready.md to continue.
[ci skip]
2020-12-31 13:09:24 +00:00
Bjørn Erik Pedersen ffbf5e45fa Allow Dart Sass transformations to be cached on disk
This enbles people to build their sites/themes on servers where the Dart Sass binary is not available.
2020-12-31 11:32:20 +01:00
Bjørn Erik Pedersen 48994ea766 dartsass: Dart Sass only supports expanded and compressed 2020-12-31 11:18:54 +01:00
Bjørn Erik Pedersen 428b0b3294 dartsass: Add missing OutputStyle option 2020-12-31 10:49:59 +01:00
Cameron Moore 1f7e9f7333 Update emoji import paths and version
Since emoji is v2, we must import it with the `/v2` suffix.  Doing so
allows the Go tools to detect the latest release.
2020-12-30 22:46:19 +01:00
Bjørn Erik Pedersen cea1574023 Add Dart Sass support
But note that the Dart Sass Embedded Protocol is still in beta (beta 5), a main release scheduled for Q1 2021.

Fixes #7380
Fixes #8102
2020-12-30 17:32:25 +01:00
Horst Gutmann f9f779786e GroupByParamDate now supports datetimes
Previously, the method only worked for date strings but not (for
instance) full RFC3339 datetime strings.
2020-12-28 17:50:55 +01:00
Bjørn Erik Pedersen a9718f44cd para: Skip para test when not on CI
Fixes #6963
2020-12-23 19:47:20 +01:00
Bjørn Erik Pedersen f802bb236a Update SECURITY.md 2020-12-22 10:09:59 +01:00
hugoreleaser 6c29418278 releaser: Add release notes to /docs for release of 0.79.1
[ci skip]
2020-12-19 17:09:29 +01:00
Bjørn Erik Pedersen 10ae7c3210 Improve LookPath 2020-12-19 17:03:07 +01:00
Patrick Kollitsch ae2d1bd52d docs: create a SECURITY.md
This file is used by Github as a tab on the repos homepage to access information about how to report security issues. The text is kept simple.

Will solve #8074
2020-12-18 17:55:49 +01:00
Bjørn Erik Pedersen 81975f847d Fix Resource.ResourceType so it always returns MIME's main type
The one exception being for the Page, which does not have a MIME type, in which you will get the value `page`.

Fixes #8052
2020-12-17 22:20:12 +01:00
Cameron Moore 8103188b9b para: Show more detail on failed time test
Give us more visibility into how badly a given host is failing in the
time test.

Updates #6963
2020-12-17 22:19:17 +01:00
Bjørn Erik Pedersen 3ba147e702 images: Add images.Overlay filter
This allows for constructs ala:

```
{{ $overlay := $img.Filter (images.Overlay $logo 50 50 )}}
```
Or:

```
{{ $logoFilter := (images.Overlay $logo 50 50 ) }}
{{ $overlay := $img | images.Filter $logoFilter }}
```

Which will overlay the logo in the top left corner (x=50, y=50) of `$img`.

Fixes #8057
Fixes #4595
Updates #6731
2020-12-17 09:14:18 +01:00
Bjørn Erik Pedersen a2d146ec32 tpl: Regenerate templates 2020-12-16 12:20:02 +01:00
Maciej Sawicki d2d493ab5d tpl: Fix series detection in opengraph
When inside front matter you specified series with spaces,
then the opengraph template wouldn't detect other articles,
because in `.Site.Taxonomies.series` they are stored by 
urlized key.

Example:

```yaml
# in front matter
series:
    - My Series
```

```gohtml
{{/* in a template */}}
{{- $series := index .Site.Taxonomies.series$name }}

{{/* was resolved to */}}
{{- $series := index {'my-series': ...} "MySeries" }}
```
2020-12-16 12:13:30 +01:00
真夜 ce96895deb hugolib/paths: Fix typo 2020-12-16 12:12:14 +01:00
Phil Davis 04b89857e1 all: Fix minor typos 2020-12-16 12:11:32 +01:00
Bjørn Erik Pedersen 21fa1e86f2 Fix BenchmarkMergeByLanguage
Fixes #7914
2020-12-09 17:47:10 +01:00
Anthony Fok c84ad8db82 deps: Bump github.com/spf13/cobra from 0.15.0 to 0.20.0
The substring match in TestExecute deploy test is adjusted accordingly.
2020-12-04 20:43:03 -07:00
Patrick Kollitsch 4e0acb89b7 chore: configure proper link to discourse.gohugo.io (#8020)
* chore: configure proper link to discourse.gohugo.io 

This adds a configuration file to the issue templates for this repo. In this config file, an issue template is added that will look like the existing issue templates, but on click will lead directly to the discourse forum instead of hoping that people read what it says there. The support.md can be deleted.

* chore: remove obsolete support.md configuration

* chore: remove obsolete autoclosing workflow
2020-12-04 10:04:35 +01:00
Bjørn Erik Pedersen 718e09ed4b tpl/internal/go_templates: Revert formatting
Should make future fork synch easier.
2020-12-03 13:47:43 +01:00
Bjørn Erik Pedersen d90e37e0c6 all: Format code with gofumpt
See https://github.com/mvdan/gofumpt
2020-12-03 13:12:58 +01:00
dependabot[bot] 32471b57bd build(deps): bump github.com/evanw/esbuild from 0.8.15 to 0.8.17
Bumps [github.com/evanw/esbuild](https://github.com/evanw/esbuild) from 0.8.15 to 0.8.17.
- [Release notes](https://github.com/evanw/esbuild/releases)
- [Changelog](https://github.com/evanw/esbuild/blob/master/CHANGELOG.md)
- [Commits](https://github.com/evanw/esbuild/compare/v0.8.15...v0.8.17)

Signed-off-by: dependabot[bot] <support@github.com>
2020-12-02 13:04:16 +01:00
Andrew Zenk 4fc918e02c tpl: Add title parameter to YouTube shortcode 2020-12-02 12:53:53 +01:00
sth 0ad378b09c Use --baseURL path for live-reload URL
Fixes #6595
2020-12-02 12:52:26 +01:00
ivan-meridianbanc-com aebfe156fb Fix RelURL and AbsURL when path starts with language 2020-12-02 12:47:01 +01:00
dependabot[bot] 907d9e9268 build(deps): bump github.com/getkin/kin-openapi from 0.31.0 to 0.32.0
Bumps [github.com/getkin/kin-openapi](https://github.com/getkin/kin-openapi) from 0.31.0 to 0.32.0.
- [Release notes](https://github.com/getkin/kin-openapi/releases)
- [Commits](https://github.com/getkin/kin-openapi/compare/v0.31.0...v0.32.0)

Signed-off-by: dependabot[bot] <support@github.com>
2020-12-02 12:26:27 +01:00
Cameron Moore 5862fd2a60 tpl: Fix substr when length parameter is zero
When length parameter is zero, always return an empty string.

Updates #7993
2020-12-01 23:20:04 +01:00
Cameron Moore 64789fb5dc tpl: Refactor and fix substr logic
Fix miscalculations when start is negative.  Results should now match
PHP substr.

Fixes #7993
2020-11-28 11:53:46 +01:00
hugoreleaser 32d4bf68da releaser: Prepare repository for 0.80.0-DEV
[ci skip]
2020-11-27 09:19:04 +00:00
hugoreleaser 1415efdcd8 releaser: Add release notes to /docs for release of 0.79.0
[ci skip]
2020-11-27 09:06:36 +00:00
hugoreleaser 4e6bf7907d releaser: Bump versions for release of 0.79.0
[ci skip]
2020-11-27 09:06:36 +00:00
Bjørn Erik Pedersen 50be4370b0 Update 0.79.0-relnotes.md 2020-11-27 09:55:51 +01:00
hugoreleaser 3d2e6a30d4 releaser: Add release notes for 0.79.0
Rename to *-ready.md to continue.
[ci skip]
2020-11-27 08:44:33 +00:00
Bjørn Erik Pedersen 4f1e4bb3fe Merge commit '9f1265fde4b9ef186148337c99f08601633b6056' 2020-11-27 09:30:05 +01:00
Bjørn Erik Pedersen 9f1265fde4 Squashed 'docs/' changes from 57c1d1a67..1de7a358c
1de7a358c Clarify that "with" blocks do not render with empty values (#1287)
b48de8b0a Update js.md
e0124e4b1 Update js.md
087b39d74 Update hosting-on-render.md (#1286)
8f02b5412 Update js.md (#1284)
8dd8a8d1d Add link to "Build Websites with Hugo" book (#1174)
ae2dc138a Fix typo in page bundles (#1283)
ab14bfec3 Update configuration directory section
17da77ff1 Update multilingual.md (#1280)
5bce8db3a Fix for site-hierarchy image, issue #60
9d7a2366d Fix typo
ad4210c41 Fix typo
c88bc0383 Fix orphan branch url (#1262)
1cf6cf5b3 Hugo 0.78.2
538c3cb86 Merge branch 'tempv0.78.2'
e5e07fc81 releaser: Add release notes to /docs for release of 0.78.2
120a61a47 Fixed wrong var assignment example
4cebbb1a7 Ignore remote JSON errors (for now)
618fcf9ba Add a link to modules config option 'replacements'
e12722779 Fix typo ("wil" -> "will") (#1273)
0670e9894 Update js.md
5bde834cf Update GH docs to say "main" as default branch
26312f93d Update index.md
eb6f51df1 Update js.md
b890dc84d Merge branch 'tempv0.78.1'
6b73ea450 releaser: Add release notes to /docs for release of 0.78.1
46e582112 Update starter-kits.md (#1268)
a62786235 Update 404 docs: GitLab auto-detects 404.html (#1173)
cbd4fd2d9 Fix typo (#1271)
2ba3f9386 Update js.md
7b5109d90 Update js.md
bc75bc962 Release 0.78.0
0b2e8b0f1 releaser: Add release notes to /docs for release of 0.78.0
9ecba8480 Merge commit 'b74591123eac47a20d1f26ff3e2d291cd9c5cfc0'
60a475df7 js: Add avoidTDZ option
3b895261f Make js.Build fully support modules

git-subtree-dir: docs
git-subtree-split: 1de7a358ca
2020-11-27 09:26:24 +01:00
Bjørn Erik Pedersen d162bbd799 publisher: Fix memory usage in writeStats
```
name                     old time/op    new time/op    delta
ClassCollectorWriter-16    72.1µs ± 0%    32.3µs ± 0%  -55.17%  (p=0.029 n=4+4)

name                     old alloc/op   new alloc/op   delta
ClassCollectorWriter-16    85.9kB ± 0%    35.1kB ± 0%  -59.16%  (p=0.029 n=4+4)

name                     old allocs/op  new allocs/op  delta
ClassCollectorWriter-16       329 ± 0%       149 ± 0%  -54.71%  (p=0.029 n=4+4)
```

Fixes #7945
2020-11-27 09:13:16 +01:00
dependabot[bot] 17e0bbe821 build(deps): bump gopkg.in/yaml.v2 from 2.3.0 to 2.4.0
Bumps [gopkg.in/yaml.v2](https://github.com/go-yaml/yaml) from 2.3.0 to 2.4.0.
- [Release notes](https://github.com/go-yaml/yaml/releases)
- [Commits](https://github.com/go-yaml/yaml/compare/v2.3.0...v2.4.0)

Signed-off-by: dependabot[bot] <support@github.com>
2020-11-26 21:41:21 +01:00
Bjørn Erik Pedersen e442cf30a2 Fix server rebuild issue with partials referenced from render hooks
Fixes #7990
2020-11-26 20:41:54 +01:00
Bjørn Erik Pedersen 7e223b3baa Allow setting the delimiter used for setting config via OS env, e.g. HUGO_
Fixes #7829
2020-11-25 20:34:34 +01:00
Bjørn Erik Pedersen 8a6e706053 deps: Update to github.com/evanw/esbuild 0.8.11 to 0.8.14
Closes #7986
2020-11-25 17:39:51 +01:00
Cameron Moore 34061706e6 output: Add more layout lookup tests
Add more tests to cover more cases and to help with documentation and
discussion of template lookup order.

Updates #7964
2020-11-25 12:52:33 +01:00
dependabot[bot] 6f7633df7d build(deps): bump github.com/google/go-cmp from 0.5.2 to 0.5.3
Bumps [github.com/google/go-cmp](https://github.com/google/go-cmp) from 0.5.2 to 0.5.3.
- [Release notes](https://github.com/google/go-cmp/releases)
- [Commits](https://github.com/google/go-cmp/compare/v0.5.2...v0.5.3)

Signed-off-by: dependabot[bot] <support@github.com>
2020-11-24 20:20:40 +01:00
Christian Oliff a546059a9c examples: Remove unneeded meta tag from blog example
```html
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
```
This was only needed for IE10 and lower (which are no longer supported) and chromeframe which was a Google plugin for IE8 and lower and was discontinued many years ago. So this meta tag can be safely removed.
2020-11-24 20:20:04 +01:00
dependabot[bot] b5d906e31e build(deps): bump github.com/getkin/kin-openapi from 0.30.0 to 0.31.0
Bumps [github.com/getkin/kin-openapi](https://github.com/getkin/kin-openapi) from 0.30.0 to 0.31.0.
- [Release notes](https://github.com/getkin/kin-openapi/releases)
- [Commits](https://github.com/getkin/kin-openapi/compare/v0.30.0...v0.31.0)

Signed-off-by: dependabot[bot] <support@github.com>
2020-11-24 14:48:09 +01:00
Bjørn Erik Pedersen fd70bdafe7 docs: Regen docshelper 2020-11-24 13:49:01 +01:00
David Jones 8f5c9a747f Add menu params
Fixes #7951
2020-11-22 22:09:59 +01:00
SatowTakeshi e4fcb672ed resources: Preserve url set in frontmatter without sanitizing
related #6007 (already closed)
2020-11-21 23:37:58 +01:00
Bjørn Erik Pedersen 18c13adcd4 watcher: Add file deleted by accident
See #7972
2020-11-21 17:21:14 +01:00
Bjørn Erik Pedersen 20a35374a3 Revert "docs: Regenerate docshelper"
This reverts commit caf16c2085.

Closes #7972
2020-11-21 12:48:48 +01:00
Bjørn Erik Pedersen caf16c2085 docs: Regenerate docshelper 2020-11-20 09:32:16 +01:00
Bjørn Erik Pedersen b298c06e05 deps: Update to Chroma v0.8.2
Closes #7970
2020-11-20 09:30:05 +01:00
dependabot[bot] 55e290af41 build(deps): bump github.com/evanw/esbuild from 0.8.8 to 0.8.11
Bumps [github.com/evanw/esbuild](https://github.com/evanw/esbuild) from 0.8.8 to 0.8.11.
- [Release notes](https://github.com/evanw/esbuild/releases)
- [Changelog](https://github.com/evanw/esbuild/blob/master/CHANGELOG.md)
- [Commits](https://github.com/evanw/esbuild/compare/v0.8.8...v0.8.11)

Signed-off-by: dependabot[bot] <support@github.com>
2020-11-19 09:51:30 +01:00
dependabot[bot] 506a190a82 build(deps): bump github.com/getkin/kin-openapi from 0.26.0 to 0.30.0
Bumps [github.com/getkin/kin-openapi](https://github.com/getkin/kin-openapi) from 0.26.0 to 0.30.0.
- [Release notes](https://github.com/getkin/kin-openapi/releases)
- [Commits](https://github.com/getkin/kin-openapi/compare/v0.26.0...v0.30.0)

Signed-off-by: dependabot[bot] <support@github.com>
2020-11-16 12:33:31 +01:00
dependabot[bot] fc81de6439 build(deps): bump github.com/evanw/esbuild from 0.8.6 to 0.8.8
Bumps [github.com/evanw/esbuild](https://github.com/evanw/esbuild) from 0.8.6 to 0.8.8.
- [Release notes](https://github.com/evanw/esbuild/releases)
- [Changelog](https://github.com/evanw/esbuild/blob/master/CHANGELOG.md)
- [Commits](https://github.com/evanw/esbuild/compare/v0.8.6...v0.8.8)

Signed-off-by: dependabot[bot] <support@github.com>
2020-11-16 12:32:33 +01:00
hugoreleaser fcaa324e3c releaser: Prepare repository for 0.79.0-DEV
[ci skip]
2020-11-13 10:19:23 +00:00
hugoreleaser 959724f0e0 releaser: Add release notes to /docs for release of 0.78.2
[ci skip]
2020-11-13 10:07:00 +00:00
hugoreleaser a3012d85d1 releaser: Bump versions for release of 0.78.2
[ci skip]
2020-11-13 10:07:00 +00:00
hugoreleaser fc7f739275 releaser: Add release notes for 0.78.2
[ci skip]
2020-11-13 10:07:00 +00:00
Bjørn Erik Pedersen 78f227b664 js: Let ESBuild handle all imports from node_modules
This commit fixes some issues where modules in /assets share the same name as in node_modules.

This was not intended, and with this commit the node_modules-components should be isolated. If you want to redefine something inside node_modules, use the `defines` option.

Fixes #7948
2020-11-13 08:54:29 +01:00
dependabot[bot] 5e03f644a4 build(deps): bump github.com/evanw/esbuild from 0.8.5 to 0.8.6
Bumps [github.com/evanw/esbuild](https://github.com/evanw/esbuild) from 0.8.5 to 0.8.6.
- [Release notes](https://github.com/evanw/esbuild/releases)
- [Changelog](https://github.com/evanw/esbuild/blob/master/CHANGELOG.md)
- [Commits](https://github.com/evanw/esbuild/compare/v0.8.5...v0.8.6)

Signed-off-by: dependabot[bot] <support@github.com>
2020-11-12 13:59:18 +01:00
dependabot[bot] a92ef20ff6 build(deps): bump github.com/evanw/esbuild from 0.8.4 to 0.8.5
Bumps [github.com/evanw/esbuild](https://github.com/evanw/esbuild) from 0.8.4 to 0.8.5.
- [Release notes](https://github.com/evanw/esbuild/releases)
- [Changelog](https://github.com/evanw/esbuild/blob/master/CHANGELOG.md)
- [Commits](https://github.com/evanw/esbuild/compare/v0.8.4...v0.8.5)

Signed-off-by: dependabot[bot] <support@github.com>
2020-11-11 23:00:27 +01:00
dependabot[bot] 0d54a84406 build(deps): bump github.com/getkin/kin-openapi from 0.22.1 to 0.26.0
Bumps [github.com/getkin/kin-openapi](https://github.com/getkin/kin-openapi) from 0.22.1 to 0.26.0.
- [Release notes](https://github.com/getkin/kin-openapi/releases)
- [Commits](https://github.com/getkin/kin-openapi/compare/v0.22.1...v0.26.0)

Signed-off-by: dependabot[bot] <support@github.com>
2020-11-08 12:44:01 +01:00
Mackenzie Morgan 943f3c932f Update GH docs to say "main" as default branch 2020-11-06 20:57:52 +01:00
AdamKorcz 4f20bf29eb Updated year in header 2020-11-06 13:19:18 +01:00
AdamKorcz 4c613d5d5d Added first fuzzer 2020-11-06 13:19:18 +01:00
dependabot[bot] 82a182e52c build(deps): bump github.com/frankban/quicktest from 1.11.1 to 1.11.2
Bumps [github.com/frankban/quicktest](https://github.com/frankban/quicktest) from 1.11.1 to 1.11.2.
- [Release notes](https://github.com/frankban/quicktest/releases)
- [Commits](https://github.com/frankban/quicktest/compare/v1.11.1...v1.11.2)

Signed-off-by: dependabot[bot] <support@github.com>
2020-11-06 13:18:22 +01:00
dependabot[bot] dfc662b208 build(deps): bump golang.org/x/text from 0.3.3 to 0.3.4
Bumps [golang.org/x/text](https://github.com/golang/text) from 0.3.3 to 0.3.4.
- [Release notes](https://github.com/golang/text/releases)
- [Commits](https://github.com/golang/text/compare/v0.3.3...v0.3.4)

Signed-off-by: dependabot[bot] <support@github.com>
2020-11-06 09:09:13 +01:00
dependabot[bot] 2f0917cc01 build(deps): bump github.com/evanw/esbuild from 0.8.3 to 0.8.4
Bumps [github.com/evanw/esbuild](https://github.com/evanw/esbuild) from 0.8.3 to 0.8.4.
- [Release notes](https://github.com/evanw/esbuild/releases)
- [Changelog](https://github.com/evanw/esbuild/blob/master/CHANGELOG.md)
- [Commits](https://github.com/evanw/esbuild/compare/v0.8.3...v0.8.4)

Signed-off-by: dependabot[bot] <support@github.com>
2020-11-06 09:01:32 +01:00
hugoreleaser 7565cda1ff releaser: Prepare repository for 0.79.0-DEV
[ci skip]
2020-11-05 09:50:35 +00:00
hugoreleaser 347f2de67d releaser: Add release notes to /docs for release of 0.78.1
[ci skip]
2020-11-05 09:38:59 +00:00
hugoreleaser 210f6d38ac releaser: Bump versions for release of 0.78.1
[ci skip]
2020-11-05 09:38:59 +00:00
hugoreleaser 03f87f8f06 releaser: Add release notes for 0.78.1
[ci skip]
2020-11-05 09:38:59 +00:00
Bjørn Erik Pedersen 3437174c3a Disable NPM test on Travis on Windows
For now.
2020-11-05 09:56:22 +01:00
Bjørn Erik Pedersen f66302ca05 travis: Install nodejs on Windows 2020-11-05 07:51:41 +01:00
Bjørn Erik Pedersen 944150bafb js: Remove external source map option
It was merged by accident and the implementation does not look correct.

Fixes #7932
2020-11-04 23:04:12 +01:00
Bjørn Erik Pedersen bf2837a314 js: Misc fixes
* Fix resolve of package.json deps in submodules
* Fix directory logic for writing assets/jsconfig.json

Fixes #7924
Fixes #7923
2020-11-04 19:21:43 +01:00
hugoreleaser cf6131dc18 releaser: Prepare repository for 0.79.0-DEV
[ci skip]
2020-11-03 13:25:12 +00:00
hugoreleaser fd62817bba releaser: Add release notes to /docs for release of 0.78.0
[ci skip]
2020-11-03 13:13:12 +00:00
hugoreleaser 3ebe83aea7 releaser: Bump versions for release of 0.78.0
[ci skip]
2020-11-03 13:13:12 +00:00
Bjørn Erik Pedersen 0c16debc7f Update 0.78.0-relnotes.md 2020-11-03 14:03:53 +01:00
hugoreleaser 794e1f9e72 releaser: Add release notes for 0.78.0
Rename to *-ready.md to continue.
[ci skip]
2020-11-03 12:23:42 +00:00
Bjørn Erik Pedersen c64e9504d8 Merge commit 'b74591123eac47a20d1f26ff3e2d291cd9c5cfc0' 2020-11-03 13:05:34 +01:00
Bjørn Erik Pedersen b74591123e Squashed 'docs/' changes from d1157b687..57c1d1a67
57c1d1a67 Add note about issue with Instagram shortcode
2a4355113 Add example for regional language tags (#1139)
5e9a60fc0 Format dates with "th", "nd", and "rd". (#1254)
43df9a7f6 Update index.md
f15f32590 Update index.md
5a15be93d Update configuration.md
e71c1c545 Update configuration.md
5fd0439ff Release Hugo 0.77.0
5b875477c releaser: Add release notes to /docs for release of 0.77.0
09a2a3199 docs: Regen docs helper
bebef9bbe Merge commit '9cabb46f68bae01aeb1859727dcb21e8a10f5ec7'
f5ed02685 tpl: Refactor time.AsTime location implementation
f3b8eccd2 tpl: Update Hugo time to support optional [LOCATION] parameter

git-subtree-dir: docs
git-subtree-split: 57c1d1a67b
2020-11-03 13:04:56 +01:00
Bjørn Erik Pedersen 3b2fe3cd33 js: Add avoidTDZ option
Fixes #7865
2020-11-03 13:04:37 +01:00
Bjørn Erik Pedersen 85e4dd7370 Make js.Build fully support modules
Fixes #7816
Fixes #7777
Fixes #7916
2020-11-03 13:04:37 +01:00
Andreas Richter 3089fc0ba1 js.Build: Generate tsconfig files
Updates #7777

Added support to allow SourceMap files to be external to the build.
In addition added more information when the js compilation has an error.
Correctly append sourceMappingURL to output file.
Fix merge conflict.
2020-11-03 13:04:37 +01:00
hugoreleaser e10e36cf70 releaser: Prepare repository for 0.78.0-DEV
[ci skip]
2020-10-30 10:24:27 +00:00
hugoreleaser ef290125c9 releaser: Add release notes to /docs for release of 0.77.0
[ci skip]
2020-10-30 10:12:16 +00:00
hugoreleaser 5d2fceecaf releaser: Bump versions for release of 0.77.0
[ci skip]
2020-10-30 10:12:16 +00:00
Bjørn Erik Pedersen 0696df6686 Release 0.77.0 2020-10-30 11:05:21 +01:00
Bjørn Erik Pedersen 5ba49c8778 Update 0.77.0-relnotes.md
[ci skip]
2020-10-30 10:39:04 +01:00
hugoreleaser c3ccda8fab releaser: Add release notes for 0.77.0
Rename to *-ready.md to continue.
[ci skip]
2020-10-30 09:22:42 +00:00
Bjørn Erik Pedersen beabc8d998 modules: Allow absolute paths for project imports
Fixes #7910
2020-10-30 10:14:08 +01:00
Bjørn Erik Pedersen 332b65e4cc docs: Regen docs helper 2020-10-30 09:52:32 +01:00
Bjørn Erik Pedersen 3553fc533a Merge commit '9cabb46f68bae01aeb1859727dcb21e8a10f5ec7' 2020-10-30 09:50:15 +01:00
Bjørn Erik Pedersen 9cabb46f68 Squashed 'docs/' changes from 9abd3043a..d1157b687
d1157b687 Fix typo -- missing word in title
34c9a9ff3 Remove Hartwell Insurance subpage broken link
d42f6d8eb Fix strings.Repeat documentation
09b49debb Release 0.76.5
149877735 Merge branch 'tempv0.76.5'
72ffeb026 releaser: Add release notes to /docs for release of 0.76.5
4150d8ae8 Fixed typo: update PrevPage to Prev
c3e630db1 Update index.md
deb7520a8 Release 0.76.4
f58bd7134 Merge branch 'tempv0.76.4'
2581fe4bc releaser: Add release notes to /docs for release of 0.76.4
26d8417fc Release 0.76.3
34c49e06a Merge branch 'tempv0.76.3'
0de2af2ef releaser: Add release notes to /docs for release of 0.76.3
cce12c0f7 Add missing closing quotes and fix code-block lang (#1250)
8c1c80d9f Update AMP link (#1251)
7b1211ffa Fix typos in multilingual.md
29e9d70fd Update index.md
172a5480b Release 0.76.2
93ff424d3 Merge branch 'temp762'
3cad3c23a releaser: Add release notes to /docs for release of 0.76.2
610221964 Update index.md
8a9d31709 Release 0.76.1
64b245aa4 Merge branch 'temp761'
f19469ff8 releaser: Add release notes to /docs for release of 0.76.1
97f0ed030 Update front-matter.md
cca71f263 Update index.md
23c64f6a3 Fix typo in 0.76.0 release note
5f79e034d Update index.md
b66567de2 netlify: Bump to Hugo 0.76.0
a3e30300d Release 0.76.0
3b057e8fe releaser: Add release notes to /docs for release of 0.76.0
7fa1cd912 docs: Regen docshelper
769712aec Merge commit 'e5568488051a571df48401e03f1304b95dbc9028'
70ce6ae33 pagemeta: Make BuildConfig.Render an enum
a78d3849f Allow cascade to be a slice with a _target discriminator
705fea656 Add force flag to server redirects config
04e4e1cc1 tpl: Add Do Not Track (dnt) option to Vimeo shortcode
025c19fe1 Fix CLI example for PostCSS 8
0c70c47b2 markup/asciidocext: Add preserveTOC option

git-subtree-dir: docs
git-subtree-split: d1157b687e
2020-10-30 09:49:15 +01:00
Bjørn Erik Pedersen 173187e263 Add module.replacements
Fixes #7904
Fixes #7908
2020-10-30 09:41:05 +01:00
Bjørn Erik Pedersen 8a1c637c44 Fix setting HUGO_MODULE_PROXY etc. via env vars
Fixes #7903
2020-10-30 09:41:04 +01:00
Cameron Moore 6d95dc9d74 tpl: Fix reflection bug in merge
Value.Type().Key() must only be called on map values.

Fixes #7899
2020-10-29 19:19:41 +01:00
José Moreira 56a343507c deploy: Do not call CDN service invalidation when executing a dry run deployment
Currently, if cache invalidation is enabled when running `hugo deploy --dryRun` with , the deployer does not take the dry run flag into consideration and triggers CloudFront/GoogleCloudCDN cache invalidation if any of those services are configured.

This change will instead print a feedback message if a dry run is in effect and quiet mode is not enabled.

Fixes #7884
2020-10-28 11:19:40 +01:00
Bhavin Gandhi d48a98c477 create: Pass editor arguments from newContentEditor correctly
If newContentEditor has editor name with arguments like `emacsclient
-n`, it fails with `executable file not found in $PATH`. This change
parses the value correctly and passes it to the given editor.

Signed-off-by: Bhavin Gandhi <bhavin7392@gmail.com>
2020-10-24 20:34:03 +02:00
Anthony Fok 3261678f63 deps: Bump github.com/spf13/cobra from 0.0.7 to 1.1.1
Cobra 1.1.1 fixes internal formatting for go-md2man v2 (which caused
man page generation e.g. "hugo gen man" to be broken since Cobra 0.0.6).
See spf13/cobra#1049 for context.
2020-10-24 03:39:53 -06:00
Eric Hagman f465c5c307 build: Allow optional "nodeploy" tag to exclude deploy command from bin
Fixes #7826
2020-10-23 09:03:41 +02:00
Gareth Watts 3400aff258 Allow cascade _target to work with non toml fm
The TOML lib unmarshals slices of string maps to []map[string]interface{}
whereas YAML and JSON decode to []interface{}

The existing tests only check for TOML working correctly, and _target
with cascade did not work at all for frontmatter defined in other formats.

Add a function to normalize those slices

Fixes #7874
2020-10-22 23:00:19 +02:00
Bjørn Erik Pedersen fdfa4a5fe6 Allow getJSON errors to be ignored
This change is mostly motivated to get a more stable CI build (we're building the Hugo site there, with Instagram and Twitter shortcodes sometimes failing).

Fixes #7866
2020-10-22 09:09:29 +02:00
dependabot[bot] 8cbe2bbfad build(deps): bump github.com/evanw/esbuild from 0.7.15 to 0.7.18
Bumps [github.com/evanw/esbuild](https://github.com/evanw/esbuild) from 0.7.15 to 0.7.18.
- [Release notes](https://github.com/evanw/esbuild/releases)
- [Changelog](https://github.com/evanw/esbuild/blob/master/CHANGELOG.md)
- [Commits](https://github.com/evanw/esbuild/compare/v0.7.15...v0.7.18)

Signed-off-by: dependabot[bot] <support@github.com>
2020-10-21 10:19:40 +02:00
Cameron Moore 807db97af8 tpl: Refactor time.AsTime location implementation 2020-10-21 09:49:25 +02:00
Mark Johnson 26eeb29147 tpl: Update Hugo time to support optional [LOCATION] parameter 2020-10-21 09:49:25 +02:00
Bjørn Erik Pedersen b886fa46bb Revert "Add benchmark for building docs site"
We already have a lot of site building benchmarks. The main problem with adding the "Hugo site docs" to the list is that it cannot easiliy  be compared to any previous release, because its content/template/whatever has changed.

This reverts commit 837e084bbe.
2020-10-17 00:37:42 +02:00
Cameron Moore 14bce18a6c highlight: Avoid making unnecessary allocation
Avoid creating a local copy of the highlight configuration when no
options are passed.

Benchmarks of building the docs site:

name        old time/op    new time/op    delta
DocsSite-2     1.94s ± 4%     1.93s ± 4%    ~     (p=0.841 n=5+5)

name        old alloc/op   new alloc/op   delta
DocsSite-2     666MB ± 1%     656MB ± 0%  -1.48%  (p=0.008 n=5+5)

name        old allocs/op  new allocs/op  delta
DocsSite-2     8.85M ± 0%     8.76M ± 0%  -1.04%  (p=0.029 n=4+4)
2020-10-16 21:14:02 +02:00
Cameron Moore 837e084bbe Add benchmark for building docs site 2020-10-16 21:13:39 +02:00
Cameron Moore 08e4f9ff9c embedded: Always show page number when 5 pages or less
Fixes #7523
2020-10-16 16:16:49 +02:00
Cameron Moore acfa153863 output: Improve layout path construction 2020-10-15 20:54:47 +02:00
dependabot[bot] f033d9f01d build(deps): bump github.com/frankban/quicktest from 1.11.0 to 1.11.1
Bumps [github.com/frankban/quicktest](https://github.com/frankban/quicktest) from 1.11.0 to 1.11.1.
- [Release notes](https://github.com/frankban/quicktest/releases)
- [Commits](https://github.com/frankban/quicktest/compare/v1.11.0...v1.11.1)

Signed-off-by: dependabot[bot] <support@github.com>
2020-10-15 00:01:45 +02:00
dependabot[bot] 59fe279424 build(deps): bump github.com/evanw/esbuild from 0.7.14 to 0.7.15
Bumps [github.com/evanw/esbuild](https://github.com/evanw/esbuild) from 0.7.14 to 0.7.15.
- [Release notes](https://github.com/evanw/esbuild/releases)
- [Changelog](https://github.com/evanw/esbuild/blob/master/CHANGELOG.md)
- [Commits](https://github.com/evanw/esbuild/compare/v0.7.14...v0.7.15)

Signed-off-by: dependabot[bot] <support@github.com>
2020-10-14 21:59:26 +02:00
Bjørn Erik Pedersen 62119022d1 Merge branch 'release-0.76.5' 2020-10-14 17:44:47 +02:00
hugoreleaser 2f3f41f736 releaser: Prepare repository for 0.77.0-DEV
[ci skip]
2020-10-14 15:28:16 +00:00
hugoreleaser 60f0725b3e releaser: Add release notes to /docs for release of 0.76.5
[ci skip]
2020-10-14 15:15:22 +00:00
hugoreleaser dcf70ea5a5 releaser: Bump versions for release of 0.76.5
[ci skip]
2020-10-14 15:15:22 +00:00
hugoreleaser 7487c0abf2 releaser: Add release notes for 0.76.5
[ci skip]
2020-10-14 15:15:22 +00:00
Bjørn Erik Pedersen 79a022a15c Render aliases even if render=link
Fixes #7832
2020-10-14 17:06:34 +02:00
Bjørn Erik Pedersen ead5799f7e Render aliases even if render=link
Fixes #7832
2020-10-14 16:59:37 +02:00
dependabot[bot] d57be11324 build(deps): bump github.com/spf13/afero from 1.4.0 to 1.4.1
Bumps [github.com/spf13/afero](https://github.com/spf13/afero) from 1.4.0 to 1.4.1.
- [Release notes](https://github.com/spf13/afero/releases)
- [Commits](https://github.com/spf13/afero/compare/v1.4.0...v1.4.1)

Signed-off-by: dependabot[bot] <support@github.com>
2020-10-12 22:54:09 +02:00
dependabot[bot] d070596694 build(deps): bump github.com/evanw/esbuild from 0.7.9 to 0.7.14
Bumps [github.com/evanw/esbuild](https://github.com/evanw/esbuild) from 0.7.9 to 0.7.14.
- [Release notes](https://github.com/evanw/esbuild/releases)
- [Changelog](https://github.com/evanw/esbuild/blob/master/CHANGELOG.md)
- [Commits](https://github.com/evanw/esbuild/compare/v0.7.9...v0.7.14)

Signed-off-by: dependabot[bot] <support@github.com>
2020-10-12 22:51:34 +02:00
Daniel Sutton f5ea359dd3 docker: Update to Go 1.15 and Alpine 3.12 2020-10-12 22:51:08 +02:00
Cameron Moore 78b26d538c output: Test all lookup permutations in TestLayout 2020-10-12 22:24:47 +02:00
Cameron Moore 28179bd556 output: Reformat TestLayout table 2020-10-12 22:24:47 +02:00
hugoreleaser fef057b489 releaser: Prepare repository for 0.77.0-DEV
[ci skip]
2020-10-12 08:45:25 +00:00
hugoreleaser 50dfe40b91 releaser: Add release notes to /docs for release of 0.76.4
[ci skip]
2020-10-12 08:32:44 +00:00
hugoreleaser 1ef4211fea releaser: Bump versions for release of 0.76.4
[ci skip]
2020-10-12 08:32:44 +00:00
hugoreleaser b148063ec0 releaser: Add release notes for 0.76.4
[ci skip]
2020-10-12 08:32:44 +00:00
Anthony Fok e9a7ebaf67 snap: Install postcss v8 explicitly as it is now a peer dependency
Fix Snap build failures since 2020-09-21
2020-10-09 12:23:38 -06:00
Bjørn Erik Pedersen 506820435c lang/i18n: Fix for language code case issue with pt-br etc.
Fixes #7804
2020-10-09 18:02:43 +02:00
Bjørn Erik Pedersen 49972d0792 Merge branch 'release-0.76.3' 2020-10-08 19:33:23 +02:00
Bjørn Erik Pedersen c98132e30e Add merge helper 2020-10-08 19:32:53 +02:00
hugoreleaser af19253f43 releaser: Prepare repository for 0.77.0-DEV
[ci skip]
2020-10-08 17:20:03 +00:00
hugoreleaser e96234590d releaser: Add release notes to /docs for release of 0.76.3
[ci skip]
2020-10-08 17:07:29 +00:00
hugoreleaser d62bc74770 releaser: Bump versions for release of 0.76.3
[ci skip]
2020-10-08 17:07:29 +00:00
hugoreleaser 1b1d62fdc9 releaser: Add release notes for 0.76.3
[ci skip]
2020-10-08 17:07:29 +00:00
Bjørn Erik Pedersen 33e9d79b78 langs/i18n: Add workaround for known language, but missing plural rule error
Closes #7798
2020-10-08 14:20:18 +02:00
Bjørn Erik Pedersen fc6abc39c7 langs/i18n: Fix for bare TOML keys
Hugo 0.76.0 updated go-i18n from v1 to v2. This allowed us to set the TOML unmarshaler to use, so we set the one we use in other places in Hugo.

But that does not support dotted bare keys, which caused some breakage in the wild.

This commit fixes that by:

* Using go-toml for language files
* Updating go-toml to the latest version
2020-10-08 14:20:18 +02:00
hugoreleaser 18ed22be5c releaser: Prepare repository for 0.77.0-DEV
[ci skip]
2020-10-07 09:11:54 +00:00
1247 changed files with 41450 additions and 12637 deletions
+1 -2
View File
@@ -1,6 +1,6 @@
defaults: &defaults
docker:
- image: bepsays/ci-goreleaser:1.15.1
- image: bepsays/ci-goreleaser:1.17.5
environment:
CGO_ENABLED: "0"
@@ -18,7 +18,6 @@ jobs:
go mod download
sleep 5
go mod verify
go test -p 1 ./...
- persist_to_workspace:
root: .
paths: .
+5
View File
@@ -0,0 +1,5 @@
blank_issues_enabled: false
contact_links:
- name: SUPPORT, ISSUES and TROUBLESHOOTING
url: https://discourse.gohugo.io/
about: Please DO NOT use Github for support requests. Please visit https://discourse.gohugo.io for support! You will be helped much faster there. If you ignore this request your issue might be closed with a discourse label.
-10
View File
@@ -1,10 +0,0 @@
---
name: Support (Do not use)
about: Please do not use Github for support requests. Visit https://discourse.gohugo.io for support
title: ''
labels: support
assignees: ''
---
Issues created with this template will be automatically closed. Please visit https://discourse.gohugo.io for the support you really, really, want!
+1 -1
View File
@@ -1,7 +1,7 @@
# See https://docs.github.com/en/github/administering-a-repository/configuration-options-for-dependency-updates#package-ecosystem
version: 2
updates:
- package-ecosystem: "gomod"
- package-ecosystem: "gomod"
directory: "/"
schedule:
interval: "daily"
-14
View File
@@ -1,14 +0,0 @@
on:
schedule:
- cron: 0 5 * * 3
name: Weekly Issue Closure
jobs:
cycle-weekly-close:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@master
- name: weekly-issue-closure
uses: bdougie/close-issues-based-on-label@master
env:
LABEL: support
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+82
View File
@@ -0,0 +1,82 @@
on: [push, pull_request]
name: Test
jobs:
test:
env:
GOPROXY: https://proxy.golang.org
GO111MODULE: on
strategy:
matrix:
go-version: [1.16.x, 1.17.x]
os: [ubuntu-latest, macos-latest, windows-latest]
runs-on: ${{ matrix.os }}
steps:
- name: Install Go
uses: actions/setup-go@37335c7bb261b353407cff977110895fa0b4f7d8
with:
go-version: ${{ matrix.go-version }}
- name: Install Ruby
uses: actions/setup-ruby@5f29a1cd8dfebf420691c4c9a0e832e2fae5a526
with:
ruby-version: '2.7'
- name: Install Python
uses: actions/setup-python@3105fb18c05ddd93efea5f9e0bef7a03a6e9e7df
with:
python-version: '3.x'
- name: Install Mage
run: go get github.com/magefile/mage@07afc7d24f4d6d6442305d49552f04fbda5ccb3e
- name: Install asciidoctor
uses: reitzig/actions-asciidoctor@7570212ae20b63653481675fb1ff62d1073632b0
- name: Checkout code
uses: actions/checkout@5a4ac9002d0be2fb38bd78e4b4dbde5606d7042f
- name: Install docutils
run: |
pip install docutils
rst2html.py --version
- if: matrix.os == 'ubuntu-latest'
name: Install pandoc on Linux
run: |
sudo apt-get update -y
sudo apt-get install -y pandoc
- if: matrix.os == 'macos-latest'
run: |
brew install pandoc
- if: matrix.os == 'windows-latest'
run: |
choco install pandoc
- run: pandoc -v
- if: matrix.os == 'ubuntu-latest'
name: Install dart-sass-embedded Linux
run: |
curl -LJO https://github.com/sass/dart-sass-embedded/releases/download/1.0.0-beta.6/sass_embedded-1.0.0-beta.6-linux-x64.tar.gz;
echo "04fc1e5e28d29a4585a701941b6dace56771d94bfbe7f9e4db28d24417ceeec3 sass_embedded-1.0.0-beta.6-linux-x64.tar.gz" | sha256sum -c;
tar -xvf sass_embedded-1.0.0-beta.6-linux-x64.tar.gz;
echo "$GITHUB_WORKSPACE/sass_embedded/" >> $GITHUB_PATH
- if: matrix.os == 'macos-latest'
name: Install dart-sass-embedded MacOS
run: |
curl -LJO https://github.com/sass/dart-sass-embedded/releases/download/1.0.0-beta.6/sass_embedded-1.0.0-beta.6-macos-x64.tar.gz;
echo "b3b984675a9b04aa22f6f2302dda4191b507ac2ca124467db2dfe7e58e72fbad sass_embedded-1.0.0-beta.6-macos-x64.tar.gz" | shasum -a 256 -c;
tar -xvf sass_embedded-1.0.0-beta.6-macos-x64.tar.gz;
echo "$GITHUB_WORKSPACE/sass_embedded/" >> $GITHUB_PATH
- if: matrix.os == 'windows-latest'
name: Install dart-sass-embedded Windows
run: |
curl -LJO https://github.com/sass/dart-sass-embedded/releases/download/1.0.0-beta.6/sass_embedded-1.0.0-beta.6-windows-x64.zip;
echo "6ae442129dbb3334bc21ef851261da6c0c1b560da790ca2e1350871d00ab816d sass_embedded-1.0.0-beta.6-windows-x64.zip" | sha256sum -c;
unzip sass_embedded-1.0.0-beta.6-windows-x64.zip;
echo "$env:GITHUB_WORKSPACE/sass_embedded/" | Out-File -FilePath $Env:GITHUB_PATH -Encoding utf-8 -Append
- name: Test
run: |
mage -v test
mage -v check;
- name: Build Docs
env:
HUGO_BUILD_TAGS: extended
HUGO_TIMEOUT: 31000
HUGO_IGNOREERRORS: error-remote-getjson
HUGO_SERVICES_INSTAGRAM_ACCESSTOKEN: dummytoken
run: |
mage -v hugo
./hugo -s docs/
./hugo --renderToMemory -s docs/
+1
View File
@@ -1,6 +1,7 @@
/hugo
docs/public*
/.idea
.vscode/*
hugo.exe
*.test
*.prof
-77
View File
@@ -1,77 +0,0 @@
language: go
dist: bionic
env:
global:
- CACHE_NAME=${TRAVIS_ARCH}
- GO111MODULE=on
- GOPROXY=https://proxy.golang.org
- HUGO_BUILD_TAGS=extended
git:
depth: false
go:
- "1.14.8"
- "1.15.1"
- master
arch:
- amd64
- arm64
os:
- linux
- osx
- windows
jobs:
allow_failures:
- go: master
- arch: arm64
fast_finish: true
exclude:
- os: windows
go: master
- arch: arm64
os: osx
- arch: arm64
os: windows
cache:
directories:
- $HOME/gopath/pkg/mod
- $HOME/.cache/go-build
- $HOME/Library/Caches/go-build
- $HOME/AppData/Local/go-build
before_install:
- df -h
# https://travis-ci.community/t/go-cant-find-gcc-with-go1-11-1-on-windows/293/5
- if [ "$TRAVIS_OS_NAME" = "windows" ]; then
choco install mingw -y;
export PATH=/c/tools/mingw64/bin:"$PATH";
fi
- gem install asciidoctor
- type asciidoctor
install:
- mkdir -p $HOME/src
- mv $TRAVIS_BUILD_DIR $HOME/src
- export TRAVIS_BUILD_DIR=$HOME/src/hugo
- cd $HOME/src/hugo
- go get github.com/magefile/mage
script:
- go mod download
- go mod verify
- mage -v test
- if [ "$TRAVIS_ARCH" = "amd64" ]; then
mage -v check;
else
HUGO_TIMEOUT=30000 mage -v check;
fi
- mage -v hugo
- ./hugo -s docs/
- ./hugo --renderToMemory -s docs/
- df -h
+3 -1
View File
@@ -50,7 +50,9 @@ Hugo has become a fully featured static site generator, so any new functionality
If it is of some complexity, the contributor is expected to maintain and support the new feature in the future (answer questions on the forum, fix any bugs etc.).
It is recommended to open up a discussion on the [Hugo Forum](https://discourse.gohugo.io/) to get feedback on your idea before you begin. If you are submitting a complex feature, create a small design proposal on the [Hugo issue tracker](https://github.com/gohugoio/hugo/issues) before you start.
It is recommended to open up a discussion on the [Hugo Forum](https://discourse.gohugo.io/) to get feedback on your idea before you begin.
Any non-trivial code change needs to update an open [issue](https://github.com/gohugoio/hugo/issues). A non-trivial code change without an issue reference with one of the labels `bug` or `enhancement` will not be merged.
Note that we do not accept new features that require [CGO](https://github.com/golang/go/wiki/cgo).
We have one exception to this rule which is LibSASS.
+4 -4
View File
@@ -2,9 +2,9 @@
# Twitter: https://twitter.com/gohugoio
# Website: https://gohugo.io/
FROM golang:1.13-alpine AS build
FROM golang:1.16-alpine AS build
# Optionally set HUGO_BUILD_TAGS to "extended" when building like so:
# Optionally set HUGO_BUILD_TAGS to "extended" or "nodeploy" when building like so:
# docker build --build-arg HUGO_BUILD_TAGS=extended .
ARG HUGO_BUILD_TAGS
@@ -19,14 +19,14 @@ COPY . /go/src/github.com/gohugoio/hugo/
# gcc/g++ are required to build SASS libraries for extended version
RUN apk update && \
apk add --no-cache gcc g++ musl-dev && \
apk add --no-cache gcc g++ musl-dev git && \
go get github.com/magefile/mage
RUN mage hugo && mage install
# ---
FROM alpine:3.11
FROM alpine:3.12
COPY --from=build /go/bin/hugo /usr/bin/hugo
+101 -73
View File
@@ -1,4 +1,4 @@
<img src="https://raw.githubusercontent.com/gohugoio/gohugoioTheme/master/static/images/hugo-logo-wide.svg?sanitize=true" alt="Hugo" width="565">
<a href="https://gohugo.io/"><img src="https://raw.githubusercontent.com/gohugoio/gohugoioTheme/master/static/images/hugo-logo-wide.svg?sanitize=true" alt="Hugo" width="565"></a>
A Fast and Flexible Static Site Generator built with love by [bep](https://github.com/bep), [spf13](http://spf13.com/) and [friends](https://github.com/gohugoio/hugo/graphs/contributors) in [Go][].
@@ -10,7 +10,7 @@ A Fast and Flexible Static Site Generator built with love by [bep](https://githu
[Twitter](https://twitter.com/gohugoio)
[![GoDoc](https://godoc.org/github.com/gohugoio/hugo?status.svg)](https://godoc.org/github.com/gohugoio/hugo)
[![Linux and macOS Build Status](https://api.travis-ci.org/gohugoio/hugo.svg?branch=master&label=Windows+and+Linux+and+macOS+build "Windows, Linux and macOS Build Status")](https://travis-ci.org/gohugoio/hugo)
[![Tests on Linux, MacOS and Windows](https://github.com/gohugoio/hugo/workflows/Test/badge.svg)](https://github.com/gohugoio/hugo/actions?query=workflow%3ATest)
[![Go Report Card](https://goreportcard.com/badge/github.com/gohugoio/hugo)](https://goreportcard.com/report/github.com/gohugoio/hugo)
## Overview
@@ -29,7 +29,7 @@ Hugo is designed to work well for any kind of website including blogs, tumbles,
#### Supported Architectures
Currently, we provide pre-built Hugo binaries for Windows, Linux, FreeBSD, NetBSD, DragonFly BSD, Open BSD, macOS (Darwin), and [Android](https://gist.github.com/bep/a0d8a26cf6b4f8bc992729b8e50b480b) for x64, i386 and ARM architectures.
Currently, we provide pre-built Hugo binaries for Windows, Linux, FreeBSD, NetBSD, DragonFly BSD, OpenBSD, macOS (Darwin), and [Android](https://gist.github.com/bep/a0d8a26cf6b4f8bc992729b8e50b480b) for x64, i386 and ARM architectures.
Hugo may also be compiled from source wherever the Go compiler tool chain can run, e.g. for other operating systems including Plan 9 and Solaris.
@@ -54,7 +54,7 @@ Use the [installation instructions in the Hugo documentation](https://gohugo.io/
#### Prerequisite Tools
* [Git](https://git-scm.com/)
* [Go (we test it with the last 2 major versions)](https://golang.org/dl/)
* [Go (we test it with the last 2 major versions; but note that Hugo 0.81.0 only builds with >= Go 1.16.)](https://golang.org/dl/)
#### Fetch from GitHub
@@ -119,78 +119,106 @@ If you are unfamiliar with the contribution process, the Hugo team will help you
For a complete guide to contributing code to Hugo, see the [Contribution Guide](CONTRIBUTING.md).
[![Analytics](https://ga-beacon.appspot.com/UA-7131036-6/hugo/readme)](https://github.com/igrigorik/ga-beacon)
[Go]: https://golang.org/
[Hugo Documentation]: https://gohugo.io/overview/introduction/
## Dependencies
Hugo stands on the shoulder of many great open source libraries, in lexical order:
Hugo stands on the shoulder of many great open source libraries.
If you run `hugo env -v` you will get a complete and up to date list.
In Hugo 0.89.0 that list is, in lexical order:
```
cloud.google.com/go/storage="v1.10.0"
cloud.google.com/go="v0.87.0"
github.com/Azure/azure-pipeline-go="v0.2.2"
github.com/Azure/azure-storage-blob-go="v0.9.0"
github.com/BurntSushi/locker="v0.0.0-20171006230638-a6e239ea1c69"
github.com/BurntSushi/toml="v0.3.1"
github.com/PuerkitoBio/purell="v1.1.1"
github.com/PuerkitoBio/urlesc="v0.0.0-20170810143723-de5bf2ad4578"
github.com/alecthomas/chroma="v0.9.4"
github.com/armon/go-radix="v1.0.0"
github.com/aws/aws-sdk-go="v1.41.14"
github.com/bep/debounce="v1.2.0"
github.com/bep/gitmap="v1.1.2"
github.com/bep/godartsass="v0.12.0"
github.com/bep/golibsass="v1.0.0"
github.com/bep/gowebp="v0.1.0"
github.com/bep/tmc="v0.5.1"
github.com/cli/safeexec="v1.0.0"
github.com/cpuguy83/go-md2man/v2="v2.0.0"
github.com/disintegration/gift="v1.2.1"
github.com/dlclark/regexp2="v1.4.0"
github.com/dustin/go-humanize="v1.0.0"
github.com/evanw/esbuild="v0.13.12"
github.com/fsnotify/fsnotify="v1.5.1"
github.com/getkin/kin-openapi="v0.80.0"
github.com/ghodss/yaml="v1.0.0"
github.com/go-openapi/jsonpointer="v0.19.5"
github.com/go-openapi/swag="v0.19.5"
github.com/gobuffalo/flect="v0.2.3"
github.com/gobwas/glob="v0.2.3"
github.com/gohugoio/go-i18n/v2="v2.1.3-0.20210430103248-4c28c89f8013"
github.com/gohugoio/locales="v0.14.0"
github.com/gohugoio/localescompressed="v0.14.0"
github.com/golang/groupcache="v0.0.0-20200121045136-8c9f03a8e57e"
github.com/golang/protobuf="v1.5.2"
github.com/google/go-cmp="v0.5.6"
github.com/google/uuid="v1.1.2"
github.com/google/wire="v0.4.0"
github.com/googleapis/gax-go/v2="v2.0.5"
github.com/googleapis/gax-go="v2.0.2+incompatible"
github.com/gorilla/websocket="v1.4.2"
github.com/inconshreveable/mousetrap="v1.0.0"
github.com/jdkato/prose="v1.2.1"
github.com/jmespath/go-jmespath="v0.4.0"
github.com/kyokomi/emoji/v2="v2.2.8"
github.com/mailru/easyjson="v0.0.0-20190626092158-b2ccc519800e"
github.com/mattn/go-ieproxy="v0.0.1"
github.com/mattn/go-isatty="v0.0.14"
github.com/mattn/go-runewidth="v0.0.9"
github.com/miekg/mmark="v1.3.6"
github.com/mitchellh/hashstructure="v1.1.0"
github.com/mitchellh/mapstructure="v1.4.2"
github.com/muesli/smartcrop="v0.3.0"
github.com/niklasfasching/go-org="v1.5.0"
github.com/olekukonko/tablewriter="v0.0.5"
github.com/pelletier/go-toml/v2="v2.0.0-beta.3.0.20210727221244-fa0796069526"
github.com/pkg/errors="v0.9.1"
github.com/rogpeppe/go-internal="v1.8.0"
github.com/russross/blackfriday/v2="v2.0.1"
github.com/russross/blackfriday="v1.5.3-0.20200218234912-41c5fccfd6f6"
github.com/rwcarlsen/goexif="v0.0.0-20190401172101-9e8deecbddbd"
github.com/sanity-io/litter="v1.5.1"
github.com/sass/libsass="3.6.5"
github.com/shurcooL/sanitized_anchor_name="v1.0.0"
github.com/spf13/afero="v1.6.0"
github.com/spf13/cast="v1.4.1"
github.com/spf13/cobra="v1.2.1"
github.com/spf13/fsync="v0.9.0"
github.com/spf13/jwalterweatherman="v1.1.0"
github.com/spf13/pflag="v1.0.5"
github.com/tdewolff/minify/v2="v2.9.22"
github.com/tdewolff/parse/v2="v2.5.21"
github.com/webmproject/libwebp="v1.2.0"
github.com/yuin/goldmark-highlighting="v0.0.0-20200307114337-60d527fdb691"
github.com/yuin/goldmark="v1.4.2"
go.opencensus.io="v0.23.0"
gocloud.dev="v0.20.0"
golang.org/x/image="v0.0.0-20210220032944-ac19c3e999fb"
golang.org/x/net="v0.0.0-20210614182718-04defd469f4e"
golang.org/x/oauth2="v0.0.0-20210628180205-a41e5a781914"
golang.org/x/sync="v0.0.0-20210220032951-036812b2e83c"
golang.org/x/sys="v0.0.0-20210908233432-aa78b53d3365"
golang.org/x/text="v0.3.7"
golang.org/x/xerrors="v0.0.0-20200804184101-5ec99f83aff1"
google.golang.org/api="v0.51.0"
google.golang.org/genproto="v0.0.0-20210716133855-ce7ef5c701ea"
google.golang.org/grpc="v1.39.0"
google.golang.org/protobuf="v1.27.1"
gopkg.in/yaml.v2="v2.4.0"
```
| Dependency | License |
| :------------- | :------------- |
| [github.com/alecthomas/chroma](https://github.com/alecthomas/chroma) | MIT License |
| [github.com/armon/go-radix](https://github.com/armon/go-radix) | MIT License |
| [github.com/aws/aws-sdk-go](https://github.com/aws/aws-sdk-go) | Apache License 2.0 |
| [github.com/bep/debounce](https://github.com/bep/debounce) | MIT License |
| [github.com/bep/gitmap](https://github.com/bep/gitmap) | MIT License |
| [github.com/bep/golibsass](https://github.com/bep/golibsass) | MIT License |
| [github.com/bep/tmc](https://github.com/bep/tmc) | MIT License |
| [github.com/BurntSushi/locker](https://github.com/BurntSushi/locker) | The Unlicense |
| [github.com/BurntSushi/toml](https://github.com/BurntSushi/toml) | MIT License |
| [github.com/cpuguy83/go-md2man](https://github.com/cpuguy83/go-md2man) | MIT License |
| [github.com/danwakefield/fnmatch](https://github.com/danwakefield/fnmatch) | BSD 2-Clause "Simplified" License |
| [github.com/disintegration/gift](https://github.com/disintegration/gift) | MIT License |
| [github.com/dustin/go-humanize](https://github.com/dustin/go-humanize) | MIT License |
| [github.com/fsnotify/fsnotify](https://github.com/fsnotify/fsnotify) | BSD 3-Clause "New" or "Revised" License |
| [github.com/gobwas/glob](https://github.com/gobwas/glob) | MIT License |
| [github.com/gorilla/websocket](https://github.com/gorilla/websocket) | BSD 2-Clause "Simplified" License |
| [github.com/hashicorp/golang-lru](https://github.com/hashicorp/golang-lru) | Mozilla Public License 2.0 |
| [github.com/hashicorp/hcl](https://github.com/hashicorp/hcl) | Mozilla Public License 2.0 |
| [github.com/jdkato/prose](https://github.com/jdkato/prose) | MIT License |
| [github.com/kr/pretty](https://github.com/kr/pretty) | MIT License |
| [github.com/kyokomi/emoji](https://github.com/kyokomi/emoji) | MIT License |
| [github.com/magiconair/properties](https://github.com/magiconair/properties) | BSD 2-Clause "Simplified" License |
| [github.com/markbates/inflect](https://github.com/markbates/inflect) | MIT License |
| [github.com/mattn/go-isatty](https://github.com/mattn/go-isatty) | MIT License |
| [github.com/mattn/go-runewidth](https://github.com/mattn/go-runewidth) | MIT License |
| [github.com/miekg/mmark](https://github.com/miekg/mmark) | Simplified BSD License |
| [github.com/mitchellh/hashstructure](https://github.com/mitchellh/hashstructure) | MIT License |
| [github.com/mitchellh/mapstructure](https://github.com/mitchellh/mapstructure) | MIT License |
| [github.com/muesli/smartcrop](https://github.com/muesli/smartcrop) | MIT License |
| [github.com/nicksnyder/go-i18n](https://github.com/nicksnyder/go-i18n) | MIT License |
| [github.com/niklasfasching/go-org](https://github.com/niklasfasching/go-org) | MIT License |
| [github.com/olekukonko/tablewriter](https://github.com/olekukonko/tablewriter) | MIT License |
| [github.com/pelletier/go-toml](https://github.com/pelletier/go-toml) | MIT License |
| [github.com/pkg/errors](https://github.com/pkg/errors) | BSD 2-Clause "Simplified" License |
| [github.com/PuerkitoBio/purell](https://github.com/PuerkitoBio/purell) | BSD 3-Clause "New" or "Revised" License |
| [github.com/PuerkitoBio/urlesc](https://github.com/PuerkitoBio/urlesc) | BSD 3-Clause "New" or "Revised" License |
| [github.com/rogpeppe/go-internal](https://github.com/rogpeppe/go-internal) | BSD 3-Clause "New" or "Revised" License |
| [github.com/russross/blackfriday](https://github.com/russross/blackfriday) | Simplified BSD License |
| [github.com/rwcarlsen/goexif](https://github.com/rwcarlsen/goexif) | BSD 2-Clause "Simplified" License |
| [github.com/spf13/afero](https://github.com/spf13/afero) | Apache License 2.0 |
| [github.com/spf13/cast](https://github.com/spf13/cast) | MIT License |
| [github.com/spf13/cobra](https://github.com/spf13/cobra) | Apache License 2.0 |
| [github.com/spf13/fsync](https://github.com/spf13/fsync) | MIT License |
| [github.com/spf13/jwalterweatherman](https://github.com/spf13/jwalterweatherman) | MIT License |
| [github.com/spf13/pflag](https://github.com/spf13/pflag) | BSD 3-Clause "New" or "Revised" License |
| [github.com/spf13/viper](https://github.com/spf13/viper) | MIT License |
| [github.com/tdewolff/minify](https://github.com/tdewolff/minify) | MIT License |
| [github.com/tdewolff/parse](https://github.com/tdewolff/parse) | MIT License |
| [github.com/yuin/goldmark](https://github.com/yuin/goldmark) | MIT License |
| [github.com/yuin/goldmark-highlighting](https://github.com/yuin/goldmark-highlighting) | MIT License |
| [go.opencensus.io](https://go.opencensus.io) | Apache License 2.0 |
| [go.uber.org/atomic](https://go.uber.org/atomic) | MIT License |
| [gocloud.dev](https://gocloud.dev) | Apache License 2.0 |
| [golang.org/x/image](https://golang.org/x/image) | BSD 3-Clause "New" or "Revised" License |
| [golang.org/x/net](https://golang.org/x/net) | BSD 3-Clause "New" or "Revised" License |
| [golang.org/x/oauth2](https://golang.org/x/oauth2) | BSD 3-Clause "New" or "Revised" License |
| [golang.org/x/sync](https://golang.org/x/sync) | BSD 3-Clause "New" or "Revised" License |
| [golang.org/x/sys](https://golang.org/x/sys) | BSD 3-Clause "New" or "Revised" License |
| [golang.org/x/text](https://golang.org/x/text) | BSD 3-Clause "New" or "Revised" License |
| [golang.org/x/xerrors](https://golang.org/x/xerrors) | BSD 3-Clause "New" or "Revised" License |
| [google.golang.org/api](https://google.golang.org/api) | BSD 3-Clause "New" or "Revised" License |
| [google.golang.org/genproto](https://google.golang.org/genproto) | Apache License 2.0 |
| [gopkg.in/ini.v1](https://gopkg.in/ini.v1) | Apache License 2.0 |
| [gopkg.in/yaml.v2](https://gopkg.in/yaml.v2) | Apache License 2.0 |
+7
View File
@@ -0,0 +1,7 @@
## Security Policy
### Reporting a Vulnerability
Please report (suspected) security vulnerabilities to **[bjorn.erik.pedersen@gmail.com](mailto:bjorn.erik.pedersen@gmail.com)**. You will receive a response from us within 48 hours. If we can confirm the issue, we will release a patch as soon as possible depending on the complexity of the issue but historically within days.
Also see [Hugo's Security Model](https://gohugo.io/about/security-model/).
+1 -1
View File
@@ -3,7 +3,7 @@
# allow user to override go executable by running as GOEXE=xxx make ...
GOEXE="${GOEXE-go}"
# Send in a regexp mathing the benchmarks you want to run, i.e. './benchSite.sh "YAML"'.
# Send in a regexp matching the benchmarks you want to run, i.e. './benchSite.sh "YAML"'.
# Note the quotes, which will be needed for more complex expressions.
# The above will run all variations, but only for front matter YAML.
+13 -8
View File
@@ -158,7 +158,6 @@ func (c *Cache) ReadOrCreate(id string,
err = create(info, f)
return
}
// GetOrCreate tries to get the file with the given id from cache. If not found or expired, create will
@@ -176,7 +175,12 @@ func (c *Cache) GetOrCreate(id string, create func() (io.ReadCloser, error)) (It
return info, r, nil
}
r, err := create()
var (
r io.ReadCloser
err error
)
r, err = create()
if err != nil {
return info, nil, err
}
@@ -207,7 +211,12 @@ func (c *Cache) GetOrCreateBytes(id string, create func() ([]byte, error)) (Item
return info, b, err
}
b, err := create()
var (
b []byte
err error
)
b, err = create()
if err != nil {
return info, nil, err
}
@@ -220,10 +229,9 @@ func (c *Cache) GetOrCreateBytes(id string, create func() ([]byte, error)) (Item
return info, nil, err
}
return info, b, nil
}
// GetBytes gets the file content with the given id from the cahce, nil if none found.
// GetBytes gets the file content with the given id from the cache, nil if none found.
func (c *Cache) GetBytes(id string) (ItemInfo, []byte, error) {
id = cleanID(id)
@@ -276,7 +284,6 @@ func (c *Cache) getOrRemove(id string) hugio.ReadSeekCloser {
}
f, err := c.Fs.Open(id)
if err != nil {
return nil
}
@@ -299,7 +306,6 @@ func (c *Cache) getString(id string) string {
defer c.nlocker.Unlock(id)
f, err := c.Fs.Open(id)
if err != nil {
return ""
}
@@ -307,7 +313,6 @@ func (c *Cache) getString(id string) string {
b, _ := ioutil.ReadAll(f)
return string(b)
}
// Caches is a named set of caches.
+23 -7
View File
@@ -19,6 +19,8 @@ import (
"strings"
"time"
"github.com/gohugoio/hugo/common/maps"
"github.com/gohugoio/hugo/config"
"github.com/gohugoio/hugo/helpers"
@@ -32,19 +34,21 @@ const (
cachesConfigKey = "caches"
resourcesGenDir = ":resourceDir/_gen"
cacheDirProject = ":cacheDir/:project"
)
var defaultCacheConfig = Config{
MaxAge: -1, // Never expire
Dir: ":cacheDir/:project",
Dir: cacheDirProject,
}
const (
cacheKeyGetJSON = "getjson"
cacheKeyGetCSV = "getcsv"
cacheKeyImages = "images"
cacheKeyAssets = "assets"
cacheKeyModules = "modules"
cacheKeyGetJSON = "getjson"
cacheKeyGetCSV = "getcsv"
cacheKeyImages = "images"
cacheKeyAssets = "assets"
cacheKeyModules = "modules"
cacheKeyGetResource = "getresource"
)
type Configs map[string]Config
@@ -68,6 +72,10 @@ var defaultCacheConfigs = Configs{
MaxAge: -1,
Dir: resourcesGenDir,
},
cacheKeyGetResource: Config{
MaxAge: -1, // Never expire
Dir: cacheDirProject,
},
}
type Config struct {
@@ -109,6 +117,11 @@ func (f Caches) AssetsCache() *Cache {
return f[cacheKeyAssets]
}
// GetResourceCache gets the file cache for remote resources.
func (f Caches) GetResourceCache() *Cache {
return f[cacheKeyGetResource]
}
func DecodeConfig(fs afero.Fs, cfg config.Provider) (Configs, error) {
c := make(Configs)
valid := make(map[string]bool)
@@ -123,6 +136,9 @@ func DecodeConfig(fs afero.Fs, cfg config.Provider) (Configs, error) {
_, isOsFs := fs.(*afero.OsFs)
for k, v := range m {
if _, ok := v.(maps.Params); !ok {
continue
}
cc := defaultCacheConfig
dc := &mapstructure.DecoderConfig{
@@ -137,7 +153,7 @@ func DecodeConfig(fs afero.Fs, cfg config.Provider) (Configs, error) {
}
if err := decoder.Decode(v); err != nil {
return nil, err
return nil, errors.Wrap(err, "failed to decode filecache config")
}
if cc.Dir == "" {
+12 -10
View File
@@ -25,7 +25,6 @@ import (
"github.com/gohugoio/hugo/config"
qt "github.com/frankban/quicktest"
"github.com/spf13/viper"
)
func TestDecodeConfig(t *testing.T) {
@@ -51,7 +50,8 @@ maxAge = "11h"
dir = "/path/to/c2"
[caches.images]
dir = "/path/to/c3"
[caches.getResource]
dir = "/path/to/c4"
`
cfg, err := config.FromConfigString(configStr, "toml")
@@ -60,7 +60,7 @@ dir = "/path/to/c3"
decoded, err := DecodeConfig(fs, cfg)
c.Assert(err, qt.IsNil)
c.Assert(len(decoded), qt.Equals, 5)
c.Assert(len(decoded), qt.Equals, 6)
c2 := decoded["getcsv"]
c.Assert(c2.MaxAge.String(), qt.Equals, "11h0m0s")
@@ -70,6 +70,9 @@ dir = "/path/to/c3"
c.Assert(c3.MaxAge, qt.Equals, time.Duration(-1))
c.Assert(c3.Dir, qt.Equals, filepath.FromSlash("/path/to/c3/filecache/images"))
c4 := decoded["getresource"]
c.Assert(c4.MaxAge, qt.Equals, time.Duration(-1))
c.Assert(c4.Dir, qt.Equals, filepath.FromSlash("/path/to/c4/filecache/getresource"))
}
func TestDecodeConfigIgnoreCache(t *testing.T) {
@@ -96,7 +99,8 @@ maxAge = 3456
dir = "/path/to/c2"
[caches.images]
dir = "/path/to/c3"
[caches.getResource]
dir = "/path/to/c4"
`
cfg, err := config.FromConfigString(configStr, "toml")
@@ -105,12 +109,11 @@ dir = "/path/to/c3"
decoded, err := DecodeConfig(fs, cfg)
c.Assert(err, qt.IsNil)
c.Assert(len(decoded), qt.Equals, 5)
c.Assert(len(decoded), qt.Equals, 6)
for _, v := range decoded {
c.Assert(v.MaxAge, qt.Equals, time.Duration(0))
}
}
func TestDecodeConfigDefault(t *testing.T) {
@@ -132,7 +135,7 @@ func TestDecodeConfigDefault(t *testing.T) {
c.Assert(err, qt.IsNil)
c.Assert(len(decoded), qt.Equals, 5)
c.Assert(len(decoded), qt.Equals, 6)
imgConfig := decoded[cacheKeyImages]
jsonConfig := decoded[cacheKeyGetJSON]
@@ -178,11 +181,10 @@ dir = "/"
_, err = DecodeConfig(fs, cfg)
c.Assert(err, qt.Not(qt.IsNil))
}
func newTestConfig() *viper.Viper {
cfg := viper.New()
func newTestConfig() config.Provider {
cfg := config.New()
cfg.Set("workingDir", filepath.FromSlash("/my/cool/hugoproject"))
cfg.Set("contentDir", "content")
cfg.Set("dataDir", "data")
-2
View File
@@ -110,7 +110,6 @@ func (c *Cache) Prune(force bool) (int, error) {
}
func (c *Cache) pruneRootDir(force bool) (int, error) {
info, err := c.Fs.Stat(c.pruneAllRootDir)
if err != nil {
if os.IsNotExist(err) {
@@ -124,5 +123,4 @@ func (c *Cache) pruneRootDir(force bool) (int, error) {
}
return hugofs.MakeReadableAndRemoveAllModulePkgDir(c.Fs, c.pruneAllRootDir)
}
-1
View File
@@ -107,5 +107,4 @@ dir = ":resourceDir/_gen"
}
}
}
-3
View File
@@ -183,7 +183,6 @@ dir = ":cacheDir/c"
c.Assert(string(b), qt.Equals, "Hugo is great!")
}
}
func TestFileCacheConcurrent(t *testing.T) {
@@ -253,7 +252,6 @@ func TestFileCacheReadOrCreateErrorInRead(t *testing.T) {
var result string
rf := func(failLevel int) func(info ItemInfo, r io.ReadSeeker) error {
return func(info ItemInfo, r io.ReadSeeker) error {
if failLevel > 0 {
if failLevel > 1 {
@@ -347,5 +345,4 @@ func newPathsSpec(t *testing.T, fs afero.Fs, configStr string) *helpers.PathSpec
p, err := helpers.NewPathSpec(hugofs.NewFrom(fs, cfg), cfg, nil)
c.Assert(err, qt.IsNil)
return p
}
+1 -2
View File
@@ -49,13 +49,12 @@ func (c *Cache) Clear() {
c.cache = make(map[string]cacheEntry)
c.nlocker = locker.NewLocker()
}
// GetOrCreate tries to get the value with the given cache key, if not found
// create will be called and cached.
// This method is thread safe. It also guarantees that the create func for a given
// key is invoced only once for this cache.
// key is invoked only once for this cache.
func (c *Cache) GetOrCreate(key string, create func() (interface{}, error)) (interface{}, error) {
c.mu.RLock()
entry, found := c.cache[key]
+3 -15
View File
@@ -58,7 +58,7 @@ func (c *Inspector) MethodsFromTypes(include []reflect.Type, exclude []reflect.T
var methods Methods
var excludes = make(map[string]bool)
excludes := make(map[string]bool)
if len(exclude) > 0 {
for _, m := range c.MethodsFromTypes(exclude, nil) {
@@ -99,11 +99,9 @@ func (c *Inspector) MethodsFromTypes(include []reflect.Type, exclude []reflect.T
name = pkgPrefix + name
return name, pkg
}
for _, t := range include {
for i := 0; i < t.NumMethod(); i++ {
m := t.Method(i)
@@ -153,7 +151,6 @@ func (c *Inspector) MethodsFromTypes(include []reflect.Type, exclude []reflect.T
methods = append(methods, method)
}
}
sort.SliceStable(methods, func(i, j int) bool {
@@ -167,16 +164,13 @@ func (c *Inspector) MethodsFromTypes(include []reflect.Type, exclude []reflect.T
}
return wi < wj
})
return methods
}
func (c *Inspector) parseSource() {
c.init.Do(func() {
if !strings.Contains(c.ProjectRootDir, "hugo") {
panic("dir must be set to the Hugo root")
}
@@ -200,7 +194,6 @@ func (c *Inspector) parseSource() {
filenames = append(filenames, path)
return nil
})
for _, filename := range filenames {
@@ -230,7 +223,6 @@ func (c *Inspector) parseSource() {
c.methodWeight[iface] = weights
}
}
}
return true
})
@@ -247,7 +239,6 @@ func (c *Inspector) parseSource() {
}
}
}
})
}
@@ -374,7 +365,7 @@ func (m Methods) Imports() []string {
}
// ToMarshalJSON creates a MarshalJSON method for these methods. Any method name
// matchin any of the regexps in excludes will be ignored.
// matching any of the regexps in excludes will be ignored.
func (m Methods) ToMarshalJSON(receiver, pkgPath string, excludes ...string) (string, []string) {
var sb strings.Builder
@@ -385,7 +376,7 @@ func (m Methods) ToMarshalJSON(receiver, pkgPath string, excludes ...string) (st
fmt.Fprintf(&sb, "func Marshal%sToJSON(%s %s) ([]byte, error) {\n", what, r, receiver)
var methods Methods
var excludeRes = make([]*regexp.Regexp, len(excludes))
excludeRes := make([]*regexp.Regexp, len(excludes))
for i, exclude := range excludes {
excludeRes[i] = regexp.MustCompile(exclude)
@@ -450,7 +441,6 @@ func (m Methods) ToMarshalJSON(receiver, pkgPath string, excludes ...string) (st
}
return sb.String(), pkgImports
}
func collectMethodsRecursive(pkg string, f []*ast.Field) []string {
@@ -481,7 +471,6 @@ func collectMethodsRecursive(pkg string, f []*ast.Field) []string {
}
return methodNames
}
func firstToLower(name string) string {
@@ -544,5 +533,4 @@ func varName(name string) string {
}
return name
}
-4
View File
@@ -25,7 +25,6 @@ import (
)
func TestMethods(t *testing.T) {
var (
zeroIE = reflect.TypeOf((*IEmbed)(nil)).Elem()
zeroIEOnly = reflect.TypeOf((*IEOnly)(nil)).Elem()
@@ -58,7 +57,6 @@ func TestMethods(t *testing.T) {
methodsStr := fmt.Sprint(methods)
c.Assert(methodsStr, qt.Contains, "MethodEmbed3(arg0 string) string")
})
t.Run("ToMarshalJSON", func(t *testing.T) {
@@ -76,9 +74,7 @@ func TestMethods(t *testing.T) {
c.Assert(pkg, qt.Contains, "encoding/json")
fmt.Println(pkg)
})
}
type I interface {
+5 -4
View File
@@ -26,9 +26,10 @@ type checkCmd struct {
}
func newCheckCmd() *checkCmd {
return &checkCmd{baseCmd: &baseCmd{cmd: &cobra.Command{
Use: "check",
Short: "Contains some verification checks",
},
return &checkCmd{baseCmd: &baseCmd{
cmd: &cobra.Command{
Use: "check",
Short: "Contains some verification checks",
},
}}
}
+5 -4
View File
@@ -24,10 +24,11 @@ type checkCmd struct {
}
func newCheckCmd() *checkCmd {
cc := &checkCmd{baseCmd: &baseCmd{cmd: &cobra.Command{
Use: "check",
Short: "Contains some verification checks",
},
cc := &checkCmd{baseCmd: &baseCmd{
cmd: &cobra.Command{
Use: "check",
Short: "Contains some verification checks",
},
}}
cc.cmd.AddCommand(newLimitCmd().getCommand())
+44 -30
View File
@@ -16,24 +16,22 @@ package commands
import (
"bytes"
"errors"
"io/ioutil"
"os"
"path/filepath"
"regexp"
"sync"
"time"
hconfig "github.com/gohugoio/hugo/config"
"golang.org/x/sync/semaphore"
"io/ioutil"
"github.com/gohugoio/hugo/common/herrors"
"github.com/gohugoio/hugo/common/hugo"
jww "github.com/spf13/jwalterweatherman"
"os"
"path/filepath"
"regexp"
"time"
"github.com/gohugoio/hugo/common/loggers"
"github.com/gohugoio/hugo/config"
@@ -60,9 +58,14 @@ type commandeerHugoState struct {
type commandeer struct {
*commandeerHugoState
logger *loggers.Logger
logger loggers.Logger
serverConfig *config.Server
// Loading state
mustHaveConfigFile bool
failOnInitErr bool
running bool
// Currently only set when in "fast render mode". But it seems to
// be fast enough that we could maybe just add it for all server modes.
changeDetector *fileChangeDetector
@@ -112,7 +115,7 @@ func (c *commandeerHugoState) hugo() *hugolib.HugoSites {
}
func (c *commandeer) errCount() int {
return int(c.logger.ErrorCounter.Count())
return int(c.logger.LogCounters().ErrorCounter.Count())
}
func (c *commandeer) getErrorWithContext() interface{} {
@@ -155,8 +158,7 @@ func (c *commandeer) initFs(fs *hugofs.Fs) error {
return nil
}
func newCommandeer(mustHaveConfigFile, running bool, h *hugoBuilderCommon, f flagsToConfigHandler, cfgInit func(c *commandeer) error, subCmdVs ...*cobra.Command) (*commandeer, error) {
func newCommandeer(mustHaveConfigFile, failOnInitErr, running bool, h *hugoBuilderCommon, f flagsToConfigHandler, cfgInit func(c *commandeer) error, subCmdVs ...*cobra.Command) (*commandeer, error) {
var rebuildDebouncer func(f func())
if running {
// The time value used is tested with mass content replacements in a fairly big Hugo site.
@@ -178,11 +180,17 @@ func newCommandeer(mustHaveConfigFile, running bool, h *hugoBuilderCommon, f fla
visitedURLs: types.NewEvictingStringQueue(10),
debounce: rebuildDebouncer,
fullRebuildSem: semaphore.NewWeighted(1),
// Init state
mustHaveConfigFile: mustHaveConfigFile,
failOnInitErr: failOnInitErr,
running: running,
// This will be replaced later, but we need something to log to before the configuration is read.
logger: loggers.NewLogger(jww.LevelWarn, jww.LevelError, out, ioutil.Discard, running),
}
return c, c.loadConfig(mustHaveConfigFile, running)
return c, c.loadConfig()
}
type fileChangeDetector struct {
@@ -247,8 +255,7 @@ func (f *fileChangeDetector) PrepareNew() {
f.current = make(map[string]string)
}
func (c *commandeer) loadConfig(mustHaveConfigFile, running bool) error {
func (c *commandeer) loadConfig() error {
if c.DepsCfg == nil {
c.DepsCfg = &deps.DepsCfg{}
}
@@ -260,7 +267,7 @@ func (c *commandeer) loadConfig(mustHaveConfigFile, running bool) error {
cfg := c.DepsCfg
c.configured = false
cfg.Running = running
cfg.Running = c.running
var dir string
if c.h.source != "" {
@@ -274,10 +281,9 @@ func (c *commandeer) loadConfig(mustHaveConfigFile, running bool) error {
sourceFs = c.DepsCfg.Fs.Source
}
environment := c.h.getEnvironment(running)
environment := c.h.getEnvironment(c.running)
doWithConfig := func(cfg config.Provider) error {
if c.ftch != nil {
c.ftch.flagsToConfig(cfg)
}
@@ -308,14 +314,22 @@ func (c *commandeer) loadConfig(mustHaveConfigFile, running bool) error {
WorkingDir: dir,
Filename: c.h.cfgFile,
AbsConfigDir: c.h.getConfigDir(dir),
Environ: os.Environ(),
Environment: environment},
Environment: environment,
},
cfgSetAndInit,
doWithConfig)
if err != nil && mustHaveConfigFile {
return err
} else if mustHaveConfigFile && len(configFiles) == 0 {
if err != nil {
// We should improve the error handling here,
// but with hugo mod init and similar there is a chicken and egg situation
// with modules already configured in config.toml, so ignore those errors.
if c.mustHaveConfigFile || (c.failOnInitErr && !moduleNotFoundRe.MatchString(err.Error())) {
return err
} else {
// Just make it a warning.
c.logger.Warnln(err)
}
} else if c.mustHaveConfigFile && len(configFiles) == 0 {
return hugolib.ErrNoConfigFile
}
@@ -327,7 +341,7 @@ func (c *commandeer) loadConfig(mustHaveConfigFile, running bool) error {
}
// Set some commonly used flags
c.doLiveReload = running && !c.Cfg.GetBool("disableLiveReload")
c.doLiveReload = c.running && !c.Cfg.GetBool("disableLiveReload")
c.fastRenderMode = c.doLiveReload && !c.Cfg.GetBool("disableFastRender")
c.showErrorInBrowser = c.doLiveReload && !c.Cfg.GetBool("disableBrowserError")
@@ -339,7 +353,7 @@ func (c *commandeer) loadConfig(mustHaveConfigFile, running bool) error {
}
}
logger, err := c.createLogger(config, running)
logger, err := c.createLogger(config)
if err != nil {
return err
}
@@ -389,7 +403,7 @@ func (c *commandeer) loadConfig(mustHaveConfigFile, running bool) error {
}
// To debug hard-to-find path issues.
//fs.Destination = hugofs.NewStacktracerFs(fs.Destination, `fr/fr`)
// fs.Destination = hugofs.NewStacktracerFs(fs.Destination, `fr/fr`)
err = c.initFs(fs)
if err != nil {
@@ -399,10 +413,13 @@ func (c *commandeer) loadConfig(mustHaveConfigFile, running bool) error {
var h *hugolib.HugoSites
h, err = hugolib.NewHugoSites(*c.DepsCfg)
var createErr error
h, createErr = hugolib.NewHugoSites(*c.DepsCfg)
if h == nil || c.failOnInitErr {
err = createErr
}
c.hugoSites = h
close(c.created)
})
if err != nil {
@@ -415,8 +432,5 @@ func (c *commandeer) loadConfig(mustHaveConfigFile, running bool) error {
}
config.Set("cacheDir", cacheDir)
cfg.Logger.INFO.Println("Using config file:", config.ConfigFileUsed())
return nil
}
+16 -10
View File
@@ -88,6 +88,7 @@ var _ commandsBuilderGetter = (*baseBuilderCmd)(nil)
type commandsBuilderGetter interface {
getCommandsBuilder() *commandsBuilder
}
type baseBuilderCmd struct {
*baseCmd
*commandsBuilder
@@ -138,7 +139,6 @@ func (c *nilCommand) getCommand() *cobra.Command {
}
func (c *nilCommand) flagsToConfig(cfg config.Provider) {
}
func (b *commandsBuilder) newHugoCmd() *hugoCmd {
@@ -162,13 +162,21 @@ Complete documentation is available at http://gohugo.io/.`,
return nil
}
c, err := initializeConfig(true, cc.buildWatch, &cc.hugoBuilderCommon, cc, cfgInit)
// prevent cobra printing error so it can be handled here (before the timeTrack prints)
cmd.SilenceErrors = true
c, err := initializeConfig(true, true, cc.buildWatch, &cc.hugoBuilderCommon, cc, cfgInit)
if err != nil {
cmd.PrintErrln("Error:", err.Error())
return err
}
cc.c = c
return c.build()
err = c.build()
if err != nil {
cmd.PrintErrln("Error:", err.Error())
}
return err
},
})
@@ -204,6 +212,7 @@ type hugoBuilderCommon struct {
environment string
buildWatch bool
poll string
gc bool
@@ -291,6 +300,7 @@ func (cc *hugoBuilderCommon) handleFlags(cmd *cobra.Command) {
cmd.Flags().StringVarP(&cc.baseURL, "baseURL", "b", "", "hostname (and path) to the root, e.g. http://spf13.com/")
cmd.Flags().Bool("enableGitInfo", false, "add Git revision, date and author info to the pages")
cmd.Flags().BoolVar(&cc.gc, "gc", false, "enable to run some cleanup tasks (remove unused cache files) after the build")
cmd.Flags().StringVar(&cc.poll, "poll", "", "set this to a poll interval, e.g --poll 700ms, to use a poll based approach to watch for file system changes")
cmd.Flags().Bool("templateMetrics", false, "display metrics about template executions")
cmd.Flags().Bool("templateMetricsHints", false, "calculate some improvement hints when combined with --templateMetrics")
@@ -322,16 +332,12 @@ func (cc *hugoBuilderCommon) handleFlags(cmd *cobra.Command) {
_ = cmd.Flags().SetAnnotation("theme", cobra.BashCompSubdirsInDir, []string{"themes"})
}
func checkErr(logger *loggers.Logger, err error, s ...string) {
func checkErr(logger loggers.Logger, err error, s ...string) {
if err == nil {
return
}
if len(s) == 0 {
logger.CRITICAL.Println(err)
return
}
for _, message := range s {
logger.ERROR.Println(message)
logger.Errorln(message)
}
logger.ERROR.Println(err)
logger.Errorln(err)
}
+12 -16
View File
@@ -20,6 +20,8 @@ import (
"path/filepath"
"testing"
"github.com/gohugoio/hugo/config"
"github.com/gohugoio/hugo/htesting"
"github.com/spf13/afero"
@@ -29,13 +31,11 @@ import (
"github.com/gohugoio/hugo/common/types"
"github.com/spf13/cobra"
"github.com/spf13/viper"
qt "github.com/frankban/quicktest"
)
func TestExecute(t *testing.T) {
c := qt.New(t)
createSite := func(c *qt.C) (string, func()) {
@@ -90,7 +90,7 @@ func TestExecute(t *testing.T) {
defer clean()
resp := Execute([]string{"deploy", "-s=" + dir, "-e=staging", "--target=mydeployment", "--dryRun"})
c.Assert(resp.Err, qt.Not(qt.IsNil))
c.Assert(resp.Err.Error(), qt.Contains, `no provider registered for "hugocloud"`)
c.Assert(resp.Err.Error(), qt.Contains, `no driver registered for "hugocloud"`)
})
c.Run("list", func(c *qt.C) {
@@ -121,10 +121,9 @@ func TestExecute(t *testing.T) {
resp := Execute([]string{"new", "site", siteDir, "-e=staging"})
c.Assert(resp.Err, qt.IsNil)
config := readFileFrom(c, filepath.Join(siteDir, "config.toml"))
c.Assert(config, qt.Contains, "baseURL = \"http://example.org/\"")
c.Assert(config, qt.Contains, "baseURL = 'http://example.org/'")
checkNewSiteInited(c, siteDir)
})
}
func checkNewSiteInited(c *qt.C, basepath string) {
@@ -168,7 +167,7 @@ func TestFlags(t *testing.T) {
name: "ignoreVendor as bool",
args: []string{"server", "--ignoreVendor"},
check: func(c *qt.C, cmd *serverCmd) {
cfg := viper.New()
cfg := config.New()
cmd.flagsToConfig(cfg)
c.Assert(cfg.Get("ignoreVendor"), qt.Equals, true)
},
@@ -178,14 +177,15 @@ func TestFlags(t *testing.T) {
name: "ignoreVendorPaths",
args: []string{"server", "--ignoreVendorPaths=github.com/**"},
check: func(c *qt.C, cmd *serverCmd) {
cfg := viper.New()
cfg := config.New()
cmd.flagsToConfig(cfg)
c.Assert(cfg.Get("ignoreVendorPaths"), qt.Equals, "github.com/**")
},
},
{
name: "Persistent flags",
args: []string{"server",
args: []string{
"server",
"--config=myconfig.toml",
"--configDir=myconfigdir",
"--contentDir=mycontent",
@@ -217,7 +217,7 @@ func TestFlags(t *testing.T) {
c.Assert(sc.serverPort, qt.Equals, 1366)
c.Assert(sc.environment, qt.Equals, "testing")
cfg := viper.New()
cfg := config.New()
sc.flagsToConfig(cfg)
c.Assert(cfg.GetString("publishDir"), qt.Equals, "/tmp/mydestination")
c.Assert(cfg.GetString("contentDir"), qt.Equals, "mycontent")
@@ -235,12 +235,12 @@ func TestFlags(t *testing.T) {
// The flag is named i18n-warnings
c.Assert(cfg.GetBool("logI18nWarnings"), qt.Equals, true)
}}}
},
},
}
for _, test := range tests {
c.Run(test.name, func(c *qt.C) {
b := newCommandsBuilder()
root := b.addAll().build()
@@ -257,11 +257,9 @@ func TestFlags(t *testing.T) {
test.check(c, b.commands[0].(*serverCmd))
})
}
}
func TestCommandsExecute(t *testing.T) {
c := qt.New(t)
dir, clean, err := createSimpleTestSite(t, testSiteConfig{})
@@ -330,7 +328,6 @@ func TestCommandsExecute(t *testing.T) {
}
}
}
type testSiteConfig struct {
@@ -399,7 +396,6 @@ Environment: {{ hugo.Environment }}
`)
return d, clean, nil
}
func writeFile(t *testing.T, filename, content string) {
+51 -12
View File
@@ -21,6 +21,9 @@ import (
"regexp"
"sort"
"strings"
"time"
"github.com/gohugoio/hugo/common/maps"
"github.com/gohugoio/hugo/parser"
"github.com/gohugoio/hugo/parser/metadecoders"
@@ -28,7 +31,6 @@ import (
"github.com/gohugoio/hugo/modules"
"github.com/spf13/cobra"
"github.com/spf13/viper"
)
var _ cmder = (*configCmd)(nil)
@@ -60,7 +62,7 @@ func (b *commandsBuilder) newConfigCmd() *configCmd {
}
func (c *configCmd) printMounts(cmd *cobra.Command, args []string) error {
cfg, err := initializeConfig(true, false, &c.hugoBuilderCommon, c, nil)
cfg, err := initializeConfig(true, false, false, &c.hugoBuilderCommon, c, nil)
if err != nil {
return err
}
@@ -68,7 +70,7 @@ func (c *configCmd) printMounts(cmd *cobra.Command, args []string) error {
allModules := cfg.Cfg.Get("allmodules").(modules.Modules)
for _, m := range allModules {
if err := parser.InterfaceToConfig(&modMounts{m: m}, metadecoders.JSON, os.Stdout); err != nil {
if err := parser.InterfaceToConfig(&modMounts{m: m, verbose: c.verbose}, metadecoders.JSON, os.Stdout); err != nil {
return err
}
}
@@ -76,12 +78,12 @@ func (c *configCmd) printMounts(cmd *cobra.Command, args []string) error {
}
func (c *configCmd) printConfig(cmd *cobra.Command, args []string) error {
cfg, err := initializeConfig(true, false, &c.hugoBuilderCommon, c, nil)
cfg, err := initializeConfig(true, false, false, &c.hugoBuilderCommon, c, nil)
if err != nil {
return err
}
allSettings := cfg.Cfg.(*viper.Viper).AllSettings()
allSettings := cfg.Cfg.Get("").(maps.Params)
// We need to clean up this, but we store objects in the config that
// isn't really interesting to the end user, so filter these.
@@ -114,7 +116,8 @@ func (c *configCmd) printConfig(cmd *cobra.Command, args []string) error {
}
type modMounts struct {
m modules.Module
verbose bool
m modules.Module
}
type modMount struct {
@@ -134,13 +137,49 @@ func (m *modMounts) MarshalJSON() ([]byte, error) {
})
}
var ownerPath string
if m.m.Owner() != nil {
ownerPath = m.m.Owner().Path()
}
if m.verbose {
config := m.m.Config()
return json.Marshal(&struct {
Path string `json:"path"`
Version string `json:"version"`
Time time.Time `json:"time"`
Owner string `json:"owner"`
Dir string `json:"dir"`
Meta map[string]interface{} `json:"meta"`
HugoVersion modules.HugoVersion `json:"hugoVersion"`
Mounts []modMount `json:"mounts"`
}{
Path: m.m.Path(),
Version: m.m.Version(),
Time: m.m.Time(),
Owner: ownerPath,
Dir: m.m.Dir(),
Meta: config.Params,
HugoVersion: config.HugoVersion,
Mounts: mounts,
})
}
return json.Marshal(&struct {
Path string `json:"path"`
Dir string `json:"dir"`
Mounts []modMount `json:"mounts"`
Path string `json:"path"`
Version string `json:"version"`
Time time.Time `json:"time"`
Owner string `json:"owner"`
Dir string `json:"dir"`
Mounts []modMount `json:"mounts"`
}{
Path: m.m.Path(),
Dir: m.m.Dir(),
Mounts: mounts,
Path: m.m.Path(),
Version: m.m.Version(),
Time: m.m.Time(),
Owner: ownerPath,
Dir: m.m.Dir(),
Mounts: mounts,
})
}
+8 -11
View File
@@ -16,6 +16,7 @@ package commands
import (
"bytes"
"fmt"
"path/filepath"
"strings"
"time"
@@ -34,14 +35,10 @@ import (
"github.com/gohugoio/hugo/hugolib"
"path/filepath"
"github.com/spf13/cobra"
)
var (
_ cmder = (*convertCmd)(nil)
)
var _ cmder = (*convertCmd)(nil)
type convertCmd struct {
outputDir string
@@ -105,7 +102,7 @@ func (cc *convertCmd) convertContents(format metadecoders.Format) error {
return newUserError("Unsafe operation not allowed, use --unsafe or set a different output path")
}
c, err := initializeConfig(true, false, &cc.hugoBuilderCommon, cc, nil)
c, err := initializeConfig(true, false, false, &cc.hugoBuilderCommon, cc, nil)
if err != nil {
return err
}
@@ -123,7 +120,7 @@ func (cc *convertCmd) convertContents(format metadecoders.Format) error {
site := h.Sites[0]
site.Log.FEEDBACK.Println("processing", len(site.AllPages()), "content files")
site.Log.Println("processing", len(site.AllPages()), "content files")
for _, p := range site.AllPages() {
if err := cc.convertAndSavePage(p, site, format); err != nil {
return err
@@ -147,19 +144,19 @@ func (cc *convertCmd) convertAndSavePage(p page.Page, site *hugolib.Site, target
errMsg := fmt.Errorf("Error processing file %q", p.Path())
site.Log.INFO.Println("Attempting to convert", p.File().Filename())
site.Log.Infoln("Attempting to convert", p.File().Filename())
f := p.File()
file, err := f.FileInfo().Meta().Open()
if err != nil {
site.Log.ERROR.Println(errMsg)
site.Log.Errorln(errMsg)
file.Close()
return nil
}
pf, err := pageparser.ParseFrontMatterAndContent(file)
if err != nil {
site.Log.ERROR.Println(errMsg)
site.Log.Errorln(errMsg)
file.Close()
return err
}
@@ -179,7 +176,7 @@ func (cc *convertCmd) convertAndSavePage(p page.Page, site *hugolib.Site, target
var newContent bytes.Buffer
err = parser.InterfaceToFrontMatter(pf.FrontMatter, targetFormat, &newContent)
if err != nil {
site.Log.ERROR.Println(errMsg)
site.Log.Errorln(errMsg)
return err
}
+3 -1
View File
@@ -11,6 +11,8 @@
// See the License for the specific language governing permissions and
// limitations under the License.
// +build !nodeploy
package commands
import (
@@ -58,7 +60,7 @@ documentation.
c.Set("maxDeletes", cc.maxDeletes)
return nil
}
comm, err := initializeConfig(true, false, &cc.hugoBuilderCommon, cc, cfgInit)
comm, err := initializeConfig(true, true, false, &cc.hugoBuilderCommon, cc, cfgInit)
if err != nil {
return err
}
+28 -12
View File
@@ -16,6 +16,8 @@ package commands
import (
"runtime"
"github.com/gohugoio/hugo/common/hugo"
"github.com/spf13/cobra"
jww "github.com/spf13/jwalterweatherman"
)
@@ -27,18 +29,32 @@ type envCmd struct {
}
func newEnvCmd() *envCmd {
return &envCmd{baseCmd: newBaseCmd(&cobra.Command{
Use: "env",
Short: "Print Hugo version and environment info",
Long: `Print Hugo version and environment info. This is useful in Hugo bug reports.`,
RunE: func(cmd *cobra.Command, args []string) error {
printHugoVersion()
jww.FEEDBACK.Printf("GOOS=%q\n", runtime.GOOS)
jww.FEEDBACK.Printf("GOARCH=%q\n", runtime.GOARCH)
jww.FEEDBACK.Printf("GOVERSION=%q\n", runtime.Version())
return &envCmd{
baseCmd: newBaseCmd(&cobra.Command{
Use: "env",
Short: "Print Hugo version and environment info",
Long: `Print Hugo version and environment info. This is useful in Hugo bug reports.
return nil
},
}),
If you add the -v flag, you will get a full dependency list.
`,
RunE: func(cmd *cobra.Command, args []string) error {
printHugoVersion()
jww.FEEDBACK.Printf("GOOS=%q\n", runtime.GOOS)
jww.FEEDBACK.Printf("GOARCH=%q\n", runtime.GOARCH)
jww.FEEDBACK.Printf("GOVERSION=%q\n", runtime.Version())
isVerbose, _ := cmd.Flags().GetBool("verbose")
if isVerbose {
deps := hugo.GetDependencyList()
for _, dep := range deps {
jww.FEEDBACK.Printf("%s\n", dep)
}
}
return nil
},
}),
}
}
+33 -20
View File
@@ -14,6 +14,9 @@
package commands
import (
"io"
"os"
"github.com/spf13/cobra"
jww "github.com/spf13/jwalterweatherman"
)
@@ -23,7 +26,7 @@ var _ cmder = (*genautocompleteCmd)(nil)
type genautocompleteCmd struct {
autocompleteTarget string
// bash for now (zsh and others will come)
// bash, zsh, fish or powershell
autocompleteType string
*baseCmd
@@ -37,44 +40,54 @@ func newGenautocompleteCmd() *genautocompleteCmd {
Short: "Generate shell autocompletion script for Hugo",
Long: `Generates a shell autocompletion script for Hugo.
NOTE: The current version supports Bash only.
This should work for *nix systems with Bash installed.
The script is written to the console (stdout).
By default, the file is written directly to /etc/bash_completion.d
for convenience, and the command may need superuser rights, e.g.:
To write to file, add the ` + "`--completionfile=/path/to/file`" + ` flag.
$ sudo hugo gen autocomplete
Add ` + "`--completionfile=/path/to/file`" + ` flag to set alternative
file-path and name.
Add ` + "`--type={bash, zsh, fish or powershell}`" + ` flag to set alternative
shell type.
Logout and in again to reload the completion scripts,
or just source them in directly:
$ . /etc/bash_completion`,
$ . /etc/bash_completion or /path/to/file`,
RunE: func(cmd *cobra.Command, args []string) error {
if cc.autocompleteType != "bash" {
return newUserError("Only Bash is supported for now")
var err error
var target io.Writer
if cc.autocompleteTarget == "" {
target = os.Stdout
} else {
target, _ = os.OpenFile(cc.autocompleteTarget, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
}
err := cmd.Root().GenBashCompletionFile(cc.autocompleteTarget)
switch cc.autocompleteType {
case "bash":
err = cmd.Root().GenBashCompletion(target)
case "zsh":
err = cmd.Root().GenZshCompletion(target)
case "fish":
err = cmd.Root().GenFishCompletion(target, true)
case "powershell":
err = cmd.Root().GenPowerShellCompletion(target)
default:
return newUserError("Unsupported completion type")
}
if err != nil {
return err
}
jww.FEEDBACK.Println("Bash completion file for Hugo saved to", cc.autocompleteTarget)
if cc.autocompleteTarget != "" {
jww.FEEDBACK.Println(cc.autocompleteType+" completion file for Hugo saved to", cc.autocompleteTarget)
}
return nil
},
})
cc.cmd.PersistentFlags().StringVarP(&cc.autocompleteTarget, "completionfile", "", "/etc/bash_completion.d/hugo.sh", "autocompletion file")
cc.cmd.PersistentFlags().StringVarP(&cc.autocompleteType, "type", "", "bash", "autocompletion type (currently only bash supported)")
// For bash-completion
cc.cmd.PersistentFlags().SetAnnotation("completionfile", cobra.BashCompFilenameExt, []string{})
cc.cmd.PersistentFlags().StringVarP(&cc.autocompleteTarget, "completionfile", "f", "", "autocompletion file, defaults to stdout")
cc.cmd.PersistentFlags().StringVarP(&cc.autocompleteType, "type", "t", "bash", "autocompletion type (bash, zsh, fish, or powershell)")
return cc
}
+4 -6
View File
@@ -22,9 +22,7 @@ import (
"github.com/spf13/cobra"
)
var (
_ cmder = (*genChromaStyles)(nil)
)
var _ cmder = (*genChromaStyles)(nil)
type genChromaStyles struct {
style string
@@ -39,9 +37,9 @@ func createGenChromaStyles() *genChromaStyles {
baseCmd: newBaseCmd(&cobra.Command{
Use: "chromastyles",
Short: "Generate CSS stylesheet for the Chroma code highlighter",
Long: `Generate CSS stylesheet for the Chroma code highlighter for a given style. This stylesheet is needed if pygmentsUseClasses is enabled in config.
Long: `Generate CSS stylesheet for the Chroma code highlighter for a given style. This stylesheet is needed if markup.highlight.noClasses is disabled in config.
See https://help.farbox.com/pygments.html for preview of available styles`,
See https://xyproto.github.io/splash/docs/all.html for a preview of the available styles`,
}),
}
@@ -49,7 +47,7 @@ See https://help.farbox.com/pygments.html for preview of available styles`,
return g.generate()
}
g.cmd.PersistentFlags().StringVar(&g.style, "style", "friendly", "highlighter style (see https://help.farbox.com/pygments.html)")
g.cmd.PersistentFlags().StringVar(&g.style, "style", "friendly", "highlighter style (see https://xyproto.github.io/splash/docs/)")
g.cmd.PersistentFlags().StringVar(&g.highlightStyle, "highlightStyle", "bg:#ffffcc", "style used for highlighting lines (see https://github.com/alecthomas/chroma)")
g.cmd.PersistentFlags().StringVar(&g.linesStyle, "linesStyle", "", "style used for line numbers (see https://github.com/alecthomas/chroma)")
+7 -5
View File
@@ -18,7 +18,6 @@ import (
"path"
"path/filepath"
"strings"
"time"
"github.com/gohugoio/hugo/helpers"
"github.com/gohugoio/hugo/hugofs"
@@ -36,7 +35,6 @@ type genDocCmd struct {
func newGenDocCmd() *genDocCmd {
const gendocFrontmatterTemplate = `---
date: %s
title: "%s"
slug: %s
url: %s
@@ -57,6 +55,12 @@ It creates one Markdown file per command with front matter suitable
for rendering in Hugo.`,
RunE: func(cmd *cobra.Command, args []string) error {
cmd.VisitParents(func(c *cobra.Command) {
// Disable the "Auto generated by spf13/cobra on DATE"
// as it creates a lot of diffs.
c.DisableAutoGenTag = true
})
if !strings.HasSuffix(cc.gendocdir, helpers.FilePathSeparator) {
cc.gendocdir += helpers.FilePathSeparator
}
@@ -66,19 +70,17 @@ for rendering in Hugo.`,
return err
}
}
now := time.Now().Format("2006-01-02")
prepender := func(filename string) string {
name := filepath.Base(filename)
base := strings.TrimSuffix(name, path.Ext(name))
url := "/commands/" + strings.ToLower(base) + "/"
return fmt.Sprintf(gendocFrontmatterTemplate, now, strings.Replace(base, "_", " ", -1), base, url)
return fmt.Sprintf(gendocFrontmatterTemplate, strings.Replace(base, "_", " ", -1), base, url)
}
linkHandler := func(name string) string {
base := strings.TrimSuffix(name, path.Ext(name))
return "/commands/" + strings.ToLower(base) + "/"
}
jww.FEEDBACK.Println("Generating Hugo command-line documentation in", cc.gendocdir, "...")
doc.GenMarkdownTreeCustom(cmd.Root(), cc.gendocdir, prepender, linkHandler)
jww.FEEDBACK.Println("Done.")
+1 -4
View File
@@ -23,9 +23,7 @@ import (
"github.com/spf13/cobra"
)
var (
_ cmder = (*genDocsHelper)(nil)
)
var _ cmder = (*genDocsHelper)(nil)
type genDocsHelper struct {
target string
@@ -70,5 +68,4 @@ func (g *genDocsHelper) generate() error {
fmt.Println("Done!")
return nil
}
+98 -84
View File
@@ -19,10 +19,20 @@ import (
"context"
"fmt"
"io/ioutil"
"os"
"os/signal"
"path/filepath"
"runtime"
"runtime/pprof"
"runtime/trace"
"strings"
"sync/atomic"
"syscall"
"time"
"github.com/gohugoio/hugo/hugofs/files"
"github.com/gohugoio/hugo/common/types"
"github.com/gohugoio/hugo/hugofs"
@@ -31,21 +41,14 @@ import (
"github.com/pkg/errors"
"github.com/gohugoio/hugo/common/herrors"
"github.com/gohugoio/hugo/common/hugo"
"github.com/gohugoio/hugo/common/loggers"
"github.com/gohugoio/hugo/common/terminal"
"syscall"
"github.com/gohugoio/hugo/hugolib/filesystems"
"golang.org/x/sync/errgroup"
"os"
"path/filepath"
"runtime"
"strings"
"time"
"github.com/gohugoio/hugo/config"
flag "github.com/spf13/pflag"
@@ -82,7 +85,6 @@ func (r Response) IsUserError() bool {
// Execute adds all child commands to the root command HugoCmd and sets flags appropriately.
// The args are usually filled with os.Args[1:].
func Execute(args []string) Response {
hugoCmd := newCommandsBuilder().addAll().build()
cmd := hugoCmd.getCommand()
cmd.SetArgs(args)
@@ -116,21 +118,19 @@ func Execute(args []string) Response {
}
// InitializeConfig initializes a config file with sensible default configuration flags.
func initializeConfig(mustHaveConfigFile, running bool,
func initializeConfig(mustHaveConfigFile, failOnInitErr, running bool,
h *hugoBuilderCommon,
f flagsToConfigHandler,
cfgInit func(c *commandeer) error) (*commandeer, error) {
c, err := newCommandeer(mustHaveConfigFile, running, h, f, cfgInit)
c, err := newCommandeer(mustHaveConfigFile, failOnInitErr, running, h, f, cfgInit)
if err != nil {
return nil, err
}
return c, nil
}
func (c *commandeer) createLogger(cfg config.Provider, running bool) (*loggers.Logger, error) {
func (c *commandeer) createLogger(cfg config.Provider) (loggers.Logger, error) {
var (
logHandle = ioutil.Discard
logThreshold = jww.LevelWarn
@@ -174,7 +174,7 @@ func (c *commandeer) createLogger(cfg config.Provider, running bool) (*loggers.L
loggers.InitGlobalLogger(stdoutThreshold, logThreshold, outHandle, logHandle)
helpers.InitLoggers()
return loggers.NewLogger(stdoutThreshold, logThreshold, outHandle, logHandle, running), nil
return loggers.NewLogger(stdoutThreshold, logThreshold, outHandle, logHandle, c.running), nil
}
func initializeFlags(cmd *cobra.Command, cfg config.Provider) {
@@ -246,7 +246,6 @@ func initializeFlags(cmd *cobra.Command, cfg config.Provider) {
setValueFromFlag(cmd.Flags(), "destination", cfg, "publishDir", false)
setValueFromFlag(cmd.Flags(), "i18n-warnings", cfg, "logI18nWarnings", false)
setValueFromFlag(cmd.Flags(), "path-warnings", cfg, "logPathWarnings", false)
}
func setValueFromFlag(flags *flag.FlagSet, key string, cfg config.Provider, targetKey string, force bool) {
@@ -281,7 +280,7 @@ func isTerminal() bool {
return terminal.IsTerminal(os.Stdout)
}
func (c *commandeer) fullBuild() error {
func (c *commandeer) fullBuild(noBuildLock bool) error {
var (
g errgroup.Group
@@ -290,6 +289,7 @@ func (c *commandeer) fullBuild() error {
if !c.h.quiet {
fmt.Println("Start building sites … ")
fmt.Println(hugo.BuildVersionString())
if isTerminal() {
defer func() {
fmt.Print(showCursor + clearLine)
@@ -298,7 +298,6 @@ func (c *commandeer) fullBuild() error {
}
copyStaticFunc := func() error {
cnt, err := c.copyStatic()
if err != nil {
return errors.Wrap(err, "Error copying static files")
@@ -307,7 +306,7 @@ func (c *commandeer) fullBuild() error {
return nil
}
buildSitesFunc := func() error {
if err := c.buildSites(); err != nil {
if err := c.buildSites(noBuildLock); err != nil {
return errors.Wrap(err, "Error building site")
}
return nil
@@ -346,7 +345,6 @@ func (c *commandeer) fullBuild() error {
}
return nil
}
func (c *commandeer) initCPUProfile() (func(), error) {
@@ -374,12 +372,12 @@ func (c *commandeer) initMemProfile() {
f, err := os.Create(c.h.memprofile)
if err != nil {
c.logger.ERROR.Println("could not create memory profile: ", err)
c.logger.Errorf("could not create memory profile: ", err)
}
defer f.Close()
runtime.GC() // get up-to-date statistics
if err := pprof.WriteHeapProfile(f); err != nil {
c.logger.ERROR.Println("could not write memory profile: ", err)
c.logger.Errorf("could not write memory profile: ", err)
}
}
@@ -419,7 +417,6 @@ func (c *commandeer) initMutexProfile() (func(), error) {
pprof.Lookup("mutex").WriteTo(f, 0)
f.Close()
}, nil
}
func (c *commandeer) initMemTicker() func() {
@@ -429,7 +426,6 @@ func (c *commandeer) initMemTicker() func() {
var m runtime.MemStats
runtime.ReadMemStats(&m)
fmt.Printf("\n\nAlloc = %v\nTotalAlloc = %v\nSys = %v\nNumGC = %v\n\n", formatByteCount(m.Alloc), formatByteCount(m.TotalAlloc), formatByteCount(m.Sys), m.NumGC)
}
go func() {
@@ -442,7 +438,6 @@ func (c *commandeer) initMemTicker() func() {
printMem()
return
}
}
}()
@@ -452,7 +447,6 @@ func (c *commandeer) initMemTicker() func() {
}
func (c *commandeer) initProfiling() (func(), error) {
stopCPUProf, err := c.initCPUProfile()
if err != nil {
return nil, err
@@ -505,7 +499,7 @@ func (c *commandeer) build() error {
}
}()
if err := c.fullBuild(); err != nil {
if err := c.fullBuild(false); err != nil {
return err
}
@@ -518,7 +512,7 @@ func (c *commandeer) build() error {
if createCounter, ok := c.destinationFs.(hugofs.DuplicatesReporter); ok {
dupes := createCounter.ReportDuplicates()
if dupes != "" {
c.logger.WARN.Println("Duplicate target paths:", dupes)
c.logger.Warnln("Duplicate target paths:", dupes)
}
}
}
@@ -532,13 +526,13 @@ func (c *commandeer) build() error {
baseWatchDir := c.Cfg.GetString("workingDir")
rootWatchDirs := getRootWatchDirsStr(baseWatchDir, watchDirs)
c.logger.FEEDBACK.Printf("Watching for changes in %s%s{%s}\n", baseWatchDir, helpers.FilePathSeparator, rootWatchDirs)
c.logger.FEEDBACK.Println("Press Ctrl+C to stop")
watcher, err := c.newWatcher(watchDirs...)
c.logger.Printf("Watching for changes in %s%s{%s}\n", baseWatchDir, helpers.FilePathSeparator, rootWatchDirs)
c.logger.Println("Press Ctrl+C to stop")
watcher, err := c.newWatcher(c.h.poll, watchDirs...)
checkErr(c.Logger, err)
defer watcher.Close()
var sigs = make(chan os.Signal, 1)
sigs := make(chan os.Signal, 1)
signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM)
<-sigs
@@ -548,7 +542,6 @@ func (c *commandeer) build() error {
}
func (c *commandeer) serverBuild() error {
defer c.timeTrack(time.Now(), "Built")
stopProfiling, err := c.initProfiling()
if err != nil {
@@ -561,7 +554,7 @@ func (c *commandeer) serverBuild() error {
}
}()
if err := c.fullBuild(); err != nil {
if err := c.fullBuild(false); err != nil {
return err
}
@@ -584,13 +577,12 @@ func (c *commandeer) copyStatic() (map[string]uint64, error) {
}
func (c *commandeer) doWithPublishDirs(f func(sourceFs *filesystems.SourceFilesystem) (uint64, error)) (map[string]uint64, error) {
langCount := make(map[string]uint64)
staticFilesystems := c.hugo().BaseFs.SourceFilesystems.Static
if len(staticFilesystems) == 0 {
c.logger.INFO.Println("No static directories found to sync")
c.logger.Infoln("No static directories found to sync")
return langCount, nil
}
@@ -662,13 +654,13 @@ func (c *commandeer) copyStaticTo(sourceFs *filesystems.SourceFilesystem) (uint6
syncer.Delete = c.Cfg.GetBool("cleanDestinationDir")
if syncer.Delete {
c.logger.INFO.Println("removing all files from destination that don't exist in static dirs")
c.logger.Infoln("removing all files from destination that don't exist in static dirs")
syncer.DeleteFilter = func(f os.FileInfo) bool {
return f.IsDir() && strings.HasPrefix(f.Name(), ".")
}
}
c.logger.INFO.Println("syncing static files to", publishDir)
c.logger.Infoln("syncing static files to", publishDir)
// because we are using a baseFs (to get the union right).
// set sync src to root
@@ -689,7 +681,7 @@ func (c *commandeer) firstPathSpec() *helpers.PathSpec {
func (c *commandeer) timeTrack(start time.Time, name string) {
elapsed := time.Since(start)
c.logger.FEEDBACK.Printf("%s in %v ms", name, int(1000*elapsed.Seconds()))
c.logger.Printf("%s in %v ms", name, int(1000*elapsed.Seconds()))
}
// getDirList provides NewWatcher() with a list of directories to watch for changes.
@@ -698,7 +690,7 @@ func (c *commandeer) getDirList() ([]string, error) {
walkFn := func(path string, fi hugofs.FileMetaInfo, err error) error {
if err != nil {
c.logger.ERROR.Println("walker: ", err)
c.logger.Errorln("walker: ", err)
return nil
}
@@ -708,23 +700,22 @@ func (c *commandeer) getDirList() ([]string, error) {
return filepath.SkipDir
}
filenames = append(filenames, fi.Meta().Filename())
filenames = append(filenames, fi.Meta().Filename)
}
return nil
}
watchFiles := c.hugo().PathSpec.BaseFs.WatchDirs()
for _, fi := range watchFiles {
if !fi.IsDir() {
filenames = append(filenames, fi.Meta().Filename())
filenames = append(filenames, fi.Meta().Filename)
continue
}
w := hugofs.NewWalkway(hugofs.WalkwayConfig{Logger: c.logger, Info: fi, WalkFn: walkFn})
if err := w.Walk(); err != nil {
c.logger.ERROR.Println("walker: ", err)
c.logger.Errorln("walker: ", err)
}
}
@@ -733,27 +724,25 @@ func (c *commandeer) getDirList() ([]string, error) {
return filenames, nil
}
func (c *commandeer) buildSites() (err error) {
return c.hugo().Build(hugolib.BuildCfg{})
func (c *commandeer) buildSites(noBuildLock bool) (err error) {
return c.hugo().Build(hugolib.BuildCfg{NoBuildLock: noBuildLock})
}
func (c *commandeer) handleBuildErr(err error, msg string) {
c.buildErr = err
c.logger.ERROR.Print(msg + ":\n\n")
c.logger.ERROR.Println(helpers.FirstUpper(err.Error()))
c.logger.Errorln(msg + ":\n")
c.logger.Errorln(helpers.FirstUpper(err.Error()))
if !c.h.quiet && c.h.verbose {
herrors.PrintStackTraceFromErr(err)
}
}
func (c *commandeer) rebuildSites(events []fsnotify.Event) error {
defer c.timeTrack(time.Now(), "Total")
c.buildErr = nil
visited := c.visitedURLs.PeekAllSet()
if c.fastRenderMode {
// Make sure we always render the home pages
for _, l := range c.languages {
langPath := c.hugo().PathSpec.GetLangSubDir(l.Lang)
@@ -763,9 +752,8 @@ func (c *commandeer) rebuildSites(events []fsnotify.Event) error {
home := c.hugo().PathSpec.PrependBasePath("/"+langPath, false)
visited[home] = true
}
}
return c.hugo().Build(hugolib.BuildCfg{RecentlyVisited: visited, ErrRecovery: c.wasError}, events...)
return c.hugo().Build(hugolib.BuildCfg{NoBuildLock: true, RecentlyVisited: visited, ErrRecovery: c.wasError}, events...)
}
func (c *commandeer) partialReRender(urls ...string) error {
@@ -777,7 +765,9 @@ func (c *commandeer) partialReRender(urls ...string) error {
for _, url := range urls {
visited[url] = true
}
return c.hugo().Build(hugolib.BuildCfg{RecentlyVisited: visited, PartialReRender: true, ErrRecovery: c.wasError})
// Note: We do not set NoBuildLock as the file lock is not acquired at this stage.
return c.hugo().Build(hugolib.BuildCfg{NoBuildLock: false, RecentlyVisited: visited, PartialReRender: true, ErrRecovery: c.wasError})
}
func (c *commandeer) fullRebuild(changeType string) {
@@ -793,13 +783,11 @@ func (c *commandeer) fullRebuild(changeType string) {
c.fullRebuildSem.Acquire(context.Background(), 1)
go func() {
defer c.fullRebuildSem.Release(1)
c.printChangeDetected(changeType)
defer func() {
// Allow any file system events to arrive back.
// This will block any rebuild on config changes for the
// duration of the sleep.
@@ -809,7 +797,7 @@ func (c *commandeer) fullRebuild(changeType string) {
defer c.timeTrack(time.Now(), "Rebuilt")
c.commandeerHugoState = newCommandeerHugoState()
err := c.loadConfig(true, true)
err := c.loadConfig()
if err != nil {
// Set the processing on pause until the state is recovered.
c.paused = true
@@ -822,13 +810,13 @@ func (c *commandeer) fullRebuild(changeType string) {
if !c.paused {
_, err := c.copyStatic()
if err != nil {
c.logger.ERROR.Println(err)
c.logger.Errorln(err)
return
}
err = c.buildSites()
err = c.buildSites(true)
if err != nil {
c.logger.ERROR.Println(err)
c.logger.Errorln(err)
} else if !c.h.buildWatch && !c.Cfg.GetBool("disableLiveReload") {
livereload.ForceRefresh()
}
@@ -837,7 +825,7 @@ func (c *commandeer) fullRebuild(changeType string) {
}
// newWatcher creates a new watcher to watch filesystem events.
func (c *commandeer) newWatcher(dirList ...string) (*watcher.Batcher, error) {
func (c *commandeer) newWatcher(pollIntervalStr string, dirList ...string) (*watcher.Batcher, error) {
if runtime.GOOS == "darwin" {
tweakLimit()
}
@@ -847,8 +835,21 @@ func (c *commandeer) newWatcher(dirList ...string) (*watcher.Batcher, error) {
return nil, err
}
watcher, err := watcher.New(1 * time.Second)
var pollInterval time.Duration
poll := pollIntervalStr != ""
if poll {
pollInterval, err = types.ToDurationE(pollIntervalStr)
if err != nil {
return nil, fmt.Errorf("invalid value for flag poll: %s", err)
}
c.logger.Printf("Use watcher with poll interval %v", pollInterval)
}
if pollInterval == 0 {
pollInterval = 500 * time.Millisecond
}
watcher, err := watcher.New(500*time.Millisecond, pollInterval, poll)
if err != nil {
return nil, err
}
@@ -862,7 +863,7 @@ func (c *commandeer) newWatcher(dirList ...string) (*watcher.Batcher, error) {
// Identifies changes to config (config.toml) files.
configSet := make(map[string]bool)
c.logger.FEEDBACK.Println("Watching for config changes in", strings.Join(c.configFiles, ", "))
c.logger.Println("Watching for config changes in", strings.Join(c.configFiles, ", "))
for _, configFile := range c.configFiles {
watcher.Add(configFile)
configSet[configFile] = true
@@ -872,14 +873,20 @@ func (c *commandeer) newWatcher(dirList ...string) (*watcher.Batcher, error) {
for {
select {
case evs := <-watcher.Events:
unlock, err := c.hugo().BaseFs.LockBuild()
if err != nil {
c.logger.Errorln("Failed to acquire a build lock: %s", err)
return
}
c.handleEvents(watcher, staticSyncer, evs, configSet)
if c.showErrorInBrowser && c.errCount() > 0 {
// Need to reload browser to show the error
livereload.ForceRefresh()
}
case err := <-watcher.Errors:
if err != nil {
c.logger.ERROR.Println("Error while watching:", err)
unlock()
case err := <-watcher.Errors():
if err != nil && !os.IsNotExist(err) {
c.logger.Errorln("Error while watching:", err)
}
}
}
@@ -895,9 +902,9 @@ func (c *commandeer) printChangeDetected(typ string) {
}
msg += " detected, rebuilding site."
c.logger.FEEDBACK.Println(msg)
c.logger.Println(msg)
const layout = "2006-01-02 15:04:05.000 -0700"
c.logger.FEEDBACK.Println(time.Now().Format(layout))
c.logger.Println(time.Now().Format(layout))
}
const (
@@ -909,7 +916,6 @@ func (c *commandeer) handleEvents(watcher *watcher.Batcher,
staticSyncer *staticSyncer,
evs []fsnotify.Event,
configSet map[string]bool) {
defer func() {
c.wasError = false
}()
@@ -950,7 +956,6 @@ func (c *commandeer) handleEvents(watcher *watcher.Batcher,
time.Sleep(100 * time.Millisecond)
}
}
}
// Config file(s) changed. Need full rebuild.
@@ -979,14 +984,16 @@ func (c *commandeer) handleEvents(watcher *watcher.Batcher,
return
}
c.logger.INFO.Println("Received System Events:", evs)
c.logger.Infoln("Received System Events:", evs)
staticEvents := []fsnotify.Event{}
dynamicEvents := []fsnotify.Event{}
// Special handling for symbolic links inside /content.
filtered := []fsnotify.Event{}
for _, ev := range evs {
if c.hugo().ShouldSkipFileChangeEvent(ev) {
continue
}
// Check the most specific first, i.e. files.
contentMapped := c.hugo().ContentChanges.GetSymbolicLinkMappings(ev.Name)
if len(contentMapped) > 0 {
@@ -1059,7 +1066,7 @@ func (c *commandeer) handleEvents(watcher *watcher.Batcher,
walkAdder := func(path string, f hugofs.FileMetaInfo, err error) error {
if f.IsDir() {
c.logger.FEEDBACK.Println("adding created directory to watchlist", path)
c.logger.Println("adding created directory to watchlist", path)
if err := watcher.Add(path); err != nil {
return err
}
@@ -1091,15 +1098,15 @@ func (c *commandeer) handleEvents(watcher *watcher.Batcher,
c.printChangeDetected("Static files")
if c.Cfg.GetBool("forceSyncStatic") {
c.logger.FEEDBACK.Printf("Syncing all static files\n")
c.logger.Printf("Syncing all static files\n")
_, err := c.copyStatic()
if err != nil {
c.logger.ERROR.Println("Error copying static files to publish dir:", err)
c.logger.Errorln("Error copying static files to publish dir:", err)
return
}
} else {
if err := staticSyncer.syncsStaticEvents(staticEvents); err != nil {
c.logger.ERROR.Println("Error syncing static files to publish dir:", err)
c.logger.Errorln("Error syncing static files to publish dir:", err)
return
}
}
@@ -1130,9 +1137,13 @@ func (c *commandeer) handleEvents(watcher *watcher.Batcher,
c.printChangeDetected("")
c.changeDetector.PrepareNew()
if err := c.rebuildSites(dynamicEvents); err != nil {
c.handleBuildErr(err, "Rebuild failed")
}
func() {
defer c.timeTrack(time.Now(), "Total")
if err := c.rebuildSites(dynamicEvents); err != nil {
c.handleBuildErr(err, "Rebuild failed")
}
}()
if doLiveReload {
if len(partitionedEvents.ContentEvents) == 0 && len(partitionedEvents.AssetEvents) > 0 {
@@ -1192,18 +1203,21 @@ func partitionDynamicEvents(sourceFs *filesystems.SourceFilesystems, events []fs
}
}
return
}
func pickOneWriteOrCreatePath(events []fsnotify.Event) string {
name := ""
// Some editors (for example notepad.exe on Windows) triggers a change
// both for directory and file. So we pick the longest path, which should
// be the file itself.
for _, ev := range events {
if (ev.Op&fsnotify.Write == fsnotify.Write || ev.Op&fsnotify.Create == fsnotify.Create) && len(ev.Name) > len(name) {
name = ev.Name
if ev.Op&fsnotify.Write == fsnotify.Write || ev.Op&fsnotify.Create == fsnotify.Create {
if files.IsIndexContentFile(ev.Name) {
return ev.Name
}
if files.IsContentFile(ev.Name) {
name = ev.Name
}
}
}
-1
View File
@@ -44,5 +44,4 @@ contentDir = "thisdoesnotexist"
_, err = cmd.ExecuteC()
c.Assert(err, qt.IsNil)
}
+7 -1
View File
@@ -13,7 +13,13 @@
package commands
import "github.com/spf13/cobra"
import (
// For time zone lookups on Windows without Go installed.
// See #8892
_ "time/tzdata"
"github.com/spf13/cobra"
)
func init() {
// This message to show to Windows users if Hugo is opened from explorer.exe
+5 -7
View File
@@ -74,11 +74,9 @@ Import from Jekyll requires two paths, e.g. ` + "`hugo import jekyll jekyll_root
cc.cmd.AddCommand(importJekyllCmd)
return cc
}
func (i *importCmd) importFromJekyll(cmd *cobra.Command, args []string) error {
if len(args) < 2 {
return newUserError(`import from jekyll requires two paths, e.g. ` + "`hugo import jekyll jekyll_root_path target_path`.")
}
@@ -255,13 +253,11 @@ func (i *importCmd) loadJekyllConfig(fs afero.Fs, jekyllRoot string) map[string]
defer f.Close()
b, err := ioutil.ReadAll(f)
if err != nil {
return nil
}
c, err := metadecoders.Default.UnmarshalToMap(b, metadecoders.YAML)
if err != nil {
return nil
}
@@ -338,8 +334,10 @@ func (i *importCmd) copyJekyllFilesAndFolders(jekyllRoot, dest string, jekyllPos
}
} else {
lowerEntryName := strings.ToLower(entry.Name())
exceptSuffix := []string{".md", ".markdown", ".html", ".htm",
".xml", ".textile", "rakefile", "gemfile", ".lock"}
exceptSuffix := []string{
".md", ".markdown", ".html", ".htm",
".xml", ".textile", "rakefile", "gemfile", ".lock",
}
isExcept := false
for _, suffix := range exceptSuffix {
if strings.HasSuffix(lowerEntryName, suffix) {
@@ -602,8 +600,8 @@ func replaceImageTag(match string) string {
}
result.WriteString(">}}")
return result.String()
}
func replaceOptionalPart(buffer *bytes.Buffer, partName string, part string) {
if len(part) > 0 {
buffer.WriteString(partName + "=\"" + part + "\" ")
+78 -38
View File
@@ -53,25 +53,41 @@ func TestConvertJekyllMetadata(t *testing.T) {
draft bool
expect string
}{
{map[interface{}]interface{}{}, "testPost", time.Date(2015, 10, 1, 0, 0, 0, 0, time.UTC), false,
`{"date":"2015-10-01T00:00:00Z"}`},
{map[interface{}]interface{}{}, "testPost", time.Date(2015, 10, 1, 0, 0, 0, 0, time.UTC), true,
`{"date":"2015-10-01T00:00:00Z","draft":true}`},
{map[interface{}]interface{}{"Permalink": "/permalink.html", "layout": "post"},
{
map[interface{}]interface{}{},
"testPost", time.Date(2015, 10, 1, 0, 0, 0, 0, time.UTC), false,
`{"date":"2015-10-01T00:00:00Z","url":"/permalink.html"}`},
{map[interface{}]interface{}{"permalink": "/permalink.html"},
`{"date":"2015-10-01T00:00:00Z"}`,
},
{
map[interface{}]interface{}{},
"testPost", time.Date(2015, 10, 1, 0, 0, 0, 0, time.UTC), true,
`{"date":"2015-10-01T00:00:00Z","draft":true}`,
},
{
map[interface{}]interface{}{"Permalink": "/permalink.html", "layout": "post"},
"testPost", time.Date(2015, 10, 1, 0, 0, 0, 0, time.UTC), false,
`{"date":"2015-10-01T00:00:00Z","url":"/permalink.html"}`},
{map[interface{}]interface{}{"category": nil, "permalink": 123},
`{"date":"2015-10-01T00:00:00Z","url":"/permalink.html"}`,
},
{
map[interface{}]interface{}{"permalink": "/permalink.html"},
"testPost", time.Date(2015, 10, 1, 0, 0, 0, 0, time.UTC), false,
`{"date":"2015-10-01T00:00:00Z"}`},
{map[interface{}]interface{}{"Excerpt_Separator": "sep"},
`{"date":"2015-10-01T00:00:00Z","url":"/permalink.html"}`,
},
{
map[interface{}]interface{}{"category": nil, "permalink": 123},
"testPost", time.Date(2015, 10, 1, 0, 0, 0, 0, time.UTC), false,
`{"date":"2015-10-01T00:00:00Z","excerpt_separator":"sep"}`},
{map[interface{}]interface{}{"category": "book", "layout": "post", "Others": "Goods", "Date": "2015-10-01 12:13:11"},
`{"date":"2015-10-01T00:00:00Z"}`,
},
{
map[interface{}]interface{}{"Excerpt_Separator": "sep"},
"testPost", time.Date(2015, 10, 1, 0, 0, 0, 0, time.UTC), false,
`{"Others":"Goods","categories":["book"],"date":"2015-10-01T12:13:11Z"}`},
`{"date":"2015-10-01T00:00:00Z","excerpt_separator":"sep"}`,
},
{
map[interface{}]interface{}{"category": "book", "layout": "post", "Others": "Goods", "Date": "2015-10-01 12:13:11"},
"testPost", time.Date(2015, 10, 1, 0, 0, 0, 0, time.UTC), false,
`{"Others":"Goods","categories":["book"],"date":"2015-10-01T12:13:11Z"}`,
},
}
for _, data := range testDataList {
@@ -90,44 +106,68 @@ func TestConvertJekyllContent(t *testing.T) {
content string
expect string
}{
{map[interface{}]interface{}{},
"Test content\r\n<!-- more -->\npart2 content", "Test content\n<!--more-->\npart2 content"},
{map[interface{}]interface{}{},
"Test content\n<!-- More -->\npart2 content", "Test content\n<!--more-->\npart2 content"},
{map[interface{}]interface{}{"excerpt_separator": "<!--sep-->"},
{
map[interface{}]interface{}{},
"Test content\r\n<!-- more -->\npart2 content", "Test content\n<!--more-->\npart2 content",
},
{
map[interface{}]interface{}{},
"Test content\n<!-- More -->\npart2 content", "Test content\n<!--more-->\npart2 content",
},
{
map[interface{}]interface{}{"excerpt_separator": "<!--sep-->"},
"Test content\n<!--sep-->\npart2 content",
"---\nexcerpt_separator: <!--sep-->\n---\nTest content\n<!--more-->\npart2 content"},
"---\nexcerpt_separator: <!--sep-->\n---\nTest content\n<!--more-->\npart2 content",
},
{map[interface{}]interface{}{}, "{% raw %}text{% endraw %}", "text"},
{map[interface{}]interface{}{}, "{%raw%} text2 {%endraw %}", "text2"},
{map[interface{}]interface{}{},
{
map[interface{}]interface{}{},
"{% highlight go %}\nvar s int\n{% endhighlight %}",
"{{< highlight go >}}\nvar s int\n{{< / highlight >}}"},
{map[interface{}]interface{}{},
"{{< highlight go >}}\nvar s int\n{{< / highlight >}}",
},
{
map[interface{}]interface{}{},
"{% highlight go linenos hl_lines=\"1 2\" %}\nvar s string\nvar i int\n{% endhighlight %}",
"{{< highlight go \"linenos=table,hl_lines=1 2\" >}}\nvar s string\nvar i int\n{{< / highlight >}}"},
"{{< highlight go \"linenos=table,hl_lines=1 2\" >}}\nvar s string\nvar i int\n{{< / highlight >}}",
},
// Octopress image tag
{map[interface{}]interface{}{},
{
map[interface{}]interface{}{},
"{% img http://placekitten.com/890/280 %}",
"{{< figure src=\"http://placekitten.com/890/280\" >}}"},
{map[interface{}]interface{}{},
"{{< figure src=\"http://placekitten.com/890/280\" >}}",
},
{
map[interface{}]interface{}{},
"{% img left http://placekitten.com/320/250 Place Kitten #2 %}",
"{{< figure class=\"left\" src=\"http://placekitten.com/320/250\" title=\"Place Kitten #2\" >}}"},
{map[interface{}]interface{}{},
"{{< figure class=\"left\" src=\"http://placekitten.com/320/250\" title=\"Place Kitten #2\" >}}",
},
{
map[interface{}]interface{}{},
"{% img right http://placekitten.com/300/500 150 250 'Place Kitten #3' %}",
"{{< figure class=\"right\" src=\"http://placekitten.com/300/500\" width=\"150\" height=\"250\" title=\"Place Kitten #3\" >}}"},
{map[interface{}]interface{}{},
"{{< figure class=\"right\" src=\"http://placekitten.com/300/500\" width=\"150\" height=\"250\" title=\"Place Kitten #3\" >}}",
},
{
map[interface{}]interface{}{},
"{% img right http://placekitten.com/300/500 150 250 'Place Kitten #4' 'An image of a very cute kitten' %}",
"{{< figure class=\"right\" src=\"http://placekitten.com/300/500\" width=\"150\" height=\"250\" title=\"Place Kitten #4\" alt=\"An image of a very cute kitten\" >}}"},
{map[interface{}]interface{}{},
"{{< figure class=\"right\" src=\"http://placekitten.com/300/500\" width=\"150\" height=\"250\" title=\"Place Kitten #4\" alt=\"An image of a very cute kitten\" >}}",
},
{
map[interface{}]interface{}{},
"{% img http://placekitten.com/300/500 150 250 'Place Kitten #4' 'An image of a very cute kitten' %}",
"{{< figure src=\"http://placekitten.com/300/500\" width=\"150\" height=\"250\" title=\"Place Kitten #4\" alt=\"An image of a very cute kitten\" >}}"},
{map[interface{}]interface{}{},
"{{< figure src=\"http://placekitten.com/300/500\" width=\"150\" height=\"250\" title=\"Place Kitten #4\" alt=\"An image of a very cute kitten\" >}}",
},
{
map[interface{}]interface{}{},
"{% img right /placekitten/300/500 'Place Kitten #4' 'An image of a very cute kitten' %}",
"{{< figure class=\"right\" src=\"/placekitten/300/500\" title=\"Place Kitten #4\" alt=\"An image of a very cute kitten\" >}}"},
{map[interface{}]interface{}{"category": "book", "layout": "post", "Date": "2015-10-01 12:13:11"},
"{{< figure class=\"right\" src=\"/placekitten/300/500\" title=\"Place Kitten #4\" alt=\"An image of a very cute kitten\" >}}",
},
{
map[interface{}]interface{}{"category": "book", "layout": "post", "Date": "2015-10-01 12:13:11"},
"somecontent",
"---\nDate: \"2015-10-01 12:13:11\"\ncategory: book\nlayout: post\n---\nsomecontent"},
"---\nDate: \"2015-10-01 12:13:11\"\ncategory: book\nlayout: post\n---\nsomecontent",
},
}
for _, data := range testDataList {
result, err := convertJekyllContent(data.metadata, data.content)
+1 -6
View File
@@ -40,13 +40,12 @@ func (lc *listCmd) buildSites(config map[string]interface{}) (*hugolib.HugoSites
return nil
}
c, err := initializeConfig(true, false, &lc.hugoBuilderCommon, lc, cfgInit)
c, err := initializeConfig(true, true, false, &lc.hugoBuilderCommon, lc, cfgInit)
if err != nil {
return nil, err
}
sites, err := hugolib.NewHugoSites(*c.DepsCfg)
if err != nil {
return nil, newSystemError("Error creating sites", err)
}
@@ -77,7 +76,6 @@ List requires a subcommand, e.g. ` + "`hugo list drafts`.",
Long: `List all of the drafts in your content directory.`,
RunE: func(cmd *cobra.Command, args []string) error {
sites, err := cc.buildSites(map[string]interface{}{"buildDrafts": true})
if err != nil {
return newSystemError("Error building sites", err)
}
@@ -97,7 +95,6 @@ List requires a subcommand, e.g. ` + "`hugo list drafts`.",
Long: `List all of the posts in your content directory which will be posted in the future.`,
RunE: func(cmd *cobra.Command, args []string) error {
sites, err := cc.buildSites(map[string]interface{}{"buildFuture": true})
if err != nil {
return newSystemError("Error building sites", err)
}
@@ -126,7 +123,6 @@ List requires a subcommand, e.g. ` + "`hugo list drafts`.",
Long: `List all of the posts in your content directory which has already expired.`,
RunE: func(cmd *cobra.Command, args []string) error {
sites, err := cc.buildSites(map[string]interface{}{"buildExpired": true})
if err != nil {
return newSystemError("Error building sites", err)
}
@@ -159,7 +155,6 @@ List requires a subcommand, e.g. ` + "`hugo list drafts`.",
"buildDrafts": true,
"buildFuture": true,
})
if err != nil {
return newSystemError("Error building sites", err)
}
+4 -5
View File
@@ -71,11 +71,12 @@ Also note that if you configure a positive maxAge for the "modules" file cache,
if all {
com, err := c.initConfig(false)
if err != nil && !moduleNotFoundRe.MatchString(err.Error()) {
if err != nil && com == nil {
return err
}
_, err = com.hugo().FileCaches.ModulesCache().Prune(true)
count, err := com.hugo().FileCaches.ModulesCache().Prune(true)
com.logger.Printf("Deleted %d files from module cache.", count)
return err
}
return c.withModsClient(true, func(c *modules.Client) error {
@@ -91,7 +92,6 @@ Also note that if you configure a positive maxAge for the "modules" file cache,
}
func (b *commandsBuilder) newModCmd() *modCmd {
c := &modCmd{}
const commonUsage = `
@@ -264,7 +264,6 @@ If a module is vendored, that is where Hugo will look for it's dependencies.
c.baseBuilderCmd = b.newBuilderCmd(cmd)
return c
}
func (c *modCmd) withModsClient(failOnMissingConfig bool, f func(*modules.Client) error) error {
@@ -286,7 +285,7 @@ func (c *modCmd) withHugo(f func(*hugolib.HugoSites) error) error {
}
func (c *modCmd) initConfig(failOnNoConfig bool) (*commandeer, error) {
com, err := initializeConfig(failOnNoConfig, false, &c.hugoBuilderCommon, c, nil)
com, err := initializeConfig(failOnNoConfig, false, false, &c.hugoBuilderCommon, c, nil)
if err != nil {
return nil, err
}
-2
View File
@@ -20,7 +20,6 @@ import (
)
func newModNPMCmd(c *modCmd) *cobra.Command {
cmd := &cobra.Command{
Use: "npm",
Short: "Various npm helpers.",
@@ -47,7 +46,6 @@ removed from Hugo, but we need to test this out in "real life" to get a feel of
so this may/will change in future versions of Hugo.
`,
RunE: func(cmd *cobra.Command, args []string) error {
return c.withHugo(func(h *hugolib.HugoSites) error {
return npm.Pack(h.BaseFs.SourceFs, h.BaseFs.Assets.Dirs)
})
+3 -14
View File
@@ -71,8 +71,7 @@ func (n *newCmd) newContent(cmd *cobra.Command, args []string) error {
return nil
}
c, err := initializeConfig(true, false, &n.hugoBuilderCommon, n, cfgInit)
c, err := initializeConfig(true, true, false, &n.hugoBuilderCommon, n, cfgInit)
if err != nil {
return err
}
@@ -81,17 +80,7 @@ func (n *newCmd) newContent(cmd *cobra.Command, args []string) error {
return newUserError("path needs to be provided")
}
createPath := args[0]
var kind string
createPath, kind = newContentPathSection(c.hugo(), createPath)
if n.contentType != "" {
kind = n.contentType
}
return create.NewContent(c.hugo(), kind, createPath)
return create.NewContent(c.hugo(), n.contentType, args[0])
}
func mkdir(x ...string) {
@@ -119,7 +108,7 @@ func newContentPathSection(h *hugolib.HugoSites, path string) (string, string) {
if h != nil {
for _, dir := range h.BaseFs.Content.Dirs {
createpath = strings.TrimPrefix(createpath, dir.Meta().Filename())
createpath = strings.TrimPrefix(createpath, dir.Meta().Filename)
}
}
+3 -4
View File
@@ -19,6 +19,7 @@ import (
"path/filepath"
"strings"
"github.com/gohugoio/hugo/config"
"github.com/gohugoio/hugo/parser/metadecoders"
_errors "github.com/pkg/errors"
@@ -29,7 +30,6 @@ import (
"github.com/gohugoio/hugo/parser"
"github.com/spf13/cobra"
jww "github.com/spf13/jwalterweatherman"
"github.com/spf13/viper"
)
var _ cmder = (*newSiteCmd)(nil)
@@ -58,7 +58,6 @@ Use ` + "`hugo new [contentPath]`" + ` to create new content.`,
cc.baseBuilderCmd = b.newBuilderBasicCmd(cmd)
return cc
}
func (n *newSiteCmd) doNewSite(fs *hugofs.Fs, basepath string, force bool) error {
@@ -103,7 +102,7 @@ func (n *newSiteCmd) doNewSite(fs *hugofs.Fs, basepath string, force bool) error
// Create a default archetype file.
helpers.SafeWriteToDisk(filepath.Join(archeTypePath, "default.md"),
strings.NewReader(create.ArchetypeTemplateTemplate), fs.Source)
strings.NewReader(create.DefaultArchetypeTemplateTemplate), fs.Source)
jww.FEEDBACK.Printf("Congratulations! Your new Hugo site is created in %s.\n\n", basepath)
jww.FEEDBACK.Println(nextStepsText())
@@ -124,7 +123,7 @@ func (n *newSiteCmd) newSite(cmd *cobra.Command, args []string) error {
forceNew, _ := cmd.Flags().GetBool("force")
return n.doNewSite(hugofs.NewDefault(viper.New()), createpath, forceNew)
return n.doNewSite(hugofs.NewDefault(config.New()), createpath, forceNew)
}
func createConfig(fs *hugofs.Fs, inpath string, kind string) (err error) {
+2 -4
View File
@@ -38,7 +38,7 @@ func (b *commandsBuilder) newNewThemeCmd() *newThemeCmd {
cmd := &cobra.Command{
Use: "theme [name]",
Short: "Create a new theme",
Long: `Create a new theme (skeleton) called [name] in the current directory.
Long: `Create a new theme (skeleton) called [name] in ./themes.
New theme is a skeleton. Please add content to the touched files. Add your
name to the copyright line in the license and adjust the theme.toml file
as you see fit.`,
@@ -52,8 +52,7 @@ as you see fit.`,
// newTheme creates a new Hugo theme template
func (n *newThemeCmd) newTheme(cmd *cobra.Command, args []string) error {
c, err := initializeConfig(false, false, &n.hugoBuilderCommon, n, nil)
c, err := initializeConfig(false, false, false, &n.hugoBuilderCommon, n, nil)
if err != nil {
return err
}
@@ -145,7 +144,6 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
}
func (n *newThemeCmd) createThemeMD(fs *hugofs.Fs, inpath string) (err error) {
by := []byte(`# theme.toml template for a Hugo theme
# See https://github.com/gohugoio/hugoThemes#themetoml for an example
+50
View File
@@ -0,0 +1,50 @@
// Copyright 2019 The Hugo Authors. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// +build nodeploy
package commands
import (
"errors"
"github.com/spf13/cobra"
)
var _ cmder = (*deployCmd)(nil)
// deployCmd supports deploying sites to Cloud providers.
type deployCmd struct {
*baseBuilderCmd
}
func (b *commandsBuilder) newDeployCmd() *deployCmd {
cc := &deployCmd{}
cmd := &cobra.Command{
Use: "deploy",
Short: "Deploy your site to a Cloud provider.",
Long: `Deploy your site to a Cloud provider.
See https://gohugo.io/hosting-and-deployment/hugo-deploy/ for detailed
documentation.
`,
RunE: func(cmd *cobra.Command, args []string) error {
return errors.New("build without HUGO_BUILD_TAGS=nodeploy to use this command")
},
}
cc.baseBuilderCmd = b.newBuilderBasicCmd(cmd)
return cc
}
-1
View File
@@ -61,7 +61,6 @@ func (c *releaseCommandeer) getCommand() *cobra.Command {
}
func (c *releaseCommandeer) flagsToConfig(cfg config.Provider) {
}
func (r *releaseCommandeer) release() error {
+35 -18
View File
@@ -31,6 +31,8 @@ import (
"syscall"
"time"
"github.com/gohugoio/hugo/common/paths"
"github.com/pkg/errors"
"github.com/gohugoio/hugo/livereload"
@@ -185,7 +187,7 @@ func (sc *serverCmd) server(cmd *cobra.Command, args []string) error {
// port set explicitly by user -- he/she probably meant it!
err = newSystemErrorF("Server startup failed: %s", err)
}
c.logger.FEEDBACK.Println("port", sc.serverPort, "already in use, attempting to use an available port")
c.logger.Println("port", sc.serverPort, "already in use, attempting to use an available port")
sp, err := helpers.FindAvailablePort()
if err != nil {
err = newSystemError("Unable to find alternative port to use:", err)
@@ -228,19 +230,30 @@ func (sc *serverCmd) server(cmd *cobra.Command, args []string) error {
}
return err
}
if err := memStats(); err != nil {
jww.WARN.Println("memstats error:", err)
}
c, err := initializeConfig(true, true, &sc.hugoBuilderCommon, sc, cfgInit)
// silence errors in cobra so we can handle them here
cmd.SilenceErrors = true
c, err := initializeConfig(true, true, true, &sc.hugoBuilderCommon, sc, cfgInit)
if err != nil {
cmd.PrintErrln("Error:", err.Error())
return err
}
if err := c.serverBuild(); err != nil {
err = func() error {
defer c.timeTrack(time.Now(), "Built")
err := c.serverBuild()
if err != nil {
cmd.PrintErrln("Error:", err.Error())
}
return err
}()
if err != nil {
return err
}
@@ -261,8 +274,7 @@ func (sc *serverCmd) server(cmd *cobra.Command, args []string) error {
for _, group := range watchGroups {
jww.FEEDBACK.Printf("Watching for changes in %s\n", group)
}
watcher, err := c.newWatcher(watchDirs...)
watcher, err := c.newWatcher(sc.poll, watchDirs...)
if err != nil {
return err
}
@@ -272,13 +284,12 @@ func (sc *serverCmd) server(cmd *cobra.Command, args []string) error {
}
return c.serve(sc)
}
func getRootWatchDirsStr(baseDir string, watchDirs []string) string {
relWatchDirs := make([]string, len(watchDirs))
for i, dir := range watchDirs {
relWatchDirs[i], _ = helpers.GetRelativePath(dir, baseDir)
relWatchDirs[i], _ = paths.GetRelativePath(dir, baseDir)
}
return strings.Join(helpers.UniqueStringsSorted(helpers.ExtractRootPaths(relWatchDirs)), ",")
@@ -301,7 +312,6 @@ func (f *fileServer) rewriteRequest(r *http.Request, toPath string) *http.Reques
r2.Header.Set("X-Rewrite-Original-URI", r.URL.RequestURI())
return r2
}
func (f *fileServer) createEndpoint(i int) (*http.ServeMux, string, string, error) {
@@ -350,14 +360,16 @@ func (f *fileServer) createEndpoint(i int) (*http.ServeMux, string, string, erro
w.WriteHeader(500)
r, err := f.errorTemplate(err)
if err != nil {
f.c.logger.ERROR.Println(err)
f.c.logger.Errorln(err)
}
port = 1313
if !f.c.paused {
port = f.c.Cfg.GetInt("liveReloadPort")
}
fmt.Fprint(w, injectLiveReloadScript(r, port))
lr := *u
lr.Host = fmt.Sprintf("%s:%d", lr.Hostname(), port)
fmt.Fprint(w, injectLiveReloadScript(r, lr))
return
}
@@ -391,7 +403,6 @@ func (f *fileServer) createEndpoint(i int) (*http.ServeMux, string, string, erro
} else {
doRedirect = false
}
}
}
@@ -411,7 +422,6 @@ func (f *fileServer) createEndpoint(i int) (*http.ServeMux, string, string, erro
}
if f.c.fastRenderMode && f.c.buildErr == nil {
if strings.HasSuffix(requestURI, "/") || strings.HasSuffix(requestURI, "html") || strings.HasSuffix(requestURI, "htm") {
if !f.c.visitedURLs.Contains(requestURI) {
// If not already on stack, re-render that single page.
@@ -451,8 +461,8 @@ var logErrorRe = regexp.MustCompile(`(?s)ERROR \d{4}/\d{2}/\d{2} \d{2}:\d{2}:\d{
func removeErrorPrefixFromLog(content string) string {
return logErrorRe.ReplaceAllLiteralString(content, "")
}
func (c *commandeer) serve(s *serverCmd) error {
func (c *commandeer) serve(s *serverCmd) error {
isMultiHost := c.hugo().IsMultihost()
var (
@@ -494,21 +504,26 @@ func (c *commandeer) serve(s *serverCmd) error {
livereload.Initialize()
}
var sigs = make(chan os.Signal, 1)
sigs := make(chan os.Signal, 1)
signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM)
for i := range baseURLs {
mu, serverURL, endpoint, err := srv.createEndpoint(i)
if doLiveReload {
mu.HandleFunc("/livereload.js", livereload.ServeJS)
mu.HandleFunc("/livereload", livereload.Handler)
u, err := url.Parse(helpers.SanitizeURL(baseURLs[i]))
if err != nil {
return err
}
mu.HandleFunc(u.Path+"/livereload.js", livereload.ServeJS)
mu.HandleFunc(u.Path+"/livereload", livereload.Handler)
}
jww.FEEDBACK.Printf("Web Server is available at %s (bind address %s)\n", serverURL, s.serverInterface)
go func() {
err = http.ListenAndServe(endpoint, mu)
if err != nil {
c.logger.ERROR.Printf("Error: %s\n", err.Error())
c.logger.Errorf("Error: %s\n", err.Error())
os.Exit(1)
}
}()
@@ -525,6 +540,8 @@ func (c *commandeer) serve(s *serverCmd) error {
<-sigs
}
c.hugo().Close()
return nil
}
+3 -2
View File
@@ -16,6 +16,7 @@ package commands
import (
"bytes"
"io"
"net/url"
"github.com/gohugoio/hugo/transform"
"github.com/gohugoio/hugo/transform/livereloadinject"
@@ -82,9 +83,9 @@ var buildErrorTemplate = `<!doctype html>
</html>
`
func injectLiveReloadScript(src io.Reader, port int) string {
func injectLiveReloadScript(src io.Reader, baseURL url.URL) string {
var b bytes.Buffer
chain := transform.Chain{livereloadinject.New(port)}
chain := transform.Chain{livereloadinject.New(baseURL)}
chain.Apply(&b, src)
return b.String()
+2 -4
View File
@@ -22,10 +22,10 @@ import (
"testing"
"time"
"github.com/gohugoio/hugo/config"
"github.com/gohugoio/hugo/helpers"
qt "github.com/frankban/quicktest"
"github.com/spf13/viper"
)
func TestServer(t *testing.T) {
@@ -73,7 +73,6 @@ func TestServer(t *testing.T) {
// Stop the server.
stop <- true
}
func TestFixURL(t *testing.T) {
@@ -102,7 +101,7 @@ func TestFixURL(t *testing.T) {
t.Run(test.TestName, func(t *testing.T) {
b := newCommandsBuilder()
s := b.newServerCmd()
v := viper.New()
v := config.New()
baseURL := test.CLIBaseURL
v.Set("baseURL", test.CfgBaseURL)
s.serverAppend = test.AppendPort
@@ -127,7 +126,6 @@ ERROR 2018/10/07 13:11:12 Rebuild failed: logged 1 error(s)
withoutError := removeErrorPrefixFromLog(content)
c.Assert(strings.Contains(withoutError, "ERROR"), qt.Equals, false)
}
func isWindowsCI() bool {
+6 -7
View File
@@ -58,7 +58,7 @@ func (s *staticSyncer) syncsStaticEvents(staticEvents []fsnotify.Event) error {
syncer.DestFs = c.Fs.Destination
// prevent spamming the log on changes
logger := helpers.NewDistinctFeedbackLogger()
logger := helpers.NewDistinctErrorLogger()
for _, ev := range staticEvents {
// Due to our approach of layering both directories and the content's rendered output
@@ -79,9 +79,9 @@ func (s *staticSyncer) syncsStaticEvents(staticEvents []fsnotify.Event) error {
fromPath := ev.Name
relPath := sourceFs.MakePathRelative(fromPath)
relPath, found := sourceFs.MakePathRelative(fromPath)
if relPath == "" {
if !found {
// Not member of this virtual host.
continue
}
@@ -107,10 +107,10 @@ func (s *staticSyncer) syncsStaticEvents(staticEvents []fsnotify.Event) error {
logger.Println("Syncing", relPath, "to", publishDir)
if err := syncer.Sync(filepath.Join(publishDir, relPath), relPath); err != nil {
c.logger.ERROR.Println(err)
c.logger.Errorln(err)
}
} else {
c.logger.ERROR.Println(err)
c.logger.Errorln(err)
}
continue
@@ -119,7 +119,7 @@ func (s *staticSyncer) syncsStaticEvents(staticEvents []fsnotify.Event) error {
// For all other event operations Hugo will sync static.
logger.Println("Syncing", relPath, "to", publishDir)
if err := syncer.Sync(filepath.Join(publishDir, relPath), relPath); err != nil {
c.logger.ERROR.Println(err)
c.logger.Errorln(err)
}
}
@@ -128,5 +128,4 @@ func (s *staticSyncer) syncsStaticEvents(staticEvents []fsnotify.Event) error {
_, err := c.doWithPublishDirs(syncFn)
return err
}
-1
View File
@@ -51,7 +51,6 @@ func Append(to interface{}, from ...interface{}) (interface{}, error) {
} else if !fromt.AssignableTo(tot) {
// Fall back to a []interface{} slice.
return appendToInterfaceSliceFromValues(tov, fromv)
}
}
}
+29 -14
View File
@@ -36,28 +36,44 @@ func TestAppend(t *testing.T) {
{nil, []interface{}{"a", "b"}, []string{"a", "b"}},
{nil, []interface{}{nil}, []interface{}{nil}},
{[]interface{}{}, []interface{}{[]string{"c", "d", "e"}}, []string{"c", "d", "e"}},
{tstSlicers{&tstSlicer{"a"}, &tstSlicer{"b"}},
{
tstSlicers{&tstSlicer{"a"}, &tstSlicer{"b"}},
[]interface{}{&tstSlicer{"c"}},
tstSlicers{&tstSlicer{"a"}, &tstSlicer{"b"}, &tstSlicer{"c"}}},
{&tstSlicers{&tstSlicer{"a"}, &tstSlicer{"b"}},
tstSlicers{&tstSlicer{"a"}, &tstSlicer{"b"}, &tstSlicer{"c"}},
},
{
&tstSlicers{&tstSlicer{"a"}, &tstSlicer{"b"}},
[]interface{}{&tstSlicer{"c"}},
tstSlicers{&tstSlicer{"a"},
tstSlicers{
&tstSlicer{"a"},
&tstSlicer{"b"},
&tstSlicer{"c"}}},
{testSlicerInterfaces{&tstSlicerIn1{"a"}, &tstSlicerIn1{"b"}},
&tstSlicer{"c"},
},
},
{
testSlicerInterfaces{&tstSlicerIn1{"a"}, &tstSlicerIn1{"b"}},
[]interface{}{&tstSlicerIn1{"c"}},
testSlicerInterfaces{&tstSlicerIn1{"a"}, &tstSlicerIn1{"b"}, &tstSlicerIn1{"c"}}},
testSlicerInterfaces{&tstSlicerIn1{"a"}, &tstSlicerIn1{"b"}, &tstSlicerIn1{"c"}},
},
//https://github.com/gohugoio/hugo/issues/5361
{[]string{"a", "b"}, []interface{}{tstSlicers{&tstSlicer{"a"}, &tstSlicer{"b"}}},
[]interface{}{"a", "b", &tstSlicer{"a"}, &tstSlicer{"b"}}},
{[]string{"a", "b"}, []interface{}{&tstSlicer{"a"}},
[]interface{}{"a", "b", &tstSlicer{"a"}}},
{
[]string{"a", "b"},
[]interface{}{tstSlicers{&tstSlicer{"a"}, &tstSlicer{"b"}}},
[]interface{}{"a", "b", &tstSlicer{"a"}, &tstSlicer{"b"}},
},
{
[]string{"a", "b"},
[]interface{}{&tstSlicer{"a"}},
[]interface{}{"a", "b", &tstSlicer{"a"}},
},
// Errors
{"", []interface{}{[]string{"a", "b"}}, false},
// No string concatenation.
{"ab",
{
"ab",
[]interface{}{"c"},
false},
false,
},
} {
result, err := Append(test.start, test.addend...)
@@ -71,5 +87,4 @@ func TestAppend(t *testing.T) {
c.Assert(err, qt.IsNil)
c.Assert(result, qt.DeepEquals, test.expected)
}
}
+10
View File
@@ -64,3 +64,13 @@ func Slice(args ...interface{}) interface{} {
}
return slice.Interface()
}
// StringSliceToInterfaceSlice converts ss to []interface{}.
func StringSliceToInterfaceSlice(ss []string) []interface{} {
result := make([]interface{}, len(ss))
for i, s := range ss {
result[i] = s
}
return result
}
+7 -7
View File
@@ -20,11 +20,13 @@ import (
qt "github.com/frankban/quicktest"
)
var _ Slicer = (*tstSlicer)(nil)
var _ Slicer = (*tstSlicerIn1)(nil)
var _ Slicer = (*tstSlicerIn2)(nil)
var _ testSlicerInterface = (*tstSlicerIn1)(nil)
var _ testSlicerInterface = (*tstSlicerIn1)(nil)
var (
_ Slicer = (*tstSlicer)(nil)
_ Slicer = (*tstSlicerIn1)(nil)
_ Slicer = (*tstSlicerIn2)(nil)
_ testSlicerInterface = (*tstSlicerIn1)(nil)
_ testSlicerInterface = (*tstSlicerIn1)(nil)
)
type testSlicerInterface interface {
Name() string
@@ -54,7 +56,6 @@ func (p *tstSlicerIn1) Slice(in interface{}) (interface{}, error) {
default:
return nil, errors.New("invalid type")
}
}
return result, nil
}
@@ -120,5 +121,4 @@ func TestSlice(t *testing.T) {
c.Assert(test.expected, qt.DeepEquals, result, errMsg)
}
}
+4
View File
@@ -18,4 +18,8 @@ package constants
const (
ErrIDAmbigousDisableKindTaxonomy = "error-disable-taxonomy"
ErrIDAmbigousOutputKindTaxonomy = "error-output-taxonomy"
// IDs for remote errors in tpl/data.
ErrRemoteGetJSON = "error-remote-getjson"
ErrRemoteGetCSV = "error-remote-getcsv"
)
+11
View File
@@ -100,6 +100,17 @@ func WithFileContextForFile(e error, realFilename, filename string, fs afero.Fs,
return WithFileContext(e, realFilename, f, matcher)
}
// WithFileContextForFileDefault tries to add file context using the default line matcher.
func WithFileContextForFileDefault(err error, filename string, fs afero.Fs) error {
err, _ = WithFileContextForFile(
err,
filename,
filename,
fs,
SimpleLineMatcher)
return err
}
// WithFileContextForFile will try to add a file context with lines matching the given matcher.
// If no match could be found, the original error is returned with false as the second return value.
func WithFileContext(e error, realFilename string, r io.Reader, matcher LineMatcherFn) (error, bool) {
-1
View File
@@ -125,5 +125,4 @@ E`, offsetMatcher)
c.Assert(location.Lines, qt.DeepEquals, []string{"A", "B", "C", "D"})
c.Assert(location.Position().LineNumber, qt.Equals, 2)
c.Assert(location.LinesPos, qt.Equals, 1)
}
+7
View File
@@ -88,3 +88,10 @@ func GetGID() uint64 {
// We will, at least to begin with, make some Hugo features (SCSS with libsass) optional,
// and this error is used to signal those situations.
var ErrFeatureNotAvailable = errors.New("this feature is not available in your current Hugo version, see https://goo.gl/YMrWcn for more information")
// Must panics if err != nil.
func Must(err error) {
if err != nil {
panic(err)
}
}
+1 -3
View File
@@ -21,9 +21,7 @@ import (
"github.com/pkg/errors"
)
var (
_ causer = (*fileError)(nil)
)
var _ causer = (*fileError)(nil)
// FileError represents an error when handling a file: Parsing a config file,
// execute a template etc.
-2
View File
@@ -36,7 +36,6 @@ func TestToLineNumberError(t *testing.T) {
{errors.New(`template: _default/single.html:4:15: executing "_default/single.html" at <.Titles>: can't evaluate field Titles in type *hugolib.PageOutput`), 0, 4, 15},
{errors.New("parse failed: template: _default/bundle-resource-meta.html:11: unexpected in operand"), 0, 11, 1},
{errors.New(`failed:: template: _default/bundle-resource-meta.html:2:7: executing "main" at <.Titles>`), 0, 2, 7},
{errors.New("error in front matter: Near line 32 (last key parsed 'title')"), 0, 32, 1},
{errors.New(`failed to load translations: (6, 7): was expecting token =, but got "g" instead`), 0, 6, 7},
} {
@@ -52,5 +51,4 @@ func TestToLineNumberError(t *testing.T) {
c.Assert(pos.ColumnNumber, qt.Equals, test.columnNumber, errMsg)
c.Assert(errors.Cause(got), qt.Not(qt.IsNil))
}
}
+13 -2
View File
@@ -16,6 +16,10 @@ package herrors
import (
"regexp"
"strconv"
"github.com/pkg/errors"
"github.com/pelletier/go-toml/v2"
)
var lineNumberExtractors = []lineNumberExtractor{
@@ -24,8 +28,7 @@ var lineNumberExtractors = []lineNumberExtractor{
newLineNumberErrHandlerFromRegexp(".*:(\\d+):"),
// TOML parse errors
newLineNumberErrHandlerFromRegexp(".*Near line (\\d+)(\\s.*)"),
tomlLineNumberExtractor,
// YAML parse errors
newLineNumberErrHandlerFromRegexp("line (\\d+):"),
@@ -35,6 +38,14 @@ var lineNumberExtractors = []lineNumberExtractor{
type lineNumberExtractor func(e error) (int, int)
var tomlLineNumberExtractor = func(e error) (int, int) {
e = errors.Cause(e)
if terr, ok := e.(*toml.DecodeError); ok {
return terr.Position()
}
return -1, -1
}
func newLineNumberErrHandlerFromRegexp(expression string) lineNumberExtractor {
re := regexp.MustCompile(expression)
return extractLineNo(re)
+276
View File
@@ -0,0 +1,276 @@
// Copyright 2020 The Hugo Authors. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package hexec
import (
"bytes"
"context"
"errors"
"fmt"
"io"
"regexp"
"strings"
"os"
"os/exec"
"github.com/cli/safeexec"
"github.com/gohugoio/hugo/config"
"github.com/gohugoio/hugo/config/security"
)
var WithDir = func(dir string) func(c *commandeer) {
return func(c *commandeer) {
c.dir = dir
}
}
var WithContext = func(ctx context.Context) func(c *commandeer) {
return func(c *commandeer) {
c.ctx = ctx
}
}
var WithStdout = func(w io.Writer) func(c *commandeer) {
return func(c *commandeer) {
c.stdout = w
}
}
var WithStderr = func(w io.Writer) func(c *commandeer) {
return func(c *commandeer) {
c.stderr = w
}
}
var WithStdin = func(r io.Reader) func(c *commandeer) {
return func(c *commandeer) {
c.stdin = r
}
}
var WithEnviron = func(env []string) func(c *commandeer) {
return func(c *commandeer) {
setOrAppend := func(s string) {
k1, _ := config.SplitEnvVar(s)
var found bool
for i, v := range c.env {
k2, _ := config.SplitEnvVar(v)
if k1 == k2 {
found = true
c.env[i] = s
}
}
if !found {
c.env = append(c.env, s)
}
}
for _, s := range env {
setOrAppend(s)
}
}
}
// New creates a new Exec using the provided security config.
func New(cfg security.Config) *Exec {
var baseEnviron []string
for _, v := range os.Environ() {
k, _ := config.SplitEnvVar(v)
if cfg.Exec.OsEnv.Accept(k) {
baseEnviron = append(baseEnviron, v)
}
}
return &Exec{
sc: cfg,
baseEnviron: baseEnviron,
}
}
// IsNotFound reports whether this is an error about a binary not found.
func IsNotFound(err error) bool {
var notFoundErr *NotFoundError
return errors.As(err, &notFoundErr)
}
// SafeCommand is a wrapper around os/exec Command which uses a LookPath
// implementation that does not search in current directory before looking in PATH.
// See https://github.com/cli/safeexec and the linked issues.
func SafeCommand(name string, arg ...string) (*exec.Cmd, error) {
bin, err := safeexec.LookPath(name)
if err != nil {
return nil, err
}
return exec.Command(bin, arg...), nil
}
// Exec encorces a security policy for commands run via os/exec.
type Exec struct {
sc security.Config
// os.Environ filtered by the Exec.OsEnviron whitelist filter.
baseEnviron []string
}
// New will fail if name is not allowed according to the configured security policy.
// Else a configured Runner will be returned ready to be Run.
func (e *Exec) New(name string, arg ...interface{}) (Runner, error) {
if err := e.sc.CheckAllowedExec(name); err != nil {
return nil, err
}
env := make([]string, len(e.baseEnviron))
copy(env, e.baseEnviron)
cm := &commandeer{
name: name,
env: env,
}
return cm.command(arg...)
}
// Npx is a convenience method to create a Runner running npx --no-install <name> <args.
func (e *Exec) Npx(name string, arg ...interface{}) (Runner, error) {
arg = append(arg[:0], append([]interface{}{"--no-install", name}, arg[0:]...)...)
return e.New("npx", arg...)
}
// Sec returns the security policies this Exec is configured with.
func (e *Exec) Sec() security.Config {
return e.sc
}
type NotFoundError struct {
name string
}
func (e *NotFoundError) Error() string {
return fmt.Sprintf("binary with name %q not found", e.name)
}
// Runner wraps a *os.Cmd.
type Runner interface {
Run() error
StdinPipe() (io.WriteCloser, error)
}
type cmdWrapper struct {
name string
c *exec.Cmd
outerr *bytes.Buffer
}
var notFoundRe = regexp.MustCompile(`(?s)not found:|could not determine executable`)
func (c *cmdWrapper) Run() error {
err := c.c.Run()
if err == nil {
return nil
}
if notFoundRe.MatchString(c.outerr.String()) {
return &NotFoundError{name: c.name}
}
return fmt.Errorf("failed to execute binary %q with args %v: %s", c.name, c.c.Args[1:], c.outerr.String())
}
func (c *cmdWrapper) StdinPipe() (io.WriteCloser, error) {
return c.c.StdinPipe()
}
type commandeer struct {
stdout io.Writer
stderr io.Writer
stdin io.Reader
dir string
ctx context.Context
name string
env []string
}
func (c *commandeer) command(arg ...interface{}) (*cmdWrapper, error) {
if c == nil {
return nil, nil
}
var args []string
for _, a := range arg {
switch v := a.(type) {
case string:
args = append(args, v)
case func(*commandeer):
v(c)
default:
return nil, fmt.Errorf("invalid argument to command: %T", a)
}
}
bin, err := safeexec.LookPath(c.name)
if err != nil {
return nil, &NotFoundError{
name: c.name,
}
}
outerr := &bytes.Buffer{}
if c.stderr == nil {
c.stderr = outerr
} else {
c.stderr = io.MultiWriter(c.stderr, outerr)
}
var cmd *exec.Cmd
if c.ctx != nil {
cmd = exec.CommandContext(c.ctx, bin, args...)
} else {
cmd = exec.Command(bin, args...)
}
cmd.Stdin = c.stdin
cmd.Stderr = c.stderr
cmd.Stdout = c.stdout
cmd.Env = c.env
cmd.Dir = c.dir
return &cmdWrapper{outerr: outerr, c: cmd, name: c.name}, nil
}
// InPath reports whether binaryName is in $PATH.
func InPath(binaryName string) bool {
if strings.Contains(binaryName, "/") {
panic("binary name should not contain any slash")
}
_, err := safeexec.LookPath(binaryName)
return err == nil
}
// LookPath finds the path to binaryName in $PATH.
// Returns "" if not found.
func LookPath(binaryName string) string {
if strings.Contains(binaryName, "/") {
panic("binary name should not contain any slash")
}
s, err := safeexec.LookPath(binaryName)
if err != nil {
return ""
}
return s
}
+1 -2
View File
@@ -23,7 +23,7 @@ import (
)
// TODO(bep) replace the private versions in /tpl with these.
// IsInt returns whether the given kind is a number.
// IsNumber returns whether the given kind is a number.
func IsNumber(kind reflect.Kind) bool {
return IsInt(kind) || IsUint(kind) || IsFloat(kind)
}
@@ -67,7 +67,6 @@ func IsTruthful(in interface{}) bool {
default:
return IsTruthfulValue(reflect.ValueOf(in))
}
}
var zeroType = reflect.TypeOf((*types.Zeroer)(nil)).Elem()
+150
View File
@@ -0,0 +1,150 @@
// Copyright 2021 The Hugo Authors. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package htime
import (
"strings"
"time"
"github.com/spf13/cast"
toml "github.com/pelletier/go-toml/v2"
"github.com/gohugoio/locales"
)
var (
longDayNames = []string{
"Sunday",
"Monday",
"Tuesday",
"Wednesday",
"Thursday",
"Friday",
"Saturday",
}
shortDayNames = []string{
"Sun",
"Mon",
"Tue",
"Wed",
"Thu",
"Fri",
"Sat",
}
shortMonthNames = []string{
"Jan",
"Feb",
"Mar",
"Apr",
"May",
"Jun",
"Jul",
"Aug",
"Sep",
"Oct",
"Nov",
"Dec",
}
longMonthNames = []string{
"January",
"February",
"March",
"April",
"May",
"June",
"July",
"August",
"September",
"October",
"November",
"December",
}
)
func NewTimeFormatter(ltr locales.Translator) TimeFormatter {
if ltr == nil {
panic("must provide a locales.Translator")
}
return TimeFormatter{
ltr: ltr,
}
}
// TimeFormatter is locale aware.
type TimeFormatter struct {
ltr locales.Translator
}
func (f TimeFormatter) Format(t time.Time, layout string) string {
if layout == "" {
return ""
}
if layout[0] == ':' {
// It may be one of Hugo's custom layouts.
switch strings.ToLower(layout[1:]) {
case "date_full":
return f.ltr.FmtDateFull(t)
case "date_long":
return f.ltr.FmtDateLong(t)
case "date_medium":
return f.ltr.FmtDateMedium(t)
case "date_short":
return f.ltr.FmtDateShort(t)
case "time_full":
return f.ltr.FmtTimeFull(t)
case "time_long":
return f.ltr.FmtTimeLong(t)
case "time_medium":
return f.ltr.FmtTimeMedium(t)
case "time_short":
return f.ltr.FmtTimeShort(t)
}
}
s := t.Format(layout)
monthIdx := t.Month() - 1 // Month() starts at 1.
dayIdx := t.Weekday()
s = strings.ReplaceAll(s, longMonthNames[monthIdx], f.ltr.MonthWide(t.Month()))
if !strings.Contains(s, f.ltr.MonthWide(t.Month())) {
s = strings.ReplaceAll(s, shortMonthNames[monthIdx], f.ltr.MonthAbbreviated(t.Month()))
}
s = strings.ReplaceAll(s, longDayNames[dayIdx], f.ltr.WeekdayWide(t.Weekday()))
if !strings.Contains(s, f.ltr.WeekdayWide(t.Weekday())) {
s = strings.ReplaceAll(s, shortDayNames[dayIdx], f.ltr.WeekdayAbbreviated(t.Weekday()))
}
return s
}
func ToTimeInDefaultLocationE(i interface{}, location *time.Location) (tim time.Time, err error) {
switch vv := i.(type) {
case toml.LocalDate:
return vv.AsTime(location), nil
case toml.LocalDateTime:
return vv.AsTime(location), nil
// issue #8895
// datetimes parsed by `go-toml` have empty zone name
// convert back them into string and use `cast`
case time.Time:
i = vv.Format(time.RFC3339)
}
return cast.ToTimeInDefaultLocationE(i, location)
}
+148
View File
@@ -0,0 +1,148 @@
// Copyright 2021 The Hugo Authors. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package htime
import (
"testing"
"time"
qt "github.com/frankban/quicktest"
translators "github.com/gohugoio/localescompressed"
)
func TestTimeFormatter(t *testing.T) {
c := qt.New(t)
june06, _ := time.Parse("2006-Jan-02", "2018-Jun-06")
june06 = june06.Add(7777 * time.Second)
jan06, _ := time.Parse("2006-Jan-02", "2018-Jan-06")
jan06 = jan06.Add(32 * time.Second)
mondayNovemberFirst, _ := time.Parse("2006-Jan-02", "2021-11-01")
mondayNovemberFirst = mondayNovemberFirst.Add(33 * time.Second)
c.Run("Norsk nynorsk", func(c *qt.C) {
f := NewTimeFormatter(translators.GetTranslator("nn"))
c.Assert(f.Format(june06, "Monday Jan 2 2006"), qt.Equals, "onsdag juni 6 2018")
c.Assert(f.Format(june06, "Mon January 2 2006"), qt.Equals, "on. juni 6 2018")
c.Assert(f.Format(june06, "Mon Mon"), qt.Equals, "on. on.")
})
c.Run("Custom layouts Norsk nynorsk", func(c *qt.C) {
f := NewTimeFormatter(translators.GetTranslator("nn"))
c.Assert(f.Format(june06, ":date_full"), qt.Equals, "onsdag 6. juni 2018")
c.Assert(f.Format(june06, ":date_long"), qt.Equals, "6. juni 2018")
c.Assert(f.Format(june06, ":date_medium"), qt.Equals, "6. juni 2018")
c.Assert(f.Format(june06, ":date_short"), qt.Equals, "06.06.2018")
c.Assert(f.Format(june06, ":time_full"), qt.Equals, "kl. 02:09:37 UTC")
c.Assert(f.Format(june06, ":time_long"), qt.Equals, "02:09:37 UTC")
c.Assert(f.Format(june06, ":time_medium"), qt.Equals, "02:09:37")
c.Assert(f.Format(june06, ":time_short"), qt.Equals, "02:09")
})
c.Run("Custom layouts English", func(c *qt.C) {
f := NewTimeFormatter(translators.GetTranslator("en"))
c.Assert(f.Format(june06, ":date_full"), qt.Equals, "Wednesday, June 6, 2018")
c.Assert(f.Format(june06, ":date_long"), qt.Equals, "June 6, 2018")
c.Assert(f.Format(june06, ":date_medium"), qt.Equals, "Jun 6, 2018")
c.Assert(f.Format(june06, ":date_short"), qt.Equals, "6/6/18")
c.Assert(f.Format(june06, ":time_full"), qt.Equals, "2:09:37 am UTC")
c.Assert(f.Format(june06, ":time_long"), qt.Equals, "2:09:37 am UTC")
c.Assert(f.Format(june06, ":time_medium"), qt.Equals, "2:09:37 am")
c.Assert(f.Format(june06, ":time_short"), qt.Equals, "2:09 am")
})
c.Run("English", func(c *qt.C) {
f := NewTimeFormatter(translators.GetTranslator("en"))
c.Assert(f.Format(june06, "Monday Jan 2 2006"), qt.Equals, "Wednesday Jun 6 2018")
c.Assert(f.Format(june06, "Mon January 2 2006"), qt.Equals, "Wed June 6 2018")
c.Assert(f.Format(june06, "Mon Mon"), qt.Equals, "Wed Wed")
})
c.Run("Weekdays German", func(c *qt.C) {
tr := translators.GetTranslator("de")
f := NewTimeFormatter(tr)
// Issue #9107
for i, weekDayWideGerman := range []string{"Montag", "Dienstag", "Mittwoch", "Donnerstag", "Freitag", "Samstag", "Sonntag"} {
date := mondayNovemberFirst.Add(time.Duration(i*24) * time.Hour)
c.Assert(tr.WeekdayWide(date.Weekday()), qt.Equals, weekDayWideGerman)
c.Assert(f.Format(date, "Monday"), qt.Equals, weekDayWideGerman)
}
for i, weekDayAbbreviatedGerman := range []string{"Mo.", "Di.", "Mi.", "Do.", "Fr.", "Sa.", "So."} {
date := mondayNovemberFirst.Add(time.Duration(i*24) * time.Hour)
c.Assert(tr.WeekdayAbbreviated(date.Weekday()), qt.Equals, weekDayAbbreviatedGerman)
c.Assert(f.Format(date, "Mon"), qt.Equals, weekDayAbbreviatedGerman)
}
})
c.Run("Months German", func(c *qt.C) {
tr := translators.GetTranslator("de")
f := NewTimeFormatter(tr)
// Issue #9107
for i, monthWideNorway := range []string{"Januar", "Februar", "März", "April", "Mai", "Juni", "Juli"} {
date := jan06.Add(time.Duration(i*24*31) * time.Hour)
c.Assert(tr.MonthWide(date.Month()), qt.Equals, monthWideNorway)
c.Assert(f.Format(date, "January"), qt.Equals, monthWideNorway)
}
})
}
func BenchmarkTimeFormatter(b *testing.B) {
june06, _ := time.Parse("2006-Jan-02", "2018-Jun-06")
b.Run("Native", func(b *testing.B) {
for i := 0; i < b.N; i++ {
got := june06.Format("Monday Jan 2 2006")
if got != "Wednesday Jun 6 2018" {
b.Fatalf("invalid format, got %q", got)
}
}
})
b.Run("Localized", func(b *testing.B) {
f := NewTimeFormatter(translators.GetTranslator("nn"))
b.ResetTimer()
for i := 0; i < b.N; i++ {
got := f.Format(june06, "Monday Jan 2 2006")
if got != "onsdag juni 6 2018" {
b.Fatalf("invalid format, got %q", got)
}
}
})
b.Run("Localized Custom", func(b *testing.B) {
f := NewTimeFormatter(translators.GetTranslator("nn"))
b.ResetTimer()
for i := 0; i < b.N; i++ {
got := f.Format(june06, ":date_medium")
if got != "6. juni 2018" {
b.Fatalf("invalid format, got %q", got)
}
}
})
}
+6 -1
View File
@@ -31,8 +31,13 @@ type ReadSeekCloser interface {
io.Closer
}
// ReadSeekCloserProvider provides a ReadSeekCloser.
type ReadSeekCloserProvider interface {
ReadSeekCloser() (ReadSeekCloser, error)
}
// ReadSeekerNoOpCloser implements ReadSeekCloser by doing nothing in Close.
// TODO(bep) rename this and simila to ReadSeekerNopCloser, naming used in stdlib, which kind of makes sense.
// TODO(bep) rename this and similar to ReadSeekerNopCloser, naming used in stdlib, which kind of makes sense.
type ReadSeekerNoOpCloser struct {
ReadSeeker
}
+65 -9
View File
@@ -18,6 +18,8 @@ import (
"html/template"
"os"
"path/filepath"
"runtime/debug"
"sort"
"strings"
"github.com/gohugoio/hugo/hugofs/files"
@@ -34,12 +36,15 @@ const (
)
var (
// commitHash contains the current Git revision. Use make to build to make
// sure this gets set.
// commitHash contains the current Git revision.
// Use mage to build to make sure this gets set.
commitHash string
// buildDate contains the date of the current build.
buildDate string
// vendorInfo contains vendor notes about the current build.
vendorInfo string
)
// Info contains information about the current Hugo environment
@@ -68,6 +73,10 @@ func (i Info) IsProduction() bool {
return i.Environment == EnvironmentProduction
}
func (i Info) IsExtended() bool {
return IsExtended
}
// NewInfo creates a new Hugo Info object.
func NewInfo(environment string) Info {
if environment == "" {
@@ -80,8 +89,10 @@ func NewInfo(environment string) Info {
}
}
// GetExecEnviron creates and gets the common os/exec environment used in the
// external programs we interact with via os/exec, e.g. postcss.
func GetExecEnviron(workDir string, cfg config.Provider, fs afero.Fs) []string {
env := os.Environ()
var env []string
nodepath := filepath.Join(workDir, "node_modules")
if np := os.Getenv("NODE_PATH"); np != "" {
nodepath = workDir + string(os.PathListSeparator) + np
@@ -89,14 +100,59 @@ func GetExecEnviron(workDir string, cfg config.Provider, fs afero.Fs) []string {
config.SetEnvVars(&env, "NODE_PATH", nodepath)
config.SetEnvVars(&env, "PWD", workDir)
config.SetEnvVars(&env, "HUGO_ENVIRONMENT", cfg.GetString("environment"))
fis, err := afero.ReadDir(fs, files.FolderJSConfig)
if err == nil {
for _, fi := range fis {
key := fmt.Sprintf("HUGO_FILE_%s", strings.ReplaceAll(strings.ToUpper(fi.Name()), ".", "_"))
value := fi.(hugofs.FileMetaInfo).Meta().Filename()
config.SetEnvVars(&env, key, value)
if fs != nil {
fis, err := afero.ReadDir(fs, files.FolderJSConfig)
if err == nil {
for _, fi := range fis {
key := fmt.Sprintf("HUGO_FILE_%s", strings.ReplaceAll(strings.ToUpper(fi.Name()), ".", "_"))
value := fi.(hugofs.FileMetaInfo).Meta().Filename
config.SetEnvVars(&env, key, value)
}
}
}
return env
}
// GetDependencyList returns a sorted dependency list on the format package="version".
// It includes both Go dependencies and (a manually maintained) list of C(++) dependencies.
func GetDependencyList() []string {
var deps []string
formatDep := func(path, version string) string {
return fmt.Sprintf("%s=%q", path, version)
}
if IsExtended {
deps = append(
deps,
// TODO(bep) consider adding a DepsNonGo() method to these upstream projects.
formatDep("github.com/sass/libsass", "3.6.5"),
formatDep("github.com/webmproject/libwebp", "v1.2.0"),
)
}
bi, ok := debug.ReadBuildInfo()
if !ok {
return deps
}
for _, dep := range bi.Deps {
deps = append(deps, formatDep(dep.Path, dep.Version))
}
sort.Strings(deps)
return deps
}
// IsRunningAsTest reports whether we are running as a test.
func IsRunningAsTest() bool {
for _, arg := range os.Args {
if strings.HasPrefix(arg, "-test") {
return true
}
}
return false
}
+1 -1
View File
@@ -32,8 +32,8 @@ func TestHugoInfo(t *testing.T) {
c.Assert(hugoInfo.Environment, qt.Equals, "production")
c.Assert(string(hugoInfo.Generator()), qt.Contains, fmt.Sprintf("Hugo %s", hugoInfo.Version()))
c.Assert(hugoInfo.IsProduction(), qt.Equals, true)
c.Assert(hugoInfo.IsExtended(), qt.Equals, IsExtended)
devHugoInfo := NewInfo("development")
c.Assert(devHugoInfo.IsProduction(), qt.Equals, false)
}
+10 -4
View File
@@ -16,7 +16,6 @@ package hugo
import (
"fmt"
"io"
"runtime"
"strings"
@@ -128,14 +127,15 @@ func (v Version) NextPatchLevel(level int) Version {
// BuildVersionString creates a version string. This is what you see when
// running "hugo version".
func BuildVersionString() string {
program := "Hugo Static Site Generator"
// program := "Hugo Static Site Generator"
program := "hugo"
version := "v" + CurrentVersion.String()
if commitHash != "" {
version += "-" + strings.ToUpper(commitHash)
}
if IsExtended {
version += "/extended"
version += "+extended"
}
osArch := runtime.GOOS + "/" + runtime.GOARCH
@@ -145,8 +145,14 @@ func BuildVersionString() string {
date = "unknown"
}
return fmt.Sprintf("%s %s %s BuildDate: %s", program, version, osArch, date)
versionString := fmt.Sprintf("%s %s %s BuildDate=%s",
program, version, osArch, date)
if vendorInfo != "" {
versionString += " VendorInfo=" + vendorInfo
}
return versionString
}
func version(version float32, patchVersion int, suffix string) string {
+1 -1
View File
@@ -16,7 +16,7 @@ package hugo
// CurrentVersion represents the current build version.
// This should be the only one.
var CurrentVersion = Version{
Number: 0.76,
Number: 0.91,
PatchLevel: 2,
Suffix: "",
}
+21 -8
View File
@@ -19,25 +19,31 @@ import (
)
// IgnorableLogger is a logger that ignores certain log statements.
type IgnorableLogger struct {
logger *Logger
type IgnorableLogger interface {
Logger
Errorsf(statementID, format string, v ...interface{})
Apply(logger Logger) IgnorableLogger
}
type ignorableLogger struct {
Logger
statements map[string]bool
}
// NewIgnorableLogger wraps the given logger and ignores the log statement IDs given.
func NewIgnorableLogger(logger *Logger, statements ...string) IgnorableLogger {
func NewIgnorableLogger(logger Logger, statements ...string) IgnorableLogger {
statementsSet := make(map[string]bool)
for _, s := range statements {
statementsSet[strings.ToLower(s)] = true
}
return IgnorableLogger{
logger: logger,
return ignorableLogger{
Logger: logger,
statements: statementsSet,
}
}
func (l IgnorableLogger) Errorf(statementID, format string, v ...interface{}) {
// Errorsf logs statementID as an ERROR if not configured as ignoreable.
func (l ignorableLogger) Errorsf(statementID, format string, v ...interface{}) {
if l.statements[statementID] {
// Ignore.
return
@@ -48,5 +54,12 @@ ignoreErrors = [%q]`, statementID)
format += ignoreMsg
l.logger.ERROR.Printf(format, v...)
l.Errorf(format, v...)
}
func (l ignorableLogger) Apply(logger Logger) IgnorableLogger {
return ignorableLogger{
Logger: logger,
statements: l.statements,
}
}
+124 -34
View File
@@ -1,4 +1,4 @@
// Copyright 2018 The Hugo Authors. All rights reserved.
// Copyright 2020 The Hugo Authors. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -29,10 +29,8 @@ import (
jww "github.com/spf13/jwalterweatherman"
)
var (
// Counts ERROR logs to the global jww logger.
GlobalErrorCounter *jww.Counter
)
// Counts ERROR logs to the global jww logger.
var GlobalErrorCounter *jww.Counter
func init() {
GlobalErrorCounter = &jww.Counter{}
@@ -56,39 +54,132 @@ func (w prefixWriter) Write(p []byte) (n int, err error) {
return len(p), nil
}
// Logger wraps a *loggers.Logger and some other related logging state.
type Logger struct {
type Logger interface {
Printf(format string, v ...interface{})
Println(v ...interface{})
PrintTimerIfDelayed(start time.Time, name string)
Debug() *log.Logger
Debugf(format string, v ...interface{})
Debugln(v ...interface{})
Info() *log.Logger
Infof(format string, v ...interface{})
Infoln(v ...interface{})
Warn() *log.Logger
Warnf(format string, v ...interface{})
Warnln(v ...interface{})
Error() *log.Logger
Errorf(format string, v ...interface{})
Errorln(v ...interface{})
Errors() string
Out() io.Writer
Reset()
// Used in tests.
LogCounters() *LogCounters
}
type LogCounters struct {
ErrorCounter *jww.Counter
WarnCounter *jww.Counter
}
type logger struct {
*jww.Notepad
// The writer that represents stdout.
// Will be ioutil.Discard when in quiet mode.
Out io.Writer
out io.Writer
ErrorCounter *jww.Counter
WarnCounter *jww.Counter
logCounters *LogCounters
// This is only set in server mode.
errors *bytes.Buffer
}
func (l *logger) Printf(format string, v ...interface{}) {
l.FEEDBACK.Printf(format, v...)
}
func (l *logger) Println(v ...interface{}) {
l.FEEDBACK.Println(v...)
}
func (l *logger) Debug() *log.Logger {
return l.DEBUG
}
func (l *logger) Debugf(format string, v ...interface{}) {
l.DEBUG.Printf(format, v...)
}
func (l *logger) Debugln(v ...interface{}) {
l.DEBUG.Println(v...)
}
func (l *logger) Infof(format string, v ...interface{}) {
l.INFO.Printf(format, v...)
}
func (l *logger) Infoln(v ...interface{}) {
l.INFO.Println(v...)
}
func (l *logger) Info() *log.Logger {
return l.INFO
}
func (l *logger) Warnf(format string, v ...interface{}) {
l.WARN.Printf(format, v...)
}
func (l *logger) Warnln(v ...interface{}) {
l.WARN.Println(v...)
}
func (l *logger) Warn() *log.Logger {
return l.WARN
}
func (l *logger) Errorf(format string, v ...interface{}) {
l.ERROR.Printf(format, v...)
}
func (l *logger) Errorln(v ...interface{}) {
l.ERROR.Println(v...)
}
func (l *logger) Error() *log.Logger {
return l.ERROR
}
func (l *logger) LogCounters() *LogCounters {
return l.logCounters
}
func (l *logger) Out() io.Writer {
return l.out
}
// PrintTimerIfDelayed prints a time statement to the FEEDBACK logger
// if considerable time is spent.
func (l *Logger) PrintTimerIfDelayed(start time.Time, name string) {
func (l *logger) PrintTimerIfDelayed(start time.Time, name string) {
elapsed := time.Since(start)
milli := int(1000 * elapsed.Seconds())
if milli < 500 {
return
}
l.FEEDBACK.Printf("%s in %v ms", name, milli)
l.Printf("%s in %v ms", name, milli)
}
func (l *Logger) PrintTimer(start time.Time, name string) {
func (l *logger) PrintTimer(start time.Time, name string) {
elapsed := time.Since(start)
milli := int(1000 * elapsed.Seconds())
l.FEEDBACK.Printf("%s in %v ms", name, milli)
l.Printf("%s in %v ms", name, milli)
}
func (l *Logger) Errors() string {
func (l *logger) Errors() string {
if l.errors == nil {
return ""
}
@@ -96,45 +187,45 @@ func (l *Logger) Errors() string {
}
// Reset resets the logger's internal state.
func (l *Logger) Reset() {
l.ErrorCounter.Reset()
func (l *logger) Reset() {
l.logCounters.ErrorCounter.Reset()
if l.errors != nil {
l.errors.Reset()
}
}
// NewLogger creates a new Logger for the given thresholds
func NewLogger(stdoutThreshold, logThreshold jww.Threshold, outHandle, logHandle io.Writer, saveErrors bool) *Logger {
func NewLogger(stdoutThreshold, logThreshold jww.Threshold, outHandle, logHandle io.Writer, saveErrors bool) Logger {
return newLogger(stdoutThreshold, logThreshold, outHandle, logHandle, saveErrors)
}
// NewDebugLogger is a convenience function to create a debug logger.
func NewDebugLogger() *Logger {
func NewDebugLogger() Logger {
return NewBasicLogger(jww.LevelDebug)
}
// NewWarningLogger is a convenience function to create a warning logger.
func NewWarningLogger() *Logger {
func NewWarningLogger() Logger {
return NewBasicLogger(jww.LevelWarn)
}
// NewInfoLogger is a convenience function to create a info logger.
func NewInfoLogger() *Logger {
func NewInfoLogger() Logger {
return NewBasicLogger(jww.LevelInfo)
}
// NewErrorLogger is a convenience function to create an error logger.
func NewErrorLogger() *Logger {
func NewErrorLogger() Logger {
return NewBasicLogger(jww.LevelError)
}
// NewBasicLogger creates a new basic logger writing to Stdout.
func NewBasicLogger(t jww.Threshold) *Logger {
func NewBasicLogger(t jww.Threshold) Logger {
return newLogger(t, jww.LevelError, os.Stdout, ioutil.Discard, false)
}
// NewBasicLoggerForWriter creates a new basic logger writing to w.
func NewBasicLoggerForWriter(t jww.Threshold, w io.Writer) *Logger {
func NewBasicLoggerForWriter(t jww.Threshold, w io.Writer) Logger {
return newLogger(t, jww.LevelError, w, ioutil.Discard, false)
}
@@ -170,7 +261,6 @@ func (a labelColorizer) Write(p []byte) (n int, err error) {
// bytes, so we lie a little.
_, err = a.w.Write([]byte(replaced))
return len(p), err
}
// InitGlobalLogger initializes the global logger, used in some rare cases.
@@ -181,7 +271,6 @@ func InitGlobalLogger(stdoutThreshold, logThreshold jww.Threshold, outHandle, lo
jww.SetLogOutput(logHandle)
jww.SetLogThreshold(logThreshold)
jww.SetStdoutThreshold(stdoutThreshold)
}
func getLogWriters(outHandle, logHandle io.Writer) (io.Writer, io.Writer) {
@@ -196,7 +285,6 @@ func getLogWriters(outHandle, logHandle io.Writer) (io.Writer, io.Writer) {
}
return outHandle, logHandle
}
type fatalLogWriter int
@@ -219,7 +307,7 @@ var fatalLogListener = func(t jww.Threshold) io.Writer {
return new(fatalLogWriter)
}
func newLogger(stdoutThreshold, logThreshold jww.Threshold, outHandle, logHandle io.Writer, saveErrors bool) *Logger {
func newLogger(stdoutThreshold, logThreshold jww.Threshold, outHandle, logHandle io.Writer, saveErrors bool) *logger {
errorCounter := &jww.Counter{}
warnCounter := &jww.Counter{}
outHandle, logHandle = getLogWriters(outHandle, logHandle)
@@ -239,11 +327,13 @@ func newLogger(stdoutThreshold, logThreshold jww.Threshold, outHandle, logHandle
listeners = append(listeners, errorCapture)
}
return &Logger{
Notepad: jww.NewNotepad(stdoutThreshold, logThreshold, outHandle, logHandle, "", log.Ldate|log.Ltime, listeners...),
Out: outHandle,
ErrorCounter: errorCounter,
WarnCounter: warnCounter,
errors: errorBuff,
return &logger{
Notepad: jww.NewNotepad(stdoutThreshold, logThreshold, outHandle, logHandle, "", log.Ldate|log.Ltime, listeners...),
out: outHandle,
logCounters: &LogCounters{
ErrorCounter: errorCounter,
WarnCounter: warnCounter,
},
errors: errorBuff,
}
}
+4 -5
View File
@@ -26,12 +26,11 @@ func TestLogger(t *testing.T) {
c := qt.New(t)
l := NewWarningLogger()
l.ERROR.Println("One error")
l.ERROR.Println("Two error")
l.WARN.Println("A warning")
c.Assert(l.ErrorCounter.Count(), qt.Equals, uint64(2))
l.Errorln("One error")
l.Errorln("Two error")
l.Warnln("A warning")
c.Assert(l.LogCounters().ErrorCounter.Count(), qt.Equals, uint64(2))
}
func TestLoggerToWriterWithPrefix(t *testing.T) {
+78 -34
View File
@@ -14,56 +14,101 @@
package maps
import (
"fmt"
"strings"
"github.com/gobwas/glob"
"github.com/gohugoio/hugo/common/types"
"github.com/gobwas/glob"
"github.com/spf13/cast"
)
// ToLower makes all the keys in the given map lower cased and will do so
// recursively.
// Notes:
// * This will modify the map given.
// * Any nested map[interface{}]interface{} will be converted to Params.
func ToLower(m Params) {
for k, v := range m {
var retyped bool
switch v.(type) {
case map[interface{}]interface{}:
var p Params = cast.ToStringMap(v)
v = p
ToLower(p)
retyped = true
case map[string]interface{}:
var p Params = v.(map[string]interface{})
v = p
ToLower(p)
retyped = true
}
lKey := strings.ToLower(k)
if retyped || k != lKey {
delete(m, k)
m[lKey] = v
}
}
}
// ToStringMapE converts in to map[string]interface{}.
func ToStringMapE(in interface{}) (map[string]interface{}, error) {
switch in.(type) {
switch vv := in.(type) {
case Params:
return in.(Params), nil
return vv, nil
case map[string]string:
var m = map[string]interface{}{}
for k, v := range vv {
m[k] = v
}
return m, nil
default:
return cast.ToStringMapE(in)
}
}
// ToParamsAndPrepare converts in to Params and prepares it for use.
// If in is nil, an empty map is returned.
// See PrepareParams.
func ToParamsAndPrepare(in interface{}) (Params, bool) {
if types.IsNil(in) {
return Params{}, true
}
m, err := ToStringMapE(in)
if err != nil {
return nil, false
}
PrepareParams(m)
return m, true
}
// MustToParamsAndPrepare calls ToParamsAndPrepare and panics if it fails.
func MustToParamsAndPrepare(in interface{}) Params {
if p, ok := ToParamsAndPrepare(in); ok {
return p
} else {
panic(fmt.Sprintf("cannot convert %T to maps.Params", in))
}
}
// ToStringMap converts in to map[string]interface{}.
func ToStringMap(in interface{}) map[string]interface{} {
m, _ := ToStringMapE(in)
return m
}
// ToStringMapStringE converts in to map[string]string.
func ToStringMapStringE(in interface{}) (map[string]string, error) {
m, err := ToStringMapE(in)
if err != nil {
return nil, err
}
return cast.ToStringMapStringE(m)
}
// ToStringMapString converts in to map[string]string.
func ToStringMapString(in interface{}) map[string]string {
m, _ := ToStringMapStringE(in)
return m
}
// ToStringMapBool converts in to bool.
func ToStringMapBool(in interface{}) map[string]bool {
m, _ := ToStringMapE(in)
return cast.ToStringMapBool(m)
}
// ToSliceStringMap converts in to []map[string]interface{}.
func ToSliceStringMap(in interface{}) ([]map[string]interface{}, error) {
switch v := in.(type) {
case []map[string]interface{}:
return v, nil
case []interface{}:
var s []map[string]interface{}
for _, entry := range v {
if vv, ok := entry.(map[string]interface{}); ok {
s = append(s, vv)
}
}
return s, nil
default:
return nil, fmt.Errorf("unable to cast %#v of type %T to []map[string]interface{}", in, in)
}
}
type keyRename struct {
pattern glob.Glob
newKey string
@@ -109,9 +154,8 @@ func (KeyRenamer) keyPath(k1, k2 string) string {
k1, k2 = strings.ToLower(k1), strings.ToLower(k2)
if k1 == "" {
return k2
} else {
return k1 + "/" + k2
}
return k1 + "/" + k2
}
func (r KeyRenamer) renamePath(parentKeyPath string, m map[string]interface{}) {
+54 -6
View File
@@ -21,10 +21,10 @@ import (
qt "github.com/frankban/quicktest"
)
func TestToLower(t *testing.T) {
func TestPrepareParams(t *testing.T) {
tests := []struct {
input map[string]interface{}
expected map[string]interface{}
input Params
expected Params
}{
{
map[string]interface{}{
@@ -47,6 +47,9 @@ func TestToLower(t *testing.T) {
"gHi": map[string]interface{}{
"J": 25,
},
"jKl": map[string]string{
"M": "26",
},
},
Params{
"abc": 32,
@@ -60,14 +63,17 @@ func TestToLower(t *testing.T) {
"ghi": Params{
"j": 25,
},
"jkl": Params{
"m": "26",
},
},
},
}
for i, test := range tests {
t.Run(fmt.Sprint(i), func(t *testing.T) {
// ToLower modifies input.
ToLower(test.input)
// PrepareParams modifies input.
PrepareParams(test.input)
if !reflect.DeepEqual(test.expected, test.input) {
t.Errorf("[%d] Expected\n%#v, got\n%#v\n", i, test.expected, test.input)
}
@@ -75,6 +81,49 @@ func TestToLower(t *testing.T) {
}
}
func TestToSliceStringMap(t *testing.T) {
c := qt.New(t)
tests := []struct {
input interface{}
expected []map[string]interface{}
}{
{
input: []map[string]interface{}{
{"abc": 123},
},
expected: []map[string]interface{}{
{"abc": 123},
},
}, {
input: []interface{}{
map[string]interface{}{
"def": 456,
},
},
expected: []map[string]interface{}{
{"def": 456},
},
},
}
for _, test := range tests {
v, err := ToSliceStringMap(test.input)
c.Assert(err, qt.IsNil)
c.Assert(v, qt.DeepEquals, test.expected)
}
}
func TestToParamsAndPrepare(t *testing.T) {
c := qt.New(t)
_, ok := ToParamsAndPrepare(map[string]interface{}{"A": "av"})
c.Assert(ok, qt.IsTrue)
params, ok := ToParamsAndPrepare(nil)
c.Assert(ok, qt.IsTrue)
c.Assert(params, qt.DeepEquals, Params{})
}
func TestRenameKeys(t *testing.T) {
c := qt.New(t)
@@ -121,5 +170,4 @@ func TestRenameKeys(t *testing.T) {
if !reflect.DeepEqual(expected, m) {
t.Errorf("Expected\n%#v, got\n%#v\n", expected, m)
}
}
+184 -2
View File
@@ -14,6 +14,7 @@
package maps
import (
"fmt"
"strings"
"github.com/spf13/cast"
@@ -29,6 +30,118 @@ func (p Params) Get(indices ...string) interface{} {
return v
}
// Set overwrites values in p with values in pp for common or new keys.
// This is done recursively.
func (p Params) Set(pp Params) {
for k, v := range pp {
vv, found := p[k]
if !found {
p[k] = v
} else {
switch vvv := vv.(type) {
case Params:
if pv, ok := v.(Params); ok {
vvv.Set(pv)
} else {
p[k] = v
}
default:
p[k] = v
}
}
}
}
// IsZero returns true if p is considered empty.
func (p Params) IsZero() bool {
if p == nil || len(p) == 0 {
return true
}
if len(p) > 1 {
return false
}
for k, _ := range p {
return k == mergeStrategyKey
}
return false
}
// Merge transfers values from pp to p for new keys.
// This is done recursively.
func (p Params) Merge(pp Params) {
p.merge("", pp)
}
// MergeRoot transfers values from pp to p for new keys where p is the
// root of the tree.
// This is done recursively.
func (p Params) MergeRoot(pp Params) {
ms, _ := p.GetMergeStrategy()
p.merge(ms, pp)
}
func (p Params) merge(ps ParamsMergeStrategy, pp Params) {
ns, found := p.GetMergeStrategy()
var ms = ns
if !found && ps != "" {
ms = ps
}
noUpdate := ms == ParamsMergeStrategyNone
noUpdate = noUpdate || (ps != "" && ps == ParamsMergeStrategyShallow)
for k, v := range pp {
if k == mergeStrategyKey {
continue
}
vv, found := p[k]
if found {
// Key matches, if both sides are Params, we try to merge.
if vvv, ok := vv.(Params); ok {
if pv, ok := v.(Params); ok {
vvv.merge(ms, pv)
}
}
} else if !noUpdate {
p[k] = v
}
}
}
func (p Params) GetMergeStrategy() (ParamsMergeStrategy, bool) {
if v, found := p[mergeStrategyKey]; found {
if s, ok := v.(ParamsMergeStrategy); ok {
return s, true
}
}
return ParamsMergeStrategyShallow, false
}
func (p Params) DeleteMergeStrategy() bool {
if _, found := p[mergeStrategyKey]; found {
delete(p, mergeStrategyKey)
return true
}
return false
}
func (p Params) SetDefaultMergeStrategy(s ParamsMergeStrategy) {
switch s {
case ParamsMergeStrategyDeep, ParamsMergeStrategyNone, ParamsMergeStrategyShallow:
default:
panic(fmt.Sprintf("invalid merge strategy %q", s))
}
p[mergeStrategyKey] = s
}
func getNested(m map[string]interface{}, indices []string) (interface{}, string, map[string]interface{}) {
if len(indices) == 0 {
return nil, "", nil
@@ -37,7 +150,11 @@ func getNested(m map[string]interface{}, indices []string) (interface{}, string,
first := indices[0]
v, found := m[strings.ToLower(cast.ToString(first))]
if !found {
if len(indices) == 1 {
return nil, first, m
}
return nil, "", nil
}
if len(indices) == 1 {
@@ -76,11 +193,10 @@ func GetNestedParam(keyStr, separator string, candidates ...Params) (interface{}
}
return nil, nil
}
func GetNestedParamFn(keyStr, separator string, lookupFn func(key string) interface{}) (interface{}, string, map[string]interface{}, error) {
keySegments := strings.Split(strings.ToLower(keyStr), separator)
keySegments := strings.Split(keyStr, separator)
if len(keySegments) == 0 {
return nil, "", nil, nil
}
@@ -105,3 +221,69 @@ func GetNestedParamFn(keyStr, separator string, lookupFn func(key string) interf
return nil, "", nil, nil
}
// ParamsMergeStrategy tells what strategy to use in Params.Merge.
type ParamsMergeStrategy string
const (
// Do not merge.
ParamsMergeStrategyNone ParamsMergeStrategy = "none"
// Only add new keys.
ParamsMergeStrategyShallow ParamsMergeStrategy = "shallow"
// Add new keys, merge existing.
ParamsMergeStrategyDeep ParamsMergeStrategy = "deep"
mergeStrategyKey = "_merge"
)
func toMergeStrategy(v interface{}) ParamsMergeStrategy {
s := ParamsMergeStrategy(cast.ToString(v))
switch s {
case ParamsMergeStrategyDeep, ParamsMergeStrategyNone, ParamsMergeStrategyShallow:
return s
default:
return ParamsMergeStrategyDeep
}
}
// PrepareParams
// * makes all the keys in the given map lower cased and will do so
// * This will modify the map given.
// * Any nested map[interface{}]interface{}, map[string]interface{},map[string]string will be converted to Params.
// * Any _merge value will be converted to proper type and value.
func PrepareParams(m Params) {
for k, v := range m {
var retyped bool
lKey := strings.ToLower(k)
if lKey == mergeStrategyKey {
v = toMergeStrategy(v)
retyped = true
} else {
switch vv := v.(type) {
case map[interface{}]interface{}:
var p Params = cast.ToStringMap(v)
v = p
PrepareParams(p)
retyped = true
case map[string]interface{}:
var p Params = v.(map[string]interface{})
v = p
PrepareParams(p)
retyped = true
case map[string]string:
p := make(Params)
for k, v := range vv {
p[k] = v
}
v = p
PrepareParams(p)
retyped = true
}
}
if retyped || k != lKey {
delete(m, k)
m[lKey] = v
}
}
}
+120 -1
View File
@@ -20,7 +20,6 @@ import (
)
func TestGetNestedParam(t *testing.T) {
m := map[string]interface{}{
"string": "value",
"first": 1,
@@ -47,5 +46,125 @@ func TestGetNestedParam(t *testing.T) {
c.Assert(must("nested_color", "_", m), qt.Equals, "blue")
c.Assert(must("nested.nestednested.color", ".", m), qt.Equals, "green")
c.Assert(must("string.name", ".", m), qt.IsNil)
c.Assert(must("nested.foo", ".", m), qt.IsNil)
}
// https://github.com/gohugoio/hugo/issues/7903
func TestGetNestedParamFnNestedNewKey(t *testing.T) {
c := qt.New(t)
nested := map[string]interface{}{
"color": "blue",
}
m := map[string]interface{}{
"nested": nested,
}
existing, nestedKey, owner, err := GetNestedParamFn("nested.new", ".", func(key string) interface{} {
return m[key]
})
c.Assert(err, qt.IsNil)
c.Assert(existing, qt.IsNil)
c.Assert(nestedKey, qt.Equals, "new")
c.Assert(owner, qt.DeepEquals, nested)
}
func TestParamsSetAndMerge(t *testing.T) {
c := qt.New(t)
createParamsPair := func() (Params, Params) {
p1 := Params{"a": "av", "c": "cv", "nested": Params{"al2": "al2v", "cl2": "cl2v"}}
p2 := Params{"b": "bv", "a": "abv", "nested": Params{"bl2": "bl2v", "al2": "al2bv"}, mergeStrategyKey: ParamsMergeStrategyDeep}
return p1, p2
}
p1, p2 := createParamsPair()
p1.Set(p2)
c.Assert(p1, qt.DeepEquals, Params{
"a": "abv",
"c": "cv",
"nested": Params{
"al2": "al2bv",
"cl2": "cl2v",
"bl2": "bl2v",
},
"b": "bv",
mergeStrategyKey: ParamsMergeStrategyDeep,
})
p1, p2 = createParamsPair()
p1.Merge(p2)
// Default is to do a shallow merge.
c.Assert(p1, qt.DeepEquals, Params{
"c": "cv",
"nested": Params{
"al2": "al2v",
"cl2": "cl2v",
},
"b": "bv",
"a": "av",
})
p1, p2 = createParamsPair()
p1.SetDefaultMergeStrategy(ParamsMergeStrategyNone)
p1.Merge(p2)
p1.DeleteMergeStrategy()
c.Assert(p1, qt.DeepEquals, Params{
"a": "av",
"c": "cv",
"nested": Params{
"al2": "al2v",
"cl2": "cl2v",
},
})
p1, p2 = createParamsPair()
p1.SetDefaultMergeStrategy(ParamsMergeStrategyShallow)
p1.Merge(p2)
p1.DeleteMergeStrategy()
c.Assert(p1, qt.DeepEquals, Params{
"a": "av",
"c": "cv",
"nested": Params{
"al2": "al2v",
"cl2": "cl2v",
},
"b": "bv",
})
p1, p2 = createParamsPair()
p1.SetDefaultMergeStrategy(ParamsMergeStrategyDeep)
p1.Merge(p2)
p1.DeleteMergeStrategy()
c.Assert(p1, qt.DeepEquals, Params{
"nested": Params{
"al2": "al2v",
"cl2": "cl2v",
"bl2": "bl2v",
},
"b": "bv",
"a": "av",
"c": "cv",
})
}
func TestParamsIsZero(t *testing.T) {
c := qt.New(t)
var nilParams Params
c.Assert(Params{}.IsZero(), qt.IsTrue)
c.Assert(nilParams.IsZero(), qt.IsTrue)
c.Assert(Params{"foo": "bar"}.IsZero(), qt.IsFalse)
c.Assert(Params{"_merge": "foo", "foo": "bar"}.IsZero(), qt.IsFalse)
c.Assert(Params{"_merge": "foo"}.IsZero(), qt.IsTrue)
}
+11 -1
View File
@@ -51,7 +51,6 @@ func NewScratcher() Scratcher {
//
// If the first add for a key is an array or slice, then the next value(s) will be appended.
func (c *Scratch) Add(key string, newAddend interface{}) (string, error) {
var newVal interface{}
c.mu.RLock()
existingAddend, found := c.values[key]
@@ -130,6 +129,17 @@ func (c *Scratch) SetInMap(key string, mapKey string, value interface{}) string
return ""
}
// DeleteInMap deletes a value to a map with the given key in the Node context.
func (c *Scratch) DeleteInMap(key string, mapKey string) string {
c.mu.Lock()
_, found := c.values[key]
if found {
delete(c.values[key].(map[string]interface{}), mapKey)
}
c.mu.Unlock()
return ""
}
// GetSortedMapValues returns a sorted map previously filled with SetInMap.
func (c *Scratch) GetSortedMapValues(key string) interface{} {
c.mu.RLock()
+14 -3
View File
@@ -53,7 +53,6 @@ func TestScratchAdd(t *testing.T) {
if err == nil {
t.Errorf("Expected error from invalid arithmetic")
}
}
func TestScratchAddSlice(t *testing.T) {
@@ -96,7 +95,6 @@ func TestScratchAddTypedSliceToInterfaceSlice(t *testing.T) {
_, err := scratch.Add("slice", []int{1, 2})
c.Assert(err, qt.IsNil)
c.Assert(scratch.Get("slice"), qt.DeepEquals, []int{1, 2})
}
// https://github.com/gohugoio/hugo/issues/5361
@@ -110,7 +108,6 @@ func TestScratchAddDifferentTypedSliceToInterfaceSlice(t *testing.T) {
_, err := scratch.Add("slice", []int{1, 2})
c.Assert(err, qt.IsNil)
c.Assert(scratch.Get("slice"), qt.DeepEquals, []interface{}{"foo", 1, 2})
}
func TestScratchSet(t *testing.T) {
@@ -191,6 +188,20 @@ func TestScratchSetInMap(t *testing.T) {
c.Assert(scratch.GetSortedMapValues("key"), qt.DeepEquals, []interface{}{0: "Abc (updated)", 1: "Def", 2: "Lux", 3: "Zyx"})
}
func TestScratchDeleteInMap(t *testing.T) {
t.Parallel()
c := qt.New(t)
scratch := NewScratch()
scratch.SetInMap("key", "lux", "Lux")
scratch.SetInMap("key", "abc", "Abc")
scratch.SetInMap("key", "zyx", "Zyx")
scratch.DeleteInMap("key", "abc")
scratch.SetInMap("key", "def", "Def")
scratch.DeleteInMap("key", "lmn") // Do nothing
c.Assert(scratch.GetSortedMapValues("key"), qt.DeepEquals, []interface{}{0: "Def", 1: "Lux", 2: "Zyx"})
}
func TestScratchGetSortedMapValues(t *testing.T) {
t.Parallel()
scratch := NewScratch()
+9 -4
View File
@@ -16,13 +16,14 @@ package para
import (
"context"
"runtime"
"sort"
"sync"
"sync/atomic"
"testing"
"time"
"github.com/gohugoio/hugo/htesting"
qt "github.com/frankban/quicktest"
)
@@ -31,6 +32,10 @@ func TestPara(t *testing.T) {
t.Skipf("skip para test, CPU count is %d", runtime.NumCPU())
}
if !htesting.IsCI() {
t.Skip("skip para test when not running on CI")
}
c := qt.New(t)
c.Run("Order", func(c *qt.C) {
@@ -60,7 +65,6 @@ func TestPara(t *testing.T) {
c.Assert(sort.IntsAreSorted(result), qt.Equals, false, qt.Commentf("Para does not seem to be parallel"))
sort.Ints(result)
c.Assert(result, qt.DeepEquals, ints)
})
c.Run("Time", func(c *qt.C) {
@@ -83,8 +87,9 @@ func TestPara(t *testing.T) {
c.Assert(r.Wait(), qt.IsNil)
c.Assert(counter, qt.Equals, int64(n))
c.Assert(time.Since(start) < n/2*time.Millisecond, qt.Equals, true)
since := time.Since(start)
limit := n / 2 * time.Millisecond
c.Assert(since < limit, qt.Equals, true, qt.Commentf("%s >= %s", since, limit))
})
}
+312
View File
@@ -0,0 +1,312 @@
// Copyright 2021 The Hugo Authors. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package paths
import (
"errors"
"fmt"
"os"
"path"
"path/filepath"
"regexp"
"strings"
)
// FilePathSeparator as defined by os.Separator.
const FilePathSeparator = string(filepath.Separator)
// filepathPathBridge is a bridge for common functionality in filepath vs path
type filepathPathBridge interface {
Base(in string) string
Clean(in string) string
Dir(in string) string
Ext(in string) string
Join(elem ...string) string
Separator() string
}
type filepathBridge struct {
}
func (filepathBridge) Base(in string) string {
return filepath.Base(in)
}
func (filepathBridge) Clean(in string) string {
return filepath.Clean(in)
}
func (filepathBridge) Dir(in string) string {
return filepath.Dir(in)
}
func (filepathBridge) Ext(in string) string {
return filepath.Ext(in)
}
func (filepathBridge) Join(elem ...string) string {
return filepath.Join(elem...)
}
func (filepathBridge) Separator() string {
return FilePathSeparator
}
var fpb filepathBridge
// ToSlashTrimLeading is just a filepath.ToSlash with an added / prefix trimmer.
func ToSlashTrimLeading(s string) string {
return strings.TrimPrefix(filepath.ToSlash(s), "/")
}
// MakeTitle converts the path given to a suitable title, trimming whitespace
// and replacing hyphens with whitespace.
func MakeTitle(inpath string) string {
return strings.Replace(strings.TrimSpace(inpath), "-", " ", -1)
}
// ReplaceExtension takes a path and an extension, strips the old extension
// and returns the path with the new extension.
func ReplaceExtension(path string, newExt string) string {
f, _ := fileAndExt(path, fpb)
return f + "." + newExt
}
func makePathRelative(inPath string, possibleDirectories ...string) (string, error) {
for _, currentPath := range possibleDirectories {
if strings.HasPrefix(inPath, currentPath) {
return strings.TrimPrefix(inPath, currentPath), nil
}
}
return inPath, errors.New("can't extract relative path, unknown prefix")
}
// Should be good enough for Hugo.
var isFileRe = regexp.MustCompile(`.*\..{1,6}$`)
// GetDottedRelativePath expects a relative path starting after the content directory.
// It returns a relative path with dots ("..") navigating up the path structure.
func GetDottedRelativePath(inPath string) string {
inPath = filepath.Clean(filepath.FromSlash(inPath))
if inPath == "." {
return "./"
}
if !isFileRe.MatchString(inPath) && !strings.HasSuffix(inPath, FilePathSeparator) {
inPath += FilePathSeparator
}
if !strings.HasPrefix(inPath, FilePathSeparator) {
inPath = FilePathSeparator + inPath
}
dir, _ := filepath.Split(inPath)
sectionCount := strings.Count(dir, FilePathSeparator)
if sectionCount == 0 || dir == FilePathSeparator {
return "./"
}
var dottedPath string
for i := 1; i < sectionCount; i++ {
dottedPath += "../"
}
return dottedPath
}
// ExtNoDelimiter takes a path and returns the extension, excluding the delimiter, i.e. "md".
func ExtNoDelimiter(in string) string {
return strings.TrimPrefix(Ext(in), ".")
}
// Ext takes a path and returns the extension, including the delimiter, i.e. ".md".
func Ext(in string) string {
_, ext := fileAndExt(in, fpb)
return ext
}
// PathAndExt is the same as FileAndExt, but it uses the path package.
func PathAndExt(in string) (string, string) {
return fileAndExt(in, pb)
}
// FileAndExt takes a path and returns the file and extension separated,
// the extension including the delimiter, i.e. ".md".
func FileAndExt(in string) (string, string) {
return fileAndExt(in, fpb)
}
// FileAndExtNoDelimiter takes a path and returns the file and extension separated,
// the extension excluding the delimiter, e.g "md".
func FileAndExtNoDelimiter(in string) (string, string) {
file, ext := fileAndExt(in, fpb)
return file, strings.TrimPrefix(ext, ".")
}
// Filename takes a file path, strips out the extension,
// and returns the name of the file.
func Filename(in string) (name string) {
name, _ = fileAndExt(in, fpb)
return
}
// PathNoExt takes a path, strips out the extension,
// and returns the name of the file.
func PathNoExt(in string) string {
return strings.TrimSuffix(in, path.Ext(in))
}
// FileAndExt returns the filename and any extension of a file path as
// two separate strings.
//
// If the path, in, contains a directory name ending in a slash,
// then both name and ext will be empty strings.
//
// If the path, in, is either the current directory, the parent
// directory or the root directory, or an empty string,
// then both name and ext will be empty strings.
//
// If the path, in, represents the path of a file without an extension,
// then name will be the name of the file and ext will be an empty string.
//
// If the path, in, represents a filename with an extension,
// then name will be the filename minus any extension - including the dot
// and ext will contain the extension - minus the dot.
func fileAndExt(in string, b filepathPathBridge) (name string, ext string) {
ext = b.Ext(in)
base := b.Base(in)
return extractFilename(in, ext, base, b.Separator()), ext
}
func extractFilename(in, ext, base, pathSeparator string) (name string) {
// No file name cases. These are defined as:
// 1. any "in" path that ends in a pathSeparator
// 2. any "base" consisting of just an pathSeparator
// 3. any "base" consisting of just an empty string
// 4. any "base" consisting of just the current directory i.e. "."
// 5. any "base" consisting of just the parent directory i.e. ".."
if (strings.LastIndex(in, pathSeparator) == len(in)-1) || base == "" || base == "." || base == ".." || base == pathSeparator {
name = "" // there is NO filename
} else if ext != "" { // there was an Extension
// return the filename minus the extension (and the ".")
name = base[:strings.LastIndex(base, ".")]
} else {
// no extension case so just return base, which willi
// be the filename
name = base
}
return
}
// GetRelativePath returns the relative path of a given path.
func GetRelativePath(path, base string) (final string, err error) {
if filepath.IsAbs(path) && base == "" {
return "", errors.New("source: missing base directory")
}
name := filepath.Clean(path)
base = filepath.Clean(base)
name, err = filepath.Rel(base, name)
if err != nil {
return "", err
}
if strings.HasSuffix(filepath.FromSlash(path), FilePathSeparator) && !strings.HasSuffix(name, FilePathSeparator) {
name += FilePathSeparator
}
return name, nil
}
// PathPrep prepares the path using the uglify setting to create paths on
// either the form /section/name/index.html or /section/name.html.
func PathPrep(ugly bool, in string) string {
if ugly {
return Uglify(in)
}
return PrettifyPath(in)
}
// PrettifyPath is the same as PrettifyURLPath but for file paths.
// /section/name.html becomes /section/name/index.html
// /section/name/ becomes /section/name/index.html
// /section/name/index.html becomes /section/name/index.html
func PrettifyPath(in string) string {
return prettifyPath(in, fpb)
}
func prettifyPath(in string, b filepathPathBridge) string {
if filepath.Ext(in) == "" {
// /section/name/ -> /section/name/index.html
if len(in) < 2 {
return b.Separator()
}
return b.Join(in, "index.html")
}
name, ext := fileAndExt(in, b)
if name == "index" {
// /section/name/index.html -> /section/name/index.html
return b.Clean(in)
}
// /section/name.html -> /section/name/index.html
return b.Join(b.Dir(in), name, "index"+ext)
}
type NamedSlice struct {
Name string
Slice []string
}
func (n NamedSlice) String() string {
if len(n.Slice) == 0 {
return n.Name
}
return fmt.Sprintf("%s%s{%s}", n.Name, FilePathSeparator, strings.Join(n.Slice, ","))
}
// FindCWD returns the current working directory from where the Hugo
// executable is run.
func FindCWD() (string, error) {
serverFile, err := filepath.Abs(os.Args[0])
if err != nil {
return "", fmt.Errorf("can't get absolute path for executable: %v", err)
}
path := filepath.Dir(serverFile)
realFile, err := filepath.EvalSymlinks(serverFile)
if err != nil {
if _, err = os.Stat(serverFile + ".exe"); err == nil {
realFile = filepath.Clean(serverFile + ".exe")
}
}
if err == nil && realFile != serverFile {
path = filepath.Dir(realFile)
}
return path, nil
}
// AddTrailingSlash adds a trailing Unix styled slash (/) if not already
// there.
func AddTrailingSlash(path string) string {
if !strings.HasSuffix(path, "/") {
path += "/"
}
return path
}
+252
View File
@@ -0,0 +1,252 @@
// Copyright 2021 The Hugo Authors. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package paths
import (
"path/filepath"
"testing"
qt "github.com/frankban/quicktest"
)
func TestGetRelativePath(t *testing.T) {
tests := []struct {
path string
base string
expect interface{}
}{
{filepath.FromSlash("/a/b"), filepath.FromSlash("/a"), filepath.FromSlash("b")},
{filepath.FromSlash("/a/b/c/"), filepath.FromSlash("/a"), filepath.FromSlash("b/c/")},
{filepath.FromSlash("/c"), filepath.FromSlash("/a/b"), filepath.FromSlash("../../c")},
{filepath.FromSlash("/c"), "", false},
}
for i, this := range tests {
// ultimately a fancy wrapper around filepath.Rel
result, err := GetRelativePath(this.path, this.base)
if b, ok := this.expect.(bool); ok && !b {
if err == nil {
t.Errorf("[%d] GetRelativePath didn't return an expected error", i)
}
} else {
if err != nil {
t.Errorf("[%d] GetRelativePath failed: %s", i, err)
continue
}
if result != this.expect {
t.Errorf("[%d] GetRelativePath got %v but expected %v", i, result, this.expect)
}
}
}
}
func TestMakePathRelative(t *testing.T) {
type test struct {
inPath, path1, path2, output string
}
data := []test{
{"/abc/bcd/ab.css", "/abc/bcd", "/bbc/bcd", "/ab.css"},
{"/abc/bcd/ab.css", "/abcd/bcd", "/abc/bcd", "/ab.css"},
}
for i, d := range data {
output, _ := makePathRelative(d.inPath, d.path1, d.path2)
if d.output != output {
t.Errorf("Test #%d failed. Expected %q got %q", i, d.output, output)
}
}
_, error := makePathRelative("a/b/c.ss", "/a/c", "/d/c", "/e/f")
if error == nil {
t.Errorf("Test failed, expected error")
}
}
func TestGetDottedRelativePath(t *testing.T) {
// on Windows this will receive both kinds, both country and western ...
for _, f := range []func(string) string{filepath.FromSlash, func(s string) string { return s }} {
doTestGetDottedRelativePath(f, t)
}
}
func doTestGetDottedRelativePath(urlFixer func(string) string, t *testing.T) {
type test struct {
input, expected string
}
data := []test{
{"", "./"},
{urlFixer("/"), "./"},
{urlFixer("post"), "../"},
{urlFixer("/post"), "../"},
{urlFixer("post/"), "../"},
{urlFixer("tags/foo.html"), "../"},
{urlFixer("/tags/foo.html"), "../"},
{urlFixer("/post/"), "../"},
{urlFixer("////post/////"), "../"},
{urlFixer("/foo/bar/index.html"), "../../"},
{urlFixer("/foo/bar/foo/"), "../../../"},
{urlFixer("/foo/bar/foo"), "../../../"},
{urlFixer("foo/bar/foo/"), "../../../"},
{urlFixer("foo/bar/foo/bar"), "../../../../"},
{"404.html", "./"},
{"404.xml", "./"},
{"/404.html", "./"},
}
for i, d := range data {
output := GetDottedRelativePath(d.input)
if d.expected != output {
t.Errorf("Test %d failed. Expected %q got %q", i, d.expected, output)
}
}
}
func TestMakeTitle(t *testing.T) {
type test struct {
input, expected string
}
data := []test{
{"Make-Title", "Make Title"},
{"MakeTitle", "MakeTitle"},
{"make_title", "make_title"},
}
for i, d := range data {
output := MakeTitle(d.input)
if d.expected != output {
t.Errorf("Test %d failed. Expected %q got %q", i, d.expected, output)
}
}
}
// Replace Extension is probably poorly named, but the intent of the
// function is to accept a path and return only the file name with a
// new extension. It's intentionally designed to strip out the path
// and only provide the name. We should probably rename the function to
// be more explicit at some point.
func TestReplaceExtension(t *testing.T) {
type test struct {
input, newext, expected string
}
data := []test{
// These work according to the above definition
{"/some/random/path/file.xml", "html", "file.html"},
{"/banana.html", "xml", "banana.xml"},
{"./banana.html", "xml", "banana.xml"},
{"banana/pie/index.html", "xml", "index.xml"},
{"../pies/fish/index.html", "xml", "index.xml"},
// but these all fail
{"filename-without-an-ext", "ext", "filename-without-an-ext.ext"},
{"/filename-without-an-ext", "ext", "filename-without-an-ext.ext"},
{"/directory/mydir/", "ext", ".ext"},
{"mydir/", "ext", ".ext"},
}
for i, d := range data {
output := ReplaceExtension(filepath.FromSlash(d.input), d.newext)
if d.expected != output {
t.Errorf("Test %d failed. Expected %q got %q", i, d.expected, output)
}
}
}
func TestExtNoDelimiter(t *testing.T) {
c := qt.New(t)
c.Assert(ExtNoDelimiter(filepath.FromSlash("/my/data.json")), qt.Equals, "json")
}
func TestFilename(t *testing.T) {
type test struct {
input, expected string
}
data := []test{
{"index.html", "index"},
{"./index.html", "index"},
{"/index.html", "index"},
{"index", "index"},
{"/tmp/index.html", "index"},
{"./filename-no-ext", "filename-no-ext"},
{"/filename-no-ext", "filename-no-ext"},
{"filename-no-ext", "filename-no-ext"},
{"directory/", ""}, // no filename case??
{"directory/.hidden.ext", ".hidden"},
{"./directory/../~/banana/gold.fish", "gold"},
{"../directory/banana.man", "banana"},
{"~/mydir/filename.ext", "filename"},
{"./directory//tmp/filename.ext", "filename"},
}
for i, d := range data {
output := Filename(filepath.FromSlash(d.input))
if d.expected != output {
t.Errorf("Test %d failed. Expected %q got %q", i, d.expected, output)
}
}
}
func TestFileAndExt(t *testing.T) {
type test struct {
input, expectedFile, expectedExt string
}
data := []test{
{"index.html", "index", ".html"},
{"./index.html", "index", ".html"},
{"/index.html", "index", ".html"},
{"index", "index", ""},
{"/tmp/index.html", "index", ".html"},
{"./filename-no-ext", "filename-no-ext", ""},
{"/filename-no-ext", "filename-no-ext", ""},
{"filename-no-ext", "filename-no-ext", ""},
{"directory/", "", ""}, // no filename case??
{"directory/.hidden.ext", ".hidden", ".ext"},
{"./directory/../~/banana/gold.fish", "gold", ".fish"},
{"../directory/banana.man", "banana", ".man"},
{"~/mydir/filename.ext", "filename", ".ext"},
{"./directory//tmp/filename.ext", "filename", ".ext"},
}
for i, d := range data {
file, ext := fileAndExt(filepath.FromSlash(d.input), fpb)
if d.expectedFile != file {
t.Errorf("Test %d failed. Expected filename %q got %q.", i, d.expectedFile, file)
}
if d.expectedExt != ext {
t.Errorf("Test %d failed. Expected extension %q got %q.", i, d.expectedExt, ext)
}
}
}
func TestFindCWD(t *testing.T) {
type test struct {
expectedDir string
expectedErr error
}
// cwd, _ := os.Getwd()
data := []test{
//{cwd, nil},
// Commenting this out. It doesn't work properly.
// There's a good reason why we don't use os.Getwd(), it doesn't actually work the way we want it to.
// I really don't know a better way to test this function. - SPF 2014.11.04
}
for i, d := range data {
dir, err := FindCWD()
if d.expectedDir != dir {
t.Errorf("Test %d failed. Expected %q but got %q", i, d.expectedDir, dir)
}
if d.expectedErr != err {
t.Errorf("Test %d failed. Expected %q but got %q", i, d.expectedErr, err)
}
}
}
+212
View File
@@ -0,0 +1,212 @@
// Copyright 2021 The Hugo Authors. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package paths
import (
"fmt"
"net/url"
"path"
"strings"
"github.com/PuerkitoBio/purell"
)
type pathBridge struct {
}
func (pathBridge) Base(in string) string {
return path.Base(in)
}
func (pathBridge) Clean(in string) string {
return path.Clean(in)
}
func (pathBridge) Dir(in string) string {
return path.Dir(in)
}
func (pathBridge) Ext(in string) string {
return path.Ext(in)
}
func (pathBridge) Join(elem ...string) string {
return path.Join(elem...)
}
func (pathBridge) Separator() string {
return "/"
}
var pb pathBridge
func sanitizeURLWithFlags(in string, f purell.NormalizationFlags) string {
s, err := purell.NormalizeURLString(in, f)
if err != nil {
return in
}
// Temporary workaround for the bug fix and resulting
// behavioral change in purell.NormalizeURLString():
// a leading '/' was inadvertently added to relative links,
// but no longer, see #878.
//
// I think the real solution is to allow Hugo to
// make relative URL with relative path,
// e.g. "../../post/hello-again/", as wished by users
// in issues #157, #622, etc., without forcing
// relative URLs to begin with '/'.
// Once the fixes are in, let's remove this kludge
// and restore SanitizeURL() to the way it was.
// -- @anthonyfok, 2015-02-16
//
// Begin temporary kludge
u, err := url.Parse(s)
if err != nil {
panic(err)
}
if len(u.Path) > 0 && !strings.HasPrefix(u.Path, "/") {
u.Path = "/" + u.Path
}
return u.String()
// End temporary kludge
// return s
}
// SanitizeURL sanitizes the input URL string.
func SanitizeURL(in string) string {
return sanitizeURLWithFlags(in, purell.FlagsSafe|purell.FlagRemoveTrailingSlash|purell.FlagRemoveDotSegments|purell.FlagRemoveDuplicateSlashes|purell.FlagRemoveUnnecessaryHostDots|purell.FlagRemoveEmptyPortSeparator)
}
// SanitizeURLKeepTrailingSlash is the same as SanitizeURL, but will keep any trailing slash.
func SanitizeURLKeepTrailingSlash(in string) string {
return sanitizeURLWithFlags(in, purell.FlagsSafe|purell.FlagRemoveDotSegments|purell.FlagRemoveDuplicateSlashes|purell.FlagRemoveUnnecessaryHostDots|purell.FlagRemoveEmptyPortSeparator)
}
// MakePermalink combines base URL with content path to create full URL paths.
// Example
// base: http://spf13.com/
// path: post/how-i-blog
// result: http://spf13.com/post/how-i-blog
func MakePermalink(host, plink string) *url.URL {
base, err := url.Parse(host)
if err != nil {
panic(err)
}
p, err := url.Parse(plink)
if err != nil {
panic(err)
}
if p.Host != "" {
panic(fmt.Errorf("can't make permalink from absolute link %q", plink))
}
base.Path = path.Join(base.Path, p.Path)
// path.Join will strip off the last /, so put it back if it was there.
hadTrailingSlash := (plink == "" && strings.HasSuffix(host, "/")) || strings.HasSuffix(p.Path, "/")
if hadTrailingSlash && !strings.HasSuffix(base.Path, "/") {
base.Path = base.Path + "/"
}
return base
}
// IsAbsURL determines whether the given path points to an absolute URL.
func IsAbsURL(path string) bool {
url, err := url.Parse(path)
if err != nil {
return false
}
return url.IsAbs() || strings.HasPrefix(path, "//")
}
// AddContextRoot adds the context root to an URL if it's not already set.
// For relative URL entries on sites with a base url with a context root set (i.e. http://example.com/mysite),
// relative URLs must not include the context root if canonifyURLs is enabled. But if it's disabled, it must be set.
func AddContextRoot(baseURL, relativePath string) string {
url, err := url.Parse(baseURL)
if err != nil {
panic(err)
}
newPath := path.Join(url.Path, relativePath)
// path strips trailing slash, ignore root path.
if newPath != "/" && strings.HasSuffix(relativePath, "/") {
newPath += "/"
}
return newPath
}
// URLizeAn
// PrettifyURL takes a URL string and returns a semantic, clean URL.
func PrettifyURL(in string) string {
x := PrettifyURLPath(in)
if path.Base(x) == "index.html" {
return path.Dir(x)
}
if in == "" {
return "/"
}
return x
}
// PrettifyURLPath takes a URL path to a content and converts it
// to enable pretty URLs.
// /section/name.html becomes /section/name/index.html
// /section/name/ becomes /section/name/index.html
// /section/name/index.html becomes /section/name/index.html
func PrettifyURLPath(in string) string {
return prettifyPath(in, pb)
}
// Uglify does the opposite of PrettifyURLPath().
// /section/name/index.html becomes /section/name.html
// /section/name/ becomes /section/name.html
// /section/name.html becomes /section/name.html
func Uglify(in string) string {
if path.Ext(in) == "" {
if len(in) < 2 {
return "/"
}
// /section/name/ -> /section/name.html
return path.Clean(in) + ".html"
}
name, ext := fileAndExt(in, pb)
if name == "index" {
// /section/name/index.html -> /section/name.html
d := path.Dir(in)
if len(d) > 1 {
return d + ext
}
return in
}
// /.xml -> /index.xml
if name == "" {
return path.Dir(in) + "index" + ext
}
// /section/name.html -> /section/name.html
return path.Clean(in)
}
+129
View File
@@ -0,0 +1,129 @@
// Copyright 2021 The Hugo Authors. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package paths
import (
"strings"
"testing"
qt "github.com/frankban/quicktest"
)
func TestSanitizeURL(t *testing.T) {
tests := []struct {
input string
expected string
}{
{"http://foo.bar/", "http://foo.bar"},
{"http://foo.bar", "http://foo.bar"}, // issue #1105
{"http://foo.bar/zoo/", "http://foo.bar/zoo"}, // issue #931
}
for i, test := range tests {
o1 := SanitizeURL(test.input)
o2 := SanitizeURLKeepTrailingSlash(test.input)
expected2 := test.expected
if strings.HasSuffix(test.input, "/") && !strings.HasSuffix(expected2, "/") {
expected2 += "/"
}
if o1 != test.expected {
t.Errorf("[%d] 1: Expected %#v, got %#v\n", i, test.expected, o1)
}
if o2 != expected2 {
t.Errorf("[%d] 2: Expected %#v, got %#v\n", i, expected2, o2)
}
}
}
func TestMakePermalink(t *testing.T) {
type test struct {
host, link, output string
}
data := []test{
{"http://abc.com/foo", "post/bar", "http://abc.com/foo/post/bar"},
{"http://abc.com/foo/", "post/bar", "http://abc.com/foo/post/bar"},
{"http://abc.com", "post/bar", "http://abc.com/post/bar"},
{"http://abc.com", "bar", "http://abc.com/bar"},
{"http://abc.com/foo/bar", "post/bar", "http://abc.com/foo/bar/post/bar"},
{"http://abc.com/foo/bar", "post/bar/", "http://abc.com/foo/bar/post/bar/"},
}
for i, d := range data {
output := MakePermalink(d.host, d.link).String()
if d.output != output {
t.Errorf("Test #%d failed. Expected %q got %q", i, d.output, output)
}
}
}
func TestAddContextRoot(t *testing.T) {
tests := []struct {
baseURL string
url string
expected string
}{
{"http://example.com/sub/", "/foo", "/sub/foo"},
{"http://example.com/sub/", "/foo/index.html", "/sub/foo/index.html"},
{"http://example.com/sub1/sub2", "/foo", "/sub1/sub2/foo"},
{"http://example.com", "/foo", "/foo"},
// cannot guess that the context root is already added int the example below
{"http://example.com/sub/", "/sub/foo", "/sub/sub/foo"},
{"http://example.com/тря", "/трям/", "/тря/трям/"},
{"http://example.com", "/", "/"},
{"http://example.com/bar", "//", "/bar/"},
}
for _, test := range tests {
output := AddContextRoot(test.baseURL, test.url)
if output != test.expected {
t.Errorf("Expected %#v, got %#v\n", test.expected, output)
}
}
}
func TestPretty(t *testing.T) {
c := qt.New(t)
c.Assert("/section/name/index.html", qt.Equals, PrettifyURLPath("/section/name.html"))
c.Assert("/section/sub/name/index.html", qt.Equals, PrettifyURLPath("/section/sub/name.html"))
c.Assert("/section/name/index.html", qt.Equals, PrettifyURLPath("/section/name/"))
c.Assert("/section/name/index.html", qt.Equals, PrettifyURLPath("/section/name/index.html"))
c.Assert("/index.html", qt.Equals, PrettifyURLPath("/index.html"))
c.Assert("/name/index.xml", qt.Equals, PrettifyURLPath("/name.xml"))
c.Assert("/", qt.Equals, PrettifyURLPath("/"))
c.Assert("/", qt.Equals, PrettifyURLPath(""))
c.Assert("/section/name", qt.Equals, PrettifyURL("/section/name.html"))
c.Assert("/section/sub/name", qt.Equals, PrettifyURL("/section/sub/name.html"))
c.Assert("/section/name", qt.Equals, PrettifyURL("/section/name/"))
c.Assert("/section/name", qt.Equals, PrettifyURL("/section/name/index.html"))
c.Assert("/", qt.Equals, PrettifyURL("/index.html"))
c.Assert("/name/index.xml", qt.Equals, PrettifyURL("/name.xml"))
c.Assert("/", qt.Equals, PrettifyURL("/"))
c.Assert("/", qt.Equals, PrettifyURL(""))
}
func TestUgly(t *testing.T) {
c := qt.New(t)
c.Assert("/section/name.html", qt.Equals, Uglify("/section/name.html"))
c.Assert("/section/sub/name.html", qt.Equals, Uglify("/section/sub/name.html"))
c.Assert("/section/name.html", qt.Equals, Uglify("/section/name/"))
c.Assert("/section/name.html", qt.Equals, Uglify("/section/name/index.html"))
c.Assert("/index.html", qt.Equals, Uglify("/index.html"))
c.Assert("/name.xml", qt.Equals, Uglify("/name.xml"))
c.Assert("/", qt.Equals, Uglify("/"))
c.Assert("/", qt.Equals, Uglify(""))
}
+1 -2
View File
@@ -50,12 +50,11 @@ func (pos Position) IsValid() bool {
var positionStringFormatfunc func(p Position) string
func createPositionStringFormatter(formatStr string) func(p Position) string {
if formatStr == "" {
formatStr = "\":file::line::col\""
}
var identifiers = []string{":file", ":line", ":col"}
identifiers := []string{":file", ":line", ":col"}
var identifiersFound []string
for i := range formatStr {
-1
View File
@@ -29,5 +29,4 @@ func TestPositionStringFormatter(t *testing.T) {
c.Assert(createPositionStringFormatter("好::col")(pos), qt.Equals, "好:13")
c.Assert(createPositionStringFormatter("")(pos), qt.Equals, "\"/my/file.txt:12:13\"")
c.Assert(pos.String(), qt.Equals, "\"/my/file.txt:12:13\"")
}
-1
View File
@@ -25,5 +25,4 @@ func TestRemoveAccents(t *testing.T) {
c.Assert(string(RemoveAccents([]byte("Resumé"))), qt.Equals, "Resume")
c.Assert(string(RemoveAccents([]byte("Hugo Rocks!"))), qt.Equals, "Hugo Rocks!")
c.Assert(string(RemoveAccentsString("Resumé")), qt.Equals, "Resume")
}
+56 -5
View File
@@ -15,21 +15,72 @@ package types
import (
"encoding/json"
"fmt"
"html/template"
"reflect"
"time"
"github.com/spf13/cast"
)
// ToStringSlicePreserveString converts v to a string slice.
// If v is a string, it will be wrapped in a string slice.
// ToDuration converts v to time.Duration.
// See ToDurationE if you need to handle errors.
func ToDuration(v interface{}) time.Duration {
d, _ := ToDurationE(v)
return d
}
// ToDurationE converts v to time.Duration.
func ToDurationE(v interface{}) (time.Duration, error) {
if n := cast.ToInt(v); n > 0 {
return time.Duration(n) * time.Millisecond, nil
}
d, err := time.ParseDuration(cast.ToString(v))
if err != nil {
return 0, fmt.Errorf("cannot convert %v to time.Duration", v)
}
return d, nil
}
// ToStringSlicePreserveString is the same as ToStringSlicePreserveStringE,
// but it never fails.
func ToStringSlicePreserveString(v interface{}) []string {
vv, _ := ToStringSlicePreserveStringE(v)
return vv
}
// ToStringSlicePreserveStringE converts v to a string slice.
// If v is a string, it will be wrapped in a string slice.
func ToStringSlicePreserveStringE(v interface{}) ([]string, error) {
if v == nil {
return nil
return nil, nil
}
if sds, ok := v.(string); ok {
return []string{sds}
return []string{sds}, nil
}
return cast.ToStringSlice(v)
result, err := cast.ToStringSliceE(v)
if err == nil {
return result, nil
}
// Probably []int or similar. Fall back to reflect.
vv := reflect.ValueOf(v)
switch vv.Kind() {
case reflect.Slice, reflect.Array:
result = make([]string, vv.Len())
for i := 0; i < vv.Len(); i++ {
s, err := cast.ToStringE(vv.Index(i).Interface())
if err != nil {
return nil, err
}
result[i] = s
}
return result, nil
default:
return nil, fmt.Errorf("failed to convert %T to a string slice", v)
}
}
// TypeToString converts v to a string if it's a valid string type.
+12 -1
View File
@@ -16,6 +16,7 @@ package types
import (
"encoding/json"
"testing"
"time"
qt "github.com/frankban/quicktest"
)
@@ -24,9 +25,10 @@ func TestToStringSlicePreserveString(t *testing.T) {
c := qt.New(t)
c.Assert(ToStringSlicePreserveString("Hugo"), qt.DeepEquals, []string{"Hugo"})
c.Assert(ToStringSlicePreserveString(qt.Commentf("Hugo")), qt.DeepEquals, []string{"Hugo"})
c.Assert(ToStringSlicePreserveString([]interface{}{"A", "B"}), qt.DeepEquals, []string{"A", "B"})
c.Assert(ToStringSlicePreserveString([]int{1, 3}), qt.DeepEquals, []string{"1", "3"})
c.Assert(ToStringSlicePreserveString(nil), qt.IsNil)
}
func TestToString(t *testing.T) {
@@ -34,5 +36,14 @@ func TestToString(t *testing.T) {
c.Assert(ToString([]byte("Hugo")), qt.Equals, "Hugo")
c.Assert(ToString(json.RawMessage("Hugo")), qt.Equals, "Hugo")
}
func TestToDuration(t *testing.T) {
c := qt.New(t)
c.Assert(ToDuration("200ms"), qt.Equals, 200*time.Millisecond)
c.Assert(ToDuration("200"), qt.Equals, 200*time.Millisecond)
c.Assert(ToDuration("4m"), qt.Equals, 4*time.Minute)
c.Assert(ToDuration("asdfadf"), qt.Equals, time.Duration(0))
}
+6
View File
@@ -27,6 +27,12 @@ type RLocker interface {
RUnlock()
}
// KeyValue is a interface{} tuple.
type KeyValue struct {
Key interface{}
Value interface{}
}
// KeyValueStr is a string tuple.
type KeyValueStr struct {
Key string
-1
View File
@@ -61,5 +61,4 @@ func TestLexicographicSort(t *testing.T) {
})
c.Assert(s, qt.DeepEquals, []string{"A", "b", "Ba", "ba", "ba", "Bz"})
}
+7 -7
View File
@@ -14,12 +14,12 @@
package config
import (
"github.com/pkg/errors"
"sort"
"strings"
"sync"
"github.com/pkg/errors"
"github.com/gohugoio/hugo/common/types"
"github.com/gobwas/glob"
@@ -34,13 +34,17 @@ var DefaultBuild = Build{
WriteStats: false,
}
// Build holds some build related condfiguration.
// Build holds some build related configuration.
type Build struct {
UseResourceCacheWhen string // never, fallback, always. Default is fallback
// When enabled, will collect and write a hugo_stats.json with some build
// related aggregated data (e.g. CSS class names).
WriteStats bool
// Can be used to toggle off writing of the intellinsense /assets/jsconfig.js
// file.
NoJSConfigInAssets bool
}
func (b Build) UseResourceCache(err error) bool {
@@ -84,7 +88,6 @@ type Sitemap struct {
}
func DecodeSitemap(prototype Sitemap, input map[string]interface{}) Sitemap {
for key, value := range input {
switch key {
case "changefreq":
@@ -112,7 +115,6 @@ type Server struct {
}
func (s *Server) init() {
s.compiledInit.Do(func() {
for _, h := range s.Headers {
s.compiledHeaders = append(s.compiledHeaders, glob.MustCompile(h.For))
@@ -146,7 +148,6 @@ func (s *Server) MatchHeaders(pattern string) []types.KeyValueStr {
})
return matches
}
func (s *Server) MatchRedirect(pattern string) Redirect {
@@ -172,7 +173,6 @@ func (s *Server) MatchRedirect(pattern string) Redirect {
}
return Redirect{}
}
type Headers struct {
+5 -7
View File
@@ -21,14 +21,12 @@ import (
"github.com/gohugoio/hugo/common/types"
qt "github.com/frankban/quicktest"
"github.com/spf13/viper"
)
func TestBuild(t *testing.T) {
c := qt.New(t)
v := viper.New()
v := New()
v.Set("build", map[string]interface{}{
"useResourceCacheWhen": "always",
})
@@ -57,7 +55,6 @@ func TestBuild(t *testing.T) {
c.Assert(b.UseResourceCache(herrors.ErrFeatureNotAvailable), qt.Equals, false)
c.Assert(b.UseResourceCache(errors.New("err")), qt.Equals, false)
c.Assert(b.UseResourceCache(nil), qt.Equals, false)
}
func TestServer(t *testing.T) {
@@ -98,7 +95,8 @@ status = 301
c.Assert(s.MatchHeaders("/foo.jpg"), qt.DeepEquals, []types.KeyValueStr{
{Key: "X-Content-Type-Options", Value: "nosniff"},
{Key: "X-Frame-Options", Value: "DENY"},
{Key: "X-XSS-Protection", Value: "1; mode=block"}})
{Key: "X-XSS-Protection", Value: "1; mode=block"},
})
c.Assert(s.MatchRedirect("/foo/bar/baz"), qt.DeepEquals, Redirect{
From: "/foo/**",
@@ -122,7 +120,8 @@ status = 301
c.Assert(s.MatchRedirect("/default/index.html"), qt.DeepEquals, Redirect{})
c.Assert(s.MatchRedirect("/default/"), qt.DeepEquals, Redirect{})
for _, errorCase := range []string{`[[server.redirects]]
for _, errorCase := range []string{
`[[server.redirects]]
from = "/**"
to = "/file"
status = 301`,
@@ -138,5 +137,4 @@ status = 301`,
c.Assert(err, qt.Not(qt.IsNil))
}
}
+117
View File
@@ -0,0 +1,117 @@
// Copyright 2021 The Hugo Authors. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package config
import (
"github.com/gohugoio/hugo/common/maps"
)
// NewCompositeConfig creates a new composite Provider with a read-only base
// and a writeable layer.
func NewCompositeConfig(base, layer Provider) Provider {
return &compositeConfig{
base: base,
layer: layer,
}
}
// compositeConfig contains a read only config base with
// a possibly writeable config layer on top.
type compositeConfig struct {
base Provider
layer Provider
}
func (c *compositeConfig) GetBool(key string) bool {
if c.layer.IsSet(key) {
return c.layer.GetBool(key)
}
return c.base.GetBool(key)
}
func (c *compositeConfig) GetInt(key string) int {
if c.layer.IsSet(key) {
return c.layer.GetInt(key)
}
return c.base.GetInt(key)
}
func (c *compositeConfig) Merge(key string, value interface{}) {
c.layer.Merge(key, value)
}
func (c *compositeConfig) GetParams(key string) maps.Params {
if c.layer.IsSet(key) {
return c.layer.GetParams(key)
}
return c.base.GetParams(key)
}
func (c *compositeConfig) GetStringMap(key string) map[string]interface{} {
if c.layer.IsSet(key) {
return c.layer.GetStringMap(key)
}
return c.base.GetStringMap(key)
}
func (c *compositeConfig) GetStringMapString(key string) map[string]string {
if c.layer.IsSet(key) {
return c.layer.GetStringMapString(key)
}
return c.base.GetStringMapString(key)
}
func (c *compositeConfig) GetStringSlice(key string) []string {
if c.layer.IsSet(key) {
return c.layer.GetStringSlice(key)
}
return c.base.GetStringSlice(key)
}
func (c *compositeConfig) Get(key string) interface{} {
if c.layer.IsSet(key) {
return c.layer.Get(key)
}
return c.base.Get(key)
}
func (c *compositeConfig) IsSet(key string) bool {
if c.layer.IsSet(key) {
return true
}
return c.base.IsSet(key)
}
func (c *compositeConfig) GetString(key string) string {
if c.layer.IsSet(key) {
return c.layer.GetString(key)
}
return c.base.GetString(key)
}
func (c *compositeConfig) Set(key string, value interface{}) {
c.layer.Set(key, value)
}
func (c *compositeConfig) SetDefaults(params maps.Params) {
c.layer.SetDefaults(params)
}
func (c *compositeConfig) WalkParams(walkFn func(params ...KeyParams) bool) {
panic("not supported")
}
func (c *compositeConfig) SetDefaultMergeStrategy() {
panic("not supported")
}
+40
View File
@@ -0,0 +1,40 @@
// Copyright 2021 The Hugo Authors. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package config
import (
"testing"
qt "github.com/frankban/quicktest"
)
func TestCompositeConfig(t *testing.T) {
c := qt.New(t)
c.Run("Set and get", func(c *qt.C) {
base, layer := New(), New()
cfg := NewCompositeConfig(base, layer)
layer.Set("a1", "av")
base.Set("b1", "bv")
cfg.Set("c1", "cv")
c.Assert(cfg.Get("a1"), qt.Equals, "av")
c.Assert(cfg.Get("b1"), qt.Equals, "bv")
c.Assert(cfg.Get("c1"), qt.Equals, "cv")
c.Assert(cfg.IsSet("c1"), qt.IsTrue)
c.Assert(layer.IsSet("c1"), qt.IsTrue)
c.Assert(base.IsSet("c1"), qt.IsFalse)
})
}
+106 -23
View File
@@ -14,13 +14,19 @@
package config
import (
"os"
"path/filepath"
"strings"
"github.com/gohugoio/hugo/common/herrors"
"github.com/pkg/errors"
"github.com/gohugoio/hugo/common/paths"
"github.com/gohugoio/hugo/common/maps"
"github.com/gohugoio/hugo/parser/metadecoders"
"github.com/spf13/afero"
"github.com/spf13/viper"
)
var (
@@ -43,32 +49,20 @@ func IsValidConfigFilename(filename string) bool {
// FromConfigString creates a config from the given YAML, JSON or TOML config. This is useful in tests.
func FromConfigString(config, configType string) (Provider, error) {
v := newViper()
m, err := readConfig(metadecoders.FormatFromString(configType), []byte(config))
if err != nil {
return nil, err
}
v.MergeConfigMap(m)
return v, nil
return NewFrom(m), nil
}
// FromFile loads the configuration from the given filename.
func FromFile(fs afero.Fs, filename string) (Provider, error) {
m, err := loadConfigFromFile(fs, filename)
if err != nil {
return nil, err
return nil, herrors.WithFileContextForFileDefault(err, filename, fs)
}
v := newViper()
err = v.MergeConfigMap(m)
if err != nil {
return nil, err
}
return v, nil
return NewFrom(m), nil
}
// FromFileToMap is the same as FromFile, but it returns the config values
@@ -86,7 +80,6 @@ func readConfig(format metadecoders.Format, data []byte) (map[string]interface{}
RenameKeys(m)
return m, nil
}
func loadConfigFromFile(fs afero.Fs, filename string) (map[string]interface{}, error) {
@@ -98,6 +91,102 @@ func loadConfigFromFile(fs afero.Fs, filename string) (map[string]interface{}, e
return m, nil
}
func LoadConfigFromDir(sourceFs afero.Fs, configDir, environment string) (Provider, []string, error) {
defaultConfigDir := filepath.Join(configDir, "_default")
environmentConfigDir := filepath.Join(configDir, environment)
cfg := New()
var configDirs []string
// Merge from least to most specific.
for _, dir := range []string{defaultConfigDir, environmentConfigDir} {
if _, err := sourceFs.Stat(dir); err == nil {
configDirs = append(configDirs, dir)
}
}
if len(configDirs) == 0 {
return nil, nil, nil
}
// Keep track of these so we can watch them for changes.
var dirnames []string
for _, configDir := range configDirs {
err := afero.Walk(sourceFs, configDir, func(path string, fi os.FileInfo, err error) error {
if fi == nil || err != nil {
return nil
}
if fi.IsDir() {
dirnames = append(dirnames, path)
return nil
}
if !IsValidConfigFilename(path) {
return nil
}
name := paths.Filename(filepath.Base(path))
item, err := metadecoders.Default.UnmarshalFileToMap(sourceFs, path)
if err != nil {
// This will be used in error reporting, use the most specific value.
dirnames = []string{path}
return errors.Wrapf(err, "failed to unmarshl config for path %q", path)
}
var keyPath []string
if name != "config" {
// Can be params.jp, menus.en etc.
name, lang := paths.FileAndExtNoDelimiter(name)
keyPath = []string{name}
if lang != "" {
keyPath = []string{"languages", lang}
switch name {
case "menu", "menus":
keyPath = append(keyPath, "menus")
case "params":
keyPath = append(keyPath, "params")
}
}
}
root := item
if len(keyPath) > 0 {
root = make(map[string]interface{})
m := root
for i, key := range keyPath {
if i >= len(keyPath)-1 {
m[key] = item
} else {
nm := make(map[string]interface{})
m[key] = nm
m = nm
}
}
}
// Migrate menu => menus etc.
RenameKeys(root)
// Set will overwrite keys with the same name, recursively.
cfg.Set("", root)
return nil
})
if err != nil {
return nil, dirnames, err
}
}
return cfg, dirnames, nil
}
var keyAliases maps.KeyRenamer
func init() {
@@ -117,9 +206,3 @@ func init() {
func RenameKeys(m map[string]interface{}) {
keyAliases.Rename(m)
}
func newViper() *viper.Viper {
v := viper.New()
return v
}
+6
View File
@@ -14,6 +14,7 @@
package config
import (
"github.com/gohugoio/hugo/common/maps"
"github.com/gohugoio/hugo/common/types"
)
@@ -22,11 +23,16 @@ type Provider interface {
GetString(key string) string
GetInt(key string) int
GetBool(key string) bool
GetParams(key string) maps.Params
GetStringMap(key string) map[string]interface{}
GetStringMapString(key string) map[string]string
GetStringSlice(key string) []string
Get(key string) interface{}
Set(key string, value interface{})
Merge(key string, value interface{})
SetDefaults(params maps.Params)
SetDefaultMergeStrategy()
WalkParams(walkFn func(params ...KeyParams) bool)
IsSet(key string) bool
}
+1 -2
View File
@@ -17,12 +17,11 @@ import (
"testing"
qt "github.com/frankban/quicktest"
"github.com/spf13/viper"
)
func TestGetStringSlicePreserveString(t *testing.T) {
c := qt.New(t)
cfg := viper.New()
cfg := New()
s := "This is a string"
sSlice := []string{"This", "is", "a", "slice"}

Some files were not shown because too many files have changed in this diff Show More