@herodevs/cli 2.0.0-beta.7 → 2.0.0-beta.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +52 -14
- package/bin/dev.js +1 -1
- package/bin/main.js +1 -1
- package/bin/run.js +1 -1
- package/dist/commands/scan/eol.d.ts +1 -0
- package/dist/commands/scan/eol.js +10 -9
- package/dist/hooks/finally/finally.js +18 -0
- package/dist/hooks/{npm-update-notifier.js → init/00_npm-update-notifier.js} +3 -3
- package/dist/hooks/init/01_initialize_amplitude.d.ts +3 -0
- package/dist/hooks/{prerun.js → init/01_initialize_amplitude.js} +2 -7
- package/dist/hooks/prerun/prerun.js +8 -0
- package/dist/service/display.svc.js +2 -2
- package/package.json +14 -10
- package/dist/hooks/finally.js +0 -14
- /package/dist/hooks/{finally.d.ts → finally/finally.d.ts} +0 -0
- /package/dist/hooks/{npm-update-notifier.d.ts → init/00_npm-update-notifier.d.ts} +0 -0
- /package/dist/hooks/{prerun.d.ts → prerun/prerun.d.ts} +0 -0
package/README.md
CHANGED
|
@@ -10,13 +10,40 @@ The HeroDevs CLI
|
|
|
10
10
|
* [@herodevs/cli](#herodevscli)
|
|
11
11
|
<!-- tocstop -->
|
|
12
12
|
|
|
13
|
-
|
|
13
|
+
### Prerequisites
|
|
14
14
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
15
|
+
- Install node v20 or higher: [Download Node](https://nodejs.org/en/download)
|
|
16
|
+
- The HeroDevs CLI expects that you have all required technology installed for the project that you are running the CLI against
|
|
17
|
+
- For example, if you are running the CLI against a Gradle project, the CLI expects you to have Java installed.
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
### Installation methods
|
|
21
|
+
|
|
22
|
+
#### Node Package Execute (NPX)
|
|
23
|
+
|
|
24
|
+
With Node installed, you can run the CLI directly from the npm registry without installing it globally or locally on your system
|
|
25
|
+
|
|
26
|
+
```sh
|
|
27
|
+
npx @herodevs/cli@beta
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
#### Global NPM Installation
|
|
31
|
+
|
|
32
|
+
```sh
|
|
33
|
+
npm install -g @herodevs/cli@beta
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
#### Binary Installation
|
|
37
|
+
|
|
38
|
+
HeroDevs CLI is available as a binary installation, without requiring `npm`. To do that, you may either download and run the script manually, or use the following cURL or Wget command:
|
|
39
|
+
|
|
40
|
+
```sh
|
|
41
|
+
curl -o- https://raw.githubusercontent.com/herodevs/cli/v2.0.0-beta.9/scripts/install.sh | bash
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
```sh
|
|
45
|
+
wget -qO- https://raw.githubusercontent.com/herodevs/cli/v2.0.0-beta.9/scripts/install.sh | bash
|
|
46
|
+
```
|
|
20
47
|
|
|
21
48
|
## TERMS
|
|
22
49
|
|
|
@@ -26,9 +53,16 @@ Use of this CLI is governed by the [HeroDevs End of Life Dataset Terms of Servic
|
|
|
26
53
|
|
|
27
54
|
The CLI is designed to be non-invasive:
|
|
28
55
|
|
|
29
|
-
* It does not install dependencies or modify package manager files (package-lock.json, yarn.lock, etc.)
|
|
56
|
+
* It does **not** install dependencies or modify package manager files (package-lock.json, yarn.lock, etc.)
|
|
30
57
|
* It analyzes the project in its current state
|
|
31
|
-
|
|
58
|
+
|
|
59
|
+
## Installing Dependencies Before Use
|
|
60
|
+
|
|
61
|
+
Some projects and ecosystems require projects to have dependencies installed already, to achieve an accurate scan result. It is **highly** recommended that you install all dependencies of your project to your working directory, before running a scan on your project, to ensure scan accuracy.
|
|
62
|
+
|
|
63
|
+
### Java Users
|
|
64
|
+
|
|
65
|
+
Maven and Gradle projects should run an install and build before scanning
|
|
32
66
|
|
|
33
67
|
## Usage
|
|
34
68
|
<!-- usage -->
|
|
@@ -37,7 +71,7 @@ $ npm install -g @herodevs/cli@beta
|
|
|
37
71
|
$ hd COMMAND
|
|
38
72
|
running command...
|
|
39
73
|
$ hd (--version)
|
|
40
|
-
@herodevs/cli/2.0.0-beta.
|
|
74
|
+
@herodevs/cli/2.0.0-beta.9 darwin-arm64 node-v22.18.0
|
|
41
75
|
$ hd --help [COMMAND]
|
|
42
76
|
USAGE
|
|
43
77
|
$ hd COMMAND
|
|
@@ -49,6 +83,7 @@ USAGE
|
|
|
49
83
|
* [`hd help [COMMAND]`](#hd-help-command)
|
|
50
84
|
* [`hd scan eol`](#hd-scan-eol)
|
|
51
85
|
* [`hd update [CHANNEL]`](#hd-update-channel)
|
|
86
|
+
* **NOTE:** Only applies to [binary installation method](#binary-installation). NPM users should use [`npm install`](#global-npm-installation) to update to the latest version.
|
|
52
87
|
|
|
53
88
|
## `hd help [COMMAND]`
|
|
54
89
|
|
|
@@ -76,13 +111,14 @@ Scan a given SBOM for EOL data
|
|
|
76
111
|
|
|
77
112
|
```
|
|
78
113
|
USAGE
|
|
79
|
-
$ hd scan eol [--json] [-f <value> | -d <value>] [-s] [--saveSbom]
|
|
114
|
+
$ hd scan eol [--json] [-f <value> | -d <value>] [-s] [--saveSbom] [--version]
|
|
80
115
|
|
|
81
116
|
FLAGS
|
|
82
117
|
-d, --dir=<value> [default: <current directory>] The directory to scan in order to create a cyclonedx SBOM
|
|
83
118
|
-f, --file=<value> The file path of an existing cyclonedx SBOM to scan for EOL
|
|
84
119
|
-s, --save Save the generated report as herodevs.report.json in the scanned directory
|
|
85
120
|
--saveSbom Save the generated SBOM as herodevs.sbom.json in the scanned directory
|
|
121
|
+
--version Show CLI version.
|
|
86
122
|
|
|
87
123
|
GLOBAL FLAGS
|
|
88
124
|
--json Format output as json.
|
|
@@ -112,12 +148,14 @@ EXAMPLES
|
|
|
112
148
|
$ hd scan eol --json
|
|
113
149
|
```
|
|
114
150
|
|
|
115
|
-
_See code: [src/commands/scan/eol.ts](https://github.com/herodevs/cli/blob/v2.0.0-beta.
|
|
151
|
+
_See code: [src/commands/scan/eol.ts](https://github.com/herodevs/cli/blob/v2.0.0-beta.9/src/commands/scan/eol.ts)_
|
|
116
152
|
|
|
117
153
|
## `hd update [CHANNEL]`
|
|
118
154
|
|
|
119
155
|
update the hd CLI
|
|
120
156
|
|
|
157
|
+
* **NOTE:** Only applies to [binary installation method](#binary-installation). NPM users should use [`npm install`](#global-npm-installation) to update to the latest version.
|
|
158
|
+
|
|
121
159
|
```
|
|
122
160
|
USAGE
|
|
123
161
|
$ hd update [CHANNEL] [--force | | [-a | -v <value> | -i]] [-b ]
|
|
@@ -157,7 +195,7 @@ _See code: [@oclif/plugin-update](https://github.com/oclif/plugin-update/blob/v4
|
|
|
157
195
|
|
|
158
196
|
You can use `@herodevs/cli` in your CI/CD pipelines to automate EOL scanning.
|
|
159
197
|
|
|
160
|
-
### Using the Docker Image (
|
|
198
|
+
### Using the Docker Image (Recommended)
|
|
161
199
|
|
|
162
200
|
We provide a Docker image that's pre-configured to run EOL scans. Based on [`cdxgen`](https://github.com/CycloneDX/cdxgen),
|
|
163
201
|
it contains build tools for most project types and will provide best results when generating an SBOM. Use these templates to generate a report and save it to your CI job artifact for analysis and processing after your scan runs.
|
|
@@ -207,9 +245,9 @@ eol-scan:
|
|
|
207
245
|
- herodevs.report.json
|
|
208
246
|
```
|
|
209
247
|
|
|
210
|
-
### Using `npx`
|
|
248
|
+
### Using `npx` in CI
|
|
211
249
|
|
|
212
|
-
You can use `npx` to run the CLI just like you
|
|
250
|
+
You can use `npx` to run the CLI in your CI pipeline, just like you would run it locally.
|
|
213
251
|
|
|
214
252
|
> [!NOTE]
|
|
215
253
|
> The development environment is expected to be ready to run the app. For best results,
|
package/bin/dev.js
CHANGED
package/bin/main.js
CHANGED
package/bin/run.js
CHANGED
|
@@ -12,6 +12,7 @@ export default class ScanEol extends Command {
|
|
|
12
12
|
dir: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
|
|
13
13
|
save: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
14
14
|
saveSbom: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
15
|
+
version: import("@oclif/core/interfaces").BooleanFlag<void>;
|
|
15
16
|
};
|
|
16
17
|
run(): Promise<EolReport | undefined>;
|
|
17
18
|
private loadSbom;
|
|
@@ -50,6 +50,7 @@ export default class ScanEol extends Command {
|
|
|
50
50
|
default: false,
|
|
51
51
|
description: `Save the generated SBOM as ${filenamePrefix}.sbom.json in the scanned directory`,
|
|
52
52
|
}),
|
|
53
|
+
version: Flags.version(),
|
|
53
54
|
};
|
|
54
55
|
async run() {
|
|
55
56
|
const { flags } = await this.parse(ScanEol);
|
|
@@ -69,6 +70,15 @@ export default class ScanEol extends Command {
|
|
|
69
70
|
sbom_generation_time: (sbomEndTime - sbomStartTime) / 1000,
|
|
70
71
|
}));
|
|
71
72
|
}
|
|
73
|
+
if (flags.saveSbom && !flags.file) {
|
|
74
|
+
const sbomPath = this.saveSbom(flags.dir, sbom);
|
|
75
|
+
this.log(`SBOM saved to ${sbomPath}`);
|
|
76
|
+
track('CLI SBOM Output Saved', (context) => ({
|
|
77
|
+
command: context.command,
|
|
78
|
+
command_flags: context.command_flags,
|
|
79
|
+
sbom_output_path: sbomPath,
|
|
80
|
+
}));
|
|
81
|
+
}
|
|
72
82
|
if (!sbom.components?.length) {
|
|
73
83
|
track('CLI EOL Scan Ended, No Components Found', (context) => ({
|
|
74
84
|
command: context.command,
|
|
@@ -104,15 +114,6 @@ export default class ScanEol extends Command {
|
|
|
104
114
|
report_output_path: reportPath,
|
|
105
115
|
}));
|
|
106
116
|
}
|
|
107
|
-
if (flags.saveSbom && !flags.file) {
|
|
108
|
-
const sbomPath = this.saveSbom(flags.dir, sbom);
|
|
109
|
-
this.log(`SBOM saved to ${sbomPath}`);
|
|
110
|
-
track('CLI SBOM Output Saved', (context) => ({
|
|
111
|
-
command: context.command,
|
|
112
|
-
command_flags: context.command_flags,
|
|
113
|
-
sbom_output_path: sbomPath,
|
|
114
|
-
}));
|
|
115
|
-
}
|
|
116
117
|
if (!this.jsonEnabled()) {
|
|
117
118
|
this.displayResults(scan);
|
|
118
119
|
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import ora, {} from 'ora';
|
|
2
|
+
import { track } from "../../service/analytics.svc.js";
|
|
3
|
+
const hook = async (opts) => {
|
|
4
|
+
const isHelpOrVersionCmd = opts.argv.includes('--help') || opts.argv.includes('--version');
|
|
5
|
+
let spinner;
|
|
6
|
+
if (!isHelpOrVersionCmd) {
|
|
7
|
+
spinner = ora().start('Cleaning up');
|
|
8
|
+
}
|
|
9
|
+
const event = track('CLI Session Ended', (context) => ({
|
|
10
|
+
cli_version: context.cli_version,
|
|
11
|
+
ended_at: new Date(),
|
|
12
|
+
})).promise;
|
|
13
|
+
if (!isHelpOrVersionCmd) {
|
|
14
|
+
await event;
|
|
15
|
+
spinner?.stop();
|
|
16
|
+
}
|
|
17
|
+
};
|
|
18
|
+
export default hook;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import updateNotifier, {} from 'update-notifier';
|
|
2
|
-
import pkg from '
|
|
3
|
-
import { debugLogger } from "
|
|
4
|
-
const updateNotifierHook = async (
|
|
2
|
+
import pkg from '../../../package.json' with { type: 'json' };
|
|
3
|
+
import { debugLogger } from "../../service/log.svc.js";
|
|
4
|
+
const updateNotifierHook = async () => {
|
|
5
5
|
debugLogger('pkg.version', pkg.version);
|
|
6
6
|
const distTag = getDistTag(pkg.version);
|
|
7
7
|
debugLogger('distTag', distTag);
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { parseArgs } from 'node:util';
|
|
2
|
-
import
|
|
3
|
-
|
|
4
|
-
const hook = async (opts) => {
|
|
2
|
+
import { initializeAnalytics, track } from "../../service/analytics.svc.js";
|
|
3
|
+
const hook = async () => {
|
|
5
4
|
const args = parseArgs({ allowPositionals: true, strict: false });
|
|
6
5
|
initializeAnalytics();
|
|
7
6
|
track('CLI Command Submitted', (context) => ({
|
|
@@ -12,9 +11,5 @@ const hook = async (opts) => {
|
|
|
12
11
|
cli_version: context.cli_version,
|
|
13
12
|
started_at: context.started_at,
|
|
14
13
|
}));
|
|
15
|
-
// If JSON flag is enabled, silence debug logging
|
|
16
|
-
if (opts.Command.prototype.jsonEnabled()) {
|
|
17
|
-
debug.disable();
|
|
18
|
-
}
|
|
19
14
|
};
|
|
20
15
|
export default hook;
|
|
@@ -58,8 +58,8 @@ export function formatScanResults(report) {
|
|
|
58
58
|
ux.colorize('bold', `${report.components.length.toLocaleString()} total packages scanned`),
|
|
59
59
|
getStatusRowText.EOL(`${EOL.toLocaleString().padEnd(5)} End-of-Life (EOL)`),
|
|
60
60
|
getStatusRowText.EOL_UPCOMING(`${EOL_UPCOMING.toLocaleString().padEnd(5)} EOL Upcoming`),
|
|
61
|
-
getStatusRowText.OK(`${OK.toLocaleString().padEnd(5)} Not End-of-Life`),
|
|
62
|
-
getStatusRowText.UNKNOWN(`${UNKNOWN.toLocaleString().padEnd(5)} Unknown Status`),
|
|
61
|
+
getStatusRowText.OK(`${OK.toLocaleString().padEnd(5)} Not End-of-Life (EOL)`),
|
|
62
|
+
getStatusRowText.UNKNOWN(`${UNKNOWN.toLocaleString().padEnd(5)} Unknown EOL Status`),
|
|
63
63
|
getStatusRowText.UNKNOWN(`${NES_AVAILABLE.toLocaleString().padEnd(5)} HeroDevs NES Remediation${NES_AVAILABLE !== 1 ? 's' : ''} Available`),
|
|
64
64
|
];
|
|
65
65
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@herodevs/cli",
|
|
3
|
-
"version": "2.0.0-beta.
|
|
3
|
+
"version": "2.0.0-beta.9",
|
|
4
4
|
"author": "HeroDevs, Inc",
|
|
5
5
|
"bin": {
|
|
6
6
|
"hd": "./bin/run.js"
|
|
@@ -26,11 +26,12 @@
|
|
|
26
26
|
"prepare": "shx test -d dist || npm run build",
|
|
27
27
|
"prepack": "oclif manifest",
|
|
28
28
|
"pretest": "npm run lint && npm run typecheck",
|
|
29
|
-
"readme": "npm run ci:fix && npm run build &&
|
|
29
|
+
"readme": "npm run ci:fix && npm run build && oclif readme",
|
|
30
30
|
"test": "globstar -- node --import tsx --test --experimental-test-module-mocks \"test/**/*.test.ts\"",
|
|
31
31
|
"test:e2e": "globstar -- node --import tsx --test \"e2e/**/*.test.ts\"",
|
|
32
32
|
"typecheck": "tsc --noEmit",
|
|
33
|
-
"version": "oclif manifest
|
|
33
|
+
"version": "oclif manifest",
|
|
34
|
+
"postversion": "node scripts/update-install-script-version.js && git add README.md"
|
|
34
35
|
},
|
|
35
36
|
"keywords": [
|
|
36
37
|
"herodevs",
|
|
@@ -38,11 +39,11 @@
|
|
|
38
39
|
"herodevs cli"
|
|
39
40
|
],
|
|
40
41
|
"dependencies": {
|
|
41
|
-
"@amplitude/analytics-node": "^1.5.
|
|
42
|
+
"@amplitude/analytics-node": "^1.5.8",
|
|
42
43
|
"@apollo/client": "^3.13.8",
|
|
43
44
|
"@cyclonedx/cdxgen": "~11.4.4",
|
|
44
45
|
"@herodevs/eol-shared": "github:herodevs/eol-shared#v0.1.11",
|
|
45
|
-
"@oclif/core": "^4.5.
|
|
46
|
+
"@oclif/core": "^4.5.3",
|
|
46
47
|
"@oclif/plugin-help": "^6.2.32",
|
|
47
48
|
"@oclif/plugin-update": "^4.7.4",
|
|
48
49
|
"graphql": "^16.11.0",
|
|
@@ -56,11 +57,11 @@
|
|
|
56
57
|
"@biomejs/biome": "^2.2.2",
|
|
57
58
|
"@oclif/test": "^4.1.13",
|
|
58
59
|
"@types/inquirer": "^9.0.9",
|
|
59
|
-
"@types/node": "^24.3.
|
|
60
|
+
"@types/node": "^24.3.1",
|
|
60
61
|
"@types/sinon": "^17.0.4",
|
|
61
62
|
"@types/update-notifier": "^6.0.8",
|
|
62
63
|
"globstar": "^1.0.0",
|
|
63
|
-
"oclif": "^4.22.
|
|
64
|
+
"oclif": "^4.22.18",
|
|
64
65
|
"shx": "^0.4.0",
|
|
65
66
|
"sinon": "^21.0.0",
|
|
66
67
|
"ts-node": "^10.9.2",
|
|
@@ -87,9 +88,12 @@
|
|
|
87
88
|
"@oclif/plugin-update"
|
|
88
89
|
],
|
|
89
90
|
"hooks": {
|
|
90
|
-
"init":
|
|
91
|
-
|
|
92
|
-
|
|
91
|
+
"init": [
|
|
92
|
+
"./dist/hooks/init/00_npm-update-notifier.js",
|
|
93
|
+
"./dist/hooks/init/01_initialize_amplitude.js"
|
|
94
|
+
],
|
|
95
|
+
"prerun": "./dist/hooks/prerun/prerun.js",
|
|
96
|
+
"finally": "./dist/hooks/finally/finally.js"
|
|
93
97
|
},
|
|
94
98
|
"topicSeparator": " ",
|
|
95
99
|
"macos": {
|
package/dist/hooks/finally.js
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import ora from 'ora';
|
|
2
|
-
import { track } from "../service/analytics.svc.js";
|
|
3
|
-
const hook = async (opts) => {
|
|
4
|
-
const spinner = ora().start('Cleaning up');
|
|
5
|
-
const event = track('CLI Session Ended', (context) => ({
|
|
6
|
-
cli_version: context.cli_version,
|
|
7
|
-
ended_at: new Date(),
|
|
8
|
-
})).promise;
|
|
9
|
-
if (!opts.argv.includes('--help')) {
|
|
10
|
-
await event;
|
|
11
|
-
}
|
|
12
|
-
spinner.stop();
|
|
13
|
-
};
|
|
14
|
-
export default hook;
|
|
File without changes
|
|
File without changes
|
|
File without changes
|