117 lines
4.1 KiB
Go
117 lines
4.1 KiB
Go
package holy
|
|
|
|
import (
|
|
"encoding/json"
|
|
"errors"
|
|
"os"
|
|
|
|
"tg-holy-bot/internal/log"
|
|
|
|
"github.com/hjson/hjson-go"
|
|
)
|
|
|
|
// ReadConfig читает и валидирует конфиг, а также выставляет некоторые default-ы, если значений для параметров в конфиге
|
|
// нет.
|
|
func ReadConfig() error {
|
|
locations, err := defaultConfigFileLocations()
|
|
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
for _, location := range locations {
|
|
fileInfo, err := os.Stat(location)
|
|
|
|
// Предполагаем, что файла либо нет, либо мы не можем его прочитать, второе надо бы логгировать, но пока забьём.
|
|
if err != nil {
|
|
continue
|
|
}
|
|
|
|
// Конфиг-файл длинноват для конфига, попробуем следующего кандидата.
|
|
if fileInfo.Size() > ConfigFileSize {
|
|
log.Warnf("Config file %s is too long for config, skipping", location)
|
|
|
|
continue
|
|
}
|
|
|
|
buf, err := os.ReadFile(location)
|
|
|
|
// Не удалось прочитать, попробуем следующего кандидата.
|
|
if err != nil {
|
|
log.Warnf("Skip reading config file %s: %s", location, err)
|
|
|
|
continue
|
|
}
|
|
|
|
// Исходя из документации, hjson какбы умеет парсить "кривой" json, но парсит его в map-ку.
|
|
// Интереснее на выходе получить структурку: то есть мы вначале конфиг преобразуем в map-ку, затем эту map-ку
|
|
// сериализуем в json, а потом json преврщааем в стркутурку. Не очень эффективно, но он и не часто требуется.
|
|
var (
|
|
sampleConfig *MyConfig
|
|
tmp map[string]any
|
|
)
|
|
|
|
err = hjson.Unmarshal(buf, &tmp)
|
|
|
|
// Не удалось распарсить - попробуем следующего кандидата.
|
|
if err != nil {
|
|
log.Warnf("Skip parsing config file %s: %s", location, err)
|
|
|
|
continue
|
|
}
|
|
|
|
tmpjson, err := json.Marshal(tmp)
|
|
|
|
// Не удалось преобразовать map-ку в json.
|
|
if err != nil {
|
|
log.Warnf("Skip parsing config file %s: %s", location, err)
|
|
|
|
continue
|
|
}
|
|
|
|
if err := json.Unmarshal(tmpjson, &sampleConfig); err != nil {
|
|
log.Warnf("Skip parsing config file %s: %s", location, err)
|
|
|
|
continue
|
|
}
|
|
|
|
if sampleConfig.Token == "" {
|
|
return errors.New("Config option token is empty. Refusing to start") //nolint: staticcheck // Looks like golangci-lint ignoring settings about fucking ST1005 check. We want readable errors despite what wants author of linter or assholes from go dev team.
|
|
}
|
|
|
|
if sampleConfig.ChannelID == 0 {
|
|
return errors.New("Config option channel_id is empty. Refusing to start") //nolint: staticcheck // Looks like golangci-lint ignoring settings about fucking ST1005 check. We want readable errors despite what wants author of linter or assholes from go dev team.
|
|
}
|
|
|
|
if sampleConfig.Loglevel == "" {
|
|
sampleConfig.Loglevel = Loglevel
|
|
|
|
log.Warnf("Config option loglevel not set, fallback to %s", sampleConfig.Loglevel)
|
|
}
|
|
|
|
if sampleConfig.Log == "" {
|
|
log.Warn("Config option log is not set, fallback to stderr")
|
|
}
|
|
|
|
if sampleConfig.When == "" {
|
|
sampleConfig.When = "CRON_TZ=Europe/Moscow 01 00 * * *"
|
|
|
|
log.Warnf("Config option when is not set, fallback to %s", sampleConfig.When)
|
|
}
|
|
|
|
if len(sampleConfig.UserAgents) != 31 {
|
|
return errors.New("Amount of user_agent strings in config must be exactly 31! Refusing to start") //nolint: staticcheck // Looks like golangci-lint ignoring settings about fucking ST1005 check. We want readable errors despite what wants author of linter or assholes from go dev team.
|
|
}
|
|
|
|
log.Infof("Using %s as config file", location)
|
|
|
|
Config = sampleConfig
|
|
|
|
return nil
|
|
}
|
|
|
|
return errors.New("Config was not loaded! Refusing to start") //nolint: staticcheck // Looks like golangci-lint ignoring settings about fucking ST1005 check. We want readable errors despite what wants author of linter or assholes from go dev team.
|
|
}
|
|
|
|
/* vim: set ft=go noet ai ts=4 sw=4 sts=4: */
|