Documentation
¶
Overview ¶
Package jsonflag is for configuration settings. It extends Go's flag package, designed for cli flags, with json config files and environmental variables. It does not replace any part of flag.
Order of precedence for set config values:
- Command line flags. (cli Example: `--flag1=flag1Value`)
- Environmental Variables (env Example: FLAG2=flag2value)
- JSON config values. (json Example: `{"flag3": "flag3Value"}`)
- Default values set on flag. (go Example: `flag.StringVar(&config.Flag4, "flag4Name", "flag4DefaultValue", "flag4Description")`)
Flag values do not need to appear in the json config file and can be left blank if desired. If not set in config struct or exported, extra json config file values will be ignored. If a value should not be set by flags, add the value in the config struct and json config file. It will still be set.
Environmental variables can be set using the flag name. The flag's name will be converted to all upper case. If set, "EnvPrefix" will be prefixed when looking up environment variables.
Environmental variables in json config will be expanded. See testing for an example where "$Flag8" is expanded.
This package uses Go's json package for decoding. The json decoder only has accesses to exported fields of structs and follows its own precedence for json decoding:
- Tags
- Exact case
- Case insensitive
CLI names must start with lower case.
Recommended Usage ¶
See testing for an example.
- Define a `config` struct with exported fields.
- Use flag's functions to set default config values. `flag.StringVar(&config.Flag1, "flag1Name", "flag1DefaultValue", "flag1Description")`
- Put config values in a `config.json` file. The config file path defaults to the cwd. You can use `--config=your_config.json` to point somewhere else.
- Call `jsonflag.Parse(&config)`
The config struct is now appropriately populated.
Config Path ¶
You can set the config path via the cli,
--config=your_config.json
You can also set it in your application. Note that this can be overwritten by the normal precedence via a cli flag as previously mentioned.
jsonflag.Path = "assets/config.json"
Design ¶
This package follows flag.Parse() fail fast design and panics on error.
Testing ¶
Since this package uses flag, test functions need a cli flag passed to verify cli parsing is working. Test will otherwise fail.
Test 1 (tests --config= form):
JSONFLAG_FLAG10=FLAG10VALUE FLAG7=FLAG7VALUE Flag8=Flag8Env go test --flag1=cliFlag1 --config=test_config.json5
Test 2 (tests -config= form):
JSONFLAG_FLAG10=FLAG10VALUE FLAG7=FLAG7VALUE Flag8=Flag8Env go test --flag1=cliFlag1 -config=test_config.json5
Test 3 (tests --config form):
JSONFLAG_FLAG10=FLAG10VALUE FLAG7=FLAG7VALUE Flag8=Flag8Env go test --flag1=cliFlag1 --config test_config.json5
Test 4 (tests -config form):
JSONFLAG_FLAG10=FLAG10VALUE FLAG7=FLAG7VALUE Flag8=Flag8Env go test --flag1=cliFlag1 -config test_config.json5
Example ¶
Example prints out values
package main
import (
"flag"
"fmt"
)
// Create two new configs. Typical usage uses only one config.
var tc Config
var tc2 Config2
// Config's values must be exported
type Config struct {
Flag1 string // Set by flag default, JSON, and CLI - CLI precedence
Flag2 string // Set by JSON only - JSON precedence
Flag3 string // Set by flag default only - default precedence
Flag4 string // Set by JSON and flag default - JSON precedence
Flag5 int // Set by JSON only int - JSON precedence
Flag6 int `json:"flagsix"` // JSON with flag default int - JSON precedence. Also tests tags.
Flag7 string // Set by environmental variable and JSON. No default, or CLI. - Env precedence
Flag8 string // Set by environmental value expansion from value in JSON config.
Flag9 string // Test expanding the default flag value ($FLAG7) with a variable to an environmental variable."
}
type Config2 struct {
Flag10 string // Test EnvPrefix. Value is set by CLI only.
}
// flags holds all flag definitions for CLI and application set.
// Flag 2 and 5 are missing to test JSON values which will still populate.
func flags() {
flag.StringVar(&tc.Flag1, "flag1", "defaultFlag1", "flag1Desc")
flag.StringVar(&tc.Flag3, "flag3", "defaultFlag3", "flag3Desc")
flag.StringVar(&tc.Flag4, "flag4", "defaultFlag4", "flag4Desc")
flag.IntVar(&tc.Flag6, "flag6", 1, "flag6Desc") // Set default value to something other than 6 for testing.
flag.StringVar(&tc.Flag7, "flag7", "defaultFlag7", "Flag7's value comes from environmental variable.")
flag.StringVar(&tc.Flag8, "flag8", "defaultFlag8", "Flag8 tests environmental expansion.")
flag.StringVar(&tc.Flag9, "flag9", "$FLAG7", "Flag9's value comes from expanding the default flag value ($FLAG7) with a variable to an environmental variable.")
Parse(&tc)
EnvPrefix = "JSONFLAG_"
flag.StringVar(&tc2.Flag10, "flag10", "", "Flag10 tests prefixing the EnvPrefix to env vars")
Parse(&tc2)
}
// Example prints out values
func main() {
fmt.Println(tc)
fmt.Println(tc2)
}
Output: {cliFlag1 jsonFlag2 defaultFlag3 jsonFlag4 5 6 FLAG7VALUE Flag8Env FLAG7VALUE} {FLAG10VALUE}
Index ¶
Examples ¶
Constants ¶
This section is empty.
Variables ¶
var EnvPrefix = ""
EnvPrefix will be prepended to flag names if set. For example, with a prefix of "MYAPP_", the flag "flag1" will become "MYAPP_FLAG1".
var Path string
Path defines the default config path and is relative to pwd.
Functions ¶
Types ¶
This section is empty.