Skip to content

Latest commit

 

History

History
201 lines (145 loc) · 4.38 KB

File metadata and controls

201 lines (145 loc) · 4.38 KB

CLI Design Patterns

Common patterns for building effective CLIs, derived from industry best practices.

Command Structure

Naming Conventions (Heroku)

  • Topics are plural nouns: apps, addons, regions
  • Commands are verbs: create, list, delete
  • Use kebab-case for multi-word names: config-vars

Flag Design (Atlassian #10, Heroku)

# Good: Flags with clear labels
mytool deploy --environment production --region us-west

# Bad: Positional arguments
mytool deploy production us-west
  • Prefer flags over positional arguments
  • Provide both long (--help) and short (-h) versions
  • Use standard flag names across commands

Error Handling

Human-Readable Errors (Atlassian #5, clig.dev)

Error: Cannot connect to database
  Connection refused at localhost:5432

  Possible solutions:
    1. Check if PostgreSQL is running
    2. Verify connection settings in config.yml

  Documentation: https://docs.app.com/errors/db-001

Structure:

  1. Clear problem statement
  2. Technical details
  3. Actionable solutions
  4. Link to documentation

Exit Codes (GNU)

  • 0 - Success
  • 1 - General error
  • 2 - Misuse of shell command
  • 126 - Command cannot execute
  • 127 - Command not found
  • 130 - Script terminated by Ctrl+C

Output Formatting

TTY Detection (Heroku, clig.dev)

# Interactive terminal: Rich output
$ mytool list
NAME        STATUS    UPDATED
app-1       ● live    2 hours ago
app-2       ◐ deploy  5 mins ago

# Pipe/redirect: Plain output
$ mytool list | grep live
app-1    live    2024-01-15T10:30:00Z

Color Usage (Heroku)

  • Use color only when outputting to a TTY
  • Respect NO_COLOR environment variable
  • Provide --no-color flag
  • Use color semantically (red=error, green=success)

Machine-Readable Output (Heroku, clig.dev)

# Human format (default)
$ mytool status
Service: healthy
Uptime: 3 days

# JSON format
$ mytool status --json
{"service":"healthy","uptime_days":3}

# Custom format
$ mytool status --format "{{.Service}} - {{.Uptime}}"
healthy - 3 days

Progress Indicators (Atlassian #3)

For operations longer than 1 second:

# Spinner for indeterminate progress
$ mytool process
Processing... ⠼

# Progress bar for determinate progress
$ mytool upload large-file.zip
Uploading... [████████░░] 80% (12.3MB/15.4MB)

# Status updates
$ mytool deploy
✓ Validated configuration
✓ Built application
→ Deploying to production...

Interactive Patterns

Prompting (Atlassian #8)

# Prompt with defaults
$ mytool init
Project name [my-app]:
Language [auto-detected: python]:
Initialize git repository? [Y/n]:

# Non-interactive mode
$ mytool init --name my-project --language python --git

Confirmations (clig.dev)

# Destructive operations require confirmation
$ mytool delete production-db
⚠ Warning: This will permanently delete 'production-db'
Type the database name to confirm: production-db
✓ Database deleted

Help and Documentation

Built-in Help (Atlassian #2, GNU)

# Every command must have help
$ mytool --help
$ mytool deploy --help

# Help format
Usage: mytool deploy [OPTIONS]

Deploy application to specified environment

Options:
  -e, --environment TEXT  Target environment (dev/staging/prod)
  -f, --force            Skip confirmation prompts
  -h, --help             Show this help message

Examples:
  # Deploy to staging
  mytool deploy --environment staging

  # Force deploy to production
  mytool deploy -e prod --force

Suggest Next Steps (Atlassian #7)

$ mytool init
✓ Created project structure
✓ Initialized configuration

Next steps:
  1. cd my-app
  2. mytool install
  3. mytool dev

Run 'mytool tutorial' for a guided walkthrough

Standard Options (GNU)

Every CLI should support:

  • --help / -h - Show help information
  • --version / -v - Show version information
  • --verbose - Increase output verbosity
  • --quiet / -q - Suppress non-error output

References

These patterns are derived from: