Files
artifactapi/internal/config/env.go
T
unkinben c39703ed0d fix: getenv treats an explicitly-empty value as unset (#85)
Fixes #69

## Why
`getenv` returned the fallback whenever `os.Getenv` was empty, so an intentionally-empty env var could not override a non-empty default.

## Changes
- Use `os.LookupEnv` to distinguish unset from set-but-empty.

## Validation
- `make e2e` passes.

Reviewed-on: #85
Co-authored-by: Ben Vincent <ben@unkin.net>
Co-committed-by: Ben Vincent <ben@unkin.net>
2026-07-02 22:09:09 +10:00

73 lines
1.4 KiB
Go

package config
import (
"fmt"
"os"
"strconv"
)
type Config struct {
ListenAddr string
DBHost string
DBPort int
DBUser string
DBPass string
DBName string
DBSSL string
RedisURL string
S3Endpoint string
S3AccessKey string
S3SecretKey string
S3Bucket string
S3Secure bool
S3Region string
}
func (c *Config) DatabaseDSN() string {
return fmt.Sprintf(
"postgres://%s:%s@%s:%d/%s?sslmode=%s",
c.DBUser, c.DBPass, c.DBHost, c.DBPort, c.DBName, c.DBSSL,
)
}
func Load() (*Config, error) {
dbPort, err := strconv.Atoi(getenv("DBPORT", "5432"))
if err != nil {
return nil, fmt.Errorf("invalid DBPORT: %w", err)
}
s3Secure, _ := strconv.ParseBool(getenv("MINIO_SECURE", "false"))
cfg := &Config{
ListenAddr: getenv("LISTEN_ADDR", ":8000"),
DBHost: getenv("DBHOST", "localhost"),
DBPort: dbPort,
DBUser: getenv("DBUSER", "artifacts"),
DBPass: getenv("DBPASS", ""),
DBName: getenv("DBNAME", "artifacts"),
DBSSL: getenv("DBSSL", "disable"),
RedisURL: getenv("REDIS_URL", "redis://localhost:6379"),
S3Endpoint: getenv("MINIO_ENDPOINT", "localhost:9000"),
S3AccessKey: getenv("MINIO_ACCESS_KEY", ""),
S3SecretKey: getenv("MINIO_SECRET_KEY", ""),
S3Bucket: getenv("MINIO_BUCKET", "artifacts"),
S3Secure: s3Secure,
S3Region: getenv("MINIO_REGION", ""),
}
return cfg, nil
}
func getenv(key, fallback string) string {
if v, ok := os.LookupEnv(key); ok {
return v
}
return fallback
}