Compare commits
2 Commits
972c4d81f5
...
2dd1fdbfa5
Author | SHA1 | Date | |
---|---|---|---|
2dd1fdbfa5 | |||
acc22a9b84 |
5
cache.go
5
cache.go
@ -8,6 +8,7 @@ import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"sort"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type cache struct {
|
||||
@ -72,7 +73,9 @@ func (self *cache) buildCachePath(context *Context, outputPath string, inputFile
|
||||
hasher := crc32.NewIEEE()
|
||||
hasher.Write([]byte(outputPath))
|
||||
|
||||
sort.Sort(filesByPath(inputFiles))
|
||||
sort.Slice(inputFiles, func(i, j int) bool {
|
||||
return strings.Compare(inputFiles[i].Path(), inputFiles[j].Path()) < 0
|
||||
})
|
||||
|
||||
for _, inputFile := range inputFiles {
|
||||
modTimeBuff := make([]byte, 8)
|
||||
|
66
file_exporter.go
Normal file
66
file_exporter.go
Normal file
@ -0,0 +1,66 @@
|
||||
package goldsmith
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
)
|
||||
|
||||
type fileExporter struct {
|
||||
targetDir string
|
||||
clean bool
|
||||
tokens map[string]bool
|
||||
}
|
||||
|
||||
func (*fileExporter) Name() string {
|
||||
return "exporter"
|
||||
}
|
||||
|
||||
func (self *fileExporter) Initialize(context *Context) error {
|
||||
self.tokens = make(map[string]bool)
|
||||
context.Threads(1)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *fileExporter) Process(context *Context, file *File) error {
|
||||
slicePath := func(path string) string {
|
||||
if filepath.IsAbs(path) {
|
||||
var err error
|
||||
if path, err = filepath.Rel("/", path); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
return filepath.Clean(path)
|
||||
}
|
||||
|
||||
for token := slicePath(file.relPath); token != "."; token = filepath.Dir(token) {
|
||||
self.tokens[token] = true
|
||||
}
|
||||
|
||||
return file.export(self.targetDir)
|
||||
}
|
||||
|
||||
func (self *fileExporter) Finalize(context *Context) error {
|
||||
if !self.clean {
|
||||
return nil
|
||||
}
|
||||
|
||||
return filepath.Walk(self.targetDir, func(path string, info os.FileInfo, err error) error {
|
||||
if path == self.targetDir {
|
||||
return nil
|
||||
}
|
||||
|
||||
relPath, err := filepath.Rel(self.targetDir, path)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
if tokenized, _ := self.tokens[relPath]; !tokenized {
|
||||
if err := os.RemoveAll(path); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
}
|
35
file_importer.go
Normal file
35
file_importer.go
Normal file
@ -0,0 +1,35 @@
|
||||
package goldsmith
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
)
|
||||
|
||||
type fileImporter struct {
|
||||
sourceDir string
|
||||
}
|
||||
|
||||
func (*fileImporter) Name() string {
|
||||
return "importer"
|
||||
}
|
||||
|
||||
func (self *fileImporter) Initialize(context *Context) error {
|
||||
return filepath.Walk(self.sourceDir, func(path string, info os.FileInfo, err error) error {
|
||||
if info.IsDir() {
|
||||
return nil
|
||||
}
|
||||
|
||||
relPath, err := filepath.Rel(self.sourceDir, path)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
file, err := context.CreateFileFromAsset(relPath, path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
context.DispatchFile(file)
|
||||
return nil
|
||||
})
|
||||
}
|
49
file_util.go
49
file_util.go
@ -1,49 +0,0 @@
|
||||
package goldsmith
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type filesByPath []*File
|
||||
|
||||
func (self filesByPath) Len() int {
|
||||
return len(self)
|
||||
}
|
||||
|
||||
func (self filesByPath) Swap(i, j int) {
|
||||
self[i], self[j] = self[j], self[i]
|
||||
}
|
||||
|
||||
func (self filesByPath) Less(i, j int) bool {
|
||||
return strings.Compare(self[i].Path(), self[j].Path()) < 0
|
||||
}
|
||||
|
||||
type fileInfo struct {
|
||||
os.FileInfo
|
||||
path string
|
||||
}
|
||||
|
||||
func cleanPath(path string) string {
|
||||
if filepath.IsAbs(path) {
|
||||
var err error
|
||||
if path, err = filepath.Rel("/", path); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
return filepath.Clean(path)
|
||||
}
|
||||
|
||||
func scanDir(rootDir string, infos chan fileInfo) {
|
||||
defer close(infos)
|
||||
|
||||
filepath.Walk(rootDir, func(path string, info os.FileInfo, err error) error {
|
||||
if err == nil {
|
||||
infos <- fileInfo{FileInfo: info, path: path}
|
||||
}
|
||||
|
||||
return err
|
||||
})
|
||||
}
|
11
goldsmith.go
11
goldsmith.go
@ -8,9 +8,6 @@ import (
|
||||
|
||||
// Goldsmith chainable context.
|
||||
type Goldsmith struct {
|
||||
sourceDir string
|
||||
targetDir string
|
||||
|
||||
contexts []*Context
|
||||
|
||||
cache *cache
|
||||
@ -24,8 +21,8 @@ type Goldsmith struct {
|
||||
|
||||
// Begin starts a chain, reading the files located in the source directory as input.
|
||||
func Begin(sourceDir string) *Goldsmith {
|
||||
goldsmith := &Goldsmith{sourceDir: sourceDir}
|
||||
goldsmith.Chain(&loader{})
|
||||
goldsmith := new(Goldsmith)
|
||||
goldsmith.Chain(&fileImporter{sourceDir: sourceDir})
|
||||
return goldsmith
|
||||
}
|
||||
|
||||
@ -77,9 +74,7 @@ func (self *Goldsmith) FilterPop() *Goldsmith {
|
||||
|
||||
// End stops a chain, writing all recieved files to targetDir as output.
|
||||
func (self *Goldsmith) End(targetDir string) []error {
|
||||
self.targetDir = targetDir
|
||||
|
||||
self.Chain(&saver{clean: self.clean})
|
||||
self.Chain(&fileExporter{targetDir: targetDir, clean: self.clean})
|
||||
for _, context := range self.contexts {
|
||||
go context.step()
|
||||
}
|
||||
|
30
loader.go
30
loader.go
@ -1,30 +0,0 @@
|
||||
package goldsmith
|
||||
|
||||
import "path/filepath"
|
||||
|
||||
type loader struct{}
|
||||
|
||||
func (*loader) Name() string {
|
||||
return "loader"
|
||||
}
|
||||
|
||||
func (*loader) Initialize(context *Context) error {
|
||||
scannedInfo := make(chan fileInfo)
|
||||
go scanDir(context.goldsmith.sourceDir, scannedInfo)
|
||||
|
||||
for info := range scannedInfo {
|
||||
if info.IsDir() {
|
||||
continue
|
||||
}
|
||||
|
||||
relPath, _ := filepath.Rel(context.goldsmith.sourceDir, info.path)
|
||||
file, err := context.CreateFileFromAsset(relPath, info.path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
context.DispatchFile(file)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
49
saver.go
49
saver.go
@ -1,49 +0,0 @@
|
||||
package goldsmith
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
)
|
||||
|
||||
type saver struct {
|
||||
clean bool
|
||||
tokens map[string]bool
|
||||
}
|
||||
|
||||
func (*saver) Name() string {
|
||||
return "saver"
|
||||
}
|
||||
|
||||
func (self *saver) Initialize(context *Context) error {
|
||||
self.tokens = make(map[string]bool)
|
||||
context.Threads(1)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *saver) Process(context *Context, file *File) error {
|
||||
for token := cleanPath(file.relPath); token != "."; token = filepath.Dir(token) {
|
||||
self.tokens[token] = true
|
||||
}
|
||||
|
||||
return file.export(context.goldsmith.targetDir)
|
||||
}
|
||||
|
||||
func (self *saver) Finalize(context *Context) error {
|
||||
if !self.clean {
|
||||
return nil
|
||||
}
|
||||
|
||||
scannedInfo := make(chan fileInfo)
|
||||
go scanDir(context.goldsmith.targetDir, scannedInfo)
|
||||
|
||||
for info := range scannedInfo {
|
||||
if info.path != context.goldsmith.targetDir {
|
||||
relPath, _ := filepath.Rel(context.goldsmith.targetDir, info.path)
|
||||
if contained, _ := self.tokens[relPath]; !contained {
|
||||
os.RemoveAll(info.path)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
Loading…
Reference in New Issue
Block a user