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,67 @@
#!/bin/bash
# Extract help text from Commander.js CLI for documentation
set -euo pipefail
CLI_COMMAND="${1:?Usage: $0 <cli-command> [output-file]}"
OUTPUT_FILE="${2:-docs/CLI-REFERENCE.md}"
echo "📚 Extracting help documentation from: $CLI_COMMAND"
# Create output directory
mkdir -p "$(dirname "$OUTPUT_FILE")"
# Start markdown file
cat > "$OUTPUT_FILE" << EOF
# CLI Reference
Auto-generated documentation for $CLI_COMMAND
---
## Main Command
\`\`\`
EOF
# Get main help
$CLI_COMMAND --help >> "$OUTPUT_FILE" || true
cat >> "$OUTPUT_FILE" << 'EOF'
```
---
## Commands
EOF
# Extract all commands
COMMANDS=$($CLI_COMMAND --help | grep -A 100 "Commands:" | tail -n +2 | awk '{print $1}' | grep -v "^$" || echo "")
if [[ -n "$COMMANDS" ]]; then
for cmd in $COMMANDS; do
echo "### \`$cmd\`" >> "$OUTPUT_FILE"
echo "" >> "$OUTPUT_FILE"
echo "\`\`\`" >> "$OUTPUT_FILE"
$CLI_COMMAND $cmd --help >> "$OUTPUT_FILE" 2>&1 || true
echo "\`\`\`" >> "$OUTPUT_FILE"
echo "" >> "$OUTPUT_FILE"
done
else
echo "No subcommands found." >> "$OUTPUT_FILE"
fi
cat >> "$OUTPUT_FILE" << EOF
---
*Generated: $(date)*
*CLI Version: $($CLI_COMMAND --version 2>/dev/null || echo "unknown")*
EOF
echo "✅ Documentation generated: $OUTPUT_FILE"
echo ""
echo "Preview:"
head -n 20 "$OUTPUT_FILE"
echo "..."

View File

@@ -0,0 +1,59 @@
#!/bin/bash
# Generate Commander.js command with options and arguments
set -euo pipefail
COMMAND_NAME="${1:?Usage: $0 <command-name> [output-file]}"
OUTPUT_FILE="${2:-src/commands/${COMMAND_NAME}.ts}"
# Create output directory
mkdir -p "$(dirname "$OUTPUT_FILE")"
echo "📝 Generating Commander.js command: $COMMAND_NAME"
cat > "$OUTPUT_FILE" << 'EOF'
import { Command, Option } from 'commander';
import chalk from 'chalk';
export function create{{COMMAND_NAME_PASCAL}}Command(): Command {
const command = new Command('{{COMMAND_NAME}}')
.description('{{DESCRIPTION}}')
.option('-v, --verbose', 'verbose output', false)
.addOption(
new Option('-e, --environment <env>', 'target environment')
.choices(['dev', 'staging', 'prod'])
.default('dev')
)
.action(async (options) => {
try {
console.log(chalk.blue(`Running {{COMMAND_NAME}} command...`));
console.log('Options:', options);
// TODO: Implement command logic
console.log(chalk.green('✓ Command completed successfully'));
} catch (error) {
console.error(chalk.red('✗ Command failed:'), error.message);
process.exit(1);
}
});
return command;
}
EOF
# Convert command name to PascalCase
COMMAND_NAME_PASCAL=$(echo "$COMMAND_NAME" | sed -r 's/(^|-)([a-z])/\U\2/g')
# Replace placeholders
sed -i "s/{{COMMAND_NAME}}/$COMMAND_NAME/g" "$OUTPUT_FILE"
sed -i "s/{{COMMAND_NAME_PASCAL}}/$COMMAND_NAME_PASCAL/g" "$OUTPUT_FILE"
sed -i "s/{{DESCRIPTION}}/Execute $COMMAND_NAME operation/g" "$OUTPUT_FILE"
echo "✅ Command generated: $OUTPUT_FILE"
echo ""
echo "Next steps:"
echo " 1. Implement command logic in the action handler"
echo " 2. Add custom options and arguments as needed"
echo " 3. Import and add to main CLI: program.addCommand(create${COMMAND_NAME_PASCAL}Command())"
echo ""

View File

@@ -0,0 +1,75 @@
#!/bin/bash
# Generate nested subcommand structure for Commander.js
set -euo pipefail
PARENT_COMMAND="${1:?Usage: $0 <parent-command> <subcommand> [output-file]}"
SUBCOMMAND="${2:?Usage: $0 <parent-command> <subcommand> [output-file]}"
OUTPUT_FILE="${3:-src/commands/${PARENT_COMMAND}/${SUBCOMMAND}.ts}"
# Create output directory
mkdir -p "$(dirname "$OUTPUT_FILE")"
echo "📝 Generating subcommand: $PARENT_COMMAND $SUBCOMMAND"
cat > "$OUTPUT_FILE" << 'EOF'
import { Command } from 'commander';
import chalk from 'chalk';
export function create{{SUBCOMMAND_PASCAL}}Command(): Command {
const command = new Command('{{SUBCOMMAND}}')
.description('{{DESCRIPTION}}')
.action(async (options) => {
try {
console.log(chalk.blue(`Running {{PARENT_COMMAND}} {{SUBCOMMAND}}...`));
// TODO: Implement subcommand logic
console.log(chalk.green('✓ Subcommand completed'));
} catch (error) {
console.error(chalk.red('✗ Subcommand failed:'), error.message);
process.exit(1);
}
});
return command;
}
EOF
# Convert to PascalCase
SUBCOMMAND_PASCAL=$(echo "$SUBCOMMAND" | sed -r 's/(^|-)([a-z])/\U\2/g')
# Replace placeholders
sed -i "s/{{PARENT_COMMAND}}/$PARENT_COMMAND/g" "$OUTPUT_FILE"
sed -i "s/{{SUBCOMMAND}}/$SUBCOMMAND/g" "$OUTPUT_FILE"
sed -i "s/{{SUBCOMMAND_PASCAL}}/$SUBCOMMAND_PASCAL/g" "$OUTPUT_FILE"
sed -i "s/{{DESCRIPTION}}/$SUBCOMMAND operation for $PARENT_COMMAND/g" "$OUTPUT_FILE"
# Generate parent command file if it doesn't exist
PARENT_FILE="src/commands/${PARENT_COMMAND}/index.ts"
if [[ ! -f "$PARENT_FILE" ]]; then
mkdir -p "$(dirname "$PARENT_FILE")"
cat > "$PARENT_FILE" << EOF
import { Command } from 'commander';
import { create${SUBCOMMAND_PASCAL}Command } from './${SUBCOMMAND}';
export function create${PARENT_COMMAND^}Command(): Command {
const command = new Command('${PARENT_COMMAND}')
.description('${PARENT_COMMAND^} operations');
// Add subcommands
command.addCommand(create${SUBCOMMAND_PASCAL}Command());
return command;
}
EOF
echo "✅ Created parent command: $PARENT_FILE"
fi
echo "✅ Subcommand generated: $OUTPUT_FILE"
echo ""
echo "Next steps:"
echo " 1. Implement subcommand logic"
echo " 2. Add to parent command: ${PARENT_FILE}"
echo " 3. Import parent in main CLI: program.addCommand(create${PARENT_COMMAND^}Command())"
echo ""

View File

@@ -0,0 +1,83 @@
#!/bin/bash
# Test Commander.js CLI with various inputs
set -euo pipefail
CLI_COMMAND="${1:?Usage: $0 <cli-command> [test-suite]}"
TEST_SUITE="${2:-basic}"
echo "🧪 Testing Commander.js CLI: $CLI_COMMAND"
echo "Test suite: $TEST_SUITE"
echo ""
PASSED=0
FAILED=0
# Helper function to run test
run_test() {
local test_name="$1"
local test_command="$2"
local expected_exit_code="${3:-0}"
echo -n "Testing: $test_name ... "
if eval "$test_command" > /dev/null 2>&1; then
actual_exit_code=0
else
actual_exit_code=$?
fi
if [[ $actual_exit_code -eq $expected_exit_code ]]; then
echo "✅ PASS"
((PASSED++))
else
echo "❌ FAIL (expected exit code $expected_exit_code, got $actual_exit_code)"
((FAILED++))
fi
}
# Basic tests
if [[ "$TEST_SUITE" == "basic" || "$TEST_SUITE" == "all" ]]; then
echo "Running basic tests..."
run_test "Help flag" "$CLI_COMMAND --help" 0
run_test "Version flag" "$CLI_COMMAND --version" 0
run_test "No arguments" "$CLI_COMMAND" 1
fi
# Command tests
if [[ "$TEST_SUITE" == "commands" || "$TEST_SUITE" == "all" ]]; then
echo ""
echo "Running command tests..."
run_test "List commands" "$CLI_COMMAND --help | grep -q 'Commands:'" 0
fi
# Option tests
if [[ "$TEST_SUITE" == "options" || "$TEST_SUITE" == "all" ]]; then
echo ""
echo "Running option tests..."
run_test "Unknown option" "$CLI_COMMAND --unknown-option" 1
run_test "Short flag" "$CLI_COMMAND -v" 0
run_test "Long flag" "$CLI_COMMAND --verbose" 0
fi
# Argument tests
if [[ "$TEST_SUITE" == "arguments" || "$TEST_SUITE" == "all" ]]; then
echo ""
echo "Running argument tests..."
run_test "Required argument missing" "$CLI_COMMAND deploy" 1
run_test "Required argument provided" "$CLI_COMMAND deploy production" 0
fi
echo ""
echo "Test Results:"
echo " Passed: $PASSED"
echo " Failed: $FAILED"
echo ""
if [[ $FAILED -gt 0 ]]; then
echo "❌ Some tests failed"
exit 1
else
echo "✅ All tests passed!"
exit 0
fi

View File

@@ -0,0 +1,139 @@
#!/bin/bash
# Validate Commander.js CLI structure and patterns
set -euo pipefail
CLI_FILE="${1:?Usage: $0 <cli-file.ts|js>}"
if [[ ! -f "$CLI_FILE" ]]; then
echo "Error: File not found: $CLI_FILE"
exit 1
fi
echo "🔍 Validating Commander.js CLI structure: $CLI_FILE"
echo ""
ERRORS=0
WARNINGS=0
# Check for Commander import
if grep -q "from 'commander'" "$CLI_FILE" || grep -q 'require("commander")' "$CLI_FILE"; then
echo "✅ Commander.js import found"
else
echo "❌ Missing Commander.js import"
((ERRORS++))
fi
# Check for Command instantiation
if grep -q "new Command()" "$CLI_FILE" || grep -q "= program" "$CLI_FILE"; then
echo "✅ Command instance created"
else
echo "❌ No Command instance found"
((ERRORS++))
fi
# Check for program.parse()
if grep -q "\.parse()" "$CLI_FILE"; then
echo "✅ program.parse() called"
else
echo "❌ Missing program.parse() call"
((ERRORS++))
fi
# Check for .name()
if grep -q "\.name(" "$CLI_FILE"; then
echo "✅ CLI name defined"
else
echo "⚠️ CLI name not set (recommended)"
((WARNINGS++))
fi
# Check for .description()
if grep -q "\.description(" "$CLI_FILE"; then
echo "✅ CLI description defined"
else
echo "⚠️ CLI description not set (recommended)"
((WARNINGS++))
fi
# Check for .version()
if grep -q "\.version(" "$CLI_FILE"; then
echo "✅ CLI version defined"
else
echo "⚠️ CLI version not set (recommended)"
((WARNINGS++))
fi
# Check for commands
COMMAND_COUNT=$(grep -c "\.command(" "$CLI_FILE" || echo "0")
if [[ $COMMAND_COUNT -gt 0 ]]; then
echo "✅ Found $COMMAND_COUNT command(s)"
else
echo "⚠️ No commands defined"
((WARNINGS++))
fi
# Check for action handlers
ACTION_COUNT=$(grep -c "\.action(" "$CLI_FILE" || echo "0")
if [[ $ACTION_COUNT -gt 0 ]]; then
echo "✅ Found $ACTION_COUNT action handler(s)"
else
echo "⚠️ No action handlers defined"
((WARNINGS++))
fi
# Check for options
OPTION_COUNT=$(grep -c "\.option(" "$CLI_FILE" || echo "0")
ADDOPTION_COUNT=$(grep -c "\.addOption(" "$CLI_FILE" || echo "0")
TOTAL_OPTIONS=$((OPTION_COUNT + ADDOPTION_COUNT))
if [[ $TOTAL_OPTIONS -gt 0 ]]; then
echo "✅ Found $TOTAL_OPTIONS option(s)"
else
echo "⚠️ No options defined"
((WARNINGS++))
fi
# Check for arguments
ARGUMENT_COUNT=$(grep -c "\.argument(" "$CLI_FILE" || echo "0")
if [[ $ARGUMENT_COUNT -gt 0 ]]; then
echo "✅ Found $ARGUMENT_COUNT argument(s)"
fi
# Check for Option class usage
if grep -q "new Option(" "$CLI_FILE"; then
echo "✅ Option class used (advanced)"
fi
# Check for error handling
if grep -q "try\|catch" "$CLI_FILE" || grep -q "\.exitOverride()" "$CLI_FILE"; then
echo "✅ Error handling present"
else
echo "⚠️ No error handling detected (recommended)"
((WARNINGS++))
fi
# Check for TypeScript
if [[ "$CLI_FILE" == *.ts ]]; then
echo "✅ TypeScript file"
# Check for types
if grep -q "import.*Command.*Option.*from 'commander'" "$CLI_FILE"; then
echo "✅ Proper TypeScript imports"
fi
fi
echo ""
echo "Summary:"
echo " Errors: $ERRORS"
echo " Warnings: $WARNINGS"
echo ""
if [[ $ERRORS -gt 0 ]]; then
echo "❌ Validation failed with $ERRORS error(s)"
exit 1
elif [[ $WARNINGS -gt 0 ]]; then
echo "⚠️ Validation passed with $WARNINGS warning(s)"
exit 0
else
echo "✅ Validation passed - excellent CLI structure!"
exit 0
fi