CLI Framework

Enterprise-grade CLI framework for building command-line tools with Forge. Features commands, subcommands, flags, middleware, prompts, tables, plugins, and seamless Forge App integration.

Forge CLI Framework is an enterprise-grade CLI framework for building powerful command-line tools in Go. It provides a comprehensive foundation for creating interactive, user-friendly CLI applications with modern UX patterns, extensive customization options, and seamless integration with Forge applications.

The CLI framework is production-ready and actively maintained. It's designed to work both standalone and integrated with Forge applications for accessing services via dependency injection.

Key Features

Architecture Overview

The CLI framework follows a modular architecture with clear separation of concerns:

Core Components:

  • CLI: Main application with command management and execution
  • Commands: Hierarchical command structure with subcommands and aliases
  • Flags: Type-safe flag parsing with validation and default values
  • Context: Command execution context with access to flags, args, and services
  • Parser: Argument and flag parsing with error handling
  • Logger: CLI-optimized logging with color-coded output
  • Help: Auto-generated help text and usage information

Interactive Components:

  • Prompts: Input, confirm, select, multi-select with arrow key navigation
  • Progress: Progress bars and spinners for long-running operations
  • Tables: Formatted tables with multiple styles and color support
  • Colors: ANSI color support with automatic terminal detection
  • Completion: Shell completion for Bash, Zsh, and Fish

Integration Features:

  • Plugins: Modular plugin system for extending functionality
  • Middleware: Before/after command hooks for cross-cutting concerns
  • Forge Integration: Access to Forge app services via dependency injection
  • Error Handling: Structured error handling with exit codes
  • Testing: Comprehensive testing utilities for CLI applications

Key Features

Commands & Subcommands - Hierarchical command structure
Comprehensive Flags - String, int, bool, slice, duration with validation
Interactive Prompts - Input, confirm, select, multi-select with arrow key navigation ⬆️⬇️
Space Bar Selection - Toggle multi-select with spacebar (modern UX) ⎵
Progress Indicators - Progress bars and spinners
Table Output - Formatted, colored tables with multiple styles
Middleware - Before/after command hooks
Plugin System - Modular, composable commands
CLI-Optimized Logger - Color-coded, simple output
Auto-Generated Help - Automatic help text generation
Shell Completion - Bash, Zsh, Fish completion
Forge Integration - Access to DI container and services

Quick Start

Get started with the CLI framework in minutes:

Make sure you have Go 1.21+ installed. The CLI framework works both standalone and integrated with Forge applications.

# Create a new Go module
mkdir my-cli-tool && cd my-cli-tool
go mod init my-cli-tool

# Add CLI framework dependency
go get github.com/xraph/forge/cli
package main

import (
    "fmt"
    "os"
    "github.com/xraph/forge/cli"
)

func main() {
    // Create CLI application
    app := cli.New(cli.Config{
        Name:        "mytool",
        Version:     "1.0.0",
        Description: "My awesome CLI tool",
    })

    // Add a hello command with flags
    helloCmd := cli.NewCommand(
        "hello",
        "Say hello to someone",
        func(ctx cli.CommandContext) error {
            name := ctx.String("name")
            if name == "" {
                name = "World"
            }
            
            ctx.Success(fmt.Sprintf("Hello, %s!", name))
            return nil
        },
        cli.WithFlag(cli.NewStringFlag("name", "n", "Name to greet", "")),
    )

    app.AddCommand(helloCmd)

    // Run the CLI
    if err := app.Run(os.Args); err != nil {
        fmt.Fprintf(os.Stderr, "Error: %v\n", err)
        os.Exit(cli.GetExitCode(err))
    }
}
package main

import (
    "os"
    "github.com/xraph/forge"
    "github.com/xraph/forge/cli"
)

func main() {
    // Create Forge app
    app := forge.NewApp(forge.AppConfig{
        Name:        "myapp",
        Version:     "1.0.0",
        Environment: "development",
    })

    // Register services
    forge.RegisterSingleton(app.Container(), "userService", 
        func(c forge.Container) (*UserService, error) {
            return NewUserService(), nil
        })

    // Create CLI with Forge integration
    cliApp := cli.NewForgeIntegratedCLI(app, cli.Config{
        Name:        "myapp-cli",
        Version:     "1.0.0",
        Description: "CLI with Forge integration",
    })

    // Add command that uses Forge services
    userCmd := cli.NewCommand(
        "user",
        "Manage users",
        func(ctx cli.CommandContext) error {
            // Access Forge service via DI
            userService, err := cli.GetService[*UserService](ctx, "userService")
            if err != nil {
                return err
            }

            users := userService.ListUsers()
            
            // Display in table format
            table := ctx.Table()
            table.SetHeader([]string{"ID", "Name", "Email"})
            for _, user := range users {
                table.AppendRow([]string{user.ID, user.Name, user.Email})
            }
            table.Render()

            return nil
        },
    )

    cliApp.AddCommand(userCmd)

    // Run the CLI
    if err := cliApp.Run(os.Args); err != nil {
        os.Exit(cli.GetExitCode(err))
    }
}

Interactive Example

The CLI framework excels at creating interactive command-line experiences:

setupCmd := cli.NewCommand(
    "setup",
    "Interactive setup wizard",
    func(ctx cli.CommandContext) error {
        ctx.Info("Welcome to the setup wizard!")

        // Simple prompt
        name, err := ctx.Prompt("What's your name?")
        if err != nil {
            return err
        }

        // Confirm prompt
        confirmed, err := ctx.Confirm(fmt.Sprintf("Is '%s' correct?", name))
        if err != nil {
            return err
        }

        if !confirmed {
            ctx.Warning("Setup cancelled")
            return nil
        }

        // Select with arrow keys
        env, err := ctx.Select("Choose environment:", []string{
            "development",
            "staging", 
            "production",
        })
        if err != nil {
            return err
        }

        // Multi-select with spacebar
        features, err := ctx.MultiSelect("Select features:", []string{
            "database",
            "cache",
            "events",
            "streaming",
        })
        if err != nil {
            return err
        }

        // Progress bar for setup
        progress := ctx.ProgressBar(100)
        for i := 0; i <= 100; i += 10 {
            progress.Set(i)
            time.Sleep(100 * time.Millisecond)
        }
        progress.Finish("Setup complete!")

        ctx.Success("Configuration saved!")
        return nil
    },
)

Next Steps

Community & Support

  • GitHub: xraph/forge - Source code and issues
  • Examples: Check the /cli/examples directory for real-world examples
  • Documentation: Comprehensive guides and API reference
  • Contributing: We welcome contributions and feedback

Ready to build powerful CLI tools? Let's start with commands!

How is this guide?

Last updated on