5
0
mirror of https://github.com/wailsapp/wails.git synced 2025-05-02 03:39:07 +08:00
wails/v2/pkg/buildassets/buildassets.go
nick-bae bd2c1ea73f
bugfix : fix error on building runnable .app on MacOS when 'name' and 'outputfilename' are different. (#3789)
* mod : added OutputFilename field to assetData \n mod : modified resolveProjectData to export OutputFilename \n mod : modified CFBundleExecutable values to .OutputFilename in info.dev.plist, info.plist

* mod : update changelog.mdx

---------

Co-authored-by: nick-bae <nick.bae@ddkakaoenterprise.com>
2024-09-29 03:06:27 +00:00

143 lines
3.9 KiB
Go

package buildassets
import (
"bytes"
"embed"
"errors"
"fmt"
iofs "io/fs"
"os"
"path/filepath"
"text/template"
"github.com/leaanthony/gosod"
"github.com/samber/lo"
"github.com/wailsapp/wails/v2/internal/fs"
"github.com/wailsapp/wails/v2/internal/project"
)
//go:embed build
var assets embed.FS
// Same as assets but chrooted into /build/
var buildAssets iofs.FS
func init() {
buildAssets = lo.Must(iofs.Sub(assets, "build"))
}
// Install will install all default project assets
func Install(targetDir string) error {
templateDir := gosod.New(assets)
err := templateDir.Extract(targetDir, nil)
if err != nil {
return err
}
return nil
}
// GetLocalPath returns the local path of the requested build asset file
func GetLocalPath(projectData *project.Project, file string) string {
return filepath.Clean(filepath.Join(projectData.GetBuildDir(), filepath.FromSlash(file)))
}
// ReadFile reads the file from the project build folder.
// If the file does not exist it falls back to the embedded file and the file will be written
// to the disk for customisation.
func ReadFile(projectData *project.Project, file string) ([]byte, error) {
localFilePath := GetLocalPath(projectData, file)
content, err := os.ReadFile(localFilePath)
if errors.Is(err, iofs.ErrNotExist) {
// The file does not exist, let's read it from the assets FS and write it to disk
content, err := iofs.ReadFile(buildAssets, file)
if err != nil {
return nil, err
}
if err := writeFileSystemFile(projectData, file, content); err != nil {
return nil, fmt.Errorf("Unable to create file in build folder: %s", err)
}
return content, nil
}
return content, err
}
// ReadFileWithProjectData reads the file from the project build folder and replaces ProjectInfo if necessary.
// If the file does not exist it falls back to the embedded file and the file will be written
// to the disk for customisation. The file written is the original unresolved one.
func ReadFileWithProjectData(projectData *project.Project, file string) ([]byte, error) {
content, err := ReadFile(projectData, file)
if err != nil {
return nil, err
}
content, err = resolveProjectData(content, projectData)
if err != nil {
return nil, fmt.Errorf("Unable to resolve data in %s: %w", file, err)
}
return content, nil
}
// ReadOriginalFileWithProjectDataAndSave reads the file from the embedded assets and replaces
// ProjectInfo if necessary.
// It will also write the resolved final file back to the project build folder.
func ReadOriginalFileWithProjectDataAndSave(projectData *project.Project, file string) ([]byte, error) {
content, err := iofs.ReadFile(buildAssets, file)
if err != nil {
return nil, fmt.Errorf("Unable to read file %s: %w", file, err)
}
content, err = resolveProjectData(content, projectData)
if err != nil {
return nil, fmt.Errorf("Unable to resolve data in %s: %w", file, err)
}
if err := writeFileSystemFile(projectData, file, content); err != nil {
return nil, fmt.Errorf("Unable to create file in build folder: %w", err)
}
return content, nil
}
type assetData struct {
Name string
Info project.Info
OutputFilename string
}
func resolveProjectData(content []byte, projectData *project.Project) ([]byte, error) {
tmpl, err := template.New("").Parse(string(content))
if err != nil {
return nil, err
}
data := &assetData{
Name: projectData.Name,
Info: projectData.Info,
OutputFilename: projectData.OutputFilename,
}
var out bytes.Buffer
if err := tmpl.Execute(&out, data); err != nil {
return nil, err
}
return out.Bytes(), nil
}
func writeFileSystemFile(projectData *project.Project, file string, content []byte) error {
targetPath := GetLocalPath(projectData, file)
if dir := filepath.Dir(targetPath); !fs.DirExists(dir) {
if err := fs.MkDirs(dir, 0o755); err != nil {
return fmt.Errorf("Unable to create directory: %w", err)
}
}
if err := os.WriteFile(targetPath, content, 0o644); err != nil {
return err
}
return nil
}