Commit Graph

914 Commits

Author SHA1 Message Date
Bjørn Erik Pedersen 65c82178b7 hugio: Speedup hasBytesWriter
The old implementation copied the incoming bytes into a fixed-size buffer
one byte at a time, and for every byte ran bytes.Contains for every
pattern over the whole buffer. That's O(n·patterns) scans of the buffer,
which showed up badly on large output (a full rendered page).

Scan each not-yet-matched pattern once per Write with bytes.Contains over
the chunk itself, in place, rather than per byte. The only carried state
is a small boundary window (the last maxPatternLen-1 bytes) joined with
the head of the next chunk, so a pattern straddling a Write boundary is
still detected. The chunk is never copied, so the extra allocation is
bounded by the longest pattern and independent of the output size. Once
all patterns have matched we mark done and drop the buffer.

patternLen summed the pattern lengths (to size the old buffer); the
boundary window only needs the longest pattern, so it's renamed
maxPatternLen and returns the max.

```bash
                  │ benchcmp.bench  │       fix-hasbytewriter.bench       │
                  │     sec/op      │    sec/op     vs base               │
HasBytesWriter-10   2473.095µ ± ∞ ¹   6.114µ ± ∞ ¹  -99.75% (p=0.029 n=4)
¹ need >= 6 samples for confidence interval at level 0.95

                  │ benchcmp.bench │       fix-hasbytewriter.bench        │
                  │      B/op      │     B/op      vs base                │
HasBytesWriter-10      48.00 ± ∞ ¹   128.00 ± ∞ ¹  +166.67% (p=0.029 n=4)
¹ need >= 6 samples for confidence interval at level 0.95

                  │ benchcmp.bench │       fix-hasbytewriter.bench       │
                  │   allocs/op    │  allocs/op   vs base                │
```
2026-07-04 13:25:35 +02:00
hugoreleaser d15baf53a9 releaser: Prepare repository for 0.164.0-DEV
[ci skip]
2026-06-18 16:39:26 +00:00
hugoreleaser 4d22555aeb releaser: Bump versions for release of 0.163.3
[ci skip]
2026-06-18 16:18:24 +00:00
hugoreleaser 96e06e1ab8 releaser: Prepare repository for 0.164.0-DEV
[ci skip]
2026-06-15 15:17:37 +00:00
hugoreleaser 19a5cec0b9 releaser: Bump versions for release of 0.163.2
[ci skip]
2026-06-15 14:55:00 +00:00
Bjørn Erik Pedersen 134674f00d Continue resolving on ERR_ACCESS_DENIED in Node's resolver
And then rethrow the ERR_ACCESS_DENIED if we cannot recover.

There's more details in #15041, but this error has been seen on Netlify with the CJS because of how Netlify has their node_modules cache folder set up.

Fixes #15041
2026-06-15 15:53:19 +02:00
hugoreleaser 1f35beb918 releaser: Prepare repository for 0.164.0-DEV
[ci skip]
2026-06-11 15:55:44 +00:00
hugoreleaser 2a4fd58818 releaser: Bump versions for release of 0.163.1
[ci skip]
2026-06-11 15:34:40 +00:00
hugoreleaser 72495f9fba releaser: Prepare repository for 0.164.0-DEV
[ci skip]
2026-06-08 14:36:12 +00:00
hugoreleaser 4a9485336a releaser: Bump versions for release of 0.163.0
[ci skip]
2026-06-08 14:13:03 +00:00
Bjørn Erik Pedersen 781fabf4e4 all: Run go fix ./... 2026-06-07 21:20:40 +02:00
Bjørn Erik Pedersen 98ad9b3c03 Only support the latest Go version
Which is currently Go 1.26.

Closes #14997
2026-06-07 17:01:04 +02:00
Joe Mooring 45c00b7c16 misc: Remove duplicate words in comments
Closes #14936
Closes #14950
Closes #14965
2026-05-29 17:54:14 +02:00
hugoreleaser b0fd7ee2e1 releaser: Prepare repository for 0.163.0-DEV
[ci skip]
2026-05-28 18:03:30 +00:00
hugoreleaser bba860e3ed releaser: Bump versions for release of 0.162.1
[ci skip]
2026-05-28 17:40:44 +00:00
Bjørn Erik Pedersen c270975049 Revert "tpl/collections: Make dict return nil when no values are provided"
This reverts commit 17a86ef5ed.

Closes #14958
2026-05-27 20:02:55 +02:00
hugoreleaser 076dfe13d0 releaser: Bump versions for release of 0.162.0
[ci skip]
2026-05-26 13:53:44 +00:00
Bjørn Erik Pedersen 90d9f812b2 Add image processing support for AVIF
The encode/decode is implemented in a WebAssembly module built from a
small C wrapper around libavif. Bundled libraries (statically linked,
compiled with the WASI SDK):

* libavif v1.4.1 (container + codec glue)
* libaom v3.14.1 (AV1 encoder + decoder)
* dav1d 1.5.3 (AV1 decoder)
* libyuv (Chromium pin) for color conversion
* parson for JSON message passing across the wasm boundary

HDR handling on the encoder:

* SDR images are written as BT.709 / sRGB / BT.601 (8-bit).
* 10-bit and up are written as BT.2020 primaries with PQ (SMPTE
  ST 2084) transfer and BT.2020-NCL matrix coefficients, signalled
  via CICP.
* Adobe-style SDR+gainmap inputs (e.g. Lightroom HDR exports) are
  baked into a single true-HDR image in BT.2020/PQ at 10-bit, with
  the CLLI (Content Light Level Information) box carried through so
  HDR-capable clients can tone-map correctly.

Limitations:

* Animated input (animated WebP/GIF) is collapsed to its first frame
  when re-encoded as AVIF; animated AVIF output is not yet supported.

Fixes #7837
2026-05-26 12:13:53 +02:00
Bjørn Erik Pedersen c4bbc2805c all: Replace RWMutex struct caches with ConcurrentMap 2026-05-24 15:29:47 +02:00
Bjørn Erik Pedersen 67aede4364 tpl/collections: Make dict return nil when no values are provided 2026-05-21 16:03:02 +02:00
Joe Mooring 5559263326 common/hmaps: Merge slice-valued module config into site config
When a module provides a config key whose value is a slice (e.g.
cascade or permalinks), and the site config declares the same key as a
map with only a merge strategy marker (_merge = 'deep'), the types do
not match and Params.merge silently dropped the module's value, leaving
the site with no effective cascade or permalink config from the module.

Fix Params.merge so that when the destination value is an empty Params
(IsZero — only the _merge key is present) and the source value is a
non-Params type, the source value is used provided the user-declared
merge strategy is not 'none'. This honours the explicit _merge
directive regardless of the surrounding shallow-merge context.

Closes #13869

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-15 19:50:42 +02:00
Bjørn Erik Pedersen ae7bf74b3e common/hexec: Make NODE_PATH a fallback for ESM bare imports
Node's ESM resolver does not consult NODE_PATH (unlike CJS require), so
an ESM postcss.config.js shipped by a Hugo theme fails when loaded from
the module cache: bare imports like `import x from "postcss-import"`
have no node_modules to walk up to.

Install a synchronous resolver hook (module.registerHooks) via
--import=data:... on every Node invocation. On ERR_MODULE_NOT_FOUND for
a bare specifier it resolves the package from each NODE_PATH entry via
createRequire().resolve(). No-op for relative, absolute, URL-scheme and
non-MODULE_NOT_FOUND failures. Synchronous hooks run on the main thread,
so no --allow-worker is needed under the Node permission model.

Fixes #13987

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-13 22:00:04 +02:00
Bjørn Erik Pedersen 16e854a437 testing: Use synctest where relevant 2026-05-13 10:07:26 +02:00
Bjørn Erik Pedersen 28147cb040 Fall back to hugo.buildDate in hugo.BuildDate() in non-vcs builds
Fixes #14862
2026-05-11 12:26:13 +02:00
Bjørn Erik Pedersen e51e761d9c css: Make css.Build's file-loader URLs absolute to web context root
When CSS imports assets via the file loader (fonts, images), the emitted
URLs were relative to the CSS output directory. That broke when the CSS
was inlined into HTML, since browsers then resolved the URLs against the
page rather than the CSS file.

Set esbuild's PublicPath to the CSS output directory joined with the
site base path so URLs work whether the CSS is published as a file or
inlined.

Fixes #14849
2026-05-10 19:08:08 +02:00
hugoreleaser 7fd65e16e4 releaser: Prepare repository for 0.162.0-DEV
[ci skip]
2026-04-29 14:17:46 +00:00
hugoreleaser ea8f66a7ce releaser: Bump versions for release of 0.161.1
[ci skip]
2026-04-29 13:56:01 +00:00
Bjørn Erik Pedersen d65af84d15 config/security: Add AllowChildProcess to security.node.permissions
Some Linux setups trigger detect-libc's spawnSync('getconf') fallback
when process.report does not expose glibcVersionRuntime, breaking
tailwindcss under the Node permission model. Add AllowChildProcess
mirroring AllowAddons/AllowWorker, default to ["tailwindcss"], and
emit --allow-child-process accordingly.

Fixes #14824
2026-04-29 13:50:37 +02:00
hugoreleaser 2bfcc6b994 releaser: Prepare repository for 0.162.0-DEV
[ci skip]
2026-04-28 12:08:01 +00:00
hugoreleaser 98d396c16a releaser: Bump versions for release of 0.161.0
[ci skip]
2026-04-28 11:46:32 +00:00
Bjørn Erik Pedersen 7622dd86ce css: Support nested hugo:vars/<name> imports
Allow CSS variables to be grouped under sub-paths and imported via
@import "hugo:vars/mobile" (or @use for Dart Sass), so callers can pass
nested dicts like:

    {{ dict "primary-color" "blue" "mobile" (dict "primary-color" "red") }}

Top-level "hugo:vars" now skips nested map entries instead of emitting
garbage for them.

Fixes #14705

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 19:42:50 +02:00
Bjørn Erik Pedersen 4c40c6d5ca helpers: Remove unused code 2026-04-23 20:05:09 +02:00
Bjørn Erik Pedersen d2594db670 common/constants: Remove unused consts 2026-04-23 20:05:09 +02:00
Bjørn Erik Pedersen ab2de51e07 common/paths: Remove unused code
Identified with:

```
punused "common/paths/**.go"
 ````
2026-04-23 20:05:09 +02:00
Bjørn Erik Pedersen a54c398b93 Harden Node tool execution with --permission flag
Add security.node.permissions config to run Node tools (PostCSS, Babel,
TailwindCSS) under Node's permission model, restricting file system access
to the working directory by default.

The binary resolution is simplified to node_modules/.bin → PATH (npx removed).
For both locations, the actual JS entry point is resolved via symlinks (macOS/Linux)
or by parsing npm wrapper scripts (Windows .cmd), then executed as
"node --permission --allow-fs-read=<path> --allow-fs-write=<path> <script>".

Users can opt out by removing "node" from security.exec.allow.

Closes #7287
2026-04-22 15:47:34 +02:00
Bjørn Erik Pedersen 7574e35b40 Replace the concurrent map with an identical upstream version 2026-04-20 18:33:59 +02:00
Bjørn Erik Pedersen b01cc14703 Revert "common/hugo: Deprecate extended and extended_withdeploy editions"
This reverts commit a17bdbc5fa.

Close #14771
2026-04-19 11:15:49 +02:00
Bjørn Erik Pedersen ce2a156a4e Add a more flexible filename identifier scheme that also allows setting roles and versions (#14754)
Fixes #14750
2026-04-15 16:44:19 +02:00
Joe Mooring a17bdbc5fa common/hugo: Deprecate extended and extended_withdeploy editions
Closes #14696
2026-04-13 23:18:23 +02:00
hugoreleaser d6bc8165e6 releaser: Bump versions for release of 0.160.1
[ci skip]
2026-04-08 14:02:42 +00:00
hugoreleaser 6b5554bac9 releaser: Prepare repository for 0.161.0-DEV
[ci skip]
2026-04-04 13:53:16 +00:00
hugoreleaser 652fc5acdd releaser: Bump versions for release of 0.160.0
[ci skip]
2026-04-04 13:32:34 +00:00
hugoreleaser 397980aab3 releaser: Prepare repository for 0.160.0-DEV
[ci skip]
2026-04-01 13:21:05 +00:00
hugoreleaser 5f4646acaa releaser: Bump versions for release of 0.159.2
[ci skip]
2026-04-01 12:59:20 +00:00
hugoreleaser 458ebdd448 releaser: Prepare repository for 0.160.0-DEV
[ci skip]
2026-03-26 10:13:11 +00:00
hugoreleaser 86c7d3afac releaser: Bump versions for release of 0.159.1
[ci skip]
2026-03-26 09:54:15 +00:00
hugoreleaser bd071d78a5 releaser: Prepare repository for 0.160.0-DEV
[ci skip]
2026-03-23 18:34:59 +00:00
hugoreleaser 2ed7d193cf releaser: Bump versions for release of 0.159.0
[ci skip]
2026-03-23 18:16:59 +00:00
Bjørn Erik Pedersen d88a29e002 npm: Use workspaces to simplify hugo mod npm pack
Rewrite `hugo mod npm pack` to use npm workspaces. Module deps are now
written to packages/hugoautogen/package.json and the root package.json
gets a "workspaces" reference. A hugo_packagemeta.json sidecar stores a
hash of all input package files so regular commands can warn when npm
deps are out of sync.

Other changes:
- Workspace glob patterns (*, **, {a,b}) are resolved via gobwas/glob.
- Workspaces defined in package.hugo.json are supported.
- package.hugo.json is only recognised at module roots, not in workspaces.
- When package.hugo.json exists, package.json is not mounted or vendored.
- packages/hugoautogen is not mounted or vendored from dependencies.
- Add usePackageJSON import option (auto/always/never) to control whether
  a module's npm deps are included. "auto" checks for Hugo config files
  or package.hugo.json.
- The staleness check is skipped when running `hugo mod npm pack` itself.

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 16:00:50 +01:00
Bjørn Erik Pedersen 182b104571 Replace deprecated excludeFiles and includeFiles with files in tests 2026-03-21 16:59:13 +01:00