95 lines
1.9 KiB
Go
95 lines
1.9 KiB
Go
package main
|
|
|
|
import (
|
|
"bufio"
|
|
"encoding/json"
|
|
"fmt"
|
|
"os"
|
|
"path/filepath"
|
|
"strings"
|
|
)
|
|
|
|
// loadConfig reads .env and .config.json from root (if present) and sets any
|
|
// keys that aren't already in the process environment. Real env vars win.
|
|
// Recognized keys: OPENAI_API_KEY, OPENAI_BASE_URL, OPENAI_MODEL.
|
|
func loadConfig(root string) error {
|
|
if err := loadEnvFile(filepath.Join(root, ".env")); err != nil {
|
|
return fmt.Errorf(".env: %w", err)
|
|
}
|
|
if err := loadJSONConfig(filepath.Join(root, ".config.json")); err != nil {
|
|
return fmt.Errorf(".config.json: %w", err)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func loadEnvFile(path string) error {
|
|
f, err := os.Open(path)
|
|
if err != nil {
|
|
if os.IsNotExist(err) {
|
|
return nil
|
|
}
|
|
return err
|
|
}
|
|
defer f.Close()
|
|
|
|
scanner := bufio.NewScanner(f)
|
|
lineNo := 0
|
|
for scanner.Scan() {
|
|
lineNo++
|
|
line := strings.TrimSpace(scanner.Text())
|
|
if line == "" || strings.HasPrefix(line, "#") {
|
|
continue
|
|
}
|
|
if strings.HasPrefix(line, "export ") {
|
|
line = strings.TrimPrefix(line, "export ")
|
|
}
|
|
eq := strings.IndexByte(line, '=')
|
|
if eq <= 0 {
|
|
return fmt.Errorf("line %d: missing '='", lineNo)
|
|
}
|
|
key := strings.TrimSpace(line[:eq])
|
|
val := strings.TrimSpace(line[eq+1:])
|
|
val = unquote(val)
|
|
setIfEmpty(key, val)
|
|
}
|
|
return scanner.Err()
|
|
}
|
|
|
|
func loadJSONConfig(path string) error {
|
|
b, err := os.ReadFile(path)
|
|
if err != nil {
|
|
if os.IsNotExist(err) {
|
|
return nil
|
|
}
|
|
return err
|
|
}
|
|
var m map[string]string
|
|
if err := json.Unmarshal(b, &m); err != nil {
|
|
return err
|
|
}
|
|
for k, v := range m {
|
|
setIfEmpty(k, v)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func setIfEmpty(key, val string) {
|
|
if key == "" {
|
|
return
|
|
}
|
|
if _, ok := os.LookupEnv(key); ok {
|
|
return
|
|
}
|
|
_ = os.Setenv(key, val)
|
|
}
|
|
|
|
func unquote(s string) string {
|
|
if len(s) >= 2 {
|
|
first, last := s[0], s[len(s)-1]
|
|
if (first == '"' && last == '"') || (first == '\'' && last == '\'') {
|
|
return s[1 : len(s)-1]
|
|
}
|
|
}
|
|
return s
|
|
}
|