102 lines
2.2 KiB
Go
102 lines
2.2 KiB
Go
|
package app
|
||
|
|
||
|
import (
|
||
|
"net/http"
|
||
|
"sync"
|
||
|
|
||
|
"github.com/caarlos0/env"
|
||
|
"github.com/jmoiron/sqlx"
|
||
|
"bitmask.me/skeleton/assets"
|
||
|
"bitmask.me/skeleton/internal/database"
|
||
|
"bitmask.me/skeleton/internal/storage"
|
||
|
"bitmask.me/skeleton/internal/templates"
|
||
|
)
|
||
|
|
||
|
// 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"`
|
||
|
}
|
||
|
|
||
|
// 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)
|
||
|
}
|
||
|
}
|