mirror of
https://github.com/wailsapp/wails.git
synced 2025-05-02 03:39:07 +08:00

* 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>
143 lines
3.9 KiB
Go
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
|
|
}
|