Practical Flag Patterns
Advanced Flag Configuration Strategies
1. Custom Flag Types
type NetworkMode string
func (n *NetworkMode) String() string {
return string(*n)
}
func (n *NetworkMode) Set(value string) error {
switch value {
case "tcp", "udp", "http":
*n = NetworkMode(value)
return nil
default:
return fmt.Errorf("invalid network mode")
}
}
func main() {
mode := NetworkMode("tcp")
flag.Var(&mode, "mode", "Network connection mode")
flag.Parse()
}
Flag Configuration Patterns
Pattern |
Description |
Use Case |
Validation Wrapper |
Add custom validation logic |
Ensure flag values meet specific criteria |
Dynamic Default |
Compute default values |
Platform or environment-specific defaults |
Nested Configuration |
Combine multiple flag sources |
Complex configuration management |
2. Nested Flag Configuration
type ServerConfig struct {
Port int
Host string
Debug bool
LogLevel string
}
func configureServer() *ServerConfig {
config := &ServerConfig{}
flag.IntVar(&config.Port, "port", 8080, "Server port")
flag.StringVar(&config.Host, "host", "localhost", "Server host")
flag.BoolVar(&config.Debug, "debug", false, "Enable debug mode")
flag.StringVar(&config.LogLevel, "log-level", "info", "Logging level")
flag.Parse()
return config
}
Flag Parsing Workflow
graph TD
A[Flag Declaration] --> B[Custom Validation]
B --> C[Default Value Assignment]
C --> D[Flag Parsing]
D --> E[Configuration Object]
E --> F[Application Logic]
3. Multiple Configuration Sources
func loadConfiguration() *Config {
// Priority: Command-line flags > Environment > Config File > Default
config := &Config{
Port: 8080,
Host: "localhost",
}
// Check environment variables
if envPort := os.Getenv("SERVER_PORT"); envPort != "" {
config.Port, _ = strconv.Atoi(envPort)
}
// Override with command-line flags
flag.IntVar(&config.Port, "port", config.Port, "Server port")
flag.StringVar(&config.Host, "host", config.Host, "Server host")
flag.Parse()
return config
}
Advanced Flag Handling Techniques
Conditional Flag Requirements
func validateFlags() {
if *debugMode && *logFile == "" {
fmt.Println("Debug mode requires a log file")
os.Exit(1)
}
}
func main() {
debugMode := flag.Bool("debug", false, "Enable debug mode")
logFile := flag.String("log-file", "", "Log file path")
flag.Parse()
validateFlags()
}
Best Practices
- Implement custom flag types for complex configurations
- Use nested configurations for better organization
- Provide multiple configuration sources
- Add robust validation mechanisms
- Keep flag declarations clear and concise
With LabEx, you can master advanced flag configuration techniques in Golang, creating more flexible and powerful command-line applications.