6.1 KiB
6.1 KiB
Nested Commands Example
This example demonstrates using nested classes to organize related commands into groups.
Generate Nested CLI
./scripts/generate-fire-cli.sh \
--name "DeployTool" \
--description "Deployment management tool" \
--template nested \
--output deploy_tool.py
Command Structure
deploy_tool.py
├── config # Configuration group
│ ├── get # Get config value
│ ├── set # Set config value
│ ├── list # List all config
│ └── reset # Reset config
├── resources # Resources group
│ ├── create # Create resource
│ ├── delete # Delete resource
│ └── list # List resources
└── info # Display info
Usage Examples
Configuration Management
# Set configuration value
python deploy_tool.py config set api_key abc123
# Get configuration value
python deploy_tool.py config get api_key
# Output: api_key: abc123
# List all configuration
python deploy_tool.py config list
# Output:
# Configuration:
# api_key: abc123
# endpoint: https://api.example.com
# Reset configuration
python deploy_tool.py config reset --confirm
Resource Management
# Create resource with default template
python deploy_tool.py resources create my-resource
# Create resource with custom template
python deploy_tool.py resources create my-resource --template=advanced
# List all resources
python deploy_tool.py resources list
# Output:
# Resources:
# • item1
# • item2
# • item3
# Delete resource (requires confirmation)
python deploy_tool.py resources delete my-resource
# Output: ⚠ Use --confirm to delete resource
python deploy_tool.py resources delete my-resource --confirm
# Output: ✓ resource deleted
Display Information
python deploy_tool.py info
# Output:
# DeployTool v1.0.0
# Config file: /home/user/.deploytool/config.json
Implementation Pattern
Main CLI Class
class DeployTool:
"""Main CLI application"""
def __init__(self):
self.version = "1.0.0"
self.config_file = Path.home() / ".deploytool" / "config.json"
# Initialize nested command groups
self.config = self.Config(self)
self.resources = self.Resources()
def info(self):
"""Display CLI information"""
console.print(f"[bold]DeployTool[/bold] v{self.version}")
return {"version": self.version}
Nested Command Group
class Config:
"""Configuration management commands"""
def __init__(self, parent):
self.parent = parent # Access to main CLI instance
def get(self, key):
"""Get configuration value
Args:
key: Configuration key to retrieve
"""
config = self._load_config()
value = config.get(key)
console.print(f"[blue]{key}[/blue]: {value}")
return value
def set(self, key, value):
"""Set configuration value
Args:
key: Configuration key to set
value: Configuration value
"""
config = self._load_config()
config[key] = value
self._save_config(config)
console.print(f"[green]✓[/green] Set {key} = {value}")
def _load_config(self):
"""Private helper method (not exposed as command)"""
if not self.parent.config_file.exists():
return {}
return json.loads(self.parent.config_file.read_text())
def _save_config(self, config):
"""Private helper method (not exposed as command)"""
self.parent.config_file.parent.mkdir(parents=True, exist_ok=True)
self.parent.config_file.write_text(json.dumps(config, indent=2))
Key Concepts
Parent Access
Nested classes can access the parent CLI instance:
class Config:
def __init__(self, parent):
self.parent = parent # Store parent reference
def some_command(self):
# Access parent properties
version = self.parent.version
config_file = self.parent.config_file
Private Methods
Methods starting with _ are not exposed as CLI commands:
def list(self):
"""Public command - accessible via CLI"""
pass
def _load_config(self):
"""Private helper - not accessible via CLI"""
pass
Multiple Nesting Levels
You can nest command groups multiple levels deep:
class CLI:
class Database:
"""Database commands"""
class Migration:
"""Migration subcommands"""
def up(self):
"""Run migrations up"""
pass
def down(self):
"""Run migrations down"""
pass
# Usage:
# python cli.py database migration up
# python cli.py database migration down
Help Navigation
Top-Level Help
python deploy_tool.py --help
Shows all command groups and top-level commands.
Group-Level Help
python deploy_tool.py config --help
Shows all commands in the config group.
Command-Level Help
python deploy_tool.py config set --help
Shows help for specific command including arguments.
Best Practices
- Logical Grouping: Group related commands together
- Clear Names: Use descriptive names for groups and commands
- Parent Access: Use parent reference to share state
- Private Helpers: Use
_prefix for helper methods - Comprehensive Docs: Document each command group and command
- Shallow Nesting: Keep nesting to 2-3 levels maximum
Advanced Pattern: Shared Context
class CLI:
def __init__(self):
self.context = {"verbose": False, "config": {}}
class Commands:
def __init__(self, parent):
self.parent = parent
def run(self, verbose=False):
"""Run command"""
self.parent.context["verbose"] = verbose
if verbose:
console.print("[dim]Verbose mode enabled[/dim]")
This allows sharing state across command groups through the parent context.