diff --git a/goldsmith.go b/goldsmith.go index 573597a..affc69b 100644 --- a/goldsmith.go +++ b/goldsmith.go @@ -88,7 +88,7 @@ func (gs *goldsmith) makeStage() stage { return s } -func (gs *goldsmith) chainSingle(s stage, cs ChainerSingle) { +func (gs *goldsmith) chainSingle(s stage, cs ChainerSingle, globs []string) { defer close(s.output) var wg sync.WaitGroup @@ -96,7 +96,16 @@ func (gs *goldsmith) chainSingle(s stage, cs ChainerSingle) { wg.Add(1) go func(f File) { defer wg.Done() - if f.Err == nil { + + matched := true + if len(globs) > 0 { + var err error + if matched, err = globMatch(file.Path, globs); err != nil { + file.Err = err + } + } + + if f.Err == nil && matched { s.output <- cs.ChainSingle(f) } else { s.output <- f @@ -107,14 +116,22 @@ func (gs *goldsmith) chainSingle(s stage, cs ChainerSingle) { wg.Wait() } -func (gs *goldsmith) chainMultiple(s stage, cm ChainerMultiple) { +func (gs *goldsmith) chainMultiple(s stage, cm ChainerMultiple, globs []string) { filtered := make(chan File) defer close(filtered) go cm.ChainMultiple(filtered, s.output) for file := range s.input { - if file.Err == nil { + matched := true + if len(globs) > 0 { + var err error + if matched, err = globMatch(file.Path, globs); err != nil { + file.Err = err + } + } + + if file.Err == nil && matched { filtered <- file } else { s.output <- file @@ -130,9 +147,9 @@ func (gs *goldsmith) Chain(ctx Context) Goldsmith { if gs.err = ctx.Err; gs.err == nil { switch c := ctx.Chainer.(type) { case ChainerSingle: - go gs.chainSingle(gs.makeStage(), c) + go gs.chainSingle(gs.makeStage(), c, ctx.Globs) case ChainerMultiple: - go gs.chainMultiple(gs.makeStage(), c) + go gs.chainMultiple(gs.makeStage(), c, ctx.Globs) } } diff --git a/types.go b/types.go index 50ac977..c25e5e6 100644 --- a/types.go +++ b/types.go @@ -46,5 +46,6 @@ type File struct { type Context struct { Chainer interface{} + Globs []string Err error } diff --git a/util.go b/util.go new file mode 100644 index 0000000..55a532f --- /dev/null +++ b/util.go @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2015 Alex Yatskov + * Author: Alex Yatskov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +package goldsmith + +import "path/filepath" + +func globMatch(pattern string, globs []string) (bool, error) { + var ( + match bool + err error + ) + + for _, glob := range globs { + match, err = filepath.Match(pattern, glob) + if err != nil || match { + break + } + } + + return match, err +}