apex-code-coverage-transformer 2.20.0 → 2.21.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/CHANGELOG.md CHANGED
@@ -5,6 +5,13 @@
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
+ ## [2.21.0](https://github.com/mcarvin8/apex-code-coverage-transformer/compare/v2.20.0...v2.21.0) (2026-06-02)
9
+
10
+
11
+ ### Features
12
+
13
+ * log out-of-range covered line remappings at debug level ([#300](https://github.com/mcarvin8/apex-code-coverage-transformer/issues/300)) ([e812869](https://github.com/mcarvin8/apex-code-coverage-transformer/commit/e812869eff4290af8d3e519ea59fd754475ac325))
14
+
8
15
  ## [2.20.0](https://github.com/mcarvin8/apex-code-coverage-transformer/compare/v2.19.2...v2.20.0) (2026-05-29)
9
16
 
10
17
 
package/README.md CHANGED
@@ -5,10 +5,9 @@
5
5
  [![License](https://img.shields.io/badge/License-MIT-yellow.svg)](https://raw.githubusercontent.com/mcarvin8/apex-code-coverage-transformer/main/LICENSE.md)
6
6
  [![Maintainability](https://qlty.sh/badges/11057a07-84da-41af-91fb-b3476e404242/maintainability.svg)](https://qlty.sh/gh/mcarvin8/projects/apex-code-coverage-transformer)
7
7
  [![codecov](https://codecov.io/gh/mcarvin8/apex-code-coverage-transformer/graph/badge.svg?token=4IQ4NWTPQZ)](https://codecov.io/gh/mcarvin8/apex-code-coverage-transformer)
8
+ [![Mutation testing badge](https://img.shields.io/endpoint?style=flat&url=https%3A%2F%2Fbadge-api.stryker-mutator.io%2Fgithub.com%2Fmcarvin8%2Fapex-code-coverage-transformer%2Fmain)](https://dashboard.stryker-mutator.io/reports/github.com/mcarvin8/apex-code-coverage-transformer/main)
8
9
 
9
- A Salesforce CLI plugin that converts Apex code coverage JSON (from deploy or test runs) into formats used by SonarQube, Codecov, GitHub, GitLab, Azure DevOps, Bitbucket, and other tools. Use it to keep coverage in sync with your CI/CD and code quality pipelines.
10
-
11
- It also produces presentation-ready output for pull-request reviews: a Markdown summary for PR/MR comments and CI job summaries, and GitHub Actions workflow command annotations that surface uncovered lines inline on the PR diff. The GitHub Actions output pairs with the Apex code quality annotations from [sf-cat](https://www.npmjs.com/package/sf-cat), so a single PR can show coverage gaps and quality findings side-by-side.
10
+ A Salesforce CLI plugin that converts Apex code coverage JSON (from deploy 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.
12
11
 
13
12
  > Missing an output format via `--format`? Open an [issue](https://github.com/mcarvin8/apex-code-coverage-transformer/issues) or submit a [pull request](https://github.com/mcarvin8/apex-code-coverage-transformer/blob/main/CONTRIBUTING.md).
14
13
 
@@ -245,11 +244,7 @@ The `github-actions` format emits one [`::warning`](https://docs.github.com/en/a
245
244
  run: cat coverage.txt
246
245
  ```
247
246
 
248
- Pairs with [`sf-cat`](https://www.npmjs.com/package/sf-cat) for code quality annotations on the same diff. Produce both at once:
249
-
250
- ```bash
251
- sf acc-transformer transform -j "coverage/test-result-codecoverage.json" -f "markdown" -f "github-actions" -f "sonar"
252
- ```
247
+ Pairs with [`sf-cat`](https://www.github.com/mcarvin8/sf-cat) for code quality annotations on the same diff if you use Salesforce Code Analyzer.
253
248
 
254
249
  ### GitLab CI
255
250
 
@@ -350,6 +345,20 @@ Error (1): ENOENT: no such file or directory: {packageDir}
350
345
 
351
346
  **Deploy coverage line numbers** — The Salesforce CLI deploy coverage JSON contains known out-of-range line numbers. 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).
352
347
 
348
+ To see each remapping, set `SF_LOG_LEVEL=debug` before running the command:
349
+
350
+ ```bash
351
+ SF_LOG_LEVEL=debug sf acc-transformer transform -j "coverage/coverage/coverage.json" -r "coverage.xml" -f "sonar"
352
+ ```
353
+
354
+ Each remapped line emits a log entry like:
355
+
356
+ ```
357
+ Remapping out-of-range covered line 512 to line 47 in force-app/main/default/classes/AccountHandler.cls (file has 98 lines)
358
+ ```
359
+
360
+ Logs are written to `~/.sf/sf-YYYY-MM-DD.log` by default. To print them to the terminal as well, set `DEBUG=sf:setCoveredLines`.
361
+
353
362
  ## License
354
363
 
355
364
  [MIT](https://raw.githubusercontent.com/mcarvin8/apex-code-coverage-transformer/main/LICENSE.md)
@@ -1,7 +1,9 @@
1
1
  'use strict';
2
2
  import { join } from 'node:path';
3
+ import { Logger } from '@salesforce/core';
3
4
  import { getTotalLines } from './getTotalLines.js';
4
5
  export async function setCoveredLines(filePath, repoRoot, lines, returnSourceContent = false) {
6
+ const logger = await Logger.child('setCoveredLines');
5
7
  const result = await getTotalLines(join(repoRoot, filePath), returnSourceContent);
6
8
  const totalLines = typeof result === 'number' ? result : result.totalLines;
7
9
  const updatedLines = {};
@@ -12,6 +14,7 @@ export async function setCoveredLines(filePath, repoRoot, lines, returnSourceCon
12
14
  if (status === 1 && lineNumber > totalLines) {
13
15
  for (let randomLine = 1; randomLine <= totalLines; randomLine++) {
14
16
  if (!usedLines.has(randomLine)) {
17
+ logger.debug(`Remapping out-of-range covered line ${lineNumber} to line ${randomLine} in ${filePath} (file has ${totalLines} lines)`);
15
18
  updatedLines[randomLine.toString()] = status;
16
19
  usedLines.add(randomLine);
17
20
  break;
@@ -1 +1 @@
1
- {"version":3,"file":"setCoveredLines.js","sourceRoot":"","sources":["../../src/utils/setCoveredLines.ts"],"names":[],"mappings":"AAAA,YAAY,CAAC;AAEb,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAMnD,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,QAAgB,EAChB,QAAgB,EAChB,KAA6B,EAC7B,mBAAmB,GAAG,KAAK;IAE3B,MAAM,MAAM,GAAG,MAAM,aAAa,CAAC,IAAI,CAAC,QAAQ,EAAE,QAAQ,CAAC,EAAE,mBAAmB,CAAC,CAAC;IAClF,MAAM,UAAU,GAAG,OAAO,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC;IAC3E,MAAM,YAAY,GAA2B,EAAE,CAAC;IAChD,MAAM,SAAS,GAAG,IAAI,GAAG,EAAU,CAAC;IAEpC,MAAM,WAAW,GAAG,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,EAAE,CAAC,QAAQ,CAAC,KAAK,EAAE,EAAE,CAAC,GAAG,QAAQ,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,CAAC;IAEhH,KAAK,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,WAAW,EAAE,CAAC;QACzC,MAAM,UAAU,GAAG,QAAQ,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;QAEtC,IAAI,MAAM,KAAK,CAAC,IAAI,UAAU,GAAG,UAAU,EAAE,CAAC;YAC5C,KAAK,IAAI,UAAU,GAAG,CAAC,EAAE,UAAU,IAAI,UAAU,EAAE,UAAU,EAAE,EAAE,CAAC;gBAChE,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,CAAC;oBAC/B,YAAY,CAAC,UAAU,CAAC,QAAQ,EAAE,CAAC,GAAG,MAAM,CAAC;oBAC7C,SAAS,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;oBAC1B,MAAM;gBACR,CAAC;YACH,CAAC;QACH,CAAC;aAAM,CAAC;YACN,YAAY,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC;YAC5B,SAAS,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;QAC5B,CAAC;IACH,CAAC;IAED,IAAI,mBAAmB,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE,CAAC;QACtD,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,CAAC,OAAO,EAAE,CAAC;IACzD,CAAC;IACD,OAAO,YAAY,CAAC;AACtB,CAAC"}
1
+ {"version":3,"file":"setCoveredLines.js","sourceRoot":"","sources":["../../src/utils/setCoveredLines.ts"],"names":[],"mappings":"AAAA,YAAY,CAAC;AAEb,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAMnD,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,QAAgB,EAChB,QAAgB,EAChB,KAA6B,EAC7B,mBAAmB,GAAG,KAAK;IAE3B,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,KAAK,CAAC,iBAAiB,CAAC,CAAC;IACrD,MAAM,MAAM,GAAG,MAAM,aAAa,CAAC,IAAI,CAAC,QAAQ,EAAE,QAAQ,CAAC,EAAE,mBAAmB,CAAC,CAAC;IAClF,MAAM,UAAU,GAAG,OAAO,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC;IAC3E,MAAM,YAAY,GAA2B,EAAE,CAAC;IAChD,MAAM,SAAS,GAAG,IAAI,GAAG,EAAU,CAAC;IAEpC,MAAM,WAAW,GAAG,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,EAAE,CAAC,QAAQ,CAAC,KAAK,EAAE,EAAE,CAAC,GAAG,QAAQ,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,CAAC;IAEhH,KAAK,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,WAAW,EAAE,CAAC;QACzC,MAAM,UAAU,GAAG,QAAQ,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;QAEtC,IAAI,MAAM,KAAK,CAAC,IAAI,UAAU,GAAG,UAAU,EAAE,CAAC;YAC5C,KAAK,IAAI,UAAU,GAAG,CAAC,EAAE,UAAU,IAAI,UAAU,EAAE,UAAU,EAAE,EAAE,CAAC;gBAChE,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,CAAC;oBAC/B,MAAM,CAAC,KAAK,CACV,uCAAuC,UAAU,YAAY,UAAU,OAAO,QAAQ,cAAc,UAAU,SAAS,CACxH,CAAC;oBACF,YAAY,CAAC,UAAU,CAAC,QAAQ,EAAE,CAAC,GAAG,MAAM,CAAC;oBAC7C,SAAS,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;oBAC1B,MAAM;gBACR,CAAC;YACH,CAAC;QACH,CAAC;aAAM,CAAC;YACN,YAAY,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC;YAC5B,SAAS,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;QAC5B,CAAC;IACH,CAAC;IAED,IAAI,mBAAmB,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE,CAAC;QACtD,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,CAAC,OAAO,EAAE,CAAC;IACzD,CAAC;IACD,OAAO,YAAY,CAAC;AACtB,CAAC"}
@@ -121,5 +121,5 @@
121
121
  ]
122
122
  }
123
123
  },
124
- "version": "2.20.0"
124
+ "version": "2.21.0"
125
125
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "apex-code-coverage-transformer",
3
3
  "description": "Transform Salesforce Apex code coverage JSONs into other formats accepted by SonarQube, GitHub, GitLab, Azure, Bitbucket, etc.",
4
- "version": "2.20.0",
4
+ "version": "2.21.0",
5
5
  "dependencies": {
6
6
  "@oclif/core": "4.8.3",
7
7
  "@salesforce/core": "8.26.3",
@@ -15,6 +15,8 @@
15
15
  "@salesforce/cli-plugins-testkit": "5.3.39",
16
16
  "@salesforce/dev-config": "4.3.3",
17
17
  "@salesforce/prettier-config": "0.0.4",
18
+ "@stryker-mutator/core": "9.6.1",
19
+ "@stryker-mutator/vitest-runner": "9.6.1",
18
20
  "@types/node": "20.19.39",
19
21
  "@vitest/coverage-v8": "4.1.5",
20
22
  "eslint-config-salesforce-typescript": "4.0.1",
@@ -98,6 +100,8 @@
98
100
  "prepack": "wireit",
99
101
  "prepare": "husky install",
100
102
  "test": "wireit",
103
+ "test:mutation": "stryker run",
104
+ "test:mutation:incremental": "node scripts/incremental-mutation.mjs",
101
105
  "test:nuts": "oclif manifest && vitest run --config ./vitest.nut.config.ts",
102
106
  "test:only": "wireit",
103
107
  "version": "oclif readme"