From b9496181bdc54a1a8b354cf8e7f5ac3532c78b47 Mon Sep 17 00:00:00 2001 From: Martin Date: Sun, 14 Aug 2022 16:19:06 +0200 Subject: [PATCH] Bugfix operation in "server/hybrid" modes go.embed asset handling in production build call the OnStartup() callback when running the null frontend structure the app_hybrid_server.go to follow the structure and code of app_production.go --- v2/go.mod | 2 +- v2/internal/appng/app_hybrid_server.go | 145 ++++-------------- v2/internal/frontend/desktop/null/frontend.go | 23 ++- v2/internal/frontend/hybrid/server.go | 2 +- 4 files changed, 50 insertions(+), 122 deletions(-) diff --git a/v2/go.mod b/v2/go.mod index b9faf8c9c1c..a4a3ea48a6f 100644 --- a/v2/go.mod +++ b/v2/go.mod @@ -43,6 +43,7 @@ require ( github.com/bitfield/script v0.19.0 github.com/charmbracelet/glamour v0.5.0 github.com/go-ole/go-ole v1.2.6 + github.com/labstack/gommon v0.3.1 ) require ( @@ -57,7 +58,6 @@ require ( github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect github.com/kevinburke/ssh_config v0.0.0-20201106050909-4977a11b4351 // indirect github.com/kr/pretty v0.3.0 // indirect - github.com/labstack/gommon v0.3.1 // indirect github.com/logrusorgru/aurora v0.0.0-20181002194514-a7b3b318ed4e // indirect github.com/lucasb-eyer/go-colorful v1.2.0 // indirect github.com/mattn/go-colorable v0.1.11 // indirect diff --git a/v2/internal/appng/app_hybrid_server.go b/v2/internal/appng/app_hybrid_server.go index a59f7c9548d..f1880edcf7c 100644 --- a/v2/internal/appng/app_hybrid_server.go +++ b/v2/internal/appng/app_hybrid_server.go @@ -1,16 +1,11 @@ //go:build (exp && hybrid) || (exp && server) // +build exp,hybrid exp,server -package appng +package app import ( "context" - "embed" "fmt" - iofs "io/fs" - "os" - "path/filepath" - "github.com/wailsapp/wails/v2/internal/binding" "github.com/wailsapp/wails/v2/internal/frontend" "github.com/wailsapp/wails/v2/internal/frontend/desktop" @@ -18,10 +13,8 @@ import ( "github.com/wailsapp/wails/v2/internal/frontend/dispatcher" "github.com/wailsapp/wails/v2/internal/frontend/hybrid" "github.com/wailsapp/wails/v2/internal/frontend/runtime" - "github.com/wailsapp/wails/v2/internal/fs" "github.com/wailsapp/wails/v2/internal/logger" "github.com/wailsapp/wails/v2/internal/menumanager" - "github.com/wailsapp/wails/v2/internal/project" "github.com/wailsapp/wails/v2/pkg/options" ) @@ -42,6 +35,10 @@ type App struct { ctx context.Context } +func (a *App) Shutdown() { + a.frontend.Quit() +} + func (a *App) Run() error { err := a.frontend.Run(a.ctx) if a.shutdownCallback != nil { @@ -50,75 +47,49 @@ func (a *App) Run() error { return err } -func (a *App) Shutdown() { - if a.shutdownCallback != nil { - a.shutdownCallback(a.ctx) - } - a.frontend.Quit() -} - // CreateApp creates the app! func CreateApp(appoptions *options.App) (*App, error) { - // Set up logger - myLogger := logger.New(appoptions.Logger) - myLogger.SetLogLevel(appoptions.LogLevel) + var err error - // If no assetdir has been defined, let's try to infer it from the project root and the asset FS. - assetdir, err := tryInferAssetDirFromFS(appoptions.Assets) - if err != nil { - return nil, err - } + ctx := context.Background() - host := "localhost" - port := int32(3112) + host, port := "localhost", int32(3112) if appoptions.Server != nil { host = appoptions.Server.Host port = appoptions.Server.Port } serverURI := fmt.Sprintf("%s:%d", host, port) - ctx := context.Background() ctx = context.WithValue(ctx, "starturl", serverURI) - - // This is to enable a backend server - // ctx = context.WithValue(ctx, "frontenddevserverurl", serverURI) - - myLogger.Info("Frontend available at '%s'", serverURI) - - // configure devserver ctx = context.WithValue(ctx, "devserver", fmt.Sprintf("%s:%d", host, port)) - // Let's override the assets to serve from on disk, if needed - absdir, err := filepath.Abs(assetdir) - if err != nil { - return nil, err - } - - myLogger.Info("Serving assets from disk: %s", absdir) - appoptions.Assets = os.DirFS(absdir) + // Merge default options + options.MergeDefaults(appoptions) - ctx = context.WithValue(ctx, "assetdir", assetdir) + debug := IsDebug() + ctx = context.WithValue(ctx, "debug", debug) - // Attach logger to context + // Set up logger + myLogger := logger.New(appoptions.Logger) + myLogger.Info("Frontend available at 'http://%s'", serverURI) + if IsDebug() { + myLogger.SetLogLevel(appoptions.LogLevel) + } else { + myLogger.SetLogLevel(appoptions.LogLevelProduction) + } ctx = context.WithValue(ctx, "logger", myLogger) - ctx = context.WithValue(ctx, "buildtype", "hybrid") - // Preflight checks + // Preflight Checks err = PreflightChecks(appoptions, myLogger) if err != nil { return nil, err } - // Merge default options - - options.MergeDefaults(appoptions) - - var menuManager *menumanager.Manager + // Create the menu manager + menuManager := menumanager.NewManager() // Process the application menu if appoptions.Menu != nil { - // Create the menu manager - menuManager = menumanager.NewManager() err = menuManager.SetApplicationMenu(appoptions.Menu) if err != nil { return nil, err @@ -128,13 +99,15 @@ func CreateApp(appoptions *options.App) (*App, error) { // Create binding exemptions - Ugly hack. There must be a better way bindingExemptions := []interface{}{appoptions.OnStartup, appoptions.OnShutdown, appoptions.OnDomReady} appBindings := binding.NewBindings(myLogger, appoptions.Bind, bindingExemptions) - - err = generateBindings(appBindings) - if err != nil { - return nil, err - } eventHandler := runtime.NewEvents(myLogger) ctx = context.WithValue(ctx, "events", eventHandler) + // Attach logger to context + if debug { + ctx = context.WithValue(ctx, "buildtype", "debug") + } else { + ctx = context.WithValue(ctx, "buildtype", "production") + } + messageDispatcher := dispatcher.NewDispatcher(ctx, myLogger, appBindings, eventHandler) appFrontend := hybrid.NewFrontend(ctx, appoptions, myLogger, appBindings, messageDispatcher) eventHandler.AddFrontend(appFrontend) @@ -146,64 +119,10 @@ func CreateApp(appoptions *options.App) (*App, error) { menuManager: menuManager, startupCallback: appoptions.OnStartup, shutdownCallback: appoptions.OnShutdown, + debug: debug, + options: appoptions, } - result.options = appoptions - return result, nil } - -func generateBindings(bindings *binding.Bindings) error { - - cwd, err := os.Getwd() - if err != nil { - return err - } - projectConfig, err := project.Load(cwd) - if err != nil { - return err - } - - targetDir := filepath.Join(projectConfig.WailsJSDir, "wailsjs", "go") - err = os.RemoveAll(targetDir) - if err != nil { - return err - } - _ = fs.MkDirs(targetDir) - - err = bindings.GenerateGoBindings(targetDir) - if err != nil { - return err - } - return nil -} - -func tryInferAssetDirFromFS(assets iofs.FS) (string, error) { - if _, isEmbedFs := assets.(embed.FS); !isEmbedFs { - // We only infer the assetdir for embed.FS assets - return "", nil - } - - path, err := fs.FindPathToFile(assets, "index.html") - if err != nil { - return "", err - } - - path, err = filepath.Abs(path) - if err != nil { - return "", err - } - - if _, err := os.Stat(filepath.Join(path, "index.html")); err != nil { - if os.IsNotExist(err) { - err = fmt.Errorf( - "inferred assetdir '%s' does not exist or does not contain an 'index.html' file, "+ - "please specify it with -assetdir or set it in wails.json", - path) - } - return "", err - } - - return path, nil -} diff --git a/v2/internal/frontend/desktop/null/frontend.go b/v2/internal/frontend/desktop/null/frontend.go index fe19907af1b..b09a56b26d5 100644 --- a/v2/internal/frontend/desktop/null/frontend.go +++ b/v2/internal/frontend/desktop/null/frontend.go @@ -11,14 +11,17 @@ import ( // Frontend implements an empty Frontend that simply waits until the context is done. type Frontend struct { // Context - ctx context.Context + ctx context.Context + frontendOptions *options.App + done bool } // NewFrontend returns an initialized Frontend -func NewFrontend(ctx context.Context) *Frontend { +func NewFrontend(ctx context.Context, appoptions *options.App) *Frontend { return &Frontend{ - ctx: ctx, + frontendOptions: appoptions, + ctx: ctx, } } @@ -73,19 +76,25 @@ func (f *Frontend) WindowSetDarkTheme() { } // Run waits until the context is done and then exits -func (f *Frontend) Run(ctx context.Context) error { +func (f *Frontend) Run(ctx context.Context) (err error) { + err = nil + go func() { + if f.frontendOptions.OnStartup != nil { + f.frontendOptions.OnStartup(f.ctx) + } + }() for { select { case <-ctx.Done(): - break + return default: time.Sleep(1 * time.Millisecond) } if f.done { - break + return } } - return nil + } // WindowCenter does nothing diff --git a/v2/internal/frontend/hybrid/server.go b/v2/internal/frontend/hybrid/server.go index cd83fbf98aa..f4df3bd1cc3 100644 --- a/v2/internal/frontend/hybrid/server.go +++ b/v2/internal/frontend/hybrid/server.go @@ -17,5 +17,5 @@ import ( // New returns a new Server frontend // A server Frontend implementation contains a devserver.Frontend wrapping a null.Frontend func NewFrontend(ctx context.Context, appoptions *options.App, logger *logger.Logger, appBindings *binding.Bindings, dispatcher frontend.Dispatcher) frontend.Frontend { - return devserver.NewFrontend(ctx, appoptions, logger, appBindings, dispatcher, nil, null.NewFrontend(ctx)) + return devserver.NewFrontend(ctx, appoptions, logger, appBindings, dispatcher, nil, null.NewFrontend(ctx, appoptions)) }