sonar-sweep 0.1.0
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/README.md +70 -0
- package/dist/cli/commands/issue-accept.d.ts +13 -0
- package/dist/cli/commands/issue-accept.js +49 -0
- package/dist/cli/commands/issue-accept.js.map +1 -0
- package/dist/cli/commands/pr-coverage.d.ts +16 -0
- package/dist/cli/commands/pr-coverage.js +79 -0
- package/dist/cli/commands/pr-coverage.js.map +1 -0
- package/dist/cli/commands/pr-issues.d.ts +15 -0
- package/dist/cli/commands/pr-issues.js +78 -0
- package/dist/cli/commands/pr-issues.js.map +1 -0
- package/dist/cli/commands/pr-report.d.ts +13 -0
- package/dist/cli/commands/pr-report.js +94 -0
- package/dist/cli/commands/pr-report.js.map +1 -0
- package/dist/cli/commands/pr-review.d.ts +16 -0
- package/dist/cli/commands/pr-review.js +93 -0
- package/dist/cli/commands/pr-review.js.map +1 -0
- package/dist/cli/index.d.ts +1 -0
- package/dist/cli/index.js +28 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/project-key.d.ts +1 -0
- package/dist/cli/project-key.js +32 -0
- package/dist/cli/project-key.js.map +1 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +8 -0
- package/dist/cli.js.map +1 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.js +7 -0
- package/dist/index.js.map +1 -0
- package/dist/service/issue-transition.d.ts +12 -0
- package/dist/service/issue-transition.js +20 -0
- package/dist/service/issue-transition.js.map +1 -0
- package/dist/service/pr-coverage.d.ts +22 -0
- package/dist/service/pr-coverage.js +48 -0
- package/dist/service/pr-coverage.js.map +1 -0
- package/dist/service/pr-issues.d.ts +29 -0
- package/dist/service/pr-issues.js +45 -0
- package/dist/service/pr-issues.js.map +1 -0
- package/dist/service/pr-report.d.ts +27 -0
- package/dist/service/pr-report.js +59 -0
- package/dist/service/pr-report.js.map +1 -0
- package/dist/service/pr-review.d.ts +39 -0
- package/dist/service/pr-review.js +81 -0
- package/dist/service/pr-review.js.map +1 -0
- package/dist/service/sonarcloud-client.d.ts +100 -0
- package/dist/service/sonarcloud-client.js +112 -0
- package/dist/service/sonarcloud-client.js.map +1 -0
- package/package.json +34 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"project-key.js","sourceRoot":"","sources":["../../src/cli/project-key.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAA;AACjD,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,SAAS,CAAA;AAClD,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAEhC,MAAM,UAAU,iBAAiB,CAAC,UAAmB;IACnD,IAAI,UAAU,EAAE,IAAI,EAAE,EAAE,CAAC;QACvB,OAAO,UAAU,CAAC,IAAI,EAAE,CAAA;IAC1B,CAAC;IAED,MAAM,OAAO,GAAG,UAAU,EAAE,CAAA;IAC5B,MAAM,cAAc,GAAG,IAAI,CAAC,OAAO,EAAE,0BAA0B,CAAC,CAAA;IAChE,IAAI,CAAC,UAAU,CAAC,cAAc,CAAC,EAAE,CAAC;QAChC,MAAM,IAAI,KAAK,CACb,+DAA+D,cAAc,oCAAoC,CAClH,CAAA;IACH,CAAC;IAED,MAAM,OAAO,GAAG,YAAY,CAAC,cAAc,EAAE,MAAM,CAAC,CAAA;IACpD,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,uCAAuC,CAAC,CAAA;IACpE,MAAM,GAAG,GAAG,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAA;IAC9B,IAAI,CAAC,GAAG,EAAE,CAAC;QACT,MAAM,IAAI,KAAK,CACb,wCAAwC,cAAc,oCAAoC,CAC3F,CAAA;IACH,CAAC;IAED,OAAO,GAAG,CAAA;AACZ,CAAC;AAED,SAAS,UAAU;IACjB,IAAI,CAAC;QACH,OAAO,YAAY,CAAC,KAAK,EAAE,CAAC,WAAW,EAAE,iBAAiB,CAAC,EAAE;YAC3D,QAAQ,EAAE,MAAM;YAChB,KAAK,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,CAAC;SACpC,CAAC,CAAC,IAAI,EAAE,CAAA;IACX,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,OAAO,CAAC,GAAG,EAAE,CAAA;IACtB,CAAC;AACH,CAAC"}
|
package/dist/cli.d.ts
ADDED
package/dist/cli.js
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { run } from './cli/index.js';
|
|
3
|
+
run(process.argv).catch((error) => {
|
|
4
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
5
|
+
process.stderr.write(`${message}\n`);
|
|
6
|
+
process.exit(1);
|
|
7
|
+
});
|
|
8
|
+
//# sourceMappingURL=cli.js.map
|
package/dist/cli.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,GAAG,EAAE,MAAM,gBAAgB,CAAA;AAEpC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;IAChC,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;IACtE,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,OAAO,IAAI,CAAC,CAAA;IACpC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;AACjB,CAAC,CAAC,CAAA"}
|
package/dist/index.d.ts
ADDED
package/dist/index.js
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export * from './service/pr-report.js';
|
|
2
|
+
export * from './service/pr-issues.js';
|
|
3
|
+
export * from './service/pr-coverage.js';
|
|
4
|
+
export * from './service/pr-review.js';
|
|
5
|
+
export * from './service/issue-transition.js';
|
|
6
|
+
export * from './service/sonarcloud-client.js';
|
|
7
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,wBAAwB,CAAA;AACtC,cAAc,wBAAwB,CAAA;AACtC,cAAc,0BAA0B,CAAA;AACxC,cAAc,wBAAwB,CAAA;AACtC,cAAc,+BAA+B,CAAA;AAC7C,cAAc,gCAAgC,CAAA"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { type SonarCloudClientOptions } from './sonarcloud-client.js';
|
|
2
|
+
export type IssueTransitionInput = {
|
|
3
|
+
issueKey: string;
|
|
4
|
+
transition: 'accept' | 'wontfix' | 'falsepositive' | 'confirm' | 'reopen' | 'resolve';
|
|
5
|
+
comment?: string;
|
|
6
|
+
};
|
|
7
|
+
export type IssueTransitionResult = {
|
|
8
|
+
issueKey: string;
|
|
9
|
+
transition: string;
|
|
10
|
+
applied: true;
|
|
11
|
+
};
|
|
12
|
+
export declare function transitionIssue(clientOptions: SonarCloudClientOptions, input: IssueTransitionInput): Promise<IssueTransitionResult>;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { SonarCloudClient } from './sonarcloud-client.js';
|
|
2
|
+
export async function transitionIssue(clientOptions, input) {
|
|
3
|
+
const issueKey = input.issueKey.trim();
|
|
4
|
+
const transition = input.transition.trim();
|
|
5
|
+
const comment = input.comment?.trim();
|
|
6
|
+
if (!issueKey) {
|
|
7
|
+
throw new Error('Missing issueKey');
|
|
8
|
+
}
|
|
9
|
+
if (!transition) {
|
|
10
|
+
throw new Error('Missing transition');
|
|
11
|
+
}
|
|
12
|
+
const client = new SonarCloudClient(clientOptions);
|
|
13
|
+
await client.doIssueTransition(issueKey, transition, comment);
|
|
14
|
+
return {
|
|
15
|
+
issueKey,
|
|
16
|
+
transition,
|
|
17
|
+
applied: true,
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=issue-transition.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"issue-transition.js","sourceRoot":"","sources":["../../src/service/issue-transition.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAgC,MAAM,wBAAwB,CAAA;AAcvF,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,aAAsC,EACtC,KAA2B;IAE3B,MAAM,QAAQ,GAAG,KAAK,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAA;IACtC,MAAM,UAAU,GAAG,KAAK,CAAC,UAAU,CAAC,IAAI,EAAE,CAAA;IAC1C,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,EAAE,IAAI,EAAE,CAAA;IAErC,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,MAAM,IAAI,KAAK,CAAC,kBAAkB,CAAC,CAAA;IACrC,CAAC;IAED,IAAI,CAAC,UAAU,EAAE,CAAC;QAChB,MAAM,IAAI,KAAK,CAAC,oBAAoB,CAAC,CAAA;IACvC,CAAC;IAED,MAAM,MAAM,GAAG,IAAI,gBAAgB,CAAC,aAAa,CAAC,CAAA;IAClD,MAAM,MAAM,CAAC,iBAAiB,CAAC,QAAQ,EAAE,UAAU,EAAE,OAAO,CAAC,CAAA;IAE7D,OAAO;QACL,QAAQ;QACR,UAAU;QACV,OAAO,EAAE,IAAI;KACd,CAAA;AACH,CAAC"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { type SonarCloudClientOptions } from './sonarcloud-client.js';
|
|
2
|
+
export type PullRequestCoverageFile = {
|
|
3
|
+
file: string;
|
|
4
|
+
coverageOnNewCode: number;
|
|
5
|
+
linesToCover: number;
|
|
6
|
+
uncoveredLines: number;
|
|
7
|
+
};
|
|
8
|
+
export type PullRequestCoverageReport = {
|
|
9
|
+
projectKey: string;
|
|
10
|
+
pullRequest: string;
|
|
11
|
+
threshold: number;
|
|
12
|
+
analysisUrl: string;
|
|
13
|
+
files: PullRequestCoverageFile[];
|
|
14
|
+
};
|
|
15
|
+
export type PullRequestCoverageInput = {
|
|
16
|
+
projectKey: string;
|
|
17
|
+
pullRequest: string;
|
|
18
|
+
threshold?: number;
|
|
19
|
+
includePassing?: boolean;
|
|
20
|
+
maxFiles?: number;
|
|
21
|
+
};
|
|
22
|
+
export declare function getPullRequestCoverage(clientOptions: SonarCloudClientOptions, input: PullRequestCoverageInput): Promise<PullRequestCoverageReport>;
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { SonarCloudClient } from './sonarcloud-client.js';
|
|
2
|
+
export async function getPullRequestCoverage(clientOptions, input) {
|
|
3
|
+
const projectKey = input.projectKey.trim();
|
|
4
|
+
const pullRequest = input.pullRequest.trim();
|
|
5
|
+
if (!projectKey) {
|
|
6
|
+
throw new Error('Missing projectKey');
|
|
7
|
+
}
|
|
8
|
+
if (!pullRequest) {
|
|
9
|
+
throw new Error('Missing pullRequest');
|
|
10
|
+
}
|
|
11
|
+
const threshold = input.threshold ?? 80;
|
|
12
|
+
const includePassing = input.includePassing ?? false;
|
|
13
|
+
const maxFiles = Math.max(1, input.maxFiles ?? 20);
|
|
14
|
+
const baseUrl = (clientOptions.baseUrl ?? 'https://sonarcloud.io').replace(/\/$/, '');
|
|
15
|
+
const client = new SonarCloudClient(clientOptions);
|
|
16
|
+
const tree = await client.getCoverageComponentTree(projectKey, pullRequest, 1, 500);
|
|
17
|
+
const files = tree.components
|
|
18
|
+
.map((component) => {
|
|
19
|
+
const file = component.path ?? component.name;
|
|
20
|
+
const coverageOnNewCode = value(component.measures, 'new_coverage');
|
|
21
|
+
const linesToCover = value(component.measures, 'new_lines_to_cover');
|
|
22
|
+
const uncoveredLines = value(component.measures, 'new_uncovered_lines');
|
|
23
|
+
return {
|
|
24
|
+
file,
|
|
25
|
+
coverageOnNewCode,
|
|
26
|
+
linesToCover,
|
|
27
|
+
uncoveredLines,
|
|
28
|
+
};
|
|
29
|
+
})
|
|
30
|
+
.filter((item) => item.linesToCover > 0)
|
|
31
|
+
.filter((item) => includePassing || item.coverageOnNewCode < threshold)
|
|
32
|
+
.sort((a, b) => a.coverageOnNewCode - b.coverageOnNewCode)
|
|
33
|
+
.slice(0, maxFiles);
|
|
34
|
+
return {
|
|
35
|
+
projectKey,
|
|
36
|
+
pullRequest,
|
|
37
|
+
threshold,
|
|
38
|
+
analysisUrl: `${baseUrl}/dashboard?id=${encodeURIComponent(projectKey)}&pullRequest=${encodeURIComponent(pullRequest)}`,
|
|
39
|
+
files,
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
function value(measures, metric) {
|
|
43
|
+
const measure = measures.find((item) => item.metric === metric);
|
|
44
|
+
const raw = measure?.periods?.[0]?.value ?? measure?.value ?? '0';
|
|
45
|
+
const parsed = Number.parseFloat(raw);
|
|
46
|
+
return Number.isFinite(parsed) ? parsed : 0;
|
|
47
|
+
}
|
|
48
|
+
//# sourceMappingURL=pr-coverage.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pr-coverage.js","sourceRoot":"","sources":["../../src/service/pr-coverage.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { type SonarCloudClientOptions } from './sonarcloud-client.js';
|
|
2
|
+
export type PullRequestIssue = {
|
|
3
|
+
key: string;
|
|
4
|
+
type: string;
|
|
5
|
+
severity: string;
|
|
6
|
+
status: string;
|
|
7
|
+
issueStatus: string;
|
|
8
|
+
rule: string;
|
|
9
|
+
message: string;
|
|
10
|
+
file: string;
|
|
11
|
+
line?: number;
|
|
12
|
+
effort?: string;
|
|
13
|
+
};
|
|
14
|
+
export type PullRequestIssuesReport = {
|
|
15
|
+
projectKey: string;
|
|
16
|
+
pullRequest: string;
|
|
17
|
+
total: number;
|
|
18
|
+
page: number;
|
|
19
|
+
pageSize: number;
|
|
20
|
+
analysisUrl: string;
|
|
21
|
+
issues: PullRequestIssue[];
|
|
22
|
+
};
|
|
23
|
+
export type PullRequestIssuesInput = {
|
|
24
|
+
projectKey: string;
|
|
25
|
+
pullRequest: string;
|
|
26
|
+
page?: number;
|
|
27
|
+
pageSize?: number;
|
|
28
|
+
};
|
|
29
|
+
export declare function getPullRequestIssues(clientOptions: SonarCloudClientOptions, input: PullRequestIssuesInput): Promise<PullRequestIssuesReport>;
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { SonarCloudClient, } from './sonarcloud-client.js';
|
|
2
|
+
export async function getPullRequestIssues(clientOptions, input) {
|
|
3
|
+
const projectKey = input.projectKey.trim();
|
|
4
|
+
const pullRequest = input.pullRequest.trim();
|
|
5
|
+
if (!projectKey) {
|
|
6
|
+
throw new Error('Missing projectKey');
|
|
7
|
+
}
|
|
8
|
+
if (!pullRequest) {
|
|
9
|
+
throw new Error('Missing pullRequest');
|
|
10
|
+
}
|
|
11
|
+
const page = input.page ?? 1;
|
|
12
|
+
const pageSize = input.pageSize ?? 100;
|
|
13
|
+
const baseUrl = (clientOptions.baseUrl ?? 'https://sonarcloud.io').replace(/\/$/, '');
|
|
14
|
+
const client = new SonarCloudClient(clientOptions);
|
|
15
|
+
const response = await client.getPullRequestIssues(projectKey, pullRequest, page, pageSize);
|
|
16
|
+
const componentPathByKey = new Map((response.components ?? []).map((component) => [
|
|
17
|
+
component.key,
|
|
18
|
+
component.path ?? component.longName ?? component.key,
|
|
19
|
+
]));
|
|
20
|
+
const issues = (response.issues ?? []).map((issue) => {
|
|
21
|
+
const file = componentPathByKey.get(issue.component) ?? issue.component.split(':').slice(1).join(':') ?? issue.component;
|
|
22
|
+
return {
|
|
23
|
+
key: issue.key,
|
|
24
|
+
type: issue.type,
|
|
25
|
+
severity: issue.severity,
|
|
26
|
+
status: issue.status,
|
|
27
|
+
issueStatus: issue.issueStatus ?? issue.status,
|
|
28
|
+
rule: issue.rule,
|
|
29
|
+
message: issue.message,
|
|
30
|
+
file,
|
|
31
|
+
line: issue.line,
|
|
32
|
+
effort: issue.effort,
|
|
33
|
+
};
|
|
34
|
+
});
|
|
35
|
+
return {
|
|
36
|
+
projectKey,
|
|
37
|
+
pullRequest,
|
|
38
|
+
total: response.total,
|
|
39
|
+
page: response.paging?.pageIndex ?? page,
|
|
40
|
+
pageSize: response.paging?.pageSize ?? pageSize,
|
|
41
|
+
analysisUrl: `${baseUrl}/dashboard?id=${encodeURIComponent(projectKey)}&pullRequest=${encodeURIComponent(pullRequest)}`,
|
|
42
|
+
issues,
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
//# sourceMappingURL=pr-issues.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pr-issues.js","sourceRoot":"","sources":["../../src/service/pr-issues.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,gBAAgB,GAIjB,MAAM,wBAAwB,CAAA;AAgC/B,MAAM,CAAC,KAAK,UAAU,oBAAoB,CACxC,aAAsC,EACtC,KAA6B;IAE7B,MAAM,UAAU,GAAG,KAAK,CAAC,UAAU,CAAC,IAAI,EAAE,CAAA;IAC1C,MAAM,WAAW,GAAG,KAAK,CAAC,WAAW,CAAC,IAAI,EAAE,CAAA;IAC5C,IAAI,CAAC,UAAU,EAAE,CAAC;QAChB,MAAM,IAAI,KAAK,CAAC,oBAAoB,CAAC,CAAA;IACvC,CAAC;IACD,IAAI,CAAC,WAAW,EAAE,CAAC;QACjB,MAAM,IAAI,KAAK,CAAC,qBAAqB,CAAC,CAAA;IACxC,CAAC;IAED,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,IAAI,CAAC,CAAA;IAC5B,MAAM,QAAQ,GAAG,KAAK,CAAC,QAAQ,IAAI,GAAG,CAAA;IACtC,MAAM,OAAO,GAAG,CAAC,aAAa,CAAC,OAAO,IAAI,uBAAuB,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAA;IAErF,MAAM,MAAM,GAAG,IAAI,gBAAgB,CAAC,aAAa,CAAC,CAAA;IAClD,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,oBAAoB,CAAC,UAAU,EAAE,WAAW,EAAE,IAAI,EAAE,QAAQ,CAAC,CAAA;IAC3F,MAAM,kBAAkB,GAAG,IAAI,GAAG,CAChC,CAAC,QAAQ,CAAC,UAAU,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,SAA8B,EAAE,EAAE,CAAC;QAClE,SAAS,CAAC,GAAG;QACb,SAAS,CAAC,IAAI,IAAI,SAAS,CAAC,QAAQ,IAAI,SAAS,CAAC,GAAG;KACtD,CAAC,CACH,CAAA;IAED,MAAM,MAAM,GAAG,CAAC,QAAQ,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,KAAiB,EAAoB,EAAE;QACjF,MAAM,IAAI,GACR,kBAAkB,CAAC,GAAG,CAAC,KAAK,CAAC,SAAS,CAAC,IAAI,KAAK,CAAC,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,KAAK,CAAC,SAAS,CAAA;QAE7G,OAAO;YACL,GAAG,EAAE,KAAK,CAAC,GAAG;YACd,IAAI,EAAE,KAAK,CAAC,IAAI;YAChB,QAAQ,EAAE,KAAK,CAAC,QAAQ;YACxB,MAAM,EAAE,KAAK,CAAC,MAAM;YACpB,WAAW,EAAE,KAAK,CAAC,WAAW,IAAI,KAAK,CAAC,MAAM;YAC9C,IAAI,EAAE,KAAK,CAAC,IAAI;YAChB,OAAO,EAAE,KAAK,CAAC,OAAO;YACtB,IAAI;YACJ,IAAI,EAAE,KAAK,CAAC,IAAI;YAChB,MAAM,EAAE,KAAK,CAAC,MAAM;SACrB,CAAA;IACH,CAAC,CAAC,CAAA;IAEF,OAAO;QACL,UAAU;QACV,WAAW;QACX,KAAK,EAAE,QAAQ,CAAC,KAAK;QACrB,IAAI,EAAE,QAAQ,CAAC,MAAM,EAAE,SAAS,IAAI,IAAI;QACxC,QAAQ,EAAE,QAAQ,CAAC,MAAM,EAAE,QAAQ,IAAI,QAAQ;QAC/C,WAAW,EAAE,GAAG,OAAO,iBAAiB,kBAAkB,CAAC,UAAU,CAAC,gBAAgB,kBAAkB,CAAC,WAAW,CAAC,EAAE;QACvH,MAAM;KACP,CAAA;AACH,CAAC"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { type SonarCloudClientOptions } from './sonarcloud-client.js';
|
|
2
|
+
export type PullRequestReport = {
|
|
3
|
+
projectKey: string;
|
|
4
|
+
pullRequest: string;
|
|
5
|
+
qualityGateStatus: string;
|
|
6
|
+
failingQualityGateConditions: Array<{
|
|
7
|
+
metricKey: string;
|
|
8
|
+
comparator: string;
|
|
9
|
+
errorThreshold?: string;
|
|
10
|
+
actualValue?: string;
|
|
11
|
+
}>;
|
|
12
|
+
analysisUrl: string;
|
|
13
|
+
issueCounts: {
|
|
14
|
+
newIssues: number;
|
|
15
|
+
acceptedIssues: number;
|
|
16
|
+
};
|
|
17
|
+
measures: {
|
|
18
|
+
securityHotspots: number;
|
|
19
|
+
coverageOnNewCode: number;
|
|
20
|
+
duplicationOnNewCode: number;
|
|
21
|
+
};
|
|
22
|
+
};
|
|
23
|
+
export type PullRequestReportInput = {
|
|
24
|
+
projectKey: string;
|
|
25
|
+
pullRequest: string;
|
|
26
|
+
};
|
|
27
|
+
export declare function getPullRequestReport(clientOptions: SonarCloudClientOptions, input: PullRequestReportInput): Promise<PullRequestReport>;
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { SonarCloudClient, } from './sonarcloud-client.js';
|
|
2
|
+
export async function getPullRequestReport(clientOptions, input) {
|
|
3
|
+
const projectKey = input.projectKey.trim();
|
|
4
|
+
const pullRequest = input.pullRequest.trim();
|
|
5
|
+
if (!projectKey) {
|
|
6
|
+
throw new Error('Missing projectKey');
|
|
7
|
+
}
|
|
8
|
+
if (!pullRequest) {
|
|
9
|
+
throw new Error('Missing pullRequest');
|
|
10
|
+
}
|
|
11
|
+
const baseUrl = (clientOptions.baseUrl ?? 'https://sonarcloud.io').replace(/\/$/, '');
|
|
12
|
+
const client = new SonarCloudClient(clientOptions);
|
|
13
|
+
const [projectStatusResponse, issuesResponse, measuresResponse] = await Promise.all([
|
|
14
|
+
client.getProjectStatus(projectKey, pullRequest),
|
|
15
|
+
client.getIssuesFacets(projectKey, pullRequest),
|
|
16
|
+
client.getMeasures(projectKey, pullRequest),
|
|
17
|
+
]);
|
|
18
|
+
const issueStatuses = issuesResponse.facets.find((facet) => facet.property === 'issueStatuses');
|
|
19
|
+
const newIssues = sumCounts(issueStatuses?.values, ['OPEN', 'CONFIRMED', 'REOPENED']);
|
|
20
|
+
const acceptedIssues = sumCounts(issueStatuses?.values, ['ACCEPTED']);
|
|
21
|
+
return {
|
|
22
|
+
projectKey,
|
|
23
|
+
pullRequest,
|
|
24
|
+
qualityGateStatus: projectStatusResponse.projectStatus.status,
|
|
25
|
+
failingQualityGateConditions: projectStatusResponse.projectStatus.conditions
|
|
26
|
+
.filter((condition) => condition.status !== 'OK')
|
|
27
|
+
.map((condition) => ({
|
|
28
|
+
metricKey: condition.metricKey,
|
|
29
|
+
comparator: condition.comparator,
|
|
30
|
+
errorThreshold: condition.errorThreshold,
|
|
31
|
+
actualValue: condition.actualValue,
|
|
32
|
+
})),
|
|
33
|
+
analysisUrl: `${baseUrl}/dashboard?id=${encodeURIComponent(projectKey)}&pullRequest=${encodeURIComponent(pullRequest)}`,
|
|
34
|
+
issueCounts: {
|
|
35
|
+
newIssues,
|
|
36
|
+
acceptedIssues,
|
|
37
|
+
},
|
|
38
|
+
measures: {
|
|
39
|
+
securityHotspots: measureValue(measuresResponse.component.measures, 'new_security_hotspots'),
|
|
40
|
+
coverageOnNewCode: measureValue(measuresResponse.component.measures, 'new_coverage'),
|
|
41
|
+
duplicationOnNewCode: measureValue(measuresResponse.component.measures, 'new_duplicated_lines_density'),
|
|
42
|
+
},
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
function sumCounts(values, keys) {
|
|
46
|
+
if (!values) {
|
|
47
|
+
return 0;
|
|
48
|
+
}
|
|
49
|
+
return values
|
|
50
|
+
.filter((item) => keys.includes(item.val))
|
|
51
|
+
.reduce((total, item) => total + item.count, 0);
|
|
52
|
+
}
|
|
53
|
+
function measureValue(measures, metric) {
|
|
54
|
+
const measure = measures.find((item) => item.metric === metric);
|
|
55
|
+
const rawValue = measure?.periods?.[0]?.value ?? measure?.value ?? '0';
|
|
56
|
+
const parsed = Number.parseFloat(rawValue);
|
|
57
|
+
return Number.isFinite(parsed) ? parsed : 0;
|
|
58
|
+
}
|
|
59
|
+
//# sourceMappingURL=pr-report.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pr-report.js","sourceRoot":"","sources":["../../src/service/pr-report.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { type SonarCloudClientOptions } from './sonarcloud-client.js';
|
|
2
|
+
export type PullRequestIssueReview = {
|
|
3
|
+
key: string;
|
|
4
|
+
type: string;
|
|
5
|
+
severity: string;
|
|
6
|
+
status: string;
|
|
7
|
+
issueStatus: string;
|
|
8
|
+
rule: string;
|
|
9
|
+
message: string;
|
|
10
|
+
file: string;
|
|
11
|
+
line?: number;
|
|
12
|
+
effort?: string;
|
|
13
|
+
issueUrl: string;
|
|
14
|
+
snippet?: {
|
|
15
|
+
startLine: number;
|
|
16
|
+
endLine: number;
|
|
17
|
+
lines: Array<{
|
|
18
|
+
line: number;
|
|
19
|
+
text: string;
|
|
20
|
+
highlight: boolean;
|
|
21
|
+
}>;
|
|
22
|
+
};
|
|
23
|
+
sourceError?: string;
|
|
24
|
+
};
|
|
25
|
+
export type PullRequestReviewReport = {
|
|
26
|
+
projectKey: string;
|
|
27
|
+
pullRequest: string;
|
|
28
|
+
total: number;
|
|
29
|
+
analysisUrl: string;
|
|
30
|
+
issues: PullRequestIssueReview[];
|
|
31
|
+
};
|
|
32
|
+
export type PullRequestReviewInput = {
|
|
33
|
+
projectKey: string;
|
|
34
|
+
pullRequest: string;
|
|
35
|
+
contextLines?: number;
|
|
36
|
+
page?: number;
|
|
37
|
+
pageSize?: number;
|
|
38
|
+
};
|
|
39
|
+
export declare function getPullRequestReview(clientOptions: SonarCloudClientOptions, input: PullRequestReviewInput): Promise<PullRequestReviewReport>;
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { SonarCloudClient } from './sonarcloud-client.js';
|
|
2
|
+
export async function getPullRequestReview(clientOptions, input) {
|
|
3
|
+
const projectKey = input.projectKey.trim();
|
|
4
|
+
const pullRequest = input.pullRequest.trim();
|
|
5
|
+
if (!projectKey) {
|
|
6
|
+
throw new Error('Missing projectKey');
|
|
7
|
+
}
|
|
8
|
+
if (!pullRequest) {
|
|
9
|
+
throw new Error('Missing pullRequest');
|
|
10
|
+
}
|
|
11
|
+
const page = input.page ?? 1;
|
|
12
|
+
const pageSize = input.pageSize ?? 100;
|
|
13
|
+
const contextLines = Math.max(0, input.contextLines ?? 3);
|
|
14
|
+
const baseUrl = (clientOptions.baseUrl ?? 'https://sonarcloud.io').replace(/\/$/, '');
|
|
15
|
+
const client = new SonarCloudClient(clientOptions);
|
|
16
|
+
const response = await client.getPullRequestIssues(projectKey, pullRequest, page, pageSize);
|
|
17
|
+
const componentPathByKey = new Map((response.components ?? []).map((component) => [
|
|
18
|
+
component.key,
|
|
19
|
+
component.path ?? component.longName ?? component.key,
|
|
20
|
+
]));
|
|
21
|
+
const issues = await Promise.all((response.issues ?? []).map(async (issue) => {
|
|
22
|
+
const file = componentPathByKey.get(issue.component) ?? issue.component.split(':').slice(1).join(':') ?? issue.component;
|
|
23
|
+
const result = {
|
|
24
|
+
key: issue.key,
|
|
25
|
+
type: issue.type,
|
|
26
|
+
severity: issue.severity,
|
|
27
|
+
status: issue.status,
|
|
28
|
+
issueStatus: issue.issueStatus ?? issue.status,
|
|
29
|
+
rule: issue.rule,
|
|
30
|
+
message: issue.message,
|
|
31
|
+
file,
|
|
32
|
+
line: issue.line,
|
|
33
|
+
effort: issue.effort,
|
|
34
|
+
issueUrl: buildIssueUrl(baseUrl, projectKey, pullRequest, issue.key),
|
|
35
|
+
};
|
|
36
|
+
if (!issue.line) {
|
|
37
|
+
return result;
|
|
38
|
+
}
|
|
39
|
+
try {
|
|
40
|
+
const source = await client.getSourceRaw(issue.component, pullRequest);
|
|
41
|
+
result.snippet = makeSnippet(source, issue.line, contextLines);
|
|
42
|
+
}
|
|
43
|
+
catch (error) {
|
|
44
|
+
result.sourceError = error instanceof Error ? error.message : String(error);
|
|
45
|
+
}
|
|
46
|
+
return result;
|
|
47
|
+
}));
|
|
48
|
+
return {
|
|
49
|
+
projectKey,
|
|
50
|
+
pullRequest,
|
|
51
|
+
total: response.total,
|
|
52
|
+
analysisUrl: `${baseUrl}/dashboard?id=${encodeURIComponent(projectKey)}&pullRequest=${encodeURIComponent(pullRequest)}`,
|
|
53
|
+
issues,
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
function buildIssueUrl(baseUrl, projectKey, pullRequest, issueKey) {
|
|
57
|
+
const url = new URL('/project/issues', baseUrl);
|
|
58
|
+
url.searchParams.set('id', projectKey);
|
|
59
|
+
url.searchParams.set('pullRequest', pullRequest);
|
|
60
|
+
url.searchParams.set('issues', issueKey);
|
|
61
|
+
url.searchParams.set('open', issueKey);
|
|
62
|
+
return String(url);
|
|
63
|
+
}
|
|
64
|
+
function makeSnippet(source, issueLine, contextLines) {
|
|
65
|
+
const lines = source.split(/\r?\n/);
|
|
66
|
+
const startLine = Math.max(1, issueLine - contextLines);
|
|
67
|
+
const endLine = Math.min(lines.length, issueLine + contextLines);
|
|
68
|
+
return {
|
|
69
|
+
startLine,
|
|
70
|
+
endLine,
|
|
71
|
+
lines: lines.slice(startLine - 1, endLine).map((text, index) => {
|
|
72
|
+
const line = startLine + index;
|
|
73
|
+
return {
|
|
74
|
+
line,
|
|
75
|
+
text,
|
|
76
|
+
highlight: line === issueLine,
|
|
77
|
+
};
|
|
78
|
+
}),
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
//# sourceMappingURL=pr-review.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pr-review.js","sourceRoot":"","sources":["../../src/service/pr-review.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
export type SonarCloudClientOptions = {
|
|
2
|
+
token: string;
|
|
3
|
+
baseUrl?: string;
|
|
4
|
+
fetchImpl?: typeof fetch;
|
|
5
|
+
};
|
|
6
|
+
export type QualityGateCondition = {
|
|
7
|
+
status: string;
|
|
8
|
+
metricKey: string;
|
|
9
|
+
comparator: string;
|
|
10
|
+
errorThreshold?: string;
|
|
11
|
+
actualValue?: string;
|
|
12
|
+
};
|
|
13
|
+
export type ProjectStatusResponse = {
|
|
14
|
+
projectStatus: {
|
|
15
|
+
status: string;
|
|
16
|
+
conditions: QualityGateCondition[];
|
|
17
|
+
};
|
|
18
|
+
};
|
|
19
|
+
export type IssuesFacetValue = {
|
|
20
|
+
val: string;
|
|
21
|
+
count: number;
|
|
22
|
+
};
|
|
23
|
+
export type IssuesSearchResponse = {
|
|
24
|
+
total: number;
|
|
25
|
+
paging?: {
|
|
26
|
+
pageIndex: number;
|
|
27
|
+
pageSize: number;
|
|
28
|
+
total: number;
|
|
29
|
+
};
|
|
30
|
+
issues?: SonarIssue[];
|
|
31
|
+
components?: SonarIssueComponent[];
|
|
32
|
+
facets: Array<{
|
|
33
|
+
property: string;
|
|
34
|
+
values: IssuesFacetValue[];
|
|
35
|
+
}>;
|
|
36
|
+
};
|
|
37
|
+
export type SonarIssue = {
|
|
38
|
+
key: string;
|
|
39
|
+
rule: string;
|
|
40
|
+
severity: string;
|
|
41
|
+
component: string;
|
|
42
|
+
line?: number;
|
|
43
|
+
status: string;
|
|
44
|
+
issueStatus?: string;
|
|
45
|
+
message: string;
|
|
46
|
+
type: string;
|
|
47
|
+
effort?: string;
|
|
48
|
+
};
|
|
49
|
+
export type SonarIssueComponent = {
|
|
50
|
+
key: string;
|
|
51
|
+
path?: string;
|
|
52
|
+
longName?: string;
|
|
53
|
+
};
|
|
54
|
+
export type MeasuresResponse = {
|
|
55
|
+
component: {
|
|
56
|
+
measures: Array<{
|
|
57
|
+
metric: string;
|
|
58
|
+
value?: string;
|
|
59
|
+
periods?: Array<{
|
|
60
|
+
index: number;
|
|
61
|
+
value: string;
|
|
62
|
+
}>;
|
|
63
|
+
}>;
|
|
64
|
+
};
|
|
65
|
+
};
|
|
66
|
+
export type ComponentTreeResponse = {
|
|
67
|
+
paging: {
|
|
68
|
+
pageIndex: number;
|
|
69
|
+
pageSize: number;
|
|
70
|
+
total: number;
|
|
71
|
+
};
|
|
72
|
+
components: Array<{
|
|
73
|
+
key: string;
|
|
74
|
+
path?: string;
|
|
75
|
+
name: string;
|
|
76
|
+
measures: Array<{
|
|
77
|
+
metric: string;
|
|
78
|
+
value?: string;
|
|
79
|
+
periods?: Array<{
|
|
80
|
+
index: number;
|
|
81
|
+
value: string;
|
|
82
|
+
}>;
|
|
83
|
+
}>;
|
|
84
|
+
}>;
|
|
85
|
+
};
|
|
86
|
+
export declare class SonarCloudClient {
|
|
87
|
+
private readonly token;
|
|
88
|
+
private readonly baseUrl;
|
|
89
|
+
private readonly fetchImpl;
|
|
90
|
+
constructor(options: SonarCloudClientOptions);
|
|
91
|
+
getProjectStatus(projectKey: string, pullRequest: string): Promise<ProjectStatusResponse>;
|
|
92
|
+
getIssuesFacets(projectKey: string, pullRequest: string): Promise<IssuesSearchResponse>;
|
|
93
|
+
getPullRequestIssues(projectKey: string, pullRequest: string, page?: number, pageSize?: number): Promise<IssuesSearchResponse>;
|
|
94
|
+
getMeasures(projectKey: string, pullRequest: string): Promise<MeasuresResponse>;
|
|
95
|
+
getCoverageComponentTree(projectKey: string, pullRequest: string, page?: number, pageSize?: number): Promise<ComponentTreeResponse>;
|
|
96
|
+
getSourceRaw(componentKey: string, pullRequest: string): Promise<string>;
|
|
97
|
+
doIssueTransition(issueKey: string, transition: string, comment?: string): Promise<void>;
|
|
98
|
+
private get;
|
|
99
|
+
private post;
|
|
100
|
+
}
|