first commit
This commit is contained in:
@@ -0,0 +1,130 @@
|
||||
package config
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
)
|
||||
|
||||
const defaultAddr = ":8080"
|
||||
const defaultDataDir = ".platform-data"
|
||||
const defaultStorageBackend = "file"
|
||||
|
||||
type Config struct {
|
||||
Addr string
|
||||
StorageBackend string
|
||||
MySQLDSN string
|
||||
DataDir string
|
||||
MetadataPath string
|
||||
LogDir string
|
||||
LogBodyBackend string
|
||||
}
|
||||
|
||||
func Load() Config {
|
||||
loadLocalEnvFiles()
|
||||
|
||||
addr := os.Getenv("PLATFORM_ADDR")
|
||||
if addr == "" {
|
||||
addr = defaultAddr
|
||||
}
|
||||
dataDir := strings.TrimSpace(os.Getenv("PLATFORM_DATA_DIR"))
|
||||
if dataDir == "" {
|
||||
dataDir = defaultDataDir
|
||||
}
|
||||
metadataPath := strings.TrimSpace(os.Getenv("PLATFORM_METADATA_PATH"))
|
||||
if metadataPath == "" {
|
||||
metadataPath = filepath.Join(dataDir, "metadata.json")
|
||||
}
|
||||
logDir := strings.TrimSpace(os.Getenv("PLATFORM_LOG_DIR"))
|
||||
if logDir == "" {
|
||||
logDir = filepath.Join(dataDir, "logs")
|
||||
}
|
||||
storageBackend := strings.TrimSpace(os.Getenv("PLATFORM_STORAGE_BACKEND"))
|
||||
if storageBackend == "" {
|
||||
storageBackend = defaultStorageBackend
|
||||
}
|
||||
logBodyBackend := strings.TrimSpace(os.Getenv("PLATFORM_LOG_BODY_BACKEND"))
|
||||
|
||||
return Config{
|
||||
Addr: addr,
|
||||
StorageBackend: storageBackend,
|
||||
MySQLDSN: strings.TrimSpace(os.Getenv("PLATFORM_MYSQL_DSN")),
|
||||
DataDir: dataDir,
|
||||
MetadataPath: metadataPath,
|
||||
LogDir: logDir,
|
||||
LogBodyBackend: logBodyBackend,
|
||||
}
|
||||
}
|
||||
|
||||
func loadLocalEnvFiles() {
|
||||
candidates := []string{".env", filepath.Join("platform", ".env")}
|
||||
for _, path := range candidates {
|
||||
loadEnvFile(path)
|
||||
}
|
||||
}
|
||||
|
||||
func loadEnvFile(path string) {
|
||||
file, err := os.Open(path)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
scanner := bufio.NewScanner(file)
|
||||
for scanner.Scan() {
|
||||
key, value, ok := parseEnvLine(scanner.Text())
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
if _, exists := os.LookupEnv(key); exists {
|
||||
continue
|
||||
}
|
||||
_ = os.Setenv(key, value)
|
||||
}
|
||||
}
|
||||
|
||||
func parseEnvLine(line string) (string, string, bool) {
|
||||
line = strings.TrimSpace(line)
|
||||
if line == "" || strings.HasPrefix(line, "#") {
|
||||
return "", "", false
|
||||
}
|
||||
line = strings.TrimSpace(strings.TrimPrefix(line, "export "))
|
||||
key, value, found := strings.Cut(line, "=")
|
||||
if !found {
|
||||
return "", "", false
|
||||
}
|
||||
key = strings.TrimSpace(key)
|
||||
if key == "" || strings.ContainsAny(key, " \t") {
|
||||
return "", "", false
|
||||
}
|
||||
value = strings.TrimSpace(stripInlineComment(strings.TrimSpace(value)))
|
||||
if len(value) >= 2 {
|
||||
if (value[0] == '"' && value[len(value)-1] == '"') || (value[0] == '\'' && value[len(value)-1] == '\'') {
|
||||
value = value[1 : len(value)-1]
|
||||
}
|
||||
}
|
||||
return key, value, true
|
||||
}
|
||||
|
||||
func stripInlineComment(value string) string {
|
||||
inSingleQuote := false
|
||||
inDoubleQuote := false
|
||||
for index, char := range value {
|
||||
switch char {
|
||||
case '\'':
|
||||
if !inDoubleQuote {
|
||||
inSingleQuote = !inSingleQuote
|
||||
}
|
||||
case '"':
|
||||
if !inSingleQuote {
|
||||
inDoubleQuote = !inDoubleQuote
|
||||
}
|
||||
case '#':
|
||||
if !inSingleQuote && !inDoubleQuote && index > 0 && value[index-1] == ' ' {
|
||||
return strings.TrimSpace(value[:index])
|
||||
}
|
||||
}
|
||||
}
|
||||
return value
|
||||
}
|
||||
Reference in New Issue
Block a user