1package main
2
3import (
4 "context"
5 "fmt"
6 "log/slog"
7 "net/http"
8 "os"
9 "os/signal"
10 "syscall"
11
12 _ "net/http/pprof" // profiling
13
14 _ "github.com/joho/godotenv/autoload" // automatically load .env files
15
16 "github.com/charmbracelet/crush/cmd"
17 "github.com/charmbracelet/crush/internal/log"
18)
19
20func main() {
21 defer log.RecoverPanic("main", func() {
22 slog.Error("Application terminated due to unhandled panic")
23 })
24
25 ctx, cancel := context.WithCancel(context.Background())
26 defer cancel()
27
28 sigChan := make(chan os.Signal, 1)
29 signal.Notify(sigChan, os.Interrupt, syscall.SIGTERM, syscall.SIGQUIT)
30
31 // Start signal handler in a goroutine
32 go func() {
33 sig := <-sigChan
34 slog.Info("Received signal, initiating graceful shutdown", "signal", sig)
35 cancel()
36 }()
37
38 if os.Getenv("CRUSH_PROFILE") != "" {
39 go func() {
40 slog.Info("Serving pprof at localhost:6060")
41 if httpErr := http.ListenAndServe("localhost:6060", nil); httpErr != nil {
42 slog.Error(fmt.Sprintf("Failed to pprof listen: %v", httpErr))
43 }
44 }()
45 }
46
47 cmd.Execute(ctx)
48}