@@ -41,7 +41,7 @@ const (
4141 SkipPython
4242)
4343
44- //go:embed app_template
44+ //go:embed all: app_template
4545var fsApp embed.FS
4646
4747func GenerateApp (basePath * paths.Path , app app.AppDescriptor , options Opts ) error {
@@ -50,6 +50,7 @@ func GenerateApp(basePath *paths.Path, app app.AppDescriptor, options Opts) erro
5050 }
5151 isSkipSketchSet := options & SkipSketch != 0
5252 isSkipPythonSet := options & SkipPython != 0
53+
5354 if ! isSkipSketchSet {
5455 if err := generateSketch (basePath ); err != nil {
5556 return fmt .Errorf ("failed to create sketch: %w" , err )
@@ -60,58 +61,109 @@ func GenerateApp(basePath *paths.Path, app app.AppDescriptor, options Opts) erro
6061 return fmt .Errorf ("failed to create python: %w" , err )
6162 }
6263 }
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 )
64+
65+ if err := generateApp (basePath , app ); err != nil {
66+ return fmt .Errorf ("failed to create app.yaml: %w" , err )
6867 }
6968
7069 return nil
7170}
7271
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- )
72+ func generateApp (basePath * paths.Path , appDesc app.AppDescriptor ) error {
73+ generateAppYaml := func (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+ )
7979
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 ()
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 ()
86+
87+ return appYamlTmpl .ExecuteTemplate (file , "app.yaml.template" , app )
88+ }
89+
90+ generateReadme := func (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 ,
101+ }
86102
87- return appYamlTmpl .ExecuteTemplate (file , "app.yaml.template" , app )
88- }
103+ if len (app .Ports ) > 0 {
104+ data .Ports = "Available application ports: " + formatPorts (app .Ports )
105+ }
89106
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 ,
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 )
111+ }
112+ defer file .Close ()
113+
114+ return readmeTmpl .Execute (file , data )
115+ }
116+
117+ copyRootFiles := func () error {
118+ fileList , err := fsApp .ReadDir (templateRoot )
119+ if err != nil {
120+ return fmt .Errorf ("read template directory: %w" , err )
121+ }
122+ for _ , filePath := range fileList {
123+ if filePath .IsDir () {
124+ continue
125+ }
126+ if path .Ext (filePath .Name ()) == ".template" {
127+ continue
128+ }
129+
130+ srcPath := path .Join (templateRoot , filePath .Name ())
131+ destPath := basePath .Join (filePath .Name ())
132+
133+ if err := func () error {
134+ srcFile , err := fsApp .Open (srcPath )
135+ if err != nil {
136+ return err
137+ }
138+ defer srcFile .Close ()
139+
140+ destFile , err := destPath .Create ()
141+ if err != nil {
142+ return fmt .Errorf ("create %q file: %w" , destPath , err )
143+ }
144+ defer destFile .Close ()
145+
146+ _ , err = io .Copy (destFile , srcFile )
147+ return err
148+ }(); err != nil {
149+ return fmt .Errorf ("copy file %s: %w" , filePath .Name (), err )
150+ }
151+ }
152+ return nil
101153 }
102154
103- if len (app .Ports ) > 0 {
104- data .Ports = "Available application ports: " + formatPorts (app .Ports )
155+ if err := copyRootFiles (); err != nil {
156+ slog .Warn ("error copying root files for app %q: %w" , appDesc .Name , err )
157+ }
158+ if err := generateReadme (basePath , appDesc ); err != nil {
159+ slog .Warn ("error generating readme for app %q: %w" , appDesc .Name , err )
105160 }
106161
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 )
162+ if err := generateAppYaml (basePath , appDesc ); err != nil {
163+ return fmt .Errorf ("generate app.yaml: %w" , err )
111164 }
112- defer file .Close ()
113165
114- return readmeTmpl . Execute ( file , data )
166+ return nil
115167}
116168
117169func generatePython (basePath * paths.Path ) error {
0 commit comments