2021-03-03 17:12:02 +00:00
|
|
|
/*
|
|
|
|
GoToSocial
|
|
|
|
Copyright (C) 2021 GoToSocial Authors admin@gotosocial.org
|
|
|
|
|
|
|
|
This program is free software: you can redistribute it and/or modify
|
|
|
|
it under the terms of the GNU Affero General Public License as published by
|
|
|
|
the Free Software Foundation, either version 3 of the License, or
|
|
|
|
(at your option) any later version.
|
|
|
|
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
GNU Affero General Public License for more details.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU Affero General Public License
|
|
|
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
*/
|
|
|
|
|
|
|
|
package config
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
"os"
|
|
|
|
|
2021-03-03 20:15:20 +00:00
|
|
|
"gopkg.in/yaml.v2"
|
2021-03-03 17:12:02 +00:00
|
|
|
)
|
|
|
|
|
2021-03-04 13:38:18 +00:00
|
|
|
// Config pulls together all the configuration needed to run gotosocial
|
2021-03-03 17:12:02 +00:00
|
|
|
type Config struct {
|
2021-03-18 22:27:43 +00:00
|
|
|
LogLevel string `yaml:"logLevel"`
|
|
|
|
ApplicationName string `yaml:"applicationName"`
|
|
|
|
DBConfig *DBConfig `yaml:"db"`
|
|
|
|
TemplateConfig *TemplateConfig `yaml:"template"`
|
2021-03-03 17:12:02 +00:00
|
|
|
}
|
|
|
|
|
2021-03-18 22:27:43 +00:00
|
|
|
// FromFile returns a new config from a file, or an error if something goes amiss.
|
|
|
|
func FromFile(path string) (*Config, error) {
|
|
|
|
c, err := loadFromFile(path)
|
|
|
|
if err != nil {
|
|
|
|
return nil, fmt.Errorf("error creating config: %s", err)
|
2021-03-04 13:38:18 +00:00
|
|
|
}
|
2021-03-18 22:27:43 +00:00
|
|
|
return c, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// Default returns a new config with default values.
|
|
|
|
// Not yet implemented.
|
|
|
|
func Default() *Config {
|
|
|
|
// TODO: find a way of doing this without code repetition, because having to
|
|
|
|
// repeat all values here and elsewhere is annoying and gonna be prone to mistakes.
|
|
|
|
return &Config{
|
2021-03-20 18:04:27 +00:00
|
|
|
DBConfig: &DBConfig{},
|
2021-03-18 22:27:43 +00:00
|
|
|
TemplateConfig: &TemplateConfig{},
|
2021-03-03 17:12:02 +00:00
|
|
|
}
|
2021-03-18 22:27:43 +00:00
|
|
|
}
|
2021-03-03 17:12:02 +00:00
|
|
|
|
2021-03-18 22:27:43 +00:00
|
|
|
// Empty just returns an empty config
|
|
|
|
func Empty() *Config {
|
|
|
|
return &Config{
|
2021-03-20 18:04:27 +00:00
|
|
|
DBConfig: &DBConfig{},
|
2021-03-18 22:27:43 +00:00
|
|
|
TemplateConfig: &TemplateConfig{},
|
|
|
|
}
|
2021-03-03 17:12:02 +00:00
|
|
|
}
|
|
|
|
|
2021-03-03 20:15:20 +00:00
|
|
|
// loadFromFile takes a path to a yaml file and attempts to load a Config object from it
|
2021-03-03 17:12:02 +00:00
|
|
|
func loadFromFile(path string) (*Config, error) {
|
|
|
|
bytes, err := os.ReadFile(path)
|
|
|
|
if err != nil {
|
|
|
|
return nil, fmt.Errorf("could not read file at path %s: %s", path, err)
|
|
|
|
}
|
|
|
|
|
|
|
|
config := &Config{}
|
2021-03-03 20:15:20 +00:00
|
|
|
if err := yaml.Unmarshal(bytes, config); err != nil {
|
2021-03-03 17:12:02 +00:00
|
|
|
return nil, fmt.Errorf("could not unmarshal file at path %s: %s", path, err)
|
|
|
|
}
|
|
|
|
|
|
|
|
return config, nil
|
|
|
|
}
|
|
|
|
|
2021-03-18 22:27:43 +00:00
|
|
|
// ParseCLIFlags sets flags on the config using the provided Flags object
|
|
|
|
func (c *Config) ParseCLIFlags(f KeyedFlags) {
|
2021-03-04 13:38:18 +00:00
|
|
|
fn := GetFlagNames()
|
|
|
|
|
|
|
|
// For all of these flags, we only want to set them on the config if:
|
|
|
|
//
|
|
|
|
// a) They haven't been set at all in the config file we already parsed,
|
|
|
|
// and so we take the default from the flags object.
|
|
|
|
//
|
|
|
|
// b) They may have been set in the config, but they've *also* been set explicitly
|
|
|
|
// as a command-line argument or an env variable, which takes priority.
|
|
|
|
|
|
|
|
// general flags
|
|
|
|
if c.LogLevel == "" || f.IsSet(fn.LogLevel) {
|
|
|
|
c.LogLevel = f.String(fn.LogLevel)
|
|
|
|
}
|
|
|
|
|
|
|
|
if c.ApplicationName == "" || f.IsSet(fn.ApplicationName) {
|
|
|
|
c.ApplicationName = f.String(fn.ApplicationName)
|
|
|
|
}
|
|
|
|
|
|
|
|
// db flags
|
|
|
|
if c.DBConfig.Type == "" || f.IsSet(fn.DbType) {
|
|
|
|
c.DBConfig.Type = f.String(fn.DbType)
|
|
|
|
}
|
|
|
|
|
|
|
|
if c.DBConfig.Address == "" || f.IsSet(fn.DbAddress) {
|
|
|
|
c.DBConfig.Address = f.String(fn.DbAddress)
|
|
|
|
}
|
|
|
|
|
|
|
|
if c.DBConfig.Port == 0 || f.IsSet(fn.DbPort) {
|
|
|
|
c.DBConfig.Port = f.Int(fn.DbPort)
|
|
|
|
}
|
2021-03-03 20:15:20 +00:00
|
|
|
|
2021-03-04 13:38:18 +00:00
|
|
|
if c.DBConfig.User == "" || f.IsSet(fn.DbUser) {
|
|
|
|
c.DBConfig.User = f.String(fn.DbUser)
|
|
|
|
}
|
|
|
|
|
|
|
|
if c.DBConfig.Password == "" || f.IsSet(fn.DbPassword) {
|
|
|
|
c.DBConfig.Password = f.String(fn.DbPassword)
|
|
|
|
}
|
|
|
|
|
|
|
|
if c.DBConfig.Database == "" || f.IsSet(fn.DbDatabase) {
|
|
|
|
c.DBConfig.Database = f.String(fn.DbDatabase)
|
|
|
|
}
|
2021-03-18 22:27:43 +00:00
|
|
|
|
|
|
|
// template flags
|
|
|
|
if c.TemplateConfig.BaseDir == "" || f.IsSet(fn.TemplateBaseDir) {
|
|
|
|
c.TemplateConfig.BaseDir = f.String(fn.TemplateBaseDir)
|
|
|
|
}
|
2021-03-03 17:12:02 +00:00
|
|
|
}
|
|
|
|
|
2021-03-04 13:38:18 +00:00
|
|
|
// KeyedFlags is a wrapper for any type that can store keyed flags and give them back.
|
|
|
|
// HINT: This works with a urfave cli context struct ;)
|
|
|
|
type KeyedFlags interface {
|
2021-03-03 17:12:02 +00:00
|
|
|
String(k string) string
|
|
|
|
Int(k string) int
|
2021-03-04 13:38:18 +00:00
|
|
|
IsSet(k string) bool
|
|
|
|
}
|
|
|
|
|
|
|
|
// Flags is used for storing the names of the various flags used for
|
|
|
|
// initializing and storing urfavecli flag variables.
|
|
|
|
type Flags struct {
|
|
|
|
LogLevel string
|
|
|
|
ApplicationName string
|
|
|
|
ConfigPath string
|
|
|
|
DbType string
|
|
|
|
DbAddress string
|
|
|
|
DbPort string
|
|
|
|
DbUser string
|
|
|
|
DbPassword string
|
|
|
|
DbDatabase string
|
2021-03-18 22:27:43 +00:00
|
|
|
TemplateBaseDir string
|
2021-03-04 13:38:18 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// GetFlagNames returns a struct containing the names of the various flags used for
|
|
|
|
// initializing and storing urfavecli flag variables.
|
|
|
|
func GetFlagNames() Flags {
|
|
|
|
return Flags{
|
|
|
|
LogLevel: "log-level",
|
|
|
|
ApplicationName: "application-name",
|
|
|
|
ConfigPath: "config-path",
|
|
|
|
DbType: "db-type",
|
|
|
|
DbAddress: "db-address",
|
|
|
|
DbPort: "db-port",
|
|
|
|
DbUser: "db-user",
|
|
|
|
DbPassword: "db-password",
|
|
|
|
DbDatabase: "db-database",
|
2021-03-18 22:27:43 +00:00
|
|
|
TemplateBaseDir: "template-basedir",
|
2021-03-04 13:38:18 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// GetEnvNames returns a struct containing the names of the environment variable keys used for
|
|
|
|
// initializing and storing urfavecli flag variables.
|
|
|
|
func GetEnvNames() Flags {
|
|
|
|
return Flags{
|
|
|
|
LogLevel: "GTS_LOG_LEVEL",
|
|
|
|
ApplicationName: "GTS_APPLICATION_NAME",
|
|
|
|
ConfigPath: "GTS_CONFIG_PATH",
|
|
|
|
DbType: "GTS_DB_TYPE",
|
|
|
|
DbAddress: "GTS_DB_ADDRESS",
|
|
|
|
DbPort: "GTS_DB_PORT",
|
|
|
|
DbUser: "GTS_DB_USER",
|
|
|
|
DbPassword: "GTS_DB_PASSWORD",
|
|
|
|
DbDatabase: "GTS_DB_DATABASE",
|
2021-03-18 22:27:43 +00:00
|
|
|
TemplateBaseDir: "GTS_TEMPLATE_BASEDIR",
|
2021-03-04 13:38:18 +00:00
|
|
|
}
|
2021-03-03 17:12:02 +00:00
|
|
|
}
|