diff --git a/v2/internal/project/project.go b/v2/internal/project/project.go index 0203f60f6..34db43acd 100644 --- a/v2/internal/project/project.go +++ b/v2/internal/project/project.go @@ -51,15 +51,16 @@ type Project struct { // RunNonNativeBuildHooks will run build hooks though they are defined for a GOOS which is not equal to the host os RunNonNativeBuildHooks bool `json:"runNonNativeBuildHooks"` - // Post build hooks for different targets, the hooks are executed in the following order - // Key: GOOS/GOARCH - Executed at build level after a build of the specific platform and arch - // Key: GOOS/* - Executed at build level after a build of the specific platform - // Key: */* - Executed at build level after a build + // Build hooks for different targets, the hooks are executed in the following order + // Key: GOOS/GOARCH - Executed at build level before/after a build of the specific platform and arch + // Key: GOOS/* - Executed at build level before/after a build of the specific platform + // Key: */* - Executed at build level before/after a build // The following keys are not yet supported. - // Key: GOOS - Executed at platform level after all builds of the specific platform - // Key: * - Executed at platform level after all builds of a platform - // Key: [empty] - Executed at global level after all builds of all platforms + // Key: GOOS - Executed at platform level before/after all builds of the specific platform + // Key: * - Executed at platform level before/after all builds of a platform + // Key: [empty] - Executed at global level before/after all builds of all platforms PostBuildHooks map[string]string `json:"postBuildHooks"` + PreBuildHooks map[string]string `json:"preBuildHooks"` // The application author Author Author diff --git a/v2/pkg/commands/build/build.go b/v2/pkg/commands/build/build.go index edc233b57..08f313725 100644 --- a/v2/pkg/commands/build/build.go +++ b/v2/pkg/commands/build/build.go @@ -115,6 +115,16 @@ func Build(options *Options) (string, error) { // Initialise Builder builder.SetProjectData(projectData) + hookArgs := map[string]string{ + "${platform}": options.Platform + "/" + options.Arch, + } + + for _, hook := range []string{options.Platform + "/" + options.Arch, options.Platform + "/*", "*/*"} { + if err := execPreBuildHook(outputLogger, options, hook, hookArgs); err != nil { + return "", err + } + } + if !options.IgnoreFrontend || options.ForceBuild { err = builder.BuildFrontend(outputLogger) if err != nil { @@ -215,10 +225,7 @@ func Build(options *Options) (string, error) { } compileBinary := options.CompiledBinary - hookArgs := map[string]string{ - "${platform}": options.Platform + "/" + options.Arch, - "${bin}": compileBinary, - } + hookArgs["${bin}"] = compileBinary for _, hook := range []string{options.Platform + "/" + options.Arch, options.Platform + "/*", "*/*"} { if err := execPostBuildHook(outputLogger, options, hook, hookArgs); err != nil { @@ -229,19 +236,33 @@ func Build(options *Options) (string, error) { return compileBinary, nil } +func execPreBuildHook(outputLogger *clilogger.CLILogger, options *Options, hookIdentifier string, argReplacements map[string]string) error { + preBuildHook := options.ProjectData.PreBuildHooks[hookIdentifier] + if preBuildHook == "" { + return nil + } + + return executeBuildHook(outputLogger, options, hookIdentifier, argReplacements, preBuildHook, "pre") +} + func execPostBuildHook(outputLogger *clilogger.CLILogger, options *Options, hookIdentifier string, argReplacements map[string]string) error { postBuildHook := options.ProjectData.PostBuildHooks[hookIdentifier] if postBuildHook == "" { return nil } + return executeBuildHook(outputLogger, options, hookIdentifier, argReplacements, postBuildHook, "post") + +} + +func executeBuildHook(outputLogger *clilogger.CLILogger, options *Options, hookIdentifier string, argReplacements map[string]string, buildHook string, hookName string) error { if !options.ProjectData.RunNonNativeBuildHooks { if hookIdentifier == "" { // That's the global hook } else { platformOfHook := strings.Split(hookIdentifier, "/")[0] if platformOfHook == "*" { - // Thats OK, we don't have a specific platform of the hook + // That's OK, we don't have a specific platform of the hook } else if platformOfHook == runtime.GOOS { // The hook is for host platform } else { @@ -252,8 +273,8 @@ func execPostBuildHook(outputLogger *clilogger.CLILogger, options *Options, hook } } - outputLogger.Print(" - Executing post build hook '%s': ", hookIdentifier) - args := strings.Split(postBuildHook, " ") + outputLogger.Print(" - Executing %s build hook '%s': ", hookName, hookIdentifier) + args := strings.Split(buildHook, " ") for i, arg := range args { newArg := argReplacements[arg] if newArg == "" { @@ -266,7 +287,10 @@ func execPostBuildHook(outputLogger *clilogger.CLILogger, options *Options, hook outputLogger.Println("%s", strings.Join(args, " ")) } - _, stderr, err := shell.RunCommand(options.BuildDirectory, args[0], args[1:]...) + stdout, stderr, err := shell.RunCommand(options.BuildDirectory, args[0], args[1:]...) + if options.Verbosity == VERBOSE { + println(stdout) + } if err != nil { return fmt.Errorf("%s - %s", err.Error(), stderr) } diff --git a/website/docs/reference/project-config.mdx b/website/docs/reference/project-config.mdx index 1005dd010..503c7089c 100644 --- a/website/docs/reference/project-config.mdx +++ b/website/docs/reference/project-config.mdx @@ -23,11 +23,16 @@ The project config resides in the `wails.json` file in the project directory. Th "devServer": "[Address to bind the wails dev sever to. Default: localhost:34115]", "appargs": "[Arguments passed to the application in shell style when in dev mode]", "runNonNativeBuildHooks": false, // Defines if build hooks should be run though they are defined for an OS other than the host OS. - "postBuildHooks": { - "GOOS/GOARCH": "[The command that will be executed after a build of the specified GOOS/GOARCH: ${platform} is replaced with the "GOOS/GOARCH" and ${bin} with the path to the compiled binary. The "GOOS/GOARCH" hook is executed before the "GOOS/*" and "*/*" hook.]", - "GOOS/*": "[The command that will be executed after a build of the specified GOOS: ${platform} is replaced with the "GOOS/GOARCH" and ${bin} with the path to the compiled binary. The "GOOS/*" hook is executed before the "*/*" hook.]", - "*/*": "[The command that will be executed after every build: ${platform} is replaced with the "GOOS/GOARCH" and ${bin} with the path to the compiled binary.]" + "preBuildHooks": { + "GOOS/GOARCH": "[The command that will be executed before a build of the specified GOOS/GOARCH: ${platform} is replaced with the "GOOS/GOARCH". The "GOOS/GOARCH" hook is executed before the "GOOS/*" and "*/*" hook.]", + "GOOS/*": "[The command that will be executed before a build of the specified GOOS: ${platform} is replaced with the "GOOS/GOARCH". The "GOOS/*" hook is executed before the "*/*" hook.]", + "*/*": "[The command that will be executed before every build: ${platform} is replaced with the "GOOS/GOARCH".]" }, + "postBuildHooks": { + "GOOS/GOARCH": "[The command that will be executed after a build of the specified GOOS/GOARCH: ${platform} is replaced with the "GOOS/GOARCH" and ${bin} with the path to the compiled binary. The "GOOS/GOARCH" hook is executed before the "GOOS/*" and "*/*" hook.]", + "GOOS/*": "[The command that will be executed after a build of the specified GOOS: ${platform} is replaced with the "GOOS/GOARCH" and ${bin} with the path to the compiled binary. The "GOOS/*" hook is executed before the "*/*" hook.]", + "*/*": "[The command that will be executed after every build: ${platform} is replaced with the "GOOS/GOARCH" and ${bin} with the path to the compiled binary.]" + }, "info": { // Data used to populate manifests and version info. "companyName": "[The company name. Default: [The project name]]", "productName": "[The product name. Default: [The project name]]",