Skip to content

Commit

Permalink
Bugfix operation in "server/hybrid" modes
Browse files Browse the repository at this point in the history
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
  • Loading branch information
m29h authored and tmclane committed Sep 27, 2023
1 parent e837c40 commit 658dbaf
Show file tree
Hide file tree
Showing 5 changed files with 55 additions and 123 deletions.
4 changes: 3 additions & 1 deletion v2/go.mod
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
module github.com/wailsapp/wails/v2

go 1.18
go 1.21

toolchain go1.21.1

require (
github.com/Masterminds/semver v1.5.0
Expand Down
6 changes: 4 additions & 2 deletions v2/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ github.com/MarvinJWendt/testza v0.2.12/go.mod h1:JOIegYyV7rX+7VZ9r77L/eH6CfJHHzX
github.com/MarvinJWendt/testza v0.3.0/go.mod h1:eFcL4I0idjtIx8P9C6KkAuLgATNKpX4/2oUqKc6bF2c=
github.com/MarvinJWendt/testza v0.4.2/go.mod h1:mSdhXiKH8sg/gQehJ63bINcCKp7RtYewEjXsvsVUPbE=
github.com/MarvinJWendt/testza v0.4.3 h1:u2XaM4IqGp9dsdUmML8/Z791fu4yjQYzOiufOtJwTII=
github.com/MarvinJWendt/testza v0.4.3/go.mod h1:CpXaOfceNEYnLDtNIyTrPPcCpDJYqzZnu2aiA2Wp33U=
github.com/Masterminds/semver v1.5.0 h1:H65muMkzWKEuNDnfl9d70GUjFniHKHRbFPGBuZ3QEww=
github.com/Masterminds/semver v1.5.0/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y=
github.com/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jBhyzoq1bpyYA=
Expand Down Expand Up @@ -69,6 +70,7 @@ github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMyw
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE=
github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg=
github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4=
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ=
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
Expand All @@ -94,6 +96,7 @@ github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa02
github.com/klauspost/cpuid/v2 v2.0.10/go.mod h1:g2LTdtYhdyuGPqyWyv7qRAmj1WBqxuObKfj5c0PQa7c=
github.com/klauspost/cpuid/v2 v2.0.12/go.mod h1:g2LTdtYhdyuGPqyWyv7qRAmj1WBqxuObKfj5c0PQa7c=
github.com/klauspost/cpuid/v2 v2.1.0 h1:eyi1Ad2aNJMW95zcSbmGg7Cg6cq3ADwLpMAP96d8rF0=
github.com/klauspost/cpuid/v2 v2.1.0/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8tyFgg4nqhuY=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
Expand All @@ -119,8 +122,6 @@ github.com/leaanthony/gosod v1.0.3/go.mod h1:BJ2J+oHsQIyIQpnLPjnqFGTMnOZXDbvWtRC
github.com/leaanthony/slicer v1.5.0/go.mod h1:FwrApmf8gOrpzEWM2J/9Lh79tyq8KTX5AzRtwV7m4AY=
github.com/leaanthony/slicer v1.6.0 h1:1RFP5uiPJvT93TAHi+ipd3NACobkW53yUiBqZheE/Js=
github.com/leaanthony/slicer v1.6.0/go.mod h1:o/Iz29g7LN0GqH3aMjWAe90381nyZlDNquK+mtH2Fj8=
github.com/leaanthony/u v1.0.1 h1:tJLpf9EsuCgSB02ojRxg8KRqMgRN6mCTvFwI55kxRFE=
github.com/leaanthony/u v1.0.1/go.mod h1:9+o6hejoRljvZ3BzdYlVL0JYCwtnAsVuN9pVTQcaRfI=
github.com/leaanthony/u v1.1.0 h1:2n0d2BwPVXSUq5yhe8lJPHdxevE2qK5G99PMStMZMaI=
github.com/leaanthony/u v1.1.0/go.mod h1:9+o6hejoRljvZ3BzdYlVL0JYCwtnAsVuN9pVTQcaRfI=
github.com/leaanthony/winicon v1.0.0 h1:ZNt5U5dY71oEoKZ97UVwJRT4e+5xo5o/ieKuHuk8NqQ=
Expand Down Expand Up @@ -262,6 +263,7 @@ golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o=
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
Expand Down
143 changes: 31 additions & 112 deletions v2/internal/app/app_hybrid_server.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,23 +5,16 @@ 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"
"github.com/wailsapp/wails/v2/internal/frontend/devserver"
"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"
)

Expand All @@ -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 {
Expand All @@ -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
Expand All @@ -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)
Expand All @@ -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
}
23 changes: 16 additions & 7 deletions v2/internal/frontend/desktop/null/frontend.go
Original file line number Diff line number Diff line change
Expand Up @@ -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,
}
}

Expand Down Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion v2/internal/frontend/hybrid/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -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))
}

0 comments on commit 658dbaf

Please sign in to comment.