conf

package
v0.0.13 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 18, 2024 License: Apache-2.0 Imports: 7 Imported by: 0

Documentation

Overview

Package conf provides a way to load configuration from JSON files and environment variables, along with a structure to hold the configuration settings for an application and the ability to set up command-line flags for configuration options.

Example
package main

import (
	"fmt"
	"os"

	"github.com/patrickward/hop/conf"
)

func main() {
	// STEP1: Define a custom configuration struct that embeds BaseConfig
	type AppConfig struct {
		conf.BaseConfig // Inherit base configuration
		Redis           struct {
			Host    string        `json:"host" env:"REDIS_HOST" default:"localhost"`
			Port    int           `json:"port" env:"REDIS_PORT" default:"6379"`
			Timeout conf.Duration `json:"timeout" env:"REDIS_TIMEOUT" default:"5s"`
		} `json:"redis"`
		API struct {
			Endpoint string        `json:"endpoint" env:"API_ENDPOINT" default:"http://api.local"`
			Timeout  conf.Duration `json:"timeout" env:"API_TIMEOUT" default:"30s"`
		} `json:"api"`
	}

	// Create a temporary config file (for example purposes only)
	configJSON := `{
        "environment": "production",
        "debug": false,
        "redis": {
            "host": "redis.prod.example.com",
            "timeout": "10s"
        },
        "api": {
            "endpoint": "https://api.prod.example.com"
        }
    }`
	tmpfile, err := os.CreateTemp("", "config.*.json")
	if err != nil {
		fmt.Printf("Error creating temp file: %v\n", err)
		return
	}
	defer func(name string) {
		_ = os.Remove(name)
	}(tmpfile.Name())

	if _, err := tmpfile.Write([]byte(configJSON)); err != nil {
		fmt.Printf("Error writing temp file: %v\n", err)
		return
	}
	_ = tmpfile.Close()

	// Set some environment variables (for example purposes only)
	_ = os.Setenv("REDIS_PORT", "6380")
	_ = os.Setenv("API_TIMEOUT", "45s")

	// STEP2: Create and load configuration
	cfg := &AppConfig{}
	if err := conf.Load(cfg, tmpfile.Name()); err != nil {
		fmt.Printf("Error loading config: %v\n", err)
		return
	}

	// Print the resulting configuration
	fmt.Printf("Environment: %s\n", cfg.App.Environment)
	fmt.Printf("Redis Host: %s\n", cfg.Redis.Host)
	fmt.Printf("Redis Port: %d\n", cfg.Redis.Port)
	fmt.Printf("Redis Timeout: %s\n", cfg.Redis.Timeout)
	fmt.Printf("API Endpoint: %s\n", cfg.API.Endpoint)
	fmt.Printf("API Timeout: %s\n", cfg.API.Timeout)

}
Output:

Environment: production
Redis Host: redis.prod.example.com
Redis Port: 6380
Redis Timeout: 10s
API Endpoint: https://api.prod.example.com
API Timeout: 45s

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func ApplyFlagOverrides

func ApplyFlagOverrides(cfg *BaseConfig, fs *flag.FlagSet)

ApplyFlagOverrides ensures that if a basic flag is set, it overrides the config

func BasicFlags

func BasicFlags(fs *flag.FlagSet)

BasicFlags sets up the common flags most apps will need

Example
package main

import (
	"flag"
	"fmt"
	"io"
	"os"

	"github.com/patrickward/hop/conf"
)

func main() {
	// STEP1: Define a custom configuration struct
	type AppConfig struct {
		conf.BaseConfig
		API struct {
			Endpoint string        `json:"endpoint" env:"API_ENDPOINT" default:"http://api.local"`
			Timeout  conf.Duration `json:"timeout" env:"API_TIMEOUT" default:"30s"`
		} `json:"api"`
	}

	// Create a temporary config file (for example purposes only)
	configJSON := `{
        "api": {
            "endpoint": "https://api.example.com"
        }
    }`
	tmpfile, err := os.CreateTemp("", "config.*.json")
	if err != nil {
		fmt.Printf("Error creating temp file: %v\n", err)
		return
	}
	defer func(name string) {
		_ = os.Remove(name)
	}(tmpfile.Name())

	if _, err := tmpfile.Write([]byte(configJSON)); err != nil {
		fmt.Printf("Error writing temp file: %v\n", err)
		return
	}
	_ = tmpfile.Close()

	// Save and restore os.Args (for example purposes only)
	oldArgs := os.Args
	defer func() { os.Args = oldArgs }()

	// Simulate command line arguments
	os.Args = []string{
		"myapp",
		"--config", tmpfile.Name(),
		"--env", "production",
		"--debug",
		"--api-timeout", "1m",
	}

	// STEP2: Set up flags
	fs := flag.NewFlagSet("myapp", flag.ContinueOnError)
	fs.SetOutput(io.Discard) // Disable flag output for example

	// STEP3: Add basic flags
	conf.BasicFlags(fs)

	// STEP4: Add custom flags for this application
	apiTimeout := fs.Duration("api-timeout", 0, "API timeout duration")

	// STEP5: Parse flags
	_ = fs.Parse(os.Args[1:])

	// STEP6: Create and load configuration
	cfg := &AppConfig{}
	if err := conf.Load(cfg, fs.Lookup("config").Value.String()); err != nil {
		fmt.Printf("Error loading config: %v\n", err)
		return
	}

	// STEP7: Apply flag overrides
	conf.ApplyFlagOverrides(&cfg.BaseConfig, fs)

	// Apply other flag values that should override config
	if apiTimeout != nil && *apiTimeout != 0 {
		cfg.API.Timeout = conf.Duration{Duration: *apiTimeout}
	}

	// Print the resulting configuration
	fmt.Printf("Environment: %s\n", cfg.App.Environment)
	fmt.Printf("Debug: %v\n", cfg.App.Debug)
	fmt.Printf("API Endpoint: %s\n", cfg.API.Endpoint)
	fmt.Printf("API Timeout: %s\n", cfg.API.Timeout)

}
Output:

Environment: production
Debug: true
API Endpoint: https://api.example.com
API Timeout: 1m0s

func Load

func Load(cfg interface{}, files ...string) error

Load sets the defaults and loads configuration from JSON files and environment variables

func NewFlagSet

func NewFlagSet(appName string, errorHandling flag.ErrorHandling) *flag.FlagSet

Types

type AppConfig added in v0.0.8

type AppConfig struct {
	Environment string `json:"environment" env:"APP_ENVIRONMENT" default:"development"`
	Debug       bool   `json:"debug" env:"APP_DEBUG" default:"false"`
	SAASMode    bool   `json:"saas_mode" env:"SAAS_MODE" default:"false"`
}

type BaseConfig

type BaseConfig struct {
	//Environment string            `json:"environment" env:"APP_ENVIRONMENT" default:"development"`
	//Debug       bool              `json:"debug" env:"APP_DEBUG" default:"false"`
	App         AppConfig         `json:"app"`
	Company     CompanyConfig     `json:"company"`
	Maintenance MaintenanceConfig `json:"maintenance"`
	Server      ServerConfig      `json:"server"`
	Database    DatabaseConfig    `json:"database"`
	SMTP        SMPTConfig        `json:"smtp"`
	Log         LogConfig         `json:"log"`
}

BaseConfig provides core configuration options

func (*BaseConfig) IsDevelopment

func (c *BaseConfig) IsDevelopment() bool

func (*BaseConfig) IsProduction

func (c *BaseConfig) IsProduction() bool

type CompanyConfig

type CompanyConfig struct {
	Address      string `json:"address" env:"COMPANY_ADDRESS" default:""`
	Name         string `json:"name" env:"COMPANY_NAME" default:""`
	LogoURL      string `json:"logo_url" env:"COMPANY_LOGO_URL" default:""`
	SupportEmail string `json:"support_email" env:"COMPANY_SUPPORT_EMAIL" default:""`
	WebsiteName  string `json:"website_name" env:"COMPANY_WEBSITE_NAME" default:""`
	WebsiteURL   string `json:"website_url" env:"COMPANY_WEBSITE_URL" default:""`
}

type DatabaseConfig

type DatabaseConfig struct {
	Driver          string   `json:"driver" env:"DB_DRIVER" default:"sqlite"`
	URI             string   `json:"uri" env:"DB_URI" default:"data/db.sqlite"`
	Timeout         Duration `json:"timeout" env:"DB_TIMEOUT" default:"10s"`
	MaxIdleConns    int      `json:"max_idle_conns" env:"DB_MAX_IDLE_CONNS" default:"10"`
	MaxIdleTime     Duration `json:"max_idle_time" env:"DB_MAX_IDLE_TIME" default:"5m"`
	MaxConnLifetime Duration `json:"max_conn_lifetime" env:"DB_MAX_CONN_LIFETIME" default:"30m"`
	AutoMigrate     bool     `json:"auto_migrate" env:"DB_AUTO_MIGRATE" default:"false"`
}

type Duration

type Duration struct {
	time.Duration
}

Duration is a wrapper around time.Duration that supports JSON marshaling/unmarshaling

Example

ExampleDuration demonstrates how to use the Duration type

package main

import (
	"fmt"
	"os"

	"github.com/patrickward/hop/conf"
)

func main() {
	type Config struct {
		Timeout conf.Duration `json:"timeout" env:"TIMEOUT" default:"30s"`
	}

	cfg := &Config{}

	// Load with just defaults
	if err := conf.Load(cfg); err != nil {
		fmt.Printf("Error loading config: %v\n", err)
		return
	}

	fmt.Printf("Default timeout: %s\n", cfg.Timeout)

	// Set environment variable
	_ = os.Setenv("TIMEOUT", "1m30s")

	// Load again with environment variable
	if err := conf.Load(cfg); err != nil {
		fmt.Printf("Error loading config: %v\n", err)
		return
	}

	fmt.Printf("Environment timeout: %s\n", cfg.Timeout)

}
Output:

Default timeout: 30s
Environment timeout: 1m30s

func (Duration) MarshalJSON

func (d Duration) MarshalJSON() ([]byte, error)

MarshalJSON implements the json.Marshaler interface

func (*Duration) UnmarshalJSON

func (d *Duration) UnmarshalJSON(b []byte) error

UnmarshalJSON implements the json.Unmarshaler interface

type LogConfig

type LogConfig struct {
	Format      string `json:"format" env:"LOG_FORMAT" default:"pretty"`
	IncludeTime bool   `json:"include_time" env:"LOG_INCLUDE_TIME" default:"false"`
	Level       string `json:"level" env:"LOG_LEVEL" default:"debug"`
	Verbose     bool   `json:"verbose" env:"LOG_VERBOSE" default:"false"`
}

type MaintenanceConfig

type MaintenanceConfig struct {
	Enabled bool   `json:"enabled" env:"MAINTENANCE_ENABLED" default:"false"`
	Message string `json:"message" env:"MAINTENANCE_MESSAGE" default:""`
}

type SMPTConfig

type SMPTConfig struct {
	Host       string   `json:"host" env:"SMTP_HOST" default:"localhost"`
	Port       int      `json:"port" env:"SMTP_PORT" default:"1025"`
	Username   string   `json:"username" env:"SMTP_USERNAME" default:""`
	Password   string   `json:"password" env:"SMTP_PASSWORD" default:""`
	From       string   `json:"from" env:"SMTP_FROM" default:""`
	AuthType   string   `json:"auth_type" env:"SMTP_AUTH_TYPE" default:"LOGIN"`
	TLSPolicy  int      `json:"tls_policy" env:"SMTP_TLS_POLICY" default:"1"`
	RetryCount int      `json:"retry_count" env:"SMTP_RETRY_COUNT" default:"3"`
	RetryDelay Duration `json:"retry_delay" env:"SMTP_RETRY_DELAY" default:"5s"`
}

type ServerConfig

type ServerConfig struct {
	BaseURL         string   `json:"base_url" env:"SERVER_BASE_URL" default:"http://localhost:4444"`
	Host            string   `json:"host" env:"SERVER_HOST" default:"localhost"`
	Port            int      `json:"port" env:"SERVER_PORT" default:"4444"`
	IdleTimeout     Duration `json:"idle_timeout" env:"SERVER_IDLE_TIMEOUT" default:"120s"`
	ReadTimeout     Duration `json:"read_timeout" env:"SERVER_READ_TIMEOUT" default:"15s"`
	WriteTimeout    Duration `json:"write_timeout" env:"SERVER_WRITE_TIMEOUT" default:"15s"`
	ShutdownTimeout Duration `json:"shutdown_timeout" env:"SERVER_SHUTDOWN_TIMEOUT" default:"10s"`
}

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL