Interface refactoring

This commit is contained in:
Alex Yatskov 2015-11-11 14:21:47 +09:00
parent 1c8f6109f9
commit 187f25cddd
2 changed files with 54 additions and 46 deletions

View File

@ -55,6 +55,25 @@ func New(srcDir, dstDir string) Goldsmith {
return gs
}
func NewFile(path string) *File {
return &File{
Path: cleanPath(path),
Meta: make(map[string]interface{}),
}
}
func NewFileStatic(path string) *File {
file := NewFile(path)
file.Type = FileStatic
return file
}
func NewFileRef(path string) *File {
file := NewFile(path)
file.Type = FileReference
return file
}
func (gs *goldsmith) scanFs() error {
fileMatches, _, err := scanDir(gs.srcDir)
if err != nil {
@ -72,7 +91,7 @@ func (gs *goldsmith) scanFs() error {
panic(err)
}
file := gs.NewFile(relPath)
file := NewFile(relPath)
var f *os.File
if f, file.Err = os.Open(match); file.Err == nil {
@ -120,6 +139,11 @@ func (gs *goldsmith) exportFile(file *File) {
return
}
if file.Type == FileReference {
gs.refFile(file.Path)
return
}
absPath := filepath.Join(gs.dstDir, file.Path)
if file.Err = os.MkdirAll(path.Dir(absPath), 0755); file.Err != nil {
return
@ -129,7 +153,7 @@ func (gs *goldsmith) exportFile(file *File) {
if f, file.Err = os.Create(absPath); file.Err == nil {
defer f.Close()
if _, file.Err = f.Write(file.Buff.Bytes()); file.Err == nil {
gs.RefFile(file.Path)
gs.refFile(file.Path)
}
}
}
@ -162,12 +186,12 @@ func (gs *goldsmith) chain(s stage, c Chainer) {
wg.Add(1)
go func() {
f, _ := c.(Filterer)
a, _ := c.(Accepter)
for file := range s.input {
if file.flags&FileFlagStatic != 0 || (f != nil && f.Filter(file.Path)) {
s.output <- file
} else {
if file.Type == FileNormal && (a == nil || a.Accept(file)) {
input <- file
} else {
s.output <- file
}
}
@ -183,37 +207,8 @@ func (gs *goldsmith) chain(s stage, c Chainer) {
}()
}
func (gs *goldsmith) NewFile(path string) *File {
if filepath.IsAbs(path) {
var err error
path, err = filepath.Rel("/", path)
if err != nil {
panic(err)
}
}
return &File{
Path: filepath.Clean(path),
Meta: make(map[string]interface{}),
}
}
func (gs *goldsmith) NewFileStatic(path string) *File {
file := gs.NewFile(path)
file.flags |= FileFlagStatic
return file
}
func (gs *goldsmith) RefFile(path string) {
if filepath.IsAbs(path) {
var err error
path, err = filepath.Rel("/", path)
if err != nil {
panic(err)
}
}
path = filepath.Clean(path)
func (gs *goldsmith) refFile(path string) {
path = cleanPath(path)
for {
gs.refs[path] = true
@ -262,6 +257,17 @@ func (gs *goldsmith) Complete() ([]*File, error) {
return files, gs.err
}
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(root string) (files, dirs []string, err error) {
err = filepath.Walk(root, func(path string, info os.FileInfo, err error) error {
if err != nil {

View File

@ -33,25 +33,27 @@ type Chainer interface {
Chain(ctx Context, input, output chan *File)
}
type Filterer interface {
Filter(path string) bool
type Accepter interface {
Accept(file *File) bool
}
type FileType int
const (
FileNormal FileType = iota
FileStatic
FileReference
)
type File struct {
Path string
Meta map[string]interface{}
Buff bytes.Buffer
Err error
flags uint32
Type FileType
}
type Context interface {
NewFileStatic(path string) *File
NewFile(path string) *File
RefFile(path string)
SrcDir() string
DstDir() string
}