A Go command-line flag parsing library with environment variable support. Command-line flags take priority over environment variables.
- Built on top of the standard
flagpackage, with consistent API and low learning curve - Automatic environment variable support — env var names are derived from flag names
- Supports
--env.prefixfor a unified environment variable prefix - Rich type support: Duration, Bytes, Text, arrays, and more
- Secret flag masking to prevent sensitive information leakage
- Required flag validation
- Post-parse callbacks (AfterParse)
go get github.com/cloudfly/flagxpackage main
import"github.com/cloudfly/flagx"var (
logFile=flagx.NewString("log.file", "", "path to log file")
logLevel=flagx.NewBool("log.level", false, "enable debug logging")
serverAddr=flagx.NewString("server.addr", ":7070", "HTTP server listen address")
serverPort=flagx.NewInt("server.port", 8080, "TCP listen port")
)
funcmain() {
flagx.Parse()
// use *logFile, *logLevel, etc.
}Usage:
# Command-line flags
./app --server.addr=:8080 --server.port=9090
# Environment variables
SERVER_ADDR=:8080 SERVER_PORT=9090 ./app
# Mixed usage (command-line takes priority)
SERVER_ADDR=:8080 ./app --server.port=9090// Booleandebug:=flagx.NewBool("debug", false, "enable debug mode")
// Stringname:=flagx.NewString("name", "default", "name of the service")
// Integerport:=flagx.NewInt("port", 8080, "listen port")
port64:=flagx.NewInt64("port64", 8080, "64-bit listen port")
// Floatratio:=flagx.NewFloat("ratio", 0.5, "ratio value")Supported time unit suffixes: ms (milliseconds), s (seconds), m (minutes), h (hours), d (days), w (weeks), y (years). Defaults to seconds when no suffix is provided.
Supports combined notation, e.g. 2h5m, 1d6h.
timeout:=flagx.NewDuration("timeout", "30s", "request timeout")
days:=flagx.NewDuration("retention", "30d", "data retention period in days")
weeks:=flagx.NewDuration("interval", "2w", "execution interval")Usage:
fmt.Println(timeout.Msecs) // millisecondsSupported byte unit suffixes:
| Suffix | Meaning | Base |
|---|---|---|
| KB | Kilobyte | 1000 |
| MB | Megabyte | 1000 |
| GB | Gigabyte | 1000 |
| TB | Terabyte | 1000 |
| KiB | Kibibyte | 1024 |
| MiB | Mebibyte | 1024 |
| GiB | Gibibyte | 1024 |
| TiB | Tebibyte | 1024 |
cacheSize:=flagx.NewBytes("cache.size", 128, "cache size in bytes")
maxUpload:=flagx.NewBytes("upload.max", 64, "max upload size", flagx.Env("MAX_UPLOAD_SIZE"))Usage:
fmt.Println(cacheSize.N) // bytes as int64fmt.Println(cacheSize.IntN()) // bytes as int (auto-truncated)Used to hold complex content such as JSON or configuration text. The value passed in must be a base64-encoded string, which is automatically decoded during parsing.
config:=flagx.NewText("config", "", "configuration content, base64 encoded")Usage:
// Pass base64-encoded JSON via command line// echo -n '{"key":"value"}' | base64
./app--config=eyJrZXkiOiJ2YWx1ZSJ9fmt.Println(config.Value) // decoded original string: {"key":"value"}Array types support two ways of passing values:
- Specify the same flag multiple times:
--items=a --items=b --items=c - Comma-separated:
--items=a,b,c
Supported array types:
// String arraytags:=flagx.NewArrayString("tags", "list of tags")
// Integer arrayports:=flagx.NewArrayInt("ports", "list of ports")
// Boolean arrayflags:=flagx.NewArrayBool("flags", "list of boolean flags")
// Duration arraytimeouts:=flagx.NewArrayDuration("timeouts", "list of timeout values")
// Bytes arraysizes:=flagx.NewArrayBytes("sizes", "list of sizes")
// Text arrayconfigs:=flagx.NewArrayText("configs", "list of configurations")Usage:
for_, tag:=range*tags {
fmt.Println(tag)
}
// Convenience method: get value at index, return default if out of boundsport:=ports.GetOptionalArgOrDefault(0, 8080)All New* functions accept a variadic last parameter opts ...Option for configuring additional flag behavior.
Customize the environment variable name. Multiple names can be specified, and they are tried in order from left to right:
// Default env var name is LOG_FILElogFile:=flagx.NewString("log.file", "", "log file path")
// Custom env var name CUSTOM_LOG_FILElogFile:=flagx.NewString("log.file", "", "log file path", flagx.Env("CUSTOM_LOG_FILE"))
// Multiple env vars, tried in orderlogFile:=flagx.NewString("log.file", "", "log file path",
flagx.Env("CUSTOM_LOG_FILE"),
flagx.Env("SERVER_LOG_PATH"),
flagx.Env("LOG_PATH"),
)Marks the flag as required. It must be set via command line or environment variable, otherwise the program exits with an error:
dsn:=flagx.NewString("mysql.dsn", "", "MySQL connection string", flagx.Required())Sets a function to be called after flag parsing is complete. Useful for post-processing based on the values of other flags.
addr:=flagx.NewString("addr", "", "server address", flagx.AfterParse(func(isSetbool, setfunc(string) error) {
if!isSet {
// If addr is not set, set its value via the set functionset(":8080")
}
}))By default, environment variable names are derived from flag names using the following rules:
- Replace
.with_ - Convert to uppercase
Examples:
log.file→LOG_FILEserver.port→SERVER_PORT
Use the --env.prefix flag to set a unified prefix for all environment variables:
./app --env.prefix=MYAPP_With this prefix, the env var names become:
log.file→MYAPP_LOG_FILEserver.port→MYAPP_SERVER_PORT
Command-line flags > Environment variables > Default values
flagx automatically masks flags whose names contain pass, key, secret, or token to prevent sensitive information from leaking in logs or monitoring output.
You can also manually register secret flags:
flagx.RegisterSecretFlag("mysql.dsn")When iterating via Visit and VisitAll, secret flag values are automatically masked (keeping the first and last 1/4 of characters, replacing the middle with *).
Parses command-line flags and environment variables. Must be called before using any flags:
flagx.Parse()Gets the environment variable name corresponding to a flag:
envName:=flagx.FlagEnvName("log.file")
// returns "LOG_FILE" by default// returns "MYAPP_LOG_FILE" when --env.prefix=MYAPP_ is set// Iterate over all flags explicitly set via command lineflagx.Visit(func(name, valuestring) {
fmt.Printf("%s = %s\n", name, value)
})
// Iterate over all flags (including unset ones)flagx.VisitAll(func(name, valuestring) {
fmt.Printf("%s = %s\n", name, value)
})Writes all explicitly set flags to an io.Writer:
flagx.WriteFlags(os.Stdout)Prints usage information:
flagx.Usage("My App v1.0.0")When -h or -help is passed, detailed descriptions of all flags are printed; otherwise, only a hint to use -help is shown.
package main
import (
"fmt""github.com/cloudfly/flagx"
)
var (
// Basic typesdebug=flagx.NewBool("debug", false, "enable debug mode")
appName=flagx.NewString("app.name", "demo", "application name")
port=flagx.NewInt("port", 8080, "listen port", flagx.Env("PORT"))
// Durationtimeout=flagx.NewDuration("timeout", "30s", "request timeout")
// BytesmaxBody=flagx.NewBytes("http.maxBody", 1024*1024, "max request body size")
// ArrayallowIPs=flagx.NewArrayString("security.allowIPs", "list of allowed IPs")
// Required flagdsn=flagx.NewString("mysql.dsn", "", "MySQL connection string", flagx.Required())
)
funcmain() {
flagx.Parse()
fmt.Printf("App: %s\n", *appName)
fmt.Printf("Port: %d\n", *port)
fmt.Printf("Debug: %v\n", *debug)
fmt.Printf("Timeout: %dms\n", timeout.Msecs)
fmt.Printf("Max Body: %d bytes\n", maxBody.N)
fmt.Printf("Allow IPs: %v\n", *allowIPs)
}