diff --git a/v3/internal/commands/bindings.go b/v3/internal/commands/bindings.go index eaf8b03d3..34650b15e 100644 --- a/v3/internal/commands/bindings.go +++ b/v3/internal/commands/bindings.go @@ -1,10 +1,52 @@ package commands import ( + "errors" + "fmt" + "github.com/pterm/pterm" "github.com/wailsapp/wails/v3/internal/flags" "github.com/wailsapp/wails/v3/internal/parser" + "path/filepath" ) func GenerateBindings(options *flags.GenerateBindingsOptions) error { - return parser.GenerateBindingsAndModels(options) + + if options.Silent { + pterm.DisableOutput() + defer pterm.EnableOutput() + } + + project, err := parser.GenerateBindingsAndModels(options) + if err != nil { + if errors.Is(err, parser.ErrNoBindingsFound) { + pterm.Info.Println("No bindings found") + return nil + } else { + return err + } + } + + absPath, err := filepath.Abs(options.OutputDirectory) + if err != nil { + return err + } + + pterm.Info.Printf("Processed: %s, %s, %s, %s, %s in %s.\n", + pluralise(project.Stats.NumPackages, "Package"), + pluralise(project.Stats.NumStructs, "Struct"), + pluralise(project.Stats.NumMethods, "Method"), + pluralise(project.Stats.NumEnums, "Enum"), + pluralise(project.Stats.NumModels, "Model"), + project.Stats.EndTime.Sub(project.Stats.StartTime).String()) + + pterm.Info.Printf("Output directory: %s\n", absPath) + + return nil +} + +func pluralise(number int, word string) string { + if number == 1 { + return fmt.Sprintf("%d %s", number, word) + } + return fmt.Sprintf("%d %ss", number, word) } diff --git a/v3/internal/parser/bindings.go b/v3/internal/parser/bindings.go index d4f8bc1b0..e3304207b 100644 --- a/v3/internal/parser/bindings.go +++ b/v3/internal/parser/bindings.go @@ -28,24 +28,24 @@ const bindingTemplate = ` const bindingTemplateTypescript = `Comments` const callByIDTypescript = `export async function {{methodName}}({{inputs}}) : {{ReturnType}} { - return wails.CallByID({{ID}}{{params}}); + return Call.ByID({{ID}}{{params}}); } ` const callByNameTypescript = `export async function {{methodName}}({{inputs}}) : {{ReturnType}} { - return wails.CallByName("{{Name}}"{{params}}); + return Call.ByName("{{Name}}"{{params}}); } ` const callByID = `export async function {{methodName}}({{inputs}}) { - return wails.CallByID({{ID}}, ...Array.prototype.slice.call(arguments, 0)); + return Call.ByID({{ID}}, ...Array.prototype.slice.call(arguments, 0)); } ` const callByName = `export async function {{methodName}}({{inputs}}) { - return wails.CallByName("{{Name}}", ...Array.prototype.slice.call(arguments, 0)); + return Call.ByName("{{Name}}", ...Array.prototype.slice.call(arguments, 0)); } ` @@ -364,6 +364,10 @@ func (p *Project) GenerateBindings(bindings map[string]map[string][]*BoundMethod var namespacedStructs map[packagePath]map[string]*ExternalStruct var thisBinding string var models []string + var mainImports = "" + if len(methods) > 0 { + mainImports = "import { Call } from '@wailsio/runtime';\n" + } for _, method := range methods { if useTypescript { thisBinding, models, namespacedStructs = GenerateBindingTypescript(structName, method, useIDs) @@ -426,9 +430,9 @@ func (p *Project) GenerateBindings(bindings map[string]map[string][]*BoundMethod } } if useTypescript { - result[relativePackageDir][structName] = headerTypescript + result[relativePackageDir][structName] + result[relativePackageDir][structName] = headerTypescript + mainImports + result[relativePackageDir][structName] } else { - result[relativePackageDir][structName] = header + result[relativePackageDir][structName] + result[relativePackageDir][structName] = header + mainImports + result[relativePackageDir][structName] } } } diff --git a/v3/internal/parser/parser.go b/v3/internal/parser/parser.go index b8ef2ac4f..8025a3f90 100644 --- a/v3/internal/parser/parser.go +++ b/v3/internal/parser/parser.go @@ -1,6 +1,7 @@ package parser import ( + "errors" "fmt" "github.com/wailsapp/wails/v3/internal/flags" "go/ast" @@ -22,6 +23,9 @@ import ( type packagePath = string type structName = string +// ErrNoBindingsFound is returned when no bound structs are found +var ErrNoBindingsFound = errors.New("no bound structs found") + type StructDef struct { Name string DocComments []string @@ -316,37 +320,42 @@ func ParseProject(projectPath string) (*Project, error) { return result, nil } -func GenerateBindingsAndModels(options *flags.GenerateBindingsOptions) error { +func GenerateBindingsAndModels(options *flags.GenerateBindingsOptions) (*Project, error) { p, err := ParseProject(options.ProjectDirectory) if err != nil { - return err + return p, err } if p.BoundMethods == nil { - return nil + return p, nil } err = os.MkdirAll(options.OutputDirectory, 0755) if err != nil { - return err + return p, err } - p.Stats.NumMethods = len(p.BoundMethods) 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 { // Write the directory err = os.MkdirAll(filepath.Join(options.OutputDirectory, pkg), 0755) if err != nil && !os.IsExist(err) { - return err + return p, err } // Write the files for structName, text := range structs { + p.Stats.NumStructs++ filename := structName + ".js" if options.TS { filename = structName + ".ts" } err = os.WriteFile(filepath.Join(options.OutputDirectory, pkg, filename), []byte(text), 0644) if err != nil { - return err + return p, err } } } @@ -358,7 +367,7 @@ func GenerateBindingsAndModels(options *flags.GenerateBindingsOptions) error { if len(p.Models) > 0 { generatedModels, err := p.GenerateModels(p.Models, p.Types, options) if err != nil { - return err + return p, err } for pkg, text := range generatedModels { // Get directory for package @@ -368,39 +377,13 @@ func GenerateBindingsAndModels(options *flags.GenerateBindingsOptions) error { err = os.WriteFile(filepath.Join(options.OutputDirectory, relativePackageDir, options.ModelsFilename), []byte(text), 0644) } if err != nil { - return err + return p, err } } p.Stats.EndTime = time.Now() - absPath, err := filepath.Abs(options.ProjectDirectory) - if err != nil { - return err - } - - fmt.Printf("Processed: %s, %s, %s, %s, %s in %s.\n", - pluralise(p.Stats.NumPackages, "Package"), - pluralise(p.Stats.NumStructs, "Struct"), - pluralise(p.Stats.NumMethods, "Method"), - pluralise(p.Stats.NumEnums, "Enum"), - pluralise(p.Stats.NumModels, "Model"), - p.Stats.EndTime.Sub(p.Stats.StartTime).String()) - - absPath, err = filepath.Abs(options.OutputDirectory) - if err != nil { - return err - } - println("Output directory: " + absPath) - - return nil -} - -func pluralise(number int, word string) string { - if number == 1 { - return fmt.Sprintf("%d %s", number, word) - } - return fmt.Sprintf("%d %ss", number, word) + return p, nil } func (p *Project) parseDirectory(dir string) (map[string]*ParsedPackage, error) { @@ -561,7 +544,7 @@ func (p *Project) findApplicationNewCalls(pkgs map[string]*ParsedPackage) (err e } p.addTypes(pkg.Path, pkg.TypeCache) if !callFound { - return fmt.Errorf("no Bound structs found") + return ErrNoBindingsFound } } return nil