Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

#4 upd docs; #6

Merged
merged 2 commits into from
Apr 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
180 changes: 179 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
- Set default values for each field using tags.
- Easy to inject as much custom parsers as you need.
- Easy to inject your own values providers as much as you need and use them all at once with priority.
- Automatic documentation generator.

## Quick start

Expand Down Expand Up @@ -51,7 +52,9 @@ type AppConfig struct {
// Supported Tags:
// - env: Specifies the environment variable name.
// - default: Specifies the default value for the field.
// - omitempty: Allows empty fields. FOR STRINGS ONLY!
// - omitempty: Allows empty fields.
// If both the parsed value and the default value are empty,
// the field will be set to the zero value for its type in Go.

LogLevel LoggerConfig
RedisConfig RedisConfig
Expand Down Expand Up @@ -263,4 +266,179 @@ func main() {
}
}

```

### Documentation generation

1. Let's say you have such config file `/internal/config/config.go`:

```go
package config

import (
"github.com/Jagerente/gocfg"
"github.com/Jagerente/gocfg/pkg/values"
"time"
cache_factory "your_cool_app/internal/router/cache"
)

type LoggerConfig struct {
LogLevel int `env:"LOG_LEVEL" default:"6" description:"https://pkg.go.dev/github.com/sirupsen/logrus@v1.9.3#Level"`
ReportCaller bool `env:"REPORT_CALLER" default:"true"`
LogFormatter int `env:"LOG_FORMATTER" default:"0"`
}

type CassandraConfig struct {
CassandraHosts string `env:"CASSANDRA_HOSTS" default:"127.0.0.1"`
CassandraKeyspace string `env:"CASSANDRA_KEYSPACE" default:"user_data_service"`
}

type RouterConfig struct {
ServerPort uint16 `env:"SERVER_PORT" default:"8080"`
Debug bool `env:"ROUTER_DEBUG" default:"true"`
CacheAdapter string `env:"CACHE_ADAPTER,omitempty" description:"Leave blank to not use.\nPossible values:\n- redis\n- memcache"`
CacheAdapterTTL time.Duration `env:"CACHE_ADAPTER_TTL,omitempty" default:"1m"`
CacheAdapterNoCacheParam string `env:"CACHE_ADAPTER_NOCACHE_PARAM,omitempty" default:"no-cache"`
}

type RedisCacheAdapterConfig struct {
RedisAddr string `env:"CACHE_ADAPTER_REDIS_ADDR,omitempty" default:":6379"`
RedisDB int `env:"CACHE_ADAPTER_REDIS_DB,omitempty" default:"0"`
RedisUsername string `env:"CACHE_ADAPTER_REDIS_USERNAME,omitempty"`
RedisPassword string `env:"CACHE_ADAPTER_REDIS_PASSWORD,omitempty"`
}

type MemcacheCacheAdapterConfig struct {
Capacity int `env:"CACHE_ADAPTER_MEMCACHE_CAPACITY,omitempty" default:"10000000"`
CachingAlgorithm cache_factory.Algorithm `env:"CACHE_ADAPTER_MEMCACHE_CACHING_ALGORITHM,omitempty" default:"LRU"`
}
type Config struct {
LoggerConfig `title:"Logger configuration"`
RouterConfig `title:"Router configuration"`
RedisCacheAdapterConfig `title:"Redis Cache Adapter configuration"`
MemcacheCacheAdapterConfig `title:"Memcache Cache Adapter configuration"`
CassandraConfig `title:"Cassandra configuration"`
}

func New() (*Config, error) {
var cfg = new(Config)

cfgManager := gocfg.NewDefault()
if dotEnvProvider, err := values.NewDotEnvProvider(); err == nil {
cfgManager = cfgManager.AddValueProviders(dotEnvProvider)
}

if err := cfgManager.Unmarshal(cfg); err != nil {
return nil, err
}

return cfg, nil
}

```

2. Create new app, for example `/cmd/docs/main.go`:

```go
package main

import (
"fmt"
"github.com/Jagerente/gocfg"
"github.com/Jagerente/gocfg/pkg/docgens"
"os"
"your_cool_app/internal/config"
)

const outputFile = ".env.dist.generated"

func main() {
cfg := new(config.Config)

file, err := os.Create(outputFile)
if err != nil {
panic(fmt.Errorf("error creating %s file: %v", outputFile, err))
}

cfgManager := gocfg.NewDefault()
if err := cfgManager.GenerateDocumentation(cfg, docgens.NewEnvDocGenerator(file)); err != nil {
panic(err)
}
}

```

3. Run it by executing `go run cmd/docs/main.go`; it will generate the following file `.env.dist.generated`:

```go
# Auto-generated config

#############################
# Logger configuration
#############################

# Description:
# https://pkg.go.dev/github.com/sirupsen/logrus@v1.9.3#Level
LOG_LEVEL=6

REPORT_CALLER=true

LOG_FORMATTER=0

#############################
# Router configuration
#############################

SERVER_PORT=8080

ROUTER_DEBUG=true

# Allowed to be empty
# Description:
# Leave blank to not use.
# Possible values:
# - redis
# - memcache
CACHE_ADAPTER=

# Allowed to be empty
CACHE_ADAPTER_TTL=1m

# Allowed to be empty
CACHE_ADAPTER_NOCACHE_PARAM=no-cache

#############################
# Redis Cache Adapter configuration
#############################

# Allowed to be empty
CACHE_ADAPTER_REDIS_ADDR=:6379

# Allowed to be empty
CACHE_ADAPTER_REDIS_DB=0

# Allowed to be empty
CACHE_ADAPTER_REDIS_USERNAME=

# Allowed to be empty
CACHE_ADAPTER_REDIS_PASSWORD=

#############################
# Memcache Cache Adapter configuration
#############################

# Allowed to be empty
CACHE_ADAPTER_MEMCACHE_CAPACITY=10000000

# Allowed to be empty
CACHE_ADAPTER_MEMCACHE_CACHING_ALGORITHM=LRU

#############################
# Cassandra configuration
#############################

CASSANDRA_HOSTS=127.0.0.1

CASSANDRA_KEYSPACE=user_data_service

```
3 changes: 2 additions & 1 deletion config.go
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,8 @@ func (c *ConfigManager) UseCustomKeyTag(tag string) *ConfigManager {
// The function recursively traverses the fields of the structure and its nested structures,
// which means structure can contain as much nested structures as you want.
//
// You may use omitempty tags to allow empty fields. STRINGS ONLY!
// You may use omitempty tags to allow fields to be empty.
// If both the parsed value and the default value are empty, the field will be set to the zero value for its type in Go.
//
// Example:
//
Expand Down
Loading