summaryrefslogtreecommitdiff
path: root/template.go
diff options
context:
space:
mode:
authorSong Li <45057405+lliissoonngg@users.noreply.github.com>2024-02-05 20:36:18 -0500
committerGitHub <noreply@github.com>2024-02-06 01:36:18 +0000
commit4d24b9d1eb9b9020107c083a55ffa2de97740d22 (patch)
tree323423d05216a8facccee3b245b8eba7fc5cb0a3 /template.go
parent24879386331ca4e58efcfa47736b850404c36f7a (diff)
Add --exclude-processing option (#1963)
* add --exclude-processing option * update documentation * add tests and address some PR comments * fix linting errors * TODO comment --------- Co-authored-by: Dave Henderson <dhenderson@gmail.com>
Diffstat (limited to 'template.go')
-rw-r--r--template.go99
1 files changed, 83 insertions, 16 deletions
diff --git a/template.go b/template.go
index 8c0aa64a..dbdabf36 100644
--- a/template.go
+++ b/template.go
@@ -204,7 +204,7 @@ func gatherTemplates(ctx context.Context, cfg *config.Config, outFileNamer func(
}}
case cfg.InputDir != "":
// input dirs presume output dirs are set too
- templates, err = walkDir(ctx, cfg, cfg.InputDir, outFileNamer, cfg.ExcludeGlob, mode, modeOverride)
+ templates, err = walkDir(ctx, cfg, cfg.InputDir, outFileNamer, cfg.ExcludeGlob, cfg.ExcludeProcessingGlob, mode, modeOverride)
if err != nil {
return nil, fmt.Errorf("walkDir: %w", err)
}
@@ -224,7 +224,7 @@ func gatherTemplates(ctx context.Context, cfg *config.Config, outFileNamer func(
// walkDir - given an input dir `dir` and an output dir `outDir`, and a list
// 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(ctx context.Context, cfg *config.Config, dir string, outFileNamer func(context.Context, string) (string, error), excludeGlob []string, mode os.FileMode, modeOverride bool) ([]Template, error) {
+func walkDir(ctx context.Context, cfg *config.Config, dir string, outFileNamer func(context.Context, string) (string, error), excludeGlob []string, excludeProcessingGlob []string, mode os.FileMode, modeOverride bool) ([]Template, error) {
dir = filepath.ToSlash(filepath.Clean(dir))
// get a filesystem rooted in the same volume as dir (or / on non-Windows)
@@ -256,7 +256,7 @@ func walkDir(ctx context.Context, cfg *config.Config, dir string, outFileNamer f
templates := make([]Template, 0)
matcher := xignore.NewMatcher(subfsys)
- matches, err := matcher.Matches(".", &xignore.MatchesOptions{
+ excludeMatches, err := matcher.Matches(".", &xignore.MatchesOptions{
Ignorefile: gomplateignore,
Nested: true, // allow nested ignorefile
AfterPatterns: excludeGlob,
@@ -265,8 +265,25 @@ func walkDir(ctx context.Context, cfg *config.Config, dir string, outFileNamer f
return nil, fmt.Errorf("ignore matching failed for %s: %w", dir, err)
}
+ excludeProcessingMatches, err := matcher.Matches(".", &xignore.MatchesOptions{
+ // TODO: fix or replace xignore module so we can avoid attempting to read the .gomplateignore file for both exclude and excludeProcessing patterns
+ Ignorefile: gomplateignore,
+ Nested: true, // allow nested ignorefile
+ AfterPatterns: excludeProcessingGlob,
+ })
+ if err != nil {
+ return nil, fmt.Errorf("passthough matching failed for %s: %w", dir, err)
+ }
+
+ passthroughFiles := make(map[string]bool)
+
+ for _, file := range excludeProcessingMatches.MatchedFiles {
+ // files that need to be directly copied
+ passthroughFiles[file] = true
+ }
+
// Unmatched ignorefile rules's files
- for _, file := range matches.UnmatchedFiles {
+ for _, file := range excludeMatches.UnmatchedFiles {
// we want to pass an absolute (as much as possible) path to fileToTemplate
inPath := filepath.Join(dir, file)
inPath = filepath.ToSlash(inPath)
@@ -277,6 +294,16 @@ func walkDir(ctx context.Context, cfg *config.Config, dir string, outFileNamer f
return nil, fmt.Errorf("outFileNamer: %w", err)
}
+ _, ok := passthroughFiles[file]
+ if ok {
+ err = copyFileToOutDir(ctx, cfg, inPath, outFile, mode, modeOverride)
+ if err != nil {
+ return nil, fmt.Errorf("copyFileToOutDir: %w", err)
+ }
+
+ continue
+ }
+
tpl, err := fileToTemplate(ctx, cfg, inPath, outFile, mode, modeOverride)
if err != nil {
return nil, fmt.Errorf("fileToTemplate: %w", err)
@@ -297,46 +324,86 @@ func walkDir(ctx context.Context, cfg *config.Config, dir string, outFileNamer f
return templates, nil
}
-func fileToTemplate(ctx context.Context, cfg *config.Config, inFile, outFile string, mode os.FileMode, modeOverride bool) (Template, error) {
- source := ""
+func readInFile(ctx context.Context, cfg *config.Config, inFile string, mode os.FileMode) (source string, newmode os.FileMode, err error) {
+ newmode = mode
+ var b []byte
//nolint:nestif
if inFile == "-" {
- b, err := io.ReadAll(cfg.Stdin)
+ b, err = io.ReadAll(cfg.Stdin)
if err != nil {
- return Template{}, fmt.Errorf("read from stdin: %w", err)
+ return source, newmode, fmt.Errorf("read from stdin: %w", err)
}
source = string(b)
} else {
- fsys, err := datafs.FSysForPath(ctx, inFile)
+ var fsys fs.FS
+ var si fs.FileInfo
+ fsys, err = datafs.FSysForPath(ctx, inFile)
if err != nil {
- return Template{}, fmt.Errorf("fsysForPath: %w", err)
+ return source, newmode, fmt.Errorf("fsysForPath: %w", err)
}
- si, err := fs.Stat(fsys, inFile)
+ si, err = fs.Stat(fsys, inFile)
if err != nil {
- return Template{}, fmt.Errorf("stat %q: %w", inFile, err)
+ return source, newmode, fmt.Errorf("stat %q: %w", inFile, err)
}
if mode == 0 {
- mode = si.Mode()
+ newmode = si.Mode()
}
// we read the file and store in memory immediately, to prevent leaking
// file descriptors.
- b, err := fs.ReadFile(fsys, inFile)
+ b, err = fs.ReadFile(fsys, inFile)
if err != nil {
- return Template{}, fmt.Errorf("readAll %q: %w", inFile, err)
+ return source, newmode, fmt.Errorf("readAll %q: %w", inFile, err)
}
source = string(b)
}
+ return source, newmode, err
+}
+func getOutfileHandler(ctx context.Context, cfg *config.Config, outFile string, mode os.FileMode, modeOverride bool) (io.Writer, error) {
// open the output file - no need to close it, as it will be closed by the
// caller later
target, err := openOutFile(ctx, outFile, 0o755, mode, modeOverride, cfg.Stdout, cfg.SuppressEmpty)
if err != nil {
- return Template{}, fmt.Errorf("openOutFile: %w", err)
+ return nil, fmt.Errorf("openOutFile: %w", err)
+ }
+
+ return target, nil
+}
+
+func copyFileToOutDir(ctx context.Context, cfg *config.Config, inFile, outFile string, mode os.FileMode, modeOverride bool) error {
+ sourceStr, newmode, err := readInFile(ctx, cfg, inFile, mode)
+ if err != nil {
+ return err
+ }
+
+ outFH, err := getOutfileHandler(ctx, cfg, outFile, newmode, modeOverride)
+ if err != nil {
+ return err
+ }
+
+ wr, ok := outFH.(io.Closer)
+ if ok && wr != os.Stdout {
+ defer wr.Close()
+ }
+
+ _, err = outFH.Write([]byte(sourceStr))
+ return err
+}
+
+func fileToTemplate(ctx context.Context, cfg *config.Config, inFile, outFile string, mode os.FileMode, modeOverride bool) (Template, error) {
+ source, newmode, err := readInFile(ctx, cfg, inFile, mode)
+ if err != nil {
+ return Template{}, err
+ }
+
+ target, err := getOutfileHandler(ctx, cfg, outFile, newmode, modeOverride)
+ if err != nil {
+ return Template{}, err
}
tmpl := Template{