hugolib: Add disableKinds option

Fixes #2534
This commit is contained in:
Bjørn Erik Pedersen 2017-02-18 10:02:12 +01:00
parent e096917f87
commit 6d2281c8ea
8 changed files with 332 additions and 43 deletions

View file

@ -153,6 +153,7 @@ var (
themesDir string
source string
logI18nWarnings bool
disableKinds []string
)
// Execute adds all child commands to the root command HugoCmd and sets flags appropriately.
@ -239,6 +240,8 @@ func initHugoBuildCommonFlags(cmd *cobra.Command) {
cmd.Flags().BoolP("noChmod", "", false, "Don't sync permission mode of files")
cmd.Flags().BoolVarP(&logI18nWarnings, "i18n-warnings", "", false, "Print missing translations")
cmd.Flags().StringSliceVar(&disableKinds, "disableKinds", []string{}, "Disable different kind of pages (home, RSS etc.)")
// Set bash-completion.
// Each flag must first be defined before using the SetAnnotation() call.
cmd.Flags().SetAnnotation("source", cobra.BashCompSubdirsInDir, []string{})
@ -290,6 +293,10 @@ func InitializeConfig(subCmdVs ...*cobra.Command) (*deps.DepsCfg, error) {
c.initializeFlags(cmdV)
}
if len(disableKinds) > 0 {
c.Set("disableKinds", disableKinds)
}
logger, err := createLogger(cfg.Cfg)
if err != nil {
return cfg, err
@ -450,6 +457,7 @@ func (c *commandeer) initializeFlags(cmd *cobra.Command) {
for _, key := range flagKeys {
c.setValueFromFlag(cmd.Flags(), key)
}
}
func (c *commandeer) setValueFromFlag(flags *flag.FlagSet, key string) {

View file

@ -0,0 +1,216 @@
// Copyright 2016 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 (
"strings"
"testing"
"fmt"
"github.com/spf13/afero"
"github.com/spf13/hugo/deps"
"github.com/spf13/hugo/helpers"
"github.com/spf13/hugo/hugofs"
"github.com/stretchr/testify/require"
)
func TestDisableKindsNoneDisabled(t *testing.T) {
t.Parallel()
doTestDisableKinds(t)
}
func TestDisableKindsSomeDisabled(t *testing.T) {
t.Parallel()
doTestDisableKinds(t, KindSection, kind404)
}
func TestDisableKindsOneDisabled(t *testing.T) {
t.Parallel()
for _, kind := range allKinds {
doTestDisableKinds(t, kind)
}
}
func TestDisableKindsAllDisabled(t *testing.T) {
t.Parallel()
doTestDisableKinds(t, allKinds...)
}
func doTestDisableKinds(t *testing.T, disabled ...string) {
siteConfigTemplate := `
baseURL = "http://example.com/blog"
enableRobotsTXT = true
disableKinds = %s
paginate = 1
defaultContentLanguage = "en"
[Taxonomies]
tag = "tags"
category = "categories"
`
pageTemplate := `---
title: "%s"
tags:
%s
categories:
- Hugo
---
# Doc
`
mf := afero.NewMemMapFs()
disabledStr := "[]"
if len(disabled) > 0 {
disabledStr = strings.Replace(fmt.Sprintf("%#v", disabled), "[]string{", "[", -1)
disabledStr = strings.Replace(disabledStr, "}", "]", -1)
}
siteConfig := fmt.Sprintf(siteConfigTemplate, disabledStr)
writeToFs(t, mf, "config.toml", siteConfig)
cfg, err := LoadConfig(mf, "", "config.toml")
require.NoError(t, err)
fs := hugofs.NewFrom(mf, cfg)
th := testHelper{cfg, fs, t}
writeSource(t, fs, "layouts/index.html", "Home|{{ .Title }}|{{ .Content }}")
writeSource(t, fs, "layouts/_default/single.html", "Single|{{ .Title }}|{{ .Content }}")
writeSource(t, fs, "layouts/_default/list.html", "List|{{ .Title }}|{{ .Content }}")
writeSource(t, fs, "layouts/_default/terms.html", "Terms List|{{ .Title }}|{{ .Content }}")
writeSource(t, fs, "layouts/404.html", "Page Not Found")
writeSource(t, fs, "content/sect/p1.md", fmt.Sprintf(pageTemplate, "P1", "- tag1"))
writeNewContentFile(t, fs, "Category Terms", "2017-01-01", "content/categories/_index.md", 10)
writeNewContentFile(t, fs, "Tag1 List", "2017-01-01", "content/tags/tag1/_index.md", 10)
h, err := NewHugoSites(deps.DepsCfg{Fs: fs, Cfg: cfg})
require.NoError(t, err)
require.Len(t, h.Sites, 1)
err = h.Build(BuildCfg{})
require.NoError(t, err)
assertDisabledKinds(th, h.Sites[0], disabled...)
}
func assertDisabledKinds(th testHelper, s *Site, disabled ...string) {
assertDisabledKind(th,
func(isDisabled bool) bool {
if isDisabled {
return len(s.RegularPages) == 0
}
return len(s.RegularPages) > 0
}, disabled, KindPage, "public/sect/p1/index.html", "Single|P1")
assertDisabledKind(th,
func(isDisabled bool) bool {
p := s.getPage(KindHome)
if isDisabled {
return p == nil
}
return p != nil
}, disabled, KindHome, "public/index.html", "Home")
assertDisabledKind(th,
func(isDisabled bool) bool {
p := s.getPage(KindSection, "sect")
if isDisabled {
return p == nil
}
return p != nil
}, disabled, KindSection, "public/sect/index.html", "Sects")
assertDisabledKind(th,
func(isDisabled bool) bool {
p := s.getPage(KindTaxonomy, "tags", "tag1")
if isDisabled {
return p == nil
}
return p != nil
}, disabled, KindTaxonomy, "public/tags/tag1/index.html", "Tag1")
assertDisabledKind(th,
func(isDisabled bool) bool {
p := s.getPage(KindTaxonomyTerm, "tags")
if isDisabled {
return p == nil
}
return p != nil
}, disabled, KindTaxonomyTerm, "public/tags/index.html", "Tags")
assertDisabledKind(th,
func(isDisabled bool) bool {
p := s.getPage(KindTaxonomyTerm, "categories")
if isDisabled {
return p == nil
}
return p != nil
}, disabled, KindTaxonomyTerm, "public/categories/index.html", "Category Terms")
assertDisabledKind(th,
func(isDisabled bool) bool {
p := s.getPage(KindTaxonomy, "categories", "hugo")
if isDisabled {
return p == nil
}
return p != nil
}, disabled, KindTaxonomy, "public/categories/hugo/index.html", "Hugo")
// The below have no page in any collection.
assertDisabledKind(th, func(isDisabled bool) bool { return true }, disabled, kindRSS, "public/index.xml", "<link>")
assertDisabledKind(th, func(isDisabled bool) bool { return true }, disabled, kindSitemap, "public/sitemap.xml", "sitemap")
assertDisabledKind(th, func(isDisabled bool) bool { return true }, disabled, kindRobotsTXT, "public/robots.txt", "User-agent")
assertDisabledKind(th, func(isDisabled bool) bool { return true }, disabled, kind404, "public/404.html", "Page Not Found")
}
func assertDisabledKind(th testHelper, kindAssert func(bool) bool, disabled []string, kind, path, matcher string) {
isDisabled := stringSliceContains(kind, disabled...)
require.True(th.T, kindAssert(isDisabled), fmt.Sprintf("%s: %t", kind, isDisabled))
if kind == kindRSS && !isDisabled {
// If the home page is also disabled, there is not RSS to look for.
if stringSliceContains(KindHome, disabled...) {
isDisabled = true
}
}
if isDisabled {
// Path should not exist
fileExists, err := helpers.Exists(path, th.Fs.Destination)
require.False(th.T, fileExists)
require.NoError(th.T, err)
} else {
th.assertFileContent(path, matcher)
}
}
func stringSliceContains(k string, values ...string) bool {
for _, v := range values {
if k == v {
return true
}
}
return false
}

View file

@ -303,15 +303,17 @@ func (h *HugoSites) createMissingPages() error {
for _, s := range h.Sites {
// home pages
home := s.findPagesByKind(KindHome)
if len(home) > 1 {
panic("Too many homes")
}
if len(home) == 0 {
n := s.newHomePage()
s.Pages = append(s.Pages, n)
newPages = append(newPages, n)
if s.isEnabled(KindHome) {
// home pages
home := s.findPagesByKind(KindHome)
if len(home) > 1 {
panic("Too many homes")
}
if len(home) == 0 {
n := s.newHomePage()
s.Pages = append(s.Pages, n)
newPages = append(newPages, n)
}
}
// taxonomy list and terms pages
@ -339,43 +341,50 @@ func (h *HugoSites) createMissingPages() error {
break
}
}
if !foundTaxonomyPage {
n := s.newTaxonomyPage(plural, key)
s.Pages = append(s.Pages, n)
newPages = append(newPages, n)
if s.isEnabled(KindTaxonomy) {
if !foundTaxonomyPage {
n := s.newTaxonomyPage(plural, key)
s.Pages = append(s.Pages, n)
newPages = append(newPages, n)
}
}
if !foundTaxonomyTermsPage {
foundTaxonomyTermsPage = true
n := s.newTaxonomyTermsPage(plural)
s.Pages = append(s.Pages, n)
newPages = append(newPages, n)
if s.isEnabled(KindTaxonomyTerm) {
if !foundTaxonomyTermsPage {
foundTaxonomyTermsPage = true
n := s.newTaxonomyTermsPage(plural)
s.Pages = append(s.Pages, n)
newPages = append(newPages, n)
}
}
}
}
}
sectionPages := s.findPagesByKind(KindSection)
if len(sectionPages) < len(s.Sections) {
for name, section := range s.Sections {
// A section may be created for the root content folder if a
// content file is placed there.
// We cannot create a section node for that, because
// that would overwrite the home page.
if name == "" {
continue
}
foundSection := false
for _, sectionPage := range sectionPages {
if sectionPage.sections[0] == name {
foundSection = true
break
if s.isEnabled(KindSection) {
sectionPages := s.findPagesByKind(KindSection)
if len(sectionPages) < len(s.Sections) {
for name, section := range s.Sections {
// A section may be created for the root content folder if a
// content file is placed there.
// We cannot create a section node for that, because
// that would overwrite the home page.
if name == "" {
continue
}
foundSection := false
for _, sectionPage := range sectionPages {
if sectionPage.sections[0] == name {
foundSection = true
break
}
}
if !foundSection {
n := s.newSectionPage(name, section)
s.Pages = append(s.Pages, n)
newPages = append(newPages, n)
}
}
if !foundSection {
n := s.newSectionPage(name, section)
s.Pages = append(s.Pages, n)
newPages = append(newPages, n)
}
}
}
@ -429,6 +438,14 @@ func (h *HugoSites) setupTranslations() {
panic("Page language missing: " + p.Title)
}
if p.Kind == kindUnknown {
p.Kind = p.s.kindFromSections(p.sections)
}
if !p.s.isEnabled(p.Kind) {
continue
}
shouldBuild := p.shouldBuild()
for i, site := range h.Sites {

View file

@ -136,6 +136,12 @@ func (h *HugoSites) process(config *BuildCfg, events ...fsnotify.Event) error {
}
func (h *HugoSites) assemble(config *BuildCfg) error {
if config.whatChanged.source {
for _, s := range h.Sites {
s.createTaxonomiesEntries()
}
}
// TODO(bep) we could probably wait and do this in one go later
h.setupTranslations()

View file

@ -218,6 +218,7 @@ func doTestMultiSitesBuild(t *testing.T, configTemplate, configSuffix string) {
// Check site config
for _, s := range sites.Sites {
require.True(t, s.Info.defaultContentLanguageInSubdir, s.Info.Title)
require.NotNil(t, s.disabledKinds)
}
enSite := sites.Sites[0]

View file

@ -42,7 +42,8 @@ import (
)
var (
cjk = regexp.MustCompile(`\p{Han}|\p{Hangul}|\p{Hiragana}|\p{Katakana}`)
cjk = regexp.MustCompile(`\p{Han}|\p{Hangul}|\p{Hiragana}|\p{Katakana}`)
allKinds = []string{KindHome, KindSection, KindTaxonomy, KindTaxonomyTerm, kindRSS, kindSitemap, kindRobotsTXT, kind404}
)
const (

View file

@ -105,13 +105,22 @@ type Site struct {
Data map[string]interface{}
Language *helpers.Language
disabledKinds map[string]bool
// Logger etc.
*deps.Deps `json:"-"`
}
func (s *Site) isEnabled(kind string) bool {
if kind == kindUnknown {
panic("Unknown kind")
}
return !s.disabledKinds[kind]
}
// reset returns a new Site prepared for rebuild.
func (s *Site) reset() *Site {
return &Site{Deps: s.Deps, Language: s.Language, owner: s.owner, PageCollections: newPageCollections()}
return &Site{Deps: s.Deps, disabledKinds: s.disabledKinds, Language: s.Language, owner: s.owner, PageCollections: newPageCollections()}
}
// newSite creates a new site with the given configuration.
@ -122,7 +131,12 @@ func newSite(cfg deps.DepsCfg) (*Site, error) {
cfg.Language = helpers.NewDefaultLanguage(cfg.Cfg)
}
s := &Site{PageCollections: c, Language: cfg.Language}
disabledKinds := make(map[string]bool)
for _, disabled := range cast.ToStringSlice(cfg.Language.Get("disableKinds")) {
disabledKinds[disabled] = true
}
s := &Site{PageCollections: c, Language: cfg.Language, disabledKinds: disabledKinds}
s.Info = newSiteInfo(siteBuilderCfg{s: s, pageCollections: c, language: s.Language})
return s, nil
@ -820,6 +834,7 @@ func (s *Site) setupPrevNext() {
}
func (s *Site) render() (err error) {
if err = s.preparePages(); err != nil {
return
}
@ -1493,8 +1508,18 @@ func (s *Site) getTaxonomyKey(key string) string {
}
return s.PathSpec.MakePathSanitized(key)
}
func (s *Site) assembleTaxonomies() {
// We need to create the top level taxonomy early in the build process
// to be able to determine the page Kind correctly.
func (s *Site) createTaxonomiesEntries() {
s.Taxonomies = make(TaxonomyList)
taxonomies := s.Language.GetStringMapString("taxonomies")
for _, plural := range taxonomies {
s.Taxonomies[plural] = make(Taxonomy)
}
}
func (s *Site) assembleTaxonomies() {
s.taxonomiesPluralSingular = make(map[string]string)
s.taxonomiesOrigKey = make(map[string]string)
@ -1503,7 +1528,6 @@ func (s *Site) assembleTaxonomies() {
s.Log.INFO.Printf("found taxonomies: %#v\n", taxonomies)
for singular, plural := range taxonomies {
s.Taxonomies[plural] = make(Taxonomy)
s.taxonomiesPluralSingular[plural] = singular
for _, p := range s.Pages {

View file

@ -130,6 +130,10 @@ func (s *Site) renderPaginator(p *Page) error {
func (s *Site) renderRSS(p *Page) error {
if !s.isEnabled(kindRSS) {
return nil
}
if s.Cfg.GetBool("disableRSS") {
return nil
}
@ -167,6 +171,10 @@ func (s *Site) renderRSS(p *Page) error {
}
func (s *Site) render404() error {
if !s.isEnabled(kind404) {
return nil
}
if s.Cfg.GetBool("disable404") {
return nil
}
@ -184,6 +192,10 @@ func (s *Site) render404() error {
}
func (s *Site) renderSitemap() error {
if !s.isEnabled(kindSitemap) {
return nil
}
if s.Cfg.GetBool("disableSitemap") {
return nil
}
@ -227,6 +239,10 @@ func (s *Site) renderSitemap() error {
}
func (s *Site) renderRobotsTXT() error {
if !s.isEnabled(kindRobotsTXT) {
return nil
}
if !s.Cfg.GetBool("enableRobotsTXT") {
return nil
}