@rsaglobaltech/specgate 0.25.0 → 0.27.1

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 (97) hide show
  1. package/CHANGELOG.md +87 -42
  2. package/README.md +6 -0
  3. package/dist/packages/core/src/domain/AgentPrompt.js +12 -0
  4. package/dist/packages/core/src/domain/AgentPrompt.js.map +1 -1
  5. package/dist/packages/core/src/domain/ChangeMeasures.js +198 -0
  6. package/dist/packages/core/src/domain/ChangeMeasures.js.map +1 -0
  7. package/dist/packages/core/src/domain/Clarification.js +5 -0
  8. package/dist/packages/core/src/domain/Clarification.js.map +1 -1
  9. package/dist/packages/core/src/domain/ConventionalCommit.js +73 -0
  10. package/dist/packages/core/src/domain/ConventionalCommit.js.map +1 -0
  11. package/dist/packages/core/src/domain/HarnessConfig.js.map +1 -1
  12. package/dist/packages/core/src/domain/HarnessReport.js +2 -0
  13. package/dist/packages/core/src/domain/HarnessReport.js.map +1 -1
  14. package/dist/packages/core/src/domain/QualityChecks.js +218 -0
  15. package/dist/packages/core/src/domain/QualityChecks.js.map +1 -0
  16. package/dist/packages/core/src/domain/QualitySummary.js +58 -0
  17. package/dist/packages/core/src/domain/QualitySummary.js.map +1 -0
  18. package/dist/packages/core/src/domain/RequirementPlan.js +11 -0
  19. package/dist/packages/core/src/domain/RequirementPlan.js.map +1 -1
  20. package/dist/packages/core/src/domain/Sarif.js +121 -0
  21. package/dist/packages/core/src/domain/Sarif.js.map +1 -0
  22. package/dist/packages/core/src/infrastructure/ChangeWorkspace.js +15 -3
  23. package/dist/packages/core/src/infrastructure/ChangeWorkspace.js.map +1 -1
  24. package/dist/packages/core/src/infrastructure/GitContributionStager.js +1 -1
  25. package/dist/packages/core/src/infrastructure/GitContributionStager.js.map +1 -1
  26. package/dist/packages/core/src/infrastructure/HarnessConfigFile.js +26 -0
  27. package/dist/packages/core/src/infrastructure/HarnessConfigFile.js.map +1 -1
  28. package/dist/packages/core/src/infrastructure/IdsAcrossBranches.js +4 -1
  29. package/dist/packages/core/src/infrastructure/IdsAcrossBranches.js.map +1 -1
  30. package/dist/packages/core/src/infrastructure/QualityBaselineFile.js +67 -0
  31. package/dist/packages/core/src/infrastructure/QualityBaselineFile.js.map +1 -0
  32. package/dist/packages/core/test/unit/rework.test.js +62 -0
  33. package/dist/packages/core/test/unit/rework.test.js.map +1 -0
  34. package/dist/scripts/cli/commands/change/ChangeCommand.js +38 -1
  35. package/dist/scripts/cli/commands/change/ChangeCommand.js.map +1 -1
  36. package/dist/scripts/cli/commands/change/TicketCommand.js +1 -1
  37. package/dist/scripts/cli/commands/change/TicketCommand.js.map +1 -1
  38. package/dist/scripts/cli/commands/harness/RunCommand.js +269 -17
  39. package/dist/scripts/cli/commands/harness/RunCommand.js.map +1 -1
  40. package/dist/scripts/cli/commands/quality/CheckCommand.js +54 -3
  41. package/dist/scripts/cli/commands/quality/CheckCommand.js.map +1 -1
  42. package/dist/scripts/cli/commands/quality/QualityCommand.js +314 -0
  43. package/dist/scripts/cli/commands/quality/QualityCommand.js.map +1 -0
  44. package/dist/scripts/cli/commands/spec/DoneCommand.js +4 -1
  45. package/dist/scripts/cli/commands/spec/DoneCommand.js.map +1 -1
  46. package/dist/scripts/cli/commands/spec/DraftCommand.js +44 -4
  47. package/dist/scripts/cli/commands/spec/DraftCommand.js.map +1 -1
  48. package/dist/scripts/cli/commands/spec/StatusCommand.js +5 -1
  49. package/dist/scripts/cli/commands/spec/StatusCommand.js.map +1 -1
  50. package/dist/scripts/cli/commands/spec/StudioCommand.js +208 -1
  51. package/dist/scripts/cli/commands/spec/StudioCommand.js.map +1 -1
  52. package/dist/scripts/docs/nav.js +13 -2
  53. package/dist/scripts/docs/nav.js.map +1 -1
  54. package/dist/scripts/docs/record-journey.js +1 -0
  55. package/dist/scripts/docs/record-journey.js.map +1 -1
  56. package/dist/scripts/docs/record-terminal.js +18 -0
  57. package/dist/scripts/docs/record-terminal.js.map +1 -1
  58. package/dist/scripts/draft/drafting-guide.js +11 -1
  59. package/dist/scripts/draft/drafting-guide.js.map +1 -1
  60. package/dist/scripts/harness/prompt.js +4 -0
  61. package/dist/scripts/harness/prompt.js.map +1 -1
  62. package/dist/scripts/harness/report.js +13 -0
  63. package/dist/scripts/harness/report.js.map +1 -1
  64. package/dist/scripts/lib/change-review.js +145 -0
  65. package/dist/scripts/lib/change-review.js.map +1 -0
  66. package/dist/scripts/lib/clarification.js +24 -5
  67. package/dist/scripts/lib/clarification.js.map +1 -1
  68. package/dist/scripts/lib/harness-guard.js +18 -0
  69. package/dist/scripts/lib/harness-guard.js.map +1 -1
  70. package/dist/scripts/lib/in-flight.js +17 -11
  71. package/dist/scripts/lib/in-flight.js.map +1 -1
  72. package/dist/scripts/lib/live-model.js +7 -1
  73. package/dist/scripts/lib/live-model.js.map +1 -1
  74. package/dist/scripts/lib/live-page.js +72 -11
  75. package/dist/scripts/lib/live-page.js.map +1 -1
  76. package/dist/scripts/lib/quality-presets.js +378 -0
  77. package/dist/scripts/lib/quality-presets.js.map +1 -0
  78. package/dist/scripts/lib/quality-run.js +579 -0
  79. package/dist/scripts/lib/quality-run.js.map +1 -0
  80. package/dist/scripts/lib/screen-requirements.js +149 -0
  81. package/dist/scripts/lib/screen-requirements.js.map +1 -0
  82. package/dist/scripts/lib/sonar-local.js +308 -0
  83. package/dist/scripts/lib/sonar-local.js.map +1 -0
  84. package/dist/scripts/lib/studio-app-page.js +1023 -0
  85. package/dist/scripts/lib/studio-app-page.js.map +1 -0
  86. package/dist/scripts/lib/studio-app.js +442 -0
  87. package/dist/scripts/lib/studio-app.js.map +1 -0
  88. package/dist/scripts/lib/studio-route.js +996 -0
  89. package/dist/scripts/lib/studio-route.js.map +1 -0
  90. package/dist/scripts/lib/surface.js +11 -0
  91. package/dist/scripts/lib/surface.js.map +1 -1
  92. package/dist/scripts/lib/ticket-keys.js +1 -1
  93. package/dist/scripts/lib/ticket-keys.js.map +1 -1
  94. package/dist/scripts/quality.js +10 -0
  95. package/dist/scripts/quality.js.map +1 -0
  96. package/package.json +1 -1
  97. package/templates/harness/harness.config.yaml.tpl +10 -1
@@ -0,0 +1,149 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.SCREEN_SURFACES = void 0;
37
+ exports.requirementSurfaces = requirementSurfaces;
38
+ exports.onScreen = onScreen;
39
+ exports.e2eTestsNaming = e2eTestsNaming;
40
+ const fs = __importStar(require("node:fs"));
41
+ const path = __importStar(require("node:path"));
42
+ const DraftChecklist_1 = require("../../packages/core/src/domain/DraftChecklist");
43
+ /**
44
+ * Which requirements are used on a screen, and whether an end-to-end test
45
+ * names them (REQ-199). Twenty requirements of the form "WHEN the user taps
46
+ * …, THEN they see …" passed the harness with a use case and a unit test and
47
+ * no screen at all; with `e2e_dir` set, the gate asks for the e2e test.
48
+ */
49
+ /** The surfaces that are a screen someone looks at. */
50
+ exports.SCREEN_SURFACES = new Set(["web", "mobile", "tablet", "desktop"]);
51
+ function read(file) {
52
+ try {
53
+ return fs.readFileSync(file, "utf8");
54
+ }
55
+ catch {
56
+ return "";
57
+ }
58
+ }
59
+ function specFiles(dir) {
60
+ const out = [path.join(dir, "spec.md")];
61
+ const walk = (d) => {
62
+ let entries = [];
63
+ try {
64
+ entries = fs.readdirSync(d, { withFileTypes: true });
65
+ }
66
+ catch {
67
+ return;
68
+ }
69
+ for (const e of entries) {
70
+ const full = path.join(d, e.name);
71
+ if (e.isDirectory() && e.name !== "archive")
72
+ walk(full);
73
+ else if (e.name === "spec.md")
74
+ out.push(full);
75
+ }
76
+ };
77
+ walk(path.join(dir, "docs", "specs"));
78
+ return out;
79
+ }
80
+ /** The trace comment of a requirement, wherever the project defines it. */
81
+ function traceOf(dir, id) {
82
+ const head = new RegExp(`^(?:###\\s+Requirement:|#{2,3})\\s+${id}\\b`);
83
+ for (const file of specFiles(dir)) {
84
+ const lines = read(file).split(/\r?\n/);
85
+ const at = lines.findIndex((l) => head.test(l));
86
+ if (at === -1)
87
+ continue;
88
+ for (let i = at + 1; i < lines.length && !/^#{2,3}\s(?!#)/.test(lines[i]); i += 1) {
89
+ if (/<!--\s*specgate:trace\b/.test(lines[i]))
90
+ return lines[i];
91
+ }
92
+ return "";
93
+ }
94
+ return "";
95
+ }
96
+ function field(trace, name) {
97
+ const m = new RegExp(`\\b${name}=(?:"([^"]*)"|([^\\s"]+?))(?=\\s|-->)`).exec(trace);
98
+ return m ? m[1] || m[2] || "" : "";
99
+ }
100
+ /**
101
+ * The surfaces a requirement is used on: its own `surfaces=`, else its actor's
102
+ * in the brief's front matter. Empty when neither says.
103
+ */
104
+ function requirementSurfaces(dir, id) {
105
+ const trace = traceOf(dir, id);
106
+ const own = field(trace, "surfaces");
107
+ if (own)
108
+ return own.split(/[,\s]+/).filter(Boolean);
109
+ const actor = field(trace, "actor").toLowerCase();
110
+ if (!actor)
111
+ return [];
112
+ for (const rel of [path.join("docs", "brief.md"), "brief.md"]) {
113
+ const brief = read(path.join(dir, rel));
114
+ if (brief)
115
+ return (0, DraftChecklist_1.actorSurfaces)(brief).get(actor) || [];
116
+ }
117
+ return [];
118
+ }
119
+ /** Whether the requirement is used on a screen. */
120
+ function onScreen(dir, id) {
121
+ return requirementSurfaces(dir, id).some((s) => exports.SCREEN_SURFACES.has(s.toLowerCase()));
122
+ }
123
+ /** The files under the e2e folder whose name or content names the requirement. */
124
+ function e2eTestsNaming(dir, e2eDir, id) {
125
+ const named = new RegExp(`(^|[^\\w-])${id}(?!\\d)`);
126
+ const out = [];
127
+ const walk = (d) => {
128
+ let entries = [];
129
+ try {
130
+ entries = fs.readdirSync(d, { withFileTypes: true });
131
+ }
132
+ catch {
133
+ return;
134
+ }
135
+ for (const e of entries) {
136
+ const full = path.join(d, e.name);
137
+ if (e.isDirectory()) {
138
+ if (e.name !== "node_modules" && !e.name.startsWith("."))
139
+ walk(full);
140
+ }
141
+ else if (named.test(e.name) || named.test(read(full))) {
142
+ out.push(path.relative(dir, full).split(path.sep).join("/"));
143
+ }
144
+ }
145
+ };
146
+ walk(path.join(dir, e2eDir));
147
+ return out;
148
+ }
149
+ //# sourceMappingURL=screen-requirements.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"screen-requirements.js","sourceRoot":"","sources":["../../../scripts/lib/screen-requirements.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,308 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.SONAR_SARIF = exports.SONAR = void 0;
37
+ exports.ensureServer = ensureServer;
38
+ exports.analysisToken = analysisToken;
39
+ exports.projectKey = projectKey;
40
+ exports.scannerProperties = scannerProperties;
41
+ exports.issuesToSarif = issuesToSarif;
42
+ exports.runSonar = runSonar;
43
+ const fs = __importStar(require("node:fs"));
44
+ const path = __importStar(require("node:path"));
45
+ const node_child_process_1 = require("node:child_process");
46
+ /**
47
+ * SonarQube Community, run locally in Docker, as one more check (REQ-226):
48
+ * no account and no server to host. The first run starts the server in a
49
+ * named container on a private network, bound to 127.0.0.1 only; a token for
50
+ * analysis is created once with the server's own default login and kept in
51
+ * `.specgate/sonar.local`, git-ignored — the person's admin password is never
52
+ * changed or stored, so they log in with admin/admin and choose their own.
53
+ * Each run analyses the project with the scanner image and writes the open
54
+ * issues as SARIF, so the baseline judges them like any other check's.
55
+ */
56
+ exports.SONAR = {
57
+ image: "sonarqube:25.9.0.112764-community",
58
+ scanner: "sonarsource/sonar-scanner-cli:11.4",
59
+ container: "specgate-sonarqube",
60
+ network: "specgate-sonar",
61
+ port: 9123,
62
+ };
63
+ const BASE = `http://127.0.0.1:${exports.SONAR.port}`;
64
+ const LOCAL = path.join(".specgate", "sonar.local");
65
+ exports.SONAR_SARIF = ".specgate/quality/sonar.sarif";
66
+ const docker = (args, timeout = 120000) => (0, node_child_process_1.spawnSync)("docker", args, { encoding: "utf8", timeout });
67
+ /**
68
+ * One HTTP call, synchronously: the checks run in spawnSync's world, so a
69
+ * short Node child does the fetch and prints the JSON.
70
+ */
71
+ function http(method, url, auth, form) {
72
+ const script = [
73
+ "(async () => {",
74
+ " try {",
75
+ " const [method, url, auth, form] = JSON.parse(process.argv[1]);",
76
+ " const r = await fetch(url, {",
77
+ " method,",
78
+ " headers: Object.assign(auth ? { Authorization: 'Basic ' + Buffer.from(auth).toString('base64') } : {},",
79
+ " form ? { 'content-type': 'application/x-www-form-urlencoded' } : {}),",
80
+ " body: form ? new URLSearchParams(form).toString() : undefined,",
81
+ " });",
82
+ " const text = await r.text();",
83
+ " let body = null; try { body = JSON.parse(text); } catch { body = text; }",
84
+ " process.stdout.write(JSON.stringify({ status: r.status, body }));",
85
+ " } catch (e) { process.stdout.write(JSON.stringify({ status: 0, body: String(e) })); }",
86
+ "})();",
87
+ ].join("\n");
88
+ const r = (0, node_child_process_1.spawnSync)(process.execPath, ["-e", script, JSON.stringify([method, url, auth, form || null])], {
89
+ encoding: "utf8",
90
+ timeout: 60000,
91
+ });
92
+ try {
93
+ return JSON.parse(r.stdout || "");
94
+ }
95
+ catch {
96
+ return { status: 0, body: r.stderr || "" };
97
+ }
98
+ }
99
+ const sleep = (ms) => (0, node_child_process_1.spawnSync)(process.execPath, ["-e", `setTimeout(() => {}, ${ms})`]);
100
+ /** The server, started if it is not, and answering UP. */
101
+ function ensureServer(timeoutMs = 5 * 60 * 1000) {
102
+ docker(["network", "create", exports.SONAR.network]);
103
+ const state = (docker(["inspect", "-f", "{{.State.Running}}", exports.SONAR.container]).stdout || "").trim();
104
+ if (state === "false")
105
+ docker(["start", exports.SONAR.container]);
106
+ else if (state !== "true") {
107
+ const run = docker([
108
+ "run",
109
+ "-d",
110
+ "--name",
111
+ exports.SONAR.container,
112
+ "--network",
113
+ exports.SONAR.network,
114
+ "-p",
115
+ `127.0.0.1:${exports.SONAR.port}:9000`,
116
+ // Its Elasticsearch asks the host for vm.max_map_count; Docker Desktop
117
+ // does not let a container set it, and one local instance does not need it.
118
+ "-e",
119
+ "SONAR_ES_BOOTSTRAP_CHECKS_DISABLE=true",
120
+ "-v",
121
+ "specgate-sonar-data:/opt/sonarqube/data",
122
+ "-v",
123
+ "specgate-sonar-extensions:/opt/sonarqube/extensions",
124
+ exports.SONAR.image,
125
+ ], 15 * 60 * 1000);
126
+ if (run.status !== 0) {
127
+ return { ok: false, message: `could not start SonarQube: ${(run.stderr || "").trim()}` };
128
+ }
129
+ }
130
+ const until = Date.now() + timeoutMs;
131
+ while (Date.now() < until) {
132
+ const r = http("GET", `${BASE}/api/system/status`, "");
133
+ if (r.status === 200 && r.body.status === "UP")
134
+ return { ok: true };
135
+ sleep(3000);
136
+ }
137
+ return {
138
+ ok: false,
139
+ message: `SonarQube did not come up at ${BASE} within ${timeoutMs / 60000} min`,
140
+ };
141
+ }
142
+ /** The analysis token: SONAR_TOKEN, else the one kept, else one created with the default login. */
143
+ function analysisToken(projectDir) {
144
+ if (process.env.SONAR_TOKEN)
145
+ return { ok: true, token: process.env.SONAR_TOKEN };
146
+ const file = path.join(projectDir, LOCAL);
147
+ try {
148
+ const kept = JSON.parse(fs.readFileSync(file, "utf8")).token;
149
+ const checked = kept ? http("GET", `${BASE}/api/authentication/validate`, `${kept}:`) : null;
150
+ if (checked && checked.status === 200 && checked.body.valid) {
151
+ return { ok: true, token: kept };
152
+ }
153
+ }
154
+ catch {
155
+ /* none kept yet */
156
+ }
157
+ const made = http("POST", `${BASE}/api/user_tokens/generate`, "admin:admin", {
158
+ name: `specgate-${path.basename(projectDir)}-${Date.now()}`,
159
+ type: "GLOBAL_ANALYSIS_TOKEN",
160
+ });
161
+ const token = made.body.token;
162
+ if (made.status !== 200 || !token) {
163
+ return {
164
+ ok: false,
165
+ message: "SonarQube's default login no longer works (its password was changed, as it should be). " +
166
+ `Create a token at ${BASE}/account/security and set it as SONAR_TOKEN in the environment.`,
167
+ };
168
+ }
169
+ fs.mkdirSync(path.dirname(file), { recursive: true });
170
+ fs.writeFileSync(file, JSON.stringify({ token }, null, 2) + "\n", "utf8");
171
+ ensureIgnored(projectDir, ".specgate/sonar.local");
172
+ return { ok: true, token };
173
+ }
174
+ /** A line in the project's .gitignore, added once. */
175
+ function ensureIgnored(projectDir, entry) {
176
+ const file = path.join(projectDir, ".gitignore");
177
+ const text = fs.existsSync(file) ? fs.readFileSync(file, "utf8") : "";
178
+ if (!text.split(/\r?\n/).includes(entry)) {
179
+ fs.writeFileSync(file, `${text.replace(/\n?$/, "\n")}${entry}\n`, "utf8");
180
+ }
181
+ }
182
+ /** The project key: the folder's name, as SonarQube accepts it. */
183
+ function projectKey(projectDir) {
184
+ return (path
185
+ .basename(path.resolve(projectDir))
186
+ .replace(/[^A-Za-z0-9_.:-]+/g, "-")
187
+ .replace(/^-|-$/g, "") || "project");
188
+ }
189
+ /** The scanner's properties for this project: Java sources and classes when it has them. */
190
+ function scannerProperties(projectDir, key) {
191
+ const has = (rel) => fs.existsSync(path.join(projectDir, rel));
192
+ const props = [
193
+ `-Dsonar.projectKey=${key}`,
194
+ "-Dsonar.scm.disabled=true",
195
+ "-Dsonar.working.directory=.specgate/quality/sonar",
196
+ ];
197
+ if (has("src/main/java")) {
198
+ props.push("-Dsonar.sources=src/main/java");
199
+ if (has("src/test/java"))
200
+ props.push("-Dsonar.tests=src/test/java");
201
+ props.push(`-Dsonar.java.binaries=${has("target/classes") ? "target/classes" : has("build/classes") ? "build/classes" : "."}`);
202
+ }
203
+ else {
204
+ props.push("-Dsonar.sources=.", "-Dsonar.exclusions=**/node_modules/**,**/dist/**,**/build/**,**/coverage/**,**/.specgate/**,**/.harness/**");
205
+ }
206
+ return props;
207
+ }
208
+ /** SonarQube's open issues as SARIF 2.1.0, its line hash as the fingerprint. */
209
+ function issuesToSarif(issues, key) {
210
+ const level = (s) => s === "BLOCKER" || s === "CRITICAL" ? "error" : s === "MAJOR" ? "warning" : "note";
211
+ return JSON.stringify({
212
+ version: "2.1.0",
213
+ runs: [
214
+ {
215
+ tool: { driver: { name: "SonarQube Community" } },
216
+ results: issues.map((i) => ({
217
+ ruleId: i.rule,
218
+ level: level(i.severity),
219
+ message: { text: i.message },
220
+ locations: [
221
+ {
222
+ physicalLocation: {
223
+ artifactLocation: { uri: i.component.replace(new RegExp(`^${key}:`), "") },
224
+ region: { startLine: i.line || 1 },
225
+ },
226
+ },
227
+ ],
228
+ ...(i.hash ? { partialFingerprints: { sonarLineHash: i.hash } } : {}),
229
+ })),
230
+ },
231
+ ],
232
+ }, null, 2);
233
+ }
234
+ /** Analyse the project and write its open issues as SARIF; shaped like spawnSync's result. */
235
+ function runSonar(projectDir, timeoutMs) {
236
+ const fail = (message) => ({ status: 1, stdout: "", stderr: message });
237
+ const up = ensureServer();
238
+ if (!up.ok)
239
+ return fail(up.message);
240
+ const tok = analysisToken(projectDir);
241
+ if (!tok.ok)
242
+ return fail(tok.message);
243
+ const key = projectKey(projectDir);
244
+ const posix = process.platform !== "win32" && typeof process.getuid === "function";
245
+ const scan = (0, node_child_process_1.spawnSync)("docker", [
246
+ "run",
247
+ "--rm",
248
+ "--network",
249
+ exports.SONAR.network,
250
+ "-v",
251
+ `${path.resolve(projectDir)}:/usr/src`,
252
+ "-w",
253
+ "/usr/src",
254
+ ...(posix ? ["--user", `${process.getuid()}:${process.getgid ? process.getgid() : 0}`] : []),
255
+ "-e",
256
+ "SONAR_TOKEN",
257
+ "-e",
258
+ `SONAR_HOST_URL=http://${exports.SONAR.container}:9000`,
259
+ "-e",
260
+ "SONAR_USER_HOME=/tmp/.sonar",
261
+ exports.SONAR.scanner,
262
+ ...scannerProperties(projectDir, key),
263
+ ], {
264
+ encoding: "utf8",
265
+ timeout: timeoutMs,
266
+ maxBuffer: 64 * 1024 * 1024,
267
+ env: { ...process.env, SONAR_TOKEN: tok.token },
268
+ });
269
+ if (scan.status !== 0) {
270
+ return {
271
+ status: scan.status,
272
+ stdout: scan.stdout || "",
273
+ stderr: scan.stderr || "",
274
+ error: scan.error,
275
+ };
276
+ }
277
+ // The analysis is processed on the server after the scanner ends.
278
+ const report = path.join(projectDir, ".specgate", "quality", "sonar", "report-task.txt");
279
+ const task = (/ceTaskId=(\S+)/.exec(fs.existsSync(report) ? fs.readFileSync(report, "utf8") : "") || [])[1];
280
+ if (task) {
281
+ for (let i = 0; i < 120; i += 1) {
282
+ const t = http("GET", `${BASE}/api/ce/task?id=${task}`, `${tok.token}:`).body;
283
+ const status = t && t.task ? t.task.status : "";
284
+ if (status && status !== "PENDING" && status !== "IN_PROGRESS")
285
+ break;
286
+ sleep(2000);
287
+ }
288
+ }
289
+ const issues = [];
290
+ for (let page = 1; page <= 20; page += 1) {
291
+ const r = http("GET", `${BASE}/api/issues/search?componentKeys=${encodeURIComponent(key)}&resolved=false&ps=500&p=${page}`, `${tok.token}:`);
292
+ const body = r.body;
293
+ if (r.status !== 200 || !body.issues)
294
+ return fail(`could not read the issues: HTTP ${r.status}`);
295
+ issues.push(...body.issues);
296
+ if (issues.length >= (body.total || 0) || body.issues.length === 0)
297
+ break;
298
+ }
299
+ const out = path.join(projectDir, exports.SONAR_SARIF);
300
+ fs.mkdirSync(path.dirname(out), { recursive: true });
301
+ fs.writeFileSync(out, issuesToSarif(issues, key), "utf8");
302
+ return {
303
+ status: 0,
304
+ stdout: `SonarQube analysed ${key}: ${issues.length} open issue(s). ${BASE}/dashboard?id=${encodeURIComponent(key)}`,
305
+ stderr: "",
306
+ };
307
+ }
308
+ //# sourceMappingURL=sonar-local.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sonar-local.js","sourceRoot":"","sources":["../../../scripts/lib/sonar-local.ts"],"names":[],"mappings":"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"}