skeleton/internal/app/app.go
2019-12-14 07:32:33 +01:00

105 lines
2.3 KiB
Go

package app
import (
"net/http"
"sync"
"bitmask.me/skeleton/assets"
"bitmask.me/skeleton/internal/database"
"bitmask.me/skeleton/internal/storage"
"bitmask.me/skeleton/internal/templates"
"github.com/caarlos0/env"
"github.com/jmoiron/sqlx"
)
// Config contains all neccessary configuration for the App
type Config struct {
DatabaseDSN string `env:"DATABASE_DSN"`
S3Key string `env:"S3_KEY"`
S3Secret string `env:"S3_SECRET"`
S3Location string `env:"S3_LOCATION"`
S3Endpoint string `env:"S3_ENDPOINT"`
S3SSL bool `env:"S3_SSL"`
S3Bucket string `env:"S3_BUCKET"`
SMTPServer string `env:"SMTP_SERVER"`
SMTPUser string `env:"SMTP_USER"`
SMTPPassword string `env:"SMTP_PASS"`
}
// ConfigFromEnv loads the configuration from environment variables
func ConfigFromEnv() *Config {
config := &Config{}
env.Parse(config)
return config
}
// App contains the dependencies for this application.
type App struct {
config *Config
Files http.FileSystem
database *sqlx.DB
// guard for lazy initialization of s3 client
storageOnce sync.Once
storage *storage.Client
// guard for lazy template loading
templatesOnce sync.Once
templates templates.Templates
}
func (c *App) Templates() templates.Templates {
c.templatesOnce.Do(func() {
c.templates = templates.LoadTemplatesFS(c.Files, "/templates")
})
return c.templates
}
func (c *App) Storage() *storage.Client {
c.storageOnce.Do(func() {
// ignore error since we will handle the nonfunctional client
// later down the line.
c.storage, _ = storage.New(&storage.Config{
Key: c.config.S3Key,
Secret: c.config.S3Secret,
Location: c.config.S3Location,
Endpoint: c.config.S3Endpoint,
SSL: c.config.S3SSL,
Bucket: c.config.S3Bucket,
})
})
return c.storage
}
func (c *App) Database() *sqlx.DB {
return c.database
}
// NewContext creates a new App from a config
func New(config *Config) *App {
context := &App{
config: config,
Files: assets.Assets,
}
initialize(context)
return context
}
func initialize(app *App) {
var err error
app.database, err = database.New(app.config.DatabaseDSN)
if err != nil {
// Since we are not sending any data yet, any error occuring here
// is likely result of a missing driver or wrong parameters.
panic(err)
}
if err != nil {
panic(err)
}
}