Inital commit

This commit is contained in:
eric
2026-03-12 18:58:43 +01:00
commit 8555b02752
36 changed files with 3312 additions and 0 deletions

View File

@@ -0,0 +1,239 @@
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
}