5
0
mirror of https://github.com/wailsapp/wails.git synced 2025-05-03 23:40:43 +08:00

[v2, dev] Build frontend only before starting the dev watcher command (#1694)

* [v2, dev] Improve logging of dev watcher command during stop

* [v2, dev] Build frontend only before starting the dev watcher command

Breaking Change: Ignore flags take precedence over Force flag.
This commit is contained in:
stffabi 2022-08-05 12:01:47 +02:00 committed by GitHub
parent 0bb1c0202b
commit 501f7a129e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 54 additions and 37 deletions

View File

@ -16,10 +16,10 @@ import (
"runtime" "runtime"
"strings" "strings"
"sync" "sync"
"sync/atomic"
"syscall" "syscall"
"time" "time"
"github.com/bitfield/script"
"github.com/google/shlex" "github.com/google/shlex"
"github.com/wailsapp/wails/v2/cmd/wails/internal" "github.com/wailsapp/wails/v2/cmd/wails/internal"
"github.com/wailsapp/wails/v2/internal/gomod" "github.com/wailsapp/wails/v2/internal/gomod"
@ -186,23 +186,15 @@ func AddSubcommand(app *clir.Cli, w io.Writer) error {
signal.Notify(quitChannel, os.Interrupt, os.Kill, syscall.SIGTERM) signal.Notify(quitChannel, os.Interrupt, os.Kill, syscall.SIGTERM)
exitCodeChannel := make(chan int, 1) exitCodeChannel := make(chan int, 1)
// Install if needed // Build the frontend if requested, but ignore building the application itself.
if installCommand := projectConfig.GetDevInstallerCommand(); installCommand != "" { ignoreFrontend := buildOptions.IgnoreFrontend
// Install initial frontend dev dependencies if !ignoreFrontend {
err = os.Chdir(filepath.Join(cwd, "frontend")) logger.Println("Building frontend for development...")
if err != nil { buildOptions.IgnoreApplication = true
return err if _, err := build.Build(buildOptions); err != nil {
}
LogGreen("Installing frontend dependencies...")
pipe := script.Exec(installCommand)
pipe.Wait()
if pipe.Error() != nil {
return pipe.Error()
}
err = os.Chdir(cwd)
if err != nil {
return err return err
} }
buildOptions.IgnoreApplication = false
} }
// frontend:dev:watcher command. // frontend:dev:watcher command.
@ -218,9 +210,11 @@ func AddSubcommand(app *clir.Cli, w io.Writer) error {
defer closer() defer closer()
} }
// Do initial build // Do initial build but only for the application.
logger.Println("Building application for development...") logger.Println("Building application for development...")
buildOptions.IgnoreFrontend = true
debugBinaryProcess, appBinary, err := restartApp(buildOptions, nil, flags, exitCodeChannel) debugBinaryProcess, appBinary, err := restartApp(buildOptions, nil, flags, exitCodeChannel)
buildOptions.IgnoreFrontend = ignoreFrontend || flags.frontendDevServerURL != ""
if err != nil { if err != nil {
return err return err
} }
@ -473,19 +467,30 @@ func runFrontendDevWatcherCommand(cwd string, devCommand string, discoverViteSer
LogGreen("Running frontend DevWatcher command: '%s'", devCommand) LogGreen("Running frontend DevWatcher command: '%s'", devCommand)
var wg sync.WaitGroup var wg sync.WaitGroup
wg.Add(1) wg.Add(1)
const (
stateRunning int32 = 0
stateCanceling = 1
stateStopped = 2
)
state := stateRunning
go func() { go func() {
if err := cmd.Wait(); err != nil { if err := cmd.Wait(); err != nil {
if err.Error() != "exit status 1" { wasRunning := atomic.CompareAndSwapInt32(&state, stateRunning, stateStopped)
if err.Error() != "exit status 1" && wasRunning {
LogRed("Error from DevWatcher '%s': %s", devCommand, err.Error()) LogRed("Error from DevWatcher '%s': %s", devCommand, err.Error())
} }
} }
atomic.StoreInt32(&state, stateStopped)
LogGreen("DevWatcher command exited!") LogGreen("DevWatcher command exited!")
wg.Done() wg.Done()
}() }()
return func() { return func() {
killProc(cmd, devCommand) if atomic.CompareAndSwapInt32(&state, stateRunning, stateCanceling) {
LogGreen("DevWatcher command killed!") LogGreen("Killing DevWatcher command...")
killProc(cmd, devCommand)
}
cancel() cancel()
wg.Wait() wg.Wait()
}, viteServerURL, nil }, viteServerURL, nil
@ -674,7 +679,6 @@ func doWatcherLoop(buildOptions *build.Options, debugBinaryProcess *process.Proc
rebuild = false rebuild = false
LogGreen("[Rebuild triggered] files updated") LogGreen("[Rebuild triggered] files updated")
// Try and build the app // Try and build the app
buildOptions.IgnoreFrontend = flags.skipFrontend || flags.frontendDevServerURL != ""
newBinaryProcess, _, err := restartApp(buildOptions, debugBinaryProcess, flags, exitCodeChannel) newBinaryProcess, _, err := restartApp(buildOptions, debugBinaryProcess, flags, exitCodeChannel)
if err != nil { if err != nil {
LogRed("Error during build: %s", err.Error()) LogRed("Error during build: %s", err.Error())

View File

@ -42,6 +42,7 @@ type Options struct {
Compiler string // The compiler command to use Compiler string // The compiler command to use
SkipModTidy bool // Skip mod tidy before compile SkipModTidy bool // Skip mod tidy before compile
IgnoreFrontend bool // Indicates if the frontend does not need building IgnoreFrontend bool // Indicates if the frontend does not need building
IgnoreApplication bool // Indicates if the application does not need building
OutputFile string // Override the output filename OutputFile string // Override the output filename
BuildDirectory string // Directory to use for building the application BuildDirectory string // Directory to use for building the application
CleanBuildDirectory bool // Indicates if the build directory should be cleaned before building CleanBuildDirectory bool // Indicates if the build directory should be cleaned before building
@ -125,13 +126,35 @@ func Build(options *Options) (string, error) {
} }
} }
if !options.IgnoreFrontend || options.ForceBuild { if !options.IgnoreFrontend {
err = builder.BuildFrontend(outputLogger) err = builder.BuildFrontend(outputLogger)
if err != nil { if err != nil {
return "", err return "", err
} }
} }
compileBinary := ""
if !options.IgnoreApplication {
compileBinary, err = execBuildApplication(builder, options)
if err != nil {
return "", err
}
}
hookArgs["${bin}"] = compileBinary
for _, hook := range []string{options.Platform + "/" + options.Arch, options.Platform + "/*", "*/*"} {
if err := execPostBuildHook(outputLogger, options, hook, hookArgs); err != nil {
return "", err
}
}
return compileBinary, nil
}
func execBuildApplication(builder Builder, options *Options) (string, error) {
// Extract logger
outputLogger := options.Logger
// If we are building for windows, we will need to generate the asset bundle before // If we are building for windows, we will need to generate the asset bundle before
// compilation. This will be a .syso file in the project root // compilation. This will be a .syso file in the project root
if options.Pack && options.Platform == "windows" { if options.Pack && options.Platform == "windows" {
@ -166,8 +189,7 @@ func Build(options *Options) (string, error) {
if options.Verbosity == VERBOSE { if options.Verbosity == VERBOSE {
outputLogger.Println("\nBuilding AMD64 Target: %s", filepath.Join(options.BuildDirectory, options.OutputFile)) outputLogger.Println("\nBuilding AMD64 Target: %s", filepath.Join(options.BuildDirectory, options.OutputFile))
} }
err = builder.CompileProject(options) err := builder.CompileProject(options)
if err != nil { if err != nil {
return "", err return "", err
} }
@ -200,10 +222,10 @@ func Build(options *Options) (string, error) {
if err != nil { if err != nil {
return "", err return "", err
} }
projectData.OutputFilename = outputFile options.ProjectData.OutputFilename = outputFile
options.CompiledBinary = filepath.Join(options.BuildDirectory, outputFile) options.CompiledBinary = filepath.Join(options.BuildDirectory, outputFile)
} else { } else {
err = builder.CompileProject(options) err := builder.CompileProject(options)
if err != nil { if err != nil {
return "", err return "", err
} }
@ -217,23 +239,14 @@ func Build(options *Options) (string, error) {
outputLogger.Print(" - Packaging application: ") outputLogger.Print(" - Packaging application: ")
// TODO: Allow cross platform build // TODO: Allow cross platform build
err = packageProject(options, runtime.GOOS) err := packageProject(options, runtime.GOOS)
if err != nil { if err != nil {
return "", err return "", err
} }
outputLogger.Println("Done.") outputLogger.Println("Done.")
} }
compileBinary := options.CompiledBinary return options.CompiledBinary, nil
hookArgs["${bin}"] = compileBinary
for _, hook := range []string{options.Platform + "/" + options.Arch, options.Platform + "/*", "*/*"} {
if err := execPostBuildHook(outputLogger, options, hook, hookArgs); err != nil {
return "", err
}
}
return compileBinary, nil
} }
func execPreBuildHook(outputLogger *clilogger.CLILogger, options *Options, hookIdentifier string, argReplacements map[string]string) error { func execPreBuildHook(outputLogger *clilogger.CLILogger, options *Options, hookIdentifier string, argReplacements map[string]string) error {