|
1 | 1 | #!/usr/bin/env node |
2 | 2 |
|
3 | | -import { Command } from "commander"; |
| 3 | +import { Command, Option } from "commander"; |
4 | 4 | import chalk from "chalk"; |
5 | 5 | import { analyseCommand } from "./commands/analyse.js"; |
6 | 6 | import { fixCommand } from "./commands/fix.js"; |
7 | 7 | import { initCommand } from "./commands/init.js"; |
8 | 8 |
|
9 | 9 | const program = new Command(); |
10 | 10 |
|
| 11 | +// Custom help formatting |
| 12 | +const formatOption = new Option("--format <format>", "Output format") |
| 13 | + .choices(["table", "json", "markdown"]) |
| 14 | + .default("table"); |
| 15 | + |
11 | 16 | program |
12 | | - .name("gds") |
13 | | - .description( |
14 | | - chalk.bold("GitDepSec") + |
15 | | - " - Analyze dependency vulnerabilities in your projects" |
16 | | - ) |
17 | | - .version("1.0.0"); |
| 17 | + .name("gds") |
| 18 | + .description( |
| 19 | + chalk.bold("GitDepSec") + |
| 20 | + " - Analyze dependency vulnerabilities in your projects\n\n" + |
| 21 | + chalk.dim("Supported ecosystems: npm, pypi, maven, go, cargo, nuget, composer") |
| 22 | + ) |
| 23 | + .version("1.0.0") |
| 24 | + .addHelpText("after", ` |
| 25 | +${chalk.bold("Examples:")} |
| 26 | + ${chalk.dim("# Scan current directory (analyse, analyze, audit all work)")} |
| 27 | + $ gds audit |
| 28 | +
|
| 29 | + ${chalk.dim("# Scan specific files")} |
| 30 | + $ gds analyse -f package.json requirements.txt |
| 31 | +
|
| 32 | + ${chalk.dim("# Scan a GitHub repository")} |
| 33 | + $ gds analyze -r owner/repo -b main |
| 34 | +
|
| 35 | + ${chalk.dim("# Export results as JSON")} |
| 36 | + $ gds audit --format json -o report.json |
| 37 | +
|
| 38 | + ${chalk.dim("# Generate fix plan")} |
| 39 | + $ gds fix -f package.json |
| 40 | +
|
| 41 | +${chalk.bold("Documentation:")} |
| 42 | + ${chalk.cyan("https://github.com/viralcodex/gitdepsec#readme")} |
| 43 | +`); |
18 | 44 |
|
19 | 45 | // Analyse command |
20 | 46 | program |
21 | | - .command("analyse") |
22 | | - .alias("analyze") |
23 | | - .description("Analyze dependencies for vulnerabilities") |
24 | | - .option("-f, --file <files...>", "Manifest file(s) to analyze") |
25 | | - .option("-r, --repo <repo>", "GitHub repository (owner/repo)") |
26 | | - .option("-b, --branch <branch>", "Branch to analyze (default: main)") |
27 | | - .option("-t, --token <token>", "GitHub personal access token") |
28 | | - .option("--no-transitive", "Disable transitive dependency scanning") |
29 | | - .option("--format <format>", "Output format: table, json, markdown", "table") |
30 | | - .option("-o, --output <file>", "Save output to file") |
31 | | - .option("-q, --quiet", "Minimal output") |
32 | | - .option("-v, --verbose", "Verbose output") |
33 | | - .action(analyseCommand); |
| 47 | + .command("analyse") |
| 48 | + .aliases(["analyze", "audit"]) |
| 49 | + .description("Analyze dependencies for vulnerabilities") |
| 50 | + .option("-f, --file <files...>", "Manifest file(s) to analyze (e.g., package.json, requirements.txt)") |
| 51 | + .option("-r, --repo <repo>", "GitHub repository in owner/repo format") |
| 52 | + .option("-b, --branch <branch>", "Branch to analyze", "main") |
| 53 | + .option("-t, --token <token>", "GitHub personal access token (or set GITHUB_TOKEN env)") |
| 54 | + .option("--transitive", "Enable transitive dependency scanning", true) |
| 55 | + .option("--no-transitive", "Disable transitive dependency scanning") |
| 56 | + .addOption(formatOption) |
| 57 | + .option("-o, --output <file>", "Save output to file (e.g., report.json)") |
| 58 | + .option("-q, --quiet", "Minimal output - only show summary") |
| 59 | + .option("-v, --verbose", "Verbose output - show detailed progress") |
| 60 | + .addHelpText("after", ` |
| 61 | +${chalk.bold("Aliases:")} analyse, analyze, audit |
| 62 | +
|
| 63 | +${chalk.bold("Supported Manifest Files:")} |
| 64 | + ${chalk.cyan("npm")} package.json, package-lock.json |
| 65 | + ${chalk.cyan("pypi")} requirements.txt, Pipfile, pyproject.toml |
| 66 | + ${chalk.cyan("maven")} pom.xml |
| 67 | + ${chalk.cyan("go")} go.mod |
| 68 | + ${chalk.cyan("cargo")} Cargo.toml |
| 69 | + ${chalk.cyan("nuget")} packages.config, *.csproj |
| 70 | + ${chalk.cyan("composer")} composer.json |
| 71 | +
|
| 72 | +${chalk.bold("Examples:")} |
| 73 | + $ gds audit ${chalk.dim("# Scan current directory")} |
| 74 | + $ gds analyse -f package.json ${chalk.dim("# Scan specific file")} |
| 75 | + $ gds analyze -r facebook/react ${chalk.dim("# Scan GitHub repo")} |
| 76 | + $ gds audit --format json -o out.json ${chalk.dim("# Export as JSON")} |
| 77 | + $ gds analyse --format markdown ${chalk.dim("# Output as markdown")} |
| 78 | + $ gds analyse --no-transitive ${chalk.dim("# Skip transitive deps")} |
| 79 | +`) |
| 80 | + .action(analyseCommand); |
34 | 81 |
|
35 | 82 | // Fix command |
36 | 83 | program |
37 | | - .command("fix") |
38 | | - .description("Generate fix recommendations for vulnerabilities") |
39 | | - .option("-f, --file <files...>", "Manifest file(s) to fix") |
40 | | - .option("-r, --repo <repo>", "GitHub repository (owner/repo)") |
41 | | - .option("-b, --branch <branch>", "Branch to analyze (default: main)") |
42 | | - .option("-t, --token <token>", "GitHub personal access token") |
43 | | - .option("--no-transitive", "Disable transitive dependency scanning") |
44 | | - .option("--format <format>", "Output format: table, json, markdown", "table") |
45 | | - .option("-o, --output <file>", "Save output to file") |
46 | | - .action(fixCommand); |
| 84 | + .command("fix") |
| 85 | + .description("Generate fix recommendations for vulnerabilities") |
| 86 | + .option("-f, --file <files...>", "Manifest file(s) to fix (e.g., package.json)") |
| 87 | + .option("-r, --repo <repo>", "GitHub repository in owner/repo format") |
| 88 | + .option("-b, --branch <branch>", "Branch to analyze", "main") |
| 89 | + .option("-t, --token <token>", "GitHub personal access token (or set GITHUB_TOKEN env)") |
| 90 | + .option("--transitive", "Enable transitive dependency scanning", true) |
| 91 | + .option("--no-transitive", "Disable transitive dependency scanning") |
| 92 | + .addOption(formatOption) |
| 93 | + .option("-o, --output <file>", "Save output to file") |
| 94 | + .addHelpText("after", ` |
| 95 | +${chalk.bold("Examples:")} |
| 96 | + $ gds fix ${chalk.dim("# Generate fix plan for current dir")} |
| 97 | + $ gds fix -f package.json ${chalk.dim("# Fix specific file")} |
| 98 | + $ gds fix --format markdown -o fixes.md ${chalk.dim("# Export as markdown")} |
| 99 | +`) |
| 100 | + .action(fixCommand); |
47 | 101 |
|
48 | 102 | // Init command |
49 | 103 | program |
50 | | - .command("init") |
51 | | - .description("Create a .gitdepsecrc configuration file") |
52 | | - .option("--force", "Overwrite existing config") |
53 | | - .action(initCommand); |
| 104 | + .command("init") |
| 105 | + .description("Create a .gitdepsecrc configuration file") |
| 106 | + .option("--force", "Overwrite existing config file") |
| 107 | + .addHelpText("after", ` |
| 108 | +${chalk.bold("Examples:")} |
| 109 | + $ gds init ${chalk.dim("# Create config interactively")} |
| 110 | + $ gds init --force ${chalk.dim("# Overwrite existing config")} |
| 111 | +
|
| 112 | +${chalk.bold("Config File Options:")} |
| 113 | + ${chalk.cyan("github_token")} GitHub personal access token |
| 114 | + ${chalk.cyan("default_branch")} Default branch to analyze |
| 115 | + ${chalk.cyan("format")} Default output format (table|json|markdown) |
| 116 | + ${chalk.cyan("transitive")} Enable transitive scanning (true|false) |
| 117 | +`) |
| 118 | + .action(initCommand); |
54 | 119 |
|
55 | 120 | // Parse arguments |
56 | 121 | program.parse(); |
0 commit comments