gitea, notion webhook
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

118 lines
3.2 KiB

package config
import (
"os"
"strings"
"github.com/joho/godotenv"
)
// Config holds all runtime settings, loaded from environment (.env optional).
type Config struct {
// Slack
SlackBotToken string
DefaultSlackChannel string // fallback channel when a recipient email can't be resolved
// Gitea
GiteaWebhookSecret string
// Notion
NotionVerificationToken string
NotionAPIToken string
NotionAssigneeProperty string
// App
MappingFile string
Addr string
// Logging
Env string // development | production
LogLevel string // debug | info | warn | error
LogFormat string // text | json
LogFile string // optional file path; empty = stdout only
}
// Load reads configuration for the given environment and loads its .env files.
//
// The environment is decided by the run command (the -env flag passed as
// envOverride). If empty, it falls back to the APP_ENV variable, then
// "development". This keeps env selection command-driven, not ambient.
//
// Precedence: an earlier-loaded file wins (godotenv.Load never overrides an
// already-set variable), and missing files are ignored:
//
// .env.{env}.local # 개인 비밀값 (git 제외, 선택)
// .env.{env} # 환경별 설정 (.env.dev / .env.prod)
// .env # 공통 기본값 (fallback)
func Load(envOverride string) Config {
env := envOverride
if env == "" {
env = getenv("APP_ENV", "dev")
}
env = normalizeEnv(env)
_ = godotenv.Load(".env." + env + ".local")
_ = godotenv.Load(".env." + env)
_ = godotenv.Load(".env")
return Config{
SlackBotToken: os.Getenv("SLACK_BOT_TOKEN"),
DefaultSlackChannel: os.Getenv("DEFAULT_SLACK_CHANNEL"),
GiteaWebhookSecret: os.Getenv("GITEA_WEBHOOK_SECRET"),
NotionVerificationToken: os.Getenv("NOTION_VERIFICATION_TOKEN"),
NotionAPIToken: os.Getenv("NOTION_API_TOKEN"),
NotionAssigneeProperty: getenv("NOTION_ASSIGNEE_PROPERTY", "담당자"),
MappingFile: getenv("MAPPING_FILE", "data/mappings.json"),
Addr: getenv("ADDR", ":8000"),
Env: env,
LogLevel: getenv("LOG_LEVEL", defaultLogLevel(env)),
LogFormat: getenv("LOG_FORMAT", defaultLogFormat(env)),
LogFile: getenv("LOG_FILE", defaultLogFile(env)),
}
}
// normalizeEnv canonicalizes the env name to the short form "dev" or "prod".
// Long forms (development/production) and unknown values map sensibly.
func normalizeEnv(s string) string {
switch strings.ToLower(strings.TrimSpace(s)) {
case "prod", "production":
return "prod"
default:
return "dev"
}
}
// IsProduction reports whether the app runs in the production environment.
func (c Config) IsProduction() bool { return c.Env == "prod" }
func defaultLogLevel(env string) string {
if env == "prod" {
return "info"
}
return "debug"
}
func defaultLogFormat(env string) string {
if env == "prod" {
return "json"
}
return "text"
}
// defaultLogFile decides where logs are written when LOG_FILE is unset:
// - dev → "" (콘솔/IDE 출력만)
// - prod → 파일로 추출 (logs/app.log)
func defaultLogFile(env string) string {
if env == "prod" {
return "logs/app.log"
}
return ""
}
func getenv(key, fallback string) string {
if v := os.Getenv(key); v != "" {
return v
}
return fallback
}