github.com/AlpineAIO/wails/v2@v2.0.0-beta.32.0.20240505041856-1047a8fa5fef/pkg/commands/build/nsis_installer.go (about)

     1  package build
     2  
     3  import (
     4  	"fmt"
     5  	"path"
     6  	"path/filepath"
     7  	"strings"
     8  
     9  	"github.com/AlpineAIO/wails/v2/internal/fs"
    10  	"github.com/AlpineAIO/wails/v2/internal/shell"
    11  	"github.com/AlpineAIO/wails/v2/internal/webview2runtime"
    12  	"github.com/AlpineAIO/wails/v2/pkg/buildassets"
    13  )
    14  
    15  const (
    16  	nsisTypeSingle   = "single"
    17  	nsisTypeMultiple = "multiple"
    18  
    19  	nsisFolder            = "windows/installer"
    20  	nsisProjectFile       = "project.nsi"
    21  	nsisToolsFile         = "wails_tools.nsh"
    22  	nsisWebView2SetupFile = "tmp/MicrosoftEdgeWebview2Setup.exe"
    23  )
    24  
    25  func GenerateNSISInstaller(options *Options, amd64Binary string, arm64Binary string) error {
    26  	outputLogger := options.Logger
    27  	outputLogger.Println("Creating NSIS installer\n------------------------------")
    28  
    29  	// Ensure the file exists, if not the template will be written.
    30  	projectFile := path.Join(nsisFolder, nsisProjectFile)
    31  	if _, err := buildassets.ReadFile(options.ProjectData, projectFile); err != nil {
    32  		return fmt.Errorf("Unable to generate NSIS installer project template: %w", err)
    33  	}
    34  
    35  	// Write the resolved nsis tools
    36  	toolsFile := path.Join(nsisFolder, nsisToolsFile)
    37  	if _, err := buildassets.ReadOriginalFileWithProjectDataAndSave(options.ProjectData, toolsFile); err != nil {
    38  		return fmt.Errorf("Unable to generate NSIS tools file: %w", err)
    39  	}
    40  
    41  	// Write the WebView2 SetupFile
    42  	webviewSetup := buildassets.GetLocalPath(options.ProjectData, path.Join(nsisFolder, nsisWebView2SetupFile))
    43  	if dir := filepath.Dir(webviewSetup); !fs.DirExists(dir) {
    44  		if err := fs.MkDirs(dir, 0o755); err != nil {
    45  			return err
    46  		}
    47  	}
    48  
    49  	if err := webview2runtime.WriteInstallerToFile(webviewSetup); err != nil {
    50  		return fmt.Errorf("Unable to write WebView2 Bootstrapper Setup: %w", err)
    51  	}
    52  
    53  	if !shell.CommandExists("makensis") {
    54  		outputLogger.Println("Warning: Cannot create installer: makensis not found")
    55  		return nil
    56  	}
    57  
    58  	nsisType := options.ProjectData.NSISType
    59  	if nsisType == nsisTypeSingle && (amd64Binary == "" || arm64Binary == "") {
    60  		nsisType = ""
    61  	}
    62  
    63  	switch nsisType {
    64  	case "":
    65  		fallthrough
    66  	case nsisTypeMultiple:
    67  		if amd64Binary != "" {
    68  			if err := makeNSIS(options, "amd64", amd64Binary, ""); err != nil {
    69  				return err
    70  			}
    71  		}
    72  
    73  		if arm64Binary != "" {
    74  			if err := makeNSIS(options, "arm64", "", arm64Binary); err != nil {
    75  				return err
    76  			}
    77  		}
    78  
    79  	case nsisTypeSingle:
    80  		if err := makeNSIS(options, "single", amd64Binary, arm64Binary); err != nil {
    81  			return err
    82  		}
    83  	default:
    84  		return fmt.Errorf("Unsupported nsisType: %s", nsisType)
    85  	}
    86  
    87  	return nil
    88  }
    89  
    90  func makeNSIS(options *Options, installerKind string, amd64Binary string, arm64Binary string) error {
    91  	verbose := options.Verbosity == VERBOSE
    92  	outputLogger := options.Logger
    93  
    94  	outputLogger.Print("  - Building '%s' installer: ", installerKind)
    95  	args := []string{}
    96  	if amd64Binary != "" {
    97  		args = append(args, "-DARG_WAILS_AMD64_BINARY="+amd64Binary)
    98  	}
    99  	if arm64Binary != "" {
   100  		args = append(args, "-DARG_WAILS_ARM64_BINARY="+arm64Binary)
   101  	}
   102  	args = append(args, nsisProjectFile)
   103  
   104  	if verbose {
   105  		outputLogger.Println("makensis %s", strings.Join(args, " "))
   106  	}
   107  
   108  	installerDir := buildassets.GetLocalPath(options.ProjectData, nsisFolder)
   109  	stdOut, stdErr, err := shell.RunCommand(installerDir, "makensis", args...)
   110  	if err != nil || verbose {
   111  		outputLogger.Println(stdOut)
   112  		outputLogger.Println(stdErr)
   113  	}
   114  	if err != nil {
   115  		return fmt.Errorf("Error during creation of the installer: %w", err)
   116  	}
   117  	outputLogger.Println("Done.")
   118  	return nil
   119  }