5
0
mirror of https://github.com/wailsapp/wails.git synced 2025-05-02 23:39:21 +08:00
wails/v2/pkg/parser/generate.go
Eng Zer Jun ef8d7d2fd7
refactor: move from io/ioutil to io and os packages
The io/ioutil package has been deprecated as of Go 1.16, see
https://golang.org/doc/go1.16#ioutil. This commit replaces the existing
io/ioutil functions with their new definitions in io and os packages.

Signed-off-by: Eng Zer Jun <engzerjun@gmail.com>
2021-11-25 12:15:43 +08:00

251 lines
5.7 KiB
Go

package parser
import (
"bytes"
_ "embed"
"os"
"path/filepath"
"text/template"
"github.com/pkg/errors"
"github.com/wailsapp/wails/v2/internal/fs"
)
//go:embed index.template
var indexTemplate string
//go:embed index.d.template
var indexDTemplate string
//go:embed package.template
var packageTemplate string
//go:embed package.d.template
var packageDTemplate string
//go:embed globals.d.template
var globalsDTemplate string
//go:embed package.json
var packageJSON string
// GenerateWailsFrontendPackage will generate a Javascript/Typescript
// package in `<project>/frontend/wails` that defines which methods
// and structs are bound to your frontend
func GenerateWailsFrontendPackage() (*ParserReport, error) {
dir, err := os.Getwd()
if err != nil {
return nil, err
}
p := NewParser()
err = p.ParseProject(dir)
if err != nil {
return nil, err
}
err = p.generateModule()
return p.parserReport(), err
}
func (p *Parser) generateModule() error {
moduleDir, err := createBackendJSDirectory()
if err != nil {
return err
}
packagesToGenerate := p.packagesToGenerate()
for _, pkg := range packagesToGenerate {
err := generatePackage(pkg, moduleDir)
if err != nil {
return err
}
}
// Copy the standard files
tgtFile := filepath.Join(moduleDir, "package.json")
err = fs.CopyFile(packageJSON, tgtFile)
if err != nil {
return err
}
// Generate the globals.d.ts file
err = generateGlobalsTS(moduleDir, packagesToGenerate)
if err != nil {
return err
}
// Generate the index.js file
err = generateIndexJS(moduleDir, packagesToGenerate)
if err != nil {
return err
}
// Generate the index.d.ts file
err = generateIndexTS(moduleDir, packagesToGenerate)
if err != nil {
return err
}
return nil
}
func createBackendJSDirectory() (string, error) {
// Calculate the package directory
// Note this is *always* called from the project directory
// so using paths relative to CWD is fine
dir, err := fs.RelativeToCwd("./frontend/backend")
if err != nil {
return "", errors.Wrap(err, "Error creating backend module directory")
}
// Remove directory if it exists - REGENERATION!
err = os.RemoveAll(dir)
if err != nil {
return "", errors.Wrap(err, "Error removing module directory")
}
// Make the directory
err = fs.Mkdir(dir)
return dir, err
}
func generatePackage(pkg *Package, moduledir string) error {
// Load typescript template
typescriptTemplateData := fs.MustLoadString(packageDTemplate)
typescriptTemplate, err := template.New("typescript").Parse(typescriptTemplateData)
if err != nil {
return errors.Wrap(err, "Error creating template")
}
// Execute javascript template
var buffer bytes.Buffer
err = typescriptTemplate.Execute(&buffer, pkg)
if err != nil {
return errors.Wrap(err, "Error generating code")
}
// Save typescript file
err = os.WriteFile(filepath.Join(moduledir, "_"+pkg.Name+".d.ts"), buffer.Bytes(), 0755)
if err != nil {
return errors.Wrap(err, "Error writing backend package file")
}
// Load javascript template
javascriptTemplateData := fs.MustLoadString(packageTemplate)
javascriptTemplate, err := template.New("javascript").Parse(javascriptTemplateData)
if err != nil {
return errors.Wrap(err, "Error creating template")
}
// Reset the buffer
buffer.Reset()
err = javascriptTemplate.Execute(&buffer, pkg)
if err != nil {
return errors.Wrap(err, "Error generating code")
}
// Save javascript file
err = os.WriteFile(filepath.Join(moduledir, "_"+pkg.Name+".js"), buffer.Bytes(), 0755)
if err != nil {
return errors.Wrap(err, "Error writing backend package file")
}
return nil
}
func generateIndexJS(dir string, packages []*Package) error {
// Load template
templateData := fs.MustLoadString(indexTemplate)
packagesTemplate, err := template.New("index").Parse(templateData)
if err != nil {
return errors.Wrap(err, "Error creating template")
}
// Execute template
var buffer bytes.Buffer
err = packagesTemplate.Execute(&buffer, packages)
if err != nil {
return errors.Wrap(err, "Error generating code")
}
// Calculate target filename
indexJS := filepath.Join(dir, "index.js")
err = os.WriteFile(indexJS, buffer.Bytes(), 0755)
if err != nil {
return errors.Wrap(err, "Error writing backend package index.js file")
}
return nil
}
func generateIndexTS(dir string, packages []*Package) error {
// Load template
templateData := fs.MustLoadString(indexDTemplate)
indexTSTemplate, err := template.New("index.d").Parse(templateData)
if err != nil {
return errors.Wrap(err, "Error creating template")
}
// Execute template
var buffer bytes.Buffer
err = indexTSTemplate.Execute(&buffer, packages)
if err != nil {
return errors.Wrap(err, "Error generating code")
}
// Calculate target filename
indexJS := filepath.Join(dir, "index.d.ts")
err = os.WriteFile(indexJS, buffer.Bytes(), 0755)
if err != nil {
return errors.Wrap(err, "Error writing backend package index.d.ts file")
}
return nil
}
func generateGlobalsTS(dir string, packages []*Package) error {
// Load template
templateData := fs.MustLoadString(globalsDTemplate)
packagesTemplate, err := template.New("globals").Parse(templateData)
if err != nil {
return errors.Wrap(err, "Error creating template")
}
// Execute template
var buffer bytes.Buffer
err = packagesTemplate.Execute(&buffer, packages)
if err != nil {
return errors.Wrap(err, "Error generating code")
}
// Calculate target filename
indexJS := filepath.Join(dir, "globals.d.ts")
err = os.WriteFile(indexJS, buffer.Bytes(), 0755)
if err != nil {
return errors.Wrap(err, "Error writing backend package globals.d.ts file")
}
return nil
}
func (p *Parser) parserReport() *ParserReport {
return &ParserReport{
Packages: p.packagesToGenerate(),
}
}