mamba

package module
v1.0.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 6, 2025 License: MIT Imports: 6 Imported by: 3

README

Mamba

Go Reference Go Report Card

A modern, 100% drop-in replacement for Cobra with enhanced terminal features including beautiful colored output, interactive prompts, loading spinners, and progress bars.

Fast, elegant, and powerful - just like the snake.

Features

  • 100% Cobra Compatible - Drop-in replacement with the same API
  • Modern Styled Output - Beautiful colors and formatting using lipgloss
  • Interactive Prompts - User-friendly input prompts with huh
  • Loading Spinners - Visual feedback for long-running operations
  • Progress Bars - Track progress for batch operations
  • Styled Help Messages - Enhanced help output with colors and structure
  • Full Flag Support - Compatible with pflag

Demo

See Mamba in action! Run the included demo to experience all features:

go get github.com/base-go/mamba
cd examples/basic
go run main.go

The demo showcases:

  • Styled output (success, error, warning, info)
  • Loading spinners with animations
  • Progress bars for batch operations
  • Interactive prompts
  • Modern help messages

Installation

go get github.com/base-go/mamba

Quick Start

package main

import (
    "github.com/base-go/mamba"
)

func main() {
    rootCmd := &mamba.Command{
        Use:   "myapp",
        Short: "My awesome CLI application",
        Run: func(cmd *mamba.Command, args []string) {
            cmd.PrintSuccess("Welcome to Mamba!")
        },
    }

    rootCmd.Execute()
}

Migration from Cobra

Migrating from Cobra to Mamba is incredibly simple - just change your imports!

Before (Cobra)
import (
    "github.com/spf13/cobra"
)

var rootCmd = &cobra.Command{
    Use:   "myapp",
    Short: "My application",
    Run: func(cmd *cobra.Command, args []string) {
        fmt.Println("Hello from Cobra")
    },
}
After (Mamba)
import (
    "github.com/base-go/mamba"
)

var rootCmd = &mamba.Command{
    Use:   "myapp",
    Short: "My application",
    Run: func(cmd *mamba.Command, args []string) {
        cmd.PrintSuccess("Hello from Mamba!")
    },
}

That's it! Your existing Cobra code will work seamlessly with Mamba, but you now have access to modern terminal features.

Mamba vs Cobra

Feature Cobra Mamba
Command structure Yes Yes
Subcommands Yes Yes
Flags (local & persistent) Yes Yes
Lifecycle hooks Yes Yes
Argument validation Yes Yes
Help generation Yes Yes (Enhanced)
Colored output No Yes
Loading spinners No Yes
Progress bars No Yes
Interactive prompts No Yes
Styled help messages No Yes
Modern terminal UX No Yes

Enhanced Features

Styled Output

Mamba provides beautiful, pre-styled output methods:

cmd := &mamba.Command{
    Use: "demo",
    Run: func(cmd *mamba.Command, args []string) {
        cmd.PrintSuccess("Operation completed successfully")
        cmd.PrintError("Something went wrong")
        cmd.PrintWarning("This is a warning")
        cmd.PrintInfo("Here's some information")
        cmd.PrintHeader("Section Header")
        cmd.PrintBullet("Bullet point item")
        cmd.PrintCode("go run main.go")
        cmd.PrintBox("Title", "Important message in a box")
    },
}
Interactive Prompts

Create beautiful interactive prompts with ease:

import "github.com/base-go/mamba/pkg/interactive"

// Simple text input
name, err := interactive.AskString("What's your name?", "Enter your name")

// Yes/No confirmation
confirmed, err := interactive.AskConfirm("Do you want to continue?", true)

// Selection from list
options := []interactive.SelectOption{
    {Key: "red", Value: "Red"},
    {Key: "blue", Value: "Blue"},
    {Key: "green", Value: "Green"},
}
color, err := interactive.AskSelect("Choose a color:", options)

// Multi-selection
selected, err := interactive.AskMultiSelect("Choose features:", options, 0)
Loading Spinners

Show progress for long-running operations:

import "github.com/base-go/mamba/pkg/spinner"

err := spinner.WithSpinner("Processing...", func() error {
    // Your long-running operation here
    time.Sleep(2 * time.Second)
    return nil
})
Progress Bars

Track progress for batch operations:

import "github.com/base-go/mamba/pkg/spinner"

spinner.WithProgress("Processing items...", total, func(update func()) {
    for i := 0; i < total; i++ {
        // Process item
        time.Sleep(100 * time.Millisecond)
        update() // Update progress bar
    }
})
Custom Styling

Use the style package directly for custom formatting:

import "github.com/base-go/mamba/pkg/style"

fmt.Println(style.Success("Success!"))
fmt.Println(style.Error("Error!"))
fmt.Println(style.Bold("Bold text"))
fmt.Println(style.Code("code snippet"))
fmt.Println(style.Header("Header"))
fmt.Println(style.Box("Title", "Content"))

Full Example

See the examples/basic directory for a complete demonstration of all features:

# Run the example
cd examples/basic
go run main.go

# Or use the pre-built binary
./mamba styled          # View styled output demo
./mamba greet --name Alice  # Try command with flags
./mamba process --count 5   # See loading spinner
./mamba progress --count 10 # See progress bar
./mamba interactive         # Try interactive prompts
./mamba list                # View feature list

API Compatibility

Mamba maintains 100% API compatibility with Cobra. All these features work identically:

  • Command structure (Use, Short, Long, Example)
  • Subcommands (AddCommand, RemoveCommand)
  • Flags (local, persistent, shorthand)
  • Lifecycle hooks (PreRun, PostRun, PersistentPreRun, etc.)
  • Argument validators (NoArgs, ExactArgs, MinimumNArgs, etc.)
  • Error handling (RunE, PreRunE, PostRunE)
  • Context support
  • Custom help and usage templates

Advanced Usage

Disabling Modern Features

If you want to disable modern styling:

disableColors := false
cmd := &mamba.Command{
    Use:          "myapp",
    EnableColors: &disableColors,
}
Custom IO Writers

Like Cobra, Mamba supports custom IO writers:

cmd.SetOutput(customWriter)
cmd.SetErr(customErrWriter)
cmd.SetIn(customReader)
Working with Existing Cobra Projects

For large projects with many files:

  1. Update imports globally:

    find . -name "*.go" -type f -exec sed -i '' 's|github.com/spf13/cobra|github.com/base-go/mamba|g' {} +
    
  2. Run go mod tidy:

    go mod tidy
    
  3. Rebuild your project:

    go build
    

That's it! Your application now has modern terminal features.

Architecture

Mamba is built on top of excellent libraries:

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

License

MIT License - see LICENSE file for details

Why Mamba?

Cobra is excellent, but modern CLI applications deserve modern UX. Mamba brings:

  • Better UX - Colors, spinners, and interactive prompts make CLIs more user-friendly
  • Zero Migration Cost - Drop-in replacement means you can adopt it incrementally
  • Progressive Enhancement - Use as much or as little of the modern features as you want
  • Battle-tested - Built on proven libraries from the Charm ecosystem

Named after the black mamba snake - fast, elegant, and powerful.

Credits

Mamba is inspired by Cobra and uses the fantastic Charm libraries for terminal UI.

Documentation

Overview

Package mamba provides a modern, drop-in replacement for Cobra with enhanced terminal features.

Mamba maintains 100% API compatibility with Cobra while adding beautiful colored output, interactive prompts, loading spinners, progress bars, and modern styled help messages.

Quick Start

Create a simple command:

package main

import (
	"github.com/base-go/mamba"
)

func main() {
	rootCmd := &mamba.Command{
		Use:   "myapp",
		Short: "My awesome CLI application",
		Run: func(cmd *mamba.Command, args []string) {
			cmd.PrintSuccess("Welcome to Mamba!")
		},
	}

	rootCmd.Execute()
}

Modern Features

Mamba adds several modern terminal features on top of Cobra's functionality:

Styled Output - Beautiful, pre-styled output methods:

cmd.PrintSuccess("Operation completed!")
cmd.PrintError("Something went wrong")
cmd.PrintWarning("Be careful")
cmd.PrintInfo("Here's some info")
cmd.PrintHeader("Section Title")

Interactive Prompts - User-friendly input with the interactive package:

import "github.com/base-go/mamba/pkg/interactive"

name, err := interactive.AskString("What's your name?", "Enter name")
confirmed, err := interactive.AskConfirm("Continue?", true)

Loading Spinners - Visual feedback for operations:

import "github.com/base-go/mamba/pkg/spinner"

spinner.WithSpinner("Processing...", func() error {
	// Your operation here
	return nil
})

Progress Bars - Track batch operations:

spinner.WithProgress("Loading...", total, func(update func()) {
	for i := 0; i < total; i++ {
		// Process item
		update()
	}
})

Migration from Cobra

Migrating from Cobra is as simple as changing imports:

Before:

import "github.com/spf13/cobra"

After:

import "github.com/base-go/mamba"

All Cobra features continue to work:

  • Command structure (Use, Short, Long, Example)
  • Subcommands (AddCommand, RemoveCommand)
  • Flags (local, persistent, shorthand)
  • Lifecycle hooks (PreRun, PostRun, PersistentPreRun, etc.)
  • Argument validators (NoArgs, ExactArgs, MinimumNArgs, etc.)
  • Error handling (RunE, PreRunE, PostRunE)
  • Context support
  • Custom help and usage templates

Styling

Use the style package for custom formatting:

import "github.com/base-go/mamba/pkg/style"

fmt.Println(style.Success("Success!"))
fmt.Println(style.Error("Error!"))
fmt.Println(style.Bold("Bold text"))
fmt.Println(style.Code("code snippet"))
fmt.Println(style.Box("Title", "Content"))

Disabling Modern Features

If needed, modern styling can be disabled:

disableColors := false
cmd := &mamba.Command{
	Use:          "myapp",
	EnableColors: &disableColors,
}

Architecture

Mamba is built on proven libraries:

  • spf13/pflag - POSIX-style flag parsing
  • charmbracelet/lipgloss - Terminal styling
  • charmbracelet/huh - Interactive forms
  • charmbracelet/bubbles - TUI components

Index

Constants

This section is empty.

Variables

View Source
var (
	// NoArgs returns an error if any args are provided
	NoArgs = func(cmd *Command, args []string) error {
		if len(args) > 0 {
			return fmt.Errorf("unknown command %q for %q", args[0], cmd.Use)
		}
		return nil
	}

	// ArbitraryArgs accepts any number of args (including zero)
	ArbitraryArgs = func(cmd *Command, args []string) error {
		return nil
	}

	// MinimumNArgs returns an error if there are not at least N args
	MinimumNArgs = func(n int) PositionalArgs {
		return func(cmd *Command, args []string) error {
			if len(args) < n {
				return fmt.Errorf("requires at least %d arg(s), only received %d", n, len(args))
			}
			return nil
		}
	}

	// MaximumNArgs returns an error if there are more than N args
	MaximumNArgs = func(n int) PositionalArgs {
		return func(cmd *Command, args []string) error {
			if len(args) > n {
				return fmt.Errorf("accepts at most %d arg(s), received %d", n, len(args))
			}
			return nil
		}
	}

	// ExactArgs returns an error if there are not exactly N args
	ExactArgs = func(n int) PositionalArgs {
		return func(cmd *Command, args []string) error {
			if len(args) != n {
				return fmt.Errorf("accepts %d arg(s), received %d", n, len(args))
			}
			return nil
		}
	}

	// RangeArgs returns an error if the number of args is not within the range [min, max]
	RangeArgs = func(min, max int) PositionalArgs {
		return func(cmd *Command, args []string) error {
			if len(args) < min || len(args) > max {
				return fmt.Errorf("accepts between %d and %d arg(s), received %d", min, max, len(args))
			}
			return nil
		}
	}
)

Standard validators for positional arguments. These can be used in the Args field of a Command to validate argument counts.

Functions

This section is empty.

Types

type Command

type Command struct {
	// Use is the one-line usage message
	Use string

	// Aliases is an array of aliases that can be used instead of the first word in Use
	Aliases []string

	// Short is the short description shown in the 'help' output
	Short string

	// Long is the long message shown in the 'help <this-command>' output
	Long string

	// Example is examples of how to use the command
	Example string

	// Run is the function to call when this command is executed
	// If both Run and RunE are defined, RunE takes precedence
	Run func(cmd *Command, args []string)

	// RunE is the function to call when this command is executed, with error handling
	RunE func(cmd *Command, args []string) error

	// PreRun is called before Run
	PreRun func(cmd *Command, args []string)

	// PreRunE is called before RunE, with error handling
	PreRunE func(cmd *Command, args []string) error

	// PostRun is called after Run
	PostRun func(cmd *Command, args []string)

	// PostRunE is called after RunE, with error handling
	PostRunE func(cmd *Command, args []string) error

	// PersistentPreRun is called before PreRun and inherited by children
	PersistentPreRun func(cmd *Command, args []string)

	// PersistentPreRunE is called before PreRunE and inherited by children
	PersistentPreRunE func(cmd *Command, args []string) error

	// PersistentPostRun is called after PostRun and inherited by children
	PersistentPostRun func(cmd *Command, args []string)

	// PersistentPostRunE is called after PostRunE and inherited by children
	PersistentPostRunE func(cmd *Command, args []string) error

	// SilenceErrors prevents error messages from being displayed
	SilenceErrors bool

	// SilenceUsage prevents usage from being displayed on errors
	SilenceUsage bool

	// DisableFlagParsing disables flag parsing
	DisableFlagParsing bool

	// DisableAutoGenTag prevents auto-generation tag in help
	DisableAutoGenTag bool

	// Hidden hides this command from help output
	Hidden bool

	// Args defines expected arguments
	Args PositionalArgs

	// ValidArgs is list of all valid non-flag arguments
	ValidArgs []string

	// ValidArgsFunction is an optional function for custom argument completion
	ValidArgsFunction func(cmd *Command, args []string, toComplete string) ([]string, error)

	// Version is the version for this command
	Version string

	// Modern terminal features
	// EnableColors enables colored output (default: auto-detect)
	EnableColors *bool

	// EnableInteractive enables interactive prompts
	EnableInteractive bool

	// ShowSpinner enables loading spinners
	ShowSpinner bool
	// contains filtered or unexported fields
}

Command represents a CLI command with modern terminal features.

Command is fully compatible with Cobra's Command struct and can be used as a drop-in replacement. It extends Cobra's functionality with modern terminal features including colored output, interactive prompts, loading spinners, and styled help messages.

Example:

cmd := &mamba.Command{
	Use:   "myapp",
	Short: "My application",
	Run: func(cmd *mamba.Command, args []string) {
		cmd.PrintSuccess("Hello, Mamba!")
	},
}
cmd.Execute()

func (*Command) AddCommand

func (c *Command) AddCommand(cmds ...*Command)

AddCommand adds one or more subcommands

func (*Command) Commands

func (c *Command) Commands() []*Command

Commands returns all subcommands

func (*Command) Context

func (c *Command) Context() interface{}

Context returns the command context

func (*Command) ErrOrStderr

func (c *Command) ErrOrStderr() io.Writer

ErrOrStderr returns the error output writer or stderr

func (*Command) Execute

func (c *Command) Execute() error

Execute runs the command

func (*Command) ExecuteContext

func (c *Command) ExecuteContext(ctx interface{}) error

ExecuteContext runs the command with context

func (*Command) Find

func (c *Command) Find(args []string) (*Command, []string, error)

Find finds the command to execute

func (*Command) Flags

func (c *Command) Flags() *pflag.FlagSet

Flags returns the complete FlagSet

func (*Command) HasAlias

func (c *Command) HasAlias(s string) bool

HasAlias checks if a string is an alias

func (*Command) HasParent

func (c *Command) HasParent() bool

HasParent returns true if the command has a parent

func (*Command) HasSubCommands

func (c *Command) HasSubCommands() bool

HasSubCommands returns true if the command has subcommands

func (*Command) Help

func (c *Command) Help() error

Help prints the help message

func (*Command) InOrStdin

func (c *Command) InOrStdin() io.Reader

InOrStdin returns the input reader or stdin

func (*Command) LocalFlags

func (c *Command) LocalFlags() *pflag.FlagSet

LocalFlags returns the local FlagSet

func (*Command) ModernHelp

func (c *Command) ModernHelp() string

ModernHelp generates a modern styled help message

func (*Command) Name

func (c *Command) Name() string

Name returns the command's name

func (*Command) OutOrStdout

func (c *Command) OutOrStdout() io.Writer

OutOrStdout returns the output writer or stdout

func (*Command) Parent

func (c *Command) Parent() *Command

Parent returns the parent command

func (*Command) ParseFlags

func (c *Command) ParseFlags(args []string) error

ParseFlags parses the flags

func (*Command) PersistentFlags

func (c *Command) PersistentFlags() *pflag.FlagSet

PersistentFlags returns the persistent FlagSet

func (*Command) PrintBox

func (c *Command) PrintBox(title, content string)

PrintBox prints text in a box

func (*Command) PrintBullet

func (c *Command) PrintBullet(msg string)

PrintBullet prints a bullet point

func (*Command) PrintCode

func (c *Command) PrintCode(code string)

PrintCode prints code or technical text

func (*Command) PrintError

func (c *Command) PrintError(msg string)

PrintError prints an error message

func (*Command) PrintHeader

func (c *Command) PrintHeader(msg string)

PrintHeader prints a header

func (*Command) PrintInfo

func (c *Command) PrintInfo(msg string)

PrintInfo prints an info message

func (*Command) PrintSubHeader

func (c *Command) PrintSubHeader(msg string)

PrintSubHeader prints a sub-header

func (*Command) PrintSuccess

func (c *Command) PrintSuccess(msg string)

PrintSuccess prints a success message

func (*Command) PrintWarning

func (c *Command) PrintWarning(msg string)

PrintWarning prints a warning message

func (*Command) RemoveCommand

func (c *Command) RemoveCommand(cmds ...*Command)

RemoveCommand removes one or more subcommands

func (*Command) Root

func (c *Command) Root() *Command

Root returns the root command

func (*Command) SetContext

func (c *Command) SetContext(ctx interface{})

SetContext sets the command context

func (*Command) SetErr

func (c *Command) SetErr(err io.Writer)

SetErr sets the error output writer

func (*Command) SetHelpCommand

func (c *Command) SetHelpCommand(cmd *Command)

SetHelpCommand sets the help command

func (*Command) SetHelpFunc

func (c *Command) SetHelpFunc(f func(*Command, []string))

SetHelpFunc sets the help function

func (*Command) SetIn

func (c *Command) SetIn(in io.Reader)

SetIn sets the input reader

func (*Command) SetOutput

func (c *Command) SetOutput(output io.Writer)

SetOutput sets the output writer

func (*Command) SetUsageFunc

func (c *Command) SetUsageFunc(f func(*Command) error)

SetUsageFunc sets the usage function

func (*Command) SetUsageTemplate

func (c *Command) SetUsageTemplate(s string)

SetUsageTemplate sets the usage template

func (*Command) SetVersionTemplate

func (c *Command) SetVersionTemplate(s string)

SetVersionTemplate sets the version template

func (*Command) Usage

func (c *Command) Usage() error

Usage prints the usage message

func (*Command) UsageString

func (c *Command) UsageString() string

UsageString returns the usage string (plain version)

func (*Command) UseLine

func (c *Command) UseLine() string

UseLine returns the usage line

type PositionalArgs

type PositionalArgs func(cmd *Command, args []string) error

PositionalArgs defines a validation function for positional arguments. It is used to validate command arguments before the Run function is called.

Example:

cmd := &mamba.Command{
	Use:  "copy <source> <dest>",
	Args: mamba.ExactArgs(2),
	Run:  func(cmd *mamba.Command, args []string) { ... },
}

Directories

Path Synopsis
examples
basic command
pkg

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL