How to use the 'default' struct tag with Go's envconfig library?

Viewed 2080

I'm trying to use the envconfig library, https://github.com/kelseyhightower/envconfig, in a program where most of the configuration variables have default values which I would only like to override if specific environment variables are set.

I've tried to run the following example program:

package main

import (
    "fmt"
    "log"

    "github.com/kelseyhightower/envconfig"
)

type config struct {
    foo string `default:"bar"`
}

func main() {
    var cfg config
    if err := envconfig.Process("app", &cfg); err != nil {
        log.Fatalln(err)
    }
    fmt.Println(cfg.foo)
}

without the APP_FOO environment variable set:

> echo $APP_FOO

However, this does not print bar as I would expect it to:

> go run use_envconfig.go 

I don't see how my implementation is different from the documented example at https://github.com/kelseyhightower/envconfig#struct-tag-support to which the following comment pertains:

If envconfig can't find an environment variable value for MYAPP_DEFAULTVAR, it will populate it with "foobar" as a default value.

How can I make this program so that the cfg's value of foo is bar unless I set the APP_FOO environment variable?

2 Answers

In your answer you accidentally fixed the problem. It's not config that needs to be capitalized. It is Foo. The following works: Demo.

type config struct {
    Foo string `default:"bar"`
}

In Go, only the capitalized fields are accessible outside the current package. Envconfig can only access capitalized fields. Think of those as private and public properties.

Lowercase is private, Uppercase is public.

A little experimentation showed that both config and foo should be capitalized (to Config and Foo, respectively). The following program,

package main

import (
    "fmt"
    "log"

    "github.com/kelseyhightower/envconfig"
)

type Config struct {
    Foo string `default:"bar"`
}

func main() {
    var cfg Config
    if err := envconfig.Process("app", &cfg); err != nil {
        log.Fatalln(err)
    }
    fmt.Println(cfg.Foo)
}

produces bar as expected:

> go run use_envconfig.go
bar
Related