jekyll-compress-flow 0.2.0 → 0.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +40 -0
- data/README.md +22 -3
- data/interface.yml +20 -0
- data/lib/jekyll/compress_flow/interface.rb +22 -0
- data/lib/jekyll/compress_flow/version.rb +1 -1
- data/lib/jekyll/compress_flow.rb +25 -2
- metadata +10 -5
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 7698a216c6b11cc78eb4dbf1fc8642b3b76e41dcb93a3f0f6e72ed939207a9ab
|
|
4
|
+
data.tar.gz: 50876d915cc373992f28fff651357c468bd9306e9651e7a280ec7e81a531825d
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 7f862ea2ee85d52f9b58e8abb5b79808cca7ec951c69fb1ab80fd3a81085292e3084e9ac7ddef365ebad1fdc75971905600adeab6f2a341d2425c3d5aacd9e1d
|
|
7
|
+
data.tar.gz: 7a750ebe879c078a28224ae84d3ec738f273b567c562f3a78face1625ce5b005b78d23b37119731a85c13f34a1f36536472d28f884b4af2a52ba13cfa89ad5a1
|
data/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,46 @@ All notable changes to this project will be documented in this file.
|
|
|
4
4
|
|
|
5
5
|
## [Unreleased]
|
|
6
6
|
|
|
7
|
+
## 0.2.2 — 2026-11-10
|
|
8
|
+
|
|
9
|
+
### Added
|
|
10
|
+
|
|
11
|
+
- `rake docs:demo` — captures the checked-in illustrative overview as
|
|
12
|
+
animated AVIF + WebP + static PNG (headless Chrome + ffmpeg + img2webp;
|
|
13
|
+
build-host tools), embedded in README via `<picture>`. Examples are
|
|
14
|
+
schematic, not generated from a live Jekyll build.
|
|
15
|
+
|
|
16
|
+
### Changed
|
|
17
|
+
|
|
18
|
+
- CI: Semgrep moved from an inline `pip3 install` pin to the pinned
|
|
19
|
+
`semgrep/semgrep` container image (tag + sha256 digest). Image bumped
|
|
20
|
+
to 1.182.1 (certificate trust fix for the eMudhra CA compromise).
|
|
21
|
+
CI Node bumped from 24 to 26 (Active LTS "Lithium" since 2026-10-28).
|
|
22
|
+
- CI: `sonarqube-scan-action` bumped to v8.4.0; `markdownlint-cli2`
|
|
23
|
+
bumped to 0.24.0; `ruby/setup-ruby` v1.335.0 → v1.338.0; in-range
|
|
24
|
+
gem updates (rubocop 1.92.2, parser 3.3.13.0, addressable 2.9.2,
|
|
25
|
+
csv 3.3.7, sass-embedded 1.108.1, rspec-* 3.13.x patches);
|
|
26
|
+
`BUNDLED WITH` 4.0.23 → 4.0.24.
|
|
27
|
+
- CI: Ruby 4.0 added to the test matrix (latest stable major;
|
|
28
|
+
`required_ruby_version >= 3.3.0` already permits it).
|
|
29
|
+
- Gemspec `description` rewritten as an RDoc `==`-headed blurb so
|
|
30
|
+
rubygems.org renders it as markup instead of a single plain paragraph.
|
|
31
|
+
|
|
32
|
+
## 0.2.1 — 2026-10-06
|
|
33
|
+
|
|
34
|
+
### Added
|
|
35
|
+
|
|
36
|
+
- `Jekyll::CompressFlow::Interface.to_h` — the config surface
|
|
37
|
+
(`compress_flow` keys plus `formats:`/`priority:` enums) derived from
|
|
38
|
+
`DEFAULTS`, serialized to a committed `interface.yml` by
|
|
39
|
+
`rake interface`; `interface_spec.rb` pins manifest freshness.
|
|
40
|
+
|
|
41
|
+
### Changed
|
|
42
|
+
|
|
43
|
+
- Register the compression dispatcher at low priority (10) by default, after
|
|
44
|
+
normal-priority processing and Fingerprint Flow (default 12); allow per-site
|
|
45
|
+
`compress_flow.priority` values from 0 through 10.
|
|
46
|
+
|
|
7
47
|
## 0.2.0 — 2026-10-03
|
|
8
48
|
|
|
9
49
|
### Added
|
data/README.md
CHANGED
|
@@ -25,6 +25,19 @@ simply happens at build time instead of request time.
|
|
|
25
25
|
|
|
26
26
|
[Compare different formats](https://speedvitals.com/blog/zstd-vs-brotli-vs-gzip/)
|
|
27
27
|
|
|
28
|
+
<!-- markdownlint-disable MD033 -->
|
|
29
|
+
<picture>
|
|
30
|
+
<source
|
|
31
|
+
srcset="docs/assets/jekyll-compress-flow-demo.avif"
|
|
32
|
+
type="image/avif">
|
|
33
|
+
<source
|
|
34
|
+
srcset="docs/assets/jekyll-compress-flow-demo.webp"
|
|
35
|
+
type="image/webp">
|
|
36
|
+
<img src="docs/assets/jekyll-compress-flow-demo.png"
|
|
37
|
+
alt="jekyll-compress-flow demo">
|
|
38
|
+
</picture>
|
|
39
|
+
<!-- markdownlint-enable MD033 -->
|
|
40
|
+
|
|
28
41
|
## Prerequisites
|
|
29
42
|
|
|
30
43
|
The plugin shells out to the platform compressor CLIs — install them on
|
|
@@ -32,7 +45,7 @@ the **build host** (not the web server; visitors need nothing):
|
|
|
32
45
|
|
|
33
46
|
| Tool | Generates | Minimum | Tested baseline |
|
|
34
47
|
| ---- | --------- | ------- | --------------- |
|
|
35
|
-
| `brotli` | `.br` | 1.1.0 | 1.2.
|
|
48
|
+
| `brotli` | `.br` | 1.1.0 | 1.2.1 (macOS) |
|
|
36
49
|
| `zstd` | `.zst` | 1.5.5 | 1.5.7 (macOS) |
|
|
37
50
|
| `gzip` | `.gz` | any | preinstalled on macOS/Linux; ships with Git for Windows |
|
|
38
51
|
|
|
@@ -124,16 +137,22 @@ configured to negotiate them via `Accept-Encoding`:
|
|
|
124
137
|
```yaml
|
|
125
138
|
compress_flow:
|
|
126
139
|
enabled: true # default: Jekyll.env == "production"
|
|
140
|
+
priority: 10 # integer 0..10; default 10, after fingerprinting
|
|
127
141
|
formats: [br, zst, gz] # subset of the three; unknown names abort
|
|
128
142
|
extensions: [html, css, js, json, xml, svg, txt, map]
|
|
129
143
|
min_size: 0 # bytes — skip tiny files
|
|
130
144
|
fail_on_error: true # false: warn + skip instead of failing build
|
|
131
145
|
```
|
|
132
146
|
|
|
147
|
+
The post-write dispatcher accepts integer priorities from 0 through 10 so
|
|
148
|
+
site-specific compression remains after the default Fingerprint Flow range
|
|
149
|
+
(11–19).
|
|
150
|
+
|
|
133
151
|
## Behavior
|
|
134
152
|
|
|
135
|
-
- Runs on `:site, :post_write
|
|
136
|
-
|
|
153
|
+
- Runs on `:site, :post_write` at low priority (10), after normal-priority
|
|
154
|
+
post-processors and the priority-12 Fingerprint Flow pass — works with any
|
|
155
|
+
generator (pages, posts, feeds, sitemap, search JSON).
|
|
137
156
|
- Compressed siblings are never re-compressed (extensions not in the
|
|
138
157
|
list); images/fonts/PDFs are skipped (already compressed formats).
|
|
139
158
|
- A missing CLI tool aborts the build once per format
|
data/interface.yml
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# Generated by `rake interface` — do not edit.
|
|
2
|
+
# Public tag/config surface for tooling (editor extensions, doc linters).
|
|
3
|
+
---
|
|
4
|
+
gem: jekyll-compress-flow
|
|
5
|
+
version: 0.2.2
|
|
6
|
+
tags: {}
|
|
7
|
+
filters: []
|
|
8
|
+
config:
|
|
9
|
+
compress_flow:
|
|
10
|
+
- enabled
|
|
11
|
+
- extensions
|
|
12
|
+
- fail_on_error
|
|
13
|
+
- formats
|
|
14
|
+
- min_size
|
|
15
|
+
- priority
|
|
16
|
+
enums:
|
|
17
|
+
formats:
|
|
18
|
+
- br
|
|
19
|
+
- gz
|
|
20
|
+
- zst
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Jekyll
|
|
4
|
+
module CompressFlow
|
|
5
|
+
# Machine-readable description of the plugin's public interface:
|
|
6
|
+
# config keys and enum values (this plugin registers no Liquid tags).
|
|
7
|
+
# `rake interface` writes this as interface.yml (shipped in the gem) so
|
|
8
|
+
# tooling like editor extensions can consume it without parsing Ruby.
|
|
9
|
+
module Interface
|
|
10
|
+
def self.to_h
|
|
11
|
+
{
|
|
12
|
+
"gem" => "jekyll-compress-flow",
|
|
13
|
+
"version" => VERSION,
|
|
14
|
+
"tags" => {},
|
|
15
|
+
"filters" => [],
|
|
16
|
+
"config" => { "compress_flow" => DEFAULTS.keys.sort },
|
|
17
|
+
"enums" => { "formats" => FORMATS.keys.sort }
|
|
18
|
+
}
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
data/lib/jekyll/compress_flow.rb
CHANGED
|
@@ -4,6 +4,7 @@ require "jekyll"
|
|
|
4
4
|
require "open3"
|
|
5
5
|
|
|
6
6
|
require_relative "compress_flow/version"
|
|
7
|
+
require_relative "compress_flow/interface"
|
|
7
8
|
|
|
8
9
|
module Jekyll
|
|
9
10
|
# Generates .br/.zst/.gz siblings for text assets in the build output so a
|
|
@@ -23,8 +24,11 @@ module Jekyll
|
|
|
23
24
|
"gz" => { "tool" => "gzip", "args" => %w[-f -9 -k] }
|
|
24
25
|
}.freeze
|
|
25
26
|
|
|
27
|
+
DEFAULT_POST_WRITE_PRIORITY = 10
|
|
28
|
+
POST_WRITE_PRIORITIES = (0..DEFAULT_POST_WRITE_PRIORITY)
|
|
26
29
|
DEFAULTS = {
|
|
27
30
|
"enabled" => nil, # nil => Jekyll.env == "production"
|
|
31
|
+
"priority" => DEFAULT_POST_WRITE_PRIORITY,
|
|
28
32
|
"extensions" => %w[html css js json xml svg txt map],
|
|
29
33
|
"formats" => %w[br zst gz],
|
|
30
34
|
"min_size" => 0,
|
|
@@ -33,6 +37,14 @@ module Jekyll
|
|
|
33
37
|
|
|
34
38
|
module_function
|
|
35
39
|
|
|
40
|
+
def post_write_priority(config)
|
|
41
|
+
priority = config.transform_keys(&:to_s).fetch("priority", DEFAULT_POST_WRITE_PRIORITY)
|
|
42
|
+
return priority if priority.is_a?(Integer) && POST_WRITE_PRIORITIES.cover?(priority)
|
|
43
|
+
|
|
44
|
+
raise Jekyll::Errors::FatalException,
|
|
45
|
+
"CompressFlow: compress_flow.priority must be an integer from 0 through 10"
|
|
46
|
+
end
|
|
47
|
+
|
|
36
48
|
# Entry point — compress all matching files under +dest+.
|
|
37
49
|
# +config+ is the site's `compress_flow:` mapping (string or symbol keys).
|
|
38
50
|
def run(dest, config = {})
|
|
@@ -87,6 +99,9 @@ module Jekyll
|
|
|
87
99
|
end
|
|
88
100
|
|
|
89
101
|
def compress(file, format, cfg)
|
|
102
|
+
# Array-form system(): no shell — tool/args are literals from the frozen
|
|
103
|
+
# FORMATS table; file is a data argument globbed under the build dest.
|
|
104
|
+
# nosemgrep: ruby.lang.security.dangerous-exec.dangerous-exec
|
|
90
105
|
ok = system(format["tool"], *format["args"], file, out: File::NULL, err: File::NULL)
|
|
91
106
|
fail_or_warn(cfg, "#{format['tool']} failed on #{file}") unless ok
|
|
92
107
|
end
|
|
@@ -95,6 +110,8 @@ module Jekyll
|
|
|
95
110
|
# banner could not be parsed (or no pattern is defined — e.g. Apple gzip
|
|
96
111
|
# vs GNU gzip use incomparable version strings), nil when not installed.
|
|
97
112
|
def tool_version(tool, pattern)
|
|
113
|
+
# Array-form capture2e: no shell — tool is a literal from frozen FORMATS.
|
|
114
|
+
# nosemgrep: ruby.lang.security.dangerous-exec.dangerous-exec
|
|
98
115
|
out, status = Open3.capture2e(tool, "--version")
|
|
99
116
|
return nil unless status.success?
|
|
100
117
|
return :unversioned unless pattern && (match = out.match(pattern))
|
|
@@ -114,6 +131,12 @@ module Jekyll
|
|
|
114
131
|
end
|
|
115
132
|
end
|
|
116
133
|
|
|
117
|
-
Jekyll::
|
|
118
|
-
|
|
134
|
+
Jekyll::CompressFlow::POST_WRITE_PRIORITIES.each do |hook_priority|
|
|
135
|
+
registered_priority = hook_priority
|
|
136
|
+
Jekyll::Hooks.register :site, :post_write, priority: registered_priority do |site|
|
|
137
|
+
config = site.config["compress_flow"] || {}
|
|
138
|
+
next unless Jekyll::CompressFlow.post_write_priority(config) == registered_priority
|
|
139
|
+
|
|
140
|
+
Jekyll::CompressFlow.run(site.dest, config)
|
|
141
|
+
end
|
|
119
142
|
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: jekyll-compress-flow
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.2.
|
|
4
|
+
version: 0.2.2
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Svend Gundestrup
|
|
@@ -29,10 +29,13 @@ dependencies:
|
|
|
29
29
|
- - "<"
|
|
30
30
|
- !ruby/object:Gem::Version
|
|
31
31
|
version: '5.0'
|
|
32
|
-
description:
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
32
|
+
description: |
|
|
33
|
+
== Precompressed siblings for Jekyll output
|
|
34
|
+
|
|
35
|
+
Writes .br, .zst and .gz siblings next to text assets at the end of a
|
|
36
|
+
build, so a precompressed-capable static server (for example Caddy's
|
|
37
|
+
file_server precompressed) can serve them without per-request
|
|
38
|
+
compression CPU.
|
|
36
39
|
email:
|
|
37
40
|
- svend@gundestrup.dk
|
|
38
41
|
executables: []
|
|
@@ -42,8 +45,10 @@ files:
|
|
|
42
45
|
- CHANGELOG.md
|
|
43
46
|
- LICENSE
|
|
44
47
|
- README.md
|
|
48
|
+
- interface.yml
|
|
45
49
|
- lib/jekyll-compress-flow.rb
|
|
46
50
|
- lib/jekyll/compress_flow.rb
|
|
51
|
+
- lib/jekyll/compress_flow/interface.rb
|
|
47
52
|
- lib/jekyll/compress_flow/version.rb
|
|
48
53
|
homepage: https://github.com/gundestrup/jekyll-compress-flow
|
|
49
54
|
licenses:
|