2017-01-10 04:55:03 -05:00
package hugolib
import (
"path/filepath"
"testing"
2017-02-17 14:52:50 -05:00
"fmt"
2018-03-15 04:37:30 -04:00
"regexp"
2017-02-17 14:52:50 -05:00
"strings"
2018-03-15 04:37:30 -04:00
jww "github.com/spf13/jwalterweatherman"
2017-06-13 12:42:45 -04:00
"github.com/gohugoio/hugo/config"
"github.com/gohugoio/hugo/deps"
2017-06-13 13:07:35 -04:00
"github.com/spf13/afero"
2017-02-20 03:33:35 -05:00
2017-06-13 12:42:45 -04:00
"github.com/gohugoio/hugo/helpers"
"github.com/gohugoio/hugo/tpl"
2017-01-10 04:55:03 -05:00
"github.com/spf13/viper"
2017-02-04 22:20:06 -05:00
"io/ioutil"
"os"
"log"
2017-06-13 12:42:45 -04:00
"github.com/gohugoio/hugo/hugofs"
2017-01-10 04:55:03 -05:00
"github.com/stretchr/testify/require"
)
2018-03-15 04:37:30 -04:00
const ( )
type sitesBuilder struct {
Cfg config . Provider
Fs * hugofs . Fs
T testing . TB
H * HugoSites
// We will add some default if not set.
templatesAdded bool
i18nAdded bool
dataAdded bool
contentAdded bool
}
func newTestSitesBuilder ( t testing . TB ) * sitesBuilder {
v := viper . New ( )
fs := hugofs . NewMem ( v )
return & sitesBuilder { T : t , Fs : fs }
}
func ( s * sitesBuilder ) WithTOMLConfig ( conf string ) * sitesBuilder {
writeSource ( s . T , s . Fs , "config.toml" , conf )
return s
}
func ( s * sitesBuilder ) WithDefaultMultiSiteConfig ( ) * sitesBuilder {
var defaultMultiSiteConfig = `
baseURL = "http://example.com/blog"
paginate = 1
disablePathToLower = true
defaultContentLanguage = "en"
defaultContentLanguageInSubdir = true
[ permalinks ]
other = "/somewhere/else/:filename"
[ blackfriday ]
angledQuotes = true
[ Taxonomies ]
tag = "tags"
[ Languages ]
[ Languages . en ]
weight = 10
title = "In English"
languageName = "English"
[ Languages . en . blackfriday ]
angledQuotes = false
[ [ Languages . en . menu . main ] ]
url = "/"
name = "Home"
weight = 0
[ Languages . fr ]
weight = 20
title = "Le Français"
languageName = "Français"
[ Languages . fr . Taxonomies ]
plaque = "plaques"
[ Languages . nn ]
weight = 30
title = "På nynorsk"
languageName = "Nynorsk"
paginatePath = "side"
[ Languages . nn . Taxonomies ]
lag = "lag"
[ [ Languages . nn . menu . main ] ]
url = "/"
name = "Heim"
weight = 1
[ Languages . nb ]
weight = 40
title = "På bokmål"
languageName = "Bokmål"
paginatePath = "side"
[ Languages . nb . Taxonomies ]
lag = "lag"
`
return s . WithTOMLConfig ( defaultMultiSiteConfig )
}
func ( s * sitesBuilder ) WithContent ( filenameContent ... string ) * sitesBuilder {
s . contentAdded = true
for i := 0 ; i < len ( filenameContent ) ; i += 2 {
filename , content := filenameContent [ i ] , filenameContent [ i + 1 ]
writeSource ( s . T , s . Fs , filepath . Join ( "content" , filename ) , content )
}
return s
}
func ( s * sitesBuilder ) WithTemplates ( filenameContent ... string ) * sitesBuilder {
s . templatesAdded = true
for i := 0 ; i < len ( filenameContent ) ; i += 2 {
filename , content := filenameContent [ i ] , filenameContent [ i + 1 ]
writeSource ( s . T , s . Fs , filepath . Join ( "layouts" , filename ) , content )
}
return s
}
func ( s * sitesBuilder ) CreateSites ( ) * sitesBuilder {
if ! s . templatesAdded {
s . addDefaultTemplates ( )
}
if ! s . i18nAdded {
s . addDefaultI18n ( )
}
if ! s . dataAdded {
s . addDefaultData ( )
}
if ! s . contentAdded {
s . addDefaultContent ( )
}
if s . Cfg == nil {
cfg , err := LoadConfig ( s . Fs . Source , "" , "config.toml" )
if err != nil {
s . T . Fatalf ( "Failed to load config: %s" , err )
}
s . Cfg = cfg
}
sites , err := NewHugoSites ( deps . DepsCfg { Fs : s . Fs , Cfg : s . Cfg } )
if err != nil {
s . T . Fatalf ( "Failed to create sites: %s" , err )
}
s . H = sites
return s
}
func ( s * sitesBuilder ) Build ( cfg BuildCfg ) * sitesBuilder {
if s . H == nil {
s . T . Fatal ( "Need to run builder.CreateSites first" )
}
err := s . H . Build ( cfg )
if err != nil {
s . T . Fatalf ( "Build failed: %s" , err )
}
return s
}
func ( s * sitesBuilder ) addDefaultTemplates ( ) {
fs := s . Fs
t := s . T
// Layouts
writeSource ( t , fs , filepath . Join ( "layouts" , "_default/single.html" ) , "Single: {{ .Title }}|{{ i18n \"hello\" }}|{{.Lang}}|{{ .Content }}" )
writeSource ( t , fs , filepath . Join ( "layouts" , "_default/list.html" ) , "{{ $p := .Paginator }}List Page {{ $p.PageNumber }}: {{ .Title }}|{{ i18n \"hello\" }}|{{ .Permalink }}|Pager: {{ template \"_internal/pagination.html\" . }}" )
writeSource ( t , fs , filepath . Join ( "layouts" , "index.html" ) , "{{ $p := .Paginator }}Default Home Page {{ $p.PageNumber }}: {{ .Title }}|{{ .IsHome }}|{{ i18n \"hello\" }}|{{ .Permalink }}|{{ .Site.Data.hugo.slogan }}" )
writeSource ( t , fs , filepath . Join ( "layouts" , "index.fr.html" ) , "{{ $p := .Paginator }}French Home Page {{ $p.PageNumber }}: {{ .Title }}|{{ .IsHome }}|{{ i18n \"hello\" }}|{{ .Permalink }}|{{ .Site.Data.hugo.slogan }}" )
// Shortcodes
writeSource ( t , fs , filepath . Join ( "layouts" , "shortcodes" , "shortcode.html" ) , "Shortcode: {{ i18n \"hello\" }}" )
// A shortcode in multiple languages
writeSource ( t , fs , filepath . Join ( "layouts" , "shortcodes" , "lingo.html" ) , "LingoDefault" )
writeSource ( t , fs , filepath . Join ( "layouts" , "shortcodes" , "lingo.fr.html" ) , "LingoFrench" )
}
func ( s * sitesBuilder ) addDefaultI18n ( ) {
fs := s . Fs
t := s . T
writeSource ( t , fs , filepath . Join ( "i18n" , "en.yaml" ) , `
hello :
other : "Hello"
` )
writeSource ( t , fs , filepath . Join ( "i18n" , "fr.yaml" ) , `
hello :
other : "Bonjour"
` )
}
func ( s * sitesBuilder ) addDefaultData ( ) {
fs := s . Fs
t := s . T
writeSource ( t , fs , filepath . FromSlash ( "data/hugo.toml" ) , "slogan = \"Hugo Rocks!\"" )
}
func ( s * sitesBuilder ) addDefaultContent ( ) {
fs := s . Fs
t := s . T
contentTemplate := ` -- -
title : doc1
weight : 1
tags :
- tag1
date : "2018-02-28"
-- -
# doc1
* some "content" *
{ { < shortcode > } }
{ { < lingo > } }
`
writeSource ( t , fs , filepath . FromSlash ( "content/sect/doc1.en.md" ) , contentTemplate )
writeSource ( t , fs , filepath . FromSlash ( "content/sect/doc1.fr.md" ) , contentTemplate )
writeSource ( t , fs , filepath . FromSlash ( "content/sect/doc1.nb.md" ) , contentTemplate )
writeSource ( t , fs , filepath . FromSlash ( "content/sect/doc1.nn.md" ) , contentTemplate )
}
func ( s * sitesBuilder ) AssertFileContent ( filename string , matches ... string ) {
content := readDestination ( s . T , s . Fs , filename )
for _ , match := range matches {
if ! strings . Contains ( content , match ) {
s . T . Fatalf ( "No match for %q in content for %s\n%q" , match , filename , content )
}
}
}
func ( s * sitesBuilder ) AssertFileContentRe ( filename string , matches ... string ) {
content := readDestination ( s . T , s . Fs , filename )
for _ , match := range matches {
r := regexp . MustCompile ( match )
if ! r . MatchString ( content ) {
s . T . Fatalf ( "No match for %q in content for %s\n%q" , match , filename , content )
}
}
}
2017-02-17 14:52:50 -05:00
type testHelper struct {
Cfg config . Provider
Fs * hugofs . Fs
T testing . TB
}
2017-02-17 15:14:52 -05:00
func ( th testHelper ) assertFileContent ( filename string , matches ... string ) {
filename = th . replaceDefaultContentLanguageValue ( filename )
2017-02-17 14:52:50 -05:00
content := readDestination ( th . T , th . Fs , filename )
for _ , match := range matches {
2017-02-17 15:14:52 -05:00
match = th . replaceDefaultContentLanguageValue ( match )
2017-02-17 14:52:50 -05:00
require . True ( th . T , strings . Contains ( content , match ) , fmt . Sprintf ( "File no match for\n%q in\n%q:\n%s" , strings . Replace ( match , "%" , "%%" , - 1 ) , filename , strings . Replace ( content , "%" , "%%" , - 1 ) ) )
}
}
2017-02-17 15:14:52 -05:00
// TODO(bep) better name for this. It does no magic replacements depending on defaultontentLanguageInSubDir.
func ( th testHelper ) assertFileContentStraight ( filename string , matches ... string ) {
2017-02-17 14:52:50 -05:00
content := readDestination ( th . T , th . Fs , filename )
for _ , match := range matches {
2017-02-17 15:14:52 -05:00
require . True ( th . T , strings . Contains ( content , match ) , fmt . Sprintf ( "File no match for\n%q in\n%q:\n%s" , strings . Replace ( match , "%" , "%%" , - 1 ) , filename , strings . Replace ( content , "%" , "%%" , - 1 ) ) )
}
}
func ( th testHelper ) assertFileContentRegexp ( filename string , matches ... string ) {
filename = th . replaceDefaultContentLanguageValue ( filename )
content := readDestination ( th . T , th . Fs , filename )
for _ , match := range matches {
match = th . replaceDefaultContentLanguageValue ( match )
2017-02-17 14:52:50 -05:00
r := regexp . MustCompile ( match )
require . True ( th . T , r . MatchString ( content ) , fmt . Sprintf ( "File no match for\n%q in\n%q:\n%s" , strings . Replace ( match , "%" , "%%" , - 1 ) , filename , strings . Replace ( content , "%" , "%%" , - 1 ) ) )
}
}
2017-04-23 16:03:25 -04:00
func ( th testHelper ) assertFileNotExist ( filename string ) {
exists , err := helpers . Exists ( filename , th . Fs . Destination )
require . NoError ( th . T , err )
require . False ( th . T , exists )
}
2017-02-17 15:14:52 -05:00
func ( th testHelper ) replaceDefaultContentLanguageValue ( value string ) string {
defaultInSubDir := th . Cfg . GetBool ( "defaultContentLanguageInSubDir" )
replace := th . Cfg . GetString ( "defaultContentLanguage" ) + "/"
if ! defaultInSubDir {
value = strings . Replace ( value , replace , "" , 1 )
}
return value
}
2017-02-04 22:20:06 -05:00
func newTestPathSpec ( fs * hugofs . Fs , v * viper . Viper ) * helpers . PathSpec {
l := helpers . NewDefaultLanguage ( v )
2017-03-25 09:37:04 -04:00
ps , _ := helpers . NewPathSpec ( fs , l )
return ps
2017-01-10 04:55:03 -05:00
}
2017-03-09 13:19:29 -05:00
func newTestDefaultPathSpec ( ) * helpers . PathSpec {
v := viper . New ( )
// Easier to reason about in tests.
v . Set ( "disablePathToLower" , true )
fs := hugofs . NewDefault ( v )
2017-03-25 09:37:04 -04:00
ps , _ := helpers . NewPathSpec ( fs , v )
return ps
2017-03-09 13:19:29 -05:00
}
2017-02-04 22:20:06 -05:00
func newTestCfg ( ) ( * viper . Viper , * hugofs . Fs ) {
v := viper . New ( )
fs := hugofs . NewMem ( v )
v . SetFs ( fs . Source )
loadDefaultSettingsFor ( v )
// Default is false, but true is easier to use as default in tests
v . Set ( "defaultContentLanguageInSubdir" , true )
return v , fs
}
// newTestSite creates a new site in the English language with in-memory Fs.
// The site will have a template system loaded and ready to use.
// Note: This is only used in single site tests.
func newTestSite ( t testing . TB , configKeyValues ... interface { } ) * Site {
cfg , fs := newTestCfg ( )
for i := 0 ; i < len ( configKeyValues ) ; i += 2 {
cfg . Set ( configKeyValues [ i ] . ( string ) , configKeyValues [ i + 1 ] )
}
2017-03-06 13:54:46 -05:00
d := deps . DepsCfg { Language : helpers . NewLanguage ( "en" , cfg ) , Fs : fs , Cfg : cfg }
2017-02-04 22:20:06 -05:00
s , err := NewSiteForCfg ( d )
if err != nil {
t . Fatalf ( "Failed to create Site: %s" , err )
}
return s
}
2017-03-27 14:43:49 -04:00
func newTestSitesFromConfig ( t testing . TB , afs afero . Fs , tomlConfig string , layoutPathContentPairs ... string ) ( testHelper , * HugoSites ) {
2017-02-20 03:33:35 -05:00
if len ( layoutPathContentPairs ) % 2 != 0 {
t . Fatalf ( "Layouts must be provided in pairs" )
}
2017-03-27 14:43:49 -04:00
writeToFs ( t , afs , "config.toml" , tomlConfig )
2017-02-20 03:33:35 -05:00
2017-03-27 14:43:49 -04:00
cfg , err := LoadConfig ( afs , "" , "config.toml" )
2017-02-20 03:33:35 -05:00
require . NoError ( t , err )
2017-03-27 14:43:49 -04:00
fs := hugofs . NewFrom ( afs , cfg )
2017-02-20 03:33:35 -05:00
th := testHelper { cfg , fs , t }
for i := 0 ; i < len ( layoutPathContentPairs ) ; i += 2 {
writeSource ( t , fs , layoutPathContentPairs [ i ] , layoutPathContentPairs [ i + 1 ] )
}
h , err := NewHugoSites ( deps . DepsCfg { Fs : fs , Cfg : cfg } )
require . NoError ( t , err )
return th , h
}
func newTestSitesFromConfigWithDefaultTemplates ( t testing . TB , tomlConfig string ) ( testHelper , * HugoSites ) {
2017-03-27 14:43:49 -04:00
return newTestSitesFromConfig ( t , afero . NewMemMapFs ( ) , tomlConfig ,
2017-02-20 03:33:35 -05:00
"layouts/_default/single.html" , "Single|{{ .Title }}|{{ .Content }}" ,
"layouts/_default/list.html" , "List|{{ .Title }}|{{ .Content }}" ,
"layouts/_default/terms.html" , "Terms List|{{ .Title }}|{{ .Content }}" ,
)
}
2017-02-04 22:20:06 -05:00
func newDebugLogger ( ) * jww . Notepad {
return jww . NewNotepad ( jww . LevelDebug , jww . LevelError , os . Stdout , ioutil . Discard , "" , log . Ldate | log . Ltime )
2017-01-10 04:55:03 -05:00
}
2017-03-03 04:47:43 -05:00
func newErrorLogger ( ) * jww . Notepad {
return jww . NewNotepad ( jww . LevelError , jww . LevelError , os . Stdout , ioutil . Discard , "" , log . Ldate | log . Ltime )
}
:sparkles: Implement Page bundling and image handling
This commit is not the smallest in Hugo's history.
Some hightlights include:
* Page bundles (for complete articles, keeping images and content together etc.).
* Bundled images can be processed in as many versions/sizes as you need with the three methods `Resize`, `Fill` and `Fit`.
* Processed images are cached inside `resources/_gen/images` (default) in your project.
* Symbolic links (both files and dirs) are now allowed anywhere inside /content
* A new table based build summary
* The "Total in nn ms" now reports the total including the handling of the files inside /static. So if it now reports more than you're used to, it is just **more real** and probably faster than before (see below).
A site building benchmark run compared to `v0.31.1` shows that this should be slightly faster and use less memory:
```bash
▶ ./benchSite.sh "TOML,num_langs=.*,num_root_sections=5,num_pages=(500|1000),tags_per_page=5,shortcodes,render"
benchmark old ns/op new ns/op delta
BenchmarkSiteBuilding/TOML,num_langs=1,num_root_sections=5,num_pages=500,tags_per_page=5,shortcodes,render-4 101785785 78067944 -23.30%
BenchmarkSiteBuilding/TOML,num_langs=1,num_root_sections=5,num_pages=1000,tags_per_page=5,shortcodes,render-4 185481057 149159919 -19.58%
BenchmarkSiteBuilding/TOML,num_langs=3,num_root_sections=5,num_pages=500,tags_per_page=5,shortcodes,render-4 103149918 85679409 -16.94%
BenchmarkSiteBuilding/TOML,num_langs=3,num_root_sections=5,num_pages=1000,tags_per_page=5,shortcodes,render-4 203515478 169208775 -16.86%
benchmark old allocs new allocs delta
BenchmarkSiteBuilding/TOML,num_langs=1,num_root_sections=5,num_pages=500,tags_per_page=5,shortcodes,render-4 532464 391539 -26.47%
BenchmarkSiteBuilding/TOML,num_langs=1,num_root_sections=5,num_pages=1000,tags_per_page=5,shortcodes,render-4 1056549 772702 -26.87%
BenchmarkSiteBuilding/TOML,num_langs=3,num_root_sections=5,num_pages=500,tags_per_page=5,shortcodes,render-4 555974 406630 -26.86%
BenchmarkSiteBuilding/TOML,num_langs=3,num_root_sections=5,num_pages=1000,tags_per_page=5,shortcodes,render-4 1086545 789922 -27.30%
benchmark old bytes new bytes delta
BenchmarkSiteBuilding/TOML,num_langs=1,num_root_sections=5,num_pages=500,tags_per_page=5,shortcodes,render-4 53243246 43598155 -18.12%
BenchmarkSiteBuilding/TOML,num_langs=1,num_root_sections=5,num_pages=1000,tags_per_page=5,shortcodes,render-4 105811617 86087116 -18.64%
BenchmarkSiteBuilding/TOML,num_langs=3,num_root_sections=5,num_pages=500,tags_per_page=5,shortcodes,render-4 54558852 44545097 -18.35%
BenchmarkSiteBuilding/TOML,num_langs=3,num_root_sections=5,num_pages=1000,tags_per_page=5,shortcodes,render-4 106903858 86978413 -18.64%
```
Fixes #3651
Closes #3158
Fixes #1014
Closes #2021
Fixes #1240
Updates #3757
2017-07-24 03:00:23 -04:00
func newWarningLogger ( ) * jww . Notepad {
return jww . NewNotepad ( jww . LevelWarn , jww . LevelError , os . Stdout , ioutil . Discard , "" , log . Ldate | log . Ltime )
}
2017-03-27 14:43:49 -04:00
func createWithTemplateFromNameValues ( additionalTemplates ... string ) func ( templ tpl . TemplateHandler ) error {
2017-01-10 04:55:03 -05:00
2017-03-27 14:43:49 -04:00
return func ( templ tpl . TemplateHandler ) error {
2017-01-10 04:55:03 -05:00
for i := 0 ; i < len ( additionalTemplates ) ; i += 2 {
err := templ . AddTemplate ( additionalTemplates [ i ] , additionalTemplates [ i + 1 ] )
if err != nil {
return err
}
}
return nil
}
}
2017-05-23 05:10:15 -04:00
func buildSingleSite ( t testing . TB , depsCfg deps . DepsCfg , buildCfg BuildCfg ) * Site {
2017-02-04 22:20:06 -05:00
return buildSingleSiteExpected ( t , false , depsCfg , buildCfg )
}
2017-05-23 05:10:15 -04:00
func buildSingleSiteExpected ( t testing . TB , expectBuildError bool , depsCfg deps . DepsCfg , buildCfg BuildCfg ) * Site {
2017-02-04 22:20:06 -05:00
h , err := NewHugoSites ( depsCfg )
2017-01-10 04:55:03 -05:00
require . NoError ( t , err )
require . Len ( t , h . Sites , 1 )
2017-02-04 22:20:06 -05:00
if expectBuildError {
require . Error ( t , h . Build ( buildCfg ) )
return nil
}
2017-01-10 04:55:03 -05:00
require . NoError ( t , h . Build ( buildCfg ) )
return h . Sites [ 0 ]
}
:sparkles: Implement Page bundling and image handling
This commit is not the smallest in Hugo's history.
Some hightlights include:
* Page bundles (for complete articles, keeping images and content together etc.).
* Bundled images can be processed in as many versions/sizes as you need with the three methods `Resize`, `Fill` and `Fit`.
* Processed images are cached inside `resources/_gen/images` (default) in your project.
* Symbolic links (both files and dirs) are now allowed anywhere inside /content
* A new table based build summary
* The "Total in nn ms" now reports the total including the handling of the files inside /static. So if it now reports more than you're used to, it is just **more real** and probably faster than before (see below).
A site building benchmark run compared to `v0.31.1` shows that this should be slightly faster and use less memory:
```bash
▶ ./benchSite.sh "TOML,num_langs=.*,num_root_sections=5,num_pages=(500|1000),tags_per_page=5,shortcodes,render"
benchmark old ns/op new ns/op delta
BenchmarkSiteBuilding/TOML,num_langs=1,num_root_sections=5,num_pages=500,tags_per_page=5,shortcodes,render-4 101785785 78067944 -23.30%
BenchmarkSiteBuilding/TOML,num_langs=1,num_root_sections=5,num_pages=1000,tags_per_page=5,shortcodes,render-4 185481057 149159919 -19.58%
BenchmarkSiteBuilding/TOML,num_langs=3,num_root_sections=5,num_pages=500,tags_per_page=5,shortcodes,render-4 103149918 85679409 -16.94%
BenchmarkSiteBuilding/TOML,num_langs=3,num_root_sections=5,num_pages=1000,tags_per_page=5,shortcodes,render-4 203515478 169208775 -16.86%
benchmark old allocs new allocs delta
BenchmarkSiteBuilding/TOML,num_langs=1,num_root_sections=5,num_pages=500,tags_per_page=5,shortcodes,render-4 532464 391539 -26.47%
BenchmarkSiteBuilding/TOML,num_langs=1,num_root_sections=5,num_pages=1000,tags_per_page=5,shortcodes,render-4 1056549 772702 -26.87%
BenchmarkSiteBuilding/TOML,num_langs=3,num_root_sections=5,num_pages=500,tags_per_page=5,shortcodes,render-4 555974 406630 -26.86%
BenchmarkSiteBuilding/TOML,num_langs=3,num_root_sections=5,num_pages=1000,tags_per_page=5,shortcodes,render-4 1086545 789922 -27.30%
benchmark old bytes new bytes delta
BenchmarkSiteBuilding/TOML,num_langs=1,num_root_sections=5,num_pages=500,tags_per_page=5,shortcodes,render-4 53243246 43598155 -18.12%
BenchmarkSiteBuilding/TOML,num_langs=1,num_root_sections=5,num_pages=1000,tags_per_page=5,shortcodes,render-4 105811617 86087116 -18.64%
BenchmarkSiteBuilding/TOML,num_langs=3,num_root_sections=5,num_pages=500,tags_per_page=5,shortcodes,render-4 54558852 44545097 -18.35%
BenchmarkSiteBuilding/TOML,num_langs=3,num_root_sections=5,num_pages=1000,tags_per_page=5,shortcodes,render-4 106903858 86978413 -18.64%
```
Fixes #3651
Closes #3158
Fixes #1014
Closes #2021
Fixes #1240
Updates #3757
2017-07-24 03:00:23 -04:00
func writeSourcesToSource ( t * testing . T , base string , fs * hugofs . Fs , sources ... [ 2 ] string ) {
2017-01-10 04:55:03 -05:00
for _ , src := range sources {
:sparkles: Implement Page bundling and image handling
This commit is not the smallest in Hugo's history.
Some hightlights include:
* Page bundles (for complete articles, keeping images and content together etc.).
* Bundled images can be processed in as many versions/sizes as you need with the three methods `Resize`, `Fill` and `Fit`.
* Processed images are cached inside `resources/_gen/images` (default) in your project.
* Symbolic links (both files and dirs) are now allowed anywhere inside /content
* A new table based build summary
* The "Total in nn ms" now reports the total including the handling of the files inside /static. So if it now reports more than you're used to, it is just **more real** and probably faster than before (see below).
A site building benchmark run compared to `v0.31.1` shows that this should be slightly faster and use less memory:
```bash
▶ ./benchSite.sh "TOML,num_langs=.*,num_root_sections=5,num_pages=(500|1000),tags_per_page=5,shortcodes,render"
benchmark old ns/op new ns/op delta
BenchmarkSiteBuilding/TOML,num_langs=1,num_root_sections=5,num_pages=500,tags_per_page=5,shortcodes,render-4 101785785 78067944 -23.30%
BenchmarkSiteBuilding/TOML,num_langs=1,num_root_sections=5,num_pages=1000,tags_per_page=5,shortcodes,render-4 185481057 149159919 -19.58%
BenchmarkSiteBuilding/TOML,num_langs=3,num_root_sections=5,num_pages=500,tags_per_page=5,shortcodes,render-4 103149918 85679409 -16.94%
BenchmarkSiteBuilding/TOML,num_langs=3,num_root_sections=5,num_pages=1000,tags_per_page=5,shortcodes,render-4 203515478 169208775 -16.86%
benchmark old allocs new allocs delta
BenchmarkSiteBuilding/TOML,num_langs=1,num_root_sections=5,num_pages=500,tags_per_page=5,shortcodes,render-4 532464 391539 -26.47%
BenchmarkSiteBuilding/TOML,num_langs=1,num_root_sections=5,num_pages=1000,tags_per_page=5,shortcodes,render-4 1056549 772702 -26.87%
BenchmarkSiteBuilding/TOML,num_langs=3,num_root_sections=5,num_pages=500,tags_per_page=5,shortcodes,render-4 555974 406630 -26.86%
BenchmarkSiteBuilding/TOML,num_langs=3,num_root_sections=5,num_pages=1000,tags_per_page=5,shortcodes,render-4 1086545 789922 -27.30%
benchmark old bytes new bytes delta
BenchmarkSiteBuilding/TOML,num_langs=1,num_root_sections=5,num_pages=500,tags_per_page=5,shortcodes,render-4 53243246 43598155 -18.12%
BenchmarkSiteBuilding/TOML,num_langs=1,num_root_sections=5,num_pages=1000,tags_per_page=5,shortcodes,render-4 105811617 86087116 -18.64%
BenchmarkSiteBuilding/TOML,num_langs=3,num_root_sections=5,num_pages=500,tags_per_page=5,shortcodes,render-4 54558852 44545097 -18.35%
BenchmarkSiteBuilding/TOML,num_langs=3,num_root_sections=5,num_pages=1000,tags_per_page=5,shortcodes,render-4 106903858 86978413 -18.64%
```
Fixes #3651
Closes #3158
Fixes #1014
Closes #2021
Fixes #1240
Updates #3757
2017-07-24 03:00:23 -04:00
writeSource ( t , fs , filepath . Join ( base , src [ 0 ] ) , src [ 1 ] )
}
}
func dumpPages ( pages ... * Page ) {
for i , p := range pages {
fmt . Printf ( "%d: Kind: %s Title: %-10s RelPermalink: %-10s Path: %-10s sections: %s Len Sections(): %d\n" ,
i + 1 ,
2018-01-15 14:40:39 -05:00
p . Kind , p . title , p . RelPermalink ( ) , p . Path ( ) , p . sections , len ( p . Sections ( ) ) )
2017-01-10 04:55:03 -05:00
}
}
2017-06-13 15:22:47 -04:00
func isCI ( ) bool {
return os . Getenv ( "CI" ) != ""
}