URI: 
       hugolib: Add disableKinds option - hugo - [fork] hugo port for 9front
  HTML git clone git@git.drkhsh.at/hugo.git
   DIR Log
   DIR Files
   DIR Refs
   DIR Submodules
   DIR README
   DIR LICENSE
       ---
   DIR commit 6d2281c8ead70ac07122027c989807c0aa1a7722
   DIR parent e096917f8738404696627a279277820dbe3a8f94
  HTML Author: Bjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>
       Date:   Sat, 18 Feb 2017 10:02:12 +0100
       
       hugolib: Add disableKinds option
       
       Fixes #2534
       
       Diffstat:
         M commands/hugo.go                    |       8 ++++++++
         A hugolib/disableKinds_test.go        |     216 +++++++++++++++++++++++++++++++
         M hugolib/hugo_sites.go               |      93 ++++++++++++++++++-------------
         M hugolib/hugo_sites_build.go         |       6 ++++++
         M hugolib/hugo_sites_build_test.go    |       1 +
         M hugolib/page.go                     |       3 ++-
         M hugolib/site.go                     |      32 +++++++++++++++++++++++++++----
         M hugolib/site_render.go              |      16 ++++++++++++++++
       
       8 files changed, 332 insertions(+), 43 deletions(-)
       ---
   DIR diff --git a/commands/hugo.go b/commands/hugo.go
       @@ -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) {
   DIR diff --git a/hugolib/disableKinds_test.go b/hugolib/disableKinds_test.go
       @@ -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
       +}
   DIR diff --git a/hugolib/hugo_sites.go b/hugolib/hugo_sites.go
       @@ -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 {
   DIR diff --git a/hugolib/hugo_sites_build.go b/hugolib/hugo_sites_build.go
       @@ -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()
        
   DIR diff --git a/hugolib/hugo_sites_build_test.go b/hugolib/hugo_sites_build_test.go
       @@ -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]
   DIR diff --git a/hugolib/page.go b/hugolib/page.go
       @@ -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 (
   DIR diff --git a/hugolib/site.go b/hugolib/site.go
       @@ -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 {
   DIR diff --git a/hugolib/site_render.go b/hugolib/site_render.go
       @@ -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
                }