qualink 0.6.0 → 0.6.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.
- package/README.md +2 -2
- package/dist/cli/commands/{coverage-dotnet.d.ts → coverage-cobertura.d.ts} +1 -1
- package/dist/cli/commands/coverage-cobertura.js +12 -0
- package/dist/cli/commands/index.d.ts +1 -1
- package/dist/cli/commands/index.js +1 -1
- package/dist/cli/index.js +2 -2
- package/dist/cli/multi-collect/patterns.d.ts +1 -1
- package/dist/cli/multi-collect/patterns.js +2 -2
- package/dist/cli/multi-collect/resolve-metadata.js +1 -1
- package/dist/cli/multi-collect/run-collector.js +4 -4
- package/dist/collectors/coverage-cobertura.d.ts +2 -0
- package/dist/collectors/{coverage-dotnet.js → coverage-cobertura.js} +3 -3
- package/dist/collectors/index.d.ts +1 -1
- package/dist/collectors/index.js +1 -1
- package/dist/sinks/elastic.js +1 -1
- package/dist/types.d.ts +4 -4
- package/package.json +9 -9
- package/dist/cli/commands/coverage-dotnet.js +0 -12
- package/dist/collectors/coverage-dotnet.d.ts +0 -2
package/README.md
CHANGED
|
@@ -110,7 +110,7 @@ qualink collect <collector> --input <path> --sink elastic [flags]
|
|
|
110
110
|
```bash
|
|
111
111
|
qualink collect eslint --input eslint-report.json --sink elastic --repo frontend-mono --category frontend --tags frontend,web
|
|
112
112
|
qualink collect sarif --input analyzers.sarif --sink elastic --repo backend-api --category backend --tags backend,api
|
|
113
|
-
qualink collect coverage-
|
|
113
|
+
qualink collect coverage-cobertura --input coverage.cobertura.xml --sink elastic --repo backend-api
|
|
114
114
|
```
|
|
115
115
|
|
|
116
116
|
### Multi-collect
|
|
@@ -160,7 +160,7 @@ Collectors:
|
|
|
160
160
|
- `lighthouse` (Lighthouse JSON)
|
|
161
161
|
- `coverage-js` (Istanbul/Vitest JSON)
|
|
162
162
|
- `sarif` (Roslyn or generic SARIF JSON)
|
|
163
|
-
- `coverage-
|
|
163
|
+
- `coverage-cobertura` (Cobertura/OpenCover XML)
|
|
164
164
|
- `junit` (JUnit XML)
|
|
165
165
|
|
|
166
166
|
ESLint file-level options (optional):
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { collectCoverageCobertura } from "../../collectors/coverage-cobertura.js";
|
|
2
|
+
import { createCollectorCommand } from "../command-factory.js";
|
|
3
|
+
import { loadTextInput } from "../load-input.js";
|
|
4
|
+
export const coverageCoberturaCommand = createCollectorCommand({
|
|
5
|
+
name: "coverage-cobertura",
|
|
6
|
+
description: "Collect Cobertura XML coverage metrics and relay them",
|
|
7
|
+
async collect(args, metadata) {
|
|
8
|
+
const input = await loadTextInput(args);
|
|
9
|
+
const documents = collectCoverageCobertura(input, metadata);
|
|
10
|
+
return { metricType: "coverage-cobertura", documents };
|
|
11
|
+
},
|
|
12
|
+
});
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export { biomeCommand } from "./biome.js";
|
|
2
|
-
export {
|
|
2
|
+
export { coverageCoberturaCommand } from "./coverage-cobertura.js";
|
|
3
3
|
export { coverageJsCommand } from "./coverage-js.js";
|
|
4
4
|
export { eslintCommand } from "./eslint.js";
|
|
5
5
|
export { junitCommand } from "./junit.js";
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export { biomeCommand } from "./biome.js";
|
|
2
|
-
export {
|
|
2
|
+
export { coverageCoberturaCommand } from "./coverage-cobertura.js";
|
|
3
3
|
export { coverageJsCommand } from "./coverage-js.js";
|
|
4
4
|
export { eslintCommand } from "./eslint.js";
|
|
5
5
|
export { junitCommand } from "./junit.js";
|
package/dist/cli/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { relative } from "node:path";
|
|
2
2
|
import { defineCommand, runMain } from "citty";
|
|
3
3
|
import { CliError } from "./cli-error.js";
|
|
4
|
-
import { biomeCommand,
|
|
4
|
+
import { biomeCommand, coverageCoberturaCommand, coverageJsCommand, eslintCommand, junitCommand, lighthouseCommand, metaCommand, pipelineCommand, sarifCommand, } from "./commands/index.js";
|
|
5
5
|
import { commonArgs, isDryRun } from "./common-args.js";
|
|
6
6
|
import { parseConfig, resolveConfig } from "./multi-collect/config.js";
|
|
7
7
|
import { discoverFiles } from "./multi-collect/discover.js";
|
|
@@ -33,7 +33,7 @@ const collectCommand = defineCommand({
|
|
|
33
33
|
lighthouse: lighthouseCommand,
|
|
34
34
|
"coverage-js": coverageJsCommand,
|
|
35
35
|
sarif: sarifCommand,
|
|
36
|
-
"coverage-
|
|
36
|
+
"coverage-cobertura": coverageCoberturaCommand,
|
|
37
37
|
junit: junitCommand,
|
|
38
38
|
},
|
|
39
39
|
async run({ args }) {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { MetricType } from "../../types.js";
|
|
2
|
-
export type CollectorKey = Extract<MetricType, "eslint" | "biome" | "coverage-js" | "coverage-
|
|
2
|
+
export type CollectorKey = Extract<MetricType, "eslint" | "biome" | "coverage-js" | "coverage-cobertura" | "sarif" | "lighthouse" | "junit">;
|
|
3
3
|
export declare const COLLECTOR_KEYS: readonly CollectorKey[];
|
|
4
4
|
export interface FilePattern {
|
|
5
5
|
/** Match against basename only */
|
|
@@ -2,7 +2,7 @@ export const COLLECTOR_KEYS = [
|
|
|
2
2
|
"eslint",
|
|
3
3
|
"biome",
|
|
4
4
|
"coverage-js",
|
|
5
|
-
"coverage-
|
|
5
|
+
"coverage-cobertura",
|
|
6
6
|
"sarif",
|
|
7
7
|
"lighthouse",
|
|
8
8
|
"junit",
|
|
@@ -11,7 +11,7 @@ export const COLLECTOR_PATTERNS = {
|
|
|
11
11
|
eslint: [{ basename: "eslint-report.json" }],
|
|
12
12
|
biome: [{ basename: "biome-report.json" }],
|
|
13
13
|
"coverage-js": [{ basename: "coverage-summary.json" }],
|
|
14
|
-
"coverage-
|
|
14
|
+
"coverage-cobertura": [
|
|
15
15
|
{ basename: "coverage.cobertura.xml" },
|
|
16
16
|
{ basename: "cobertura-coverage.xml" },
|
|
17
17
|
],
|
|
@@ -116,7 +116,7 @@ export function resolveFileMetadata(filePath, collectorKey) {
|
|
|
116
116
|
const stopAt = gitRoot ?? fileDir;
|
|
117
117
|
const overrides = {};
|
|
118
118
|
// Detect project name
|
|
119
|
-
if (collectorKey === "coverage-
|
|
119
|
+
if (collectorKey === "coverage-cobertura" || collectorKey === "sarif") {
|
|
120
120
|
overrides.projectName = findNearestProjectName(fileDir, stopAt) ?? null;
|
|
121
121
|
}
|
|
122
122
|
else {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { collectBiome } from "../../collectors/biome.js";
|
|
2
|
-
import {
|
|
2
|
+
import { collectCoverageCobertura } from "../../collectors/coverage-cobertura.js";
|
|
3
3
|
import { collectCoverageJs } from "../../collectors/coverage-js.js";
|
|
4
4
|
import { collectEslint } from "../../collectors/eslint.js";
|
|
5
5
|
import { collectJunit } from "../../collectors/junit.js";
|
|
@@ -53,10 +53,10 @@ export async function runCollector(key, filePath, metadata, urlOverride) {
|
|
|
53
53
|
const documents = collectCoverageJs(input, metadata);
|
|
54
54
|
return { metricType: "coverage-js", documents };
|
|
55
55
|
}
|
|
56
|
-
case "coverage-
|
|
56
|
+
case "coverage-cobertura": {
|
|
57
57
|
const input = await readTextFile(filePath);
|
|
58
|
-
const documents =
|
|
59
|
-
return { metricType: "coverage-
|
|
58
|
+
const documents = collectCoverageCobertura(input, metadata);
|
|
59
|
+
return { metricType: "coverage-cobertura", documents };
|
|
60
60
|
}
|
|
61
61
|
case "sarif": {
|
|
62
62
|
const input = await readJsonFile(filePath);
|
|
@@ -39,7 +39,7 @@ function parseOpenCover(root) {
|
|
|
39
39
|
branchesCovered: readNumber(summary, "@_visitedBranchPoints"),
|
|
40
40
|
};
|
|
41
41
|
}
|
|
42
|
-
export function
|
|
42
|
+
export function collectCoverageCobertura(xmlInput, metadata) {
|
|
43
43
|
const parser = new XMLParser({
|
|
44
44
|
ignoreAttributes: false,
|
|
45
45
|
attributeNamePrefix: "@_",
|
|
@@ -76,8 +76,8 @@ export function collectCoverageDotnet(xmlInput, metadata) {
|
|
|
76
76
|
const functionsCovered = 0;
|
|
77
77
|
const doc = {
|
|
78
78
|
...baseDocument({
|
|
79
|
-
metricType: "coverage-
|
|
80
|
-
tool: "
|
|
79
|
+
metricType: "coverage-cobertura",
|
|
80
|
+
tool: "cobertura",
|
|
81
81
|
languages: ["csharp"],
|
|
82
82
|
metadata,
|
|
83
83
|
}),
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export { collectBiome } from "./biome.js";
|
|
2
|
-
export {
|
|
2
|
+
export { collectCoverageCobertura } from "./coverage-cobertura.js";
|
|
3
3
|
export { collectCoverageJs } from "./coverage-js.js";
|
|
4
4
|
export { collectEslint } from "./eslint.js";
|
|
5
5
|
export { collectLighthouse } from "./lighthouse.js";
|
package/dist/collectors/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export { collectBiome } from "./biome.js";
|
|
2
|
-
export {
|
|
2
|
+
export { collectCoverageCobertura } from "./coverage-cobertura.js";
|
|
3
3
|
export { collectCoverageJs } from "./coverage-js.js";
|
|
4
4
|
export { collectEslint } from "./eslint.js";
|
|
5
5
|
export { collectLighthouse } from "./lighthouse.js";
|
package/dist/sinks/elastic.js
CHANGED
|
@@ -5,7 +5,7 @@ export const INDEX_BY_TYPE = {
|
|
|
5
5
|
lighthouse: "codequality-lighthouse",
|
|
6
6
|
"coverage-js": "codequality-coverage-js",
|
|
7
7
|
sarif: "codequality-sarif",
|
|
8
|
-
"coverage-
|
|
8
|
+
"coverage-cobertura": "codequality-coverage-cobertura",
|
|
9
9
|
junit: "codequality-junit",
|
|
10
10
|
meta: "codequality-meta",
|
|
11
11
|
pipeline: "codequality-pipeline",
|
package/dist/types.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export type Language = "js" | "ts" | "csharp" | (string & {});
|
|
2
2
|
export type Environment = "dev" | "test" | "prod" | "ci";
|
|
3
|
-
export type MetricType = "biome" | "eslint" | "lighthouse" | "coverage-js" | "sarif" | "coverage-
|
|
3
|
+
export type MetricType = "biome" | "eslint" | "lighthouse" | "coverage-js" | "sarif" | "coverage-cobertura" | "junit" | "meta" | "pipeline";
|
|
4
4
|
export interface BaseMetricDocument {
|
|
5
5
|
"@timestamp": string;
|
|
6
6
|
metric_type: MetricType;
|
|
@@ -102,8 +102,8 @@ export interface BiomeFileIssue {
|
|
|
102
102
|
fixable_errors: number;
|
|
103
103
|
fixable_warnings: number;
|
|
104
104
|
}
|
|
105
|
-
export interface
|
|
106
|
-
metric_type: "coverage-
|
|
105
|
+
export interface CoberturaCoverageMetricDocument extends CoverageMetricDocument {
|
|
106
|
+
metric_type: "coverage-cobertura";
|
|
107
107
|
coverage_format: "cobertura" | "opencover" | (string & {});
|
|
108
108
|
}
|
|
109
109
|
export interface JunitMetricDocument extends BaseMetricDocument {
|
|
@@ -128,7 +128,7 @@ export interface PipelineMetricDocument extends BaseMetricDocument {
|
|
|
128
128
|
start_time: string | null;
|
|
129
129
|
stage_name: string | null;
|
|
130
130
|
}
|
|
131
|
-
export type NormalizedDocument = BiomeMetricDocument | EslintMetricDocument | LighthouseMetricDocument | CoverageJsMetricDocument | SarifMetricDocument |
|
|
131
|
+
export type NormalizedDocument = BiomeMetricDocument | EslintMetricDocument | LighthouseMetricDocument | CoverageJsMetricDocument | SarifMetricDocument | CoberturaCoverageMetricDocument | JunitMetricDocument | MetaMetricDocument | PipelineMetricDocument;
|
|
132
132
|
export interface CommonMetadata {
|
|
133
133
|
repo: string;
|
|
134
134
|
category: string | null;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "qualink",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.1",
|
|
4
4
|
"description": "Collect, normalize, and relay code quality metrics from CI",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -17,17 +17,17 @@
|
|
|
17
17
|
"node": ">=22"
|
|
18
18
|
},
|
|
19
19
|
"dependencies": {
|
|
20
|
-
"citty": "^0.2.
|
|
21
|
-
"fast-xml-parser": "^5.
|
|
20
|
+
"citty": "^0.2.2",
|
|
21
|
+
"fast-xml-parser": "^5.7.3"
|
|
22
22
|
},
|
|
23
23
|
"devDependencies": {
|
|
24
|
-
"@biomejs/biome": "^2.4.
|
|
25
|
-
"@types/node": "^25.
|
|
26
|
-
"@vitest/coverage-v8": "^4.
|
|
27
|
-
"git-cliff": "^2.
|
|
24
|
+
"@biomejs/biome": "^2.4.14",
|
|
25
|
+
"@types/node": "^25.6.0",
|
|
26
|
+
"@vitest/coverage-v8": "^4.1.5",
|
|
27
|
+
"git-cliff": "^2.13.1",
|
|
28
28
|
"ts-node": "^10.9.2",
|
|
29
|
-
"typescript": "^
|
|
30
|
-
"vitest": "^4.
|
|
29
|
+
"typescript": "^6.0.3",
|
|
30
|
+
"vitest": "^4.1.5"
|
|
31
31
|
},
|
|
32
32
|
"repository": {
|
|
33
33
|
"type": "git",
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import { collectCoverageDotnet } from "../../collectors/coverage-dotnet.js";
|
|
2
|
-
import { createCollectorCommand } from "../command-factory.js";
|
|
3
|
-
import { loadTextInput } from "../load-input.js";
|
|
4
|
-
export const coverageDotnetCommand = createCollectorCommand({
|
|
5
|
-
name: "coverage-dotnet",
|
|
6
|
-
description: "Collect .NET coverage metrics and relay them",
|
|
7
|
-
async collect(args, metadata) {
|
|
8
|
-
const input = await loadTextInput(args);
|
|
9
|
-
const documents = collectCoverageDotnet(input, metadata);
|
|
10
|
-
return { metricType: "coverage-dotnet", documents };
|
|
11
|
-
},
|
|
12
|
-
});
|