[v3] Fix binding generator output and import paths (#3334)

* Fix relative import path computation

* Fix models output path

* Add option to generate bindings using bundled runtime

* Update binding example

* Fix testdata

* Update changelog

---------

Co-authored-by: Lea Anthony <lea.anthony@gmail.com>
This commit is contained in:
Fabio Massaioli
2024-03-22 21:18:04 +11:00
committed by GitHub
co-authored by Lea Anthony
parent f0986a6441
commit 45b2681dfc
56 changed files with 364 additions and 372 deletions
+9 -5
View File
@@ -20,7 +20,7 @@ const headerTypescript = `// Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH Â M
`
const bindingTemplate = `
/**Comments
/**Comments
* @function {{methodName}}* @param names {string}
* @returns {Promise<string>}
**/
@@ -345,7 +345,7 @@ func isContext(input *Parameter) bool {
return input.Type.Package == "context" && input.Type.Name == "Context"
}
func (p *Project) GenerateBindings(bindings map[string]map[string][]*BoundMethod, useIDs bool, useTypescript bool) map[string]map[string]string {
func (p *Project) GenerateBindings(bindings map[string]map[string][]*BoundMethod, modelsFilename string, useIDs bool, useTypescript bool, useBundledRuntime bool) map[string]map[string]string {
var result = make(map[string]map[string]string)
@@ -374,7 +374,11 @@ func (p *Project) GenerateBindings(bindings map[string]map[string][]*BoundMethod
var models []string
var mainImports = ""
if len(methods) > 0 {
mainImports = "import {Call} from '@wailsio/runtime';\n"
if useBundledRuntime {
mainImports = "import {Call} from '/wails/runtime.js';\n"
} else {
mainImports = "import {Call} from '@wailsio/runtime';\n"
}
}
for _, method := range methods {
if useTypescript {
@@ -405,7 +409,7 @@ func (p *Project) GenerateBindings(bindings map[string]map[string][]*BoundMethod
sort.Strings(namespacedStructNames)
for _, thisStructName := range namespacedStructNames {
structInfo := namespacedStruct[thisStructName]
typedefs += " * @typedef {import('" + relativePackageDir + "/models')." + thisStructName + "} " + namePrefix + structInfo.Name + "\n"
typedefs += " * @typedef {import('" + relativePackageDir + "/" + modelsFilename + "')." + thisStructName + "} " + namePrefix + structInfo.Name + "\n"
}
}
typedefs += " */\n"
@@ -429,7 +433,7 @@ func (p *Project) GenerateBindings(bindings map[string]map[string][]*BoundMethod
if namePrefix != "" {
imports += "import {" + thisStructName + " as " + namePrefix + structInfo.Name + "} from '" + relativePackageDir + "/models';\n"
} else {
imports += "import {" + thisStructName + "} from '" + relativePackageDir + "/models';\n"
imports += "import {" + thisStructName + "} from '" + relativePackageDir + "/" + modelsFilename + "';\n"
}
}
}
+1 -1
View File
@@ -684,7 +684,7 @@ func TestGenerateBindings(t *testing.T) {
project.outputDirectory = "frontend/bindings"
// Generate Bindings
got := project.GenerateBindings(project.BoundMethods, tt.useIDs, tt.useTypescript)
got := project.GenerateBindings(project.BoundMethods, "models", tt.useIDs, tt.useTypescript, false)
for dirName, structDetails := range got {
// iterate the struct names in structDetails
+3 -2
View File
@@ -3,11 +3,12 @@ package parser
import (
"bytes"
"embed"
"github.com/wailsapp/wails/v3/internal/flags"
"io"
"sort"
"strings"
"text/template"
"github.com/wailsapp/wails/v3/internal/flags"
)
//go:embed templates
@@ -36,7 +37,7 @@ func (p *Project) GenerateModel(wr io.Writer, def *ModelDefinitions, options *fl
tmpl, err := template.New(templateName).ParseFS(templates, "templates/"+templateName)
if err != nil {
println("Unable to create class template: " + err.Error())
println("Unable to initialize model template: " + err.Error())
return err
}
+42 -19
View File
@@ -351,27 +351,32 @@ func GenerateBindingsAndModels(options *flags.GenerateBindingsOptions) (*Project
if err != nil {
return p, err
}
p.outputDirectory = options.OutputDirectory
for _, pkg := range p.BoundMethods {
for _, boundMethods := range pkg {
p.Stats.NumMethods += len(boundMethods)
}
}
generatedMethods := p.GenerateBindings(p.BoundMethods, options.UseIDs, options.TS)
for pkg, structs := range generatedMethods {
generatedMethods := p.GenerateBindings(p.BoundMethods, options.ModelsFilename, options.UseIDs, options.TS, options.UseBundledRuntime)
for pkgDir, structs := range generatedMethods {
// Write the directory
err = os.MkdirAll(filepath.Join(options.OutputDirectory, pkg), 0755)
err = os.MkdirAll(filepath.Join(options.OutputDirectory, pkgDir), 0755)
if err != nil && !os.IsExist(err) {
return p, err
}
// Write the files
for structName, text := range structs {
p.Stats.NumStructs++
filename := structName + ".js"
var filename string
if options.TS {
filename = structName + ".ts"
} else {
filename = structName + ".js"
}
err = os.WriteFile(filepath.Join(options.OutputDirectory, pkg, filename), []byte(text), 0644)
err = os.WriteFile(filepath.Join(options.OutputDirectory, pkgDir, filename), []byte(text), 0644)
if err != nil {
return p, err
}
@@ -387,12 +392,20 @@ func GenerateBindingsAndModels(options *flags.GenerateBindingsOptions) (*Project
if err != nil {
return p, err
}
for pkg, text := range generatedModels {
// Get directory for package
pkgInfo := p.packageCache[pkg]
relativePackageDir := p.RelativeBindingsDir(pkgInfo, pkgInfo)
for pkgDir, text := range generatedModels {
// Write the directory
err = os.WriteFile(filepath.Join(options.OutputDirectory, relativePackageDir, options.ModelsFilename), []byte(text), 0644)
err = os.MkdirAll(filepath.Join(options.OutputDirectory, pkgDir), 0755)
if err != nil && !os.IsExist(err) {
return p, err
}
// Write the file
var filename string
if options.TS {
filename = options.ModelsFilename + ".ts"
} else {
filename = options.ModelsFilename + ".js"
}
err = os.WriteFile(filepath.Join(options.OutputDirectory, pkgDir, filename), []byte(text), 0644)
}
if err != nil {
return p, err
@@ -1175,25 +1188,35 @@ func (p *Project) parseTypes(pkgs map[string]*ParsedPackage) {
}
func (p *Project) RelativeBindingsDir(dir *ParsedPackage, dir2 *ParsedPackage) string {
if dir.Dir == dir2.Dir {
return "."
}
// Calculate the relative path from the bindings directory to the package directory
absoluteSourceDir := dir.Dir
if absoluteSourceDir == p.Path {
// Calculate the relative path from the bindings directory of dir to that of dir2
var (
absoluteSourceDir string
absoluteTargetDir string
)
if dir.Dir == p.Path {
absoluteSourceDir = filepath.Join(p.Path, p.outputDirectory, "main")
} else {
absoluteSourceDir = dir.Dir
relativeSourceDir := strings.TrimPrefix(dir.Dir, p.Path)
absoluteSourceDir = filepath.Join(p.Path, p.outputDirectory, relativeSourceDir)
}
targetRelativeDir := strings.TrimPrefix(dir2.Dir, p.Path)
targetBindingsDir := filepath.Join(p.Path, p.outputDirectory, targetRelativeDir)
// Calculate the relative path from the source directory to the target directory
relativePath, err := filepath.Rel(absoluteSourceDir, targetBindingsDir)
if dir2.Dir == p.Path {
absoluteTargetDir = filepath.Join(p.Path, p.outputDirectory, "main")
} else {
relativeTargetDir := strings.TrimPrefix(dir2.Dir, p.Path)
absoluteTargetDir = filepath.Join(p.Path, p.outputDirectory, relativeTargetDir)
}
relativePath, err := filepath.Rel(absoluteSourceDir, absoluteTargetDir)
if err != nil {
panic(err)
}
return filepath.ToSlash(relativePath)
}
@@ -9,7 +9,7 @@ import {Call} from '@wailsio/runtime';
*/
/**
* Greet does XYZ
* Greet does XYZ
* @function Greet
* @param name {string}
* @param title {Title}
@@ -20,7 +20,7 @@ export async function Greet(name, title) {
}
/**
* NewPerson creates a new person
* NewPerson creates a new person
* @function NewPerson
* @param name {string}
* @returns {Promise<Person>}
@@ -8,7 +8,7 @@
*/
/**
* Greet does XYZ
* Greet does XYZ
* @function Greet
* @param name {string}
* @param title {Title}
@@ -19,7 +19,7 @@ export async function Greet(name, title) {
}
/**
* NewPerson creates a new person
* NewPerson creates a new person
* @function NewPerson
* @param name {string}
* @returns {Promise<Person>}
@@ -8,7 +8,7 @@ import {Call} from '@wailsio/runtime';
*/
/**
* Greet does XYZ
* Greet does XYZ
* @function Greet
* @param name {string}
* @param title {servicesTitle}
@@ -8,7 +8,7 @@ import {Call} from '@wailsio/runtime';
*/
/**
* Greet does XYZ
* Greet does XYZ
* @function Greet
* @param name {string}
* @param title {servicesTitle}
@@ -8,7 +8,7 @@ import {Call} from '@wailsio/runtime';
*/
/**
* Greet does XYZ
* Greet does XYZ
* @function Greet
* @param name {string}
* @returns {Promise<string>}
@@ -18,7 +18,7 @@ export async function Greet(name) {
}
/**
* NewPerson creates a new person
* NewPerson creates a new person
* @function NewPerson
* @param name {string}
* @returns {Promise<Person>}
@@ -8,7 +8,7 @@ import {Call} from '@wailsio/runtime';
*/
/**
* Greet does XYZ
* Greet does XYZ
* @function Greet
* @param name {string}
* @returns {Promise<string>}
@@ -18,7 +18,7 @@ export async function Greet(name) {
}
/**
* NewPerson creates a new person
* NewPerson creates a new person
* @function NewPerson
* @param name {string}
* @returns {Promise<Person>}
@@ -8,7 +8,7 @@ import {Call} from '@wailsio/runtime';
*/
/**
* Yay does this and that
* Yay does this and that
* @function Yay
* @returns {Promise<Address>}
**/
@@ -8,7 +8,7 @@ import {Call} from '@wailsio/runtime';
*/
/**
* Yay does this and that
* Yay does this and that
* @function Yay
* @returns {Promise<Address>}
**/
@@ -8,7 +8,7 @@ import {Call} from '@wailsio/runtime';
*/
/**
* Greet does XYZ
* Greet does XYZ
* @function Greet
* @param name {string}
* @returns {Promise<string>}
@@ -18,7 +18,7 @@ export async function Greet(name) {
}
/**
* NewPerson creates a new person
* NewPerson creates a new person
* @function NewPerson
* @param name {string}
* @returns {Promise<Person>}
@@ -8,7 +8,7 @@ import {Call} from '@wailsio/runtime';
*/
/**
* Greet does XYZ
* Greet does XYZ
* @function Greet
* @param name {string}
* @returns {Promise<string>}
@@ -18,7 +18,7 @@ export async function Greet(name) {
}
/**
* NewPerson creates a new person
* NewPerson creates a new person
* @function NewPerson
* @param name {string}
* @returns {Promise<Person>}
@@ -8,7 +8,7 @@ import {Call} from '@wailsio/runtime';
*/
/**
* Yay does this and that
* Yay does this and that
* @function Yay
* @returns {Promise<Address>}
**/
@@ -8,7 +8,7 @@ import {Call} from '@wailsio/runtime';
*/
/**
* Yay does this and that
* Yay does this and that
* @function Yay
* @returns {Promise<Address>}
**/
@@ -5,7 +5,7 @@
import {Call} from '@wailsio/runtime';
/**
* Greet someone
* Greet someone
* @function Greet
* @param name {string}
* @returns {Promise<string>}
@@ -5,7 +5,7 @@
import {Call} from '@wailsio/runtime';
/**
* Greet someone
* Greet someone
* @function Greet
* @param name {string}
* @returns {Promise<string>}
@@ -5,7 +5,7 @@
import {Call} from '@wailsio/runtime';
/**
* Greet someone
* Greet someone
* @function Greet
* @param name {string}
* @returns {Promise<string>}
@@ -15,7 +15,7 @@ export async function Greet(name) {
}
/**
* Greet someone
* Greet someone
* @function GreetWithContext
* @param name {string}
* @returns {Promise<string>}
@@ -5,7 +5,7 @@
import {Call} from '@wailsio/runtime';
/**
* Greet someone
* Greet someone
* @function Greet
* @param name {string}
* @returns {Promise<string>}
@@ -15,7 +15,7 @@ export async function Greet(name) {
}
/**
* Greet someone
* Greet someone
* @function GreetWithContext
* @param name {string}
* @returns {Promise<string>}

Some files were not shown because too many files have changed in this diff Show More