Moonshark/moonshark.go

117 lines
3.1 KiB
Go

package main
import (
"Moonshark/modules"
"fmt"
"os"
"os/signal"
"path/filepath"
"syscall"
luajit "git.sharkk.net/Sky/LuaJIT-to-Go"
)
func main() {
if len(os.Args) < 2 {
fmt.Fprintf(os.Stderr, "Usage: %s <script.lua>\n", filepath.Base(os.Args[0]))
os.Exit(1)
}
scriptPath := os.Args[1]
// Check if file exists
if _, err := os.Stat(scriptPath); os.IsNotExist(err) {
fmt.Fprintf(os.Stderr, "Error: script file '%s' not found\n", scriptPath)
os.Exit(1)
}
// Create new Lua state with standard libraries
state := luajit.New()
if state == nil {
fmt.Fprintf(os.Stderr, "Error: failed to create Lua state\n")
os.Exit(1)
}
defer state.Close()
// Set up module system
registry := modules.NewModuleRegistry()
if err := registry.LoadEmbeddedModules(); err != nil {
fmt.Fprintf(os.Stderr, "Warning: failed to load built-in modules: %v\n", err)
}
// Backup original require and install module system
modules.BackupOriginalRequire(state)
if err := registry.InstallModules(state); err != nil {
fmt.Fprintf(os.Stderr, "Error: failed to install module system: %v\n", err)
os.Exit(1)
}
// Get the absolute path to the script directory
scriptDir := filepath.Dir(scriptPath)
absScriptDir, err := filepath.Abs(scriptDir)
if err != nil {
fmt.Fprintf(os.Stderr, "Error: failed to get absolute path: %v\n", err)
os.Exit(1)
}
// Add script directory to Lua's package.path
packagePath := filepath.Join(absScriptDir, "?.lua")
if err := state.AddPackagePath(packagePath); err != nil {
fmt.Fprintf(os.Stderr, "Warning: failed to add script directory to package.path: %v\n", err)
}
// Read script file
scriptContent, err := os.ReadFile(scriptPath)
if err != nil {
fmt.Fprintf(os.Stderr, "Error reading script file '%s': %v\n", scriptPath, err)
os.Exit(1)
}
// Compile script to bytecode
bytecode, err := state.CompileBytecode(string(scriptContent), scriptPath)
if err != nil {
fmt.Fprintf(os.Stderr, "Error compiling '%s': %v\n", scriptPath, err)
os.Exit(1)
}
// Execute the compiled bytecode
if err := state.LoadAndRunBytecode(bytecode, scriptPath); err != nil {
fmt.Fprintf(os.Stderr, "Error executing '%s': %v\n", scriptPath, err)
os.Exit(1)
}
// Check if any servers are running to determine if we need to wait
hasRunningServers := false
if result, err := state.ExecuteWithResult(`
for i = 1, 100 do
if moonshark.http_server_is_running(i) then
return true
end
end
return false
`); err == nil {
if running, ok := result.(bool); ok && running {
hasRunningServers = true
}
}
// Only set up signal handling if there are long-running services
if hasRunningServers {
sigChan := make(chan os.Signal, 1)
signal.Notify(sigChan, syscall.SIGINT, syscall.SIGTERM)
fmt.Printf("Script executed successfully. Press Ctrl+C to stop...\n")
// Wait for signal
<-sigChan
fmt.Printf("\nReceived shutdown signal. Cleaning up...\n")
// Cleanup HTTP servers through Lua
if err := state.DoString("moonshark.http_cleanup_servers()"); err != nil {
fmt.Printf("Warning: failed to cleanup servers: %v\n", err)
}
fmt.Printf("Shutdown complete.\n")
}
}