saasitone/config/config.go

165 lines
3.8 KiB
Go

package config
import (
"os"
"path/filepath"
"strings"
"time"
"github.com/spf13/viper"
)
const (
// TemplateExt stores the extension used for the template files
TemplateExt = ".gohtml"
// StaticDir stores the name of the directory that will serve static files
StaticDir = "static"
// StaticPrefix stores the URL prefix used when serving static files
StaticPrefix = "files"
)
type environment string
const (
// EnvLocal represents the local environment
EnvLocal environment = "local"
// EnvTest represents the test environment
EnvTest environment = "test"
// EnvDevelop represents the development environment
EnvDevelop environment = "dev"
// EnvStaging represents the staging environment
EnvStaging environment = "staging"
// EnvQA represents the qa environment
EnvQA environment = "qa"
// EnvProduction represents the production environment
EnvProduction environment = "prod"
)
// SwitchEnvironment sets the environment variable used to dictate which environment the application is
// currently running in.
// This must be called prior to loading the configuration in order for it to take effect.
func SwitchEnvironment(env environment) {
if err := os.Setenv("PAGODA_APP_ENVIRONMENT", string(env)); err != nil {
panic(err)
}
}
type (
// Config stores complete configuration
Config struct {
HTTP HTTPConfig
App AppConfig
Cache CacheConfig
Storage StorageConfig
Tasks TasksConfig
Mail MailConfig
}
// HTTPConfig stores HTTP configuration
HTTPConfig struct {
Hostname string
Port uint16
ReadTimeout time.Duration
WriteTimeout time.Duration
IdleTimeout time.Duration
TLS struct {
Enabled bool
Certificate string
Key string
}
}
// AppConfig stores application configuration
AppConfig struct {
Name string
Environment environment
EncryptionKey string
Timeout time.Duration
PasswordToken struct {
Expiration time.Duration
Length int
}
EmailVerificationTokenExpiration time.Duration
}
// CacheConfig stores the cache configuration
CacheConfig struct {
Capacity int
Expiration struct {
StaticFile time.Duration
Page time.Duration
}
}
// StorageConfig stores the storage configuration
StorageConfig struct {
// DatabaseFile is the path used to find the database file.
// It can be an absolute path, or a path relative to the config file location.
DatabaseFile string
// MigrationsDir is the path used to find the migration files.
// It can be an absolute path, or a path relative to the config file location.
MigrationsDir string
}
// TasksConfig stores the tasks configuration
TasksConfig struct {
PollInterval time.Duration
MaxRetries int
Goroutines int
}
// MailConfig stores the mail configuration
MailConfig struct {
Hostname string
Port uint16
User string
Password string
FromAddress string
}
)
// GetConfig loads and returns configuration
func GetConfig() (Config, error) {
var c Config
// Load the config file
viper.SetConfigName("config")
viper.SetConfigType("yaml")
viper.AddConfigPath(".")
viper.AddConfigPath("config")
viper.AddConfigPath("../")
viper.AddConfigPath("../../")
// Load env variables
viper.SetEnvPrefix("pagoda")
viper.AutomaticEnv()
viper.SetEnvKeyReplacer(strings.NewReplacer(".", "_"))
if err := viper.ReadInConfig(); err != nil {
return c, err
}
if err := viper.Unmarshal(&c); err != nil {
return c, err
}
usedConfigFilePath := viper.GetViper().ConfigFileUsed()
configFileDir := filepath.Dir(usedConfigFilePath)
if !filepath.IsAbs(c.Storage.DatabaseFile) {
c.Storage.DatabaseFile = filepath.Join(configFileDir, c.Storage.DatabaseFile)
}
if !filepath.IsAbs(c.Storage.MigrationsDir) {
c.Storage.MigrationsDir = filepath.Join(configFileDir, c.Storage.MigrationsDir)
}
return c, nil
}