@godv61/dsh-task-engine 0.30.1 → 0.30.3

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.
@@ -0,0 +1,82 @@
1
+ function apiUrl(host, path) {
2
+ return new URL(`${host.replace(/\/$/u, '')}${path}`);
3
+ }
4
+ async function readJson(url, token, fetcher) {
5
+ const response = await fetcher(url, { headers: { Authorization: `Bearer ${token}` }, signal: AbortSignal.timeout(15_000) });
6
+ if (!response.ok)
7
+ throw new Error(`SonarQube 规则查询失败(HTTP ${response.status})`);
8
+ return response.json();
9
+ }
10
+ /** The last server analysis supplies the project's actual languages; a new project may have none yet. */
11
+ export function parseAnalyzedLanguages(value) {
12
+ if (typeof value !== 'string')
13
+ return [];
14
+ return [...new Set(value.split(';').flatMap(part => {
15
+ const match = /^([a-z][a-z0-9_-]*)=\d+$/iu.exec(part.trim());
16
+ return match ? [match[1].toUpperCase()] : [];
17
+ }))];
18
+ }
19
+ export async function projectAnalyzedLanguages(host, project, token, fetcher = fetch) {
20
+ const url = apiUrl(host, '/api/measures/component');
21
+ url.searchParams.set('component', project);
22
+ url.searchParams.set('metricKeys', 'ncloc_language_distribution');
23
+ try {
24
+ const data = await readJson(url, token, fetcher);
25
+ return parseAnalyzedLanguages(data?.component?.measures?.find((measure) => measure.metric === 'ncloc_language_distribution')?.value);
26
+ }
27
+ catch {
28
+ // Projects without an analysis or metric permission can still inspect their configured profiles.
29
+ return [];
30
+ }
31
+ }
32
+ /** Only project-effective profiles are queried; rules are fetched for the selected profile on demand. */
33
+ export async function listSonarProjectRules(host, project, token, language, fetcher = fetch) {
34
+ const url = apiUrl(host, '/api/qualityprofiles/search');
35
+ url.searchParams.set('project', project);
36
+ const [data, analyzed_languages] = await Promise.all([
37
+ readJson(url, token, fetcher), projectAnalyzedLanguages(host, project, token, fetcher),
38
+ ]);
39
+ if (!Array.isArray(data?.profiles))
40
+ throw new Error('SonarQube 未返回当前项目的 Quality Profile');
41
+ const analyzed = new Set(analyzed_languages);
42
+ const profiles = data.profiles.flatMap((profile) => typeof profile.key === 'string' && typeof profile.name === 'string' && typeof profile.language === 'string'
43
+ && Number.isFinite(Number(profile.activeRuleCount)) && Number(profile.activeRuleCount) > 0
44
+ ? [{ key: profile.key, name: profile.name, language: profile.language.toUpperCase(),
45
+ active_rules: Number(profile.activeRuleCount), analyzed: analyzed.has(profile.language.toUpperCase()) }]
46
+ : []).sort((left, right) => Number(right.analyzed) - Number(left.analyzed) || left.language.localeCompare(right.language));
47
+ const selected = language ? profiles.find(profile => profile.language === language.toUpperCase())
48
+ : profiles[0];
49
+ if (!selected) {
50
+ if (language)
51
+ throw new Error(`当前项目没有 ${language} 的 Quality Profile`);
52
+ return { profiles, analyzed_languages, selected_language: '', rules: [], rule_total: 0 };
53
+ }
54
+ const rules = [];
55
+ let total = 0;
56
+ for (let page = 1; page <= 20; page++) {
57
+ const rulesUrl = apiUrl(host, '/api/rules/search');
58
+ rulesUrl.searchParams.set('qprofile', selected.key);
59
+ rulesUrl.searchParams.set('activation', 'true');
60
+ rulesUrl.searchParams.set('f', 'repo,name,severity,actives');
61
+ rulesUrl.searchParams.set('p', String(page));
62
+ rulesUrl.searchParams.set('ps', '500');
63
+ const result = await readJson(rulesUrl, token, fetcher);
64
+ if (!Array.isArray(result?.rules) || !Number.isFinite(Number(result.total))) {
65
+ throw new Error('SonarQube 未返回当前配置的规则列表');
66
+ }
67
+ total = Number(result.total);
68
+ for (const rule of result.rules) {
69
+ if (typeof rule.key !== 'string' || typeof rule.name !== 'string')
70
+ continue;
71
+ const active = result.actives?.[rule.key]?.[0];
72
+ rules.push({ key: rule.key, name: rule.name, language: selected.language,
73
+ severity: String(active?.severity ?? rule.severity ?? '—') });
74
+ }
75
+ if (rules.length >= total || result.rules.length === 0)
76
+ break;
77
+ }
78
+ if (rules.length !== total)
79
+ throw new Error(`SonarQube 规则列表不完整:已读取 ${rules.length}/${total} 条`);
80
+ return { profiles, analyzed_languages, selected_language: selected.language, rules, rule_total: total };
81
+ }
82
+ //# sourceMappingURL=sonar-rule-catalog.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sonar-rule-catalog.js","sourceRoot":"","sources":["../src/sonar-rule-catalog.ts"],"names":[],"mappings":"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"}
package/lib/sonar.d.ts CHANGED
@@ -50,6 +50,12 @@ export interface SonarAudit {
50
50
  report_path?: string;
51
51
  /** Changed task files actually analyzed by the local engine. */
52
52
  scanned_files?: string[];
53
+ /** Active project rules by language and whether an analyzer was synchronized locally. */
54
+ profile_coverage?: {
55
+ language: string;
56
+ active_rules: number;
57
+ analyzer: string;
58
+ }[];
53
59
  }
54
60
  /** Limit local analysis to the project-relative source roots used by the project's scanner. */
55
61
  export declare function validAuditIncludePaths(value: unknown): value is string[];
package/lib/sonar.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"sonar.js","sourceRoot":"","sources":["../src/sonar.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"sonar.js","sourceRoot":"","sources":["../src/sonar.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ export interface SonarLintEnginePaths {
2
+ java: string;
3
+ lib: string;
4
+ plugins: string[];
5
+ }
6
+ /** Caller may pass a cache directory for testing; normal installations live outside project repositories. */
7
+ export declare function resolveSonarLintEngine(cacheBase?: string, signal?: AbortSignal, archivePath?: string): Promise<SonarLintEnginePaths>;
@@ -0,0 +1,150 @@
1
+ /** Install the standalone SonarLint backend on first use; connected mode fetches analyzers from SonarQube. */
2
+ import { execFile } from 'node:child_process';
3
+ import { createHash, randomUUID } from 'node:crypto';
4
+ import { copyFileSync, createReadStream, createWriteStream, existsSync, mkdirSync, renameSync, rmSync } from 'node:fs';
5
+ import { homedir } from 'node:os';
6
+ import { join, relative, resolve, sep } from 'node:path';
7
+ import { Readable } from 'node:stream';
8
+ import { pipeline } from 'node:stream/promises';
9
+ import { promisify } from 'node:util';
10
+ const run = promisify(execFile);
11
+ const VERSION = '11.9.0.86162';
12
+ const BASE = `https://repo.maven.apache.org/maven2/org/sonarsource/sonarlint/core/sonarlint-backend-cli/${VERSION}`;
13
+ const DISTRIBUTIONS = {
14
+ 'win32-x64': { archive: 'windows_x64.zip', sha256: 'ff08fa813ef0507155d8e550b90425174cf778e63a473eabca53c19fe942f90b' },
15
+ 'linux-x64': { archive: 'linux_x64.tar.gz', sha256: 'e3746b02ee7f66c2d01198a472d21067aebf84c0f042b8336cd9ecddce9284ce' },
16
+ 'darwin-x64': { archive: 'macosx_x64.tar.gz', sha256: '3afe23b87f8080a20bbe3e8a783cd1ea4502023b685a37fde21d1b0b3ca7ed44' },
17
+ 'darwin-arm64': { archive: 'macosx_aarch64.tar.gz', sha256: '95faa1a243a8d5e1f5ce6a9125dacbb25de455a95b5f398beca8fe4686448dd9' },
18
+ };
19
+ function pluginsFromEnvironment() {
20
+ return process.env.DSH_SONARLINT_PLUGINS?.split(sep === '\\' ? ';' : ':').filter(Boolean) ?? [];
21
+ }
22
+ function installedPaths(root) {
23
+ return { java: join(root, 'jre', 'bin', process.platform === 'win32' ? 'java.exe' : 'java'),
24
+ lib: join(root, 'lib'), plugins: pluginsFromEnvironment() };
25
+ }
26
+ function isInstalled(root) {
27
+ const paths = installedPaths(root);
28
+ return existsSync(paths.java) && existsSync(join(paths.lib, `sonarlint-backend-cli-${VERSION}.jar`));
29
+ }
30
+ function safeTemporaryPath(parent, candidate) {
31
+ const rel = relative(resolve(parent), resolve(candidate));
32
+ if (!rel || rel === '..' || rel.startsWith(`..${sep}`) || rel.startsWith(sep)) {
33
+ throw new Error('SonarLint temporary installation path escaped its cache directory');
34
+ }
35
+ }
36
+ async function download(url, destination, signal) {
37
+ // curl honors HTTPS_PROXY on all supported hosts; DSH_SONARLINT_PROXY is an explicit DSH-only override.
38
+ const proxy = process.env.DSH_SONARLINT_PROXY;
39
+ const controller = new AbortController();
40
+ const onAbort = () => controller.abort();
41
+ signal?.addEventListener('abort', onAbort, { once: true });
42
+ try {
43
+ await run('curl', ['--fail', '--location', '--silent', '--show-error', '--proto', '=https',
44
+ '--proto-redir', '=https', '--connect-timeout', '20', '--max-time', '1800',
45
+ '--retry', '3', '--retry-delay', '3', '--retry-all-errors', '--continue-at', '-',
46
+ '--output', destination, url], { timeout: 1_850_000,
47
+ env: proxy ? { ...process.env, HTTPS_PROXY: proxy, https_proxy: proxy } : process.env,
48
+ signal: controller.signal });
49
+ return;
50
+ }
51
+ catch (error) {
52
+ if (error.code !== 'ENOENT') {
53
+ throw new Error(`无法下载 SonarLint 后台组件;检查 Maven Central 网络或 DSH_SONARLINT_PROXY 代理设置:${String(error)}`);
54
+ }
55
+ }
56
+ finally {
57
+ signal?.removeEventListener('abort', onAbort);
58
+ }
59
+ let response;
60
+ try {
61
+ response = await fetch(url, { signal: signal ? AbortSignal.any([signal, AbortSignal.timeout(1_800_000)]) : AbortSignal.timeout(1_800_000) });
62
+ }
63
+ catch (error) {
64
+ throw new Error(`无法下载 SonarLint 后台组件;检查 Maven Central 网络或代理:${String(error)}`);
65
+ }
66
+ if (!response.ok || !response.body)
67
+ throw new Error(`SonarLint 后台组件下载失败:HTTP ${response.status}`);
68
+ const length = Number(response.headers.get('content-length') ?? 0);
69
+ if (length > 500 * 1024 * 1024)
70
+ throw new Error('SonarLint 后台组件下载包过大');
71
+ await pipeline(Readable.fromWeb(response.body), createWriteStream(destination));
72
+ }
73
+ async function sha256(path) {
74
+ const digest = createHash('sha256');
75
+ for await (const chunk of createReadStream(path))
76
+ digest.update(chunk);
77
+ return digest.digest('hex');
78
+ }
79
+ const pending = new Map();
80
+ /** Caller may pass a cache directory for testing; normal installations live outside project repositories. */
81
+ export async function resolveSonarLintEngine(cacheBase = join(homedir(), '.dsh', 'sonarlint-runtime'), signal, archivePath) {
82
+ const explicitJava = process.env.DSH_SONARLINT_JAVA;
83
+ const explicitLib = process.env.DSH_SONARLINT_LIB;
84
+ const plugins = pluginsFromEnvironment();
85
+ if (explicitJava || explicitLib) {
86
+ if (!explicitJava || !explicitLib || !existsSync(explicitJava) || !existsSync(explicitLib)
87
+ || plugins.some(path => !existsSync(path))) {
88
+ throw new Error('SonarLint 自定义路径不完整;请同时设置有效的 DSH_SONARLINT_JAVA 和 DSH_SONARLINT_LIB');
89
+ }
90
+ return { java: explicitJava, lib: explicitLib, plugins };
91
+ }
92
+ if (plugins.some(path => !existsSync(path)))
93
+ throw new Error('DSH_SONARLINT_PLUGINS 中有不存在的分析器路径');
94
+ const platform = `${process.platform}-${process.arch}`;
95
+ const distribution = DISTRIBUTIONS[platform];
96
+ if (!distribution)
97
+ throw new Error(`当前系统 ${platform} 暂无自动安装的 SonarLint 后台组件;可设置 DSH_SONARLINT_JAVA 和 DSH_SONARLINT_LIB`);
98
+ const root = join(cacheBase, VERSION, platform);
99
+ if (isInstalled(root))
100
+ return installedPaths(root);
101
+ const existing = pending.get(root);
102
+ if (existing)
103
+ return existing;
104
+ const task = (async () => {
105
+ const parent = join(cacheBase, VERSION);
106
+ mkdirSync(parent, { recursive: true });
107
+ const stage = join(parent, `.install-${platform}-${randomUUID()}`);
108
+ safeTemporaryPath(parent, stage);
109
+ mkdirSync(stage);
110
+ try {
111
+ const archive = join(stage, `distribution.${distribution.archive.endsWith('.zip') ? 'zip' : 'tar.gz'}`);
112
+ if (archivePath) {
113
+ copyFileSync(archivePath, archive);
114
+ }
115
+ else {
116
+ await download(`${BASE}/sonarlint-backend-cli-${VERSION}-${distribution.archive}`, archive, signal);
117
+ }
118
+ const hash = await sha256(archive);
119
+ if (hash !== distribution.sha256)
120
+ throw new Error('SonarLint 后台组件校验失败;下载内容与官方校验值不符');
121
+ await run('tar', ['-xf', archive, '-C', stage], { timeout: 180_000 });
122
+ rmSync(archive);
123
+ if (!isInstalled(stage))
124
+ throw new Error('SonarLint 后台组件缺少 Java 或后台依赖 JAR');
125
+ if (!isInstalled(root)) {
126
+ try {
127
+ renameSync(stage, root);
128
+ }
129
+ catch (error) {
130
+ if (!isInstalled(root))
131
+ throw error;
132
+ }
133
+ }
134
+ return installedPaths(root);
135
+ }
136
+ finally {
137
+ safeTemporaryPath(parent, stage);
138
+ if (existsSync(stage))
139
+ rmSync(stage, { recursive: true, force: true });
140
+ }
141
+ })();
142
+ pending.set(root, task);
143
+ try {
144
+ return await task;
145
+ }
146
+ finally {
147
+ pending.delete(root);
148
+ }
149
+ }
150
+ //# sourceMappingURL=sonarlint-install.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sonarlint-install.js","sourceRoot":"","sources":["../src/sonarlint-install.ts"],"names":[],"mappings":"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"}
@@ -12,6 +12,18 @@ interface ChangedFile {
12
12
  }
13
13
  /** Compare the current working tree with a reference; an untracked file is wholly new. */
14
14
  export declare function changedLines(root: string, reference: string, taskPaths?: string[]): Promise<ChangedFile[]>;
15
+ export declare function lastLocalRuleUpdate(policy: SonarPolicy, root: string): string | undefined;
16
+ interface LocalBinding {
17
+ connection_id: string;
18
+ updated_at: string;
19
+ }
20
+ export declare function currentBinding(stateDir: string): LocalBinding | undefined;
21
+ export declare function saveBinding(stateDir: string, binding: LocalBinding): void;
15
22
  /** Analyze only changed supported files with the project's synchronized Quality Profile. */
16
- export declare function inspectLocalRules(policy: SonarPolicy, token: string, root: string, scopeHash: string, signal?: AbortSignal, taskPaths?: string[]): Promise<SonarAudit>;
23
+ export declare function inspectLocalRules(policy: SonarPolicy, token: string, root: string, scopeHash: string, signal?: AbortSignal, taskPaths?: string[], prepareOnly?: boolean, connectionId?: string): Promise<SonarAudit>;
24
+ /** Prepare the backend and verify project rule synchronization without auditing or uploading source files. */
25
+ export declare function prepareLocalAnalyzer(policy: SonarPolicy, token: string, root: string, signal?: AbortSignal, updateRules?: boolean): Promise<{
26
+ profiles: NonNullable<SonarAudit['profile_coverage']>;
27
+ updated_at?: string;
28
+ }>;
17
29
  export {};
@@ -1,12 +1,13 @@
1
1
  /** Local SonarQube for IDE engine. It reads server rules and source files; it never runs a scanner or uploads an analysis. */
2
2
  import { spawn, execFile } from 'node:child_process';
3
3
  import { createHash, randomUUID } from 'node:crypto';
4
- import { existsSync, mkdirSync, mkdtempSync, readFileSync, rmSync } from 'node:fs';
4
+ import { existsSync, mkdirSync, mkdtempSync, readFileSync, rmSync, writeFileSync, renameSync } from 'node:fs';
5
5
  import { homedir, tmpdir } from 'node:os';
6
6
  import { join, relative, resolve, sep } from 'node:path';
7
7
  import { pathToFileURL } from 'node:url';
8
8
  import { promisify } from 'node:util';
9
9
  import { isBlockingFinding, isIncludedAuditPath } from "./sonar.js";
10
+ import { resolveSonarLintEngine } from "./sonarlint-install.js";
10
11
  const run = promisify(execFile);
11
12
  const SUPPORTED_FILE = /\.(?:java|js|jsx|ts|tsx|vue|css|scss|html|jsp|xml|json|ya?ml|sql|properties|py|go|kt|kts|cs|c|cc|cpp|h|hpp|php|rb|sh|scala|groovy)$/iu;
12
13
  function isAuditSource(path) {
@@ -100,23 +101,55 @@ export async function changedLines(root, reference, taskPaths) {
100
101
  return [...files.values()].filter(file => file.lines.size
101
102
  && (scoped === undefined || scoped.has(file.path.replaceAll('\\', '/').toLowerCase())));
102
103
  }
103
- /** The engine can be installed independently; environment paths point to its Java runtime and SonarLint JARs. */
104
- function enginePaths() {
105
- const java = process.env.DSH_SONARLINT_JAVA;
106
- const lib = process.env.DSH_SONARLINT_LIB;
107
- const plugins = process.env.DSH_SONARLINT_PLUGINS?.split(sep === '\\' ? ';' : ':').filter(Boolean) ?? [];
108
- if (!java || !lib || !plugins.length || !existsSync(java) || !existsSync(lib) || plugins.some(path => !existsSync(path))) {
109
- throw new Error('本地 Sonar 审核需要 DSH_SONARLINT_JAVA、DSH_SONARLINT_LIB 和 DSH_SONARLINT_PLUGINS;请先安装 SonarLint 后台组件并配置路径');
104
+ function localStateDir(policy, root) {
105
+ const cacheKey = `${resolve(root).toLowerCase()}\0${policy.host_url}\0${policy.project_key}`;
106
+ return join(homedir(), '.dsh', 'sonarlint-cache', createHash('sha256').update(cacheKey).digest('hex').slice(0, 24));
107
+ }
108
+ export function lastLocalRuleUpdate(policy, root) {
109
+ return currentBinding(localStateDir(policy, root))?.updated_at;
110
+ }
111
+ export function currentBinding(stateDir) {
112
+ try {
113
+ const binding = JSON.parse(readFileSync(join(stateDir, 'dsh-binding.json'), 'utf8'));
114
+ if (/^project-[0-9a-f-]{36}$/u.test(binding.connection_id) && !Number.isNaN(Date.parse(binding.updated_at))) {
115
+ return binding;
116
+ }
117
+ }
118
+ catch (error) {
119
+ if (error.code !== 'ENOENT')
120
+ throw new Error('本地 SonarQube 规则绑定记录损坏,请检查本机 DSH 缓存');
121
+ }
122
+ return undefined;
123
+ }
124
+ export function saveBinding(stateDir, binding) {
125
+ mkdirSync(stateDir, { recursive: true });
126
+ const temporary = join(stateDir, `.dsh-binding-${randomUUID()}.json`);
127
+ try {
128
+ writeFileSync(temporary, JSON.stringify(binding), { encoding: 'utf8', mode: 0o600 });
129
+ renameSync(temporary, join(stateDir, 'dsh-binding.json'));
130
+ }
131
+ finally {
132
+ rmSync(temporary, { force: true });
110
133
  }
111
- return { java, lib, plugins };
134
+ }
135
+ function connectionCachePath(stateDir, connectionId) {
136
+ if (connectionId !== 'project' && !/^project-[0-9a-f-]{36}$/u.test(connectionId)) {
137
+ throw new Error('无效的本地 SonarQube 连接标识');
138
+ }
139
+ const path = resolve(stateDir, Buffer.from(connectionId).toString('hex'));
140
+ const relativePath = relative(resolve(stateDir), path);
141
+ if (!relativePath || relativePath === '..' || relativePath.startsWith(`..${sep}`) || relativePath.startsWith(sep)) {
142
+ throw new Error('本地 SonarQube 缓存路径超出项目目录');
143
+ }
144
+ return path;
112
145
  }
113
146
  /** Analyze only changed supported files with the project's synchronized Quality Profile. */
114
- export async function inspectLocalRules(policy, token, root, scopeHash, signal, taskPaths) {
147
+ export async function inspectLocalRules(policy, token, root, scopeHash, signal, taskPaths, prepareOnly = false, connectionId) {
115
148
  if (!token)
116
149
  throw new Error('本地规则审核需要当前项目 SonarQube Token');
117
150
  if (!policy.reference_branch)
118
151
  throw new Error('本地规则审核需要新代码参考分支');
119
- const changes = (await changedLines(root, policy.reference_branch))
152
+ const changes = (prepareOnly ? [] : await changedLines(root, policy.reference_branch))
120
153
  .filter(file => isIncludedAuditPath(file.path, policy.include_paths));
121
154
  if (taskPaths !== undefined) {
122
155
  const missing = missingLocalAuditScope(changes.map(file => file.path), taskPaths);
@@ -142,7 +175,7 @@ export async function inspectLocalRules(policy, token, root, scopeHash, signal,
142
175
  const serverMain = branchData.branches?.find(branch => branch.isMain === true)?.name;
143
176
  if (!serverMain)
144
177
  throw new Error('SonarQube 未返回项目主分支,无法同步本地规则');
145
- const paths = enginePaths();
178
+ const paths = await resolveSonarLintEngine(undefined, signal);
146
179
  const supported = changes.filter(change => localLanguage(change.path));
147
180
  const files = supported.map(change => {
148
181
  const absolute = resolve(root, change.path);
@@ -154,8 +187,8 @@ export async function inspectLocalRules(policy, token, root, scopeHash, signal,
154
187
  });
155
188
  const fileLines = new Map(supported.map((change, index) => [files[index].uri, change.lines]));
156
189
  const newFiles = new Set(files.filter((_, index) => supported[index]?.newFile).map(file => file.uri));
157
- const cacheKey = `${resolve(root).toLowerCase()}\0${policy.host_url}\0${policy.project_key}`;
158
- const stateDir = join(homedir(), '.dsh', 'sonarlint-cache', createHash('sha256').update(cacheKey).digest('hex').slice(0, 24));
190
+ const stateDir = localStateDir(policy, root);
191
+ connectionId ??= currentBinding(stateDir)?.connection_id ?? 'project';
159
192
  mkdirSync(stateDir, { recursive: true });
160
193
  const workDir = mkdtempSync(join(tmpdir(), 'dsh-sonarlint-'));
161
194
  const child = spawn(paths.java, ['-cp', join(paths.lib, '*'),
@@ -252,12 +285,12 @@ export async function inspectLocalRules(policy, token, root, scopeHash, signal,
252
285
  httpConfiguration: { sslConfiguration: {} }, backendCapabilities: ['FULL_SYNCHRONIZATION'],
253
286
  storageRoot: stateDir, workDir, embeddedPluginPaths: paths.plugins, connectedModeEmbeddedPluginPathsByKey: {},
254
287
  enabledLanguagesInStandaloneMode: ['JAVA'], extraEnabledLanguagesInConnectedMode: ['JS', 'TS', 'CSS', 'HTML', 'XML'], disabledPluginKeysForAnalysis: [],
255
- sonarQubeConnections: [{ connectionId: 'project', serverUrl: policy.host_url, disableNotifications: true }], sonarCloudConnections: [],
288
+ sonarQubeConnections: [{ connectionId, serverUrl: policy.host_url, disableNotifications: true }], sonarCloudConnections: [],
256
289
  standaloneRuleConfigByKey: {}, isFocusOnNewCode: false, automaticAnalysisEnabled: false,
257
290
  languageSpecificRequirements: { omnisharpDownloadEnabled: false }, logLevel: 'WARN',
258
291
  }, 30_000);
259
292
  notify('configuration/didAddConfigurationScopes', { addedScopes: [{ id: 'project', bindable: true, name: 'Project',
260
- binding: { connectionId: 'project', sonarProjectKey: policy.project_key, bindingSuggestionDisabled: true } }] });
293
+ binding: { connectionId, sonarProjectKey: policy.project_key, bindingSuggestionDisabled: true } }] });
261
294
  let readyTimer;
262
295
  try {
263
296
  await Promise.race([readiness, exited, new Promise((_, reject) => {
@@ -268,15 +301,41 @@ export async function inspectLocalRules(policy, token, root, scopeHash, signal,
268
301
  if (readyTimer)
269
302
  clearTimeout(readyTimer);
270
303
  }
271
- if (files.length) {
272
- notify('file/didUpdateFileSystem', { addedFiles: files, changedFiles: [], removedFiles: [] });
273
- const status = await request('file/getFilesStatus', { fileUrisByConfigScopeId: { project: files.map(file => file.uri) } });
274
- const excluded = files.filter(file => status.fileStatuses?.[file.uri]?.excluded);
304
+ const pluginStatus = await request('plugin/getPluginStatuses', { configurationScopeId: 'project' }, 30_000);
305
+ if (!Array.isArray(pluginStatus?.pluginStatuses))
306
+ throw new Error('SonarLint 未返回本地语言分析器状态,不能判定审核覆盖范围');
307
+ if (connectionId !== 'project') {
308
+ const configFile = join(connectionCachePath(stateDir, connectionId), 'projects', Buffer.from(policy.project_key).toString('hex'), 'analyzer_config.pb');
309
+ for (let attempt = 0; attempt < 20 && !existsSync(configFile); attempt++) {
310
+ await new Promise(resolve => setTimeout(resolve, 250));
311
+ }
312
+ if (!existsSync(configFile))
313
+ throw new Error('SonarLint 尚未写入当前项目的最新规则配置;本次更新未生效');
314
+ }
315
+ const analyzers = new Map(pluginStatus.pluginStatuses.flatMap((entry) => typeof entry.language === 'string' && typeof entry.state === 'string' ? [[entry.language.toUpperCase(), entry.state]] : []));
316
+ const profileCoverage = profileData.profiles.filter(profile => profile.language && Number(profile.activeRuleCount) > 0)
317
+ .map(profile => ({ language: profile.language.toUpperCase(), active_rules: Number(profile.activeRuleCount),
318
+ analyzer: analyzers.get(profile.language.toUpperCase()) ?? 'UNAVAILABLE' }));
319
+ const activeLanguages = new Set(profileCoverage.map(profile => profile.language));
320
+ const unavailable = supported.filter(change => {
321
+ const language = localLanguage(change.path);
322
+ return language && activeLanguages.has(language) && analyzers.get(language) !== 'SYNCED';
323
+ });
324
+ const unavailablePaths = new Set(unavailable.map(change => change.path));
325
+ uncovered.push(...unavailable.map(change => change.path));
326
+ const scanned = files.filter(file => {
327
+ const language = localLanguage(file.ideRelativePath);
328
+ return !!language && activeLanguages.has(language) && !unavailablePaths.has(file.ideRelativePath);
329
+ });
330
+ if (scanned.length) {
331
+ notify('file/didUpdateFileSystem', { addedFiles: scanned, changedFiles: [], removedFiles: [] });
332
+ const status = await request('file/getFilesStatus', { fileUrisByConfigScopeId: { project: scanned.map(file => file.uri) } });
333
+ const excluded = scanned.filter(file => status.fileStatuses?.[file.uri]?.excluded);
275
334
  if (excluded.length)
276
335
  throw new Error(`SonarLint 排除了新增代码:${excluded.map(file => file.ideRelativePath).join(', ')}`);
277
336
  }
278
- const response = files.length ? await request('analysis/analyzeFilesAndTrack', {
279
- configurationScopeId: 'project', analysisId: randomUUID(), filesToAnalyze: files.map(file => file.uri),
337
+ const response = scanned.length ? await request('analysis/analyzeFilesAndTrack', {
338
+ configurationScopeId: 'project', analysisId: randomUUID(), filesToAnalyze: scanned.map(file => file.uri),
280
339
  extraProperties: {}, shouldFetchServerIssues: false,
281
340
  }) : { rawIssues: [], failedAnalysisFiles: [] };
282
341
  if (response.failedAnalysisFiles?.length)
@@ -299,7 +358,7 @@ export async function inspectLocalRules(policy, token, root, scopeHash, signal,
299
358
  return { ce_task_id: 'local', analysis_id: randomUUID(), gate: blocking.length || uncovered.length ? 'ERROR' : 'OK',
300
359
  checked_at: new Date().toISOString(), scope_hash: scopeHash, findings, blocking,
301
360
  ...(uncovered.length ? { uncovered_files: uncovered } : {}),
302
- target: policy.reference_branch, scanned_files: supported.map(file => file.path) };
361
+ target: policy.reference_branch, scanned_files: scanned.map(file => file.ideRelativePath), profile_coverage: profileCoverage };
303
362
  }
304
363
  finally {
305
364
  settled = true;
@@ -314,4 +373,35 @@ export async function inspectLocalRules(policy, token, root, scopeHash, signal,
314
373
  }
315
374
  }
316
375
  }
376
+ /** Prepare the backend and verify project rule synchronization without auditing or uploading source files. */
377
+ export async function prepareLocalAnalyzer(policy, token, root, signal, updateRules = false) {
378
+ const stateDir = localStateDir(policy, root);
379
+ const previousId = currentBinding(stateDir)?.connection_id ?? 'project';
380
+ const connectionId = updateRules ? `project-${randomUUID()}` : undefined;
381
+ let audit;
382
+ try {
383
+ audit = await inspectLocalRules(policy, token, root, 'prepare-only', signal, undefined, true, connectionId);
384
+ if (connectionId)
385
+ saveBinding(stateDir, { connection_id: connectionId, updated_at: audit.checked_at });
386
+ }
387
+ catch (error) {
388
+ if (connectionId)
389
+ setTimeout(() => {
390
+ try {
391
+ rmSync(connectionCachePath(stateDir, connectionId), { recursive: true, force: true });
392
+ }
393
+ catch { /* The backend may still hold this cache. */ }
394
+ }, 3000).unref();
395
+ throw error;
396
+ }
397
+ if (connectionId && previousId !== connectionId)
398
+ setTimeout(() => {
399
+ try {
400
+ rmSync(connectionCachePath(stateDir, previousId), { recursive: true, force: true });
401
+ }
402
+ catch { /* Keep the old cache if it is in use. */ }
403
+ }, 3000).unref();
404
+ const updatedAt = connectionId ? audit.checked_at : currentBinding(stateDir)?.updated_at;
405
+ return { profiles: audit.profile_coverage ?? [], ...(updatedAt ? { updated_at: updatedAt } : {}) };
406
+ }
317
407
  //# sourceMappingURL=sonarlint-local.js.map