opencode-sonarqube 1.2.15 → 1.2.17
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/dist/index.js +35 -37
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -3999,10 +3999,10 @@ function numberToRating(num) {
|
|
|
3999
3999
|
const ratings = ["A", "B", "C", "D", "E"];
|
|
4000
4000
|
return ratings[num - 1] ?? "?";
|
|
4001
4001
|
}
|
|
4002
|
-
function SonarQubeError(message,
|
|
4002
|
+
function SonarQubeError(message, code, statusCode) {
|
|
4003
4003
|
const error45 = new Error(message);
|
|
4004
4004
|
error45.name = "SonarQubeError";
|
|
4005
|
-
error45.code =
|
|
4005
|
+
error45.code = code;
|
|
4006
4006
|
error45.statusCode = statusCode;
|
|
4007
4007
|
return error45;
|
|
4008
4008
|
}
|
|
@@ -17825,9 +17825,9 @@ class SourcesAPI {
|
|
|
17825
17825
|
from: from ?? 1,
|
|
17826
17826
|
to
|
|
17827
17827
|
});
|
|
17828
|
-
return response.sources.map(([line,
|
|
17828
|
+
return response.sources.map(([line, code]) => ({
|
|
17829
17829
|
line,
|
|
17830
|
-
code: this.stripHtmlTags(
|
|
17830
|
+
code: this.stripHtmlTags(code)
|
|
17831
17831
|
}));
|
|
17832
17832
|
} catch (error45) {
|
|
17833
17833
|
this.logger.warn(`Failed to fetch source lines: ${error45}`);
|
|
@@ -18056,6 +18056,14 @@ class DuplicationsAPI {
|
|
|
18056
18056
|
}
|
|
18057
18057
|
}
|
|
18058
18058
|
// src/api/ce.ts
|
|
18059
|
+
import { appendFileSync } from "node:fs";
|
|
18060
|
+
var debugLog = (msg) => {
|
|
18061
|
+
try {
|
|
18062
|
+
appendFileSync("/tmp/sonarqube-plugin-debug.log", `${new Date().toISOString()} [ce] ${msg}
|
|
18063
|
+
`);
|
|
18064
|
+
} catch {}
|
|
18065
|
+
};
|
|
18066
|
+
|
|
18059
18067
|
class ComputeEngineAPI {
|
|
18060
18068
|
client;
|
|
18061
18069
|
logger;
|
|
@@ -18118,21 +18126,39 @@ class ComputeEngineAPI {
|
|
|
18118
18126
|
const { current, queue } = await this.getComponentTasks(componentKey);
|
|
18119
18127
|
return current !== undefined || queue.length > 0;
|
|
18120
18128
|
}
|
|
18121
|
-
async waitForTask(taskId, pollIntervalMs = 2000) {
|
|
18129
|
+
async waitForTask(taskId, pollIntervalMs = 2000, maxWaitMs = 300000) {
|
|
18122
18130
|
this.logger.info(`Waiting for task to complete: ${taskId}`);
|
|
18123
|
-
|
|
18131
|
+
const startTime = Date.now();
|
|
18132
|
+
let taskNotFoundRetries = 0;
|
|
18133
|
+
const maxTaskNotFoundRetries = 10;
|
|
18134
|
+
debugLog(`waitForTask: starting for ${taskId}`);
|
|
18135
|
+
while (Date.now() - startTime < maxWaitMs) {
|
|
18124
18136
|
const task = await this.getTask(taskId);
|
|
18125
18137
|
if (!task) {
|
|
18126
|
-
|
|
18127
|
-
|
|
18138
|
+
taskNotFoundRetries++;
|
|
18139
|
+
debugLog(`waitForTask: task not found, retry ${taskNotFoundRetries}/${maxTaskNotFoundRetries}`);
|
|
18140
|
+
if (taskNotFoundRetries >= maxTaskNotFoundRetries) {
|
|
18141
|
+
this.logger.warn(`Task ${taskId} not found after ${maxTaskNotFoundRetries} retries`);
|
|
18142
|
+
debugLog(`waitForTask: giving up after ${maxTaskNotFoundRetries} retries`);
|
|
18143
|
+
return;
|
|
18144
|
+
}
|
|
18145
|
+
this.logger.debug(`Task ${taskId} not found yet, retrying (${taskNotFoundRetries}/${maxTaskNotFoundRetries})...`);
|
|
18146
|
+
await new Promise((resolve) => setTimeout(resolve, pollIntervalMs));
|
|
18147
|
+
continue;
|
|
18128
18148
|
}
|
|
18149
|
+
taskNotFoundRetries = 0;
|
|
18150
|
+
debugLog(`waitForTask: task found, status=${task.status}`);
|
|
18129
18151
|
if (task.status === "SUCCESS" || task.status === "FAILED" || task.status === "CANCELED") {
|
|
18130
18152
|
this.logger.info(`Task completed with status: ${task.status}`);
|
|
18153
|
+
debugLog(`waitForTask: task completed with ${task.status}`);
|
|
18131
18154
|
return task;
|
|
18132
18155
|
}
|
|
18133
18156
|
this.logger.debug(`Task in progress: ${task.status}`);
|
|
18134
18157
|
await new Promise((resolve) => setTimeout(resolve, pollIntervalMs));
|
|
18135
18158
|
}
|
|
18159
|
+
this.logger.warn(`Timeout waiting for task ${taskId}`);
|
|
18160
|
+
debugLog(`waitForTask: timeout after ${maxWaitMs}ms`);
|
|
18161
|
+
return;
|
|
18136
18162
|
}
|
|
18137
18163
|
async waitForAnalysis(componentKey, timeoutMs = 300000, pollIntervalMs = 2000) {
|
|
18138
18164
|
this.logger.info(`Waiting for analysis to complete: ${componentKey}`);
|
|
@@ -18902,14 +18928,7 @@ function formatIssueBlock(issue2, _number2) {
|
|
|
18902
18928
|
}
|
|
18903
18929
|
|
|
18904
18930
|
// src/scanner/runner.ts
|
|
18905
|
-
import { appendFileSync } from "node:fs";
|
|
18906
18931
|
var logger3 = new Logger("scanner-runner");
|
|
18907
|
-
var debugLog = (msg) => {
|
|
18908
|
-
try {
|
|
18909
|
-
appendFileSync("/tmp/sonarqube-plugin-debug.log", `${new Date().toISOString()} [runner] ${msg}
|
|
18910
|
-
`);
|
|
18911
|
-
} catch {}
|
|
18912
|
-
};
|
|
18913
18932
|
function extractTaskId(output) {
|
|
18914
18933
|
const taskIdRegex = /api\/ce\/task\?id=(\w+)/;
|
|
18915
18934
|
const taskIdMatch = taskIdRegex.exec(output);
|
|
@@ -19009,7 +19028,6 @@ async function runAnalysis(config2, state, options, directory) {
|
|
|
19009
19028
|
exclusions: options.exclusions ?? config2.exclusions
|
|
19010
19029
|
}, config2, dir);
|
|
19011
19030
|
}
|
|
19012
|
-
debugLog(`Running scanner for ${options.projectKey}...`);
|
|
19013
19031
|
const scannerResult = await runScanner(config2, state, {
|
|
19014
19032
|
projectKey: options.projectKey,
|
|
19015
19033
|
projectName,
|
|
@@ -19020,35 +19038,25 @@ async function runAnalysis(config2, state, options, directory) {
|
|
|
19020
19038
|
pullRequest: options.pullRequest,
|
|
19021
19039
|
branch: options.branch
|
|
19022
19040
|
}, dir);
|
|
19023
|
-
debugLog(`Scanner result: success=${scannerResult.success}, taskId=${scannerResult.taskId ?? "NONE"}, exitCode=${scannerResult.exitCode}`);
|
|
19024
19041
|
if (scannerResult.success && scannerResult.taskId) {
|
|
19025
|
-
debugLog(`Waiting for task ${scannerResult.taskId}...`);
|
|
19026
19042
|
logger3.info(`Waiting for analysis task ${scannerResult.taskId} to complete...`);
|
|
19027
19043
|
try {
|
|
19028
19044
|
const task = await api2.ce.waitForTask(scannerResult.taskId);
|
|
19029
19045
|
if (task) {
|
|
19030
|
-
debugLog(`Task completed: status=${task.status}`);
|
|
19031
19046
|
logger3.info(`Analysis task completed: ${task.status}`);
|
|
19032
19047
|
if (task.status === "FAILED") {
|
|
19033
|
-
debugLog(`Task FAILED: ${task.errorMessage ?? "Unknown error"}`);
|
|
19034
19048
|
logger3.error(`Analysis failed: ${task.errorMessage ?? "Unknown error"}`);
|
|
19035
19049
|
}
|
|
19036
19050
|
} else {
|
|
19037
|
-
debugLog(`Task not found!`);
|
|
19038
19051
|
logger3.warn("Task not found - continuing with available results");
|
|
19039
19052
|
}
|
|
19040
19053
|
} catch (waitError) {
|
|
19041
|
-
debugLog(`waitForTask error: ${waitError instanceof Error ? waitError.message : String(waitError)}`);
|
|
19042
19054
|
logger3.debug("Could not wait for task via CE API", { waitError });
|
|
19043
19055
|
}
|
|
19044
19056
|
} else if (scannerResult.success) {
|
|
19045
|
-
debugLog(`No task ID found, waiting 3 seconds...`);
|
|
19046
19057
|
logger3.debug("No task ID in scanner output, waiting briefly...");
|
|
19047
19058
|
await Bun.sleep(3000);
|
|
19048
|
-
} else {
|
|
19049
|
-
debugLog(`Scanner failed - not waiting for task`);
|
|
19050
19059
|
}
|
|
19051
|
-
debugLog(`Fetching quality gate and issues from API...`);
|
|
19052
19060
|
try {
|
|
19053
19061
|
const [qgStatus, issueCounts, formattedIssues] = await Promise.all([
|
|
19054
19062
|
api2.qualityGate.getStatus(options.projectKey),
|
|
@@ -19056,8 +19064,6 @@ async function runAnalysis(config2, state, options, directory) {
|
|
|
19056
19064
|
api2.issues.getFormattedIssues({ projectKey: options.projectKey })
|
|
19057
19065
|
]);
|
|
19058
19066
|
const qualityGateStatus = qgStatus.projectStatus.status;
|
|
19059
|
-
debugLog(`Quality gate: ${qualityGateStatus}`);
|
|
19060
|
-
debugLog(`Issues: blocker=${issueCounts.blocker}, critical=${issueCounts.critical}, major=${issueCounts.major}`);
|
|
19061
19067
|
let metrics = {
|
|
19062
19068
|
bugs: issueCounts.blocker + issueCounts.critical,
|
|
19063
19069
|
vulnerabilities: 0,
|
|
@@ -20238,9 +20244,6 @@ if (isDirectCLI) {
|
|
|
20238
20244
|
}
|
|
20239
20245
|
|
|
20240
20246
|
// src/index.ts
|
|
20241
|
-
function executeUserCode(code) {
|
|
20242
|
-
return eval(code);
|
|
20243
|
-
}
|
|
20244
20247
|
var SHARED_STATE_FILE = "/tmp/sonarqube-plugin-shared-state.json";
|
|
20245
20248
|
var readSharedState = () => {
|
|
20246
20249
|
try {
|
|
@@ -20677,13 +20680,8 @@ Fix these issues before ${operationType === "commit" ? "committing" : "pushing"}
|
|
|
20677
20680
|
return checkExistingIssuesAndBlock(api2, state.projectKey, operationType, blockingSeverity, shouldBlock);
|
|
20678
20681
|
}
|
|
20679
20682
|
await showToast("SonarQube: Running pre-commit analysis...", "info");
|
|
20680
|
-
safeLog(`[handleGitOperationCheck] Starting runAnalysis...`);
|
|
20681
20683
|
const analysisResult = await runAnalysis(config2, state, { projectKey: state.projectKey }, dir);
|
|
20682
|
-
safeLog(`[handleGitOperationCheck]
|
|
20683
|
-
safeLog(` qualityGate=${analysisResult.qualityGateStatus}`);
|
|
20684
|
-
safeLog(` issues: blocker=${analysisResult.issues.blocker}, critical=${analysisResult.issues.critical}, major=${analysisResult.issues.major}`);
|
|
20685
|
-
safeLog(` success=${analysisResult.success}`);
|
|
20686
|
-
safeLog(` blockingSeverity=${blockingSeverity}, shouldBlock=${shouldBlock}`);
|
|
20684
|
+
safeLog(`[handleGitOperationCheck] qualityGate=${analysisResult.qualityGateStatus}`);
|
|
20687
20685
|
return processAnalysisResult(analysisResult, blockingSeverity, shouldBlock, fixBeforeCommit, autoFix);
|
|
20688
20686
|
} catch (err) {
|
|
20689
20687
|
safeLog(`[handleGitOperationCheck] ERROR: ${err instanceof Error ? err.message : String(err)}`);
|