How to do it...

These steps cover writing and running your application:

  1. From your Terminal or console application, create a new directory called ~/projects/go-programming-cookbook/chapter2/envvar.
  2. Navigate to this directory.
  3. Run the following command:
$ go mod init github.com/PacktPublishing/Go-Programming-Cookbook-Second-Edition/chapter2/envvar

You should see a file called go.mod that contains the following:

module github.com/PacktPublishing/Go-Programming-Cookbook-Second-Edition/chapter2/envvar   
  1. Copy tests from ~/projects/go-programming-cookbook-original/chapter2/envvar, or use this as an opportunity to write some of your own code!
  2. Create a file called config.go with the following contents:
        package envvar

import (
"encoding/json"
"os"

"github.com/kelseyhightower/envconfig"
"github.com/pkg/errors"
)

// LoadConfig will load files optionally from the json file
// stored at path, then will override those values based on the
// envconfig struct tags. The envPrefix is how we prefix our
// environment variables.
func LoadConfig(path, envPrefix string, config interface{})
error {
if path != "" {
err := LoadFile(path, config)
if err != nil {
return errors.Wrap(err, "error loading config from
file")
}
}
err := envconfig.Process(envPrefix, config)
return errors.Wrap(err, "error loading config from env")
}

// LoadFile unmarshals a JSON file into a config struct
func LoadFile(path string, config interface{}) error {
configFile, err := os.Open(path)
if err != nil {
return errors.Wrap(err, "failed to read config file")
}
defer configFile.Close()

decoder := json.NewDecoder(configFile)
if err = decoder.Decode(config); err != nil {
return errors.Wrap(err, "failed to decode config file")
}
return nil
}
  1. Create a new directory named example and navigate to it.
  2. Create a main.go file with the following contents:
        package main

import (
"bytes"
"fmt"
"io/ioutil"
"os"

"github.com/PacktPublishing/
Go-Programming-Cookbook-Second-Edition/
chapter2/envvar"
)

// Config will hold the config we
// capture from a json file and env vars
type Config struct {
Version string `json:"version" required:"true"`
IsSafe bool `json:"is_safe" default:"true"`
Secret string `json:"secret"`
}

func main() {
var err error

// create a temporary file to hold
// an example json file
tf, err := ioutil.TempFile("", "tmp")
if err != nil {
panic(err)
}
defer tf.Close()
defer os.Remove(tf.Name())

// create a json file to hold
// our secrets
secrets := `{
"secret": "so so secret"
}`

if _, err =
tf.Write(bytes.NewBufferString(secrets).Bytes());
err != nil {
panic(err)
}

// We can easily set environment variables
// as needed
if err = os.Setenv("EXAMPLE_VERSION", "1.0.0"); err != nil
{
panic(err)
}
if err = os.Setenv("EXAMPLE_ISSAFE", "false"); err != nil {
panic(err)
}

c := Config{}
if err = envvar.LoadConfig(tf.Name(), "EXAMPLE", &c);
err != nil {
panic(err)
}

fmt.Println("secrets file contains =", secrets)

// We can also read them
fmt.Println("EXAMPLE_VERSION =",
os.Getenv("EXAMPLE_VERSION"))
fmt.Println("EXAMPLE_ISSAFE =",
os.Getenv("EXAMPLE_ISSAFE"))

// The final config is a mix of json and environment
// variables
fmt.Printf("Final Config: %#v ", c)
}
  1. Run go run main.go.
  2. You may also run the following commands:
go build
./example
  1. You should see the following output:
$ go run main.go
secrets file contains = {
"secret": "so so secret"
}
EXAMPLE_VERSION = 1.0.0
EXAMPLE_ISSAFE = false
Final Config: main.Config{Version:"1.0.0", IsSafe:false,
Secret:"so so secret"}
  1. The go.mod file may be updated, and the go.sum file should now be present in the top-level recipe directory.
  2. If you copied or wrote your own tests, go up one directory and run go test, and ensure that all the tests pass.
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.144.205.223