Change File to interface

This commit is contained in:
Alex Yatskov 2024-02-19 16:26:41 -08:00
parent 55ed95ddbb
commit 2f95fdba2d
29 changed files with 181 additions and 172 deletions

View File

@ -15,7 +15,7 @@ type cache struct {
baseDir string baseDir string
} }
func (self *cache) retrieveFile(context *Context, outputPath string, inputFiles []*File) (*File, error) { func (self *cache) retrieveFile(context *Context, outputPath string, inputFiles []File) (File, error) {
cachePath, err := self.buildCachePath(context, outputPath, inputFiles) cachePath, err := self.buildCachePath(context, outputPath, inputFiles)
if err != nil { if err != nil {
return nil, err return nil, err
@ -33,7 +33,7 @@ func (self *cache) retrieveFile(context *Context, outputPath string, inputFiles
return outputFile, nil return outputFile, nil
} }
func (self *cache) storeFile(context *Context, outputFile *File, inputFiles []*File) error { func (self *cache) storeFile(context *Context, outputFile File, inputFiles []File) error {
cachePath, err := self.buildCachePath(context, outputFile.Path(), inputFiles) cachePath, err := self.buildCachePath(context, outputFile.Path(), inputFiles)
if err != nil { if err != nil {
return err return err
@ -69,7 +69,7 @@ func (self *cache) storeFile(context *Context, outputFile *File, inputFiles []*F
return nil return nil
} }
func (self *cache) buildCachePath(context *Context, outputPath string, inputFiles []*File) (string, error) { func (self *cache) buildCachePath(context *Context, outputPath string, inputFiles []File) (string, error) {
hasher := crc32.NewIEEE() hasher := crc32.NewIEEE()
hasher.Write([]byte(outputPath)) hasher.Write([]byte(outputPath))

View File

@ -24,20 +24,20 @@ type Context struct {
threads int threads int
index int index int
filesIn chan *File filesIn chan File
filesOut chan *File filesOut chan File
} }
// CreateFileFrom data creates a new file instance from the provided data buffer. // CreateFileFrom data creates a new file instance from the provided data buffer.
func (self *Context) CreateFileFromReader(sourcePath string, reader io.Reader) (*File, error) { func (self *Context) CreateFileFromReader(sourcePath string, reader io.Reader) (File, error) {
data, err := io.ReadAll(reader) data, err := io.ReadAll(reader)
if err != nil { if err != nil {
return nil, err return nil, err
} }
file := &File{ file := &rawFile{
relPath: sourcePath, relPath: sourcePath,
props: make(map[string]Prop), props: make(map[string]FileProp),
modTime: time.Now(), modTime: time.Now(),
size: int64(len(data)), size: int64(len(data)),
reader: bytes.NewReader(data), reader: bytes.NewReader(data),
@ -48,7 +48,7 @@ func (self *Context) CreateFileFromReader(sourcePath string, reader io.Reader) (
} }
// CreateFileFromAsset creates a new file instance from the provided file path. // CreateFileFromAsset creates a new file instance from the provided file path.
func (self *Context) CreateFileFromAsset(sourcePath, dataPath string) (*File, error) { func (self *Context) CreateFileFromAsset(sourcePath, dataPath string) (File, error) {
if filepath.IsAbs(sourcePath) { if filepath.IsAbs(sourcePath) {
return nil, errors.New("source paths must be relative") return nil, errors.New("source paths must be relative")
} }
@ -65,9 +65,9 @@ func (self *Context) CreateFileFromAsset(sourcePath, dataPath string) (*File, er
return nil, errors.New("assets must be files") return nil, errors.New("assets must be files")
} }
file := &File{ file := &rawFile{
relPath: sourcePath, relPath: sourcePath,
props: make(map[string]Prop), props: make(map[string]FileProp),
modTime: info.ModTime(), modTime: info.ModTime(),
size: info.Size(), size: info.Size(),
dataPath: dataPath, dataPath: dataPath,
@ -78,14 +78,14 @@ func (self *Context) CreateFileFromAsset(sourcePath, dataPath string) (*File, er
} }
// DispatchFile causes the file to get passed to the next link in the chain. // DispatchFile causes the file to get passed to the next link in the chain.
func (self *Context) DispatchFile(file *File) { func (self *Context) DispatchFile(file File) {
self.filesOut <- file self.filesOut <- file
} }
// DispatchAndCacheFile caches the file data (excluding the metadata), taking // DispatchAndCacheFile caches the file data (excluding the metadata), taking
// dependencies on any input files that are needed to generate it, and then // dependencies on any input files that are needed to generate it, and then
// passes it to the next link in the chain. // passes it to the next link in the chain.
func (self *Context) DispatchAndCacheFile(outputFile *File, inputFiles ...*File) { func (self *Context) DispatchAndCacheFile(outputFile File, inputFiles ...File) {
if self.goldsmith.cache != nil { if self.goldsmith.cache != nil {
self.goldsmith.cache.storeFile(self, outputFile, inputFiles) self.goldsmith.cache.storeFile(self, outputFile, inputFiles)
} }
@ -96,8 +96,8 @@ func (self *Context) DispatchAndCacheFile(outputFile *File, inputFiles ...*File)
// RetrieveCachedFile looks up file data (excluding the metadata), given an // RetrieveCachedFile looks up file data (excluding the metadata), given an
// output path and any input files that are needed to generate it. The function // output path and any input files that are needed to generate it. The function
// will return nil if the desired file is not found in the cache. // will return nil if the desired file is not found in the cache.
func (self *Context) RetrieveCachedFile(outputPath string, inputFiles ...*File) *File { func (self *Context) RetrieveCachedFile(outputPath string, inputFiles ...File) File {
var outputFile *File var outputFile File
if self.goldsmith.cache != nil { if self.goldsmith.cache != nil {
outputFile, _ = self.goldsmith.cache.retrieveFile(self, outputPath, inputFiles) outputFile, _ = self.goldsmith.cache.retrieveFile(self, outputPath, inputFiles)
} }

131
file.go
View File

@ -9,15 +9,9 @@ import (
"time" "time"
) )
type ( type rawFile struct {
Prop any
PropMap map[string]Prop
)
// File represents in-memory or on-disk files in a chain.
type File struct {
relPath string relPath string
props map[string]Prop props map[string]FileProp
modTime time.Time modTime time.Time
size int64 size int64
@ -27,8 +21,23 @@ type File struct {
index int index int
} }
// Rename modifies the file path relative to the source directory. func (self *rawFile) Path() string {
func (self *File) Rename(path string) error { return filepath.ToSlash(self.relPath)
}
func (self *rawFile) Dir() string {
return filepath.ToSlash(filepath.Dir(self.relPath))
}
func (self *rawFile) Name() string {
return filepath.Base(self.relPath)
}
func (self *rawFile) Ext() string {
return filepath.Ext(self.relPath)
}
func (self *rawFile) Rename(path string) error {
if filepath.IsAbs(path) { if filepath.IsAbs(path) {
return fmt.Errorf("unexpected absolute path: %s", path) return fmt.Errorf("unexpected absolute path: %s", path)
} }
@ -37,38 +46,15 @@ func (self *File) Rename(path string) error {
return nil return nil
} }
// Path returns the file path relative to the source directory. func (self *rawFile) Size() int64 {
func (self *File) Path() string {
return filepath.ToSlash(self.relPath)
}
// Dir returns the containing directory of the file.
func (self *File) Dir() string {
return filepath.ToSlash(filepath.Dir(self.relPath))
}
// Name returns the base name of the file.
func (self *File) Name() string {
return filepath.Base(self.relPath)
}
// Ext returns the extension of the file.
func (self *File) Ext() string {
return filepath.Ext(self.relPath)
}
// Size returns the file length in bytes.
func (self *File) Size() int64 {
return self.size return self.size
} }
// ModTime returns the time of the file's last modification. func (self *rawFile) ModTime() time.Time {
func (self *File) ModTime() time.Time {
return self.modTime return self.modTime
} }
// Read reads file data into the provided buffer. func (self *rawFile) Read(data []byte) (int, error) {
func (self *File) Read(data []byte) (int, error) {
if err := self.load(); err != nil { if err := self.load(); err != nil {
return 0, err return 0, err
} }
@ -76,8 +62,7 @@ func (self *File) Read(data []byte) (int, error) {
return self.reader.Read(data) return self.reader.Read(data)
} }
// Write writes file data into the provided writer. func (self *rawFile) WriteTo(writer io.Writer) (int64, error) {
func (self *File) WriteTo(writer io.Writer) (int64, error) {
if err := self.load(); err != nil { if err := self.load(); err != nil {
return 0, err return 0, err
} }
@ -85,8 +70,7 @@ func (self *File) WriteTo(writer io.Writer) (int64, error) {
return self.reader.WriteTo(writer) return self.reader.WriteTo(writer)
} }
// Seek updates the file pointer to the desired position. func (self *rawFile) Seek(offset int64, whence int) (int64, error) {
func (self *File) Seek(offset int64, whence int) (int64, error) {
if self.reader == nil && offset == 0 && (whence == io.SeekStart || whence == io.SeekCurrent) { if self.reader == nil && offset == 0 && (whence == io.SeekStart || whence == io.SeekCurrent) {
return 0, nil return 0, nil
} }
@ -98,29 +82,20 @@ func (self *File) Seek(offset int64, whence int) (int64, error) {
return self.reader.Seek(offset, whence) return self.reader.Seek(offset, whence)
} }
// GoString returns value for string formatting. func (self *rawFile) GoString() string {
func (self *File) GoString() string {
return self.relPath return self.relPath
} }
// RemoveProp deletes the metadata property for the provided name. func (self *rawFile) SetProp(name string, value FileProp) {
func (self *File) RemoveProp(name string) {
delete(self.props, name)
}
// SetProp updates the metadata property for the provided name.
func (self *File) SetProp(name string, value Prop) {
self.props[name] = value self.props[name] = value
} }
// Prop returns the metadata property for the provided name. func (self *rawFile) Prop(name string) (FileProp, bool) {
func (self *File) Prop(name string) (Prop, bool) {
value, ok := self.props[name] value, ok := self.props[name]
return value, ok return value, ok
} }
// PropOrDef returns the metadata property for the provided name or the default. func (self *rawFile) PropOrDef(name string, valueDef FileProp) FileProp {
func (self *File) PropOrDef(name string, valueDef Prop) Prop {
if value, ok := self.Prop(name); ok { if value, ok := self.Prop(name); ok {
return value return value
} }
@ -128,19 +103,25 @@ func (self *File) PropOrDef(name string, valueDef Prop) Prop {
return valueDef return valueDef
} }
// Props returns all of the metadata properties. func (self *rawFile) Props() FileProps {
func (self *File) Props() PropMap {
return self.props return self.props
} }
// CopyProps copies all metadata properties from the provided file. func (self *rawFile) CopyProps(file File) {
func (self *File) CopyProps(file *File) { for key, value := range file.Props() {
for key, value := range file.props {
self.props[key] = value self.props[key] = value
} }
} }
func (self *File) load() error { func (self *rawFile) RemoveProp(name string) {
delete(self.props, name)
}
func (self *rawFile) Index() int {
return self.index
}
func (self *rawFile) load() error {
if self.reader != nil { if self.reader != nil {
return nil return nil
} }
@ -153,35 +134,3 @@ func (self *File) load() error {
self.reader = bytes.NewReader(data) self.reader = bytes.NewReader(data)
return nil return nil
} }
func (self *File) export(targetDir string) error {
targetPath := filepath.Join(targetDir, self.relPath)
if targetInfo, err := os.Stat(targetPath); err == nil && !targetInfo.ModTime().Before(self.ModTime()) {
return nil
}
if err := os.MkdirAll(filepath.Dir(targetPath), 0755); err != nil {
return err
}
fw, err := os.Create(targetPath)
if err != nil {
return err
}
defer fw.Close()
if err := self.load(); err != nil {
return err
}
if _, err := self.Seek(0, io.SeekStart); err != nil {
return err
}
if _, err := self.WriteTo(fw); err != nil {
return err
}
return nil
}

View File

@ -1,6 +1,7 @@
package goldsmith package goldsmith
import ( import (
"io"
"os" "os"
"path/filepath" "path/filepath"
) )
@ -21,7 +22,7 @@ func (self *fileExporter) Initialize(context *Context) error {
return nil return nil
} }
func (self *fileExporter) Process(context *Context, file *File) error { func (self *fileExporter) Process(context *Context, file File) error {
slicePath := func(path string) string { slicePath := func(path string) string {
if filepath.IsAbs(path) { if filepath.IsAbs(path) {
var err error var err error
@ -33,11 +34,34 @@ func (self *fileExporter) Process(context *Context, file *File) error {
return filepath.Clean(path) return filepath.Clean(path)
} }
for token := slicePath(file.relPath); token != "."; token = filepath.Dir(token) { for token := slicePath(file.Path()); token != "."; token = filepath.Dir(token) {
self.tokens[token] = true self.tokens[token] = true
} }
return file.export(self.targetDir) targetPath := filepath.Join(self.targetDir, file.Path())
if targetInfo, err := os.Stat(targetPath); err == nil && !targetInfo.ModTime().Before(file.ModTime()) {
return nil
}
if err := os.MkdirAll(filepath.Dir(targetPath), 0755); err != nil {
return err
}
fw, err := os.Create(targetPath)
if err != nil {
return err
}
defer fw.Close()
if _, err := file.Seek(0, io.SeekStart); err != nil {
return err
}
if _, err := file.WriteTo(fw); err != nil {
return err
}
return nil
} }
func (self *fileExporter) Finalize(context *Context) error { func (self *fileExporter) Finalize(context *Context) error {

View File

@ -7,9 +7,9 @@ type filterEntry struct {
type filterStack []filterEntry type filterStack []filterEntry
func (self *filterStack) accept(file *File) bool { func (self *filterStack) accept(file File) bool {
for _, entry := range *self { for _, entry := range *self {
if entry.index >= file.index && !entry.filter.Accept(file) { if entry.index >= file.Index() && !entry.filter.Accept(file) {
return false return false
} }
} }

View File

@ -16,6 +16,6 @@ func (*Condition) Name() string {
return "condition" return "condition"
} }
func (self *Condition) Accept(file *goldsmith.File) bool { func (self *Condition) Accept(file goldsmith.File) bool {
return self.accept return self.accept
} }

View File

@ -20,7 +20,7 @@ func (*operatorAnd) Name() string {
return "operator" return "operator"
} }
func (self *operatorAnd) Accept(file *goldsmith.File) bool { func (self *operatorAnd) Accept(file goldsmith.File) bool {
for _, filter := range self.filters { for _, filter := range self.filters {
if !filter.Accept(file) { if !filter.Accept(file) {
return false return false
@ -42,7 +42,7 @@ func (*operatorNot) Name() string {
return "operator" return "operator"
} }
func (self *operatorNot) Accept(file *goldsmith.File) bool { func (self *operatorNot) Accept(file goldsmith.File) bool {
return !self.filter.Accept(file) return !self.filter.Accept(file)
} }
@ -58,7 +58,7 @@ func (*operatorOr) Name() string {
return "operator" return "operator"
} }
func (self *operatorOr) Accept(file *goldsmith.File) bool { func (self *operatorOr) Accept(file goldsmith.File) bool {
for _, filter := range self.filters { for _, filter := range self.filters {
if filter.Accept(file) { if filter.Accept(file) {
return true return true

View File

@ -25,7 +25,7 @@ func (*Wildcard) Name() string {
return "wildcard" return "wildcard"
} }
func (self *Wildcard) Accept(file *goldsmith.File) bool { func (self *Wildcard) Accept(file goldsmith.File) bool {
filePath := self.adjustCase(file.Path()) filePath := self.adjustCase(file.Path())
for _, wildcard := range self.wildcards { for _, wildcard := range self.wildcards {

View File

@ -45,7 +45,7 @@ func (self *Goldsmith) Chain(plugin Plugin) *Goldsmith {
plugin: plugin, plugin: plugin,
filtersExt: append(filterStack(nil), self.filters...), filtersExt: append(filterStack(nil), self.filters...),
index: self.index, index: self.index,
filesOut: make(chan *File), filesOut: make(chan File),
} }
if len(self.contexts) > 0 { if len(self.contexts) > 0 {
@ -87,7 +87,7 @@ func (self *Goldsmith) End(targetDir string) []error {
return self.errors return self.errors
} }
func (self *Goldsmith) fault(name string, file *File, err error) { func (self *Goldsmith) fault(name string, file File, err error) {
self.mutex.Lock() self.mutex.Lock()
defer self.mutex.Unlock() defer self.mutex.Unlock()

View File

@ -1,5 +1,10 @@
package goldsmith package goldsmith
import (
"io"
"time"
)
// Plugin contains the minimum set of methods required on plugins. Plugins can // Plugin contains the minimum set of methods required on plugins. Plugins can
// also optionally implement Initializer, Processor, and Finalizer interfaces. // also optionally implement Initializer, Processor, and Finalizer interfaces.
type Plugin interface { type Plugin interface {
@ -14,7 +19,7 @@ type Initializer interface {
// Processor allows for optional processing of files passing through a plugin. // Processor allows for optional processing of files passing through a plugin.
type Processor interface { type Processor interface {
Process(context *Context, file *File) error Process(context *Context, file File) error
} }
// Finalizer allows for optional finalization of a plugin after all files // Finalizer allows for optional finalization of a plugin after all files
@ -26,5 +31,36 @@ type Finalizer interface {
// Filter is used to determine which files should continue in the chain. // Filter is used to determine which files should continue in the chain.
type Filter interface { type Filter interface {
Name() string Name() string
Accept(file *File) bool Accept(file File) bool
}
type (
FileProp any
FileProps map[string]FileProp
)
// File represents in-memory or on-disk files in a chain.
type File interface {
Path() string
Dir() string
Name() string
Ext() string
Rename(path string) error
Size() int64
ModTime() time.Time
Read(data []byte) (int, error)
WriteTo(writer io.Writer) (int64, error)
Seek(offset int64, whence int) (int64, error)
SetProp(name string, value FileProp)
Prop(name string) (FileProp, bool)
PropOrDef(name string, valueDef FileProp) FileProp
Props() FileProps
CopyProps(file File)
RemoveProp(name string)
GoString() string
Index() int
} }

View File

@ -50,7 +50,7 @@ func (*Absolute) Initialize(context *goldsmith.Context) error {
return nil return nil
} }
func (self *Absolute) Process(context *goldsmith.Context, inputFile *goldsmith.File) error { func (self *Absolute) Process(context *goldsmith.Context, inputFile goldsmith.File) error {
if outputFile := context.RetrieveCachedFile(inputFile.Path(), inputFile); outputFile != nil { if outputFile := context.RetrieveCachedFile(inputFile.Path(), inputFile); outputFile != nil {
outputFile.CopyProps(inputFile) outputFile.CopyProps(inputFile)
context.DispatchFile(outputFile) context.DispatchFile(outputFile)

View File

@ -19,7 +19,7 @@ type Crumb struct {
// Node represents information about a specific file in the site's structure. // Node represents information about a specific file in the site's structure.
type Node struct { type Node struct {
File *goldsmith.File File goldsmith.File
Parent *Node Parent *Node
Children []*Node Children []*Node
@ -75,7 +75,7 @@ func (*Breadcrumbs) Initialize(context *goldsmith.Context) error {
return nil return nil
} }
func (self *Breadcrumbs) Process(context *goldsmith.Context, inputFile *goldsmith.File) error { func (self *Breadcrumbs) Process(context *goldsmith.Context, inputFile goldsmith.File) error {
var parentNameStr string var parentNameStr string
if parentName, ok := inputFile.Prop(self.parentKey); ok { if parentName, ok := inputFile.Prop(self.parentKey); ok {
parentNameStr, _ = parentName.(string) parentNameStr, _ = parentName.(string)

View File

@ -15,7 +15,7 @@ import (
) )
// A Comparer callback function is used to sort files within a collection group. // A Comparer callback function is used to sort files within a collection group.
type Comparer func(i, j *goldsmith.File) (less bool) type Comparer func(i, j goldsmith.File) (less bool)
// Collection chainable plugin context. // Collection chainable plugin context.
type Collection struct { type Collection struct {
@ -23,8 +23,8 @@ type Collection struct {
groupsKey string groupsKey string
comparer Comparer comparer Comparer
groups map[string][]*goldsmith.File groups map[string][]goldsmith.File
files []*goldsmith.File files []goldsmith.File
mutex sync.Mutex mutex sync.Mutex
} }
@ -33,7 +33,7 @@ func New() *Collection {
return &Collection{ return &Collection{
collectionKey: "Collection", collectionKey: "Collection",
groupsKey: "Groups", groupsKey: "Groups",
groups: make(map[string][]*goldsmith.File), groups: make(map[string][]goldsmith.File),
} }
} }
@ -66,7 +66,7 @@ func (*Collection) Initialize(context *goldsmith.Context) error {
return nil return nil
} }
func (self *Collection) Process(context *goldsmith.Context, inputFile *goldsmith.File) error { func (self *Collection) Process(context *goldsmith.Context, inputFile goldsmith.File) error {
self.mutex.Lock() self.mutex.Lock()
defer func() { defer func() {
inputFile.SetProp(self.groupsKey, self.groups) inputFile.SetProp(self.groupsKey, self.groups)
@ -110,7 +110,7 @@ func (self *Collection) Finalize(context *goldsmith.Context) error {
} }
type fileSorter struct { type fileSorter struct {
files []*goldsmith.File files []goldsmith.File
comparer Comparer comparer Comparer
} }

View File

@ -14,12 +14,12 @@ import (
) )
// Processor callback function to modify documents. // Processor callback function to modify documents.
type Processor func(*goldsmith.File, *goquery.Document) error type Processor func(goldsmith.File, *goquery.Document) error
// Document plugin context. // Document plugin context.
type Document struct { type Document struct {
callback Processor callback Processor
files []*goldsmith.File files []goldsmith.File
mutex sync.Mutex mutex sync.Mutex
} }
@ -37,7 +37,7 @@ func (*Document) Initialize(context *goldsmith.Context) error {
return nil return nil
} }
func (self *Document) Process(context *goldsmith.Context, inputFile *goldsmith.File) error { func (self *Document) Process(context *goldsmith.Context, inputFile goldsmith.File) error {
doc, err := goquery.NewDocumentFromReader(inputFile) doc, err := goquery.NewDocumentFromReader(inputFile)
if err != nil { if err != nil {
return err return err

View File

@ -8,7 +8,7 @@ import (
"github.com/PuerkitoBio/goquery" "github.com/PuerkitoBio/goquery"
) )
func process(file *goldsmith.File, doc *goquery.Document) error { func process(file goldsmith.File, doc *goquery.Document) error {
doc.Find("h1").SetAttr("style", "color: red;") doc.Find("h1").SetAttr("style", "color: red;")
return nil return nil
} }

View File

@ -71,7 +71,7 @@ func (*FrontMatter) Initialize(context *goldsmith.Context) error {
return nil return nil
} }
func (*FrontMatter) Process(context *goldsmith.Context, inputFile *goldsmith.File) error { func (*FrontMatter) Process(context *goldsmith.Context, inputFile goldsmith.File) error {
meta, body, err := parse(inputFile) meta, body, err := parse(inputFile)
if err != nil { if err != nil {
return err return err

View File

@ -18,7 +18,7 @@ type Entry struct {
Name string Name string
Path string Path string
IsDir bool IsDir bool
File *goldsmith.File File goldsmith.File
} }
// Index chainable plugin context. // Index chainable plugin context.
@ -60,7 +60,7 @@ func (*Index) Name() string {
return "index" return "index"
} }
func (self *Index) Process(context *goldsmith.Context, inputFile *goldsmith.File) error { func (self *Index) Process(context *goldsmith.Context, inputFile goldsmith.File) error {
self.mutex.Lock() self.mutex.Lock()
defer self.mutex.Unlock() defer self.mutex.Unlock()
@ -131,7 +131,7 @@ func (self *Index) Finalize(context *goldsmith.Context) error {
type directory struct { type directory struct {
entries entriesByName entries entriesByName
indexFile *goldsmith.File indexFile goldsmith.File
} }
type entriesByName []Entry type entriesByName []Entry

View File

@ -20,8 +20,8 @@ type Layout struct {
defaultLayout *string defaultLayout *string
helpers template.FuncMap helpers template.FuncMap
inputFiles []*goldsmith.File inputFiles []goldsmith.File
templateFiles []*goldsmith.File templateFiles []goldsmith.File
mutex sync.Mutex mutex sync.Mutex
template *template.Template template *template.Template
@ -70,7 +70,7 @@ func (self *Layout) Initialize(context *goldsmith.Context) error {
return nil return nil
} }
func (self *Layout) Process(context *goldsmith.Context, inputFile *goldsmith.File) error { func (self *Layout) Process(context *goldsmith.Context, inputFile goldsmith.File) error {
self.mutex.Lock() self.mutex.Lock()
defer self.mutex.Unlock() defer self.mutex.Unlock()
@ -128,7 +128,7 @@ func (self *Layout) Finalize(context *goldsmith.Context) error {
return nil return nil
} }
func (self *Layout) getFileLayout(file *goldsmith.File) (string, bool) { func (self *Layout) getFileLayout(file goldsmith.File) (string, bool) {
if name, ok := file.Props()[self.layoutKey].(string); ok { if name, ok := file.Props()[self.layoutKey].(string); ok {
return name, true return name, true
} }

View File

@ -37,7 +37,7 @@ func (self *LiveJs) Initialize(context *goldsmith.Context) error {
return nil return nil
} }
func (self *LiveJs) Process(context *goldsmith.Context, inputFile *goldsmith.File) error { func (self *LiveJs) Process(context *goldsmith.Context, inputFile goldsmith.File) error {
if outputFile := context.RetrieveCachedFile(inputFile.Path(), inputFile); outputFile != nil { if outputFile := context.RetrieveCachedFile(inputFile.Path(), inputFile); outputFile != nil {
outputFile.CopyProps(inputFile) outputFile.CopyProps(inputFile)
context.DispatchFile(outputFile) context.DispatchFile(outputFile)

View File

@ -47,7 +47,7 @@ func (self *Markdown) Initialize(context *goldsmith.Context) error {
return nil return nil
} }
func (self *Markdown) Process(context *goldsmith.Context, inputFile *goldsmith.File) error { func (self *Markdown) Process(context *goldsmith.Context, inputFile goldsmith.File) error {
outputPath := strings.TrimSuffix(inputFile.Path(), path.Ext(inputFile.Path())) + ".html" outputPath := strings.TrimSuffix(inputFile.Path(), path.Ext(inputFile.Path())) + ".html"
if outputFile := context.RetrieveCachedFile(outputPath, inputFile); outputFile != nil { if outputFile := context.RetrieveCachedFile(outputPath, inputFile); outputFile != nil {
outputFile.CopyProps(inputFile) outputFile.CopyProps(inputFile)

View File

@ -37,7 +37,7 @@ func (*Minify) Initialize(context *goldsmith.Context) error {
return nil return nil
} }
func (*Minify) Process(context *goldsmith.Context, inputFile *goldsmith.File) error { func (*Minify) Process(context *goldsmith.Context, inputFile goldsmith.File) error {
if outputFile := context.RetrieveCachedFile(inputFile.Path(), inputFile); outputFile != nil { if outputFile := context.RetrieveCachedFile(inputFile.Path(), inputFile); outputFile != nil {
outputFile.CopyProps(inputFile) outputFile.CopyProps(inputFile)
context.DispatchFile(outputFile) context.DispatchFile(outputFile)

View File

@ -22,13 +22,13 @@ import (
type Namer func(path string, index int) string type Namer func(path string, index int) string
// Lister callback function is used to return a metadata slice which should be paged across several files. // Lister callback function is used to return a metadata slice which should be paged across several files.
type Lister func(file *goldsmith.File) interface{} type Lister func(file goldsmith.File) interface{}
// Page represents information about a given metadata segment. // Page represents information about a given metadata segment.
type Page struct { type Page struct {
Index int Index int
Items interface{} Items interface{}
File *goldsmith.File File goldsmith.File
Next *Page Next *Page
Prev *Page Prev *Page
@ -51,7 +51,7 @@ type Pager struct {
inheritedKeys []string inheritedKeys []string
itemsPerPage int itemsPerPage int
files []*goldsmith.File files []goldsmith.File
mutex sync.Mutex mutex sync.Mutex
} }
@ -114,7 +114,7 @@ func (*Pager) Initialize(context *goldsmith.Context) error {
return nil return nil
} }
func (self *Pager) Process(context *goldsmith.Context, inputFile *goldsmith.File) error { func (self *Pager) Process(context *goldsmith.Context, inputFile goldsmith.File) error {
self.mutex.Lock() self.mutex.Lock()
defer self.mutex.Unlock() defer self.mutex.Unlock()
@ -208,7 +208,7 @@ func (self *Pager) Finalize(ctx *goldsmith.Context) error {
return nil return nil
} }
func (self *Pager) isEnabledForFile(file *goldsmith.File) (bool, error) { func (self *Pager) isEnabledForFile(file goldsmith.File) (bool, error) {
enableRaw, ok := file.Prop(self.enableKey) enableRaw, ok := file.Prop(self.enableKey)
if !ok { if !ok {
return false, nil return false, nil

View File

@ -11,9 +11,9 @@ import (
) )
func Test(self *testing.T) { func Test(self *testing.T) {
lister := func(file *goldsmith.File) interface{} { lister := func(file goldsmith.File) interface{} {
if groupsRaw, ok := file.Prop("Groups"); ok { if groupsRaw, ok := file.Prop("Groups"); ok {
if groups, ok := groupsRaw.(map[string][]*goldsmith.File); ok { if groups, ok := groupsRaw.(map[string][]goldsmith.File); ok {
if group, ok := groups["group"]; ok { if group, ok := groups["group"]; ok {
return group return group
} }

View File

@ -1,7 +1,7 @@
package rule package rule
import ( import (
"io/ioutil" "io"
"path/filepath" "path/filepath"
"sync" "sync"
@ -19,14 +19,14 @@ type rule struct {
type ruleApply struct { type ruleApply struct {
rule rule
Props map[string]goldsmith.Prop Props map[string]goldsmith.FileProp
} }
type ruleDrop struct { type ruleDrop struct {
rule rule
} }
func (self *rule) accept(inputFile *goldsmith.File) bool { func (self *rule) accept(inputFile goldsmith.File) bool {
if !wildcard.New(filepath.Join(self.baseDir, "**")).Accept(inputFile) { if !wildcard.New(filepath.Join(self.baseDir, "**")).Accept(inputFile) {
return false return false
} }
@ -52,7 +52,7 @@ func (self *rule) accept(inputFile *goldsmith.File) bool {
return operator.Not(wildcard.New(rejectPaths...)).Accept(inputFile) return operator.Not(wildcard.New(rejectPaths...)).Accept(inputFile)
} }
func (self *ruleApply) apply(inputFile *goldsmith.File) { func (self *ruleApply) apply(inputFile goldsmith.File) {
if self.accept(inputFile) { if self.accept(inputFile) {
for name, value := range self.Props { for name, value := range self.Props {
inputFile.SetProp(name, value) inputFile.SetProp(name, value)
@ -60,7 +60,7 @@ func (self *ruleApply) apply(inputFile *goldsmith.File) {
} }
} }
func (self *ruleDrop) drop(inputFile *goldsmith.File) bool { func (self *ruleDrop) drop(inputFile goldsmith.File) bool {
return self.accept(inputFile) return self.accept(inputFile)
} }
@ -69,8 +69,8 @@ type ruleSet struct {
Drop []*ruleDrop Drop []*ruleDrop
} }
func newRuleSet(inputFile *goldsmith.File) (*ruleSet, error) { func newRuleSet(inputFile goldsmith.File) (*ruleSet, error) {
data, err := ioutil.ReadAll(inputFile) data, err := io.ReadAll(inputFile)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -91,7 +91,7 @@ func newRuleSet(inputFile *goldsmith.File) (*ruleSet, error) {
return &ruleSet, nil return &ruleSet, nil
} }
func (self *ruleSet) process(inputFile *goldsmith.File) bool { func (self *ruleSet) process(inputFile goldsmith.File) bool {
for _, rule := range self.Apply { for _, rule := range self.Apply {
rule.apply(inputFile) rule.apply(inputFile)
} }
@ -110,7 +110,7 @@ type Rule struct {
filename string filename string
ruleSets []*ruleSet ruleSets []*ruleSet
inputFiles []*goldsmith.File inputFiles []goldsmith.File
mutex sync.Mutex mutex sync.Mutex
} }
@ -128,7 +128,7 @@ func (*Rule) Name() string {
return "rule" return "rule"
} }
func (self *Rule) Process(context *goldsmith.Context, inputFile *goldsmith.File) error { func (self *Rule) Process(context *goldsmith.Context, inputFile goldsmith.File) error {
if inputFile.Name() == self.filename { if inputFile.Name() == self.filename {
ruleSet, err := newRuleSet(inputFile) ruleSet, err := newRuleSet(inputFile)
if err != nil { if err != nil {

View File

@ -62,7 +62,7 @@ func (*Summary) Initialize(context *goldsmith.Context) error {
return nil return nil
} }
func (self *Summary) Process(context *goldsmith.Context, inputFile *goldsmith.File) error { func (self *Summary) Process(context *goldsmith.Context, inputFile goldsmith.File) error {
doc, err := goquery.NewDocumentFromReader(inputFile) doc, err := goquery.NewDocumentFromReader(inputFile)
if err != nil { if err != nil {
return err return err

View File

@ -120,7 +120,7 @@ func (self *Syndicate) WithFeed(name string, config FeedConfig) *Syndicate {
return self return self
} }
func (self *Syndicate) Process(context *goldsmith.Context, inputFile *goldsmith.File) error { func (self *Syndicate) Process(context *goldsmith.Context, inputFile goldsmith.File) error {
defer context.DispatchFile(inputFile) defer context.DispatchFile(inputFile)
getString := func(key string) string { getString := func(key string) string {

View File

@ -74,7 +74,7 @@ func (*Syntax) Initialize(context *goldsmith.Context) error {
return nil return nil
} }
func (self *Syntax) Process(context *goldsmith.Context, inputFile *goldsmith.File) error { func (self *Syntax) Process(context *goldsmith.Context, inputFile goldsmith.File) error {
if outputFile := context.RetrieveCachedFile(inputFile.Path(), inputFile); outputFile != nil { if outputFile := context.RetrieveCachedFile(inputFile.Path(), inputFile); outputFile != nil {
outputFile.CopyProps(inputFile) outputFile.CopyProps(inputFile)
context.DispatchFile(outputFile) context.DispatchFile(outputFile)

View File

@ -18,7 +18,7 @@ import (
// TagInfo contains site-wide information about a particular tag. // TagInfo contains site-wide information about a particular tag.
type TagInfo struct { type TagInfo struct {
TaggedFiles filesByPath TaggedFiles filesByPath
IndexFile *goldsmith.File IndexFile goldsmith.File
SafeName string SafeName string
RawName string RawName string
} }
@ -44,7 +44,7 @@ type Tags struct {
infoByName tagInfoByName infoByName tagInfoByName
infoByCount tagInfoByCount infoByCount tagInfoByCount
files []*goldsmith.File files []goldsmith.File
mutex sync.Mutex mutex sync.Mutex
} }
@ -98,7 +98,7 @@ func (*Tags) Initialize(context *goldsmith.Context) error {
return nil return nil
} }
func (self *Tags) Process(context *goldsmith.Context, inputFile *goldsmith.File) error { func (self *Tags) Process(context *goldsmith.Context, inputFile goldsmith.File) error {
tagState := &TagState{ tagState := &TagState{
TagsByName: &self.infoByName, TagsByName: &self.infoByName,
TagsByCount: &self.infoByCount, TagsByCount: &self.infoByCount,
@ -185,8 +185,8 @@ func (self *Tags) Finalize(context *goldsmith.Context) error {
return nil return nil
} }
func (self *Tags) buildPages(context *goldsmith.Context) ([]*goldsmith.File, error) { func (self *Tags) buildPages(context *goldsmith.Context) ([]goldsmith.File, error) {
var files []*goldsmith.File var files []goldsmith.File
for tag, info := range self.info { for tag, info := range self.info {
var err error var err error
info.IndexFile, err = context.CreateFileFromReader(self.tagPagePath(tag), bytes.NewReader(nil)) info.IndexFile, err = context.CreateFileFromReader(self.tagPagePath(tag), bytes.NewReader(nil))
@ -273,7 +273,7 @@ func (self tagInfoByName) Less(i, j int) bool {
return false return false
} }
type filesByPath []*goldsmith.File type filesByPath []goldsmith.File
func (self filesByPath) Len() int { func (self filesByPath) Len() int {
return len(self) return len(self)

View File

@ -81,7 +81,7 @@ func (*Thumbnail) Initialize(context *goldsmith.Context) error {
return nil return nil
} }
func (self *Thumbnail) Process(context *goldsmith.Context, inputFile *goldsmith.File) error { func (self *Thumbnail) Process(context *goldsmith.Context, inputFile goldsmith.File) error {
defer context.DispatchFile(inputFile) defer context.DispatchFile(inputFile)
thumbPath := self.namer(inputFile.Path(), self.size) thumbPath := self.namer(inputFile.Path(), self.size)
@ -104,7 +104,7 @@ func (self *Thumbnail) Process(context *goldsmith.Context, inputFile *goldsmith.
return nil return nil
} }
func (self *Thumbnail) thumbnail(context *goldsmith.Context, inputFile *goldsmith.File, thumbPath string) (*goldsmith.File, error) { func (self *Thumbnail) thumbnail(context *goldsmith.Context, inputFile goldsmith.File, thumbPath string) (goldsmith.File, error) {
var thumbFormat imaging.Format var thumbFormat imaging.Format
switch strings.ToLower(filepath.Ext(thumbPath)) { switch strings.ToLower(filepath.Ext(thumbPath)) {
case ".jpg", ".jpeg": case ".jpg", ".jpeg":