Skip to content

Commit 21272ae

Browse files
committed
feat: support custom template replacement
1 parent 356a360 commit 21272ae

File tree

4 files changed

+121
-1
lines changed

4 files changed

+121
-1
lines changed

pkg/replacer/replacer.go

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import (
99
"os"
1010
"path/filepath"
1111
"strings"
12+
"text/template"
1213
"time"
1314

1415
"github.com/zhufuyi/sponge/pkg/gofile"
@@ -28,6 +29,7 @@ type Replacer interface {
2829
SaveFiles() error
2930
ReadFile(filename string) ([]byte, error)
3031
GetFiles() []string
32+
SaveTemplateFiles(m map[string]interface{}, parentDir ...string) error
3133
}
3234

3335
// replacerInfo replacer information
@@ -287,6 +289,86 @@ func (r *replacerInfo) SaveFiles() error {
287289
return nil
288290
}
289291

292+
// SaveTemplateFiles save file with setting
293+
func (r *replacerInfo) SaveTemplateFiles(m map[string]interface{}, parentDir ...string) error {
294+
refDir := ""
295+
if len(parentDir) > 0 {
296+
refDir = strings.Join(parentDir, gofile.GetPathDelimiter())
297+
}
298+
299+
writeData := make(map[string][]byte, len(r.files))
300+
for _, file := range r.files {
301+
data, err := replaceTemplateData(file, m)
302+
if err != nil {
303+
return err
304+
}
305+
newFilePath := r.getNewFilePath2(file, refDir)
306+
newFilePath = trimExt(newFilePath)
307+
if gofile.IsExists(newFilePath) {
308+
return fmt.Errorf("file %s already exists, cancel code generation", newFilePath)
309+
}
310+
newFilePath, err = replaceTemplateFilePath(newFilePath, m)
311+
if err != nil {
312+
return err
313+
}
314+
writeData[newFilePath] = data
315+
}
316+
317+
for file, data := range writeData {
318+
err := saveToNewFile(file, data)
319+
if err != nil {
320+
return err
321+
}
322+
}
323+
324+
return nil
325+
}
326+
327+
func replaceTemplateData(file string, m map[string]interface{}) ([]byte, error) {
328+
data, err := os.ReadFile(file)
329+
if err != nil {
330+
return nil, fmt.Errorf("read file failed, err=%s", err)
331+
}
332+
if !bytes.Contains(data, []byte("{{")) {
333+
return data, nil
334+
}
335+
336+
builder := bytes.Buffer{}
337+
tmpl, err := template.New(file).Parse(string(data))
338+
if err != nil {
339+
return nil, fmt.Errorf("parse data failed, err=%s", err)
340+
}
341+
err = tmpl.Execute(&builder, m)
342+
if err != nil {
343+
return nil, fmt.Errorf("execute data failed, err=%s", err)
344+
}
345+
return builder.Bytes(), nil
346+
}
347+
348+
func replaceTemplateFilePath(file string, m map[string]interface{}) (string, error) {
349+
if !strings.Contains(file, "{{") {
350+
return file, nil
351+
}
352+
353+
builder := strings.Builder{}
354+
tmpl, err := template.New("file: " + file).Parse(file)
355+
if err != nil {
356+
return file, fmt.Errorf("parse file failed, err=%s", err)
357+
}
358+
err = tmpl.Execute(&builder, m)
359+
if err != nil {
360+
return file, fmt.Errorf("execute file failed, err=%s", err)
361+
}
362+
return builder.String(), nil
363+
}
364+
365+
func trimExt(file string) string {
366+
file = strings.TrimSuffix(file, ".tmpl")
367+
file = strings.TrimSuffix(file, ".tpl")
368+
file = strings.TrimSuffix(file, ".template")
369+
return file
370+
}
371+
290372
func (r *replacerInfo) isIgnoreFile(file string) bool {
291373
isIgnore := false
292374
for _, v := range r.ignoreFiles {
@@ -334,6 +416,18 @@ func (r *replacerInfo) getNewFilePath(file string) string {
334416
return newFilePath
335417
}
336418

419+
func (r *replacerInfo) getNewFilePath2(file string, refDir string) string {
420+
if refDir == "" {
421+
return r.getNewFilePath(file)
422+
}
423+
424+
newFilePath := r.outPath + gofile.GetPathDelimiter() + refDir + gofile.GetPathDelimiter() + strings.Replace(file, r.path, "", 1)
425+
if gofile.IsWindows() {
426+
newFilePath = strings.ReplaceAll(newFilePath, "/", "\\")
427+
}
428+
return newFilePath
429+
}
430+
337431
// if windows, convert the path splitter
338432
func (r *replacerInfo) convertPathDelimiter(filePath string) string {
339433
if r.isActual && gofile.IsWindows() {

pkg/replacer/replacer_test.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,22 @@ func TestNewWithFS(t *testing.T) {
8888
}
8989
}
9090

91+
func TestSaveTemplateFiles(t *testing.T) {
92+
out := fmt.Sprintf("%s/replacer_test/template_%s", os.TempDir(), time.Now().Format("150405"))
93+
m := map[string]interface{}{
94+
"service": map[string]interface{}{"name": "user", "version": 1.0},
95+
"port": 8080,
96+
"isSecure": true,
97+
}
98+
99+
r, err := New("testDir")
100+
assert.NoError(t, err)
101+
_ = r.SetOutputDir(out)
102+
err = r.SaveTemplateFiles(m)
103+
assert.NoError(t, err)
104+
t.Log(out)
105+
}
106+
91107
func TestReplacerError(t *testing.T) {
92108
_, err := New("/notfound")
93109
assert.Error(t, err)

pkg/replacer/testDir/foo.txt

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,7 @@
1-
456
1+
456
2+
3+
{{.service}}
4+
{{.service.name}}
5+
{{.service.version}}
6+
{{.port}}
7+
{{.isSecure}}

pkg/replacer/testDir/replace/test.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
11
test1
22

33
to do replace
4+
5+
{{.service}}
6+
{{.port}}
7+
{{.isSecure}}

0 commit comments

Comments
 (0)