ref: a49bf8707b7f247f1c83b8087abd02a84d2ba136
parent: d76e5f36b412eb68be3cd5a53bacc099ec46280f
author: Bjørn Erik Pedersen <[email protected]>
date: Thu Mar 16 06:04:30 EDT 2017
hugolib: Remove siteWriter
--- a/hugolib/alias.go
+++ b/hugolib/alias.go
@@ -41,14 +41,13 @@
}
type aliasHandler struct {
- Templates *template.Template
- log *jww.Notepad
- allowRoot bool
- publishDir string
+ Templates *template.Template
+ log *jww.Notepad
+ allowRoot bool
}
-func newAliasHandler(t *template.Template, l *jww.Notepad, allowRoot bool, publishDir string) aliasHandler {
- return aliasHandler{t, l, allowRoot, publishDir}
+func newAliasHandler(t *template.Template, l *jww.Notepad, allowRoot bool) aliasHandler {
+ return aliasHandler{t, l, allowRoot}
}
func (a aliasHandler) renderAlias(isXHTML bool, permalink string, page *Page) (io.Reader, error) {
@@ -85,7 +84,7 @@
func (s *Site) publishDestAlias(allowRoot bool, path, permalink string, p *Page) (err error) {
- handler := newAliasHandler(s.Tmpl.Lookup("alias.html"), s.Log, allowRoot, s.absPublishDir())
+ handler := newAliasHandler(s.Tmpl.Lookup("alias.html"), s.Log, allowRoot)
isXHTML := strings.HasSuffix(path, ".xhtml")
@@ -183,5 +182,5 @@
a.log.INFO.Printf("Alias \"%s\" translated to \"%s\"\n", originalAlias, alias)
}
- return filepath.Join(a.publishDir, alias), nil
+ return alias, nil
}
--- a/hugolib/alias_test.go
+++ b/hugolib/alias_test.go
@@ -15,6 +15,7 @@
import (
"path/filepath"
+ "runtime"
"testing"
"github.com/spf13/hugo/deps"
@@ -72,4 +73,46 @@
th.assertFileContent(filepath.Join("public", "page", "index.html"), "For some moments the old man")
// the alias redirector
th.assertFileContent(filepath.Join("public", "foo", "bar", "index.html"), "ALIASTEMPLATE")
+}
+
+func TestTargetPathHTMLRedirectAlias(t *testing.T) {
+ h := newAliasHandler(nil, newErrorLogger(), false)
+
+ errIsNilForThisOS := runtime.GOOS != "windows"
+
+ tests := []struct {
+ value string
+ expected string
+ errIsNil bool
+ }{
+ {"", "", false},
+ {"s", filepath.FromSlash("s/index.html"), true},
+ {"/", "", false},
+ {"alias 1", filepath.FromSlash("alias 1/index.html"), true},
+ {"alias 2/", filepath.FromSlash("alias 2/index.html"), true},
+ {"alias 3.html", "alias 3.html", true},
+ {"alias4.html", "alias4.html", true},
+ {"/alias 5.html", "alias 5.html", true},
+ {"/трям.html", "трям.html", true},
+ {"../../../../tmp/passwd", "", false},
+ {"/foo/../../../../tmp/passwd", filepath.FromSlash("tmp/passwd/index.html"), true},
+ {"foo/../../../../tmp/passwd", "", false},
+ {"C:\\Windows", filepath.FromSlash("C:\\Windows/index.html"), errIsNilForThisOS},
+ {"/trailing-space /", filepath.FromSlash("trailing-space /index.html"), errIsNilForThisOS},
+ {"/trailing-period./", filepath.FromSlash("trailing-period./index.html"), errIsNilForThisOS},
+ {"/tab\tseparated/", filepath.FromSlash("tab\tseparated/index.html"), errIsNilForThisOS},
+ {"/chrome/?p=help&ctx=keyboard#topic=3227046", filepath.FromSlash("chrome/?p=help&ctx=keyboard#topic=3227046/index.html"), errIsNilForThisOS},
+ {"/LPT1/Printer/", filepath.FromSlash("LPT1/Printer/index.html"), errIsNilForThisOS},
+ }
+
+ for _, test := range tests {
+ path, err := h.targetPathAlias(test.value)
+ if (err == nil) != test.errIsNil {
+ t.Errorf("Expected err == nil => %t, got: %t. err: %s", test.errIsNil, err == nil, err)
+ continue
+ }
+ if err == nil && path != test.expected {
+ t.Errorf("Expected: \"%s\", got: \"%s\"", test.expected, path)
+ }
+ }
}
--- a/hugolib/handler_file.go
+++ b/hugolib/handler_file.go
@@ -39,7 +39,10 @@
func (h defaultHandler) Extensions() []string { return []string{"*"} }
func (h defaultHandler) FileConvert(f *source.File, s *Site) HandledResult {
- s.w.writeDestFile(f.Path(), f.Contents)
+ err := s.publish(f.Path(), f.Contents)
+ if err != nil {
+ return HandledResult{err: err}
+ }
return HandledResult{file: f}
}
@@ -48,6 +51,9 @@
func (h cssHandler) Extensions() []string { return []string{"css"} }
func (h cssHandler) FileConvert(f *source.File, s *Site) HandledResult {
x := cssmin.Minify(f.Bytes())
- s.w.writeDestFile(f.Path(), bytes.NewReader(x))
+ err := s.publish(f.Path(), bytes.NewReader(x))
+ if err != nil {
+ return HandledResult{err: err}
+ }
return HandledResult{file: f}
}
--- a/hugolib/hugo_sites_build.go
+++ b/hugolib/hugo_sites_build.go
@@ -200,8 +200,6 @@
func (h *HugoSites) render(config *BuildCfg) error {
if !config.SkipRender {
for _, s := range h.Sites {
- s.initSiteWriter()
-
if err := s.render(); err != nil {
return err
}
--- a/hugolib/site.go
+++ b/hugolib/site.go
@@ -98,9 +98,6 @@
Menus Menus
timer *nitro.B
- // This is not a pointer by design.
- w siteWriter
-
layoutHandler *output.LayoutHandler
draftCount int
@@ -1215,8 +1212,6 @@
numWorkers := getGoMaxProcs() * 4
wg := &sync.WaitGroup{}
- s.initSiteWriter()
-
for i := 0; i < numWorkers; i++ {
wg.Add(2)
go fileConverter(s, fileConvChan, results, wg)
@@ -1802,11 +1797,11 @@
transformer := transform.NewChain(transform.AbsURLInXML)
transformer.Apply(outBuffer, renderBuffer, path)
- return s.w.writeDestFile(dest, outBuffer)
+ return s.publish(dest, outBuffer)
}
-func (s *Site) renderAndWritePage(f output.Format, name string, dest string, d interface{}, layouts ...string) error {
+func (s *Site) renderAndWritePage(name string, dest string, d interface{}, layouts ...string) error {
renderBuffer := bp.GetBuffer()
defer bp.PutBuffer(renderBuffer)
@@ -1819,9 +1814,6 @@
outBuffer := bp.GetBuffer()
defer bp.PutBuffer(outBuffer)
- // Note: this is not a pointer, as we may mutate the state below.
- w := s.w
-
transformLinks := transform.NewEmptyTransforms()
if s.Info.relativeURLs || s.Info.canonifyURLs {
@@ -1878,7 +1870,7 @@
}
- if err = w.writeDestPage(f, dest, outBuffer); err != nil {
+ if err = s.publish(dest, outBuffer); err != nil {
return err
}
@@ -1928,6 +1920,7 @@
}
func (s *Site) publish(path string, r io.Reader) (err error) {
+ path = filepath.Join(s.absPublishDir(), path)
return helpers.WriteToDisk(path, r, s.Fs.Destination)
}
@@ -1936,20 +1929,6 @@
return s.Language.Lang
}
return ""
-}
-
-func (s *Site) initSiteWriter() {
- if s.Fs == nil {
- panic("Must have Fs")
- }
- s.w = siteWriter{
- langDir: s.langDir(),
- publishDir: s.absPublishDir(),
- uglyURLs: s.Cfg.GetBool("uglyURLs"),
- relativeURLs: s.Info.relativeURLs,
- fs: s.Fs,
- log: s.Log,
- }
}
func (s *Site) draftStats() string {
--- a/hugolib/site_render.go
+++ b/hugolib/site_render.go
@@ -19,8 +19,6 @@
"sync"
"time"
- "github.com/spf13/hugo/output"
-
bp "github.com/spf13/hugo/bufferpool"
)
@@ -100,7 +98,7 @@
s.Log.DEBUG.Printf("Render %s to %q with layouts %q", pageOutput.Kind, targetPath, layouts)
- if err := s.renderAndWritePage(outFormat, "page "+pageOutput.FullFilePath(), targetPath, pageOutput, layouts...); err != nil {
+ if err := s.renderAndWritePage("page "+pageOutput.FullFilePath(), targetPath, pageOutput, layouts...); err != nil {
results <- err
}
@@ -149,7 +147,8 @@
addend := fmt.Sprintf("/%s/%d", paginatePath, pageNumber)
targetPath, _ := p.targetPath(addend)
- if err := s.renderAndWritePage(p.outputFormat, pagerNode.Title,
+ if err := s.renderAndWritePage(
+ pagerNode.Title,
targetPath, pagerNode, p.layouts()...); err != nil {
return err
}
@@ -219,7 +218,7 @@
nfLayouts := []string{"404.html"}
- return s.renderAndWritePage(output.HTMLType, "404 page", "404.html", p, s.appendThemeTemplates(nfLayouts)...)
+ return s.renderAndWritePage("404 page", "404.html", p, s.appendThemeTemplates(nfLayouts)...)
}
@@ -289,7 +288,7 @@
err := s.renderForLayouts("robots", n, outBuffer, s.appendThemeTemplates(rLayouts)...)
if err == nil {
- err = s.w.writeDestFile("robots.txt", outBuffer)
+ err = s.publish("robots.txt", outBuffer)
}
return err
--- a/hugolib/site_writer.go
+++ /dev/null
@@ -1,129 +1,0 @@
-// Copyright 2017 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 (
- "io"
- "path/filepath"
-
- "github.com/spf13/hugo/helpers"
- "github.com/spf13/hugo/hugofs"
- "github.com/spf13/hugo/output"
- jww "github.com/spf13/jwalterweatherman"
-)
-
-// We may find some abstractions/interface(s) here once we star with
-// "Multiple Output Formats".
-type siteWriter struct {
- langDir string
- publishDir string
- relativeURLs bool
- uglyURLs bool
- allowRoot bool // For aliases
-
- fs *hugofs.Fs
-
- log *jww.Notepad
-}
-
-func (w siteWriter) targetPathPage(f output.Format, src string) (string, error) {
- dir, err := w.baseTargetPathPage(f, src)
- if err != nil {
- return "", err
- }
- if w.publishDir != "" {
- dir = filepath.Join(w.publishDir, dir)
- }
- return dir, nil
-}
-
-func (w siteWriter) baseTargetPathPage(f output.Format, src string) (string, error) {
- if src == helpers.FilePathSeparator {
- return "index.html", nil
- }
-
- // The anatomy of a target path:
- // langDir
- // BaseName
- // Suffix
- // ROOT?
- // dir
- // name
-
- dir, file := filepath.Split(src)
- isRoot := dir == ""
- ext := extension(filepath.Ext(file))
- name := filename(file)
-
- if w.langDir != "" && dir == helpers.FilePathSeparator && name == w.langDir {
- return filepath.Join(dir, name, "index"+ext), nil
- }
-
- if w.uglyURLs || file == "index.html" || (isRoot && file == "404.html") {
- return filepath.Join(dir, name+ext), nil
- }
-
- dir = filepath.Join(dir, name, "index"+ext)
-
- return dir, nil
-
-}
-
-func (w siteWriter) targetPathFile(src string) (string, error) {
- return filepath.Join(w.publishDir, filepath.FromSlash(src)), nil
-}
-
-func extension(ext string) string {
- switch ext {
- case ".md", ".rst":
- return ".html"
- }
-
- if ext != "" {
- return ext
- }
-
- return ".html"
-}
-
-func filename(f string) string {
- ext := filepath.Ext(f)
- if ext == "" {
- return f
- }
-
- return f[:len(f)-len(ext)]
-}
-
-func (w siteWriter) writeDestPage(f output.Format, path string, reader io.Reader) error {
- w.log.DEBUG.Println("creating page:", path)
- path, _ = w.targetPathFile(path)
- // TODO(bep) output remove this file ... targetPath, err := w.targetPathPage(tp, path)
-
- return w.publish(path, reader)
-}
-
-func (w siteWriter) writeDestFile(path string, r io.Reader) (err error) {
- w.log.DEBUG.Println("creating file:", path)
- targetPath, err := w.targetPathFile(path)
- if err != nil {
- return err
- }
- return w.publish(targetPath, r)
-}
-
-func (w siteWriter) publish(path string, r io.Reader) (err error) {
-
- return helpers.WriteToDisk(path, r, w.fs.Destination)
-}
--- a/hugolib/site_writer_test.go
+++ /dev/null
@@ -1,151 +1,0 @@
-// Copyright 2017 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 (
- "path/filepath"
- "runtime"
- "testing"
-
- "github.com/spf13/hugo/output"
-)
-
-func TestTargetPathHTMLRedirectAlias(t *testing.T) {
- h := newAliasHandler(nil, newErrorLogger(), false, "")
-
- errIsNilForThisOS := runtime.GOOS != "windows"
-
- tests := []struct {
- value string
- expected string
- errIsNil bool
- }{
- {"", "", false},
- {"s", filepath.FromSlash("s/index.html"), true},
- {"/", "", false},
- {"alias 1", filepath.FromSlash("alias 1/index.html"), true},
- {"alias 2/", filepath.FromSlash("alias 2/index.html"), true},
- {"alias 3.html", "alias 3.html", true},
- {"alias4.html", "alias4.html", true},
- {"/alias 5.html", "alias 5.html", true},
- {"/трям.html", "трям.html", true},
- {"../../../../tmp/passwd", "", false},
- {"/foo/../../../../tmp/passwd", filepath.FromSlash("tmp/passwd/index.html"), true},
- {"foo/../../../../tmp/passwd", "", false},
- {"C:\\Windows", filepath.FromSlash("C:\\Windows/index.html"), errIsNilForThisOS},
- {"/trailing-space /", filepath.FromSlash("trailing-space /index.html"), errIsNilForThisOS},
- {"/trailing-period./", filepath.FromSlash("trailing-period./index.html"), errIsNilForThisOS},
- {"/tab\tseparated/", filepath.FromSlash("tab\tseparated/index.html"), errIsNilForThisOS},
- {"/chrome/?p=help&ctx=keyboard#topic=3227046", filepath.FromSlash("chrome/?p=help&ctx=keyboard#topic=3227046/index.html"), errIsNilForThisOS},
- {"/LPT1/Printer/", filepath.FromSlash("LPT1/Printer/index.html"), errIsNilForThisOS},
- }
-
- for _, test := range tests {
- path, err := h.targetPathAlias(test.value)
- if (err == nil) != test.errIsNil {
- t.Errorf("Expected err == nil => %t, got: %t. err: %s", test.errIsNil, err == nil, err)
- continue
- }
- if err == nil && path != test.expected {
- t.Errorf("Expected: \"%s\", got: \"%s\"", test.expected, path)
- }
- }
-}
-
-func TestTargetPathPage(t *testing.T) {
- w := siteWriter{log: newErrorLogger()}
-
- tests := []struct {
- content string
- expected string
- }{
- {"/", "index.html"},
- {"index.html", "index.html"},
- {"bar/index.html", "bar/index.html"},
- {"foo", "foo/index.html"},
- {"foo.html", "foo/index.html"},
- {"foo.xhtml", "foo/index.xhtml"},
- {"section", "section/index.html"},
- {"section/", "section/index.html"},
- {"section/foo", "section/foo/index.html"},
- {"section/foo.html", "section/foo/index.html"},
- {"section/foo.rss", "section/foo/index.rss"},
- }
-
- for _, test := range tests {
- dest, err := w.targetPathPage(output.HTMLType, filepath.FromSlash(test.content))
- expected := filepath.FromSlash(test.expected)
- if err != nil {
- t.Fatalf("Translate returned and unexpected err: %s", err)
- }
-
- if dest != expected {
- t.Errorf("Translate expected return: %s, got: %s", expected, dest)
- }
- }
-}
-
-func TestTargetPathPageBase(t *testing.T) {
- w := siteWriter{log: newErrorLogger()}
-
- tests := []struct {
- content string
- expected string
- }{
- {"/", "a/base/index.html"},
- }
-
- for _, test := range tests {
-
- for _, pd := range []string{"a/base", "a/base/"} {
- w.publishDir = pd
- dest, err := w.targetPathPage(output.HTMLType, test.content)
- if err != nil {
- t.Fatalf("Translated returned and err: %s", err)
- }
-
- if dest != filepath.FromSlash(test.expected) {
- t.Errorf("Translate expected: %s, got: %s", test.expected, dest)
- }
- }
- }
-}
-
-// TODO(bep) output
-func _TestTargetPathUglyURLs(t *testing.T) {
- w := siteWriter{log: newErrorLogger(), uglyURLs: true}
-
- tests := []struct {
- outFormat output.Format
- content string
- expected string
- }{
- {output.HTMLType, "foo.html", "foo.html"},
- {output.HTMLType, "/", "index.html"},
- {output.HTMLType, "section", "section.html"},
- {output.HTMLType, "index.html", "index.html"},
- {output.JSONType, "section", "section.json"},
- }
-
- for i, test := range tests {
- dest, err := w.targetPathPage(test.outFormat, filepath.FromSlash(test.content))
- if err != nil {
- t.Fatalf(" [%d] targetPathPage returned an unexpected err: %s", i, err)
- }
-
- if dest != test.expected {
- t.Errorf("[%d] targetPathPage expected return: %s, got: %s", i, test.expected, dest)
- }
- }
-}