Files
coding-agent/config.go
2026-04-17 11:12:45 +03:00

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
}