1
Fork 0
This commit is contained in:
Alex Yatskov 2024-03-03 21:30:32 -08:00
parent 22ffaae954
commit 889397b9c5
8 changed files with 51 additions and 185 deletions

View File

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

33
chain_state.go Normal file
View File

@ -0,0 +1,33 @@
// Package goldsmith generates static websites.
package goldsmith
import (
"fmt"
"sync"
)
type chainState struct {
contexts []*Context
cache *cache
filters filterStack
clean bool
index int
errors []error
mutex sync.Mutex
}
func (self *chainState) fault(name string, file *File, err error) {
self.mutex.Lock()
defer self.mutex.Unlock()
var faultError error
if file == nil {
faultError = fmt.Errorf("[%s]: %w", name, err)
} else {
faultError = fmt.Errorf("[%s@%v]: %w", name, file, err)
}
self.errors = append(self.errors, faultError)
}

View File

@ -28,14 +28,18 @@ type Context struct {
}
// 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(relPath string, reader io.Reader) (*File, error) {
if filepath.IsAbs(relPath) {
return nil, errors.New("file paths must be relative")
}
data, err := io.ReadAll(reader)
if err != nil {
return nil, err
}
file := &File{
relPath: sourcePath,
relPath: relPath,
props: make(FileProps),
modTime: time.Now(),
size: int64(len(data)),
@ -47,13 +51,9 @@ func (self *Context) CreateFileFromReader(sourcePath string, reader io.Reader) (
}
// CreateFileFromAsset creates a new file instance from the provided file path.
func (self *Context) CreateFileFromAsset(sourcePath, dataPath string) (*File, error) {
if filepath.IsAbs(sourcePath) {
return nil, errors.New("source paths must be relative")
}
if filepath.IsAbs(dataPath) {
return nil, errors.New("data paths must be relative")
func (self *Context) CreateFileFromAsset(relPath, dataPath string) (*File, error) {
if filepath.IsAbs(relPath) {
return nil, errors.New("file paths must be relative")
}
info, err := os.Stat(dataPath)
@ -61,11 +61,11 @@ func (self *Context) CreateFileFromAsset(sourcePath, dataPath string) (*File, er
return nil, err
}
if info.IsDir() {
return nil, errors.New("assets must be files")
return nil, errors.New("file paths cannot be directories")
}
file := &File{
relPath: sourcePath,
relPath: relPath,
props: make(FileProps),
modTime: info.ModTime(),
size: info.Size(),
@ -86,7 +86,7 @@ func (self *Context) DispatchFile(file *File) {
// passes it to the next link in the chain.
func (self *Context) DispatchAndCacheFile(outputFile *File, inputFiles ...*File) {
if self.chain.cache != nil {
self.chain.cache.storeFile(self, outputFile, inputFiles)
self.chain.cache.storeFile(outputFile, inputFiles)
}
self.DispatchFile(outputFile)

View File

@ -1,6 +0,0 @@
package goldsmith
type contextFile struct {
rawFile
index int
}

View File

@ -21,7 +21,7 @@ func (self *fileImporter) Initialize(context *Context) error {
relPath, err := filepath.Rel(self.sourceDir, path)
if err != nil {
panic(err)
return err
}
file, err := context.CreateFileFromAsset(relPath, path)

View File

@ -1,11 +1,6 @@
// Package goldsmith generates static websites.
package goldsmith
import (
"fmt"
"sync"
)
// Goldsmith chainable context.
type Goldsmith struct {
chain *chainState
@ -13,7 +8,7 @@ type Goldsmith struct {
// Begin starts a chain, reading the files located in the source directory as input.
func (self *Goldsmith) Begin(sourceDir string) *Goldsmith {
self.chain = new(chainState)
self.chain = &chainState{}
self.Chain(&fileImporter{sourceDir: sourceDir})
return self
}
@ -81,29 +76,3 @@ func (self *Goldsmith) End(targetDir string) []error {
return errors
}
type chainState struct {
contexts []*Context
cache *cache
filters filterStack
clean bool
index int
errors []error
mutex sync.Mutex
}
func (self *chainState) fault(name string, file *File, err error) {
self.mutex.Lock()
defer self.mutex.Unlock()
var faultError error
if file == nil {
faultError = fmt.Errorf("[%s]: %w", name, err)
} else {
faultError = fmt.Errorf("[%s@%v]: %w", name, file, err)
}
self.errors = append(self.errors, faultError)
}

View File

@ -1,130 +0,0 @@
package goldsmith
import (
"bytes"
"fmt"
"io"
"os"
"path/filepath"
"time"
)
type rawFile struct {
relPath string
props map[string]FileProp
modTime time.Time
size int64
dataPath string
reader *bytes.Reader
}
func (self *rawFile) Path() string {
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) {
return fmt.Errorf("unexpected absolute path: %s", path)
}
self.relPath = path
return nil
}
func (self *rawFile) Size() int64 {
return self.size
}
func (self *rawFile) ModTime() time.Time {
return self.modTime
}
func (self *rawFile) Read(data []byte) (int, error) {
if err := self.load(); err != nil {
return 0, err
}
return self.reader.Read(data)
}
func (self *rawFile) WriteTo(writer io.Writer) (int64, error) {
if err := self.load(); err != nil {
return 0, err
}
return self.reader.WriteTo(writer)
}
func (self *rawFile) Seek(offset int64, whence int) (int64, error) {
if self.reader == nil && offset == 0 && (whence == io.SeekStart || whence == io.SeekCurrent) {
return 0, nil
}
if err := self.load(); err != nil {
return 0, err
}
return self.reader.Seek(offset, whence)
}
func (self *rawFile) GoString() string {
return self.relPath
}
func (self *rawFile) SetProp(name string, value FileProp) {
self.props[name] = value
}
func (self *rawFile) Prop(name string) (FileProp, bool) {
value, ok := self.props[name]
return value, ok
}
func (self *rawFile) PropOrDef(name string, valueDef FileProp) FileProp {
if value, ok := self.Prop(name); ok {
return value
}
return valueDef
}
func (self *rawFile) Props() FileProps {
return self.props
}
func (self *rawFile) CopyProps(file File) {
for key, value := range file.Props() {
self.props[key] = value
}
}
func (self *rawFile) RemoveProp(name string) {
delete(self.props, name)
}
func (self *rawFile) load() error {
if self.reader != nil {
return nil
}
data, err := os.ReadFile(self.dataPath)
if err != nil {
return err
}
self.reader = bytes.NewReader(data)
return nil
}