2026-07-04 10:16:52 +03:00
// Clyx compiler/bundler utility, Go implementation
// Created by Luxferre in 2026, released into the public domain
2026-07-04 10:13:40 +03:00
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 )
}