apex-code-coverage-transformer 2.19.2 → 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,27 @@
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
+
15
+ ## [2.20.0](https://github.com/mcarvin8/apex-code-coverage-transformer/compare/v2.19.2...v2.20.0) (2026-05-29)
16
+
17
+
18
+ ### Features
19
+
20
+ * add --min-coverage and --max-annotations flags ([#294](https://github.com/mcarvin8/apex-code-coverage-transformer/issues/294)) ([0eb4de9](https://github.com/mcarvin8/apex-code-coverage-transformer/commit/0eb4de91165471160062e673eac368fac3351a35))
21
+
22
+
23
+ ### Bug Fixes
24
+
25
+ * cap GitHub Actions annotations at 50 with overflow notice ([#293](https://github.com/mcarvin8/apex-code-coverage-transformer/issues/293)) ([ad3bdff](https://github.com/mcarvin8/apex-code-coverage-transformer/commit/ad3bdffb79c5271dfa32d24814dcb0c1005b9930))
26
+ * guard against NaN line-rate in Cobertura when no lines tracked ([#292](https://github.com/mcarvin8/apex-code-coverage-transformer/issues/292)) ([f44d69d](https://github.com/mcarvin8/apex-code-coverage-transformer/commit/f44d69d106835ce3c438fd12a5101715247a9974))
27
+ * warn and deduplicate on same-named Apex files across packages ([#290](https://github.com/mcarvin8/apex-code-coverage-transformer/issues/290)) ([be00604](https://github.com/mcarvin8/apex-code-coverage-transformer/commit/be00604859e1dfffae6e4bda2ad0b82f89ff5dfb))
28
+
8
29
  ## [2.19.2](https://github.com/mcarvin8/apex-code-coverage-transformer/compare/v2.19.1...v2.19.2) (2026-05-26)
9
30
 
10
31
 
package/README.md CHANGED
@@ -5,14 +5,12 @@
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 is designed to pair 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
 
15
- <!-- TABLE OF CONTENTS -->
16
14
  <details>
17
15
  <summary>Table of Contents</summary>
18
16
 
@@ -20,21 +18,12 @@ It also produces presentation-ready output for pull-request reviews: a Markdown
20
18
  - [Install](#install)
21
19
  - [Quick Start](#quick-start)
22
20
  - [Usage](#usage)
23
- - [Salesforce CLI](#salesforce-cli)
24
- - [SFDX Hardis](#sfdx-hardis)
25
- - [What This Plugin Fixes and Adds](#what-this-plugin-fixes-and-adds)
26
21
  - [Command Reference](#command-reference)
27
- - [sf acc-transformer transform](#sf-acc-transformer-transform)
28
22
  - [Coverage Report Formats](#coverage-report-formats)
29
23
  - [CI/CD Integration](#cicd-integration)
30
- - [Codecov](#codecov)
31
- - [SonarQube](#sonarqube)
32
- - [GitHub Actions](#github-actions)
33
- - [GitLab CI](#gitlab-ci)
34
24
  - [Automatic Transformation (Hook)](#automatic-transformation-hook)
35
25
  - [Troubleshooting](#troubleshooting)
36
- - [Contributing](#contributing)
37
- - [License](#license)
26
+
38
27
  </details>
39
28
 
40
29
  ## Prerequisites
@@ -52,21 +41,23 @@ sf plugins install apex-code-coverage-transformer@latest
52
41
 
53
42
  ## Quick Start
54
43
 
55
- 1. **Generate Apex code coverage (JSON)**
44
+ 1. **Generate Apex code coverage (JSON)**
45
+
56
46
  From tests:
57
47
 
58
48
  ```bash
59
49
  sf apex run test --code-coverage --output-dir "coverage"
60
50
  ```
61
51
 
62
- Or from deploy/validate:
52
+ From deploy/validate:
63
53
 
64
54
  ```bash
65
55
  sf project deploy start --coverage-formatters json --results-dir "coverage"
66
56
  # or: sf project deploy validate --coverage-formatters json --results-dir "coverage"
67
57
  ```
68
58
 
69
- 2. **Transform to your target format**
59
+ 2. **Transform to your target format**
60
+
70
61
  Test output → `coverage/test-result-codecoverage.json`. Deploy output → `coverage/coverage/coverage.json`.
71
62
 
72
63
  ```bash
@@ -76,16 +67,15 @@ sf plugins install apex-code-coverage-transformer@latest
76
67
  # Codecov (Cobertura)
77
68
  sf acc-transformer transform -j "coverage/test-result-codecoverage.json" -r "coverage.xml" -f "cobertura"
78
69
 
79
- # Multiple formats
70
+ # Multiple formats at once
80
71
  sf acc-transformer transform -j "coverage/test-result-codecoverage.json" -f "sonar" -f "cobertura" -f "jacoco"
81
72
  ```
82
73
 
83
- 3. **Upload to your tool**
84
- See [CI/CD Integration](#cicd-integration) for Codecov, SonarQube, GitHub Actions, and GitLab.
74
+ 3. **Upload to your tool** — see [CI/CD Integration](#cicd-integration).
85
75
 
86
76
  ## Usage
87
77
 
88
- This plugin is for Salesforce DX projects (`sfdx-project.json`). It maps Apex names in the CLI coverage JSON to file paths in your package directories and only includes files that exist in those directories. Apex from managed or unlocked packages (not in your repo) is excluded and reported with a [warning](#troubleshooting).
78
+ This plugin is for Salesforce DX projects (`sfdx-project.json`). The Salesforce CLI coverage JSON uses Apex class names (e.g. `no-map/AccountTriggerHandler`) rather than file paths — this plugin maps those names to actual paths in your package directories and only includes files that exist there. Deploy and test coverage use different JSON structures; this plugin normalizes both. Apex from managed or unlocked packages (not in your repo) is excluded and reported with a [warning](#troubleshooting).
89
79
 
90
80
  To run transformation automatically after deploy or test commands, use the [Hook](#automatic-transformation-hook).
91
81
 
@@ -93,7 +83,7 @@ To run transformation automatically after deploy or test commands, use the [Hook
93
83
 
94
84
  > **Important:** If the generated `package.xml` only contains Apex test classes, the Salesforce CLI deploy coverage report will be empty. The deploy manifest must include actual Apex classes or triggers under test for the CLI to return coverage data in the JSON output.
95
85
 
96
- ### Salesforce CLI
86
+ ### Generating coverage
97
87
 
98
88
  **Deploy/validate** — coverage path: `coverage/coverage/coverage.json`
99
89
 
@@ -108,31 +98,21 @@ sf apex run test --code-coverage --output-dir "coverage"
108
98
  sf apex get test --test-run-id <id> --code-coverage --output-dir "coverage"
109
99
  ```
110
100
 
111
- ### SFDX Hardis
101
+ **SFDX Hardis** — coverage path: `hardis-report/apex-coverage-results.json`
112
102
 
113
103
  Works with [sfdx-hardis](https://github.com/hardisgroupcom/sfdx-hardis):
114
104
 
115
- - `sf hardis project deploy smart` (when `COVERAGE_FORMATTER_JSON=true`)
105
+ - `sf hardis project deploy smart` (requires `COVERAGE_FORMATTER_JSON=true`)
116
106
  - `sf hardis org test apex`
117
107
 
118
- Coverage file: `hardis-report/apex-coverage-results.json`.
119
-
120
- ## What This Plugin Fixes and Adds
121
-
122
- - **File mapping** — Maps names like `no-map/AccountTriggerHandler` to paths like `force-app/main/default/classes/AccountTriggerHandler.cls`.
123
- - **Normalization** — Aligns deploy and test coverage structures so external tools can consume them.
124
- - **Extra formats** — Outputs Sonar, Cobertura, JaCoCo, LCOV, Clover, and more (see [Coverage Report Formats](#coverage-report-formats)).
125
- - **Deploy-coverage fixes** — Corrects known CLI issues (e.g. out-of-range covered lines, wrong line counts) by re-numbering covered lines in deploy reports. Uncovered lines are already correct. This workaround will be removed in a future **breaking** release once Salesforce fixes the API; see [forcedotcom/salesforcedx-vscode#5511](https://github.com/forcedotcom/salesforcedx-vscode/issues/5511) and [forcedotcom/cli#1568](https://github.com/forcedotcom/cli/issues/1568). Test-command coverage is unaffected.
126
-
127
108
  ## Command Reference
128
109
 
129
- Single command: `sf acc-transformer transform`.
130
-
131
110
  ### sf acc-transformer transform
132
111
 
133
112
  ```
134
113
  USAGE
135
- $ sf acc-transformer transform -j <value> [-r <value>] [-f <value>] [-i <value>] [--json]
114
+ $ sf acc-transformer transform -j <value> [-r <value>] [-f <value>] [-i <value>]
115
+ [--min-coverage <value>] [--max-annotations <value>] [--json]
136
116
 
137
117
  FLAGS
138
118
  -j, --coverage-json=<value> Path to the code coverage JSON from deploy or test.
@@ -140,6 +120,10 @@ FLAGS
140
120
  -f, --format=<value> Output format (repeat for multiple). Default: sonar.
141
121
  Multiple formats append to filename, e.g. coverage-sonar.xml.
142
122
  -i, --ignore-package-directory=<value> Package directory to ignore (as in sfdx-project.json). Repeatable.
123
+ --min-coverage=<value> Minimum required line coverage percentage (0–100). Exits with an error
124
+ if overall coverage is below this value. Reports are written first.
125
+ --max-annotations=<value> Maximum ::warning annotations emitted by --format github-actions.
126
+ Default: 50. Overflow is summarised in a ::notice line.
143
127
 
144
128
  GLOBAL FLAGS
145
129
  --json Output as JSON.
@@ -166,53 +150,58 @@ Use `-f` / `--format` to choose the output format. Multiple `-f` values produce
166
150
 
167
151
  ## CI/CD Integration
168
152
 
169
- ### Codecov
153
+ ### Shared setup (GitHub Actions)
170
154
 
171
- Cobertura is a good default. **CLI upload:**
155
+ All GitHub Actions examples below assume these steps run first:
172
156
 
173
- ```bash
174
- sf apex run test --code-coverage --output-dir "coverage"
175
- sf acc-transformer transform -j "coverage/test-result-codecoverage.json" -r "coverage.xml" -f "cobertura"
176
- codecovcli upload-process --file coverage.xml
157
+ ```yaml
158
+ - uses: actions/checkout@v4
159
+ - name: Install Salesforce CLI
160
+ run: npm install -g @salesforce/cli
161
+ - name: Install Coverage Transformer Plugin
162
+ run: echo y | sf plugins install apex-code-coverage-transformer
163
+ - name: Authenticate to Salesforce
164
+ run: sf org login sfdx-url --sfdx-url-file ${{ secrets.SFDX_AUTH_URL }} --alias ci-org
165
+ - name: Run Apex Tests
166
+ run: sf apex run test --code-coverage --output-dir coverage --target-org ci-org
177
167
  ```
178
168
 
179
- **GitHub Action:**
169
+ ### Codecov
180
170
 
181
171
  ```yaml
182
- name: Salesforce CI with Codecov
183
- on: [push, pull_request]
184
- jobs:
185
- test:
186
- runs-on: ubuntu-latest
187
- steps:
188
- - uses: actions/checkout@v4
189
- - name: Install Salesforce CLI
190
- run: npm install -g @salesforce/cli
191
- - name: Install Coverage Transformer Plugin
192
- run: echo y | sf plugins install apex-code-coverage-transformer
193
- - name: Authenticate to Salesforce
194
- run: sf org login sfdx-url --sfdx-url-file ${{ secrets.SFDX_AUTH_URL }} --alias ci-org
195
- - name: Run Apex Tests
196
- run: sf apex run test --code-coverage --output-dir coverage --target-org ci-org
197
- - name: Transform Coverage to Cobertura
198
- run: sf acc-transformer transform -j "coverage/test-result-codecoverage.json" -r "coverage.xml" -f "cobertura"
199
- - name: Upload to Codecov
200
- uses: codecov/codecov-action@v4
201
- with:
202
- files: ./coverage.xml
203
- flags: apex
204
- token: ${{ secrets.CODECOV_TOKEN }}
172
+ - name: Transform Coverage to Cobertura
173
+ run: sf acc-transformer transform -j "coverage/test-result-codecoverage.json" -r "coverage.xml" -f "cobertura"
174
+ - name: Upload to Codecov
175
+ uses: codecov/codecov-action@v4
176
+ with:
177
+ files: ./coverage.xml
178
+ flags: apex
179
+ token: ${{ secrets.CODECOV_TOKEN }}
205
180
  ```
206
181
 
207
- ### SonarQube
182
+ ### SonarQube / SonarCloud
208
183
 
209
- Use the **sonar** format and upload using SonarQube's generic test coverage report formatter, `sonar.coverageReportPaths`.
184
+ ```yaml
185
+ - name: Transform Coverage to Sonar Format
186
+ run: sf acc-transformer transform -j "coverage/test-result-codecoverage.json" -r "coverage.xml" -f "sonar"
187
+ - name: SonarCloud Scan
188
+ uses: SonarSource/sonarcloud-github-action@master
189
+ env:
190
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
191
+ SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
192
+ with:
193
+ args: >
194
+ -Dsonar.projectKey=your-project-key
195
+ -Dsonar.organization=your-org
196
+ -Dsonar.sources=force-app
197
+ -Dsonar.tests=force-app
198
+ -Dsonar.test.inclusions=**/*Test.cls
199
+ -Dsonar.coverageReportPaths=coverage.xml
200
+ ```
210
201
 
211
- **Scanner:**
202
+ For a self-hosted scanner:
212
203
 
213
204
  ```bash
214
- sf apex run test --code-coverage --output-dir "coverage"
215
- sf acc-transformer transform -j "coverage/test-result-codecoverage.json" -r "coverage.xml" -f "sonar"
216
205
  sonar-scanner \
217
206
  -Dsonar.projectKey=your-project-key \
218
207
  -Dsonar.sources=force-app \
@@ -223,87 +212,13 @@ sonar-scanner \
223
212
  -Dsonar.login=$SONAR_TOKEN
224
213
  ```
225
214
 
226
- **SonarCloud GitHub Action:**
227
-
228
- ```yaml
229
- name: SonarCloud Analysis
230
- on: [push, pull_request]
231
- jobs:
232
- sonarcloud:
233
- runs-on: ubuntu-latest
234
- steps:
235
- - uses: actions/checkout@v4
236
- with:
237
- fetch-depth: 0
238
- - name: Install Salesforce CLI
239
- run: npm install -g @salesforce/cli
240
- - name: Install Coverage Transformer Plugin
241
- run: echo y | sf plugins install apex-code-coverage-transformer
242
- - name: Authenticate to Salesforce
243
- run: sf org login sfdx-url --sfdx-url-file ${{ secrets.SFDX_AUTH_URL }} --alias ci-org
244
- - name: Run Apex Tests
245
- run: sf apex run test --code-coverage --output-dir coverage --target-org ci-org
246
- - name: Transform Coverage to Sonar Format
247
- run: sf acc-transformer transform -j "coverage/test-result-codecoverage.json" -r "coverage.xml" -f "sonar"
248
- - name: SonarCloud Scan
249
- uses: SonarSource/sonarcloud-github-action@master
250
- env:
251
- GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
252
- SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
253
- with:
254
- args: >
255
- -Dsonar.projectKey=your-project-key
256
- -Dsonar.organization=your-org
257
- -Dsonar.sources=force-app
258
- -Dsonar.tests=force-app
259
- -Dsonar.test.inclusions=**/*Test.cls
260
- -Dsonar.coverageReportPaths=coverage.xml
261
- ```
262
-
263
215
  ### GitHub Actions
264
216
 
265
- Use Cobertura (or LCOV) with a coverage summary action:
266
-
267
- ```yaml
268
- name: Salesforce CI with Coverage Report
269
- on: [push, pull_request]
270
- jobs:
271
- test:
272
- runs-on: ubuntu-latest
273
- steps:
274
- - uses: actions/checkout@v4
275
- - name: Install Salesforce CLI
276
- run: npm install -g @salesforce/cli
277
- - name: Install Coverage Transformer Plugin
278
- run: echo y | sf plugins install apex-code-coverage-transformer
279
- - name: Authenticate to Salesforce
280
- run: sf org login sfdx-url --sfdx-url-file ${{ secrets.SFDX_AUTH_URL }} --alias ci-org
281
- - name: Run Apex Tests
282
- run: sf apex run test --code-coverage --output-dir coverage --target-org ci-org
283
- - name: Transform Coverage to Cobertura
284
- run: sf acc-transformer transform -j "coverage/test-result-codecoverage.json" -r "coverage.xml" -f "cobertura"
285
- - name: Code Coverage Report
286
- uses: irongut/CodeCoverageSummary@v1.3.0
287
- with:
288
- filename: coverage.xml
289
- badge: true
290
- format: markdown
291
- output: both
292
- - name: Add Coverage PR Comment
293
- uses: marocchino/sticky-pull-request-comment@v2
294
- if: github.event_name == 'pull_request'
295
- with:
296
- recreate: true
297
- path: code-coverage-results.md
298
- ```
299
-
300
217
  #### Markdown PR comments (built-in)
301
218
 
302
- Skip the third-party summary action by using the built-in `markdown` format. The output is ready to drop straight into a PR comment or the GitHub Actions [job summary](https://docs.github.com/en/actions/using-workflows/workflow-commands-for-github-actions#adding-a-job-summary):
219
+ Skip third-party summary actions by using the built-in `markdown` format:
303
220
 
304
221
  ```yaml
305
- - name: Run Apex Tests
306
- run: sf apex run test --code-coverage --output-dir coverage --target-org ci-org
307
222
  - name: Transform Coverage to Markdown
308
223
  run: sf acc-transformer transform -j "coverage/test-result-codecoverage.json" -r "coverage.md" -f "markdown"
309
224
  - name: Add coverage to job summary
@@ -316,33 +231,23 @@ Skip the third-party summary action by using the built-in `markdown` format. The
316
231
  path: coverage.md
317
232
  ```
318
233
 
319
- The Markdown report includes an overall summary block, a per-package-directory table, and a file-level table sorted with the lowest coverage first so reviewers see the most actionable rows at the top.
234
+ The Markdown report includes an overall summary block, a per-package-directory table, and a file-level table sorted with lowest coverage first so reviewers see the most actionable rows at the top.
320
235
 
321
- #### GitHub Actions inline annotations
236
+ #### Inline annotations
322
237
 
323
- The `github-actions` format emits one [`::warning`](https://docs.github.com/en/actions/reference/workflow-commands-for-github-actions) workflow command per uncovered Apex line, plus a `::notice` summary. When a step prints the file to stdout, the runner renders annotations inline on the PR diff and on the workflow run page.
238
+ The `github-actions` format emits one [`::warning`](https://docs.github.com/en/actions/reference/workflow-commands-for-github-actions) per uncovered Apex line, plus a `::notice` summary. When a step prints the file to stdout, the runner renders annotations inline on the PR diff and on the workflow run page.
324
239
 
325
240
  ```yaml
326
- - name: Run Apex Tests
327
- run: sf apex run test --code-coverage --output-dir coverage --target-org ci-org
328
241
  - name: Transform Coverage to GitHub Actions Annotations
329
242
  run: sf acc-transformer transform -j "coverage/test-result-codecoverage.json" -r "coverage.txt" -f "github-actions"
330
243
  - name: Emit coverage annotations
331
244
  run: cat coverage.txt
332
245
  ```
333
246
 
334
- This pairs with the [`sf-cat`](https://www.npmjs.com/package/sf-cat) plugin's GitHub Actions output for code quality findings, so a single PR shows coverage gaps and quality issues as inline annotations on the same diff.
335
-
336
- You can produce both at once with multiple `-f` flags:
337
-
338
- ```bash
339
- sf acc-transformer transform -j "coverage/test-result-codecoverage.json" -f "markdown" -f "github-actions" -f "sonar"
340
- ```
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.
341
248
 
342
249
  ### GitLab CI
343
250
 
344
- Cobertura for coverage in the UI:
345
-
346
251
  ```yaml
347
252
  stages:
348
253
  - test
@@ -357,8 +262,6 @@ apex-tests:
357
262
  script:
358
263
  - sf apex run test --code-coverage --output-dir coverage --target-org ci-org
359
264
  - sf acc-transformer transform -j "coverage/test-result-codecoverage.json" -r "coverage.xml" -f "cobertura"
360
- # Parse the coverage report and output the TOTAL coverage percentage (2 decimal places)
361
- # to the job log. GitLab reads this line using the `coverage` keyword regex to track pipeline coverage.
362
265
  - |
363
266
  COVERAGE_FILE="coverage.xml"
364
267
  if [ -s "$COVERAGE_FILE" ]; then
@@ -402,12 +305,20 @@ Sample configs: [Salesforce CLI](https://raw.githubusercontent.com/mcarvin8/apex
402
305
 
403
306
  ## Troubleshooting
404
307
 
405
- **File not in package directory** — File is omitted from the report and a warning is shown:
308
+ **File not in package directory** — File is omitted from the report:
406
309
 
407
310
  ```
408
311
  Warning: The file name AccountTrigger was not found in any package directory.
409
312
  ```
410
313
 
314
+ **Duplicate Apex file across package directories** — Two packages contain a file with the same name (e.g. `AccountHelper.cls` in both `force-app` and `package2`). The first one found is used; the second is ignored:
315
+
316
+ ```
317
+ Warning: Duplicate Apex file "AccountHelper.cls" found in multiple package directories. Using "force-app/main/default/classes/AccountHelper.cls"; ignoring "package2/main/default/classes/AccountHelper.cls".
318
+ ```
319
+
320
+ Resolve by renaming one of the files or using `--ignore-package-directory` to exclude the package whose version should not be included.
321
+
411
322
  **No files matched** — Report will be empty:
412
323
 
413
324
  ```
@@ -432,9 +343,21 @@ Error (1): sfdx-project.json not found in any parent directory.
432
343
  Error (1): ENOENT: no such file or directory: {packageDir}
433
344
  ```
434
345
 
435
- ## Contributing
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).
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
+ ```
436
359
 
437
- Contributions are welcome. See [CONTRIBUTING.md](https://github.com/mcarvin8/apex-code-coverage-transformer/blob/main/CONTRIBUTING.md).
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`.
438
361
 
439
362
  ## License
440
363
 
@@ -9,6 +9,8 @@ export default class TransformerTransform extends SfCommand<TransformerTransform
9
9
  'output-report': import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
10
10
  format: import("@oclif/core/interfaces").OptionFlag<string[] | undefined, import("@oclif/core/interfaces").CustomOptions>;
11
11
  'ignore-package-directory': import("@oclif/core/interfaces").OptionFlag<string[] | undefined, import("@oclif/core/interfaces").CustomOptions>;
12
+ 'min-coverage': import("@oclif/core/interfaces").OptionFlag<number | undefined, import("@oclif/core/interfaces").CustomOptions>;
13
+ 'max-annotations': import("@oclif/core/interfaces").OptionFlag<number, import("@oclif/core/interfaces").CustomOptions>;
12
14
  };
13
15
  run(): Promise<TransformerTransformResult>;
14
16
  }
@@ -3,6 +3,7 @@ import { SfCommand, Flags } from '@salesforce/sf-plugins-core';
3
3
  import { Messages } from '@salesforce/core';
4
4
  import { transformCoverageReport } from '../../transformers/coverageTransformer.js';
5
5
  import { formatOptions } from '../../utils/constants.js';
6
+ import { DEFAULT_MAX_ANNOTATIONS } from '../../transformers/generators/generateGitHubActions.js';
6
7
  Messages.importMessagesDirectoryFromMetaUrl(import.meta.url);
7
8
  const messages = Messages.loadMessages('apex-code-coverage-transformer', 'transformer.transform');
8
9
  export default class TransformerTransform extends SfCommand {
@@ -34,20 +35,35 @@ export default class TransformerTransform extends SfCommand {
34
35
  required: false,
35
36
  multiple: true,
36
37
  }),
38
+ // eslint-disable-next-line sf-plugin/flag-min-max-default
39
+ 'min-coverage': Flags.integer({
40
+ summary: messages.getMessage('flags.min-coverage.summary'),
41
+ required: false,
42
+ min: 0,
43
+ max: 100,
44
+ }),
45
+ 'max-annotations': Flags.integer({
46
+ summary: messages.getMessage('flags.max-annotations.summary'),
47
+ required: false,
48
+ min: 1,
49
+ default: DEFAULT_MAX_ANNOTATIONS,
50
+ }),
37
51
  };
38
52
  async run() {
39
53
  const { flags } = await this.parse(TransformerTransform);
40
54
  const warnings = [];
41
- const result = await transformCoverageReport(flags['coverage-json'], flags['output-report'], flags['format'] ?? ['sonar'], flags['ignore-package-directory'] ?? []);
55
+ const result = await transformCoverageReport(flags['coverage-json'], flags['output-report'], flags['format'] ?? ['sonar'], flags['ignore-package-directory'] ?? [], {
56
+ minCoverage: flags['min-coverage'],
57
+ maxAnnotations: flags['max-annotations'],
58
+ });
42
59
  warnings.push(...result.warnings);
43
- const finalPath = result.finalPaths;
60
+ this.log(`The coverage report has been written to: ${result.finalPaths.join(', ')}`);
44
61
  if (warnings.length > 0) {
45
62
  warnings.forEach((warning) => {
46
63
  this.warn(warning);
47
64
  });
48
65
  }
49
- this.log(`The coverage report has been written to: ${finalPath.join(', ')}`);
50
- return { path: finalPath };
66
+ return { path: result.finalPaths };
51
67
  }
52
68
  }
53
69
  //# sourceMappingURL=transform.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"transform.js","sourceRoot":"","sources":["../../../src/commands/acc-transformer/transform.ts"],"names":[],"mappings":"AAAA,YAAY,CAAC;AAEb,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,6BAA6B,CAAC;AAC/D,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAE5C,OAAO,EAAE,uBAAuB,EAAE,MAAM,2CAA2C,CAAC;AACpF,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAEzD,QAAQ,CAAC,kCAAkC,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAC7D,MAAM,QAAQ,GAAG,QAAQ,CAAC,YAAY,CAAC,gCAAgC,EAAE,uBAAuB,CAAC,CAAC;AAElG,MAAM,CAAC,OAAO,OAAO,oBAAqB,SAAQ,SAAqC;IAC9E,MAAM,CAAmB,OAAO,GAAG,QAAQ,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC;IAClE,MAAM,CAAmB,WAAW,GAAG,QAAQ,CAAC,UAAU,CAAC,aAAa,CAAC,CAAC;IAC1E,MAAM,CAAmB,QAAQ,GAAG,QAAQ,CAAC,WAAW,CAAC,UAAU,CAAC,CAAC;IAErE,MAAM,CAAmB,KAAK,GAAG;QACtC,eAAe,EAAE,KAAK,CAAC,IAAI,CAAC;YAC1B,OAAO,EAAE,QAAQ,CAAC,UAAU,CAAC,6BAA6B,CAAC;YAC3D,IAAI,EAAE,GAAG;YACT,QAAQ,EAAE,IAAI;SACf,CAAC;QACF,eAAe,EAAE,KAAK,CAAC,IAAI,CAAC;YAC1B,OAAO,EAAE,QAAQ,CAAC,UAAU,CAAC,6BAA6B,CAAC;YAC3D,IAAI,EAAE,GAAG;YACT,QAAQ,EAAE,IAAI;YACd,OAAO,EAAE,cAAc;SACxB,CAAC;QACF,MAAM,EAAE,KAAK,CAAC,MAAM,CAAC;YACnB,OAAO,EAAE,QAAQ,CAAC,UAAU,CAAC,sBAAsB,CAAC;YACpD,IAAI,EAAE,GAAG;YACT,QAAQ,EAAE,KAAK;YACf,QAAQ,EAAE,IAAI;YACd,OAAO,EAAE,aAAa;SACvB,CAAC;QACF,0BAA0B,EAAE,KAAK,CAAC,SAAS,CAAC;YAC1C,OAAO,EAAE,QAAQ,CAAC,UAAU,CAAC,wCAAwC,CAAC;YACtE,IAAI,EAAE,GAAG;YACT,QAAQ,EAAE,KAAK;YACf,QAAQ,EAAE,IAAI;SACf,CAAC;KACH,CAAC;IAEK,KAAK,CAAC,GAAG;QACd,MAAM,EAAE,KAAK,EAAE,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,oBAAoB,CAAC,CAAC;QACzD,MAAM,QAAQ,GAAa,EAAE,CAAC;QAE9B,MAAM,MAAM,GAAG,MAAM,uBAAuB,CAC1C,KAAK,CAAC,eAAe,CAAC,EACtB,KAAK,CAAC,eAAe,CAAC,EACtB,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,EAC5B,KAAK,CAAC,0BAA0B,CAAC,IAAI,EAAE,CACxC,CAAC;QACF,QAAQ,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAC;QAClC,MAAM,SAAS,GAAG,MAAM,CAAC,UAAU,CAAC;QAEpC,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACxB,QAAQ,CAAC,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;gBAC3B,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YACrB,CAAC,CAAC,CAAC;QACL,CAAC;QAED,IAAI,CAAC,GAAG,CAAC,4CAA4C,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAC7E,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC;IAC7B,CAAC"}
1
+ {"version":3,"file":"transform.js","sourceRoot":"","sources":["../../../src/commands/acc-transformer/transform.ts"],"names":[],"mappings":"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"}
@@ -71,9 +71,12 @@ export class CoberturaCoverageHandler extends BaseHandler {
71
71
  for (const pkg of this.coverageObj.coverage.packages.package) {
72
72
  const totalLines = pkg.classes.class.reduce((sum, cls) => sum + cls['@line-rate'] * cls.lines.line.length, 0);
73
73
  const totalClasses = pkg.classes.class.reduce((sum, cls) => sum + cls.lines.line.length, 0);
74
- pkg['@line-rate'] = parseFloat((totalLines / totalClasses).toFixed(4));
74
+ pkg['@line-rate'] = totalClasses > 0 ? parseFloat((totalLines / totalClasses).toFixed(4)) : 0;
75
75
  }
76
- this.coverageObj.coverage['@line-rate'] = parseFloat((this.coverageObj.coverage['@lines-covered'] / this.coverageObj.coverage['@lines-valid']).toFixed(4));
76
+ this.coverageObj.coverage['@line-rate'] =
77
+ this.coverageObj.coverage['@lines-valid'] > 0
78
+ ? parseFloat((this.coverageObj.coverage['@lines-covered'] / this.coverageObj.coverage['@lines-valid']).toFixed(4))
79
+ : 0;
77
80
  this.coverageObj.coverage.packages.package.sort((a, b) => a['@name'].localeCompare(b['@name']));
78
81
  for (const pkg of this.coverageObj.coverage.packages.package) {
79
82
  pkg.classes.class.sort((a, b) => a['@filename'].localeCompare(b['@filename']));
@@ -1 +1 @@
1
- {"version":3,"file":"cobertura.js","sourceRoot":"","sources":["../../src/handlers/cobertura.ts"],"names":[],"mappings":"AAAA,YAAY,CAAC;AAGb,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAEvD;;;;;;;GAOG;AACH,MAAM,OAAO,wBAAyB,SAAQ,WAAW;IACtC,WAAW,CAA0B;IAC9C,UAAU,CAAgC;IAElD;QACE,KAAK,EAAE,CAAC;QACR,IAAI,CAAC,WAAW,GAAG;YACjB,QAAQ,EAAE;gBACR,cAAc,EAAE,CAAC;gBACjB,gBAAgB,EAAE,CAAC;gBACnB,YAAY,EAAE,CAAC;gBACf,iBAAiB,EAAE,CAAC;gBACpB,mBAAmB,EAAE,CAAC;gBACtB,cAAc,EAAE,CAAC;gBACjB,YAAY,EAAE,IAAI,CAAC,GAAG,EAAE;gBACxB,aAAa,EAAE,CAAC;gBAChB,UAAU,EAAE,KAAK;gBACjB,OAAO,EAAE,EAAE,MAAM,EAAE,CAAC,GAAG,CAAC,EAAE;gBAC1B,QAAQ,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE;aAC1B;SACF,CAAC;QACF,IAAI,CAAC,UAAU,GAAG,IAAI,GAAG,EAAE,CAAC;IAC9B,CAAC;IAEM,WAAW,CAAC,QAAgB,EAAE,QAAgB,EAAE,KAA6B;QAClF,MAAM,WAAW,GAAG,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,yCAAyC;QAErF,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,WAAW,CAAC,EAAE,CAAC;YACtC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,WAAW,EAAE;gBAC/B,OAAO,EAAE,WAAW;gBACpB,YAAY,EAAE,CAAC;gBACf,cAAc,EAAE,CAAC;gBACjB,OAAO,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE;aACvB,CAAC,CAAC;QACL,CAAC;QAED,MAAM,UAAU,GAAG,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,WAAW,CAAE,CAAC;QACrD,MAAM,EAAE,UAAU,EAAE,YAAY,EAAE,GAAG,IAAI,CAAC,iBAAiB,CAAC,KAAK,CAAC,CAAC;QAEnE,MAAM,QAAQ,GAAmB;YAC/B,OAAO,EAAE,QAAQ;YACjB,WAAW,EAAE,QAAQ;YACrB,YAAY,EAAE,CAAC;YACf,cAAc,EAAE,CAAC;YACjB,OAAO,EAAE,EAAE;YACX,KAAK,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE;SACpB,CAAC;QAEF,KAAK,MAAM,CAAC,UAAU,EAAE,SAAS,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;YAC5D,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC;gBACvB,SAAS,EAAE,MAAM,CAAC,UAAU,CAAC;gBAC7B,OAAO,EAAE,SAAS,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;gBAChC,SAAS,EAAE,OAAO;aACnB,CAAC,CAAC;QACL,CAAC;QAED,IAAI,UAAU,GAAG,CAAC,EAAE,CAAC;YACnB,QAAQ,CAAC,YAAY,CAAC,GAAG,UAAU,CAAC,CAAC,YAAY,GAAG,UAAU,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC;QAC9E,CAAC;QAED,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,cAAc,CAAC,IAAI,UAAU,CAAC;QACxD,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,gBAAgB,CAAC,IAAI,YAAY,CAAC;QAE5D,UAAU,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACxC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,WAAW,EAAE,UAAU,CAAC,CAAC;IAC/C,CAAC;IAEM,QAAQ;QACb,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,QAAQ,CAAC,OAAO,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,MAAM,EAAE,CAAC,CAAC;QAElF,KAAK,MAAM,GAAG,IAAI,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,QAAQ,CAAC,OAAO,EAAE,CAAC;YAC7D,MAAM,UAAU,GAAG,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,CAAC,GAAG,GAAG,GAAG,CAAC,YAAY,CAAC,GAAG,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;YAC9G,MAAM,YAAY,GAAG,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,CAAC,GAAG,GAAG,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;YAE5F,GAAG,CAAC,YAAY,CAAC,GAAG,UAAU,CAAC,CAAC,UAAU,GAAG,YAAY,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC;QACzE,CAAC;QAED,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,YAAY,CAAC,GAAG,UAAU,CAClD,CAAC,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,gBAAgB,CAAC,GAAG,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,cAAc,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CACrG,CAAC;QAEF,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;QAChG,KAAK,MAAM,GAAG,IAAI,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,QAAQ,CAAC,OAAO,EAAE,CAAC;YAC7D,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;QACjF,CAAC;QAED,OAAO,IAAI,CAAC,WAAW,CAAC;IAC1B,CAAC;CACF;AAED,6BAA6B;AAC7B,eAAe,CAAC,QAAQ,CAAC;IACvB,IAAI,EAAE,WAAW;IACjB,WAAW,EAAE,mDAAmD;IAChE,aAAa,EAAE,MAAM;IACrB,OAAO,EAAE,GAAG,EAAE,CAAC,IAAI,wBAAwB,EAAE;IAC7C,cAAc,EAAE,CAAC,SAAS,EAAE,cAAc,EAAE,SAAS,EAAE,QAAQ,EAAE,gBAAgB,CAAC;CACnF,CAAC,CAAC"}
1
+ {"version":3,"file":"cobertura.js","sourceRoot":"","sources":["../../src/handlers/cobertura.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,9 @@
1
- export declare function transformCoverageReport(jsonFilePath: string, outputReportPath: string, formats: string[], ignoreDirs: string[]): Promise<{
1
+ export type TransformOptions = {
2
+ minCoverage?: number;
3
+ maxAnnotations?: number;
4
+ };
5
+ export declare function transformCoverageReport(jsonFilePath: string, outputReportPath: string, formats: string[], ignoreDirs: string[], options?: TransformOptions): Promise<{
2
6
  finalPaths: string[];
3
7
  warnings: string[];
8
+ lineRate: number;
4
9
  }>;
@@ -10,21 +10,21 @@ import { getConcurrencyThreshold } from '../utils/getConcurrencyThreshold.js';
10
10
  import { checkCoverageDataType } from '../utils/setCoverageDataType.js';
11
11
  import { mapLimit } from '../utils/mapLimit.js';
12
12
  import { generateAndWriteReport } from './reportGenerator.js';
13
- export async function transformCoverageReport(jsonFilePath, outputReportPath, formats, ignoreDirs) {
13
+ export async function transformCoverageReport(jsonFilePath, outputReportPath, formats, ignoreDirs, options) {
14
14
  const warnings = [];
15
15
  const finalPaths = [];
16
16
  const formatAmount = formats.length;
17
- let filesProcessed = 0;
18
17
  const jsonData = await tryReadJson(jsonFilePath, warnings);
19
18
  if (!jsonData)
20
- return { finalPaths: [outputReportPath], warnings };
19
+ return { finalPaths: [outputReportPath], warnings, lineRate: 0 };
21
20
  const parsedData = JSON.parse(jsonData);
22
21
  const { repoRoot, packageDirectories } = await getPackageDirectories(ignoreDirs);
23
22
  const handlers = createHandlers(formats);
24
23
  const commandType = checkCoverageDataType(parsedData);
25
24
  const concurrencyLimit = getConcurrencyThreshold();
26
25
  // Build file path cache upfront to avoid O(n*m) directory traversals
27
- const filePathCache = await buildFilePathCache(packageDirectories, repoRoot);
26
+ const { cache: filePathCache, warnings: cacheWarnings } = await buildFilePathCache(packageDirectories, repoRoot);
27
+ warnings.push(...cacheWarnings);
28
28
  const context = {
29
29
  handlers,
30
30
  packageDirs: packageDirectories,
@@ -33,24 +33,30 @@ export async function transformCoverageReport(jsonFilePath, outputReportPath, fo
33
33
  warnings,
34
34
  filePathCache,
35
35
  };
36
+ let processResult;
36
37
  if (commandType === 'DeployCoverageData') {
37
- filesProcessed = await processDeployCoverage(parsedData, context);
38
+ processResult = await processDeployCoverage(parsedData, context);
38
39
  }
39
40
  else if (commandType === 'TestCoverageData') {
40
- filesProcessed = await processTestCoverage(parsedData, context);
41
+ processResult = await processTestCoverage(parsedData, context);
41
42
  }
42
43
  else {
43
44
  throw new Error('The provided JSON does not match a known coverage data format from the Salesforce deploy or test command.');
44
45
  }
45
- if (filesProcessed === 0) {
46
+ if (processResult.processed === 0) {
46
47
  warnings.push('None of the files listed in the coverage JSON were processed. The coverage report will be empty.');
47
48
  }
49
+ const lineRate = processResult.totalLines > 0 ? processResult.coveredLines / processResult.totalLines : 0;
50
+ const renderOptions = options?.maxAnnotations !== undefined ? { maxAnnotations: options.maxAnnotations } : undefined;
48
51
  for (const [format, handler] of handlers.entries()) {
49
52
  const coverageObj = handler.finalize();
50
- const finalPath = await generateAndWriteReport(outputReportPath, coverageObj, format, formatAmount);
53
+ const finalPath = await generateAndWriteReport(outputReportPath, coverageObj, format, formatAmount, renderOptions);
51
54
  finalPaths.push(finalPath);
52
55
  }
53
- return { finalPaths, warnings };
56
+ if (options?.minCoverage !== undefined && lineRate * 100 < options.minCoverage) {
57
+ throw new Error(`Coverage of ${(lineRate * 100).toFixed(2)}% is below the required minimum of ${options.minCoverage}%.`);
58
+ }
59
+ return { finalPaths, warnings, lineRate };
54
60
  }
55
61
  function hasSourceContent(result) {
56
62
  return typeof result === 'object' && result !== null && 'sourceContent' in result;
@@ -79,8 +85,15 @@ function createHandlers(formats) {
79
85
  }
80
86
  return handlers;
81
87
  }
88
+ function countLines(lines) {
89
+ const totalLines = Object.keys(lines).length;
90
+ const coveredLines = Object.values(lines).filter((v) => v === 1).length;
91
+ return { totalLines, coveredLines };
92
+ }
82
93
  async function processDeployCoverage(data, context) {
83
94
  let processed = 0;
95
+ let totalLines = 0;
96
+ let coveredLines = 0;
84
97
  await mapLimit(Object.keys(data), context.concurrencyLimit, async (fileName) => {
85
98
  const fileInfo = data[fileName];
86
99
  const formattedName = fileName.replace(/no-map[\\/]+/, '');
@@ -93,15 +106,20 @@ async function processDeployCoverage(data, context) {
93
106
  const updatedLines = hasSourceContent(setCoveredResult) ? setCoveredResult.updatedLines : setCoveredResult;
94
107
  const sourceContent = hasSourceContent(setCoveredResult) ? setCoveredResult.sourceContent : undefined;
95
108
  fileInfo.s = updatedLines;
109
+ const counts = countLines(updatedLines);
110
+ totalLines += counts.totalLines;
111
+ coveredLines += counts.coveredLines;
96
112
  for (const handler of context.handlers.values()) {
97
113
  handler.processFile(path, formattedName, updatedLines, sourceContent);
98
114
  }
99
115
  processed++;
100
116
  });
101
- return processed;
117
+ return { processed, totalLines, coveredLines };
102
118
  }
103
119
  async function processTestCoverage(data, context) {
104
120
  let processed = 0;
121
+ let totalLines = 0;
122
+ let coveredLines = 0;
105
123
  await mapLimit(data, context.concurrencyLimit, async (entry) => {
106
124
  const formattedName = entry.name.replace(/no-map[\\/]+/, '');
107
125
  const path = findFilePath(formattedName, context.filePathCache);
@@ -109,12 +127,15 @@ async function processTestCoverage(data, context) {
109
127
  context.warnings.push(`The file name ${formattedName} was not found in any package directory.`);
110
128
  return;
111
129
  }
130
+ const counts = countLines(entry.lines);
131
+ totalLines += counts.totalLines;
132
+ coveredLines += counts.coveredLines;
112
133
  const sourceContent = context.handlers.has('html') ? await readSourceFile(join(context.repoRoot, path)) : undefined;
113
134
  for (const handler of context.handlers.values()) {
114
135
  handler.processFile(path, formattedName, entry.lines, sourceContent);
115
136
  }
116
137
  processed++;
117
138
  });
118
- return processed;
139
+ return { processed, totalLines, coveredLines };
119
140
  }
120
141
  //# sourceMappingURL=coverageTransformer.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"coverageTransformer.js","sourceRoot":"","sources":["../../src/transformers/coverageTransformer.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"coverageTransformer.js","sourceRoot":"","sources":["../../src/transformers/coverageTransformer.ts"],"names":[],"mappings":"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"}
@@ -1,2 +1,3 @@
1
1
  import { GitHubActionsCoverageObject } from '../../utils/types.js';
2
- export declare function generateGitHubActions(coverageObj: GitHubActionsCoverageObject): string;
2
+ export declare const DEFAULT_MAX_ANNOTATIONS = 50;
3
+ export declare function generateGitHubActions(coverageObj: GitHubActionsCoverageObject, maxAnnotations?: number): string;
@@ -1,3 +1,4 @@
1
+ export const DEFAULT_MAX_ANNOTATIONS = 50;
1
2
  function formatPercent(lineRate) {
2
3
  return `${(lineRate * 100).toFixed(2)}%`;
3
4
  }
@@ -17,11 +18,17 @@ function escapeProperty(value) {
17
18
  function escapeData(value) {
18
19
  return value.replace(/%/g, '%25').replace(/\r/g, '%0D').replace(/\n/g, '%0A');
19
20
  }
20
- export function generateGitHubActions(coverageObj) {
21
+ export function generateGitHubActions(coverageObj, maxAnnotations = DEFAULT_MAX_ANNOTATIONS) {
21
22
  const { summary, uncoveredLines } = coverageObj;
22
23
  const overall = formatPercent(summary.lineRate);
23
24
  const summaryLine = `::notice title=Apex Code Coverage::Overall coverage ${escapeData(overall)} (${summary.coveredLines}/${summary.totalLines} lines, ${summary.uncoveredLines} uncovered across ${summary.fileCount} file${summary.fileCount === 1 ? '' : 's'})`;
24
- const annotations = uncoveredLines.map(({ filePath, lineNumber }) => `::warning file=${escapeProperty(filePath)},line=${lineNumber},title=Uncovered Apex line::Line ${lineNumber} is not covered by any Apex test`);
25
- return [summaryLine, ...annotations].join('\n');
25
+ const visible = uncoveredLines.slice(0, maxAnnotations);
26
+ const truncated = uncoveredLines.length - visible.length;
27
+ const annotations = visible.map(({ filePath, lineNumber }) => `::warning file=${escapeProperty(filePath)},line=${lineNumber},title=Uncovered Apex line::Line ${lineNumber} is not covered by any Apex test`);
28
+ const lines = [summaryLine, ...annotations];
29
+ if (truncated > 0) {
30
+ lines.push(`::notice title=Apex Code Coverage::${truncated} additional uncovered line${truncated === 1 ? '' : 's'} not shown. GitHub Actions limits annotations per step.`);
31
+ }
32
+ return lines.join('\n');
26
33
  }
27
34
  //# sourceMappingURL=generateGitHubActions.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"generateGitHubActions.js","sourceRoot":"","sources":["../../../src/transformers/generators/generateGitHubActions.ts"],"names":[],"mappings":"AAEA,SAAS,aAAa,CAAC,QAAgB;IACrC,OAAO,GAAG,CAAC,QAAQ,GAAG,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC;AAC3C,CAAC;AAED;;;;GAIG;AACH,SAAS,cAAc,CAAC,KAAa;IACnC,OAAO,KAAK;SACT,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC;SACpB,OAAO,CAAC,KAAK,EAAE,KAAK,CAAC;SACrB,OAAO,CAAC,KAAK,EAAE,KAAK,CAAC;SACrB,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC;SACpB,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;AAC1B,CAAC;AAED,SAAS,UAAU,CAAC,KAAa;IAC/B,OAAO,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;AAChF,CAAC;AAED,MAAM,UAAU,qBAAqB,CAAC,WAAwC;IAC5E,MAAM,EAAE,OAAO,EAAE,cAAc,EAAE,GAAG,WAAW,CAAC;IAChD,MAAM,OAAO,GAAG,aAAa,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IAEhD,MAAM,WAAW,GAAG,uDAAuD,UAAU,CACnF,OAAO,CACR,KAAK,OAAO,CAAC,YAAY,IAAI,OAAO,CAAC,UAAU,WAAW,OAAO,CAAC,cAAc,qBAC/E,OAAO,CAAC,SACV,QAAQ,OAAO,CAAC,SAAS,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC;IAE9C,MAAM,WAAW,GAAG,cAAc,CAAC,GAAG,CACpC,CAAC,EAAE,QAAQ,EAAE,UAAU,EAAE,EAAE,EAAE,CAC3B,kBAAkB,cAAc,CAAC,QAAQ,CAAC,SAAS,UAAU,oCAAoC,UAAU,kCAAkC,CAChJ,CAAC;IAEF,OAAO,CAAC,WAAW,EAAE,GAAG,WAAW,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAClD,CAAC"}
1
+ {"version":3,"file":"generateGitHubActions.js","sourceRoot":"","sources":["../../../src/transformers/generators/generateGitHubActions.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,uBAAuB,GAAG,EAAE,CAAC;AAE1C,SAAS,aAAa,CAAC,QAAgB;IACrC,OAAO,GAAG,CAAC,QAAQ,GAAG,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC;AAC3C,CAAC;AAED;;;;GAIG;AACH,SAAS,cAAc,CAAC,KAAa;IACnC,OAAO,KAAK;SACT,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC;SACpB,OAAO,CAAC,KAAK,EAAE,KAAK,CAAC;SACrB,OAAO,CAAC,KAAK,EAAE,KAAK,CAAC;SACrB,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC;SACpB,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;AAC1B,CAAC;AAED,SAAS,UAAU,CAAC,KAAa;IAC/B,OAAO,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;AAChF,CAAC;AAED,MAAM,UAAU,qBAAqB,CACnC,WAAwC,EACxC,cAAc,GAAG,uBAAuB;IAExC,MAAM,EAAE,OAAO,EAAE,cAAc,EAAE,GAAG,WAAW,CAAC;IAChD,MAAM,OAAO,GAAG,aAAa,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IAEhD,MAAM,WAAW,GAAG,uDAAuD,UAAU,CACnF,OAAO,CACR,KAAK,OAAO,CAAC,YAAY,IAAI,OAAO,CAAC,UAAU,WAAW,OAAO,CAAC,cAAc,qBAC/E,OAAO,CAAC,SACV,QAAQ,OAAO,CAAC,SAAS,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC;IAE9C,MAAM,OAAO,GAAG,cAAc,CAAC,KAAK,CAAC,CAAC,EAAE,cAAc,CAAC,CAAC;IACxD,MAAM,SAAS,GAAG,cAAc,CAAC,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAEzD,MAAM,WAAW,GAAG,OAAO,CAAC,GAAG,CAC7B,CAAC,EAAE,QAAQ,EAAE,UAAU,EAAE,EAAE,EAAE,CAC3B,kBAAkB,cAAc,CAAC,QAAQ,CAAC,SAAS,UAAU,oCAAoC,UAAU,kCAAkC,CAChJ,CAAC;IAEF,MAAM,KAAK,GAAG,CAAC,WAAW,EAAE,GAAG,WAAW,CAAC,CAAC;IAE5C,IAAI,SAAS,GAAG,CAAC,EAAE,CAAC;QAClB,KAAK,CAAC,IAAI,CACR,sCAAsC,SAAS,6BAA6B,SAAS,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,yDAAyD,CAChK,CAAC;IACJ,CAAC;IAED,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC"}
@@ -1,3 +1,6 @@
1
1
  import { AnyCoverageObject } from '../utils/types.js';
2
- export declare function generateAndWriteReport(outputPath: string, coverageObj: AnyCoverageObject, format: string, formatAmount: number): Promise<string>;
2
+ export type ReportRenderOptions = {
3
+ maxAnnotations?: number;
4
+ };
5
+ export declare function generateAndWriteReport(outputPath: string, coverageObj: AnyCoverageObject, format: string, formatAmount: number, options?: ReportRenderOptions): Promise<string>;
3
6
  export declare function getExtensionForFormat(format: string): string;
@@ -22,13 +22,13 @@ const STRING_FORMAT_RENDERERS = {
22
22
  lcovonly: (obj) => generateLcov(obj),
23
23
  html: (obj) => generateHtml(obj),
24
24
  markdown: (obj) => generateMarkdown(obj),
25
- 'github-actions': (obj) => generateGitHubActions(obj),
25
+ 'github-actions': (obj, opts) => generateGitHubActions(obj, opts?.maxAnnotations),
26
26
  json: (obj) => JSON.stringify(obj, null, 2),
27
27
  'json-summary': (obj) => JSON.stringify(obj, null, 2),
28
28
  simplecov: (obj) => JSON.stringify(obj, null, 2),
29
29
  };
30
- export async function generateAndWriteReport(outputPath, coverageObj, format, formatAmount) {
31
- const content = generateReportContent(coverageObj, format);
30
+ export async function generateAndWriteReport(outputPath, coverageObj, format, formatAmount, options) {
31
+ const content = generateReportContent(coverageObj, format, options);
32
32
  const extension = HandlerRegistry.getExtension(format);
33
33
  const base = basename(outputPath, extname(outputPath)); // e.g., 'coverage'
34
34
  const dir = dirname(outputPath);
@@ -37,9 +37,9 @@ export async function generateAndWriteReport(outputPath, coverageObj, format, fo
37
37
  await writeFile(filePath, content, 'utf-8');
38
38
  return filePath;
39
39
  }
40
- function generateReportContent(coverageObj, format) {
40
+ function generateReportContent(coverageObj, format, options) {
41
41
  const renderer = STRING_FORMAT_RENDERERS[format];
42
- return renderer ? renderer(coverageObj) : generateXmlContent(coverageObj, format);
42
+ return renderer ? renderer(coverageObj, options) : generateXmlContent(coverageObj, format);
43
43
  }
44
44
  function generateXmlContent(coverageObj, format) {
45
45
  const isHeadless = isXmlReportFormat(format);
@@ -1 +1 @@
1
- {"version":3,"file":"reportGenerator.js","sourceRoot":"","sources":["../../src/transformers/reportGenerator.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"reportGenerator.js","sourceRoot":"","sources":["../../src/transformers/reportGenerator.ts"],"names":[],"mappings":"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"}
@@ -1,9 +1,5 @@
1
- /**
2
- * Build a cache mapping filenames to their full paths.
3
- * This prevents recursive directory searches for every file in the coverage report.
4
- *
5
- * @param packageDirectories - Array of package directory paths to scan
6
- * @param repoRoot - Repository root path
7
- * @returns Map of filename (without path) to full relative path
8
- */
9
- export declare function buildFilePathCache(packageDirectories: string[], repoRoot: string): Promise<Map<string, string>>;
1
+ export type FilePathCacheResult = {
2
+ cache: Map<string, string>;
3
+ warnings: string[];
4
+ };
5
+ export declare function buildFilePathCache(packageDirectories: string[], repoRoot: string): Promise<FilePathCacheResult>;
@@ -2,23 +2,17 @@
2
2
  import { readdir, stat } from 'node:fs/promises';
3
3
  import { join, relative } from 'node:path';
4
4
  import { normalizePathToUnix } from './normalizePathToUnix.js';
5
- /**
6
- * Build a cache mapping filenames to their full paths.
7
- * This prevents recursive directory searches for every file in the coverage report.
8
- *
9
- * @param packageDirectories - Array of package directory paths to scan
10
- * @param repoRoot - Repository root path
11
- * @returns Map of filename (without path) to full relative path
12
- */
13
5
  export async function buildFilePathCache(packageDirectories, repoRoot) {
14
- const cache = new Map();
15
- const extensions = ['cls', 'trigger'];
16
- await Promise.all(packageDirectories.map(async (directory) => {
17
- await scanDirectory(directory, repoRoot, extensions, cache);
18
- }));
19
- return cache;
6
+ const ctx = {
7
+ repoRoot,
8
+ extensions: ['cls', 'trigger'],
9
+ cache: new Map(),
10
+ warnings: [],
11
+ };
12
+ await Promise.all(packageDirectories.map(async (directory) => scanDirectory(directory, ctx)));
13
+ return { cache: ctx.cache, warnings: ctx.warnings };
20
14
  }
21
- async function scanDirectory(directory, repoRoot, extensions, cache) {
15
+ async function scanDirectory(directory, ctx) {
22
16
  let entries;
23
17
  try {
24
18
  entries = await readdir(directory);
@@ -40,25 +34,27 @@ async function scanDirectory(directory, repoRoot, extensions, cache) {
40
34
  continue;
41
35
  }
42
36
  if (stats.isDirectory()) {
43
- // Queue subdirectory scanning
44
- subdirPromises.push(scanDirectory(fullPath, repoRoot, extensions, cache));
37
+ subdirPromises.push(scanDirectory(fullPath, ctx));
45
38
  }
46
39
  else {
47
- // Check if this is an Apex file
48
- const ext = entry.split('.').pop();
49
- if (ext && extensions.includes(ext)) {
50
- const relativePath = normalizePathToUnix(relative(repoRoot, fullPath));
51
- // Store with the full filename as key (e.g., "AccountHandler.cls")
52
- cache.set(entry, relativePath);
53
- // Also store without extension for lookups (e.g., "AccountHandler")
54
- const nameWithoutExt = entry.substring(0, entry.lastIndexOf('.'));
55
- if (!cache.has(nameWithoutExt)) {
56
- cache.set(nameWithoutExt, relativePath);
57
- }
58
- }
40
+ processApexFile(entry, fullPath, ctx);
59
41
  }
60
42
  }
61
- // Process all subdirectories in parallel
62
43
  await Promise.all(subdirPromises);
63
44
  }
45
+ function processApexFile(entry, fullPath, ctx) {
46
+ const ext = entry.split('.').pop();
47
+ if (!ext || !ctx.extensions.includes(ext))
48
+ return;
49
+ const relativePath = normalizePathToUnix(relative(ctx.repoRoot, fullPath));
50
+ const nameWithoutExt = entry.substring(0, entry.lastIndexOf('.'));
51
+ if (ctx.cache.has(entry)) {
52
+ ctx.warnings.push(`Duplicate Apex file "${entry}" found in multiple package directories. Using "${ctx.cache.get(entry)}"; ignoring "${relativePath}".`);
53
+ return;
54
+ }
55
+ ctx.cache.set(entry, relativePath);
56
+ if (!ctx.cache.has(nameWithoutExt)) {
57
+ ctx.cache.set(nameWithoutExt, relativePath);
58
+ }
59
+ }
64
60
  //# sourceMappingURL=buildFilePathCache.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"buildFilePathCache.js","sourceRoot":"","sources":["../../src/utils/buildFilePathCache.ts"],"names":[],"mappings":"AAAA,YAAY,CAAC;AAEb,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AACjD,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAC3C,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAE/D;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAAC,kBAA4B,EAAE,QAAgB;IACrF,MAAM,KAAK,GAAG,IAAI,GAAG,EAAkB,CAAC;IACxC,MAAM,UAAU,GAAG,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC;IAEtC,MAAM,OAAO,CAAC,GAAG,CACf,kBAAkB,CAAC,GAAG,CAAC,KAAK,EAAE,SAAS,EAAE,EAAE;QACzC,MAAM,aAAa,CAAC,SAAS,EAAE,QAAQ,EAAE,UAAU,EAAE,KAAK,CAAC,CAAC;IAC9D,CAAC,CAAC,CACH,CAAC;IAEF,OAAO,KAAK,CAAC;AACf,CAAC;AAED,KAAK,UAAU,aAAa,CAC1B,SAAiB,EACjB,QAAgB,EAChB,UAAoB,EACpB,KAA0B;IAE1B,IAAI,OAAiB,CAAC;IAEtB,IAAI,CAAC;QACH,OAAO,GAAG,MAAM,OAAO,CAAC,SAAS,CAAC,CAAC;IACrC,CAAC;IAAC,MAAM,CAAC;QACP,qDAAqD;QACrD,OAAO;IACT,CAAC;IAED,MAAM,cAAc,GAAyB,EAAE,CAAC;IAEhD,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;QAC5B,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC;QACxC,IAAI,KAAK,CAAC;QAEV,IAAI,CAAC;YACH,4CAA4C;YAC5C,KAAK,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,CAAC;QAC/B,CAAC;QAAC,MAAM,CAAC;YACP,+BAA+B;YAC/B,SAAS;QACX,CAAC;QAED,IAAI,KAAK,CAAC,WAAW,EAAE,EAAE,CAAC;YACxB,8BAA8B;YAC9B,cAAc,CAAC,IAAI,CAAC,aAAa,CAAC,QAAQ,EAAE,QAAQ,EAAE,UAAU,EAAE,KAAK,CAAC,CAAC,CAAC;QAC5E,CAAC;aAAM,CAAC;YACN,gCAAgC;YAChC,MAAM,GAAG,GAAG,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,CAAC;YACnC,IAAI,GAAG,IAAI,UAAU,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;gBACpC,MAAM,YAAY,GAAG,mBAAmB,CAAC,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC,CAAC;gBACvE,mEAAmE;gBACnE,KAAK,CAAC,GAAG,CAAC,KAAK,EAAE,YAAY,CAAC,CAAC;gBAC/B,oEAAoE;gBACpE,MAAM,cAAc,GAAG,KAAK,CAAC,SAAS,CAAC,CAAC,EAAE,KAAK,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC;gBAClE,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,cAAc,CAAC,EAAE,CAAC;oBAC/B,KAAK,CAAC,GAAG,CAAC,cAAc,EAAE,YAAY,CAAC,CAAC;gBAC1C,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC;IAED,yCAAyC;IACzC,MAAM,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;AACpC,CAAC"}
1
+ {"version":3,"file":"buildFilePathCache.js","sourceRoot":"","sources":["../../src/utils/buildFilePathCache.ts"],"names":[],"mappings":"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"}
@@ -1,8 +1 @@
1
- /**
2
- * Find file path using a pre-built cache (fast) or fallback to the old method.
3
- *
4
- * @param fileName - Name of the file to find
5
- * @param filePathCache - Optional pre-built cache of filename -> path mappings
6
- * @returns Normalized Unix-style relative path or undefined if not found
7
- */
8
- export declare function findFilePath(fileName: string, filePathCache?: Map<string, string>): string | undefined;
1
+ export declare function findFilePath(fileName: string, filePathCache: Map<string, string>): string | undefined;
@@ -1,35 +1,14 @@
1
1
  'use strict';
2
- /**
3
- * Find file path using a pre-built cache (fast) or fallback to the old method.
4
- *
5
- * @param fileName - Name of the file to find
6
- * @param filePathCache - Optional pre-built cache of filename -> path mappings
7
- * @returns Normalized Unix-style relative path or undefined if not found
8
- */
9
2
  export function findFilePath(fileName, filePathCache) {
10
- if (filePathCache) {
11
- return findFilePathFromCache(fileName, filePathCache);
12
- }
13
- // Fallback to old behavior should never happen in practice,
14
- // but keeping for backwards compatibility
15
- return undefined;
16
- }
17
- function findFilePathFromCache(fileName, cache) {
18
- // Try exact match first
19
- const exactMatch = cache.get(fileName);
20
- if (exactMatch) {
3
+ const exactMatch = filePathCache.get(fileName);
4
+ if (exactMatch)
21
5
  return exactMatch;
22
- }
23
- // Try with .cls extension
24
- const clsMatch = cache.get(`${fileName}.cls`);
25
- if (clsMatch) {
6
+ const clsMatch = filePathCache.get(`${fileName}.cls`);
7
+ if (clsMatch)
26
8
  return clsMatch;
27
- }
28
- // Try with .trigger extension
29
- const triggerMatch = cache.get(`${fileName}.trigger`);
30
- if (triggerMatch) {
9
+ const triggerMatch = filePathCache.get(`${fileName}.trigger`);
10
+ if (triggerMatch)
31
11
  return triggerMatch;
32
- }
33
12
  return undefined;
34
13
  }
35
14
  //# sourceMappingURL=findFilePath.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"findFilePath.js","sourceRoot":"","sources":["../../src/utils/findFilePath.ts"],"names":[],"mappings":"AAAA,YAAY,CAAC;AAEb;;;;;;GAMG;AACH,MAAM,UAAU,YAAY,CAAC,QAAgB,EAAE,aAAmC;IAChF,IAAI,aAAa,EAAE,CAAC;QAClB,OAAO,qBAAqB,CAAC,QAAQ,EAAE,aAAa,CAAC,CAAC;IACxD,CAAC;IAED,4DAA4D;IAC5D,0CAA0C;IAC1C,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,SAAS,qBAAqB,CAAC,QAAgB,EAAE,KAA0B;IACzE,wBAAwB;IACxB,MAAM,UAAU,GAAG,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IACvC,IAAI,UAAU,EAAE,CAAC;QACf,OAAO,UAAU,CAAC;IACpB,CAAC;IAED,0BAA0B;IAC1B,MAAM,QAAQ,GAAG,KAAK,CAAC,GAAG,CAAC,GAAG,QAAQ,MAAM,CAAC,CAAC;IAC9C,IAAI,QAAQ,EAAE,CAAC;QACb,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED,8BAA8B;IAC9B,MAAM,YAAY,GAAG,KAAK,CAAC,GAAG,CAAC,GAAG,QAAQ,UAAU,CAAC,CAAC;IACtD,IAAI,YAAY,EAAE,CAAC;QACjB,OAAO,YAAY,CAAC;IACtB,CAAC;IAED,OAAO,SAAS,CAAC;AACnB,CAAC"}
1
+ {"version":3,"file":"findFilePath.js","sourceRoot":"","sources":["../../src/utils/findFilePath.ts"],"names":[],"mappings":"AAAA,YAAY,CAAC;AAEb,MAAM,UAAU,YAAY,CAAC,QAAgB,EAAE,aAAkC;IAC/E,MAAM,UAAU,GAAG,aAAa,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IAC/C,IAAI,UAAU;QAAE,OAAO,UAAU,CAAC;IAElC,MAAM,QAAQ,GAAG,aAAa,CAAC,GAAG,CAAC,GAAG,QAAQ,MAAM,CAAC,CAAC;IACtD,IAAI,QAAQ;QAAE,OAAO,QAAQ,CAAC;IAE9B,MAAM,YAAY,GAAG,aAAa,CAAC,GAAG,CAAC,GAAG,QAAQ,UAAU,CAAC,CAAC;IAC9D,IAAI,YAAY;QAAE,OAAO,YAAY,CAAC;IAEtC,OAAO,SAAS,CAAC;AACnB,CAAC"}
@@ -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"}
@@ -31,3 +31,11 @@ Output format for the coverage report.
31
31
  # flags.ignore-package-directory.summary
32
32
 
33
33
  Ignore a package directory when looking for matching files in the coverage report.
34
+
35
+ # flags.min-coverage.summary
36
+
37
+ Minimum required line coverage percentage (0–100). The command exits with an error if overall coverage is below this threshold. Reports are still written before the check.
38
+
39
+ # flags.max-annotations.summary
40
+
41
+ Maximum number of GitHub Actions ::warning annotations to emit when using --format github-actions. Defaults to 50. Annotations beyond this limit are summarised in a ::notice line.
@@ -79,6 +79,23 @@
79
79
  "hasDynamicHelp": false,
80
80
  "multiple": true,
81
81
  "type": "option"
82
+ },
83
+ "min-coverage": {
84
+ "name": "min-coverage",
85
+ "required": false,
86
+ "summary": "Minimum required line coverage percentage (0–100). The command exits with an error if overall coverage is below this threshold. Reports are still written before the check.",
87
+ "hasDynamicHelp": false,
88
+ "multiple": false,
89
+ "type": "option"
90
+ },
91
+ "max-annotations": {
92
+ "name": "max-annotations",
93
+ "required": false,
94
+ "summary": "Maximum number of GitHub Actions ::warning annotations to emit when using --format github-actions. Defaults to 50. Annotations beyond this limit are summarised in a ::notice line.",
95
+ "default": 50,
96
+ "hasDynamicHelp": false,
97
+ "multiple": false,
98
+ "type": "option"
82
99
  }
83
100
  },
84
101
  "hasDynamicHelp": false,
@@ -104,5 +121,5 @@
104
121
  ]
105
122
  }
106
123
  },
107
- "version": "2.19.2"
124
+ "version": "2.21.0"
108
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.19.2",
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"