2016-08-05 05:04:52 -04:00
// Copyright 2016-present 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 hugolib
import (
Add Hugo Modules
This commit implements Hugo Modules.
This is a broad subject, but some keywords include:
* A new `module` configuration section where you can import almost anything. You can configure both your own file mounts nd the file mounts of the modules you import. This is the new recommended way of configuring what you earlier put in `configDir`, `staticDir` etc. And it also allows you to mount folders in non-Hugo-projects, e.g. the `SCSS` folder in the Bootstrap GitHub project.
* A module consists of a set of mounts to the standard 7 component types in Hugo: `static`, `content`, `layouts`, `data`, `assets`, `i18n`, and `archetypes`. Yes, Theme Components can now include content, which should be very useful, especially in bigger multilingual projects.
* Modules not in your local file cache will be downloaded automatically and even "hot replaced" while the server is running.
* Hugo Modules supports and encourages semver versioned modules, and uses the minimal version selection algorithm to resolve versions.
* A new set of CLI commands are provided to manage all of this: `hugo mod init`, `hugo mod get`, `hugo mod graph`, `hugo mod tidy`, and `hugo mod vendor`.
All of the above is backed by Go Modules.
Fixes #5973
Fixes #5996
Fixes #6010
Fixes #5911
Fixes #5940
Fixes #6074
Fixes #6082
Fixes #6092
2019-05-03 03:16:58 -04:00
"bytes"
"fmt"
"path/filepath"
2021-06-09 04:58:18 -04:00
"strings"
2016-08-05 05:04:52 -04:00
"testing"
2021-07-15 09:31:50 -04:00
"github.com/gohugoio/hugo/config"
2021-06-09 04:58:18 -04:00
"github.com/gohugoio/hugo/media"
"github.com/google/go-cmp/cmp"
2019-08-10 15:05:17 -04:00
qt "github.com/frankban/quicktest"
2021-06-09 04:58:18 -04:00
"github.com/gohugoio/hugo/common/maps"
2017-02-04 22:20:06 -05:00
"github.com/spf13/afero"
2016-08-05 05:04:52 -04:00
)
2017-02-04 22:20:06 -05:00
func TestLoadConfig ( t * testing . T ) {
2019-08-10 15:05:17 -04:00
c := qt . New ( t )
2018-03-18 06:07:24 -04:00
2021-07-15 09:31:50 -04:00
loadConfig := func ( c * qt . C , configContent string , fromDir bool ) config . Provider {
mm := afero . NewMemMapFs ( )
filename := "config.toml"
descriptor := ConfigSourceDescriptor { Fs : mm }
if fromDir {
filename = filepath . Join ( "config" , "_default" , filename )
descriptor . AbsConfigDir = "config"
}
writeToFs ( t , mm , filename , configContent )
cfg , _ , err := LoadConfig ( descriptor )
c . Assert ( err , qt . IsNil )
return cfg
}
c . Run ( "Basic" , func ( c * qt . C ) {
c . Parallel ( )
// Add a random config variable for testing.
// side = page in Norwegian.
cfg := loadConfig ( c , ` PaginatePath = "side" ` , false )
c . Assert ( cfg . GetString ( "paginatePath" ) , qt . Equals , "side" )
} )
// Issue #8763
for _ , fromDir := range [ ] bool { false , true } {
testName := "Taxonomy overrides"
if fromDir {
testName += " from dir"
}
c . Run ( testName , func ( c * qt . C ) {
c . Parallel ( )
cfg := loadConfig ( c , ` [ taxonomies ]
appellation = "appellations"
vigneron = "vignerons" ` , fromDir )
c . Assert ( cfg . Get ( "taxonomies" ) , qt . DeepEquals , maps . Params {
"appellation" : "appellations" ,
"vigneron" : "vignerons" ,
} )
} )
}
2016-08-05 05:04:52 -04:00
}
2018-03-18 06:07:24 -04:00
2017-08-09 14:13:02 -04:00
func TestLoadMultiConfig ( t * testing . T ) {
t . Parallel ( )
2019-08-10 15:05:17 -04:00
c := qt . New ( t )
2018-03-18 06:07:24 -04:00
2017-08-09 14:13:02 -04:00
// Add a random config variable for testing.
// side = page in Norwegian.
configContentBase := `
DontChange = "same"
PaginatePath = "side"
`
configContentSub := `
PaginatePath = "top"
`
mm := afero . NewMemMapFs ( )
writeToFs ( t , mm , "base.toml" , configContentBase )
writeToFs ( t , mm , "override.toml" , configContentSub )
2018-03-18 06:07:24 -04:00
cfg , _ , err := LoadConfig ( ConfigSourceDescriptor { Fs : mm , Filename : "base.toml,override.toml" } )
2019-08-10 15:05:17 -04:00
c . Assert ( err , qt . IsNil )
2017-08-09 14:13:02 -04:00
2019-08-10 15:05:17 -04:00
c . Assert ( cfg . GetString ( "paginatePath" ) , qt . Equals , "top" )
c . Assert ( cfg . GetString ( "DontChange" ) , qt . Equals , "same" )
2018-03-18 06:07:24 -04:00
}
2021-06-22 12:17:49 -04:00
func TestLoadConfigFromThemes ( t * testing . T ) {
2018-03-18 06:07:24 -04:00
t . Parallel ( )
2019-08-10 15:05:17 -04:00
c := qt . New ( t )
2018-03-18 06:07:24 -04:00
2021-06-09 04:58:18 -04:00
mainConfigTemplate := `
2018-03-18 06:07:24 -04:00
theme = "test-theme"
baseURL = "https://example.com/"
[ frontmatter ]
date = [ "date" , "publishDate" ]
[ params ]
2021-06-09 04:58:18 -04:00
MERGE_PARAMS
2018-03-18 06:07:24 -04:00
p1 = "p1 main"
2021-06-09 04:58:18 -04:00
[ params . b ]
b1 = "b1 main"
[ params . b . c ]
bc1 = "bc1 main"
2018-03-18 06:07:24 -04:00
[ mediaTypes ]
[ mediaTypes . "text/m1" ]
2018-08-28 08:18:12 -04:00
suffixes = [ "m1main" ]
2018-03-18 06:07:24 -04:00
[ outputFormats . o1 ]
mediaType = "text/m1"
baseName = "o1main"
[ languages ]
[ languages . en ]
languageName = "English"
[ languages . en . params ]
pl1 = "p1-en-main"
[ languages . nb ]
languageName = "Norsk"
[ languages . nb . params ]
pl1 = "p1-nb-main"
[ [ menu . main ] ]
name = "menu-main-main"
[ [ menu . top ] ]
name = "menu-top-main"
`
themeConfig := `
baseURL = "http://bep.is/"
2021-08-22 05:57:37 -04:00
# Can not be set in theme .
disableKinds = [ "taxonomy" , "term" ]
2018-03-18 06:07:24 -04:00
# Can not be set in theme .
[ frontmatter ]
expiryDate = [ "date" ]
[ params ]
p1 = "p1 theme"
p2 = "p2 theme"
2021-06-09 04:58:18 -04:00
[ params . b ]
b1 = "b1 theme"
b2 = "b2 theme"
[ params . b . c ]
bc1 = "bc1 theme"
bc2 = "bc2 theme"
[ params . b . c . d ]
bcd1 = "bcd1 theme"
2018-03-18 06:07:24 -04:00
[ mediaTypes ]
[ mediaTypes . "text/m1" ]
2018-08-28 08:18:12 -04:00
suffixes = [ "m1theme" ]
2018-03-18 06:07:24 -04:00
[ mediaTypes . "text/m2" ]
2018-08-28 08:18:12 -04:00
suffixes = [ "m2theme" ]
2018-03-18 06:07:24 -04:00
[ outputFormats . o1 ]
mediaType = "text/m1"
baseName = "o1theme"
[ outputFormats . o2 ]
mediaType = "text/m2"
baseName = "o2theme"
[ languages ]
[ languages . en ]
languageName = "English2"
[ languages . en . params ]
pl1 = "p1-en-theme"
pl2 = "p2-en-theme"
[ [ languages . en . menu . main ] ]
name = "menu-lang-en-main"
[ [ languages . en . menu . theme ] ]
name = "menu-lang-en-theme"
[ languages . nb ]
languageName = "Norsk2"
[ languages . nb . params ]
pl1 = "p1-nb-theme"
pl2 = "p2-nb-theme"
top = "top-nb-theme"
[ [ languages . nb . menu . main ] ]
name = "menu-lang-nb-main"
[ [ languages . nb . menu . theme ] ]
name = "menu-lang-nb-theme"
[ [ languages . nb . menu . top ] ]
name = "menu-lang-nb-top"
[ [ menu . main ] ]
name = "menu-main-theme"
[ [ menu . thememenu ] ]
name = "menu-theme"
`
2021-07-03 04:40:59 -04:00
buildForConfig := func ( t testing . TB , mainConfig , themeConfig string ) * sitesBuilder {
2021-06-09 04:58:18 -04:00
b := newTestSitesBuilder ( t )
b . WithConfigFile ( "toml" , mainConfig ) . WithThemeConfigFile ( "toml" , themeConfig )
2021-06-22 12:17:49 -04:00
return b . Build ( BuildCfg { } )
}
buildForStrategy := func ( t testing . TB , s string ) * sitesBuilder {
mainConfig := strings . ReplaceAll ( mainConfigTemplate , "MERGE_PARAMS" , s )
2021-07-03 04:40:59 -04:00
return buildForConfig ( t , mainConfig , themeConfig )
2021-06-09 04:58:18 -04:00
}
2018-03-18 06:07:24 -04:00
2021-06-09 04:58:18 -04:00
c . Run ( "Merge default" , func ( c * qt . C ) {
b := buildForStrategy ( c , "" )
got := b . Cfg . Get ( "" ) . ( maps . Params )
2021-08-22 05:57:37 -04:00
// Issue #8866
b . Assert ( b . Cfg . Get ( "disableKinds" ) , qt . IsNil )
2021-06-09 04:58:18 -04:00
b . Assert ( got [ "params" ] , qt . DeepEquals , maps . Params {
"b" : maps . Params {
"b1" : "b1 main" ,
"c" : maps . Params {
"bc1" : "bc1 main" ,
"bc2" : "bc2 theme" ,
"d" : maps . Params { "bcd1" : string ( "bcd1 theme" ) } ,
} ,
"b2" : "b2 theme" ,
} ,
"p2" : "p2 theme" ,
"p1" : "p1 main" ,
} )
b . Assert ( got [ "mediatypes" ] , qt . DeepEquals , maps . Params {
"text/m2" : maps . Params {
2022-03-17 17:03:27 -04:00
"suffixes" : [ ] any {
2021-06-09 04:58:18 -04:00
"m2theme" ,
} ,
} ,
"text/m1" : maps . Params {
2022-03-17 17:03:27 -04:00
"suffixes" : [ ] any {
2021-06-09 04:58:18 -04:00
"m1main" ,
} ,
} ,
} )
var eq = qt . CmpEquals (
cmp . Comparer ( func ( m1 , m2 media . Type ) bool {
if m1 . SubType != m2 . SubType {
return false
}
return m1 . FirstSuffix == m2 . FirstSuffix
} ) ,
)
mediaTypes := b . H . Sites [ 0 ] . mediaTypesConfig
m1 , _ := mediaTypes . GetByType ( "text/m1" )
m2 , _ := mediaTypes . GetByType ( "text/m2" )
b . Assert ( got [ "outputformats" ] , eq , maps . Params {
"o1" : maps . Params {
"mediatype" : m1 ,
"basename" : "o1main" ,
} ,
"o2" : maps . Params {
"basename" : "o2theme" ,
"mediatype" : m2 ,
} ,
} )
b . Assert ( got [ "languages" ] , qt . DeepEquals , maps . Params {
"en" : maps . Params {
"languagename" : "English" ,
"params" : maps . Params {
"pl2" : "p2-en-theme" ,
"pl1" : "p1-en-main" ,
} ,
"menus" : maps . Params {
2022-03-17 17:03:27 -04:00
"main" : [ ] any {
map [ string ] any {
2021-06-09 04:58:18 -04:00
"name" : "menu-lang-en-main" ,
} ,
} ,
2022-03-17 17:03:27 -04:00
"theme" : [ ] any {
map [ string ] any {
2021-06-09 04:58:18 -04:00
"name" : "menu-lang-en-theme" ,
} ,
} ,
} ,
} ,
"nb" : maps . Params {
"languagename" : "Norsk" ,
"params" : maps . Params {
"top" : "top-nb-theme" ,
"pl1" : "p1-nb-main" ,
"pl2" : "p2-nb-theme" ,
} ,
"menus" : maps . Params {
2022-03-17 17:03:27 -04:00
"main" : [ ] any {
map [ string ] any {
2021-06-09 04:58:18 -04:00
"name" : "menu-lang-nb-main" ,
} ,
} ,
2022-03-17 17:03:27 -04:00
"theme" : [ ] any {
map [ string ] any {
2021-06-09 04:58:18 -04:00
"name" : "menu-lang-nb-theme" ,
} ,
} ,
2022-03-17 17:03:27 -04:00
"top" : [ ] any {
map [ string ] any {
2021-06-09 04:58:18 -04:00
"name" : "menu-lang-nb-top" ,
} ,
} ,
} ,
} ,
} )
c . Assert ( got [ "baseurl" ] , qt . Equals , "https://example.com/" )
} )
c . Run ( "Merge shallow" , func ( c * qt . C ) {
b := buildForStrategy ( c , fmt . Sprintf ( "_merge=%q" , "shallow" ) )
got := b . Cfg . Get ( "" ) . ( maps . Params )
// Shallow merge, only add new keys to params.
b . Assert ( got [ "params" ] , qt . DeepEquals , maps . Params {
"p1" : "p1 main" ,
"b" : maps . Params {
"b1" : "b1 main" ,
"c" : maps . Params {
"bc1" : "bc1 main" ,
} ,
} ,
"p2" : "p2 theme" ,
} )
} )
2018-03-18 06:07:24 -04:00
2021-06-22 12:17:49 -04:00
c . Run ( "Merge no params in project" , func ( c * qt . C ) {
b := buildForConfig (
2021-07-03 04:40:59 -04:00
c ,
2021-06-22 12:17:49 -04:00
"baseURL=\"https://example.org\"\ntheme = \"test-theme\"\n" ,
"[params]\np1 = \"p1 theme\"\n" ,
)
got := b . Cfg . Get ( "" ) . ( maps . Params )
b . Assert ( got [ "params" ] , qt . DeepEquals , maps . Params {
"p1" : "p1 theme" ,
} )
} )
c . Run ( "Merge language no menus or params in project" , func ( c * qt . C ) {
b := buildForConfig (
2021-07-03 04:40:59 -04:00
c ,
2021-06-22 12:17:49 -04:00
`
theme = "test-theme"
baseURL = "https://example.com/"
[ languages ]
[ languages . en ]
languageName = "English"
` ,
`
[ languages ]
[ languages . en ]
languageName = "EnglishTheme"
[ languages . en . params ]
p1 = "themep1"
[ [ languages . en . menus . main ] ]
name = "menu-theme"
` ,
)
got := b . Cfg . Get ( "" ) . ( maps . Params )
b . Assert ( got [ "languages" ] , qt . DeepEquals ,
maps . Params {
"en" : maps . Params {
"languagename" : "English" ,
"menus" : maps . Params {
2022-03-17 17:03:27 -04:00
"main" : [ ] any {
map [ string ] any {
2021-06-22 12:17:49 -04:00
"name" : "menu-theme" ,
} ,
} ,
} ,
"params" : maps . Params {
"p1" : "themep1" ,
} ,
} ,
} ,
)
} )
2021-07-03 04:40:59 -04:00
// Issue #8724
for _ , mergeStrategy := range [ ] string { "none" , "shallow" } {
c . Run ( fmt . Sprintf ( "Merge with sitemap config in theme, mergestrategy %s" , mergeStrategy ) , func ( c * qt . C ) {
smapConfigTempl := ` [ sitemap ]
changefreq = % q
filename = "sitemap.xml"
priority = 0.5 `
b := buildForConfig (
c ,
fmt . Sprintf ( "_merge=%q\nbaseURL=\"https://example.org\"\ntheme = \"test-theme\"\n" , mergeStrategy ) ,
"baseURL=\"http://example.com\"\n" + fmt . Sprintf ( smapConfigTempl , "monthly" ) ,
)
got := b . Cfg . Get ( "" ) . ( maps . Params )
if mergeStrategy == "none" {
b . Assert ( got [ "sitemap" ] , qt . DeepEquals , maps . Params {
"priority" : int ( - 1 ) ,
"filename" : "sitemap.xml" ,
} )
b . AssertFileContent ( "public/sitemap.xml" , "schemas/sitemap" )
} else {
b . Assert ( got [ "sitemap" ] , qt . DeepEquals , maps . Params {
"priority" : int ( - 1 ) ,
"filename" : "sitemap.xml" ,
"changefreq" : "monthly" ,
} )
b . AssertFileContent ( "public/sitemap.xml" , "<changefreq>monthly</changefreq>" )
}
} )
}
2017-08-09 14:13:02 -04:00
}
2018-05-04 04:18:45 -04:00
2021-06-16 13:11:01 -04:00
func TestLoadConfigFromThemeDir ( t * testing . T ) {
t . Parallel ( )
mainConfig := `
theme = "test-theme"
[ params ]
m1 = "mv1"
`
themeConfig := `
[ params ]
t1 = "tv1"
t2 = "tv2"
`
themeConfigDir := filepath . Join ( "themes" , "test-theme" , "config" )
themeConfigDirDefault := filepath . Join ( themeConfigDir , "_default" )
themeConfigDirProduction := filepath . Join ( themeConfigDir , "production" )
projectConfigDir := "config"
b := newTestSitesBuilder ( t )
b . WithConfigFile ( "toml" , mainConfig ) . WithThemeConfigFile ( "toml" , themeConfig )
b . Assert ( b . Fs . Source . MkdirAll ( themeConfigDirDefault , 0777 ) , qt . IsNil )
b . Assert ( b . Fs . Source . MkdirAll ( themeConfigDirProduction , 0777 ) , qt . IsNil )
b . Assert ( b . Fs . Source . MkdirAll ( projectConfigDir , 0777 ) , qt . IsNil )
b . WithSourceFile ( filepath . Join ( projectConfigDir , "config.toml" ) , ` [ params ]
m2 = "mv2"
` )
b . WithSourceFile ( filepath . Join ( themeConfigDirDefault , "config.toml" ) , ` [ params ]
t2 = "tv2d"
t3 = "tv3d"
` )
b . WithSourceFile ( filepath . Join ( themeConfigDirProduction , "config.toml" ) , ` [ params ]
t3 = "tv3p"
` )
b . Build ( BuildCfg { } )
got := b . Cfg . Get ( "params" ) . ( maps . Params )
b . Assert ( got , qt . DeepEquals , maps . Params {
"t3" : "tv3p" ,
"m1" : "mv1" ,
"t1" : "tv1" ,
"t2" : "tv2d" ,
} )
}
2018-05-04 04:18:45 -04:00
func TestPrivacyConfig ( t * testing . T ) {
t . Parallel ( )
2019-08-10 15:05:17 -04:00
c := qt . New ( t )
2018-05-04 04:18:45 -04:00
tomlConfig := `
someOtherValue = "foo"
[ privacy ]
[ privacy . youtube ]
2018-05-21 08:02:30 -04:00
privacyEnhanced = true
2018-05-04 04:18:45 -04:00
`
b := newTestSitesBuilder ( t )
b . WithConfigFile ( "toml" , tomlConfig )
b . Build ( BuildCfg { SkipRender : true } )
2019-08-10 15:05:17 -04:00
c . Assert ( b . H . Sites [ 0 ] . Info . Config ( ) . Privacy . YouTube . PrivacyEnhanced , qt . Equals , true )
2018-05-04 04:18:45 -04:00
}
Add Hugo Modules
This commit implements Hugo Modules.
This is a broad subject, but some keywords include:
* A new `module` configuration section where you can import almost anything. You can configure both your own file mounts nd the file mounts of the modules you import. This is the new recommended way of configuring what you earlier put in `configDir`, `staticDir` etc. And it also allows you to mount folders in non-Hugo-projects, e.g. the `SCSS` folder in the Bootstrap GitHub project.
* A module consists of a set of mounts to the standard 7 component types in Hugo: `static`, `content`, `layouts`, `data`, `assets`, `i18n`, and `archetypes`. Yes, Theme Components can now include content, which should be very useful, especially in bigger multilingual projects.
* Modules not in your local file cache will be downloaded automatically and even "hot replaced" while the server is running.
* Hugo Modules supports and encourages semver versioned modules, and uses the minimal version selection algorithm to resolve versions.
* A new set of CLI commands are provided to manage all of this: `hugo mod init`, `hugo mod get`, `hugo mod graph`, `hugo mod tidy`, and `hugo mod vendor`.
All of the above is backed by Go Modules.
Fixes #5973
Fixes #5996
Fixes #6010
Fixes #5911
Fixes #5940
Fixes #6074
Fixes #6082
Fixes #6092
2019-05-03 03:16:58 -04:00
func TestLoadConfigModules ( t * testing . T ) {
t . Parallel ( )
2019-08-10 15:05:17 -04:00
c := qt . New ( t )
Add Hugo Modules
This commit implements Hugo Modules.
This is a broad subject, but some keywords include:
* A new `module` configuration section where you can import almost anything. You can configure both your own file mounts nd the file mounts of the modules you import. This is the new recommended way of configuring what you earlier put in `configDir`, `staticDir` etc. And it also allows you to mount folders in non-Hugo-projects, e.g. the `SCSS` folder in the Bootstrap GitHub project.
* A module consists of a set of mounts to the standard 7 component types in Hugo: `static`, `content`, `layouts`, `data`, `assets`, `i18n`, and `archetypes`. Yes, Theme Components can now include content, which should be very useful, especially in bigger multilingual projects.
* Modules not in your local file cache will be downloaded automatically and even "hot replaced" while the server is running.
* Hugo Modules supports and encourages semver versioned modules, and uses the minimal version selection algorithm to resolve versions.
* A new set of CLI commands are provided to manage all of this: `hugo mod init`, `hugo mod get`, `hugo mod graph`, `hugo mod tidy`, and `hugo mod vendor`.
All of the above is backed by Go Modules.
Fixes #5973
Fixes #5996
Fixes #6010
Fixes #5911
Fixes #5940
Fixes #6074
Fixes #6082
Fixes #6092
2019-05-03 03:16:58 -04:00
// https://github.com/gohugoio/hugoThemes#themetoml
const (
// Before Hugo 0.56 each theme/component could have its own theme.toml
// with some settings, mostly used on the Hugo themes site.
// To preserve combability we read these files into the new "modules"
// section in config.toml.
o1t = `
name = "Component o1"
license = "MIT"
min_version = 0.38
`
// This is the component's config.toml, using the old theme syntax.
o1c = `
theme = [ "n2" ]
`
n1 = `
title = "Component n1"
[ module ]
description = "Component n1 description"
[ module . hugoVersion ]
min = "0.40.0"
max = "0.50.0"
extended = true
[ [ module . imports ] ]
path = "o1"
[ [ module . imports ] ]
path = "n3"
`
n2 = `
title = "Component n2"
`
n3 = `
title = "Component n3"
`
n4 = `
title = "Component n4"
`
)
b := newTestSitesBuilder ( t )
writeThemeFiles := func ( name , configTOML , themeTOML string ) {
b . WithSourceFile ( filepath . Join ( "themes" , name , "data" , "module.toml" ) , fmt . Sprintf ( "name=%q" , name ) )
if configTOML != "" {
b . WithSourceFile ( filepath . Join ( "themes" , name , "config.toml" ) , configTOML )
}
if themeTOML != "" {
b . WithSourceFile ( filepath . Join ( "themes" , name , "theme.toml" ) , themeTOML )
}
}
writeThemeFiles ( "n1" , n1 , "" )
writeThemeFiles ( "n2" , n2 , "" )
writeThemeFiles ( "n3" , n3 , "" )
writeThemeFiles ( "n4" , n4 , "" )
writeThemeFiles ( "o1" , o1c , o1t )
b . WithConfigFile ( "toml" , `
[ module ]
[ [ module . imports ] ]
path = "n1"
[ [ module . imports ] ]
path = "n4"
` )
b . Build ( BuildCfg { } )
modulesClient := b . H . Paths . ModulesClient
var graphb bytes . Buffer
modulesClient . Graph ( & graphb )
2019-08-10 15:05:17 -04:00
expected := ` project n1
Add Hugo Modules
This commit implements Hugo Modules.
This is a broad subject, but some keywords include:
* A new `module` configuration section where you can import almost anything. You can configure both your own file mounts nd the file mounts of the modules you import. This is the new recommended way of configuring what you earlier put in `configDir`, `staticDir` etc. And it also allows you to mount folders in non-Hugo-projects, e.g. the `SCSS` folder in the Bootstrap GitHub project.
* A module consists of a set of mounts to the standard 7 component types in Hugo: `static`, `content`, `layouts`, `data`, `assets`, `i18n`, and `archetypes`. Yes, Theme Components can now include content, which should be very useful, especially in bigger multilingual projects.
* Modules not in your local file cache will be downloaded automatically and even "hot replaced" while the server is running.
* Hugo Modules supports and encourages semver versioned modules, and uses the minimal version selection algorithm to resolve versions.
* A new set of CLI commands are provided to manage all of this: `hugo mod init`, `hugo mod get`, `hugo mod graph`, `hugo mod tidy`, and `hugo mod vendor`.
All of the above is backed by Go Modules.
Fixes #5973
Fixes #5996
Fixes #6010
Fixes #5911
Fixes #5940
Fixes #6074
Fixes #6082
Fixes #6092
2019-05-03 03:16:58 -04:00
n1 o1
o1 n2
n1 n3
project n4
2019-08-10 15:05:17 -04:00
`
c . Assert ( graphb . String ( ) , qt . Equals , expected )
Add Hugo Modules
This commit implements Hugo Modules.
This is a broad subject, but some keywords include:
* A new `module` configuration section where you can import almost anything. You can configure both your own file mounts nd the file mounts of the modules you import. This is the new recommended way of configuring what you earlier put in `configDir`, `staticDir` etc. And it also allows you to mount folders in non-Hugo-projects, e.g. the `SCSS` folder in the Bootstrap GitHub project.
* A module consists of a set of mounts to the standard 7 component types in Hugo: `static`, `content`, `layouts`, `data`, `assets`, `i18n`, and `archetypes`. Yes, Theme Components can now include content, which should be very useful, especially in bigger multilingual projects.
* Modules not in your local file cache will be downloaded automatically and even "hot replaced" while the server is running.
* Hugo Modules supports and encourages semver versioned modules, and uses the minimal version selection algorithm to resolve versions.
* A new set of CLI commands are provided to manage all of this: `hugo mod init`, `hugo mod get`, `hugo mod graph`, `hugo mod tidy`, and `hugo mod vendor`.
All of the above is backed by Go Modules.
Fixes #5973
Fixes #5996
Fixes #6010
Fixes #5911
Fixes #5940
Fixes #6074
Fixes #6082
Fixes #6092
2019-05-03 03:16:58 -04:00
}
func TestLoadConfigWithOsEnvOverrides ( t * testing . T ) {
2019-08-10 15:05:17 -04:00
c := qt . New ( t )
Add Hugo Modules
This commit implements Hugo Modules.
This is a broad subject, but some keywords include:
* A new `module` configuration section where you can import almost anything. You can configure both your own file mounts nd the file mounts of the modules you import. This is the new recommended way of configuring what you earlier put in `configDir`, `staticDir` etc. And it also allows you to mount folders in non-Hugo-projects, e.g. the `SCSS` folder in the Bootstrap GitHub project.
* A module consists of a set of mounts to the standard 7 component types in Hugo: `static`, `content`, `layouts`, `data`, `assets`, `i18n`, and `archetypes`. Yes, Theme Components can now include content, which should be very useful, especially in bigger multilingual projects.
* Modules not in your local file cache will be downloaded automatically and even "hot replaced" while the server is running.
* Hugo Modules supports and encourages semver versioned modules, and uses the minimal version selection algorithm to resolve versions.
* A new set of CLI commands are provided to manage all of this: `hugo mod init`, `hugo mod get`, `hugo mod graph`, `hugo mod tidy`, and `hugo mod vendor`.
All of the above is backed by Go Modules.
Fixes #5973
Fixes #5996
Fixes #6010
Fixes #5911
Fixes #5940
Fixes #6074
Fixes #6082
Fixes #6092
2019-05-03 03:16:58 -04:00
baseConfig := `
2021-03-19 06:05:17 -04:00
theme = "mytheme"
Add Hugo Modules
This commit implements Hugo Modules.
This is a broad subject, but some keywords include:
* A new `module` configuration section where you can import almost anything. You can configure both your own file mounts nd the file mounts of the modules you import. This is the new recommended way of configuring what you earlier put in `configDir`, `staticDir` etc. And it also allows you to mount folders in non-Hugo-projects, e.g. the `SCSS` folder in the Bootstrap GitHub project.
* A module consists of a set of mounts to the standard 7 component types in Hugo: `static`, `content`, `layouts`, `data`, `assets`, `i18n`, and `archetypes`. Yes, Theme Components can now include content, which should be very useful, especially in bigger multilingual projects.
* Modules not in your local file cache will be downloaded automatically and even "hot replaced" while the server is running.
* Hugo Modules supports and encourages semver versioned modules, and uses the minimal version selection algorithm to resolve versions.
* A new set of CLI commands are provided to manage all of this: `hugo mod init`, `hugo mod get`, `hugo mod graph`, `hugo mod tidy`, and `hugo mod vendor`.
All of the above is backed by Go Modules.
Fixes #5973
Fixes #5996
Fixes #6010
Fixes #5911
Fixes #5940
Fixes #6074
Fixes #6082
Fixes #6092
2019-05-03 03:16:58 -04:00
environment = "production"
enableGitInfo = true
intSlice = [ 5 , 7 , 9 ]
floatSlice = [ 3.14 , 5.19 ]
stringSlice = [ "a" , "b" ]
2021-06-09 04:58:18 -04:00
[ outputFormats ]
[ outputFormats . ofbase ]
mediaType = "text/plain"
2020-11-24 08:11:42 -05:00
[ params ]
2021-06-09 04:58:18 -04:00
paramWithNoEnvOverride = "nooverride"
2020-11-24 08:11:42 -05:00
[ params . api_config ]
api_key = "default_key"
another_key = "default another_key"
Add Hugo Modules
This commit implements Hugo Modules.
This is a broad subject, but some keywords include:
* A new `module` configuration section where you can import almost anything. You can configure both your own file mounts nd the file mounts of the modules you import. This is the new recommended way of configuring what you earlier put in `configDir`, `staticDir` etc. And it also allows you to mount folders in non-Hugo-projects, e.g. the `SCSS` folder in the Bootstrap GitHub project.
* A module consists of a set of mounts to the standard 7 component types in Hugo: `static`, `content`, `layouts`, `data`, `assets`, `i18n`, and `archetypes`. Yes, Theme Components can now include content, which should be very useful, especially in bigger multilingual projects.
* Modules not in your local file cache will be downloaded automatically and even "hot replaced" while the server is running.
* Hugo Modules supports and encourages semver versioned modules, and uses the minimal version selection algorithm to resolve versions.
* A new set of CLI commands are provided to manage all of this: `hugo mod init`, `hugo mod get`, `hugo mod graph`, `hugo mod tidy`, and `hugo mod vendor`.
All of the above is backed by Go Modules.
Fixes #5973
Fixes #5996
Fixes #6010
Fixes #5911
Fixes #5940
Fixes #6074
Fixes #6082
Fixes #6092
2019-05-03 03:16:58 -04:00
[ imaging ]
anchor = "smart"
quality = 75
`
2021-06-29 03:38:05 -04:00
newB := func ( t testing . TB ) * sitesBuilder {
b := newTestSitesBuilder ( t ) . WithConfigFile ( "toml" , baseConfig )
Add Hugo Modules
This commit implements Hugo Modules.
This is a broad subject, but some keywords include:
* A new `module` configuration section where you can import almost anything. You can configure both your own file mounts nd the file mounts of the modules you import. This is the new recommended way of configuring what you earlier put in `configDir`, `staticDir` etc. And it also allows you to mount folders in non-Hugo-projects, e.g. the `SCSS` folder in the Bootstrap GitHub project.
* A module consists of a set of mounts to the standard 7 component types in Hugo: `static`, `content`, `layouts`, `data`, `assets`, `i18n`, and `archetypes`. Yes, Theme Components can now include content, which should be very useful, especially in bigger multilingual projects.
* Modules not in your local file cache will be downloaded automatically and even "hot replaced" while the server is running.
* Hugo Modules supports and encourages semver versioned modules, and uses the minimal version selection algorithm to resolve versions.
* A new set of CLI commands are provided to manage all of this: `hugo mod init`, `hugo mod get`, `hugo mod graph`, `hugo mod tidy`, and `hugo mod vendor`.
All of the above is backed by Go Modules.
Fixes #5973
Fixes #5996
Fixes #6010
Fixes #5911
Fixes #5940
Fixes #6074
Fixes #6082
Fixes #6092
2019-05-03 03:16:58 -04:00
2021-06-29 03:38:05 -04:00
b . WithSourceFile ( "themes/mytheme/config.toml" , `
2021-03-19 06:05:17 -04:00
2021-06-09 04:58:18 -04:00
[ outputFormats ]
[ outputFormats . oftheme ]
mediaType = "text/plain"
[ outputFormats . ofbase ]
mediaType = "application/xml"
2021-03-19 06:05:17 -04:00
[ params ]
[ params . mytheme_section ]
theme_param = "themevalue"
2021-06-09 04:58:18 -04:00
theme_param_nooverride = "nooverride"
2021-03-19 06:05:17 -04:00
[ params . mytheme_section2 ]
theme_param = "themevalue2"
` )
2021-06-29 03:38:05 -04:00
return b
}
Add Hugo Modules
This commit implements Hugo Modules.
This is a broad subject, but some keywords include:
* A new `module` configuration section where you can import almost anything. You can configure both your own file mounts nd the file mounts of the modules you import. This is the new recommended way of configuring what you earlier put in `configDir`, `staticDir` etc. And it also allows you to mount folders in non-Hugo-projects, e.g. the `SCSS` folder in the Bootstrap GitHub project.
* A module consists of a set of mounts to the standard 7 component types in Hugo: `static`, `content`, `layouts`, `data`, `assets`, `i18n`, and `archetypes`. Yes, Theme Components can now include content, which should be very useful, especially in bigger multilingual projects.
* Modules not in your local file cache will be downloaded automatically and even "hot replaced" while the server is running.
* Hugo Modules supports and encourages semver versioned modules, and uses the minimal version selection algorithm to resolve versions.
* A new set of CLI commands are provided to manage all of this: `hugo mod init`, `hugo mod get`, `hugo mod graph`, `hugo mod tidy`, and `hugo mod vendor`.
All of the above is backed by Go Modules.
Fixes #5973
Fixes #5996
Fixes #6010
Fixes #5911
Fixes #5940
Fixes #6074
Fixes #6082
Fixes #6092
2019-05-03 03:16:58 -04:00
2021-06-29 03:38:05 -04:00
c . Run ( "Variations" , func ( c * qt . C ) {
b := newB ( c )
b . WithEnviron (
"HUGO_ENVIRONMENT" , "test" ,
"HUGO_NEW" , "new" , // key not in config.toml
"HUGO_ENABLEGITINFO" , "false" ,
"HUGO_IMAGING_ANCHOR" , "top" ,
"HUGO_IMAGING_RESAMPLEFILTER" , "CatmullRom" ,
"HUGO_STRINGSLICE" , ` ["c", "d"] ` ,
"HUGO_INTSLICE" , ` [5, 8, 9] ` ,
"HUGO_FLOATSLICE" , ` [5.32] ` ,
// Issue #7829
"HUGOxPARAMSxAPI_CONFIGxAPI_KEY" , "new_key" ,
// Delimiters are case sensitive.
"HUGOxPARAMSxAPI_CONFIGXANOTHER_KEY" , "another_key" ,
// Issue #8346
"HUGOxPARAMSxMYTHEME_SECTIONxTHEME_PARAM" , "themevalue_changed" ,
"HUGOxPARAMSxMYTHEME_SECTION2xTHEME_PARAM" , "themevalue2_changed" ,
"HUGO_PARAMS_EMPTY" , ` ` ,
"HUGO_PARAMS_HTML" , ` <a target="_blank" /> ` ,
// Issue #8618
"HUGO_SERVICES_GOOGLEANALYTICS_ID" , ` gaid ` ,
"HUGO_PARAMS_A_B_C" , "abc" ,
)
b . Build ( BuildCfg { } )
cfg := b . H . Cfg
s := b . H . Sites [ 0 ]
scfg := s . siteConfigConfig . Services
c . Assert ( cfg . Get ( "environment" ) , qt . Equals , "test" )
c . Assert ( cfg . GetBool ( "enablegitinfo" ) , qt . Equals , false )
c . Assert ( cfg . Get ( "new" ) , qt . Equals , "new" )
c . Assert ( cfg . Get ( "imaging.anchor" ) , qt . Equals , "top" )
c . Assert ( cfg . Get ( "imaging.quality" ) , qt . Equals , int64 ( 75 ) )
c . Assert ( cfg . Get ( "imaging.resamplefilter" ) , qt . Equals , "CatmullRom" )
2022-03-17 17:03:27 -04:00
c . Assert ( cfg . Get ( "stringSlice" ) , qt . DeepEquals , [ ] any { "c" , "d" } )
c . Assert ( cfg . Get ( "floatSlice" ) , qt . DeepEquals , [ ] any { 5.32 } )
c . Assert ( cfg . Get ( "intSlice" ) , qt . DeepEquals , [ ] any { 5 , 8 , 9 } )
2021-06-29 03:38:05 -04:00
c . Assert ( cfg . Get ( "params.api_config.api_key" ) , qt . Equals , "new_key" )
c . Assert ( cfg . Get ( "params.api_config.another_key" ) , qt . Equals , "default another_key" )
c . Assert ( cfg . Get ( "params.mytheme_section.theme_param" ) , qt . Equals , "themevalue_changed" )
c . Assert ( cfg . Get ( "params.mytheme_section.theme_param_nooverride" ) , qt . Equals , "nooverride" )
c . Assert ( cfg . Get ( "params.mytheme_section2.theme_param" ) , qt . Equals , "themevalue2_changed" )
c . Assert ( cfg . Get ( "params.empty" ) , qt . Equals , ` ` )
c . Assert ( cfg . Get ( "params.html" ) , qt . Equals , ` <a target="_blank" /> ` )
params := cfg . Get ( "params" ) . ( maps . Params )
c . Assert ( params [ "paramwithnoenvoverride" ] , qt . Equals , "nooverride" )
c . Assert ( cfg . Get ( "params.paramwithnoenvoverride" ) , qt . Equals , "nooverride" )
c . Assert ( scfg . GoogleAnalytics . ID , qt . Equals , "gaid" )
c . Assert ( cfg . Get ( "params.a.b" ) , qt . DeepEquals , maps . Params {
"c" : "abc" ,
} )
ofBase , _ := s . outputFormatsConfig . GetByName ( "ofbase" )
ofTheme , _ := s . outputFormatsConfig . GetByName ( "oftheme" )
c . Assert ( ofBase . MediaType , qt . Equals , media . TextType )
c . Assert ( ofTheme . MediaType , qt . Equals , media . TextType )
Add Hugo Modules
This commit implements Hugo Modules.
This is a broad subject, but some keywords include:
* A new `module` configuration section where you can import almost anything. You can configure both your own file mounts nd the file mounts of the modules you import. This is the new recommended way of configuring what you earlier put in `configDir`, `staticDir` etc. And it also allows you to mount folders in non-Hugo-projects, e.g. the `SCSS` folder in the Bootstrap GitHub project.
* A module consists of a set of mounts to the standard 7 component types in Hugo: `static`, `content`, `layouts`, `data`, `assets`, `i18n`, and `archetypes`. Yes, Theme Components can now include content, which should be very useful, especially in bigger multilingual projects.
* Modules not in your local file cache will be downloaded automatically and even "hot replaced" while the server is running.
* Hugo Modules supports and encourages semver versioned modules, and uses the minimal version selection algorithm to resolve versions.
* A new set of CLI commands are provided to manage all of this: `hugo mod init`, `hugo mod get`, `hugo mod graph`, `hugo mod tidy`, and `hugo mod vendor`.
All of the above is backed by Go Modules.
Fixes #5973
Fixes #5996
Fixes #6010
Fixes #5911
Fixes #5940
Fixes #6074
Fixes #6082
Fixes #6092
2019-05-03 03:16:58 -04:00
2021-06-09 04:58:18 -04:00
} )
2021-06-29 03:38:05 -04:00
// Issue #8709
c . Run ( "Set in string" , func ( c * qt . C ) {
b := newB ( c )
b . WithEnviron (
2021-10-22 07:12:09 -04:00
"HUGO_ENABLEGITINFO" , "false" ,
2021-06-29 03:38:05 -04:00
// imaging.anchor is a string, and it's not possible
// to set a child attribute.
"HUGO_IMAGING_ANCHOR_FOO" , "top" ,
)
b . Build ( BuildCfg { } )
cfg := b . H . Cfg
c . Assert ( cfg . Get ( "imaging.anchor" ) , qt . Equals , "smart" )
2021-06-09 04:58:18 -04:00
2021-06-29 03:38:05 -04:00
} )
2021-06-09 04:58:18 -04:00
Add Hugo Modules
This commit implements Hugo Modules.
This is a broad subject, but some keywords include:
* A new `module` configuration section where you can import almost anything. You can configure both your own file mounts nd the file mounts of the modules you import. This is the new recommended way of configuring what you earlier put in `configDir`, `staticDir` etc. And it also allows you to mount folders in non-Hugo-projects, e.g. the `SCSS` folder in the Bootstrap GitHub project.
* A module consists of a set of mounts to the standard 7 component types in Hugo: `static`, `content`, `layouts`, `data`, `assets`, `i18n`, and `archetypes`. Yes, Theme Components can now include content, which should be very useful, especially in bigger multilingual projects.
* Modules not in your local file cache will be downloaded automatically and even "hot replaced" while the server is running.
* Hugo Modules supports and encourages semver versioned modules, and uses the minimal version selection algorithm to resolve versions.
* A new set of CLI commands are provided to manage all of this: `hugo mod init`, `hugo mod get`, `hugo mod graph`, `hugo mod tidy`, and `hugo mod vendor`.
All of the above is backed by Go Modules.
Fixes #5973
Fixes #5996
Fixes #6010
Fixes #5911
Fixes #5940
Fixes #6074
Fixes #6082
Fixes #6092
2019-05-03 03:16:58 -04:00
}
2022-06-04 11:39:34 -04:00
func TestInvalidDefaultMarkdownHandler ( t * testing . T ) {
t . Parallel ( )
files := `
-- config . toml --
[ markup ]
defaultMarkdownHandler = ' blackfriday '
-- content / _index . md --
# # Foo
-- layouts / index . html --
{ { . Content } }
`
b , err := NewIntegrationTestBuilder (
IntegrationTestConfig {
T : t ,
TxtarString : files ,
} ,
) . BuildE ( )
b . Assert ( err , qt . IsNotNil )
b . Assert ( err . Error ( ) , qt . Contains , "Configured defaultMarkdownHandler \"blackfriday\" not found. Did you mean to use goldmark? Blackfriday was removed in Hugo v0.100.0." )
}