@coana-tech/cli 13.19.2 → 13.19.4

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.
Files changed (2) hide show
  1. package/cli.js +139 -29
  2. package/package.json +1 -1
package/cli.js CHANGED
@@ -95630,7 +95630,9 @@ var init_constants3 = __esm({
95630
95630
  "REACHABILITY_ANALYZERS_SCRIPT_PATH",
95631
95631
  "JAVA_HOME",
95632
95632
  "GRADLE_HOME",
95633
- "SBT_HOME"
95633
+ "SBT_HOME",
95634
+ "HOME",
95635
+ "USER"
95634
95636
  ];
95635
95637
  }
95636
95638
  });
@@ -95800,7 +95802,7 @@ var init_other_modules_communicator = __esm({
95800
95802
  }
95801
95803
  async runInDocker(image, entryPoint, commandName, args2, subprojectPath, tmpDir, env = process.env) {
95802
95804
  const envArgs = Object.keys(env).filter((key) => !DOCKER_ENV_VARS_BLACKLIST.includes(key)).flatMap((key) => ["-e", key]);
95803
- const cmd = cmdt`docker run --pull always -v ${this.rootWorkingDir}:/project -v ${tmpDir}:${tmpDir}
95805
+ const cmd = cmdt`docker run --pull always --rm -v ${this.rootWorkingDir}:/project -v ${tmpDir}:${tmpDir}
95804
95806
  -v=${this.options.coanaLogPath}:${this.options.coanaLogPath}
95805
95807
  ${envArgs} ${image} ${entryPoint} ${commandName} ${args2}`;
95806
95808
  return await execPipeAndLogOnFailure(cmd, subprojectPath, { env });
@@ -130101,7 +130103,9 @@ __export(dashboard_integration_exports, {
130101
130103
  getExperimentName: () => getExperimentName,
130102
130104
  getPreviousAnalysisResults: () => getPreviousAnalysisResults,
130103
130105
  sendCLIProgressToDashboard: () => sendCLIProgressToDashboard,
130106
+ sendDependencyTreesToDashboard: () => sendDependencyTreesToDashboard,
130104
130107
  sendErrorReportToDashboard: () => sendErrorReportToDashboard,
130108
+ sendLogToDashboard: () => sendLogToDashboard,
130105
130109
  sendRegressionsToDashboard: () => sendRegressionsToDashboard,
130106
130110
  sendToDashboard: () => sendToDashboard,
130107
130111
  sendWarningToDashboard: () => sendWarningToDashboard,
@@ -130249,6 +130253,22 @@ async function sendWarningToDashboard(message2, data2, additionalData, reportId,
130249
130253
  logger.warn("Unable to send warning to dashboard:", error.message);
130250
130254
  }
130251
130255
  }
130256
+ async function sendDependencyTreesToDashboard(dependencyTrees, reportId, apiKey) {
130257
+ try {
130258
+ await sendPostRequest(
130259
+ coanaAPIUrls.SEND_DEPENDENCY_TREES.replace(":reportId", reportId),
130260
+ apiKey,
130261
+ {},
130262
+ dependencyTrees
130263
+ );
130264
+ } catch (e) {
130265
+ sendWarningToDashboard("Unable to send dependency trees", { reportId }, void 0, reportId, apiKey);
130266
+ logger.warn(
130267
+ "Unable to send dependency trees:",
130268
+ e.message
130269
+ );
130270
+ }
130271
+ }
130252
130272
  async function sendToDashboard(report, writeReportToFile, reportId, apiKey) {
130253
130273
  try {
130254
130274
  if (writeReportToFile) {
@@ -130285,6 +130305,17 @@ async function sendErrorReportToDashboard(apiKey, stackTrace, shouldLogSharing,
130285
130305
  console.log("Error submitting crash report to dashboard:", e);
130286
130306
  }
130287
130307
  }
130308
+ async function sendLogToDashboard(logContent, reportId, apiKey) {
130309
+ if (!logContent) return;
130310
+ logger.info("Sending log to Coana");
130311
+ try {
130312
+ await sendPostRequest(coanaAPIUrls.SEND_LOG.replace(":reportId", reportId), apiKey, { reportId }, {
130313
+ logContent
130314
+ });
130315
+ } catch (error) {
130316
+ logger.warn("Unable to send log to dashboard:", error.message);
130317
+ }
130318
+ }
130288
130319
  async function sendPostRequest(url2, apiKey, params, data2) {
130289
130320
  const axiosConfig = {
130290
130321
  headers: {
@@ -130310,10 +130341,12 @@ var init_dashboard_integration = __esm({
130310
130341
  CREATE_ANALYSIS_METADATA: `${coanaAPI}/reports/:reportId/analysis-metadata`,
130311
130342
  REPORT_CLI_PROGRESS: `${coanaAPI}/reports/:reportId/cli-progress`,
130312
130343
  CREATE_REGRESSIONS: `${coanaAPI}/reports/:reportId/regressions`,
130344
+ SEND_LOG: `${coanaAPI}/reports/:reportId/log`,
130313
130345
  GET_LATEST_BUCKETS: `${coanaAPI}/latest-buckets`,
130314
130346
  GET_LATEST_RESULTS: `${coanaAPI}/latest-results`,
130315
130347
  GET_EXPERIMENT_NAME: `${coanaAPI}/experiment-name`,
130316
- REPORT_WARNING: `${coanaAPI}/cli/warn`
130348
+ REPORT_WARNING: `${coanaAPI}/cli/warn`,
130349
+ SEND_DEPENDENCY_TREES: `${coanaAPI}/reports/:reportId/dependency-trees`
130317
130350
  };
130318
130351
  reportSubmitEndpoint = process.env.COANA_CLI_SUBMIT_ENDPOINT ?? "https://app.coana.tech/api/v1/reports/submit";
130319
130352
  errorSubmitEndpoint = process.env.COANA_CLI_ERROR_SUBMIT_ENDPOINT ?? "https://app.coana.tech/api/v1/cli/error";
@@ -189074,13 +189107,56 @@ var init_slack = __esm({
189074
189107
  });
189075
189108
 
189076
189109
  // ../web-compat-utils/src/dependency-tree.ts
189110
+ var dependency_tree_exports = {};
189111
+ __export(dependency_tree_exports, {
189112
+ ADVISORY_ECOSYSTEMS: () => ADVISORY_ECOSYSTEMS,
189113
+ ADVISORY_SEVERITIES: () => ADVISORY_SEVERITIES,
189114
+ PACKAGE_MANAGERS: () => PACKAGE_MANAGERS,
189115
+ getEcosystem: () => getEcosystem,
189116
+ mergeDependencyTrees: () => mergeDependencyTrees,
189117
+ toPlainDependencyTree: () => toPlainDependencyTree
189118
+ });
189077
189119
  function getEcosystem({ ecosystem }) {
189078
189120
  return ecosystem ?? "NPM";
189079
189121
  }
189080
- var ADVISORY_ECOSYSTEMS;
189122
+ function mergeDependencyTrees(dependencyTrees) {
189123
+ if (dependencyTrees.length === 1) return dependencyTrees[0];
189124
+ const newTree = {
189125
+ ...dependencyTrees[0],
189126
+ transitiveDependencies: {},
189127
+ dependencies: []
189128
+ };
189129
+ for (const dependencyTree of dependencyTrees) {
189130
+ if (dependencyTree.dependencies)
189131
+ newTree.dependencies = i([...newTree.dependencies, ...dependencyTree.dependencies ?? []]);
189132
+ for (const [identifier, node] of Object.entries(dependencyTree.transitiveDependencies)) {
189133
+ if (!newTree.transitiveDependencies[identifier])
189134
+ newTree.transitiveDependencies[identifier] = { ...node, dependencies: [...node.dependencies ?? []] };
189135
+ else {
189136
+ const existingNode = newTree.transitiveDependencies[identifier];
189137
+ existingNode.dependencies = i([...existingNode.dependencies ?? [], ...node.dependencies ?? []]);
189138
+ }
189139
+ }
189140
+ }
189141
+ return newTree;
189142
+ }
189143
+ function toPlainDependencyTree(dependencyTree) {
189144
+ function pickNode(node) {
189145
+ return a(node, ["packageName", "version", "dependencies", "resolvedType"]);
189146
+ }
189147
+ return {
189148
+ ...pickNode(dependencyTree),
189149
+ transitiveDependencies: Object.fromEntries(
189150
+ Object.entries(dependencyTree.transitiveDependencies).map(([key, value]) => [key, pickNode(value)])
189151
+ ),
189152
+ ecosystem: dependencyTree.ecosystem
189153
+ };
189154
+ }
189155
+ var ADVISORY_ECOSYSTEMS, ADVISORY_SEVERITIES, PACKAGE_MANAGERS;
189081
189156
  var init_dependency_tree = __esm({
189082
189157
  "../web-compat-utils/src/dependency-tree.ts"() {
189083
189158
  "use strict";
189159
+ init_dist();
189084
189160
  ADVISORY_ECOSYSTEMS = [
189085
189161
  "COMPOSER",
189086
189162
  "ERLANG",
@@ -189095,6 +189171,24 @@ var init_dependency_tree = __esm({
189095
189171
  "RUST",
189096
189172
  "SWIFT"
189097
189173
  ];
189174
+ ADVISORY_SEVERITIES = ["info", "INFO", "low", "LOW", "moderate", "MODERATE", "high", "HIGH", "critical", "CRITICAL"];
189175
+ PACKAGE_MANAGERS = [
189176
+ "NPM",
189177
+ "PNPM",
189178
+ "YARN",
189179
+ "RUSH",
189180
+ "MAVEN",
189181
+ "GRADLE",
189182
+ "SBT",
189183
+ "POETRY",
189184
+ "PIP_REQUIREMENTS",
189185
+ "PIPENV",
189186
+ "GO",
189187
+ "CARGO",
189188
+ "NUGET",
189189
+ "RUBYGEMS",
189190
+ "COMPOSER"
189191
+ ];
189098
189192
  }
189099
189193
  });
189100
189194
 
@@ -190036,7 +190130,7 @@ var require_version = __commonJS({
190036
190130
  "use strict";
190037
190131
  Object.defineProperty(exports2, "__esModule", { value: true });
190038
190132
  exports2.version = void 0;
190039
- exports2.version = "13.19.2";
190133
+ exports2.version = "13.19.4";
190040
190134
  }
190041
190135
  });
190042
190136
 
@@ -190071,6 +190165,7 @@ var require_cli_core = __commonJS({
190071
190165
  var dashboard_integration_1 = (init_dashboard_integration(), __toCommonJS(dashboard_integration_exports));
190072
190166
  var vulnerability_scanning_1 = require_vulnerability_scanning();
190073
190167
  var version_12 = require_version();
190168
+ var dependency_tree_1 = (init_dependency_tree(), __toCommonJS(dependency_tree_exports));
190074
190169
  var CliCore = class {
190075
190170
  options;
190076
190171
  spinner;
@@ -190130,24 +190225,31 @@ var require_cli_core = __commonJS({
190130
190225
  } catch (e) {
190131
190226
  await this.spinner.fail();
190132
190227
  logger_singleton_1.logger.error("CLI failed with error:", e);
190133
- await this.shareLogWithDashboard(e, true);
190228
+ await this.shareErrorLogWithDashboard(e, true);
190134
190229
  throw e;
190135
190230
  }
190136
190231
  }
190137
- async shareLogWithDashboard(e, shouldLogSharing) {
190232
+ async getLogContent() {
190233
+ await logger_singleton_1.logger.finish();
190234
+ let logContent;
190235
+ try {
190236
+ logContent = await (0, promises_12.readFile)(this.coanaLogPath, "utf-8");
190237
+ } catch (e) {
190238
+ this.spinner.suspend(() => {
190239
+ console.error("Error reading log file", e);
190240
+ });
190241
+ }
190242
+ return logContent;
190243
+ }
190244
+ async shareErrorLogWithDashboard(e, shouldLogSharing) {
190138
190245
  if (this.options.apiKey) {
190139
- await logger_singleton_1.logger.finish();
190140
- let logContent;
190141
- try {
190142
- logContent = await (0, promises_12.readFile)(this.coanaLogPath, "utf-8");
190143
- } catch (e2) {
190144
- this.spinner.suspend(() => {
190145
- console.error("Error reading log file", e2);
190146
- });
190147
- }
190148
- await (0, dashboard_integration_1.sendErrorReportToDashboard)(this.options.apiKey, e.stack ?? e.message ?? "Unknown stack trace", shouldLogSharing, this.options.repoUrl, this.options.projectName, logContent);
190246
+ await (0, dashboard_integration_1.sendErrorReportToDashboard)(this.options.apiKey, e.stack ?? e.message ?? "Unknown stack trace", shouldLogSharing, this.options.repoUrl, this.options.projectName, await this.getLogContent());
190149
190247
  }
190150
190248
  }
190249
+ async shareLogWithDashboard() {
190250
+ if (this.options.apiKey && this.reportId)
190251
+ await (0, dashboard_integration_1.sendLogToDashboard)(await this.getLogContent(), this.reportId, this.options.apiKey);
190252
+ }
190151
190253
  async outputAndShareReport(report) {
190152
190254
  logger_singleton_1.logger.info("Report computed successfully");
190153
190255
  const outputDir = this.options.outputDir;
@@ -190172,9 +190274,12 @@ var require_cli_core = __commonJS({
190172
190274
  }
190173
190275
  if (report.vulnerabilities.some((v) => v.codeAwareScanResult.type === "analysisError")) {
190174
190276
  logger_singleton_1.logger.warn("Analysis error detected in the report - sharing log with Coana to help debug the issue");
190175
- await this.shareLogWithDashboard(new Error("Sharing log due to analysis error"), false);
190277
+ await this.shareErrorLogWithDashboard(new Error("Sharing log due to analysis error"), false);
190176
190278
  } else if (report.vulnerabilities.some((v) => v.ecosystem === "PIP")) {
190177
- await this.shareLogWithDashboard(new Error("Sharing log file for run including a python project"), false);
190279
+ await this.shareErrorLogWithDashboard(new Error("Sharing log file for run including a python project"), false);
190280
+ }
190281
+ if (this.options.runEnv === "MANAGED_SCAN") {
190282
+ this.shareLogWithDashboard();
190178
190283
  }
190179
190284
  if (this.options.printReport) {
190180
190285
  logger_singleton_1.logger.info(JSON.stringify((0, lodash_1.omit)(report, "dependencyTrees"), null, 2));
@@ -190226,18 +190331,10 @@ var require_cli_core = __commonJS({
190226
190331
  await this.spinner.setText(`Compiling report`);
190227
190332
  const allVulnerabilities = workspacesOutput.flatMap(({ vulnerabilities }) => vulnerabilities);
190228
190333
  this.spinner.stop();
190229
- const dependencyTrees = workspacesOutput.map(({ subprojectPath, workspacePath, dependencyTree }) => ({
190230
- treeType: "v1",
190231
- dependencyTree,
190232
- ecosystem: dependencyTree.ecosystem ?? "NPM",
190233
- workspacePath,
190234
- subprojectPath
190235
- }));
190236
190334
  const report = {
190237
- reportType: "v6",
190335
+ reportType: "v7",
190238
190336
  vulnerabilities: allVulnerabilities,
190239
- ...await this.createMetadataForReport(manager, startTime),
190240
- dependencyTrees: dependencyTrees.flat()
190337
+ ...await this.createMetadataForReport(manager, startTime)
190241
190338
  };
190242
190339
  return report;
190243
190340
  }
@@ -190365,6 +190462,19 @@ var require_cli_core = __commonJS({
190365
190462
  this.sendProgress("PREPARE_PROJECT_AND_GET_PROJECT_DATA", true, subprojectPath);
190366
190463
  const projectInfo = await otherModulesCommunicator.prepareProjectAndGetProjectData(packageManagerName, subprojectPath, workspacePaths, this.options.lightweightReachability, this.options.providerProject ? await this.runOnProvider(this.options.providerProject) : void 0);
190367
190464
  this.sendProgress("PREPARE_PROJECT_AND_GET_PROJECT_DATA", false, subprojectPath);
190465
+ const workspaceToPlainDependencyTree = Object.fromEntries(workspacePaths.map((workspacePath) => [
190466
+ workspacePath,
190467
+ (0, dependency_tree_1.toPlainDependencyTree)(projectInfo[workspacePath].dataForAnalysis.dependencyTree)
190468
+ ]));
190469
+ const dependencyTrees = workspacePaths.map((workspacePath) => ({
190470
+ treeType: "v1",
190471
+ dependencyTree: workspaceToPlainDependencyTree[workspacePath],
190472
+ ecosystem: workspaceToPlainDependencyTree[workspacePath].ecosystem ?? "NPM",
190473
+ workspacePath,
190474
+ subprojectPath: (0, path_1.relative)(rootWorkingDirectory, subprojectPath) || "."
190475
+ }));
190476
+ if (this.shareWithDashboard)
190477
+ (0, dashboard_integration_1.sendDependencyTreesToDashboard)(dependencyTrees, this.reportId, this.options.apiKey);
190368
190478
  const workspaceToVulnerabilities = Object.fromEntries(await (0, async_1.asyncMap)(workspacePaths, async (workspacePath) => this.spinner.wrap(`Scanning for vulnerabilities: (${subProjAndWsPath.packageManagerName}) ${(0, path_1.join)(subProjAndWsPath.subprojectPath, workspacePath)}`, async () => {
190369
190479
  const dependencyTree = projectInfo[workspacePath].dataForAnalysis.dependencyTree;
190370
190480
  this.sendProgress("SCAN_FOR_VULNERABILITIES", true, subprojectPath, workspacePath);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@coana-tech/cli",
3
- "version": "13.19.2",
3
+ "version": "13.19.4",
4
4
  "description": "Coana CLI",
5
5
  "bin": {
6
6
  "@coana-tech/cli": "./cli.js"