diff options
| author | Zealic <zealic@gmail.com> | 2019-02-03 01:01:36 +0800 |
|---|---|---|
| committer | Dave Henderson <dhenderson@gmail.com> | 2019-02-02 12:01:36 -0500 |
| commit | d1873444c90e68b5e8ba7492fb83abd36d7ab0ea (patch) | |
| tree | 49fee8234e7793aa8ecd82dd0f8248988f7a9cf8 /template.go | |
| parent | 462c8fde7cd829d80ccfb379c015dd7c463adc68 (diff) | |
Add .gomplateignore support (#225)
* Add .gomplateignore support
* + Added xignore dependency.
* Fix gometalinter problem : gocyclo and unconvert
* Use xignore to support .gomplateignore.
* Adding intgegration tests for .gomplateignore
* Use AfterPatterns to replace default exclude option implement.
* * Fix lint issue.
* * Fix unittest issue.
* * Clean test files.
* Update docs/content/usage.md
Co-Authored-By: zealic <zealic@gmail.com>
* Use minor range version for xignore.
* Unexport .gomplateignore const.
Diffstat (limited to 'template.go')
| -rw-r--r-- | template.go | 96 |
1 files changed, 37 insertions, 59 deletions
diff --git a/template.go b/template.go index 1741de10..b79e024f 100644 --- a/template.go +++ b/template.go @@ -14,8 +14,12 @@ import ( "github.com/pkg/errors" "github.com/spf13/afero" + "github.com/zealic/xignore" ) +// ignorefile name, like .gitignore +const gomplateignore = ".gomplateignore" + // for overriding in tests var stdin io.ReadCloser = os.Stdin var fs = afero.NewOsFs() @@ -139,57 +143,57 @@ func processTemplates(templates []*tplate) ([]*tplate, error) { } // walkDir - given an input dir `dir` and an output dir `outDir`, and a list -// of exclude globs (if any), walk the input directory and create a list of +// of .gomplateignore and exclude globs (if any), walk the input directory and create a list of // tplate objects, and an error, if any. func walkDir(dir, outDir string, excludeGlob []string, mode os.FileMode, modeOverride bool) ([]*tplate, error) { dir = filepath.Clean(dir) outDir = filepath.Clean(outDir) - si, err := fs.Stat(dir) - if err != nil { - return nil, err - } - entries, err := afero.ReadDir(fs, dir) + dirStat, err := fs.Stat(dir) if err != nil { return nil, err } + dirMode := dirStat.Mode() - if err = fs.MkdirAll(outDir, si.Mode()); err != nil { - return nil, err - } - - excludes, err := executeCombinedGlob(excludeGlob) + templates := make([]*tplate, 0) + matcher := xignore.NewMatcher(fs) + matches, err := matcher.Matches(dir, &xignore.MatchesOptions{ + Ignorefile: gomplateignore, + Nested: true, // allow nested ignorefile + AfterPatterns: excludeGlob, + }) if err != nil { return nil, err } - templates := make([]*tplate, 0) - for _, entry := range entries { - nextInPath := filepath.Join(dir, entry.Name()) - nextOutPath := filepath.Join(outDir, entry.Name()) + // Unmatched ignorefile rules's files + files := matches.UnmatchedFiles + for _, file := range files { + nextInPath := filepath.Join(dir, file) + nextOutPath := filepath.Join(outDir, file) - if inList(excludes, nextInPath) { - continue + if mode == 0 { + stat, perr := fs.Stat(nextInPath) + if perr == nil { + mode = stat.Mode() + } else { + mode = dirMode + } } - if entry.IsDir() { - t, err := walkDir(nextInPath, nextOutPath, excludes, mode, modeOverride) - if err != nil { - return nil, err - } - templates = append(templates, t...) - } else { - if mode == 0 { - mode = entry.Mode() - } - templates = append(templates, &tplate{ - name: nextInPath, - targetPath: nextOutPath, - mode: mode, - modeOverride: modeOverride, - }) + // Ensure file parent dirs + if err = fs.MkdirAll(filepath.Dir(nextOutPath), dirMode); err != nil { + return nil, err } + + templates = append(templates, &tplate{ + name: nextInPath, + targetPath: nextOutPath, + mode: mode, + modeOverride: modeOverride, + }) } + return templates, nil } @@ -213,16 +217,6 @@ func fileToTemplates(inFile, outFile string, mode os.FileMode, modeOverride bool return tmpl, nil } -func inList(list []string, entry string) bool { - for _, file := range list { - if file == entry { - return true - } - } - - return false -} - func openOutFile(filename string, mode os.FileMode, modeOverride bool) (out io.WriteCloser, err error) { if conv.ToBool(env.Getenv("GOMPLATE_SUPPRESS_EMPTY", "false")) { out = newEmptySkipper(func() (io.WriteCloser, error) { @@ -272,22 +266,6 @@ func readInput(filename string) (string, error) { return string(bytes), nil } -// takes an array of glob strings and executes it as a whole, -// returning a merged list of globbed files -func executeCombinedGlob(globArray []string) ([]string, error) { - var combinedExcludes []string - for _, glob := range globArray { - excludeList, err := afero.Glob(fs, glob) - if err != nil { - return nil, err - } - - combinedExcludes = append(combinedExcludes, excludeList...) - } - - return combinedExcludes, nil -} - // emptySkipper is a io.WriteCloser wrapper that will only start writing once a // non-whitespace byte has been encountered. The writer must be provided by the // `open` func |
