@@ -2,11 +2,12 @@ package generate
22
33import (
44 "fmt"
5+ "io"
6+ "log"
57 "os"
68 "path"
79 "path/filepath"
810 "regexp"
9- "strings"
1011 "sync"
1112 "text/template"
1213
@@ -15,8 +16,9 @@ import (
1516 "github.com/commitdev/zero/internal/module"
1617 "github.com/commitdev/zero/internal/util"
1718 "github.com/commitdev/zero/pkg/util/flog"
18-
1919 "github.com/commitdev/zero/pkg/util/fs"
20+
21+ "github.com/gabriel-vasile/mimetype"
2022)
2123
2224// Generate accepts a projectconfig struct and renders the templates for all referenced modules
@@ -52,22 +54,23 @@ func Generate(projectConfig projectconfig.ZeroProjectConfig) error {
5254 mod .Parameters ,
5355 }
5456
55- fileTemplates := newTemplates (moduleDir , outputDir , false )
57+ txtTypeFiles , binTypeFiles := sortFileType (moduleDir , outputDir , false )
5658
57- executeTemplates (fileTemplates , templateData , delimiters )
59+ executeTemplates (txtTypeFiles , templateData , delimiters )
60+ copyBinFiles (binTypeFiles )
5861 }
5962 return nil
6063}
6164
62- type TemplateConfig struct {
65+ type fileConfig struct {
6366 source string
6467 destination string
65- isTemplate bool
6668}
6769
68- // newTemplates walks the module directory to find all to be templated
69- func newTemplates (moduleDir string , outputDir string , overwrite bool ) []* TemplateConfig {
70- templates := []* TemplateConfig {}
70+ // sortFileType walks the module directory to find and classify all files into bin / text/plain (non-bin) types.
71+ func sortFileType (moduleDir string , outputDir string , overwrite bool ) ([]* fileConfig , []* fileConfig ) {
72+ binTypeFiles := []* fileConfig {}
73+ txtTypeFiles := []* fileConfig {}
7174
7275 paths , err := getAllFilePathsInDirectory (moduleDir )
7376 if err != nil {
@@ -80,11 +83,6 @@ func newTemplates(moduleDir string, outputDir string, overwrite bool) []*Templat
8083 continue
8184 }
8285
83- _ , file := filepath .Split (path )
84- hasTmpltSuffix := strings .HasSuffix (file , constants .TemplateExtn )
85- if hasTmpltSuffix {
86- file = strings .Replace (file , constants .TemplateExtn , "" , - 1 )
87- }
8886 outputPath := fs .ReplacePath (path , moduleDir , outputDir )
8987
9088 if ! overwrite {
@@ -94,13 +92,34 @@ func newTemplates(moduleDir string, outputDir string, overwrite bool) []*Templat
9492 }
9593 }
9694
97- templates = append (templates , & TemplateConfig {
95+ // detect the file type
96+ detectedMIME , err := mimetype .DetectFile (path )
97+ if err != nil {
98+ panic (err )
99+ }
100+
101+ // detect root file type
102+ isBinary := true
103+ for mime := detectedMIME ; mime != nil ; mime = mime .Parent () {
104+ if mime .Is ("text/plain" ) {
105+ isBinary = false
106+ }
107+ }
108+
109+ if isBinary {
110+ binTypeFiles = append (binTypeFiles , & fileConfig {
111+ source : path ,
112+ destination : outputPath ,
113+ })
114+ continue
115+ }
116+
117+ txtTypeFiles = append (txtTypeFiles , & fileConfig {
98118 source : path ,
99119 destination : outputPath ,
100- isTemplate : hasTmpltSuffix ,
101120 })
102121 }
103- return templates
122+ return txtTypeFiles , binTypeFiles
104123}
105124
106125// getAllFilePathsInDirectory Recursively get all file paths in directory, including sub-directories.
@@ -122,7 +141,7 @@ func getAllFilePathsInDirectory(moduleDir string) ([]string, error) {
122141 return paths , nil
123142}
124143
125- func executeTemplates (templates []* TemplateConfig , data interface {}, delimiters []string ) {
144+ func executeTemplates (templates []* fileConfig , data interface {}, delimiters []string ) {
126145 var wg sync.WaitGroup
127146 leftDelim := delimiters [0 ]
128147 rightDelim := delimiters [1 ]
@@ -162,3 +181,40 @@ func executeTemplates(templates []*TemplateConfig, data interface{}, delimiters
162181
163182 wg .Wait ()
164183}
184+
185+ func copyBinFiles (binTypeFiles []* fileConfig ) {
186+
187+ for _ , binFile := range binTypeFiles {
188+ source := binFile .source
189+ dest := binFile .destination
190+
191+ // create dir
192+ outputDirPath , _ := path .Split (dest )
193+ err := fs .CreateDirs (outputDirPath )
194+ if err != nil {
195+ flog .Errorf ("Error creating directory '%s': %v" , source , err )
196+ }
197+
198+ // create refs to src and dest
199+ from , err := os .Open (source )
200+ if err != nil {
201+ flog .Errorf ("Error opening file to read '%s' : %v" , source , err )
202+ }
203+ defer from .Close ()
204+
205+ to , err := os .OpenFile (dest , os .O_RDWR | os .O_CREATE , 0666 )
206+ if err != nil {
207+ log .Fatal (err )
208+ flog .Errorf ("Error creating file '%s': %v" , dest , err )
209+ }
210+ defer to .Close ()
211+
212+ // copy file
213+ _ , err = io .Copy (to , from )
214+ if err != nil {
215+ flog .Errorf ("Error copying file '%s' : %v" , source , err )
216+ } else {
217+ flog .Successf ("Finished copying file : %s" , dest )
218+ }
219+ }
220+ }
0 commit comments