Practical Flag Patterns
Comprehensive Subcommand Flag Design
Pattern 1: Nested Subcommand Architecture
package main
import (
"flag"
"fmt"
"os"
)
func main() {
deployCmd := flag.NewFlagSet("deploy", flag.ExitOnError)
env := deployCmd.String("env", "staging", "Deployment environment")
serverCmd := flag.NewFlagSet("server", flag.ExitOnError)
port := serverCmd.Int("port", 8080, "Server listening port")
if len(os.Args) < 2 {
fmt.Println("Expected 'deploy' or 'server' subcommands")
os.Exit(1)
}
switch os.Args[1] {
case "deploy":
deployCmd.Parse(os.Args[2:])
fmt.Printf("Deploying to %s environment\n", *env)
case "server":
serverCmd.Parse(os.Args[2:])
fmt.Printf("Starting server on port %d\n", *port)
default:
fmt.Println("Unknown command")
os.Exit(1)
}
}
Flag Pattern Classifications
Pattern |
Description |
Use Case |
Nested Subcommands |
Hierarchical command structure |
Complex CLI tools |
Conditional Flags |
Context-dependent flag validation |
Flexible configurations |
Required Flags |
Mandatory parameter enforcement |
Critical settings |
Pattern 2: Conditional Flag Validation
func validateDeploymentFlags(env string, replicas int) error {
if env == "" {
return fmt.Errorf("environment cannot be empty")
}
if replicas < 1 || replicas > 10 {
return fmt.Errorf("replicas must be between 1 and 10")
}
return nil
}
Advanced Flag Handling Workflow
graph TD
A[Parse Subcommand] --> B{Validate Flags}
B --> |Valid| C[Execute Command]
B --> |Invalid| D[Show Error Message]
D --> E[Display Usage Instructions]
Pattern 3: Configuration File Integration
type Config struct {
Environment string
Verbose bool
LogLevel string
}
func loadConfigFromFlags() *Config {
config := &Config{}
flag.StringVar(&config.Environment, "env", "development", "Deployment environment")
flag.BoolVar(&config.Verbose, "verbose", false, "Enable verbose logging")
flag.StringVar(&config.LogLevel, "log-level", "info", "Logging level")
flag.Parse()
return config
}
Best Practices for LabEx CLI Development
- Use meaningful flag names
- Provide comprehensive help text
- Implement robust error handling
- Support configuration flexibility
- Minimize flag parsing complexity
- Use pointer-based flag definitions
- Implement lazy initialization
- Cache parsed configuration
Error Handling Strategy
func handleFlagErrors(err error) {
if err != nil {
fmt.Fprintf(os.Stderr, "Flag error: %v\n", err)
os.Exit(1)
}
}
Conclusion
Effective flag patterns enable developers to create sophisticated, user-friendly command-line interfaces with robust configuration management and intuitive interaction models.