Docs

cli tool

šŸ”§ DevTools CLI

A command-line tool demonstrating Click, Rich, and practical CLI development patterns.

Features

  • •File management utilities
  • •Git helpers
  • •Code statistics
  • •Project scaffolding
  • •Beautiful terminal output with Rich

Installation

# Install in development mode
pip install -e .

# Or install dependencies only
pip install click rich

Usage

File Operations

# Count files matching a pattern
devtools files count ./src
devtools files count . --pattern "*.py"

# Find files with details
devtools files find . --pattern "*.py" --limit 20

# Calculate directory size
devtools files size ./project

# Display directory tree
devtools files tree . --depth 3

Git Helpers

# Enhanced git status with colors
devtools git status

# Pretty git log with table format
devtools git log --count 15

# List branches with info
devtools git branches --all

# Clean up merged branches
devtools git cleanup --dry-run
devtools git cleanup  # Actually delete

Code Statistics

# Count lines of code
devtools stats lines ./src
devtools stats lines . --ext .py --ext .js

# Find TODO/FIXME comments
devtools stats todos ./
devtools stats todos . --pattern "TODO|FIXME|HACK|XXX"

# Project summary
devtools stats summary .

Project Scaffolding

# Create new Python project
devtools new python myproject

# Create FastAPI project
devtools new fastapi myapi

# Create CLI tool project
devtools new cli mytool

# Create in specific directory
devtools new python myproject --path ~/projects

Project Structure

02_cli_tool/
ā”œā”€ā”€ devtools/
│   ā”œā”€ā”€ __init__.py
│   ā”œā”€ā”€ main.py          # CLI entry point
│   ā”œā”€ā”€ commands/
│   │   ā”œā”€ā”€ __init__.py
│   │   ā”œā”€ā”€ files.py     # File commands
│   │   ā”œā”€ā”€ git.py       # Git commands
│   │   ā”œā”€ā”€ stats.py     # Code statistics
│   │   └── scaffold.py  # Project creation
│   └── utils/
│       ā”œā”€ā”€ __init__.py
│       ā”œā”€ā”€ console.py   # Rich console helpers
│       └── helpers.py   # Utility functions
ā”œā”€ā”€ tests/
│   ā”œā”€ā”€ __init__.py
│   └── test_cli.py
ā”œā”€ā”€ pyproject.toml
└── README.md

Key Concepts Demonstrated

Click Framework Patterns

# Command groups for organizing subcommands
@click.group()
def cli():
    """Main CLI group."""
    pass

@cli.command()
@click.argument('path')
@click.option('--pattern', '-p', default='*')
def find(path, pattern):
    """Find files matching pattern."""
    pass

# Nested command groups
cli.add_command(files)  # devtools files ...
cli.add_command(git)    # devtools git ...

Rich Library Features

from rich.console import Console
from rich.table import Table
from rich.tree import Tree

console = Console()

# Beautiful tables
table = Table(title="Results")
table.add_column("File", style="cyan")
table.add_column("Size", style="green")
console.print(table)

# Colored output
console.print("[green]Success![/green]")
console.print("[red]Error:[/red] Something went wrong")

# Directory trees
tree = Tree("[bold blue]project/[/bold blue]")
tree.add("src/")
console.print(tree)

CLI Best Practices

  1. •Use command groups - Organize related commands
  2. •Provide help text - Document every command and option
  3. •Use sensible defaults - Make common cases easy
  4. •Show progress - Use progress bars for long operations
  5. •Handle errors gracefully - Catch exceptions, show helpful messages
  6. •Support dry-run - Let users preview destructive operations

Running Tests

# Install test dependencies
pip install pytest

# Run tests
pytest tests/

# Run with verbose output
pytest tests/ -v

Extending the CLI

Adding a New Command Group

# devtools/commands/docker.py
import click
from rich.console import Console

console = Console()

@click.group()
def docker():
    """Docker management commands."""
    pass

@docker.command()
def ps():
    """List running containers."""
    # Implementation here
    pass

# In main.py, add:
# from .commands import docker
# cli.add_command(docker.docker)

Adding Options and Arguments

@click.command()
@click.argument('path', type=click.Path(exists=True))
@click.option('--recursive', '-r', is_flag=True, help='Search recursively')
@click.option('--limit', '-l', default=10, help='Max results')
@click.option('--format', type=click.Choice(['json', 'table']))
def search(path, recursive, limit, format):
    """Search for files."""
    pass

Dependencies

  • •click (>=8.0.0) - Command line interface creation
  • •rich (>=13.0.0) - Beautiful terminal formatting

Learning Resources

Cli Tool - Python Tutorial | DeepML