init
This commit is contained in:
189
bin.go
Normal file
189
bin.go
Normal file
@@ -0,0 +1,189 @@
|
||||
package main
|
||||
|
||||
//go:generate bash -c "cd app && bun install && bun run build && sed -i 's/\"elysia\": \"^1.3.21\",/\"@sveltejs\\/kit\": \"^2.22.0\",\\n\\t\\t\"elysia\": \"^1.3.21\",/' build/package.json"
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"embed"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/fs"
|
||||
"log"
|
||||
"os"
|
||||
"os/exec"
|
||||
"os/signal"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"syscall"
|
||||
)
|
||||
|
||||
//go:embed all:app/build
|
||||
var buildFiles embed.FS
|
||||
|
||||
func main() {
|
||||
port := os.Getenv("PORT")
|
||||
if port == "" {
|
||||
port = "3000"
|
||||
}
|
||||
|
||||
homeDir, err := os.UserHomeDir()
|
||||
if err != nil {
|
||||
log.Fatal("Failed to get home directory:", err)
|
||||
}
|
||||
bunPath := filepath.Join(homeDir, ".bun", "bin", "bun")
|
||||
fmt.Printf("Looking for Bun at: %s\n", bunPath)
|
||||
|
||||
if _, err := os.Stat(bunPath); os.IsNotExist(err) {
|
||||
fmt.Println("Bun runtime not found. Installing Bun...")
|
||||
if err := installBun(); err != nil {
|
||||
log.Fatal("Failed to install Bun:", err)
|
||||
}
|
||||
if _, err := os.Stat(bunPath); os.IsNotExist(err) {
|
||||
log.Fatal("Bun installation failed - binary not found at:", bunPath)
|
||||
}
|
||||
fmt.Printf("Bun installed successfully at: %s\n", bunPath)
|
||||
} else {
|
||||
fmt.Printf("Found existing Bun at: %s\n", bunPath)
|
||||
}
|
||||
|
||||
tempDir, err := os.MkdirTemp("", "craftstation-*")
|
||||
if err != nil {
|
||||
log.Fatal("Failed to create temp directory:", err)
|
||||
}
|
||||
defer os.RemoveAll(tempDir)
|
||||
|
||||
buildFS, err := fs.Sub(buildFiles, "app/build")
|
||||
if err != nil {
|
||||
log.Fatal("Failed to create sub filesystem:", err)
|
||||
}
|
||||
|
||||
err = extractFiles(buildFS, tempDir)
|
||||
if err != nil {
|
||||
log.Fatal("Failed to extract files:", err)
|
||||
}
|
||||
|
||||
buildPath := tempDir
|
||||
|
||||
fmt.Println("Installing dependencies...")
|
||||
installCmd := exec.Command(bunPath, "install")
|
||||
installCmd.Dir = buildPath
|
||||
installCmd.Stdout = os.Stdout
|
||||
installCmd.Stderr = os.Stderr
|
||||
|
||||
if err := installCmd.Run(); err != nil {
|
||||
log.Fatal("Failed to install dependencies:", err)
|
||||
}
|
||||
|
||||
cmd := exec.Command(bunPath, "index.js")
|
||||
cmd.Dir = buildPath
|
||||
cmd.Env = append(os.Environ(),
|
||||
"PORT="+port,
|
||||
"NODE_ENV=production",
|
||||
"FORCE_COLOR=1",
|
||||
"BUN_LOG_LEVEL=info",
|
||||
)
|
||||
|
||||
stdout, err := cmd.StdoutPipe()
|
||||
if err != nil {
|
||||
log.Fatal("Failed to create stdout pipe:", err)
|
||||
}
|
||||
stderr, err := cmd.StderrPipe()
|
||||
if err != nil {
|
||||
log.Fatal("Failed to create stderr pipe:", err)
|
||||
}
|
||||
|
||||
fmt.Printf("[Runtime] Craftstation server starting on port %s\n", port)
|
||||
fmt.Printf("[Runtime] Open http://localhost:%s in your browser\n", port)
|
||||
|
||||
sigChan := make(chan os.Signal, 1)
|
||||
signal.Notify(sigChan, syscall.SIGINT, syscall.SIGTERM)
|
||||
|
||||
go func() {
|
||||
<-sigChan
|
||||
fmt.Println("\nShutting down server...")
|
||||
if cmd.Process != nil {
|
||||
cmd.Process.Signal(syscall.SIGTERM)
|
||||
}
|
||||
os.Exit(0)
|
||||
}()
|
||||
|
||||
if err := cmd.Start(); err != nil {
|
||||
log.Fatal("Failed to start server:", err)
|
||||
}
|
||||
|
||||
go func() {
|
||||
scanner := bufio.NewScanner(stdout)
|
||||
for scanner.Scan() {
|
||||
fmt.Printf("[Webserver] %s\n", scanner.Text())
|
||||
}
|
||||
}()
|
||||
|
||||
go func() {
|
||||
scanner := bufio.NewScanner(stderr)
|
||||
for scanner.Scan() {
|
||||
fmt.Printf("[Webserver Error] %s\n", scanner.Text())
|
||||
}
|
||||
}()
|
||||
|
||||
if err := cmd.Wait(); err != nil {
|
||||
if exitErr, ok := err.(*exec.ExitError); ok {
|
||||
if status, ok := exitErr.Sys().(syscall.WaitStatus); ok {
|
||||
os.Exit(status.ExitStatus())
|
||||
}
|
||||
}
|
||||
log.Fatal("Server process failed:", err)
|
||||
}
|
||||
}
|
||||
|
||||
func installBun() error {
|
||||
fmt.Println("Installing Bun runtime...")
|
||||
var cmd *exec.Cmd
|
||||
|
||||
switch runtime.GOOS {
|
||||
case "windows":
|
||||
cmd = exec.Command("powershell", "-c", "irm bun.sh/install.ps1 | iex")
|
||||
case "darwin", "linux":
|
||||
cmd = exec.Command("bash", "-c", "curl -fsSL https://bun.sh/install | bash")
|
||||
default:
|
||||
return fmt.Errorf("unsupported operating system: %s", runtime.GOOS)
|
||||
}
|
||||
|
||||
cmd.Stdout = os.Stdout
|
||||
cmd.Stderr = os.Stderr
|
||||
|
||||
if err := cmd.Run(); err != nil {
|
||||
return fmt.Errorf("failed to run Bun installer: %w", err)
|
||||
}
|
||||
|
||||
fmt.Println("Bun installation completed!")
|
||||
return nil
|
||||
}
|
||||
|
||||
func extractFiles(fsys fs.FS, destDir string) error {
|
||||
return fs.WalkDir(fsys, ".", func(path string, d fs.DirEntry, err error) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
destPath := filepath.Join(destDir, path)
|
||||
|
||||
if d.IsDir() {
|
||||
return os.MkdirAll(destPath, 0755)
|
||||
}
|
||||
|
||||
file, err := fsys.Open(path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
destFile, err := os.Create(destPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer destFile.Close()
|
||||
|
||||
_, err = io.Copy(destFile, file)
|
||||
return err
|
||||
})
|
||||
}
|
Reference in New Issue
Block a user