Initial commit

This commit is contained in:
Zhongwei Li
2025-11-30 09:04:14 +08:00
commit 70c36b5eff
248 changed files with 47482 additions and 0 deletions

View File

@@ -0,0 +1,513 @@
# Advanced Option Class Usage
Comprehensive examples of the Option class for advanced option handling.
## Basic Option Class
```typescript
import { Command, Option } from 'commander';
const program = new Command();
program
.command('deploy')
.addOption(
new Option('-e, --env <environment>', 'target environment')
.choices(['dev', 'staging', 'prod'])
.default('dev')
)
.action((options) => {
console.log('Environment:', options.env);
});
program.parse();
```
## Option with Choices
```typescript
import { Command, Option } from 'commander';
program
.command('log')
.addOption(
new Option('-l, --level <level>', 'log level')
.choices(['debug', 'info', 'warn', 'error'])
.default('info')
)
.addOption(
new Option('-f, --format <format>', 'output format')
.choices(['json', 'yaml', 'table'])
.default('table')
)
.action((options) => {
console.log(`Logging at ${options.level} level in ${options.format} format`);
});
```
Usage:
```bash
mycli log --level debug --format json
mycli log --level invalid # Error: invalid choice
```
## Mandatory Options
```typescript
import { Command, Option } from 'commander';
program
.command('deploy')
.addOption(
new Option('-t, --token <token>', 'API token')
.makeOptionMandatory()
)
.addOption(
new Option('-e, --env <environment>', 'environment')
.choices(['dev', 'staging', 'prod'])
.makeOptionMandatory()
)
.action((options) => {
console.log('Deploying with token:', options.token);
console.log('Environment:', options.env);
});
```
Usage:
```bash
mycli deploy # Error: required option missing
mycli deploy --token abc --env prod # ✓ Works
```
## Options from Environment Variables
```typescript
import { Command, Option } from 'commander';
program
.command('deploy')
.addOption(
new Option('-t, --token <token>', 'API token')
.env('API_TOKEN')
.makeOptionMandatory()
)
.addOption(
new Option('-u, --api-url <url>', 'API URL')
.env('API_URL')
.default('https://api.example.com')
)
.action((options) => {
console.log('Token:', options.token);
console.log('API URL:', options.apiUrl);
});
```
Usage:
```bash
export API_TOKEN=abc123
export API_URL=https://custom-api.com
mycli deploy # Uses environment variables
mycli deploy --token xyz # CLI arg overrides env var
```
## Custom Argument Parsers
```typescript
import { Command, Option } from 'commander';
program
.command('scale')
.addOption(
new Option('-r, --replicas <count>', 'number of replicas')
.argParser((value) => {
const count = parseInt(value, 10);
if (isNaN(count) || count < 1 || count > 100) {
throw new Error('Replicas must be between 1 and 100');
}
return count;
})
.default(3)
)
.addOption(
new Option('-m, --memory <size>', 'memory limit')
.argParser((value) => {
// Parse sizes like "512M", "2G"
const match = value.match(/^(\d+)([MG])$/i);
if (!match) {
throw new Error('Invalid memory format (use 512M or 2G)');
}
const [, num, unit] = match;
const mb = parseInt(num) * (unit.toUpperCase() === 'G' ? 1024 : 1);
return mb;
})
.default(512)
)
.action((options) => {
console.log('Replicas:', options.replicas);
console.log('Memory:', options.memory, 'MB');
});
```
Usage:
```bash
mycli scale --replicas 5 --memory 2G
# Replicas: 5
# Memory: 2048 MB
```
## Conflicting Options
```typescript
import { Command, Option } from 'commander';
program
.command('build')
.addOption(
new Option('--cache', 'enable caching')
.conflicts('noCache')
)
.addOption(
new Option('--no-cache', 'disable caching')
.conflicts('cache')
)
.addOption(
new Option('--watch', 'watch mode')
.conflicts('production')
)
.addOption(
new Option('--production', 'production build')
.conflicts('watch')
)
.action((options) => {
console.log('Cache:', options.cache);
console.log('Watch:', options.watch);
console.log('Production:', options.production);
});
```
Usage:
```bash
mycli build --cache # ✓ Works
mycli build --no-cache # ✓ Works
mycli build --cache --no-cache # ✗ Error: conflicting options
mycli build --watch --production # ✗ Error: conflicting options
```
## Option Implies
```typescript
import { Command, Option } from 'commander';
program
.command('server')
.addOption(
new Option('--ssl', 'enable SSL')
.implies({ sslCert: './cert.pem', sslKey: './key.pem' })
)
.addOption(
new Option('--ssl-cert <path>', 'SSL certificate path')
)
.addOption(
new Option('--ssl-key <path>', 'SSL key path')
)
.addOption(
new Option('--secure', 'secure mode')
.implies({ ssl: true, httpsOnly: true })
)
.addOption(
new Option('--https-only', 'enforce HTTPS')
)
.action((options) => {
console.log('SSL:', options.ssl);
console.log('SSL Cert:', options.sslCert);
console.log('SSL Key:', options.sslKey);
console.log('HTTPS Only:', options.httpsOnly);
});
```
Usage:
```bash
mycli server --ssl
# SSL: true
# SSL Cert: ./cert.pem
# SSL Key: ./key.pem
mycli server --secure
# SSL: true
# HTTPS Only: true
```
## Preset Configurations
```typescript
import { Command, Option } from 'commander';
program
.command('deploy')
.addOption(
new Option('--preset <preset>', 'use preset configuration')
.choices(['minimal', 'standard', 'enterprise'])
.argParser((value) => {
const presets = {
minimal: {
replicas: 1,
memory: '256M',
cpu: '0.25',
autoScaling: false,
},
standard: {
replicas: 3,
memory: '512M',
cpu: '0.5',
autoScaling: true,
},
enterprise: {
replicas: 10,
memory: '2G',
cpu: '2',
autoScaling: true,
loadBalancer: true,
monitoring: true,
},
};
return presets[value as keyof typeof presets];
})
)
.action((options) => {
if (options.preset) {
console.log('Using preset configuration:');
console.log(JSON.stringify(options.preset, null, 2));
}
});
```
Usage:
```bash
mycli deploy --preset enterprise
# Using preset configuration:
# {
# "replicas": 10,
# "memory": "2G",
# "cpu": "2",
# "autoScaling": true,
# "loadBalancer": true,
# "monitoring": true
# }
```
## Hidden Options (Debug/Internal)
```typescript
import { Command, Option } from 'commander';
program
.command('build')
.option('-p, --production', 'production build')
.addOption(
new Option('--debug', 'enable debug mode')
.hideHelp()
)
.addOption(
new Option('--internal-api', 'use internal API')
.hideHelp()
.default(false)
)
.action((options) => {
if (options.debug) {
console.log('Debug mode enabled');
console.log('All options:', options);
}
});
```
## Complex Validation
```typescript
import { Command, Option } from 'commander';
program
.command('backup')
.addOption(
new Option('-s, --schedule <cron>', 'backup schedule (cron format)')
.argParser((value) => {
// Validate cron expression
const cronRegex = /^(\*|([0-9]|1[0-9]|2[0-9]|3[0-9]|4[0-9]|5[0-9])|\*\/([0-9]|1[0-9]|2[0-9]|3[0-9]|4[0-9]|5[0-9])) (\*|([0-9]|1[0-9]|2[0-3])|\*\/([0-9]|1[0-9]|2[0-3])) (\*|([1-9]|1[0-9]|2[0-9]|3[0-1])|\*\/([1-9]|1[0-9]|2[0-9]|3[0-1])) (\*|([1-9]|1[0-2])|\*\/([1-9]|1[0-2])) (\*|([0-6])|\*\/([0-6]))$/;
if (!cronRegex.test(value)) {
throw new Error('Invalid cron expression');
}
return value;
})
)
.addOption(
new Option('-r, --retention <days>', 'backup retention in days')
.argParser((value) => {
const days = parseInt(value, 10);
if (isNaN(days) || days < 1 || days > 365) {
throw new Error('Retention must be between 1 and 365 days');
}
return days;
})
.default(30)
)
.action((options) => {
console.log('Schedule:', options.schedule);
console.log('Retention:', options.retention, 'days');
});
```
Usage:
```bash
mycli backup --schedule "0 2 * * *" --retention 90
# Schedule: 0 2 * * *
# Retention: 90 days
```
## Cumulative Options
```typescript
import { Command, Option } from 'commander';
program
.command('log')
.addOption(
new Option('-v, --verbose', 'increase verbosity')
.argParser((value, previous) => {
return previous + 1;
})
.default(0)
)
.action((options) => {
console.log('Verbosity level:', options.verbose);
// 0 = normal
// 1 = verbose (-v)
// 2 = very verbose (-vv)
// 3 = debug (-vvv)
});
```
Usage:
```bash
mycli log # verbosity: 0
mycli log -v # verbosity: 1
mycli log -vv # verbosity: 2
mycli log -vvv # verbosity: 3
```
## Complete Example
```typescript
#!/usr/bin/env node
import { Command, Option } from 'commander';
import chalk from 'chalk';
const program = new Command();
program
.name('deploy-cli')
.version('1.0.0');
program
.command('deploy')
.description('Deploy application with advanced options')
// Required with choices
.addOption(
new Option('-e, --env <environment>', 'deployment environment')
.choices(['dev', 'staging', 'prod'])
.makeOptionMandatory()
)
// Environment variable with validation
.addOption(
new Option('-t, --token <token>', 'API token')
.env('DEPLOY_TOKEN')
.makeOptionMandatory()
.argParser((value) => {
if (value.length < 32) {
throw new Error('Token must be at least 32 characters');
}
return value;
})
)
// Custom parser with unit conversion
.addOption(
new Option('-m, --memory <size>', 'memory allocation')
.argParser((value) => {
const match = value.match(/^(\d+)([MG])$/i);
if (!match) {
throw new Error('Memory must be in format: 512M or 2G');
}
const [, num, unit] = match;
return parseInt(num) * (unit.toUpperCase() === 'G' ? 1024 : 1);
})
.default(512)
)
// Conflicting options
.addOption(
new Option('--fast', 'fast deployment (skip tests)')
.conflicts('safe')
)
.addOption(
new Option('--safe', 'safe deployment (full tests)')
.conflicts('fast')
.default(true)
)
// Implies relationship
.addOption(
new Option('--production-mode', 'enable production optimizations')
.implies({ env: 'prod', safe: true, monitoring: true })
)
.addOption(
new Option('--monitoring', 'enable monitoring')
)
// Hidden debug option
.addOption(
new Option('--debug', 'debug mode')
.hideHelp()
)
.action((options) => {
console.log(chalk.blue('Deployment Configuration:'));
console.log('Environment:', chalk.yellow(options.env));
console.log('Token:', options.token ? chalk.green('***set***') : chalk.red('missing'));
console.log('Memory:', `${options.memory}MB`);
console.log('Mode:', options.fast ? 'fast' : 'safe');
console.log('Production Mode:', options.productionMode || false);
console.log('Monitoring:', options.monitoring || false);
if (options.debug) {
console.log(chalk.gray('\nDebug - All options:'));
console.log(chalk.gray(JSON.stringify(options, null, 2)));
}
console.log(chalk.green('\n✓ Deployment started'));
});
program.parse();
```
Usage:
```bash
export DEPLOY_TOKEN=abc123xyz789abc123xyz789abc12345
# Basic deployment
deploy-cli deploy --env staging
# Custom memory
deploy-cli deploy --env prod --memory 4G
# Fast mode
deploy-cli deploy --env dev --fast
# Production mode (implies multiple settings)
deploy-cli deploy --production-mode
# Debug
deploy-cli deploy --env dev --debug
```

View File

@@ -0,0 +1,284 @@
# Basic Commander.js Usage
Simple examples demonstrating core Commander.js features.
## Example 1: Simple CLI with Commands
```typescript
import { Command } from 'commander';
const program = new Command();
program
.name('mycli')
.description('My CLI tool')
.version('1.0.0');
// Command without options
program
.command('init')
.description('Initialize project')
.action(() => {
console.log('Initializing project...');
});
// Command with options
program
.command('build')
.description('Build project')
.option('-w, --watch', 'watch mode')
.action((options) => {
console.log('Building...');
if (options.watch) {
console.log('Watch mode enabled');
}
});
program.parse();
```
**Usage:**
```bash
mycli init
mycli build
mycli build --watch
mycli --help
mycli --version
```
## Example 2: Command with Arguments
```typescript
import { Command } from 'commander';
const program = new Command();
program
.name('mycli')
.version('1.0.0');
program
.command('greet <name>')
.description('Greet someone')
.action((name) => {
console.log(`Hello, ${name}!`);
});
program
.command('add <a> <b>')
.description('Add two numbers')
.action((a, b) => {
const sum = parseInt(a) + parseInt(b);
console.log(`${a} + ${b} = ${sum}`);
});
program.parse();
```
**Usage:**
```bash
mycli greet Alice
# Output: Hello, Alice!
mycli add 5 3
# Output: 5 + 3 = 8
```
## Example 3: Options with Different Types
```typescript
import { Command } from 'commander';
const program = new Command();
program
.name('mycli')
.version('1.0.0');
program
.command('serve')
.description('Start development server')
// Boolean flag
.option('-o, --open', 'open browser', false)
// Option with value
.option('-p, --port <port>', 'port number', '3000')
// Option with default
.option('-h, --host <host>', 'hostname', 'localhost')
// Negatable option
.option('--no-color', 'disable colors')
.action((options) => {
console.log(`Server running at http://${options.host}:${options.port}`);
console.log('Open browser:', options.open);
console.log('Colors:', options.color);
});
program.parse();
```
**Usage:**
```bash
mycli serve
# Uses defaults
mycli serve --port 8080
# Uses custom port
mycli serve --open --no-color
# Opens browser and disables colors
```
## Example 4: Global Options
```typescript
import { Command } from 'commander';
const program = new Command();
program
.name('mycli')
.version('1.0.0')
// Global options
.option('-v, --verbose', 'verbose output')
.option('-c, --config <path>', 'config file path');
program
.command('deploy')
.action((options, command) => {
const globalOpts = command.parent?.opts();
console.log('Deploying...');
if (globalOpts?.verbose) {
console.log('Verbose mode enabled');
console.log('Config:', globalOpts.config);
}
});
program.parse();
```
**Usage:**
```bash
mycli deploy
# Normal output
mycli --verbose deploy
# Verbose output
mycli --verbose --config ./config.json deploy
# Verbose with custom config
```
## Example 5: Multiple Commands
```typescript
import { Command } from 'commander';
import chalk from 'chalk';
const program = new Command();
program.name('mycli').version('1.0.0');
program
.command('init')
.description('Initialize new project')
.action(() => {
console.log(chalk.green('✓ Project initialized'));
});
program
.command('build')
.description('Build project')
.action(() => {
console.log(chalk.blue('Building...'));
console.log(chalk.green('✓ Build complete'));
});
program
.command('test')
.description('Run tests')
.action(() => {
console.log(chalk.blue('Running tests...'));
console.log(chalk.green('✓ All tests passed'));
});
program
.command('deploy')
.description('Deploy to production')
.action(() => {
console.log(chalk.yellow('Deploying...'));
console.log(chalk.green('✓ Deployed'));
});
program.parse();
```
**Usage:**
```bash
mycli init
mycli build
mycli test
mycli deploy
mycli --help # Shows all commands
```
## Running the Examples
### Setup
1. Create a new project:
```bash
mkdir my-cli
cd my-cli
npm init -y
```
2. Install dependencies:
```bash
npm install commander chalk
npm install -D typescript @types/node tsx
```
3. Configure TypeScript:
```bash
npx tsc --init --target ES2022 --module ESNext
```
4. Create `src/index.ts` with any example above
5. Run with tsx:
```bash
npx tsx src/index.ts --help
```
### Building for Production
```bash
# Build TypeScript
npx tsc
# Run compiled version
node dist/index.js
```
### Making it Executable
Add to `package.json`:
```json
{
"bin": {
"mycli": "./dist/index.js"
}
}
```
Add shebang to top of source file:
```typescript
#!/usr/bin/env node
import { Command } from 'commander';
// ... rest of code
```
Install globally for testing:
```bash
npm link
mycli --help
```

View File

@@ -0,0 +1,558 @@
# Nested Commands Demo
Examples of building multi-level command hierarchies with Commander.js.
## Basic Nested Commands
```typescript
import { Command } from 'commander';
const program = new Command();
program.name('mycli').version('1.0.0');
// Create parent command
const config = program.command('config').description('Configuration management');
// Add subcommands
config
.command('get <key>')
.description('Get config value')
.action((key) => {
console.log(`Getting ${key}...`);
});
config
.command('set <key> <value>')
.description('Set config value')
.action((key, value) => {
console.log(`Setting ${key} = ${value}`);
});
config
.command('list')
.description('List all config')
.action(() => {
console.log('Listing config...');
});
program.parse();
```
Usage:
```bash
mycli config get api-key
mycli config set api-key abc123
mycli config list
mycli config --help # Shows subcommands
```
## Multiple Command Groups
```typescript
import { Command } from 'commander';
import chalk from 'chalk';
const program = new Command();
program.name('mycli').version('1.0.0');
// Database commands
const db = program.command('db').description('Database operations');
db.command('migrate')
.description('Run migrations')
.option('-d, --dry-run', 'show migrations')
.action((options) => {
console.log(chalk.blue('Running migrations...'));
});
db.command('seed')
.description('Seed database')
.option('-e, --env <env>', 'environment', 'dev')
.action((options) => {
console.log(chalk.blue(`Seeding ${options.env} database...`));
});
db.command('reset')
.description('Reset database')
.option('-f, --force', 'skip confirmation')
.action((options) => {
if (!options.force) {
console.log(chalk.red('Use --force to confirm'));
return;
}
console.log(chalk.yellow('Resetting database...'));
});
// User commands
const user = program.command('user').description('User management');
user
.command('list')
.description('List users')
.option('-p, --page <page>', 'page number', '1')
.action((options) => {
console.log(`Listing users (page ${options.page})`);
});
user
.command('create <username> <email>')
.description('Create user')
.action((username, email) => {
console.log(chalk.green(`Created user: ${username} (${email})`));
});
user
.command('delete <userId>')
.description('Delete user')
.option('-f, --force', 'skip confirmation')
.action((userId, options) => {
console.log(chalk.red(`Deleted user: ${userId}`));
});
// Cache commands
const cache = program.command('cache').description('Cache management');
cache
.command('clear')
.description('Clear cache')
.option('-a, --all', 'clear all caches')
.action((options) => {
console.log('Clearing cache...');
});
cache
.command('stats')
.description('Show cache statistics')
.action(() => {
console.log('Cache stats:');
console.log(' Size: 1.2 GB');
console.log(' Hits: 89%');
});
program.parse();
```
Usage:
```bash
mycli db migrate --dry-run
mycli db seed --env prod
mycli db reset --force
mycli user list --page 2
mycli user create john john@example.com
mycli user delete 123 --force
mycli cache clear --all
mycli cache stats
```
## Three-Level Nesting
```typescript
import { Command } from 'commander';
const program = new Command();
program.name('mycli').version('1.0.0');
// Level 1: Cloud
const cloud = program.command('cloud').description('Cloud operations');
// Level 2: AWS
const aws = cloud.command('aws').description('AWS operations');
// Level 3: EC2
const ec2 = aws.command('ec2').description('EC2 operations');
ec2
.command('list')
.description('List EC2 instances')
.action(() => {
console.log('Listing EC2 instances...');
});
ec2
.command('start <instanceId>')
.description('Start EC2 instance')
.action((instanceId) => {
console.log(`Starting instance ${instanceId}...`);
});
ec2
.command('stop <instanceId>')
.description('Stop EC2 instance')
.action((instanceId) => {
console.log(`Stopping instance ${instanceId}...`);
});
// Level 3: S3
const s3 = aws.command('s3').description('S3 operations');
s3.command('list')
.description('List S3 buckets')
.action(() => {
console.log('Listing S3 buckets...');
});
s3.command('upload <file> <bucket>')
.description('Upload to S3')
.action((file, bucket) => {
console.log(`Uploading ${file} to ${bucket}...`);
});
// Level 2: Azure
const azure = cloud.command('azure').description('Azure operations');
azure
.command('vm-list')
.description('List VMs')
.action(() => {
console.log('Listing Azure VMs...');
});
program.parse();
```
Usage:
```bash
mycli cloud aws ec2 list
mycli cloud aws ec2 start i-123456
mycli cloud aws s3 list
mycli cloud aws s3 upload file.txt my-bucket
mycli cloud azure vm-list
```
## CRUD Pattern
```typescript
import { Command } from 'commander';
import chalk from 'chalk';
const program = new Command();
program.name('api-cli').version('1.0.0');
function createResourceCommands(name: string) {
const resource = program.command(name).description(`${name} management`);
resource
.command('list')
.description(`List all ${name}`)
.option('-p, --page <page>', 'page number', '1')
.option('-l, --limit <limit>', 'items per page', '10')
.action((options) => {
console.log(chalk.blue(`Listing ${name}...`));
console.log(`Page ${options.page}, Limit ${options.limit}`);
});
resource
.command('get <id>')
.description(`Get ${name} by ID`)
.action((id) => {
console.log(chalk.blue(`Getting ${name} ${id}...`));
});
resource
.command('create')
.description(`Create new ${name}`)
.option('-d, --data <json>', 'JSON data')
.action((options) => {
console.log(chalk.green(`Creating ${name}...`));
console.log('Data:', options.data);
});
resource
.command('update <id>')
.description(`Update ${name}`)
.option('-d, --data <json>', 'JSON data')
.action((id, options) => {
console.log(chalk.yellow(`Updating ${name} ${id}...`));
console.log('Data:', options.data);
});
resource
.command('delete <id>')
.description(`Delete ${name}`)
.option('-f, --force', 'skip confirmation')
.action((id, options) => {
if (!options.force) {
console.log(chalk.red('Use --force to confirm deletion'));
return;
}
console.log(chalk.red(`Deleted ${name} ${id}`));
});
return resource;
}
// Create CRUD commands for different resources
createResourceCommands('users');
createResourceCommands('posts');
createResourceCommands('comments');
program.parse();
```
Usage:
```bash
# Users
api-cli users list --page 2
api-cli users get 123
api-cli users create --data '{"name":"John"}'
api-cli users update 123 --data '{"email":"new@example.com"}'
api-cli users delete 123 --force
# Posts
api-cli posts list
api-cli posts get 456
api-cli posts create --data '{"title":"Hello"}'
# Comments
api-cli comments list
```
## Modular Command Structure
Split commands into separate files for better organization:
**src/commands/config.ts**
```typescript
import { Command } from 'commander';
export function createConfigCommand(): Command {
const config = new Command('config').description('Configuration management');
config
.command('get <key>')
.description('Get config value')
.action((key) => {
console.log(`Getting ${key}...`);
});
config
.command('set <key> <value>')
.description('Set config value')
.action((key, value) => {
console.log(`Setting ${key} = ${value}`);
});
return config;
}
```
**src/commands/user.ts**
```typescript
import { Command } from 'commander';
export function createUserCommand(): Command {
const user = new Command('user').description('User management');
user
.command('list')
.description('List users')
.action(() => {
console.log('Listing users...');
});
user
.command('create <username>')
.description('Create user')
.action((username) => {
console.log(`Creating user: ${username}`);
});
return user;
}
```
**src/index.ts**
```typescript
import { Command } from 'commander';
import { createConfigCommand } from './commands/config';
import { createUserCommand } from './commands/user';
const program = new Command();
program
.name('mycli')
.version('1.0.0')
.description('My CLI tool');
// Add command groups
program.addCommand(createConfigCommand());
program.addCommand(createUserCommand());
program.parse();
```
## Nested Commands with Shared Options
```typescript
import { Command } from 'commander';
const program = new Command();
program.name('deploy-cli').version('1.0.0');
// Parent deploy command with shared options
const deploy = program
.command('deploy')
.description('Deployment operations')
.option('-e, --env <environment>', 'environment', 'dev')
.option('-v, --verbose', 'verbose output');
// Subcommands inherit parent context
deploy
.command('start')
.description('Start deployment')
.option('-f, --force', 'force deployment')
.action((options, command) => {
const parentOpts = command.parent?.opts();
console.log('Environment:', parentOpts?.env);
console.log('Verbose:', parentOpts?.verbose);
console.log('Force:', options.force);
});
deploy
.command('status')
.description('Check deployment status')
.action((options, command) => {
const parentOpts = command.parent?.opts();
console.log(`Checking ${parentOpts?.env} status...`);
});
deploy
.command('rollback [version]')
.description('Rollback deployment')
.action((version, options, command) => {
const parentOpts = command.parent?.opts();
console.log(`Rolling back ${parentOpts?.env}...`);
});
program.parse();
```
Usage:
```bash
deploy-cli deploy --env prod start --force
deploy-cli deploy --env staging status
deploy-cli deploy --verbose rollback v1.0.0
```
## Command Aliases
```typescript
import { Command } from 'commander';
const program = new Command();
program.name('mycli').version('1.0.0');
const db = program.command('database').alias('db').description('Database ops');
db.command('migrate')
.alias('m')
.description('Run migrations')
.action(() => {
console.log('Running migrations...');
});
db.command('seed')
.alias('s')
.description('Seed database')
.action(() => {
console.log('Seeding...');
});
program.parse();
```
Usage (all equivalent):
```bash
mycli database migrate
mycli db migrate
mycli db m
mycli database seed
mycli db seed
mycli db s
```
## Complete CLI Example
```typescript
#!/usr/bin/env node
import { Command } from 'commander';
import chalk from 'chalk';
const program = new Command();
program
.name('project-cli')
.version('1.0.0')
.description('Project management CLI');
// Project commands
const project = program.command('project').alias('p').description('Project operations');
project
.command('init <name>')
.description('Initialize new project')
.option('-t, --template <type>', 'template', 'basic')
.action((name, options) => {
console.log(chalk.green(`✓ Initialized ${name} with ${options.template} template`));
});
project
.command('build')
.description('Build project')
.action(() => {
console.log(chalk.blue('Building...'));
});
// Environment commands
const env = program.command('env').alias('e').description('Environment management');
env
.command('list')
.alias('ls')
.description('List environments')
.action(() => {
console.log('dev, staging, prod');
});
env
.command('create <name>')
.description('Create environment')
.action((name) => {
console.log(chalk.green(`✓ Created environment: ${name}`));
});
// Deploy commands
const deploy = program.command('deploy').alias('d').description('Deployment operations');
deploy
.command('start <env>')
.description('Start deployment')
.action((env) => {
console.log(chalk.blue(`Deploying to ${env}...`));
});
deploy
.command('status [env]')
.description('Check status')
.action((env) => {
console.log(`Status of ${env || 'all'}:`);
});
program.parse();
```
Usage:
```bash
project-cli project init my-app --template advanced
project-cli p build
project-cli env list
project-cli e create staging
project-cli deploy start prod
project-cli d status
```

View File

@@ -0,0 +1,406 @@
# Commander.js Options and Arguments Demo
Comprehensive examples of option and argument patterns.
## Option Patterns
### 1. Boolean Flags
```typescript
program
.command('build')
.option('-w, --watch', 'watch for changes')
.option('-m, --minify', 'minify output')
.option('-v, --verbose', 'verbose logging')
.action((options) => {
console.log('Watch:', options.watch); // true or undefined
console.log('Minify:', options.minify);
console.log('Verbose:', options.verbose);
});
```
Usage:
```bash
mycli build --watch --minify
```
### 2. Options with Required Values
```typescript
program
.command('deploy')
.option('-e, --env <environment>', 'deployment environment')
.option('-r, --region <region>', 'AWS region')
.action((options) => {
console.log('Environment:', options.env);
console.log('Region:', options.region);
});
```
Usage:
```bash
mycli deploy --env production --region us-west-2
```
### 3. Options with Optional Values
```typescript
program
.command('log')
.option('-f, --file [path]', 'log file path')
.action((options) => {
if (options.file === true) {
console.log('Using default log file');
} else if (options.file) {
console.log('Log file:', options.file);
}
});
```
Usage:
```bash
mycli log --file # file = true
mycli log --file custom.log # file = 'custom.log'
mycli log # file = undefined
```
### 4. Options with Defaults
```typescript
program
.command('serve')
.option('-p, --port <port>', 'port number', '3000')
.option('-h, --host <host>', 'hostname', 'localhost')
.action((options) => {
console.log(`http://${options.host}:${options.port}`);
});
```
Usage:
```bash
mycli serve # Uses defaults
mycli serve --port 8080 # Custom port
```
### 5. Negatable Options
```typescript
program
.command('build')
.option('--cache', 'enable cache')
.option('--no-cache', 'disable cache')
.option('--color', 'enable colors')
.option('--no-color', 'disable colors')
.action((options) => {
console.log('Cache:', options.cache); // undefined, true, or false
console.log('Color:', options.color);
});
```
Usage:
```bash
mycli build # cache & color = undefined
mycli build --cache # cache = true
mycli build --no-cache # cache = false
mycli build --no-color # color = false
```
### 6. Variadic Options
```typescript
program
.command('tag')
.option('-t, --tags <tags...>', 'multiple tags')
.action((options) => {
console.log('Tags:', options.tags); // Array
});
```
Usage:
```bash
mycli tag --tags v1.0 production stable
# Tags: ['v1.0', 'production', 'stable']
```
### 7. Options with Custom Parsers
```typescript
program
.command('scale')
.option('-r, --replicas <count>', 'replica count', parseInt)
.option('-m, --memory <mb>', 'memory in MB', parseFloat)
.option('-t, --timeout <sec>', 'timeout', (value) => {
return parseInt(value) * 1000; // Convert to ms
})
.action((options) => {
console.log('Replicas:', options.replicas); // Number
console.log('Memory:', options.memory); // Number
console.log('Timeout:', options.timeout); // Number (ms)
});
```
Usage:
```bash
mycli scale --replicas 5 --memory 512.5 --timeout 30
```
## Argument Patterns
### 1. Required Arguments
```typescript
program
.command('deploy <environment>')
.description('Deploy to environment')
.action((environment) => {
console.log('Deploying to:', environment);
});
```
Usage:
```bash
mycli deploy production # ✓ Works
mycli deploy # ✗ Error: missing required argument
```
### 2. Optional Arguments
```typescript
program
.command('create <name> [description]')
.description('Create item')
.action((name, description) => {
console.log('Name:', name);
console.log('Description:', description || 'No description');
});
```
Usage:
```bash
mycli create "My Item"
mycli create "My Item" "A detailed description"
```
### 3. Variadic Arguments
```typescript
program
.command('add <items...>')
.description('Add multiple items')
.action((items) => {
console.log('Items:', items); // Array
items.forEach((item, i) => {
console.log(` ${i + 1}. ${item}`);
});
});
```
Usage:
```bash
mycli add item1 item2 item3
# Items: ['item1', 'item2', 'item3']
```
### 4. Mixed Required and Optional
```typescript
program
.command('copy <source> <destination> [options]')
.description('Copy files')
.action((source, destination, options) => {
console.log('Source:', source);
console.log('Destination:', destination);
console.log('Options:', options || 'none');
});
```
### 5. Arguments with Descriptions
```typescript
program
.command('deploy <environment>')
.argument('<environment>', 'target environment (dev, staging, prod)')
.argument('[region]', 'deployment region', 'us-east-1')
.action((environment, region) => {
console.log(`Deploying to ${environment} in ${region}`);
});
```
### 6. Arguments with Custom Parsers
```typescript
program
.command('wait <seconds>')
.argument('<seconds>', 'seconds to wait', parseFloat)
.action(async (seconds) => {
console.log(`Waiting ${seconds} seconds...`);
await new Promise((resolve) => setTimeout(resolve, seconds * 1000));
console.log('Done!');
});
```
Usage:
```bash
mycli wait 2.5 # Waits 2.5 seconds
```
### 7. Arguments with Validation
```typescript
program
.command('set-port <port>')
.argument('<port>', 'port number', (value) => {
const port = parseInt(value, 10);
if (isNaN(port)) {
throw new Error('Port must be a number');
}
if (port < 1 || port > 65535) {
throw new Error('Port must be between 1 and 65535');
}
return port;
})
.action((port) => {
console.log('Port set to:', port);
});
```
## Combined Patterns
### Arguments + Options
```typescript
program
.command('deploy <environment>')
.argument('<environment>', 'deployment environment')
.option('-f, --force', 'force deployment')
.option('-d, --dry-run', 'simulate deployment')
.option('-t, --tag <tag>', 'deployment tag', 'latest')
.action((environment, options) => {
console.log('Environment:', environment);
console.log('Force:', options.force);
console.log('Dry run:', options.dryRun);
console.log('Tag:', options.tag);
});
```
Usage:
```bash
mycli deploy production --force --tag v1.2.3
```
### Variadic Arguments + Options
```typescript
program
.command('compile <files...>')
.argument('<files...>', 'files to compile')
.option('-o, --output <dir>', 'output directory', './dist')
.option('-m, --minify', 'minify output')
.action((files, options) => {
console.log('Files:', files);
console.log('Output:', options.output);
console.log('Minify:', options.minify);
});
```
Usage:
```bash
mycli compile src/a.ts src/b.ts --output build --minify
```
### Multiple Option Types
```typescript
program
.command('start')
.option('-p, --port <port>', 'port', '3000')
.option('-h, --host <host>', 'host', 'localhost')
.option('-o, --open', 'open browser')
.option('--no-color', 'disable colors')
.option('-e, --env <vars...>', 'environment variables')
.action((options) => {
console.log('Server:', `http://${options.host}:${options.port}`);
console.log('Open:', options.open);
console.log('Color:', options.color);
console.log('Env:', options.env);
});
```
Usage:
```bash
mycli start --port 8080 --open --env NODE_ENV=production DEBUG=true
```
## Complete Example
```typescript
#!/usr/bin/env node
import { Command } from 'commander';
import chalk from 'chalk';
const program = new Command();
program.name('deploy-cli').version('1.0.0');
program
.command('deploy <environment> [region]')
.description('Deploy application')
.argument('<environment>', 'target environment (dev, staging, prod)')
.argument('[region]', 'deployment region', 'us-east-1')
.option('-f, --force', 'skip confirmations', false)
.option('-d, --dry-run', 'simulate deployment', false)
.option('-t, --tag <tag>', 'deployment tag', 'latest')
.option('-r, --replicas <count>', 'replica count', parseInt, 3)
.option('--env <vars...>', 'environment variables')
.option('--no-rollback', 'disable auto-rollback')
.action((environment, region, options) => {
console.log(chalk.blue('Deployment Configuration:'));
console.log('Environment:', chalk.yellow(environment));
console.log('Region:', region);
console.log('Tag:', options.tag);
console.log('Replicas:', options.replicas);
console.log('Force:', options.force);
console.log('Dry run:', options.dryRun);
console.log('Rollback:', options.rollback);
if (options.env) {
console.log('Environment variables:');
options.env.forEach((v) => console.log(` ${v}`));
}
if (options.dryRun) {
console.log(chalk.yellow('\n🔍 Dry run - no actual deployment'));
return;
}
console.log(chalk.green('\n✓ Deployment complete!'));
});
program.parse();
```
Usage examples:
```bash
# Basic
deploy-cli deploy production
# With region
deploy-cli deploy staging us-west-2
# With options
deploy-cli deploy prod --force --replicas 5
# With environment variables
deploy-cli deploy prod --env NODE_ENV=production API_KEY=xyz
# Dry run
deploy-cli deploy prod --dry-run --no-rollback
# All together
deploy-cli deploy production us-west-2 \
--force \
--tag v2.0.0 \
--replicas 10 \
--env NODE_ENV=production DEBUG=false \
--no-rollback
```