Skip to content

Commit 0af875a

Browse files
authored
feat: output JSON by default in scan sbom command; rename created files to herodevs.* (#260)
1 parent 16e9117 commit 0af875a

File tree

13 files changed

+46
-32
lines changed

13 files changed

+46
-32
lines changed

README.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ USAGE
8585
FLAGS
8686
-c, --csv Output in CSV format
8787
-m, --months=<value> [default: 12] The number of months of git history to review
88-
-s, --save Save the committers report as eol.committers.<output>
88+
-s, --save Save the committers report as herodevs.committers.<output>
8989
9090
GLOBAL FLAGS
9191
--json Format output as json.
@@ -117,7 +117,7 @@ FLAGS
117117
-c, --csv Save output in CSV format (only applies when using --save)
118118
-d, --dir=<value> The directory to scan in order to create a cyclonedx sbom
119119
-f, --file=<value> The file path of an existing cyclonedx sbom to scan for EOL
120-
-s, --save Save the list of purls as eol.purls.<output>
120+
-s, --save Save the list of purls as herodevs.purls.<output>
121121
122122
GLOBAL FLAGS
123123
--json Format output as json.
@@ -152,7 +152,7 @@ FLAGS
152152
-d, --dir=<value> The directory to scan in order to create a cyclonedx sbom
153153
-f, --file=<value> The file path of an existing cyclonedx sbom to scan for EOL
154154
-p, --purls=<value> The file path of a list of purls to scan for EOL
155-
-s, --save Save the generated report as eol.report.json in the scanned directory
155+
-s, --save Save the generated report as herodevs.report.json in the scanned directory
156156
157157
GLOBAL FLAGS
158158
--json Format output as json.
@@ -184,7 +184,7 @@ FLAGS
184184
-b, --background Run the scan in the background
185185
-d, --dir=<value> The directory to scan in order to create a cyclonedx sbom
186186
-f, --file=<value> The file path of an existing cyclonedx sbom to scan for EOL
187-
-s, --save Save the generated SBOM as eol.sbom.json in the scanned directory
187+
-s, --save Save the generated SBOM as herodevs.sbom.json in the scanned directory
188188
189189
GLOBAL FLAGS
190190
--json Format output as json.
File renamed without changes.

e2e/scan/eol.test.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import { describe, it } from 'node:test';
88
import { fileURLToPath } from 'node:url';
99
import { promisify } from 'node:util';
1010
import { runCommand } from '@oclif/test';
11-
import { config } from '../../src/config/constants';
11+
import { config, filenamePrefix } from '../../src/config/constants';
1212

1313
const execAsync = promisify(exec);
1414

@@ -62,8 +62,8 @@ describe('scan:eol e2e', () => {
6262
const __dirname = path.dirname(fileURLToPath(import.meta.url));
6363
const fixturesDir = path.resolve(__dirname, '../fixtures');
6464
const simplePurls = path.resolve(__dirname, '../fixtures/npm/simple.purls.json');
65-
const simpleSbom = path.join(fixturesDir, 'npm/eol.sbom.json');
66-
const reportPath = path.resolve(fixturesDir, 'eol.report.json');
65+
const simpleSbom = path.join(fixturesDir, `npm/${filenamePrefix}.sbom.json`);
66+
const reportPath = path.resolve(fixturesDir, `${filenamePrefix}.report.json`);
6767
const upToDatePurls = path.resolve(__dirname, '../fixtures/npm/up-to-date.purls.json');
6868
const emptyPurlsPath = path.resolve(__dirname, '../fixtures/npm/empty.purls.json');
6969

@@ -213,7 +213,7 @@ describe('with directory flag', () => {
213213
const __dirname = path.dirname(fileURLToPath(import.meta.url));
214214
const simpleDir = path.resolve(__dirname, '../fixtures/npm/simple');
215215
const upToDateDir = path.resolve(__dirname, '../fixtures/npm/up-to-date');
216-
const reportPath = path.join(simpleDir, 'eol.report.json');
216+
const reportPath = path.join(simpleDir, `${filenamePrefix}.report.json`);
217217

218218
async function run(cmd: string) {
219219
// Ensure test directory exists and is clean

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
"ci": "biome ci",
1818
"ci:fix": "biome check --write",
1919
"clean": "shx rm -rf dist && npm run clean:files && shx rm -rf node_modules",
20-
"clean:files": "shx rm -f eol.**.csv eol.**.json eol.**.text",
20+
"clean:files": "shx rm -f herodevs.**.csv herodevs.**.json herodevs.**.txt",
2121
"dev": "npm run build && ./bin/dev.js",
2222
"dev:debug": "npm run build && DEBUG=oclif:* ./bin/dev.js",
2323
"format": "biome format --write",

src/commands/report/committers.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { Command, Flags } from '@oclif/core';
33

44
import fs from 'node:fs';
55
import path from 'node:path';
6+
import { filenamePrefix } from '../../config/constants.ts';
67
import {
78
type CommitEntry,
89
type ReportData,
@@ -37,7 +38,7 @@ export default class Committers extends Command {
3738
}),
3839
save: Flags.boolean({
3940
char: 's',
40-
description: 'Save the committers report as eol.committers.<output>',
41+
description: `Save the committers report as ${filenamePrefix}.committers.<output>`,
4142
default: false,
4243
}),
4344
};
@@ -61,7 +62,7 @@ export default class Committers extends Command {
6162
// JSON mode
6263
if (save) {
6364
try {
64-
fs.writeFileSync(path.resolve('eol.committers.json'), JSON.stringify(reportData, null, 2));
65+
fs.writeFileSync(path.resolve(`${filenamePrefix}.committers.json`), JSON.stringify(reportData, null, 2));
6566
this.log('Report written to json');
6667
} catch (error) {
6768
this.error(`Failed to save JSON report: ${getErrorMessage(error)}`);
@@ -77,7 +78,7 @@ export default class Committers extends Command {
7778
const csvOutput = formatAsCsv(reportData);
7879
if (save) {
7980
try {
80-
fs.writeFileSync(path.resolve('eol.committers.csv'), csvOutput);
81+
fs.writeFileSync(path.resolve(`${filenamePrefix}.committers.csv`), csvOutput);
8182
this.log('Report written to csv');
8283
} catch (error) {
8384
this.error(`Failed to save CSV report: ${getErrorMessage(error)}`);
@@ -90,7 +91,7 @@ export default class Committers extends Command {
9091

9192
if (save) {
9293
try {
93-
fs.writeFileSync(path.resolve('eol.committers.txt'), textOutput);
94+
fs.writeFileSync(path.resolve(`${filenamePrefix}.committers.txt`), textOutput);
9495
this.log('Report written to txt');
9596
} catch (error) {
9697
this.error(`Failed to save txt report: ${getErrorMessage(error)}`);

src/commands/report/purls.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import fs from 'node:fs';
22
import path from 'node:path';
33
import { Command, Flags, ux } from '@oclif/core';
44

5+
import { filenamePrefix } from '../../config/constants.ts';
56
import { getErrorMessage, isErrnoException } from '../../service/error.svc.ts';
67
import { extractPurls, getPurlOutput } from '../../service/purls.svc.ts';
78
import ScanSbom from '../scan/sbom.ts';
@@ -28,7 +29,7 @@ export default class ReportPurls extends Command {
2829
save: Flags.boolean({
2930
char: 's',
3031
default: false,
31-
description: 'Save the list of purls as eol.purls.<output>',
32+
description: `Save the list of purls as ${filenamePrefix}.purls.<output>`,
3233
}),
3334
csv: Flags.boolean({
3435
char: 'c',
@@ -57,7 +58,7 @@ export default class ReportPurls extends Command {
5758
if (save) {
5859
try {
5960
const outputFile = csv && !this.jsonEnabled() ? 'csv' : 'json';
60-
const outputPath = path.join(_dirFlag || process.cwd(), `eol.purls.${outputFile}`);
61+
const outputPath = path.join(_dirFlag || process.cwd(), `${filenamePrefix}.purls.${outputFile}`);
6162
const purlOutput = getPurlOutput(purls, outputFile);
6263
fs.writeFileSync(outputPath, purlOutput);
6364

src/commands/scan/eol.ts

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import terminalLink from 'terminal-link';
55
import { batchSubmitPurls } from '../../api/nes/nes.client.ts';
66
import type { ScanResult } from '../../api/types/hd-cli.types.js';
77
import type { ComponentStatus, InsightsEolScanComponent } from '../../api/types/nes.types.ts';
8-
import { config } from '../../config/constants.ts';
8+
import { config, filenamePrefix } from '../../config/constants.ts';
99
import type { Sbom } from '../../service/eol/cdx.svc.ts';
1010
import { getErrorMessage, isErrnoException } from '../../service/error.svc.ts';
1111
import { extractPurls, parsePurlsFile } from '../../service/purls.svc.ts';
@@ -37,7 +37,7 @@ export default class ScanEol extends Command {
3737
save: Flags.boolean({
3838
char: 's',
3939
default: false,
40-
description: 'Save the generated report as eol.report.json in the scanned directory',
40+
description: `Save the generated report as ${filenamePrefix}.report.json in the scanned directory`,
4141
}),
4242
};
4343

@@ -61,7 +61,7 @@ export default class ScanEol extends Command {
6161
}
6262

6363
this.log('* Use --json to output the report payload');
64-
this.log('* Use --save to save the report to eol.report.json');
64+
this.log(`* Use --save to save the report to ${filenamePrefix}.report.json`);
6565
this.log('* Use --help for more commands or options');
6666
}
6767

@@ -116,19 +116,19 @@ export default class ScanEol extends Command {
116116

117117
private async saveReport(components: InsightsEolScanComponent[], createdOn?: string): Promise<void> {
118118
const { flags } = await this.parse(ScanEol);
119-
const reportPath = path.join(flags.dir || process.cwd(), 'eol.report.json');
119+
const reportPath = path.join(flags.dir || process.cwd(), `${filenamePrefix}.report.json`);
120120

121121
try {
122122
fs.writeFileSync(reportPath, JSON.stringify({ components, createdOn }, null, 2));
123-
this.log('Report saved to eol.report.json');
123+
this.log(`Report saved to ${filenamePrefix}.report.json`);
124124
} catch (error) {
125125
if (!isErrnoException(error)) {
126126
this.error(`Failed to save report: ${getErrorMessage(error)}`);
127127
}
128128
if (error.code === 'EACCES') {
129-
this.error('Permission denied. Unable to save report to eol.report.json');
129+
this.error(`Permission denied. Unable to save report to ${filenamePrefix}.report.json`);
130130
} else if (error.code === 'ENOSPC') {
131-
this.error('No space left on device. Unable to save report to eol.report.json');
131+
this.error(`No space left on device. Unable to save report to ${filenamePrefix}.report.json`);
132132
} else {
133133
this.error(`Failed to save report: ${getErrorMessage(error)}`);
134134
}

src/commands/scan/sbom.ts

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { spawn } from 'node:child_process';
22
import fs from 'node:fs';
33
import { join, resolve } from 'node:path';
44
import { Command, Flags, ux } from '@oclif/core';
5+
import { filenamePrefix } from '../../config/constants.ts';
56
import type { Sbom } from '../../service/eol/cdx.svc.ts';
67
import { createSbom, validateIsCycloneDxSbom } from '../../service/eol/eol.svc.ts';
78
import { getErrorMessage } from '../../service/error.svc.ts';
@@ -25,7 +26,7 @@ export default class ScanSbom extends Command {
2526
save: Flags.boolean({
2627
char: 's',
2728
default: false,
28-
description: 'Save the generated SBOM as eol.sbom.json in the scanned directory',
29+
description: `Save the generated SBOM as ${filenamePrefix}.sbom.json in the scanned directory`,
2930
}),
3031
background: Flags.boolean({
3132
char: 'b',
@@ -45,14 +46,13 @@ export default class ScanSbom extends Command {
4546
}
4647

4748
static getSbomArgs(flags: Record<string, string>): string[] {
48-
const { dir, file, save, json, background } = flags ?? {};
49+
const { dir, file, background } = flags ?? {};
4950

50-
const sbomArgs = [];
51+
const sbomArgs = ['--json'];
5152

5253
if (file) sbomArgs.push('--file', file);
5354
if (dir) sbomArgs.push('--dir', dir);
5455
// if (save) sbomArgs.push('--save'); // only save if sbom command is used directly with -s flag
55-
if (json) sbomArgs.push('--json');
5656
if (background) sbomArgs.push('--background');
5757

5858
return sbomArgs;
@@ -75,17 +75,24 @@ export default class ScanSbom extends Command {
7575
const path = dir || process.cwd();
7676
if (file) {
7777
sbom = this._getSbomFromFile(file);
78+
ux.action.stop();
7879
} else if (background) {
7980
this._getSbomInBackground(path);
80-
this.log(`The scan is running in the background. The file will be saved at ${path}/eol.sbom.json`);
81+
this.log(`The scan is running in the background. The file will be saved at ${path}/${filenamePrefix}.sbom.json`);
82+
ux.action.stop();
8183
return;
8284
} else {
8385
sbom = await this._getSbomFromScan(path);
86+
ux.action.stop();
8487
if (save) {
8588
this._saveSbom(path, sbom);
8689
}
8790
}
8891

92+
if (!save) {
93+
this.log(JSON.stringify(sbom, null, 2));
94+
}
95+
8996
return sbom;
9097
}
9198

@@ -158,7 +165,7 @@ export default class ScanSbom extends Command {
158165

159166
private _saveSbom(dir: string, sbom: Sbom) {
160167
try {
161-
const outputPath = join(dir, 'eol.sbom.json');
168+
const outputPath = join(dir, `${filenamePrefix}.sbom.json`);
162169
fs.writeFileSync(outputPath, JSON.stringify(sbom, null, 2));
163170
if (!this.jsonEnabled()) {
164171
this.log(`SBOM saved to ${outputPath}`);

src/config/constants.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,5 @@ export const config = {
88
graphqlPath: process.env.GRAPHQL_PATH || GRAPHQL_PATH,
99
showVulnCount: true,
1010
};
11+
12+
export const filenamePrefix = 'herodevs';

src/service/eol/sbom.worker.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { writeFileSync } from 'node:fs';
22
import { join } from 'node:path';
33
import { createBom } from '@cyclonedx/cdxgen';
4+
import { filenamePrefix } from '../../config/constants.ts';
45
import { SBOM_DEFAULT__OPTIONS } from './cdx.svc.ts';
56

67
process.on('uncaughtException', (err) => {
@@ -18,7 +19,7 @@ try {
1819
const options = JSON.parse(process.argv[2]);
1920
const { path, opts } = options;
2021
const { bomJson } = await createBom(path, { ...SBOM_DEFAULT__OPTIONS, ...opts });
21-
const outputPath = join(path, 'eol.sbom.json');
22+
const outputPath = join(path, `${filenamePrefix}.sbom.json`);
2223
writeFileSync(outputPath, JSON.stringify(bomJson, null, 2));
2324
process.exit(0);
2425
} catch (error: unknown) {

0 commit comments

Comments
 (0)