package process import ( "fmt" "os" "time" "git.eeqj.de/sneak/formless/database" _ "github.com/jinzhu/gorm/dialects/postgres" _ "github.com/jinzhu/gorm/dialects/sqlite" "github.com/k0kubun/pp" "github.com/mattn/go-isatty" "github.com/rs/zerolog" "github.com/rs/zerolog/log" "github.com/spf13/viper" ) // CLIEntry is the main entrypoint func CLIEntry(version string, buildarch string) int { f := new(Formless) f.version = version f.buildarch = buildarch f.configure() f.setupLogging() f.setupDatabase() return f.runForever() } // Feta is the main structure/process of this app type Formless struct { version string buildarch string api *Server dbm *database.Manager startup time.Time } func (f *Formless) configure() { viper.SetConfigName("formless") viper.SetConfigType("yaml") viper.AddConfigPath("/etc/formless") // path to look for the config file in viper.AddConfigPath("$HOME/.config/formless") // call multiple times to add many search paths viper.SetEnvPrefix("FORMLESS") viper.AutomaticEnv() viper.SetDefault("Debug", false) viper.SetDefault("DBURL", fmt.Sprintf("sqlite://%s", os.ExpandEnv("$HOME/Library/ApplicationSupport/formless/formless.db"))) if err := viper.ReadInConfig(); err != nil { if _, ok := err.(viper.ConfigFileNotFoundError); ok { // Config file not found; ignore error if desired } else { // Config file was found but another error was produced log.Panic(). Err(err). Msg("cannot read config file") } } if viper.GetBool("debug") { pp.Print(viper.AllSettings()) } } func (f *Formless) identify() { log.Info(). Str("version", f.version). Str("buildarch", f.buildarch). Msg("starting") } func (f *Formless) setupDatabase() { f.dbm = database.New() } func (f *Formless) setupLogging() { log.Logger = log.With().Caller().Logger() tty := isatty.IsTerminal(os.Stdin.Fd()) || isatty.IsCygwinTerminal(os.Stdin.Fd()) if tty { out := zerolog.NewConsoleWriter( func(w *zerolog.ConsoleWriter) { // Customize time format w.TimeFormat = time.RFC3339 }, ) log.Logger = log.Output(out) } // always log in UTC zerolog.TimestampFunc = func() time.Time { return time.Now().UTC() } zerolog.SetGlobalLevel(zerolog.InfoLevel) if viper.GetBool("debug") { zerolog.SetGlobalLevel(zerolog.DebugLevel) } f.identify() } func (f *Formless) uptime() time.Duration { return time.Since(f.startup) } func (f *Formless) runForever() int { f.startup = time.Now() home := os.Getenv("HOME") if home == "" { panic("can't find home directory") } f.api = new(Server) f.api.SetFormless(f) // api needs to get to us to access data go f.api.Serve() // this goroutine (main) does nothing until we handle signals // maybe use a context or something // FIXME(sneak) for { time.Sleep(1 * time.Second) } return 0 }