Skip to content

Commit 856dff7

Browse files
committed
feat(cli): add stat log in verbose mod
1 parent 4cad005 commit 856dff7

File tree

13 files changed

+78
-22
lines changed

13 files changed

+78
-22
lines changed

bin/index.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,8 @@ function defaultScannerCommand(name, options = {}) {
148148
const cmd = prog.command(name)
149149
.option("-d, --depth", i18n.getTokenSync("cli.commands.option_depth"), Infinity)
150150
.option("--silent", i18n.getTokenSync("cli.commands.option_silent"), false)
151-
.option("-c, --contacts", i18n.getTokenSync("cli.commands.option_contacts"), []);
151+
.option("-c, --contacts", i18n.getTokenSync("cli.commands.option_contacts"), [])
152+
.option("--verbose", i18n.getTokenSync("cli.commands.option_verbose"), false);
152153

153154
if (includeOutput) {
154155
cmd.option("-o, --output", i18n.getTokenSync("cli.commands.option_output"), "nsecure-result");

docs/cli/auto.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,4 +28,4 @@ $ nsecure auto --keep
2828
| `--vulnerabilityStrategy` | `-s` | github-advisory | Strategy used to fetch package vulnerabilities (see Vulnera [available strategy](https://github.com/NodeSecure/vulnera?tab=readme-ov-file#available-strategy)). |
2929
| `--keep` | `-k` | `false` | Preserve JSON payload after execution. |
3030
| `--developer` | `-d` | `false` | Launch the server in developer mode, enabling automatic HTML component refresh. |
31-
| `--contacts` | `-c` | `[]` | List of contacts to highlight. |
31+
| `--contacts` | `-c` | `[]` | List of contacts to highlight. | `--verbose` | | `false` | Sets cli log level to verbose, causing the CLI to output more detailed logs. |

docs/cli/cwd.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,4 +18,4 @@ $ nsecure cwd [options]
1818
| `--silent` | | `false` | Suppress console output, making execution silent. |
1919
| `--output` | `-o` | `nsecure-result` | Specify the output file for the results. |
2020
| `--vulnerabilityStrategy` | `-s` | github-advisory | Strategy used to fetch package vulnerabilities (see Vulnera [available strategy](https://github.com/NodeSecure/vulnera?tab=readme-ov-file#available-strategy)). |
21-
| `--contacts` | `-c` | `[]` | List of contacts to highlight. |
21+
| `--contacts` | `-c` | `[]` | List of contacts to highlight. | `--verbose` | | `false` | Sets cli log level to verbose, causing the CLI to output more detailed logs. |

docs/cli/from.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,4 +24,4 @@ $ nsecure from express@3.0.0 -o express-report
2424
| `--silent` | | `false` | Suppress console output, making execution silent. |
2525
| `--output` | `-o` | `nsecure-result` | Specify the output file for the results. |
2626
| `--vulnerabilityStrategy` | `-s` | github-advisory | Strategy used to fetch package vulnerabilities (see Vulnera [available strategy](https://github.com/NodeSecure/vulnera?tab=readme-ov-file#available-strategy)). |
27-
| `--contacts` | `-c` | `[]` | List of contacts to highlight. |
27+
| `--contacts` | `-c` | `[]` | List of contacts to highlight. | `--verbose` | | `false` | Sets cli log level to verbose, causing the CLI to output more detailed logs. |

i18n/arabic.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
/* eslint-disable @stylistic/max-len */
2-
31
// Import Third-party Dependencies
42
import { taggedString as tS } from "@nodesecure/i18n";
53

@@ -10,11 +8,13 @@ const cli = {
108
successfully_written_json: tS`تم كتابة ملف النتائج بنجاح في: ${0}`,
119
http_server_started: "تم تشغيل خادم HTTP على:",
1210
missingEnv: tS`متغير البيئة ${0} مفقود!`,
11+
stat: tS`${0} ${1} في ${2}`,
1312
commands: {
1413
option_depth: "أقصى عمق للتبعيات لجلبه",
1514
option_output: "اسم ملف JSON الناتج",
1615
option_silent: "تفعيل الوضع الصامت الذي يعطل مؤشرات CLI",
1716
option_contacts: "قائمة جهات الاتصال للتمييز",
17+
option_verbose: "ضبط مستوى الـ log الخاص بالـ CLI على verbose، مما يجعل الـ CLI يولّد logs أكثر تفصيلاً.",
1818
strategy: "مصدر الثغرات للاستخدام",
1919
cwd: {
2020
desc: "تشغيل تحليل الأمان على دليل العمل الحالي",

i18n/english.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,13 @@ const cli = {
1010
successfully_written_json: tS`Successfully written results file at: ${0}`,
1111
http_server_started: "HTTP Server started on:",
1212
missingEnv: tS`Environment variable ${0} is missing!`,
13+
stat: tS`${0} ${1} in ${2}`,
1314
commands: {
1415
option_depth: "Maximum dependencies depth to fetch",
1516
option_output: "Json file output name",
1617
option_silent: "enable silent mode which disable CLI spinners",
1718
option_contacts: "List of contacts to hightlight",
19+
option_verbose: "Sets cli log level to verbose, causing the CLI to output more detailed logs.",
1820
strategy: "Vulnerabilities source to use",
1921
cwd: {
2022
desc: "Run security analysis on the current working dir",

i18n/french.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,13 @@ const cli = {
1010
successfully_written_json: tS`Ecriture du fichier de résultats réalisée avec succès ici : ${0}`,
1111
http_server_started: "Serveur HTTP démarré sur :",
1212
missingEnv: tS`La variable d'environnement ${0} est manquante!`,
13+
stat: tS`${0} ${1} en ${2}`,
1314
commands: {
1415
option_depth: "Niveau de profondeur de dépendances maximum à aller chercher",
1516
option_output: "Nom de sortie du fichier json",
1617
option_silent: "Activer le mode silencieux qui désactive les spinners du CLI",
1718
option_contacts: "Liste des contacts à mettre en évidence",
19+
option_verbose: "Définir le niveau de log CLI à verbeux, ce qui amènera la CLI à générer des logs plus détaillés.",
1820
strategy: "Source de vulnérabilités à utiliser",
1921
cwd: {
2022
desc: "Démarre une analyse de sécurité sur le dossier courant",

i18n/turkish.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,13 @@ const cli = {
1010
successfully_written_json: tS`Sonuç dosyası başarıyla yazıldı: ${0}`,
1111
http_server_started: "HTTP Sunucusu başlatıldı:",
1212
missingEnv: tS`${0} ortam değişkeni eksik!`,
13+
stat: tS`${0} ${1} içinde ${2}`,
1314
commands: {
1415
option_depth: "Getirilecek maksimum bağımlılık derinliği",
1516
option_output: "JSON dosyası çıktı adı",
1617
option_silent: "CLI döndürücülerini devre dışı bırakan sessiz modu etkinleştir",
1718
option_contacts: "Vurgulanacak kişilerin listesi",
19+
option_verbose: "CLI'nin log seviyesini verbose olarak ayarlar, bu da CLI'nin daha ayrıntılı loglar üretmesine neden olur.",
1820
strategy: "Kullanılacak güvenlik açığı kaynağı",
1921
cwd: {
2022
desc: "Geçerli çalışma dizininde güvenlik analizi çalıştır",

package.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -95,20 +95,20 @@
9595
"@nodesecure/i18n": "^4.0.2",
9696
"@nodesecure/js-x-ray": "^11.0.1",
9797
"@nodesecure/licenses-conformance": "^2.1.0",
98+
"@nodesecure/mama": "2.0.2",
9899
"@nodesecure/npm-registry-sdk": "^4.4.0",
99100
"@nodesecure/ossf-scorecard-sdk": "^3.2.1",
100101
"@nodesecure/rc": "^5.0.0",
101102
"@nodesecure/report": "4.1.1",
102-
"@nodesecure/scanner": "9.0.0",
103-
"@nodesecure/mama": "2.0.2",
103+
"@nodesecure/scanner": "10.2.0",
104104
"@nodesecure/server": "1.0.0",
105105
"@nodesecure/utils": "^2.2.0",
106106
"@nodesecure/vulnera": "^2.0.1",
107107
"@openally/result": "^2.0.0",
108108
"@topcli/cliui": "^1.1.0",
109109
"@topcli/pretty-json": "^1.0.0",
110110
"@topcli/prompts": "^2.0.0",
111-
"@topcli/spinner": "^4.0.0",
111+
"@topcli/spinner": "4.2.1",
112112
"filenamify": "^7.0.0",
113113
"highlightjs-line-numbers.js": "^2.8.0",
114114
"ini": "^6.0.0",

src/commands/scanner.js

Lines changed: 59 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -65,21 +65,24 @@ export async function cwd(options) {
6565
full,
6666
vulnerabilityStrategy,
6767
silent,
68-
contacts
68+
contacts,
69+
verbose
6970
} = options;
7071

71-
const payload = await scanner.cwd(
72+
const payload = await scanner.workingDir(
7273
process.cwd(),
73-
{ maxDepth, usePackageLock: !nolock, fullLockMode: full, vulnerabilityStrategy, highlight:
74-
{ contacts: parseContacts(contacts) } },
74+
{
75+
maxDepth, usePackageLock: !nolock, fullLockMode: full, vulnerabilityStrategy, highlight:
76+
{ contacts: parseContacts(contacts) }, isVerbose: verbose
77+
},
7578
initLogger(void 0, !silent)
7679
);
7780

7881
return await logAndWrite(payload, output, { local: true });
7982
}
8083

8184
export async function from(spec, options) {
82-
const { depth: maxDepth = Infinity, output, silent, contacts, vulnerabilityStrategy } = options;
85+
const { depth: maxDepth = Infinity, output, silent, contacts, vulnerabilityStrategy, verbose } = options;
8386

8487
const payload = await scanner.from(
8588
spec,
@@ -88,20 +91,23 @@ export async function from(spec, options) {
8891
vulnerabilityStrategy,
8992
highlight: {
9093
contacts: parseContacts(contacts)
91-
}
94+
},
95+
isVerbose: verbose
9296
},
9397
initLogger(spec, !silent)
9498
);
9599

96100
return await logAndWrite(payload, output);
97101
}
98102

103+
const spinners = [];
104+
99105
function initLogger(spec, verbose = true) {
100106
const spinner = {
101-
walkTree: new Spinner({ verbose }),
102-
tarball: new Spinner({ verbose }),
103-
registry: new Spinner({ verbose }),
104-
fetchManifest: new Spinner({ verbose }),
107+
walkTree: buildSpinner(verbose),
108+
tarball: buildSpinner(verbose),
109+
registry: buildSpinner(verbose),
110+
fetchManifest: buildSpinner(verbose),
105111
i18n: {
106112
start: {
107113
fetchManifest: "cli.commands.from.searching",
@@ -122,6 +128,13 @@ function initLogger(spec, verbose = true) {
122128
}
123129
};
124130

131+
function buildSpinner(verbose) {
132+
const spinner = new Spinner({ verbose });
133+
spinners.push(spinner);
134+
135+
return spinner;
136+
}
137+
125138
const logger = new scanner.Logger();
126139
logger.on("start", (eventName) => {
127140
if (!(eventName in spinner)) {
@@ -154,27 +167,62 @@ function initLogger(spec, verbose = true) {
154167

155168
const spin = spinner[eventName];
156169
const tokenName = spinner.i18n.end[eventName];
157-
const execTime = kleur.cyan().bold(ms(Number(spin.elapsedTime.toFixed(2))));
170+
const execTime = kleur.cyan().bold(formatMs(spin.elapsedTime));
158171

159172
if (eventName === "walkTree") {
160173
spin.succeed(kleur.white().bold(
161174
i18n.getTokenSync(tokenName, kleur.yellow().bold(i18n.getTokenSync("depWalker.dep_tree")), execTime)));
175+
spin.succeeded = true;
162176
}
163177
else if (eventName === "registry") {
164178
spin.succeed(kleur.white().bold(i18n.getTokenSync(tokenName)));
179+
spin.succeeded = true;
165180
}
166181
else if (eventName === "tarball") {
167182
spin.succeed(kleur.white().bold(i18n.getTokenSync(tokenName, kleur.green().bold(logger.count("walkTree")), execTime)));
183+
spin.succeeded = true;
168184
}
169185
else if (eventName === "fetchManifest") {
170186
spin.succeed(kleur.white().bold(i18n.getTokenSync(tokenName, kleur.green().bold(spec), execTime)));
187+
spin.succeeded = true;
171188
console.log("");
172189
}
173190
});
174191

192+
logger.on("stat", (stat) => {
193+
stopSpinners();
194+
console.log(kleur.bold.white(
195+
i18n.getTokenSync("cli.stat",
196+
kleur.blue().bold("verbose"),
197+
stat.name,
198+
kleur.cyan().bold(formatMs(stat.executionTime))
199+
)));
200+
startSpinners();
201+
});
202+
175203
return logger;
176204
}
177205

206+
function formatMs(time) {
207+
return ms(Number(time.toFixed(2)));
208+
}
209+
210+
function stopSpinners() {
211+
spinners.forEach((spinner) => {
212+
if (!spinner.succeeded) {
213+
spinner.stop();
214+
}
215+
});
216+
}
217+
218+
function startSpinners() {
219+
spinners.forEach((spinner) => {
220+
if (!spinner.succeeded) {
221+
spinner.start();
222+
}
223+
});
224+
}
225+
178226
async function logAndWrite(
179227
/** @type {import("@nodesecure/scanner").Payload} */
180228
payload,

0 commit comments

Comments
 (0)