fang

repository·main·Indexed 24 days ago

https://github.com/charmbracelet/fang

A CLI starter kit and experimental library for Cobra-based applications. Fang provides 'batteries-included' features to enhance UX and aesthetics, including styled help and usage pages, styled error reporting, automatic --version support, and built-in commands for shell completions and manpage generation. It supports themeable output with adaptive light/dark mode switching via ColorSchemeFunc.

Tokens
2.6K
Snippets
6
Records
21
Agent score
84%

What's inside fang

  1. Features of Fang

    main

    Fang provides several out-of-the-box enhancements for CLI tools:

    • Fancy output: Fully styled help and usage pages.
    • Fancy errors: Fully styled error messages.
    • Automatic --version: Automatically sets the version to your build info or a custom version.
    • Manpages: Adds a hidden man command to generate manpages using mango.
    • Completions: Adds a completion command to generate shell completions.
    • Themeable: Supports the built-in theme or custom themes.
    • UX Improvements: Silent usage output (help is not automatically shown after a user error).
  2. Upgrade from Fang v0.x to Fang v2

    main

    To upgrade to Fang v2, you must update your import paths to use the Charm vanity domain and include the v2 major version. You also need to update your go.mod file to point to the new module.

    Steps:

    1. Update imports from github.com/charmbracelet/fang to charm.land/fang/v2.
    2. Update your dependencies using go get.

    Recommended migration command: Use gofmt to automate the import replacement across your project:

    gofmt -w -r 'github.com/charmbracelet/fang -> charm.land/fang/v2' .
    go get charm.land/fang/v2@latest
  3. Use Fang to run Cobra applications

    main

    Fang is a CLI starter kit designed for Cobra-based applications. To integrate Fang into your project, replace your standard Cobra execution logic with fang.Execute. This provides enhanced features like styled help/usage pages, styled errors, automatic --version support, and built-in commands for manpage generation and shell completions.

    Pass a context.Context and your root *cobra.Command to fang.Execute.

    package main
    
    import (
    	"context"
    	"os"
    
    	"github.com/charmbracelet/fang"
    	"github.com/spf13/cobra"
    )
    
    func main() {
    	cmd := &cobra.Command{
    		Use:   "example",
    		Short: "A simple example program!",
    	}
    	if err := fang.Execute(context.Background(), cmd); err != nil {
    		os.Exit(1)
    	}
    }
  4. Migrate custom themes to WithColorSchemeFunc in Fang v2

    main

    In Fang v2, the WithTheme option is deprecated. You should migrate to WithColorSchemeFunc, which allows your theme to adapt to the terminal's light or dark mode using a lipgloss.LightDarkFunc.

    Before (Deprecated):

    fang.Execute(ctx, cmd, fang.WithTheme(myColorScheme))

    After (Recommended):

    fang.Execute(ctx, cmd, fang.WithColorSchemeFunc(func(lipgloss.LightDarkFunc) fang.ColorScheme {
        return myColorScheme
    }))
    // Preferred in v2
    fang.Execute(ctx, cmd, fang.WithColorSchemeFunc(func(lipgloss.LightDarkFunc) fang.ColorScheme {
        return myColorScheme
    }))
  5. Use Styles to apply themes to UI elements

    main

    The Styles struct contains pre-configured lipgloss.Style objects that map the semantic colors from a ColorScheme to specific visual properties (like bolding, padding, or background colors).

    To use them, you typically initialize a ColorScheme and then use the internal makeStyles logic (or the exported Styles if provided by the package entrypoint) to get the ready-to-use styles for Text, Title, Codeblock, Program, etc.

  6. Implement custom error handling with ErrorHandler

    main
    While DefaultErrorHandler is provided, you can implement your own error handling logic by following the ErrorHandler pattern. The DefaultErrorHandler is used to ensure that errors are presented clearly to users with appropriate terminal styling or plain text for non-interactive environments.
  7. Use adaptive themes with WithColorSchemeFunc

    main

    Fang v2 introduces WithColorSchemeFunc to support adaptive themes. This function receives a lipgloss.LightDarkFunc (aliased as ld), which you can use to return different colors based on whether the terminal is in light or dark mode.

    Example of defining an adaptive fang.ColorScheme:

    fang.Execute(ctx, cmd, fang.WithColorSchemeFunc(func(ld lipgloss.LightDarkFunc) fang.ColorScheme {
        return fang.ColorScheme{
            Primary:   ld(lipgloss.Color("#FF6B6B"), lipgloss.Color("#4ECDC4")),
            Secondary: ld(lipgloss.Color("#95E1D3"), lipgloss.Color("#F38181")),
            Muted:     ld(lipgloss.Color("#999999"), lipgloss.Color("#666666")),
        }
    }))
    fang.Execute(ctx, cmd, fang.WithColorSchemeFunc(func(ld lipgloss.LightDarkFunc) fang.ColorScheme {
        return fang.ColorScheme{
            Primary:   ld(lipgloss.Color("#FF6B6B"), lipgloss.Color("#4ECDC4")),
            Secondary: ld(lipgloss.Color("#95E1D3"), lipgloss.Color("#F38181")),
            Muted:     ld(lipgloss.Color("#999999"), lipgloss.Color("#666666")),
            // ...
        }
    }))
  8. Initialize the default ColorScheme

    main
    Use DefaultColorScheme to create a ColorScheme using the project's default palette. It accepts a lipgloss.LightDarkFunc, which allows the theme to adapt based on whether the user's terminal is in light or dark mode.
  9. Define a custom ColorSchemeFunc

    main

    To support dynamic light/dark mode switching, use WithColorSchemeFunc. This function receives a lipgloss.LightDarkFunc and returns a ColorScheme.

    type ColorSchemeFunc = func(lipgloss.LightDarkFunc) ColorScheme

  10. Configure fang using Options

    main

    You can pass multiple Option functions to Execute to customize the application behavior. Common options include:

    • WithoutCompletions(): Disables the default completion command.
    • WithoutManpage(): Disables the hidden man command used for generating man pages.
    • WithoutVersion(): Skips the -v/--version functionality.
    • WithVersion(version string): Sets the application version.
    • WithCommit(commit string): Sets the commit SHA for version display.
    • WithColorSchemeFunc(cs ColorSchemeFunc): Sets a function to determine the color scheme based on light/dark mode.
    • WithErrorHandler(handler ErrorHandler): Sets a custom function to handle and print errors.
    • WithNotifySignal(signals ...os.Signal): Sets signals that should interrupt the execution of the program via signal.NotifyContext.

    Note: WithTheme is deprecated; use WithColorSchemeFunc instead.

  11. Initialize a styled Cobra application with Execute()

    main

    The Execute function is the primary entrypoint for applying fang styling to a cobra.Command. It configures help formatting, versioning, man page generation, and error handling. It also handles Windows VT processing to ensure ANSI escape sequences work correctly.

    By default, Execute enables man pages, completions, and uses DefaultColorScheme and DefaultErrorHandler. You can customize this behavior using Option functions.