sabisan/cmd/server/main.go
2026-05-16 20:38:13 +01:00

114 lines
2.3 KiB
Go

package main
import (
"bufio"
"fmt"
"log"
"net/http"
"os"
"strings"
"time"
"archi_folio/internal/app"
"archi_folio/internal/store"
)
func main() {
if err := loadDotEnv(".env"); err != nil {
log.Fatal(err)
}
version, err := readVersion("VERSION")
if err != nil {
log.Fatal(err)
}
cfg := app.Config{
Addr: requiredEnv("ADDR"),
DatabasePath: requiredEnv("DATABASE_PATH"),
SessionSecret: requiredEnv("SESSION_SECRET"),
AdminUsername: requiredEnv("ADMIN_USERNAME"),
AdminPassword: requiredEnv("ADMIN_PASSWORD"),
UploadDir: requiredEnv("UPLOAD_DIR"),
Version: version,
}
db, err := store.Open(cfg.DatabasePath)
if err != nil {
log.Fatal(err)
}
defer db.Close()
if err := db.Migrate(cfg.AdminUsername, cfg.AdminPassword); err != nil {
log.Fatal(err)
}
srv, err := app.New(cfg, db)
if err != nil {
log.Fatal(err)
}
server := &http.Server{
Addr: cfg.Addr,
Handler: srv.Routes(),
ReadHeaderTimeout: 5 * time.Second,
}
log.Printf("serving on http://localhost%s", cfg.Addr)
log.Fatal(server.ListenAndServe())
}
func loadDotEnv(path string) error {
file, err := os.Open(path)
if os.IsNotExist(err) {
return nil
}
if err != nil {
return err
}
defer file.Close()
scanner := bufio.NewScanner(file)
for lineNumber := 1; scanner.Scan(); lineNumber++ {
line := strings.TrimSpace(scanner.Text())
if line == "" || strings.HasPrefix(line, "#") {
continue
}
key, value, ok := strings.Cut(line, "=")
if !ok {
return fmt.Errorf("%s:%d: expected KEY=value", path, lineNumber)
}
key = strings.TrimSpace(key)
value = strings.TrimSpace(value)
value = strings.Trim(value, `"'`)
if key == "" {
return fmt.Errorf("%s:%d: empty key", path, lineNumber)
}
if _, exists := os.LookupEnv(key); !exists {
if err := os.Setenv(key, value); err != nil {
return err
}
}
}
return scanner.Err()
}
func requiredEnv(key string) string {
value, ok := os.LookupEnv(key)
if !ok || strings.TrimSpace(value) == "" {
log.Fatalf("missing required environment variable %s", key)
}
return value
}
func readVersion(path string) (string, error) {
data, err := os.ReadFile(path)
if err != nil {
return "", err
}
version := strings.TrimSpace(string(data))
if version == "" {
return "", fmt.Errorf("%s is empty", path)
}
return version, nil
}