apex-code-coverage-transformer 3.1.9 → 3.1.11
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/CHANGELOG.md +14 -0
- package/README.md +7 -3
- package/lib/transformers/coverageProcessor.js +19 -33
- package/lib/transformers/coverageProcessor.js.map +1 -1
- package/oclif.manifest.json +1 -1
- package/package.json +14 -14
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,20 @@
|
|
|
5
5
|
|
|
6
6
|
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
|
|
7
7
|
|
|
8
|
+
## [3.1.11](https://github.com/mcarvin8/apex-code-coverage-transformer/compare/v3.1.10...v3.1.11) (2026-10-12)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
### Bug Fixes
|
|
12
|
+
|
|
13
|
+
* **deps:** bump fast-copy from 3.0.2 to 3.1.0 ([#413](https://github.com/mcarvin8/apex-code-coverage-transformer/issues/413)) ([58e12e9](https://github.com/mcarvin8/apex-code-coverage-transformer/commit/58e12e90b69cdbb7e63e53bacf92c06e3d842aaa))
|
|
14
|
+
|
|
15
|
+
## [3.1.10](https://github.com/mcarvin8/apex-code-coverage-transformer/compare/v3.1.9...v3.1.10) (2026-10-12)
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
### Bug Fixes
|
|
19
|
+
|
|
20
|
+
* **deps:** bump the dependencies group across 1 directory with 3 updates ([#409](https://github.com/mcarvin8/apex-code-coverage-transformer/issues/409)) ([5ca0bae](https://github.com/mcarvin8/apex-code-coverage-transformer/commit/5ca0bae2f303e7e01d1e9e4311d0f626044a67a2))
|
|
21
|
+
|
|
8
22
|
## [3.1.9](https://github.com/mcarvin8/apex-code-coverage-transformer/compare/v3.1.8...v3.1.9) (2026-09-30)
|
|
9
23
|
|
|
10
24
|
|
package/README.md
CHANGED
|
@@ -4,12 +4,14 @@
|
|
|
4
4
|
[](https://npmjs.org/package/apex-code-coverage-transformer)
|
|
5
5
|
[](https://github.com/marketplace/actions/apex-code-coverage-transformer)
|
|
6
6
|
[](https://raw.githubusercontent.com/mcarvin8/apex-code-coverage-transformer/main/LICENSE.md)
|
|
7
|
-
[](https://qlty.sh/gh/mcarvin8/projects/apex-code-coverage-transformer)
|
|
8
7
|
[](https://codecov.io/gh/mcarvin8/apex-code-coverage-transformer)
|
|
9
8
|
[](https://dashboard.stryker-mutator.io/reports/github.com/mcarvin8/apex-code-coverage-transformer/main)
|
|
10
9
|
|
|
11
10
|
Transforms (and optionally merges) Apex code coverage JSON from Salesforce deployments or test runs into formats used by SonarQube, Codecov, GitHub, GitLab, Azure DevOps, Bitbucket, and other tools, keeping coverage visible across pull requests, CI/CD pipelines, and code quality platforms. Available as a **Salesforce CLI plugin** for any provider, and as a **native GitHub Action** for GitHub Actions users who want to skip installing the CLI.
|
|
12
11
|
|
|
12
|
+
> [!WARNING]
|
|
13
|
+
> **Note:** Salesforce deploy command coverage reports contain a known bug where covered lines can be reported beyond the end of a file. This plugin automatically re-numbers those lines to keep deploy coverage accurate. Salesforce API v68.0 is expected to resolve the bug; the fix is kept in place for API v67.0 and earlier. Test-command coverage is unaffected. See [Troubleshooting](#troubleshooting) for details.
|
|
14
|
+
|
|
13
15
|
<details>
|
|
14
16
|
<summary>Table of Contents</summary>
|
|
15
17
|
|
|
@@ -193,7 +195,7 @@ EXAMPLES
|
|
|
193
195
|
`sf acc-transformer transform -j "coverage1.json" -j "coverage2.json" -r "coverage.xml" -f "sonar"`
|
|
194
196
|
```
|
|
195
197
|
|
|
196
|
-
_See code: [src/commands/acc-transformer/transform.ts](https://github.com/mcarvin8/apex-code-coverage-transformer/blob/v3.1.
|
|
198
|
+
_See code: [src/commands/acc-transformer/transform.ts](https://github.com/mcarvin8/apex-code-coverage-transformer/blob/v3.1.11/src/commands/acc-transformer/transform.ts)_
|
|
197
199
|
<!-- commandsstop -->
|
|
198
200
|
|
|
199
201
|
## Coverage Report Formats
|
|
@@ -588,7 +590,9 @@ Error (1): sfdx-project.json not found in any parent directory.
|
|
|
588
590
|
Error (1): ENOENT: no such file or directory: {packageDir}
|
|
589
591
|
```
|
|
590
592
|
|
|
591
|
-
**Deploy coverage line numbers** —
|
|
593
|
+
**Deploy coverage line numbers** — Salesforce deploy command coverage reports contain known out-of-range line numbers, regardless of the coverage format requested from the Salesforce CLI. This plugin corrects them automatically by re-numbering covered lines; uncovered lines are unaffected. Test-command coverage is unaffected. See [forcedotcom/salesforcedx-vscode#5511](https://github.com/forcedotcom/salesforcedx-vscode/issues/5511) and [forcedotcom/cli#1568](https://github.com/forcedotcom/cli/issues/1568).
|
|
594
|
+
|
|
595
|
+
Salesforce API v68.0 is expected to resolve the out-of-range line numbers in deploy coverage. The re-numbering logic is kept intact for compatibility with API v67.0 and earlier. It only acts on covered lines beyond the end of a file, so when deploy coverage contains no out-of-range lines, it makes no changes.
|
|
592
596
|
|
|
593
597
|
To see each remapping, set `SF_LOG_LEVEL=debug` before running the command - each remapped line prints directly to the terminal:
|
|
594
598
|
|
|
@@ -30,13 +30,12 @@ export function countLines(lines) {
|
|
|
30
30
|
const coveredLines = Object.values(lines).filter((v) => v === 1).length;
|
|
31
31
|
return { totalLines, coveredLines };
|
|
32
32
|
}
|
|
33
|
-
|
|
33
|
+
async function processEntries(items, context, getName, resolveLines) {
|
|
34
34
|
let processed = 0;
|
|
35
35
|
let totalLines = 0;
|
|
36
36
|
let coveredLines = 0;
|
|
37
|
-
await mapLimit(
|
|
38
|
-
const
|
|
39
|
-
const formattedName = fileName.replace(/no-map[\\/]+/, '');
|
|
37
|
+
await mapLimit(items, context.concurrencyLimit, async (item) => {
|
|
38
|
+
const formattedName = getName(item).replace(/no-map[\\/]+/, '');
|
|
40
39
|
const path = findFilePath(formattedName, context.filePathCache);
|
|
41
40
|
if (!path) {
|
|
42
41
|
context.warnings.push(`The file name ${formattedName} was not found in any package directory.`);
|
|
@@ -45,43 +44,30 @@ export async function processDeployCoverage(data, context) {
|
|
|
45
44
|
if (context.excludePatterns.some((pattern) => matchesGlob(path, pattern, { matchBase: true }))) {
|
|
46
45
|
return;
|
|
47
46
|
}
|
|
48
|
-
const
|
|
49
|
-
const
|
|
50
|
-
const sourceContent = hasSourceContent(setCoveredResult) ? setCoveredResult.sourceContent : undefined;
|
|
51
|
-
fileInfo.s = updatedLines;
|
|
52
|
-
const counts = countLines(updatedLines);
|
|
47
|
+
const { lines, sourceContent } = await resolveLines(item, path);
|
|
48
|
+
const counts = countLines(lines);
|
|
53
49
|
totalLines += counts.totalLines;
|
|
54
50
|
coveredLines += counts.coveredLines;
|
|
55
51
|
for (const handler of context.handlers.values()) {
|
|
56
|
-
handler.processFile(path, formattedName,
|
|
52
|
+
handler.processFile(path, formattedName, lines, sourceContent);
|
|
57
53
|
}
|
|
58
54
|
processed++;
|
|
59
55
|
});
|
|
60
56
|
return { processed, totalLines, coveredLines };
|
|
61
57
|
}
|
|
62
|
-
export
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
if (!path) {
|
|
70
|
-
context.warnings.push(`The file name ${formattedName} was not found in any package directory.`);
|
|
71
|
-
return;
|
|
72
|
-
}
|
|
73
|
-
if (context.excludePatterns.some((pattern) => matchesGlob(path, pattern, { matchBase: true }))) {
|
|
74
|
-
return;
|
|
75
|
-
}
|
|
76
|
-
const counts = countLines(entry.lines);
|
|
77
|
-
totalLines += counts.totalLines;
|
|
78
|
-
coveredLines += counts.coveredLines;
|
|
79
|
-
const sourceContent = context.handlers.has('html') ? await readSourceFile(join(context.repoRoot, path)) : undefined;
|
|
80
|
-
for (const handler of context.handlers.values()) {
|
|
81
|
-
handler.processFile(path, formattedName, entry.lines, sourceContent);
|
|
82
|
-
}
|
|
83
|
-
processed++;
|
|
58
|
+
export function processDeployCoverage(data, context) {
|
|
59
|
+
return processEntries(Object.keys(data), context, (fileName) => fileName, async (fileName, path) => {
|
|
60
|
+
const fileInfo = data[fileName];
|
|
61
|
+
const result = await setCoveredLines(path, context.repoRoot, fileInfo.s, context.handlers.has('html'));
|
|
62
|
+
const updatedLines = hasSourceContent(result) ? result.updatedLines : result;
|
|
63
|
+
fileInfo.s = updatedLines;
|
|
64
|
+
return { lines: updatedLines, sourceContent: hasSourceContent(result) ? result.sourceContent : undefined };
|
|
84
65
|
});
|
|
85
|
-
|
|
66
|
+
}
|
|
67
|
+
export function processTestCoverage(data, context) {
|
|
68
|
+
return processEntries(data, context, (entry) => entry.name, async (entry, path) => ({
|
|
69
|
+
lines: entry.lines,
|
|
70
|
+
sourceContent: context.handlers.has('html') ? await readSourceFile(join(context.repoRoot, path)) : undefined,
|
|
71
|
+
}));
|
|
86
72
|
}
|
|
87
73
|
//# sourceMappingURL=coverageProcessor.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"coverageProcessor.js","sourceRoot":"","sources":["../../src/transformers/coverageProcessor.ts"],"names":[],"mappings":"AAAA,qCAAqC;AACrC,YAAY,CAAC;AAEb,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAC/D,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AACxD,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AACtD,OAAO,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAChD,OAAO,EAA8B,eAAe,EAAE,MAAM,6BAA6B,CAAC;AAS1F,MAAM,UAAU,cAAc,CAAC,OAAiB;IAC9C,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAiD,CAAC;IAC1E,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;QAC7B,QAAQ,CAAC,GAAG,CAAC,MAAM,EAAE,kBAAkB,CAAC,MAAM,CAAC,CAAC,CAAC;IACnD,CAAC;IACD,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,SAAS,gBAAgB,CACvB,MAA6B;IAE7B,OAAO,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,KAAK,IAAI,IAAI,eAAe,IAAI,MAAM,CAAC;AACpF,CAAC;AAED,KAAK,UAAU,cAAc,CAAC,YAAoB;IAChD,IAAI,CAAC;QACH,OAAO,MAAM,QAAQ,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC;IAC/C,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,SAAS,CAAC;IACnB,CAAC;AACH,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,KAA6B;IACtD,MAAM,UAAU,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC;IAC7C,MAAM,YAAY,GAAG,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC;IACxE,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,CAAC;AACtC,CAAC;
|
|
1
|
+
{"version":3,"file":"coverageProcessor.js","sourceRoot":"","sources":["../../src/transformers/coverageProcessor.ts"],"names":[],"mappings":"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"}
|
package/oclif.manifest.json
CHANGED
package/package.json
CHANGED
|
@@ -1,33 +1,33 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "apex-code-coverage-transformer",
|
|
3
3
|
"description": "Transform Salesforce Apex code coverage JSON for SonarQube, SonarCloud, GitHub, GitLab, Azure, and Bitbucket",
|
|
4
|
-
"version": "3.1.
|
|
4
|
+
"version": "3.1.11",
|
|
5
5
|
"dependencies": {
|
|
6
|
-
"@oclif/core": "
|
|
7
|
-
"@salesforce/core": "9.
|
|
8
|
-
"@salesforce/sf-plugins-core": "13.0.
|
|
6
|
+
"@oclif/core": "5.1.2",
|
|
7
|
+
"@salesforce/core": "9.2.0",
|
|
8
|
+
"@salesforce/sf-plugins-core": "13.0.4"
|
|
9
9
|
},
|
|
10
10
|
"devDependencies": {
|
|
11
11
|
"@actions/core": "3.0.1",
|
|
12
|
-
"@biomejs/biome": "2.5.
|
|
13
|
-
"@commitlint/cli": "21.2.
|
|
14
|
-
"@commitlint/config-conventional": "21.2.
|
|
12
|
+
"@biomejs/biome": "2.5.14",
|
|
13
|
+
"@commitlint/cli": "21.2.3",
|
|
14
|
+
"@commitlint/config-conventional": "21.2.3",
|
|
15
15
|
"@salesforce/cli-plugins-testkit": "5.3.66",
|
|
16
16
|
"@salesforce/dev-config": "4.3.3",
|
|
17
17
|
"@stryker-mutator/core": "10.0.0",
|
|
18
18
|
"@stryker-mutator/vitest-runner": "10.0.0",
|
|
19
|
-
"@types/node": "26.
|
|
20
|
-
"@vitest/coverage-v8": "
|
|
19
|
+
"@types/node": "26.6.3",
|
|
20
|
+
"@vitest/coverage-v8": "5.0.2",
|
|
21
21
|
"esbuild": "0.28.2",
|
|
22
22
|
"husky": "9.1.7",
|
|
23
|
-
"knip": "6.
|
|
24
|
-
"lint-staged": "17.
|
|
23
|
+
"knip": "6.38.0",
|
|
24
|
+
"lint-staged": "17.6.0",
|
|
25
25
|
"ls-engines": "0.10.1",
|
|
26
|
-
"oclif": "
|
|
26
|
+
"oclif": "6.0.2",
|
|
27
27
|
"shx": "0.4.0",
|
|
28
|
-
"tsx": "4.23.
|
|
28
|
+
"tsx": "4.23.15",
|
|
29
29
|
"typescript": "7.0.2",
|
|
30
|
-
"vitest": "
|
|
30
|
+
"vitest": "5.0.2",
|
|
31
31
|
"wireit": "0.14.13"
|
|
32
32
|
},
|
|
33
33
|
"engines": {
|