1
0
mirror of https://github.com/danog/gojekyll.git synced 2024-11-30 07:18:59 +01:00
gojekyll/site/write.go
2021-06-16 14:51:59 +08:00

115 lines
2.5 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package site
import (
"bytes"
"fmt"
"io"
"os"
"path/filepath"
"github.com/osteele/gojekyll/plugins"
"github.com/osteele/gojekyll/utils"
)
// Write cleans the destination and writes files into it.
// It sets TZ from the site config.
func (s *Site) Write() (int, error) {
if err := s.setTimeZone(); err != nil {
return 0, err
}
if err := s.ensureRendered(); err != nil {
return 0, err
}
if err := s.Clean(); err != nil {
return 0, err
}
return s.WriteFiles()
}
// WriteFiles writes output files.
func (s *Site) WriteFiles() (count int, err error) {
errs := make(chan error)
// without this, large sites run out of file descriptors
sem := make(chan bool, 20)
for i, n := 0, cap(sem); i < n; i++ {
sem <- true
}
for _, d := range s.OutputDocs() {
count++
go func(d Document) {
<-sem
errs <- s.WriteDoc(d)
sem <- true
}(d)
}
var errList []error
for i := 0; i < count; i++ {
if e := <-errs; e != nil {
errList = append(errList, e)
}
}
return count, combineErrors(errList)
}
// WriteDoc writes a document to the destination directory.
func (s *Site) WriteDoc(d Document) error {
from := d.Source()
rel := d.URL()
if !d.IsStatic() && filepath.Ext(rel) == "" {
rel = filepath.Join(rel, "index.html")
}
to := filepath.Join(s.DestDir(), rel)
if s.cfg.Verbose {
fmt.Println("create", to, "from", d.Source())
}
if s.cfg.DryRun {
// FIXME render the page, just don't write it
return nil
}
// nolint: gas
if err := os.MkdirAll(filepath.Dir(to), 0755); err != nil {
return err
}
switch {
case d.IsStatic():
return utils.CopyFileContents(to, from, 0644)
default:
return utils.VisitCreatedFile(to, func(w io.Writer) error {
return s.WriteDocument(w, d)
})
}
}
// WriteDocument writes the rendered document.
func (s *Site) WriteDocument(w io.Writer, d Document) error {
switch p := d.(type) {
case Page:
return s.WritePage(w, p)
default:
return d.Write(w)
}
}
// WritePage writes the rendered page. It is called as part of site.Write,
// but also, in an incremental build, to write a single page therefore it
// also ensures that all pages have been rendered before writing this one.
func (s *Site) WritePage(w io.Writer, p Page) error {
if err := s.ensureRendered(); err != nil {
return err
}
buf := new(bytes.Buffer)
if err := p.Write(buf); err != nil {
return err
}
b := buf.Bytes()
err := s.runHooks(func(p plugins.Plugin) (err error) {
b, err = p.PostRender(b)
return
})
if err != nil {
return err
}
_, err = w.Write(b)
return err
}