139 lines
3.1 KiB
Go
139 lines
3.1 KiB
Go
package main
|
|
|
|
import (
|
|
"archive/zip"
|
|
"bytes"
|
|
"fmt"
|
|
"io"
|
|
"os"
|
|
"os/exec"
|
|
"path/filepath"
|
|
"runtime"
|
|
"strings"
|
|
)
|
|
|
|
func getGopath() string {
|
|
gopath := os.Getenv("GOPATH")
|
|
if gopath != "" {
|
|
return gopath
|
|
}
|
|
out, err := exec.Command("go", "env", "GOPATH").Output()
|
|
if err == nil {
|
|
return strings.TrimSpace(string(out))
|
|
}
|
|
home, err := os.UserHomeDir()
|
|
if err == nil {
|
|
return filepath.Join(home, "go")
|
|
}
|
|
return ""
|
|
}
|
|
|
|
func addPathToZip(zw *zip.Writer, path string) error {
|
|
return filepath.Walk(path, func(walkPath string, walkInfo os.FileInfo, walkErr error) error {
|
|
if walkErr != nil {
|
|
return walkErr
|
|
}
|
|
if walkInfo.IsDir() {
|
|
return nil
|
|
}
|
|
|
|
file, err := os.Open(walkPath)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer file.Close()
|
|
|
|
header, err := zip.FileInfoHeader(walkInfo)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
// Convert path to use forward slashes for ZIP compatibility
|
|
relPath := filepath.ToSlash(walkPath)
|
|
header.Name = relPath
|
|
header.Method = zip.Deflate
|
|
|
|
writer, err := zw.CreateHeader(header)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
_, err = io.Copy(writer, file)
|
|
return err
|
|
})
|
|
}
|
|
|
|
func main() {
|
|
if len(os.Args) < 3 {
|
|
fmt.Println("Clyx compiler/bundler")
|
|
fmt.Println("Usage: clyxc out-bin-path src1 src2...")
|
|
os.Exit(1)
|
|
}
|
|
|
|
outfile := os.Args[1]
|
|
srcs := os.Args[2:]
|
|
|
|
// Check if output file exists
|
|
if _, err := os.Stat(outfile); err == nil {
|
|
fmt.Fprintf(os.Stderr, "File %s exists, won't overwrite!\n", outfile)
|
|
os.Exit(1)
|
|
}
|
|
|
|
fmt.Println(strings.Join(srcs, " "))
|
|
|
|
// Locate the Clyx interpreter binary
|
|
gopath := getGopath()
|
|
if gopath == "" {
|
|
fmt.Fprintln(os.Stderr, "Error: GOPATH could not be determined")
|
|
os.Exit(1)
|
|
}
|
|
|
|
clyxName := "clyx"
|
|
if runtime.GOOS == "windows" {
|
|
clyxName = "clyx.exe"
|
|
}
|
|
clyxPath := filepath.Join(gopath, "bin", clyxName)
|
|
|
|
clyxBin, err := os.ReadFile(clyxPath)
|
|
if err != nil {
|
|
fmt.Fprintf(os.Stderr, "Error: Clyx interpreter binary not found at %s. Please install it first using: go install codeberg.org/luxferre/clyx@latest\n", clyxPath)
|
|
os.Exit(1)
|
|
}
|
|
|
|
// Create ZIP archive in memory
|
|
var zipBuf bytes.Buffer
|
|
zw := zip.NewWriter(&zipBuf)
|
|
|
|
for _, src := range srcs {
|
|
if err := addPathToZip(zw, src); err != nil {
|
|
fmt.Fprintf(os.Stderr, "Error adding %s to ZIP: %v\n", src, err)
|
|
os.Exit(1)
|
|
}
|
|
}
|
|
|
|
if err := zw.Close(); err != nil {
|
|
fmt.Fprintf(os.Stderr, "Error closing ZIP writer: %v\n", err)
|
|
os.Exit(1)
|
|
}
|
|
|
|
// Write bundled executable
|
|
out, err := os.OpenFile(outfile, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0755)
|
|
if err != nil {
|
|
fmt.Fprintf(os.Stderr, "Error creating output file: %v\n", err)
|
|
os.Exit(1)
|
|
}
|
|
defer out.Close()
|
|
|
|
if _, err := out.Write(clyxBin); err != nil {
|
|
fmt.Fprintf(os.Stderr, "Error writing Clyx binary: %v\n", err)
|
|
os.Exit(1)
|
|
}
|
|
|
|
if _, err := out.Write(zipBuf.Bytes()); err != nil {
|
|
fmt.Fprintf(os.Stderr, "Error writing ZIP archive: %v\n", err)
|
|
os.Exit(1)
|
|
}
|
|
|
|
fmt.Printf("Executable bundled into %s\n", outfile)
|
|
}
|