@@ -19,7 +19,6 @@ import (
1919 "embed"
2020 "fmt"
2121 "io"
22- "log/slog"
2322 "os"
2423 "path"
2524 "strconv"
@@ -41,7 +40,7 @@ const (
4140 SkipPython
4241)
4342
44- //go:embed app_template
43+ //go:embed all: app_template
4544var fsApp embed.FS
4645
4746func GenerateApp (basePath * paths.Path , app app.AppDescriptor , options Opts ) error {
@@ -50,6 +49,7 @@ func GenerateApp(basePath *paths.Path, app app.AppDescriptor, options Opts) erro
5049 }
5150 isSkipSketchSet := options & SkipSketch != 0
5251 isSkipPythonSet := options & SkipPython != 0
52+
5353 if ! isSkipSketchSet {
5454 if err := generateSketch (basePath ); err != nil {
5555 return fmt .Errorf ("failed to create sketch: %w" , err )
@@ -60,58 +60,108 @@ func GenerateApp(basePath *paths.Path, app app.AppDescriptor, options Opts) erro
6060 return fmt .Errorf ("failed to create python: %w" , err )
6161 }
6262 }
63- if err := generateReadme (basePath , app ); err != nil {
64- slog .Warn ("error generating readme for app %q: %w" , app .Name , err )
65- }
66- if err := generateAppYaml (basePath , app ); err != nil {
67- return fmt .Errorf ("failed to create app content: %w" , err )
63+
64+ if err := generateApp (basePath , app ); err != nil {
65+ return fmt .Errorf ("failed to create app.yaml: %w" , err )
6866 }
6967
7068 return nil
7169}
7270
73- func generateAppYaml (basePath * paths.Path , app app.AppDescriptor ) error {
74- appYamlTmpl := template .Must (
75- template .New ("app.yaml" ).
76- Funcs (template.FuncMap {"joinInts" : formatPorts }).
77- ParseFS (fsApp , path .Join (templateRoot , "app.yaml.template" )),
78- )
71+ func generateApp (basePath * paths.Path , appDesc app.AppDescriptor ) error {
72+ generateAppYaml := func (basePath * paths.Path , app app.AppDescriptor ) error {
73+ appYamlTmpl := template .Must (
74+ template .New ("app.yaml" ).
75+ Funcs (template.FuncMap {"joinInts" : formatPorts }).
76+ ParseFS (fsApp , path .Join (templateRoot , "app.yaml.template" )),
77+ )
7978
80- outputPath := basePath .Join ("app.yaml" )
81- file , err := os .Create (outputPath .String ())
82- if err != nil {
83- return fmt .Errorf ("failed to create file %s: %w" , outputPath .String (), err )
84- }
85- defer file .Close ()
79+ outputPath := basePath .Join ("app.yaml" )
80+ file , err := os .Create (outputPath .String ())
81+ if err != nil {
82+ return fmt .Errorf ("failed to create file %s: %w" , outputPath .String (), err )
83+ }
84+ defer file .Close ()
85+
86+ return appYamlTmpl .ExecuteTemplate (file , "app.yaml.template" , app )
87+ }
88+
89+ generateReadme := func (basePath * paths.Path , app app.AppDescriptor ) error {
90+ readmeTmpl := template .Must (template .ParseFS (fsApp , path .Join (templateRoot , "README.md.template" )))
91+ data := struct {
92+ Title string
93+ Icon string
94+ Description string
95+ Ports string
96+ }{
97+ Title : app .Name ,
98+ Icon : app .Icon ,
99+ Description : app .Description ,
100+ }
86101
87- return appYamlTmpl .ExecuteTemplate (file , "app.yaml.template" , app )
88- }
102+ if len (app .Ports ) > 0 {
103+ data .Ports = "Available application ports: " + formatPorts (app .Ports )
104+ }
89105
90- func generateReadme (basePath * paths.Path , app app.AppDescriptor ) error {
91- readmeTmpl := template .Must (template .ParseFS (fsApp , path .Join (templateRoot , "README.md.template" )))
92- data := struct {
93- Title string
94- Icon string
95- Description string
96- Ports string
97- }{
98- Title : app .Name ,
99- Icon : app .Icon ,
100- Description : app .Description ,
106+ outputPath := basePath .Join ("README.md" )
107+ file , err := os .Create (outputPath .String ())
108+ if err != nil {
109+ return fmt .Errorf ("failed to create file %s: %w" , outputPath .String (), err )
110+ }
111+ defer file .Close ()
112+
113+ return readmeTmpl .Execute (file , data )
101114 }
102115
103- if len (app .Ports ) > 0 {
104- data .Ports = "Available application ports: " + formatPorts (app .Ports )
116+ copyRootFiles := func () error {
117+ fileList , err := fsApp .ReadDir (templateRoot )
118+ if err != nil {
119+ return fmt .Errorf ("read template directory: %w" , err )
120+ }
121+ for _ , filePath := range fileList {
122+ if filePath .IsDir () {
123+ continue
124+ }
125+ if path .Ext (filePath .Name ()) == ".template" {
126+ continue
127+ }
128+
129+ srcPath := path .Join (templateRoot , filePath .Name ())
130+ destPath := basePath .Join (filePath .Name ())
131+
132+ if err := func () error {
133+ srcFile , err := fsApp .Open (srcPath )
134+ if err != nil {
135+ return err
136+ }
137+ defer srcFile .Close ()
138+
139+ destFile , err := destPath .Create ()
140+ if err != nil {
141+ return fmt .Errorf ("create %q file: %w" , destPath , err )
142+ }
143+ defer destFile .Close ()
144+
145+ _ , err = io .Copy (destFile , srcFile )
146+ return err
147+ }(); err != nil {
148+ return fmt .Errorf ("copy file %s: %w" , filePath .Name (), err )
149+ }
150+ }
151+ return nil
105152 }
106153
107- outputPath := basePath .Join ("README.md" )
108- file , err := os .Create (outputPath .String ())
109- if err != nil {
110- return fmt .Errorf ("failed to create file %s: %w" , outputPath .String (), err )
154+ if err := copyRootFiles (); err != nil {
155+ return fmt .Errorf ("copy root files: %w" , err )
156+ }
157+ if err := generateAppYaml (basePath , appDesc ); err != nil {
158+ return fmt .Errorf ("generate app.yaml: %w" , err )
159+ }
160+ if err := generateReadme (basePath , appDesc ); err != nil {
161+ return fmt .Errorf ("generate README.md: %w" , err )
111162 }
112- defer file .Close ()
113163
114- return readmeTmpl . Execute ( file , data )
164+ return nil
115165}
116166
117167func generatePython (basePath * paths.Path ) error {
0 commit comments