Files
2025-11-30 09:04:14 +08:00

153 lines
3.0 KiB
Go

package main
import (
"database/sql"
"fmt"
"log"
"os"
"github.com/urfave/cli/v2"
)
// AppContext holds shared state across commands
type AppContext struct {
Config *Config
DB *sql.DB
Verbose bool
}
// Config represents application configuration
type Config struct {
Host string
Port int
Database string
}
func main() {
app := &cli.App{
Name: "context-demo",
Usage: "Demonstration of context and state management",
Flags: []cli.Flag{
&cli.BoolFlag{
Name: "verbose",
Aliases: []string{"v"},
Usage: "Enable verbose output",
},
&cli.StringFlag{
Name: "config",
Aliases: []string{"c"},
Usage: "Path to config file",
Value: "config.yaml",
},
},
// Initialize shared context
Before: func(c *cli.Context) error {
verbose := c.Bool("verbose")
configPath := c.String("config")
if verbose {
fmt.Printf("Loading config from: %s\n", configPath)
}
// Create application context
appCtx := &AppContext{
Config: &Config{
Host: "localhost",
Port: 5432,
Database: "mydb",
},
Verbose: verbose,
}
// Simulate database connection
// In real app: appCtx.DB, err = sql.Open("postgres", connStr)
if verbose {
fmt.Println("Connected to database")
}
// Store context in app metadata
c.App.Metadata["ctx"] = appCtx
return nil
},
// Cleanup shared resources
After: func(c *cli.Context) error {
if ctx, ok := c.App.Metadata["ctx"].(*AppContext); ok {
if ctx.DB != nil {
// ctx.DB.Close()
if ctx.Verbose {
fmt.Println("Database connection closed")
}
}
}
return nil
},
Commands: []*cli.Command{
{
Name: "query",
Usage: "Execute a database query",
Action: func(c *cli.Context) error {
// Retrieve context
ctx := c.App.Metadata["ctx"].(*AppContext)
if ctx.Verbose {
fmt.Printf("Connecting to %s:%d/%s\n",
ctx.Config.Host,
ctx.Config.Port,
ctx.Config.Database)
}
fmt.Println("Executing query...")
// Use ctx.DB for actual query
return nil
},
},
{
Name: "migrate",
Usage: "Run database migrations",
Action: func(c *cli.Context) error {
// Retrieve context
ctx := c.App.Metadata["ctx"].(*AppContext)
if ctx.Verbose {
fmt.Println("Running migrations with context...")
}
fmt.Printf("Migrating database: %s\n", ctx.Config.Database)
// Use ctx.DB for migrations
return nil
},
},
{
Name: "status",
Usage: "Check database status",
Action: func(c *cli.Context) error {
// Retrieve context
ctx := c.App.Metadata["ctx"].(*AppContext)
fmt.Printf("Database: %s\n", ctx.Config.Database)
fmt.Printf("Host: %s:%d\n", ctx.Config.Host, ctx.Config.Port)
fmt.Println("Status: Connected")
if ctx.Verbose {
fmt.Println("Verbose mode: enabled")
}
return nil
},
},
},
}
if err := app.Run(os.Args); err != nil {
log.Fatal(err)
}
}