add support for env variables to the DSL

This commit is contained in:
2025-09-02 00:54:38 -06:00
parent c6f14e1787
commit 69f507f176
12 changed files with 842 additions and 84 deletions

View File

@ -4,6 +4,7 @@ import (
"fmt"
"go/format"
"masonry/lang"
"strconv"
"strings"
"golang.org/x/text/cases"
@ -69,6 +70,8 @@ import (
"fmt"
"log"
"net/http"
"os"
"strconv"
"sync"
"time"
"github.com/google/uuid"
@ -362,25 +365,95 @@ func (si *ServerInterpreter) generateMainFunction() string {
}
}
// Server configuration
host := "localhost"
port := 8080
// Generate server configuration code that handles env vars and defaults at runtime
code.WriteString("\n\t// Server configuration\n")
code.WriteString(si.generateServerConfigCode())
if si.server != nil {
for _, setting := range si.server.Settings {
if setting.Host != nil {
host = *setting.Host
}
if setting.Port != nil {
port = *setting.Port
}
}
}
code.WriteString(fmt.Sprintf("\n\taddr := \"%s:%d\"\n", host, port))
code.WriteString("\n\taddr := fmt.Sprintf(\"%s:%d\", host, port)\n")
code.WriteString("\tfmt.Printf(\"Server starting on %s\\n\", addr)\n")
code.WriteString("\tlog.Fatal(http.ListenAndServe(addr, r))\n")
code.WriteString("}\n")
return code.String()
}
// generateServerConfigCode generates Go code that handles server configuration at runtime
func (si *ServerInterpreter) generateServerConfigCode() string {
var code strings.Builder
// Default values
hostDefault := "localhost"
portDefault := 8080
var hostConfigValueCode, portConfigValueCode string
if si.server != nil {
for _, setting := range si.server.Settings {
if setting.Host != nil {
if setting.Host.EnvVar != nil && setting.Host.EnvVar.Default != nil {
hostDefault = *setting.Host.EnvVar.Default
}
hostConfigValueCode = si.generateConfigValueCode("host", setting.Host)
}
if setting.Port != nil {
if setting.Port.EnvVar != nil && setting.Port.EnvVar.Default != nil {
if defInt, err := strconv.Atoi(*setting.Port.EnvVar.Default); err == nil {
portDefault = defInt
}
}
portConfigValueCode = si.generateIntValueCode("port", setting.Port)
}
}
}
code.WriteString(fmt.Sprintf("\thost := \"%s\"\n", hostDefault))
code.WriteString(fmt.Sprintf("\tport := %d\n\n", portDefault))
code.WriteString(hostConfigValueCode)
code.WriteString(portConfigValueCode)
return code.String()
}
// generateConfigValueCode generates Go code to resolve a ConfigValue at runtime
func (si *ServerInterpreter) generateConfigValueCode(varName string, configValue *lang.ConfigValue) string {
var code strings.Builder
if configValue.Literal != nil {
// Simple literal assignment
code.WriteString(fmt.Sprintf("\t%s = %q\n", varName, *configValue.Literal))
} else if configValue.EnvVar != nil {
// Environment variable with optional default
code.WriteString(fmt.Sprintf("\tif envVal := os.Getenv(%q); envVal != \"\" {\n", configValue.EnvVar.Name))
code.WriteString(fmt.Sprintf("\t\t%s = envVal\n", varName))
if configValue.EnvVar.Default != nil {
code.WriteString("\t} else {\n")
code.WriteString(fmt.Sprintf("\t\t%s = %q\n", varName, *configValue.EnvVar.Default))
}
code.WriteString("\t}\n")
}
return code.String()
}
// generateIntValueCode generates Go code to resolve an IntValue at runtime
func (si *ServerInterpreter) generateIntValueCode(varName string, intValue *lang.IntValue) string {
var code strings.Builder
if intValue.Literal != nil {
// Simple literal assignment
code.WriteString(fmt.Sprintf("\t%s = %d\n", varName, *intValue.Literal))
} else if intValue.EnvVar != nil {
// Environment variable with optional default
code.WriteString(fmt.Sprintf("\tif envVal := os.Getenv(%q); envVal != \"\" {\n", intValue.EnvVar.Name))
code.WriteString(fmt.Sprintf("\t\tif val, err := strconv.Atoi(envVal); err == nil {\n"))
code.WriteString(fmt.Sprintf("\t\t\t%s = val\n", varName))
code.WriteString("\t\t}\n")
if intValue.EnvVar.Default != nil {
code.WriteString("\t} else {\n")
code.WriteString(fmt.Sprintf("\t\t%s = %s\n", varName, *intValue.EnvVar.Default))
}
code.WriteString("\t}\n")
}
return code.String()
}