diff --git a/error.go b/error.go index 06b31f9..b0ecaaa 100644 --- a/error.go +++ b/error.go @@ -2,12 +2,15 @@ package goldsmith import "fmt" +// Error wraps the core error type to provide a plugin or filter name in +// addition to the file path that was being processed at the time. type Error struct { Name string Path string Err error } +// Error returns a string representation of the error. func (err Error) Error() string { var path string if len(err.Path) > 0 { diff --git a/file.go b/file.go index 790def3..86c7e54 100644 --- a/file.go +++ b/file.go @@ -12,6 +12,7 @@ import ( "time" ) +// File represents in-memory or on-disk files in a chain. type File struct { sourcePath string dataPath string @@ -26,30 +27,37 @@ type File struct { modTime time.Time } +// Path returns the file path relative to the source directory. func (file *File) Path() string { return file.sourcePath } +// Name returns the base name of the file. func (file *File) Name() string { return path.Base(file.sourcePath) } +// Dir returns the containing directory of the file. func (file *File) Dir() string { return path.Dir(file.sourcePath) } +// Ext returns the extension of the file. func (file *File) Ext() string { return path.Ext(file.sourcePath) } +// Size returns the file length in bytes. func (file *File) Size() int64 { return file.size } +// ModTime returns the time of the file's last modification. func (file *File) ModTime() time.Time { return file.modTime } +// Read reads file data into the provided buffer. func (file *File) Read(data []byte) (int, error) { if err := file.load(); err != nil { return 0, err @@ -58,6 +66,7 @@ func (file *File) Read(data []byte) (int, error) { return file.reader.Read(data) } +// Write writes file data into the provided writer. func (file *File) WriteTo(writer io.Writer) (int64, error) { if err := file.load(); err != nil { return 0, err @@ -66,6 +75,7 @@ func (file *File) WriteTo(writer io.Writer) (int64, error) { return file.reader.WriteTo(writer) } +// Seek updates the file pointer to the desired position. func (file *File) Seek(offset int64, whence int) (int64, error) { if file.reader == nil && offset == 0 && (whence == os.SEEK_SET || whence == os.SEEK_CUR) { return 0, nil diff --git a/goldsmith.go b/goldsmith.go index 447cde7..252b1aa 100644 --- a/goldsmith.go +++ b/goldsmith.go @@ -1,3 +1,4 @@ +// Package goldsmith generates static websites. package goldsmith import ( @@ -8,6 +9,7 @@ import ( "sync" ) +// Goldsmith chainable context. type Goldsmith struct { sourceDir string targetDir string @@ -23,6 +25,7 @@ type Goldsmith struct { mutex sync.Mutex } +// Begin starts a chain, reading the files located in sourceDir as input. func Begin(sourceDir string) *Goldsmith { goldsmith := &Goldsmith{ sourceDir: sourceDir, @@ -34,11 +37,13 @@ func Begin(sourceDir string) *Goldsmith { return goldsmith } +// Cache enables caching in cacheDir for the remainder of the chain. func (goldsmith *Goldsmith) Cache(cacheDir string) *Goldsmith { goldsmith.fileCache = &cache{cacheDir} return goldsmith } +// Chain links a plugin instance into the chain. func (goldsmith *Goldsmith) Chain(plugin Plugin) *Goldsmith { goldsmith.contextHasher.Write([]byte(plugin.Name())) @@ -59,11 +64,13 @@ func (goldsmith *Goldsmith) Chain(plugin Plugin) *Goldsmith { return goldsmith } +// FilterPush pushes a filter instance on the chain's filter stack. func (goldsmith *Goldsmith) FilterPush(filter Filter) *Goldsmith { goldsmith.fileFilters = append(goldsmith.fileFilters, filter) return goldsmith } +// FilterPop pops a filter instance from the chain's filter stack. func (goldsmith *Goldsmith) FilterPop() *Goldsmith { count := len(goldsmith.fileFilters) if count == 0 { @@ -74,6 +81,7 @@ func (goldsmith *Goldsmith) FilterPop() *Goldsmith { return goldsmith } +// End stops a chain, writing all recieved files to targetDir as output. func (goldsmith *Goldsmith) End(targetDir string) []error { goldsmith.targetDir = targetDir diff --git a/interface.go b/interface.go index 0337f5c..9a88004 100644 --- a/interface.go +++ b/interface.go @@ -1,26 +1,30 @@ package goldsmith +// Plugin contains the minimum set of methods required on plugins. Plugins can +// also optionally implement Initializer, Processor, and Finalizer interfaces. +type Plugin interface { + Name() string +} + +// Initializer is used to optionally initialize a plugin and to specify a +// filter to be used for determining which files will be processed. type Initializer interface { Initialize(context *Context) (Filter, error) } +// Processor allows for optional processing of files passing through a plugin. type Processor interface { Process(context *Context, file *File) error } +// Finalizer allows for optional finalization of a plugin after all files +// queued in the chain have passed through it. type Finalizer interface { Finalize(context *Context) error } -type Component interface { - Name() string -} - +// Filter is used to determine which files should continue in the chain. type Filter interface { - Component + Name() string Accept(file *File) (bool, error) } - -type Plugin interface { - Component -}