Compare commits
2 Commits
972c4d81f5
...
2dd1fdbfa5
Author | SHA1 | Date | |
---|---|---|---|
2dd1fdbfa5 | |||
acc22a9b84 |
5
cache.go
5
cache.go
@ -8,6 +8,7 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"sort"
|
"sort"
|
||||||
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
type cache struct {
|
type cache struct {
|
||||||
@ -72,7 +73,9 @@ func (self *cache) buildCachePath(context *Context, outputPath string, inputFile
|
|||||||
hasher := crc32.NewIEEE()
|
hasher := crc32.NewIEEE()
|
||||||
hasher.Write([]byte(outputPath))
|
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 {
|
for _, inputFile := range inputFiles {
|
||||||
modTimeBuff := make([]byte, 8)
|
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.
|
// Goldsmith chainable context.
|
||||||
type Goldsmith struct {
|
type Goldsmith struct {
|
||||||
sourceDir string
|
|
||||||
targetDir string
|
|
||||||
|
|
||||||
contexts []*Context
|
contexts []*Context
|
||||||
|
|
||||||
cache *cache
|
cache *cache
|
||||||
@ -24,8 +21,8 @@ type Goldsmith struct {
|
|||||||
|
|
||||||
// Begin starts a chain, reading the files located in the source directory as input.
|
// Begin starts a chain, reading the files located in the source directory as input.
|
||||||
func Begin(sourceDir string) *Goldsmith {
|
func Begin(sourceDir string) *Goldsmith {
|
||||||
goldsmith := &Goldsmith{sourceDir: sourceDir}
|
goldsmith := new(Goldsmith)
|
||||||
goldsmith.Chain(&loader{})
|
goldsmith.Chain(&fileImporter{sourceDir: sourceDir})
|
||||||
return goldsmith
|
return goldsmith
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -77,9 +74,7 @@ func (self *Goldsmith) FilterPop() *Goldsmith {
|
|||||||
|
|
||||||
// End stops a chain, writing all recieved files to targetDir as output.
|
// End stops a chain, writing all recieved files to targetDir as output.
|
||||||
func (self *Goldsmith) End(targetDir string) []error {
|
func (self *Goldsmith) End(targetDir string) []error {
|
||||||
self.targetDir = targetDir
|
self.Chain(&fileExporter{targetDir: targetDir, clean: self.clean})
|
||||||
|
|
||||||
self.Chain(&saver{clean: self.clean})
|
|
||||||
for _, context := range self.contexts {
|
for _, context := range self.contexts {
|
||||||
go context.step()
|
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