Skip to content

Commit 845a614

Browse files
authored
More CLI improvements (#52)
* feat: add core functionality for vulnerability analysis and fix planning - Implemented configuration loading with environment variable support. - Added constants for GitHub API and default settings. - Created fix planner to generate actionable plans for vulnerabilities. - Developed GitHub service for interacting with GitHub repositories. - Introduced progress tracking for CLI operations. - Defined types for dependencies, vulnerabilities, and analysis results. - Added utility functions for formatting analysis and fix plan outputs. - Created a test API for validating programmatic interactions. - Configured TypeScript settings for building and type declarations. * vercelignore * feat: add GitHub Actions workflow for publishing CLI to npm * refactor: improve code formatting and consistency across multiple files - Standardized indentation and spacing in GitHubService and CLIProgress classes. - Enhanced error handling and response formatting in GitHubService methods. - Updated progress reporting in CLIProgress to improve clarity and verbosity. - Refined type definitions in types.ts for better readability and consistency. - Enhanced output formatting in formatters.ts for vulnerability reports and fix plans. - Improved test-api.ts output formatting for better readability during tests.
1 parent 2820aa0 commit 845a614

15 files changed

Lines changed: 1703 additions & 1564 deletions

File tree

packages/cli/.gitdepsecrc

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"github_token": "",
3+
"include_transitive": true,
4+
"output_format": "table"
5+
}

packages/cli/README.md

Lines changed: 33 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -110,41 +110,41 @@ export GDS_OUTPUT_FORMAT=table
110110

111111
## Commands
112112

113-
| Command | Description |
114-
|---------|-------------|
115-
| `gds analyse` | Analyze dependencies for vulnerabilities |
116-
| `gds fix` | Generate fix recommendations |
117-
| `gds init` | Create configuration file |
118-
| `gds --version` | Show version |
119-
| `gds --help` | Show help |
113+
| Command | Description |
114+
| --------------- | ---------------------------------------- |
115+
| `gds analyse` | Analyze dependencies for vulnerabilities |
116+
| `gds fix` | Generate fix recommendations |
117+
| `gds init` | Create configuration file |
118+
| `gds --version` | Show version |
119+
| `gds --help` | Show help |
120120

121121
## CLI Options Reference
122122

123123
### `gds analyse`
124124

125-
| Option | Description |
126-
|--------|-------------|
127-
| `-f, --file <files...>` | Manifest file(s) to analyze |
128-
| `-r, --repo <repo>` | GitHub repository in `owner/repo` format |
129-
| `-b, --branch <branch>` | Branch to analyze |
130-
| `-t, --token <token>` | GitHub personal access token |
131-
| `--no-transitive` | Disable transitive dependency scanning |
132-
| `--format <format>` | Output format: `table`, `json`, `markdown` |
133-
| `-o, --output <file>` | Save output to file |
134-
| `-q, --quiet` | Minimal output |
135-
| `-v, --verbose` | Verbose output |
125+
| Option | Description |
126+
| ----------------------- | ------------------------------------------ |
127+
| `-f, --file <files...>` | Manifest file(s) to analyze |
128+
| `-r, --repo <repo>` | GitHub repository in `owner/repo` format |
129+
| `-b, --branch <branch>` | Branch to analyze |
130+
| `-t, --token <token>` | GitHub personal access token |
131+
| `--no-transitive` | Disable transitive dependency scanning |
132+
| `--format <format>` | Output format: `table`, `json`, `markdown` |
133+
| `-o, --output <file>` | Save output to file |
134+
| `-q, --quiet` | Minimal output |
135+
| `-v, --verbose` | Verbose output |
136136

137137
### `gds fix`
138138

139-
| Option | Description |
140-
|--------|-------------|
141-
| `-f, --file <files...>` | Manifest file(s) to generate fixes for |
142-
| `-r, --repo <repo>` | GitHub repository in `owner/repo` format |
143-
| `-b, --branch <branch>` | Branch to analyze |
144-
| `-t, --token <token>` | GitHub personal access token |
145-
| `--no-transitive` | Disable transitive dependency scanning |
146-
| `--format <format>` | Output format: `table`, `json`, `markdown` |
147-
| `-o, --output <file>` | Save output to file |
139+
| Option | Description |
140+
| ----------------------- | ------------------------------------------ |
141+
| `-f, --file <files...>` | Manifest file(s) to generate fixes for |
142+
| `-r, --repo <repo>` | GitHub repository in `owner/repo` format |
143+
| `-b, --branch <branch>` | Branch to analyze |
144+
| `-t, --token <token>` | GitHub personal access token |
145+
| `--no-transitive` | Disable transitive dependency scanning |
146+
| `--format <format>` | Output format: `table`, `json`, `markdown` |
147+
| `-o, --output <file>` | Save output to file |
148148

149149
## Supported Ecosystems
150150

@@ -159,13 +159,14 @@ export GDS_OUTPUT_FORMAT=table
159159

160160
For `gds analyse`:
161161

162-
| Code | Description |
163-
|------|-------------|
164-
| 0 | Success, no vulnerabilities found |
165-
| 1 | Vulnerabilities found |
166-
| 2 | Error during analysis |
162+
| Code | Description |
163+
| ---- | --------------------------------- |
164+
| 0 | Success, no vulnerabilities found |
165+
| 1 | Vulnerabilities found |
166+
| 2 | Error during analysis |
167167

168168
For `gds fix`:
169+
169170
- `0`: Fix plan generated
170171
- `2`: Error during fix plan generation
171172

packages/cli/src/cli.ts

Lines changed: 99 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,56 +1,121 @@
11
#!/usr/bin/env node
22

3-
import { Command } from "commander";
3+
import { Command, Option } from "commander";
44
import chalk from "chalk";
55
import { analyseCommand } from "./commands/analyse.js";
66
import { fixCommand } from "./commands/fix.js";
77
import { initCommand } from "./commands/init.js";
88

99
const program = new Command();
1010

11+
// Custom help formatting
12+
const formatOption = new Option("--format <format>", "Output format")
13+
.choices(["table", "json", "markdown"])
14+
.default("table");
15+
1116
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+
`);
1844

1945
// Analyse command
2046
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);
3481

3582
// Fix command
3683
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);
47101

48102
// Init command
49103
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);
54119

55120
// Parse arguments
56121
program.parse();

0 commit comments

Comments
 (0)