package main import ( "context" "fmt" "io" "os" "os/signal" ) type contextKey struct{ name string } type console struct { io.Reader io.Writer err io.Writer context.Context abort func() } func (c console) Log(v ...any) { fmt.Fprintln(c.err, v...) } func (c console) Args() args { return c.Get("args").(args) } func (c *console) Set(name string, value any) { c.Context = context.WithValue(c.Context, contextKey{name}, value) } func (c console) Get(name string) any { return c.Context.Value(contextKey{name}) } type args struct { dbtype string dbfile string baseFeed string Nick string URI string } func env(key, def string) string { if v, ok := os.LookupEnv(key); ok { return v } return def } func main() { ctx, stop := signal.NotifyContext(context.Background(), os.Interrupt) console := console{os.Stdin, os.Stdout, os.Stderr, ctx, stop} go func() { <-ctx.Done(); console.Log("shutdown"); stop() }() args := args{ env("XT_DBTYPE", "sqlite3"), env("XT_DBFILE", "file:twt.db"), env("XT_BASE_FEED", "feed"), env("XT_NICK", "xuu"), env("XT_URI", "https://txt.sour.is/users/xuu/twtxt.txt"), } console.Set("args", args) if err := run(console); err != nil { fmt.Println(err) os.Exit(1) } }