Image resource refactor

This commit pulls most of the image related logic into its own package, to make it easier to reason about and extend.

This is also a rewrite of the transformation logic used in Hugo Pipes, mostly to allow constructs like the one below:

    {{ ($myimg | fingerprint ).Width }}

Fixes #5903
Fixes #6234
Fixes #6266
This commit is contained in:
Bjørn Erik Pedersen
2019-08-18 11:21:27 +02:00
parent 58d4c0a8be
commit f9978ed164
34 changed files with 2674 additions and 1556 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 88 KiB

View File

@@ -42,8 +42,7 @@ import (
)
func TestPageBundlerSiteRegular(t *testing.T) {
t.Parallel()
c := qt.New(t)
baseBaseURL := "https://example.com"
for _, baseURLPath := range []string{"", "/hugo"} {
@@ -55,15 +54,14 @@ func TestPageBundlerSiteRegular(t *testing.T) {
}
ugly := ugly
canonify := canonify
t.Run(fmt.Sprintf("ugly=%t,canonify=%t,path=%s", ugly, canonify, baseURLPathId),
func(t *testing.T) {
t.Parallel()
c.Run(fmt.Sprintf("ugly=%t,canonify=%t,path=%s", ugly, canonify, baseURLPathId),
func(c *qt.C) {
c.Parallel()
baseURL := baseBaseURL + baseURLPath
relURLBase := baseURLPath
if canonify {
relURLBase = ""
}
c := qt.New(t)
fs, cfg := newTestBundleSources(t)
cfg.Set("baseURL", baseURL)
cfg.Set("canonifyURLs", canonify)

View File

@@ -14,6 +14,7 @@
package hugolib
import (
"io"
"os"
"path/filepath"
"testing"
@@ -167,6 +168,64 @@ T1: {{ $r.Content }}
}
func TestResourceChainBasic(t *testing.T) {
t.Parallel()
b := newTestSitesBuilder(t)
b.WithTemplatesAdded("index.html", `
{{ $hello := "<h1> Hello World! </h1>" | resources.FromString "hello.html" | fingerprint "sha512" | minify | fingerprint }}
HELLO: {{ $hello.Name }}|{{ $hello.RelPermalink }}|{{ $hello.Content | safeHTML }}
{{ $img := resources.Get "images/sunset.jpg" }}
{{ $fit := $img.Fit "200x200" }}
{{ $fit2 := $fit.Fit "100x200" }}
{{ $img = $img | fingerprint }}
SUNSET: {{ $img.Name }}|{{ $img.RelPermalink }}|{{ $img.Width }}|{{ len $img.Content }}
FIT: {{ $fit.Name }}|{{ $fit.RelPermalink }}|{{ $fit.Width }}
`)
fs := b.Fs.Source
imageDir := filepath.Join("assets", "images")
b.Assert(os.MkdirAll(imageDir, 0777), qt.IsNil)
src, err := os.Open("testdata/sunset.jpg")
b.Assert(err, qt.IsNil)
out, err := fs.Create(filepath.Join(imageDir, "sunset.jpg"))
b.Assert(err, qt.IsNil)
_, err = io.Copy(out, src)
b.Assert(err, qt.IsNil)
out.Close()
b.Running()
for i := 0; i < 2; i++ {
b.Build(BuildCfg{})
b.AssertFileContent("public/index.html",
`
SUNSET: images/sunset.jpg|/images/sunset.a9bf1d944e19c0f382e0d8f51de690f7d0bc8fa97390c4242a86c3e5c0737e71.jpg|900|90587
FIT: images/sunset.jpg|/images/sunset_hu59e56ffff1bc1d8d122b1403d34e039f_90587_200x200_fit_q75_box.jpg|200
`)
b.EditFiles("page1.md", `
---
title: "Page 1 edit"
summary: "Edited summary"
---
Edited content.
`)
b.Assert(b.Fs.Destination.Remove("public"), qt.IsNil)
b.H.ResourceSpec.ClearCaches()
}
}
func TestResourceChain(t *testing.T) {
t.Parallel()
@@ -353,9 +412,11 @@ Publish 2: {{ $cssPublish2.Permalink }}
"Publish 1: body{color:blue} /external1.min.css",
"Publish 2: http://example.com/external2.min.css",
)
c.Assert(b.CheckExists("public/external2.min.css"), qt.Equals, true)
c.Assert(b.CheckExists("public/external1.min.css"), qt.Equals, true)
c.Assert(b.CheckExists("public/inline.min.css"), qt.Equals, false)
b.Assert(b.CheckExists("public/external2.css"), qt.Equals, false)
b.Assert(b.CheckExists("public/external1.css"), qt.Equals, false)
b.Assert(b.CheckExists("public/external2.min.css"), qt.Equals, true)
b.Assert(b.CheckExists("public/external1.min.css"), qt.Equals, true)
b.Assert(b.CheckExists("public/inline.min.css"), qt.Equals, false)
}},
{"unmarshal", func() bool { return true }, func(b *sitesBuilder) {

View File

@@ -536,6 +536,7 @@ func (s *sitesBuilder) changeEvents() []fsnotify.Event {
}
func (s *sitesBuilder) build(cfg BuildCfg, shouldFail bool) *sitesBuilder {
s.Helper()
defer func() {
s.changedFiles = nil
}()