240 lines
5.4 KiB
Go
240 lines
5.4 KiB
Go
package main
|
|
|
|
import (
|
|
"bufio"
|
|
"flag"
|
|
"fmt"
|
|
"io"
|
|
"os"
|
|
"os/exec"
|
|
"path/filepath"
|
|
"strings"
|
|
)
|
|
|
|
type repeatedFlag []string
|
|
|
|
func (value *repeatedFlag) String() string {
|
|
return strings.Join(*value, ",")
|
|
}
|
|
|
|
func (value *repeatedFlag) Set(input string) error {
|
|
*value = append(*value, input)
|
|
return nil
|
|
}
|
|
|
|
func main() {
|
|
var clean bool
|
|
var extraArgs repeatedFlag
|
|
var manifestPath string
|
|
var mode string
|
|
var outDir string
|
|
var outputPath string
|
|
var packageDir string
|
|
var ts bool
|
|
var wailsPath string
|
|
|
|
flag.BoolVar(&clean, "clean", true, "")
|
|
flag.Var(&extraArgs, "extra-arg", "")
|
|
flag.StringVar(&manifestPath, "manifest", "", "")
|
|
flag.StringVar(&mode, "mode", "", "")
|
|
flag.StringVar(&outDir, "out-dir", "", "")
|
|
flag.StringVar(&outputPath, "out", "", "")
|
|
flag.StringVar(&packageDir, "package-dir", "", "")
|
|
flag.BoolVar(&ts, "ts", true, "")
|
|
flag.StringVar(&wailsPath, "wails", "", "")
|
|
flag.Parse()
|
|
|
|
require(mode != "", "missing --mode")
|
|
require(outDir != "", "missing --out-dir")
|
|
require(wailsPath != "", "missing --wails")
|
|
|
|
var err error
|
|
wailsPath, err = filepath.Abs(wailsPath)
|
|
must(err)
|
|
must(resolveGoEnvToAbsolutePath())
|
|
|
|
switch mode {
|
|
case "action":
|
|
require(manifestPath != "", "missing --manifest")
|
|
require(outputPath != "", "missing --out")
|
|
must(runActionMode(manifestPath, outputPath, outDir, wailsPath, clean, ts, extraArgs))
|
|
case "workspace":
|
|
require(packageDir != "", "missing --package-dir")
|
|
must(runWorkspaceMode(packageDir, outDir, wailsPath, clean, ts, extraArgs))
|
|
default:
|
|
panic("unsupported --mode")
|
|
}
|
|
}
|
|
|
|
func resolveGoEnvToAbsolutePath() error {
|
|
goBinary := os.Getenv("GO_BIN")
|
|
if goBinary == "" || filepath.IsAbs(goBinary) {
|
|
return nil
|
|
}
|
|
|
|
absolutePath, err := filepath.Abs(goBinary)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
return os.Setenv("GO_BIN", absolutePath)
|
|
}
|
|
|
|
func runActionMode(manifestPath string, outputPath string, outDir string, wailsPath string, clean bool, ts bool, extraArgs []string) error {
|
|
tempRoot, err := os.MkdirTemp("", "rules-wails-bindings-*")
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer os.RemoveAll(tempRoot)
|
|
|
|
workDir := filepath.Join(tempRoot, "work")
|
|
if err := os.MkdirAll(workDir, 0o755); err != nil {
|
|
return err
|
|
}
|
|
if err := stageManifest(manifestPath, workDir); err != nil {
|
|
return err
|
|
}
|
|
if err := runBindings(workDir, outDir, wailsPath, clean, ts, extraArgs); err != nil {
|
|
return err
|
|
}
|
|
|
|
if err := os.RemoveAll(outputPath); err != nil {
|
|
return err
|
|
}
|
|
if err := os.MkdirAll(outputPath, 0o755); err != nil {
|
|
return err
|
|
}
|
|
return copyTree(filepath.Join(workDir, outDir), outputPath)
|
|
}
|
|
|
|
func runWorkspaceMode(packageDir string, outDir string, wailsPath string, clean bool, ts bool, extraArgs []string) error {
|
|
return runBindings(packageDir, outDir, wailsPath, clean, ts, extraArgs)
|
|
}
|
|
|
|
func runBindings(cwd string, outDir string, wailsPath string, clean bool, ts bool, extraArgs []string) error {
|
|
commandArgs := []string{"generate", "bindings", "-d", outDir}
|
|
if clean {
|
|
commandArgs = append(commandArgs, "-clean")
|
|
}
|
|
if ts {
|
|
commandArgs = append(commandArgs, "-ts")
|
|
}
|
|
commandArgs = append(commandArgs, extraArgs...)
|
|
|
|
command := exec.Command(wailsPath, commandArgs...)
|
|
command.Dir = cwd
|
|
command.Stdout = os.Stdout
|
|
command.Stderr = os.Stderr
|
|
return command.Run()
|
|
}
|
|
|
|
func stageManifest(manifestPath string, destinationRoot string) error {
|
|
entries, err := readManifest(manifestPath)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
for _, entry := range entries {
|
|
destinationPath := filepath.Join(destinationRoot, entry.relativePath)
|
|
if err := os.MkdirAll(filepath.Dir(destinationPath), 0o755); err != nil {
|
|
return err
|
|
}
|
|
if err := copyFile(entry.sourcePath, destinationPath); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func readManifest(path string) ([]manifestEntry, error) {
|
|
file, err := os.Open(path)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer file.Close()
|
|
|
|
entries := make([]manifestEntry, 0)
|
|
scanner := bufio.NewScanner(file)
|
|
for scanner.Scan() {
|
|
line := strings.TrimSpace(scanner.Text())
|
|
if line == "" {
|
|
continue
|
|
}
|
|
parts := strings.SplitN(line, "\t", 2)
|
|
if len(parts) != 2 {
|
|
return nil, fmt.Errorf("invalid manifest line: %s", line)
|
|
}
|
|
entries = append(entries, manifestEntry{
|
|
sourcePath: parts[0],
|
|
relativePath: parts[1],
|
|
})
|
|
}
|
|
|
|
return entries, scanner.Err()
|
|
}
|
|
|
|
func copyTree(sourceRoot string, destinationRoot string) error {
|
|
return filepath.Walk(sourceRoot, func(path string, info os.FileInfo, err error) error {
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
relativePath, err := filepath.Rel(sourceRoot, path)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if relativePath == "." {
|
|
return nil
|
|
}
|
|
|
|
destinationPath := filepath.Join(destinationRoot, relativePath)
|
|
if info.IsDir() {
|
|
return os.MkdirAll(destinationPath, 0o755)
|
|
}
|
|
|
|
if err := os.MkdirAll(filepath.Dir(destinationPath), 0o755); err != nil {
|
|
return err
|
|
}
|
|
|
|
return copyFile(path, destinationPath)
|
|
})
|
|
}
|
|
|
|
func copyFile(sourcePath string, destinationPath string) error {
|
|
sourceFile, err := os.Open(sourcePath)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer sourceFile.Close()
|
|
|
|
destinationFile, err := os.Create(destinationPath)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer destinationFile.Close()
|
|
|
|
if _, err := io.Copy(destinationFile, sourceFile); err != nil {
|
|
return err
|
|
}
|
|
|
|
return destinationFile.Chmod(0o644)
|
|
}
|
|
|
|
func must(err error) {
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
}
|
|
|
|
func require(condition bool, message string) {
|
|
if !condition {
|
|
panic(message)
|
|
}
|
|
}
|
|
|
|
type manifestEntry struct {
|
|
sourcePath string
|
|
relativePath string
|
|
}
|