package main import ( "context" "encoding/json" "fmt" "os" "path/filepath" "github.com/jackc/pgx/v5/pgxpool" "shop/internal/check" ) func main() { loadDotEnv() ctx := context.Background() report := check.AppInfo() report.Items = append(report.Items, check.ToolVersions(ctx)...) dbURL := os.Getenv("DATABASE_URL") if dbURL == "" { report.Items = append(report.Items, check.Item{ Name: "database", Status: check.StatusWarn, Detail: "DATABASE_URL не задан — запустите: go run ./cmd/install", }) } else { pool, err := pgxpool.New(ctx, dbURL) if err != nil { report.Items = append(report.Items, check.Item{ Name: "database", Status: check.StatusError, Detail: err.Error(), }) } else { defer pool.Close() dbItems, err := check.Database(ctx, pool) if err != nil { report.Items = append(report.Items, check.Item{ Name: "database", Status: check.StatusError, Detail: err.Error(), }) } else { report.Items = append(report.Items, dbItems...) } } } enc := json.NewEncoder(os.Stdout) enc.SetIndent("", " ") _ = enc.Encode(report) fmt.Println() printSummary(report) if !report.Healthy() { os.Exit(1) } } func printSummary(r check.Report) { fmt.Printf("ShopNova %s | %s\n\n", r.AppVersion, r.GoVersion) for _, it := range r.Items { mark := "✓" switch it.Status { case check.StatusWarn: mark = "!" case check.StatusError: mark = "✗" } line := fmt.Sprintf(" %s %-18s %s", mark, it.Name+":", it.Detail) if it.Expected != "" { line += " (ожидается " + it.Expected + ")" } fmt.Println(line) } } func loadDotEnv() { root, _ := os.Getwd() path := filepath.Join(root, ".env") data, err := os.ReadFile(path) if err != nil { return } for _, line := range splitLines(string(data)) { line = trimComment(line) if line == "" { continue } k, v, ok := splitKV(line) if !ok { continue } if os.Getenv(k) == "" { _ = os.Setenv(k, v) } } } func splitLines(s string) []string { var lines []string start := 0 for i := 0; i < len(s); i++ { if s[i] == '\n' { lines = append(lines, s[start:i]) start = i + 1 } } if start < len(s) { lines = append(lines, s[start:]) } return lines } func trimComment(s string) string { if i := indexByte(s, '#'); i >= 0 { s = s[:i] } for len(s) > 0 && (s[len(s)-1] == ' ' || s[len(s)-1] == '\r') { s = s[:len(s)-1] } for len(s) > 0 && s[0] == ' ' { s = s[1:] } return s } func splitKV(s string) (string, string, bool) { for i := 0; i < len(s); i++ { if s[i] == '=' { return s[:i], s[i+1:], true } } return "", "", false } func indexByte(s string, c byte) int { for i := 0; i < len(s); i++ { if s[i] == c { return i } } return -1 }