wonsz

package module
v0.1.1 Latest Latest
Warning

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

Go to latest
Published: Aug 1, 2023 License: MIT Imports: 9 Imported by: 0

README

img


Wrapper Of Naughty SnakeZ


The best of Viper & Cobra combined.
Ready to go solution for configurable CLI programs.

example workflow Go Report Card PkgGoDev

What does it do?

It creates a configuration struct, that fields are automatically bound to:

  1. configuration file
  2. environment variables
  3. command line flags

Why?

  • Let's say you want to write a configurable app.

So, I use viper to load configuration from file. I fetch configuration fields by viper.Get(key).

  • But it sucks to not have autocompletion from IDE.

So, I marshall your config to a struct.

  • But let's say, you dockerized your app and when you run containers, you want also to manage config by environment variables.

So, I use AutomaticEnv to get env variables.

  • But it marshalls to struct only when you bind specific environment variables by name.

I would bind them by viper.BindEnv().

  • But you have config struct field named like: ThisIsMyConfigField, so you must set THISISMYCONFIGFIELD env variable, which is not really readable and nice.

:/

  • And let's say, you also want to run your app like a CLI app.

I would use cobra.

  • But you may also want configuration fields to be overwritten with values from the command line flags.

So, I use viper.BindPFlag to bind some flags to your config structs.

  • And you end up with 3 different names of the same config field and pretty complicated initialization logic. Also, you must remember to add proper code when adding a new field to the configuration, so every way of loading the config field is properly handled.

So I use this library, and then you just create 1 config struct without any tags, initialize it, and you have all 3 ways of configuring your app (by the configuration file, by environment variables, and by command flags) out of the box and in one place.
And I have all the above problems resolved!

  • Awessssome!

How to install?

Import dependency into your project.

go get -d github.com/Mrucznik/wonsz

How to use?

Simplest application

// main.go file
package main

import (
	"fmt"
	"github.com/Mrucznik/wonsz"
	"github.com/spf13/cobra"
)

var config Configuration

type Configuration struct {
	// Here we declare configuration fields. No need to add any tags.
	SnakeName string
}

var rootCmd = &cobra.Command{Run: execute}

func main() {
	wonsz.BindConfig(&config, // pointer to the configuration struct
		rootCmd,            // root cobra command
		wonsz.ConfigOpts{}) // Wonsz configuration options

	rootCmd.Execute()
}

func execute(_ *cobra.Command, _ []string) {
	fmt.Printf("Application config: %+v\n", config)
}

This is the simplest example, more detailed you will find here.

Integrate with an existing application

  1. Create file config/config.go
    // config.go file
    package config
    
    var Config Configuration
    
    type Configuration struct {
    // Here we declare configuration fields. No need to add any tags.
        SnakeName string
    }
    
  2. Bind created config structure to cobra & viper using wonsz.BindConfig()
// cmd/root.go
package cmd

import (
    "github.com/Mrucznik/wonsz"
	"github.com/You/your-project/config"
    "github.com/spf13/cobra"
)

var rootCmd = &cobra.Command{
	// your root cobra command
}

func init() {
	wonsz.BindConfig(&config.Config, rootCmd, wonsz.ConfigOpts{})
	
	// other code
}

  1. Done!

Configure and run your application with

  • default struct values
    config := &Config{
        SnakeName: "nope-rope",
    }
    
  • configuration files e.g.
    • config.json
      {
        "snake_name": "hazard spaghetti" 
      }
      
    • config.yaml
      snake_name: "judgemental shoelace"
      
    • config.toml
      snake_name = "slippery tube dude"
      
  • environment variables
    SNAKE_NAME="caution ramen" go run main.go
    
  • command-line flags
    go run main.go --snake-name="danger noodle"
    

Key concepts

  • names in configurations files should be in snake_case
  • environment variables are in SCREAMING_SNAKE_CASE
  • command-line flags names should be dash separated

Detailed configuration options

You can find more information by checking out example app.

Documentation

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func BindConfig

func BindConfig(config interface{}, rootCmd *cobra.Command, options ConfigOpts) error

BindConfig binds configuration structure to config file, environment variables and cobra command flags. The config parameter should be a pointer to configuration structure. You can pass nil to rootCmd, if you don't want to bind cobra command flags with config.

Example
os.Setenv("EXAMPLE_FIELD", "this is my example config field")

var myConfig struct {
	ExampleField string
}

err := BindConfig(&myConfig, nil, ConfigOpts{})
if err != nil {
	panic(err)
}

fmt.Println(myConfig.ExampleField)
Output:

this is my example config field

func Get

func Get() interface{}

Get returns a config struct instance to which Wonsz binds configuration.

func GetViper

func GetViper() *globalViper.Viper

GetViper returns a viper instance used by Wonsz.

Types

type ConfigOpts

type ConfigOpts struct {
	// Environment variables prefix.
	// E.g. if your prefix is "wonsz", the env registry will look for env variables that start with "WONSZ_".
	EnvPrefix string

	// Paths to search for the config file in.
	ConfigPaths []string

	// Type of the configuration file, e.g. "json".
	// Wonsz use Viper for loading the configuration file,
	// so you can use any type of configuration file that Viper supports.
	ConfigType string

	// Name for the config file. Does not include extension.
	ConfigName string

	// Pass own viper instance. Default is global viper instance.
	Viper *globalViper.Viper
}

ConfigOpts provide additional options to configure Wonsz.

type Tag

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

Tag contains the name and value of a structure field tag.

func GetTagsForField

func GetTagsForField(field reflect.StructField) []Tag

GetTagsForField extracts field tag names and values from specified structure.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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