tsconf

package module
v0.1.0 Latest Latest
Warning

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

Go to latest
Published: Jun 12, 2025 License: MIT Imports: 17 Imported by: 0

README

TSConf - Go Configuration Management Library

English | 中文文档

A powerful, flexible, and easy-to-use configuration management library for Go applications. TSConf supports multiple file formats, configuration merging and encryption/decryption capabilities.

Go Report Card Go Version PkgGoDev

Features

  • Multiple Format Support: JSON, YAML, TOML, INI, ENV files
  • Configuration Merging: Load multiple files with priority-based merging
  • Type Conversion: Powered by spf13/cast for robust type conversions
  • Dot Notation: Access nested configuration values using dot notation (e.g., server.database.host)
  • No Error Handling Required: All getter methods return zero values for non-existent keys (except Load and SetConfigs)
  • Encryption Support: Built-in AES-GCM encryption for sensitive configuration files
  • Rich Data Types: Support for strings, integers, booleans, floats, slices, maps, time, and duration
  • Thread-Safe: Safe for concurrent use
  • Zero Dependencies: Only uses standard library and well-established packages

Installation

go get github.com/tinystack/tsconf

Quick Start

package main

import (
    "fmt"
    "github.com/tinystack/tsconf"
)

func main() {
    // Create a new config instance
    config := tsconf.NewConfig()

    // Load configuration from file
    if err := config.Load("config.json"); err != nil {
        panic(err)
    }

    // Access configuration values - no error handling needed!
    appName := config.GetString("app.name")
    port := config.GetInt("server.port")
    debug := config.GetBool("app.debug")

    fmt.Printf("App: %s, Port: %d, Debug: %t\n", appName, port, debug)
}

API Reference

Core Methods
NewConfig() *Config

Creates a new configuration instance.

Load(path string) error

Loads and parses a configuration file. Supports merging multiple files with later files having higher priority.

config := tsconf.NewConfig()

// Load multiple files - later files override earlier ones
config.Load("config.json")          // Base configuration
config.Load("config.local.yaml")    // Local overrides
config.Load("config.prod.toml")     // Environment-specific
SetConfigs(configs map[string]any) error

Programmatically sets configuration values using dot notation.

configs := map[string]any{
    "server.host": "localhost",
    "server.port": 8080,
    "database.host": "db.example.com",
    "features.auth": true,
}
config.SetConfigs(configs)
Getter Methods (Zero-Value Return)

All getter methods return appropriate zero values when keys don't exist, eliminating the need for error handling.

String Values
// Get string value
name := config.GetString("app.name")           // Returns "" if not found
alias := config.Get("app.alias")               // Alias for GetString
Numeric Values
port := config.GetInt("server.port")           // Returns 0 if not found
timeout := config.GetFloat64("server.timeout") // Returns 0.0 if not found
Boolean Values
debug := config.GetBool("app.debug")           // Returns false if not found
Slice Values
// Handles both arrays and comma-separated strings
tags := config.GetStringSlice("app.tags")     // Returns []string{} if not found
ports := config.GetIntSlice("server.ports")   // Returns []int{} if not found
rates := config.GetFloatSlice("api.rates")    // Returns []float64{} if not found
Map Values
// Get nested configuration as map
metadata := config.GetStringMap("app.metadata")           // Returns map[string]any{}
settings := config.GetStringMapString("app.settings")     // Returns map[string]string{}
Time and Duration Values
// Supports various time formats
createdAt := config.GetTime("app.created_at")     // Returns time.Time{} if not found

// Supports duration strings like "30s", "5m", "2h30m"
timeout := config.GetDuration("server.timeout")   // Returns 0 if not found
Utility Methods
// Check if a key exists
exists := config.IsSet("database.enabled")    // Returns bool
Encryption Methods
SetEncryptionKey(key string)

Sets the encryption key for encrypting/decrypting configuration files.

Encrypt(data []byte) ([]byte, error)

Encrypts data using AES-GCM encryption.

Decrypt(data []byte) ([]byte, error)

Decrypts data using AES-GCM decryption.

config := tsconf.NewConfig()
config.SetEncryptionKey("your-secret-key-32-chars-long!")

// Encrypt sensitive config
data := []byte(`{"api_key": "secret"}`)
encrypted, _ := config.Encrypt(data)

// Save encrypted file and load it
os.WriteFile("secret.json", encrypted, 0644)
config.Load("secret.json")  // Automatically decrypts if key is set

Type Conversion Examples

TSConf uses spf13/cast for robust type conversions:

config := tsconf.NewConfig()
config.SetConfigs(map[string]any{
    "port":        "8080",           // String to int
    "debug":       "true",           // String to bool
    "timeout":     "30.5",           // String to float
    "tags":        "web,api,auth",   // CSV string to slice
    "numbers":     "1,2,3,4,5",      // CSV string to int slice
    "rates":       "1.1,2.2,3.3",   // CSV string to float slice
    "duration":    "5m30s",          // String to duration
    "created":     "2023-01-01T12:00:00Z", // String to time
})

// All conversions handled automatically
port := config.GetInt("port")               // 8080
debug := config.GetBool("debug")            // true
timeout := config.GetFloat64("timeout")     // 30.5
tags := config.GetStringSlice("tags")       // ["web", "api", "auth"]
numbers := config.GetIntSlice("numbers")    // [1, 2, 3, 4, 5]
rates := config.GetFloatSlice("rates")      // [1.1, 2.2, 3.3]
duration := config.GetDuration("duration")  // 5m30s
created := config.GetTime("created")        // 2023-01-01 12:00:00 +0000 UTC

File Format Examples

JSON
{
  "app": {
    "name": "MyApp",
    "port": 8080,
    "debug": true,
    "features": ["auth", "logging"]
  },
  "database": {
    "host": "localhost",
    "timeout": "30s"
  }
}
YAML
app:
  name: MyApp
  port: 8080
  debug: true
  features:
    - auth
    - logging
database:
  host: localhost
  timeout: 30s
TOML
[app]
name = "MyApp"
port = 8080
debug = true
features = ["auth", "logging"]

[database]
host = "localhost"
timeout = "30s"
INI
[DEFAULT]
global_key = global_value

[app]
name = MyApp
port = 8080
debug = true
features = auth,logging

[database]
host = localhost
timeout = 30s
ENV
APP_NAME=MyApp
APP_PORT=8080
APP_DEBUG=true
APP_FEATURES=auth,logging
DATABASE_HOST=localhost
DATABASE_TIMEOUT=30s

Advanced Usage

Configuration Merging
config := tsconf.NewConfig()

// Load base configuration
config.Load("config.json")

// Load environment-specific overrides
config.Load("config.production.yaml")

// Load local development overrides
config.Load("config.local.toml")

// Later files override earlier ones
appName := config.GetString("app.name")  // From the last loaded file
Working with Complex Data
// Nested maps
settings := config.GetStringMap("app.settings")
if settings["feature_flags"] != nil {
    flags := settings["feature_flags"].(map[string]any)
    // Process feature flags
}

// Check existence before use
if config.IsSet("optional.feature") {
    feature := config.GetBool("optional.feature")
    // Use feature
}

// Time-based configuration
deployment := config.GetTime("deployment.timestamp")
if !deployment.IsZero() {
    fmt.Printf("Deployed at: %s\n", deployment.Format("2006-01-02 15:04:05"))
}

// Duration configuration
cacheTTL := config.GetDuration("cache.ttl")
if cacheTTL > 0 {
    // Set up cache with TTL
}
Error Handling
config := tsconf.NewConfig()

// Only Load and SetConfigs can return errors
if err := config.Load("config.json"); err != nil {
    log.Fatalf("Failed to load config: %v", err)
}

// All getter methods return zero values - no error handling needed
port := config.GetInt("server.port")  // 0 if not found
if port == 0 {
    port = 8080  // Default value
}

// Use IsSet to distinguish between zero values and missing keys
if !config.IsSet("server.port") {
    log.Println("Port not configured, using default")
}

Best Practices

  1. Use dot notation for nested configuration access
  2. Load multiple files for environment-specific configurations
  3. Check with IsSet() when zero values are valid configuration values
  4. Use appropriate data types (GetInt for ports, GetDuration for timeouts)
  5. Set encryption keys for sensitive configuration files
  6. Leverage type conversion - let cast handle string-to-type conversions

Performance

TSConf is designed for performance:

  • Efficient parsing and caching
  • Minimal memory allocation
  • Fast key lookups using dot notation
  • Benchmark results:
    • Load operation: ~32μs
    • Get operation: ~79ns

License

This project is licensed under the MIT License - see the LICENSE file for details.

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.


Links:

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Config

type Config struct {
	// contains filtered or unexported fields
}

Config represents the configuration manager that supports multiple file formats and provides methods for loading, merging, and retrieving configuration values

func NewConfig

func NewConfig() *Config

NewConfig creates a new Config instance

func (*Config) Decrypt

func (c *Config) Decrypt(data []byte) ([]byte, error)

Decrypt decrypts data using AES-GCM

func (*Config) Encrypt

func (c *Config) Encrypt(data []byte) ([]byte, error)

Encrypt encrypts data using AES-GCM

func (*Config) Get

func (c *Config) Get(key string) string

Get retrieves a configuration value as string

func (*Config) GetBool

func (c *Config) GetBool(key string) bool

GetBool retrieves a configuration value as boolean

func (*Config) GetDuration

func (c *Config) GetDuration(key string) time.Duration

GetDuration retrieves a configuration value as time.Duration

func (*Config) GetFloat64

func (c *Config) GetFloat64(key string) float64

GetFloat64 retrieves a configuration value as float64

func (*Config) GetFloatSlice

func (c *Config) GetFloatSlice(key string) []float64

GetFloatSlice retrieves a configuration value as float64 slice

func (*Config) GetInt

func (c *Config) GetInt(key string) int

GetInt retrieves a configuration value as integer

func (*Config) GetIntSlice

func (c *Config) GetIntSlice(key string) []int

GetIntSlice retrieves a configuration value as integer slice

func (*Config) GetString

func (c *Config) GetString(key string) string

GetString is an alias for Get method

func (*Config) GetStringMap

func (c *Config) GetStringMap(key string) map[string]any

GetStringMap retrieves a configuration value as map[string]any

func (*Config) GetStringMapString

func (c *Config) GetStringMapString(key string) map[string]string

GetStringMapString retrieves a configuration value as map[string]string

func (*Config) GetStringSlice

func (c *Config) GetStringSlice(key string) []string

GetStringSlice retrieves a configuration value as string slice

func (*Config) GetTime

func (c *Config) GetTime(key string) time.Time

GetTime retrieves a configuration value as time.Time

func (*Config) IsSet

func (c *Config) IsSet(key string) bool

IsSet checks if a configuration key exists

func (*Config) Load

func (c *Config) Load(path string) error

Load reads and parses configuration files, supporting merging and priority management Supports .json, .ini, .yaml, .yml, .toml, .env file formats Later loaded files have higher priority and can override earlier values

func (*Config) SetConfigs

func (c *Config) SetConfigs(configs map[string]any) error

SetConfigs sets configuration values using dot notation keys Supports nested keys like "section.key.subkey" Overwrites existing values

func (*Config) SetEncryptionKey

func (c *Config) SetEncryptionKey(key string)

SetEncryptionKey sets the encryption key for encrypting/decrypting configuration files

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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