apex-code-coverage-transformer 2.19.2 → 2.20.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,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
+ ## [2.20.0](https://github.com/mcarvin8/apex-code-coverage-transformer/compare/v2.19.2...v2.20.0) (2026-05-29)
9
+
10
+
11
+ ### Features
12
+
13
+ * 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))
14
+
15
+
16
+ ### Bug Fixes
17
+
18
+ * 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))
19
+ * 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))
20
+ * 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))
21
+
8
22
  ## [2.19.2](https://github.com/mcarvin8/apex-code-coverage-transformer/compare/v2.19.1...v2.19.2) (2026-05-26)
9
23
 
10
24
 
package/README.md CHANGED
@@ -8,11 +8,10 @@
8
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
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.
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.
12
12
 
13
13
  > 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
14
 
15
- <!-- TABLE OF CONTENTS -->
16
15
  <details>
17
16
  <summary>Table of Contents</summary>
18
17
 
@@ -20,21 +19,12 @@ It also produces presentation-ready output for pull-request reviews: a Markdown
20
19
  - [Install](#install)
21
20
  - [Quick Start](#quick-start)
22
21
  - [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
22
  - [Command Reference](#command-reference)
27
- - [sf acc-transformer transform](#sf-acc-transformer-transform)
28
23
  - [Coverage Report Formats](#coverage-report-formats)
29
24
  - [CI/CD Integration](#cicd-integration)
30
- - [Codecov](#codecov)
31
- - [SonarQube](#sonarqube)
32
- - [GitHub Actions](#github-actions)
33
- - [GitLab CI](#gitlab-ci)
34
25
  - [Automatic Transformation (Hook)](#automatic-transformation-hook)
35
26
  - [Troubleshooting](#troubleshooting)
36
- - [Contributing](#contributing)
37
- - [License](#license)
27
+
38
28
  </details>
39
29
 
40
30
  ## Prerequisites
@@ -52,21 +42,23 @@ sf plugins install apex-code-coverage-transformer@latest
52
42
 
53
43
  ## Quick Start
54
44
 
55
- 1. **Generate Apex code coverage (JSON)**
45
+ 1. **Generate Apex code coverage (JSON)**
46
+
56
47
  From tests:
57
48
 
58
49
  ```bash
59
50
  sf apex run test --code-coverage --output-dir "coverage"
60
51
  ```
61
52
 
62
- Or from deploy/validate:
53
+ From deploy/validate:
63
54
 
64
55
  ```bash
65
56
  sf project deploy start --coverage-formatters json --results-dir "coverage"
66
57
  # or: sf project deploy validate --coverage-formatters json --results-dir "coverage"
67
58
  ```
68
59
 
69
- 2. **Transform to your target format**
60
+ 2. **Transform to your target format**
61
+
70
62
  Test output → `coverage/test-result-codecoverage.json`. Deploy output → `coverage/coverage/coverage.json`.
71
63
 
72
64
  ```bash
@@ -76,16 +68,15 @@ sf plugins install apex-code-coverage-transformer@latest
76
68
  # Codecov (Cobertura)
77
69
  sf acc-transformer transform -j "coverage/test-result-codecoverage.json" -r "coverage.xml" -f "cobertura"
78
70
 
79
- # Multiple formats
71
+ # Multiple formats at once
80
72
  sf acc-transformer transform -j "coverage/test-result-codecoverage.json" -f "sonar" -f "cobertura" -f "jacoco"
81
73
  ```
82
74
 
83
- 3. **Upload to your tool**
84
- See [CI/CD Integration](#cicd-integration) for Codecov, SonarQube, GitHub Actions, and GitLab.
75
+ 3. **Upload to your tool** — see [CI/CD Integration](#cicd-integration).
85
76
 
86
77
  ## Usage
87
78
 
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).
79
+ 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
80
 
90
81
  To run transformation automatically after deploy or test commands, use the [Hook](#automatic-transformation-hook).
91
82
 
@@ -93,7 +84,7 @@ To run transformation automatically after deploy or test commands, use the [Hook
93
84
 
94
85
  > **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
86
 
96
- ### Salesforce CLI
87
+ ### Generating coverage
97
88
 
98
89
  **Deploy/validate** — coverage path: `coverage/coverage/coverage.json`
99
90
 
@@ -108,31 +99,21 @@ sf apex run test --code-coverage --output-dir "coverage"
108
99
  sf apex get test --test-run-id <id> --code-coverage --output-dir "coverage"
109
100
  ```
110
101
 
111
- ### SFDX Hardis
102
+ **SFDX Hardis** — coverage path: `hardis-report/apex-coverage-results.json`
112
103
 
113
104
  Works with [sfdx-hardis](https://github.com/hardisgroupcom/sfdx-hardis):
114
105
 
115
- - `sf hardis project deploy smart` (when `COVERAGE_FORMATTER_JSON=true`)
106
+ - `sf hardis project deploy smart` (requires `COVERAGE_FORMATTER_JSON=true`)
116
107
  - `sf hardis org test apex`
117
108
 
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
109
  ## Command Reference
128
110
 
129
- Single command: `sf acc-transformer transform`.
130
-
131
111
  ### sf acc-transformer transform
132
112
 
133
113
  ```
134
114
  USAGE
135
- $ sf acc-transformer transform -j <value> [-r <value>] [-f <value>] [-i <value>] [--json]
115
+ $ sf acc-transformer transform -j <value> [-r <value>] [-f <value>] [-i <value>]
116
+ [--min-coverage <value>] [--max-annotations <value>] [--json]
136
117
 
137
118
  FLAGS
138
119
  -j, --coverage-json=<value> Path to the code coverage JSON from deploy or test.
@@ -140,6 +121,10 @@ FLAGS
140
121
  -f, --format=<value> Output format (repeat for multiple). Default: sonar.
141
122
  Multiple formats append to filename, e.g. coverage-sonar.xml.
142
123
  -i, --ignore-package-directory=<value> Package directory to ignore (as in sfdx-project.json). Repeatable.
124
+ --min-coverage=<value> Minimum required line coverage percentage (0–100). Exits with an error
125
+ if overall coverage is below this value. Reports are written first.
126
+ --max-annotations=<value> Maximum ::warning annotations emitted by --format github-actions.
127
+ Default: 50. Overflow is summarised in a ::notice line.
143
128
 
144
129
  GLOBAL FLAGS
145
130
  --json Output as JSON.
@@ -166,53 +151,58 @@ Use `-f` / `--format` to choose the output format. Multiple `-f` values produce
166
151
 
167
152
  ## CI/CD Integration
168
153
 
169
- ### Codecov
154
+ ### Shared setup (GitHub Actions)
170
155
 
171
- Cobertura is a good default. **CLI upload:**
156
+ All GitHub Actions examples below assume these steps run first:
172
157
 
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
158
+ ```yaml
159
+ - uses: actions/checkout@v4
160
+ - name: Install Salesforce CLI
161
+ run: npm install -g @salesforce/cli
162
+ - name: Install Coverage Transformer Plugin
163
+ run: echo y | sf plugins install apex-code-coverage-transformer
164
+ - name: Authenticate to Salesforce
165
+ run: sf org login sfdx-url --sfdx-url-file ${{ secrets.SFDX_AUTH_URL }} --alias ci-org
166
+ - name: Run Apex Tests
167
+ run: sf apex run test --code-coverage --output-dir coverage --target-org ci-org
177
168
  ```
178
169
 
179
- **GitHub Action:**
170
+ ### Codecov
180
171
 
181
172
  ```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 }}
173
+ - name: Transform Coverage to Cobertura
174
+ run: sf acc-transformer transform -j "coverage/test-result-codecoverage.json" -r "coverage.xml" -f "cobertura"
175
+ - name: Upload to Codecov
176
+ uses: codecov/codecov-action@v4
177
+ with:
178
+ files: ./coverage.xml
179
+ flags: apex
180
+ token: ${{ secrets.CODECOV_TOKEN }}
205
181
  ```
206
182
 
207
- ### SonarQube
183
+ ### SonarQube / SonarCloud
208
184
 
209
- Use the **sonar** format and upload using SonarQube's generic test coverage report formatter, `sonar.coverageReportPaths`.
185
+ ```yaml
186
+ - name: Transform Coverage to Sonar Format
187
+ run: sf acc-transformer transform -j "coverage/test-result-codecoverage.json" -r "coverage.xml" -f "sonar"
188
+ - name: SonarCloud Scan
189
+ uses: SonarSource/sonarcloud-github-action@master
190
+ env:
191
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
192
+ SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
193
+ with:
194
+ args: >
195
+ -Dsonar.projectKey=your-project-key
196
+ -Dsonar.organization=your-org
197
+ -Dsonar.sources=force-app
198
+ -Dsonar.tests=force-app
199
+ -Dsonar.test.inclusions=**/*Test.cls
200
+ -Dsonar.coverageReportPaths=coverage.xml
201
+ ```
210
202
 
211
- **Scanner:**
203
+ For a self-hosted scanner:
212
204
 
213
205
  ```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
206
  sonar-scanner \
217
207
  -Dsonar.projectKey=your-project-key \
218
208
  -Dsonar.sources=force-app \
@@ -223,87 +213,13 @@ sonar-scanner \
223
213
  -Dsonar.login=$SONAR_TOKEN
224
214
  ```
225
215
 
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
216
  ### GitHub Actions
264
217
 
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
218
  #### Markdown PR comments (built-in)
301
219
 
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):
220
+ Skip third-party summary actions by using the built-in `markdown` format:
303
221
 
304
222
  ```yaml
305
- - name: Run Apex Tests
306
- run: sf apex run test --code-coverage --output-dir coverage --target-org ci-org
307
223
  - name: Transform Coverage to Markdown
308
224
  run: sf acc-transformer transform -j "coverage/test-result-codecoverage.json" -r "coverage.md" -f "markdown"
309
225
  - name: Add coverage to job summary
@@ -316,24 +232,20 @@ Skip the third-party summary action by using the built-in `markdown` format. The
316
232
  path: coverage.md
317
233
  ```
318
234
 
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.
235
+ 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
236
 
321
- #### GitHub Actions inline annotations
237
+ #### Inline annotations
322
238
 
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.
239
+ 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
240
 
325
241
  ```yaml
326
- - name: Run Apex Tests
327
- run: sf apex run test --code-coverage --output-dir coverage --target-org ci-org
328
242
  - name: Transform Coverage to GitHub Actions Annotations
329
243
  run: sf acc-transformer transform -j "coverage/test-result-codecoverage.json" -r "coverage.txt" -f "github-actions"
330
244
  - name: Emit coverage annotations
331
245
  run: cat coverage.txt
332
246
  ```
333
247
 
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:
248
+ Pairs with [`sf-cat`](https://www.npmjs.com/package/sf-cat) for code quality annotations on the same diff. Produce both at once:
337
249
 
338
250
  ```bash
339
251
  sf acc-transformer transform -j "coverage/test-result-codecoverage.json" -f "markdown" -f "github-actions" -f "sonar"
@@ -341,8 +253,6 @@ sf acc-transformer transform -j "coverage/test-result-codecoverage.json" -f "mar
341
253
 
342
254
  ### GitLab CI
343
255
 
344
- Cobertura for coverage in the UI:
345
-
346
256
  ```yaml
347
257
  stages:
348
258
  - test
@@ -357,8 +267,6 @@ apex-tests:
357
267
  script:
358
268
  - sf apex run test --code-coverage --output-dir coverage --target-org ci-org
359
269
  - 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
270
  - |
363
271
  COVERAGE_FILE="coverage.xml"
364
272
  if [ -s "$COVERAGE_FILE" ]; then
@@ -402,12 +310,20 @@ Sample configs: [Salesforce CLI](https://raw.githubusercontent.com/mcarvin8/apex
402
310
 
403
311
  ## Troubleshooting
404
312
 
405
- **File not in package directory** — File is omitted from the report and a warning is shown:
313
+ **File not in package directory** — File is omitted from the report:
406
314
 
407
315
  ```
408
316
  Warning: The file name AccountTrigger was not found in any package directory.
409
317
  ```
410
318
 
319
+ **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:
320
+
321
+ ```
322
+ 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".
323
+ ```
324
+
325
+ Resolve by renaming one of the files or using `--ignore-package-directory` to exclude the package whose version should not be included.
326
+
411
327
  **No files matched** — Report will be empty:
412
328
 
413
329
  ```
@@ -432,9 +348,7 @@ Error (1): sfdx-project.json not found in any parent directory.
432
348
  Error (1): ENOENT: no such file or directory: {packageDir}
433
349
  ```
434
350
 
435
- ## Contributing
436
-
437
- Contributions are welcome. See [CONTRIBUTING.md](https://github.com/mcarvin8/apex-code-coverage-transformer/blob/main/CONTRIBUTING.md).
351
+ **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).
438
352
 
439
353
  ## License
440
354
 
@@ -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":"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"}
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":"AAAA,qCAAqC;AACrC,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAE/D,OAAO,EAAE,qBAAqB,EAAE,MAAM,mCAAmC,CAAC;AAC1E,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AACxD,OAAO,EAAE,kBAAkB,EAAE,MAAM,gCAAgC,CAAC;AACpE,OAAO,EAAE,eAAe,EAA8B,MAAM,6BAA6B,CAAC;AAC1F,OAAO,EAAE,uBAAuB,EAAE,MAAM,qCAAqC,CAAC;AAC9E,OAAO,EAAE,qBAAqB,EAAE,MAAM,iCAAiC,CAAC;AACxE,OAAO,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAChD,OAAO,EAAE,sBAAsB,EAAE,MAAM,sBAAsB,CAAC;AAY9D,MAAM,CAAC,KAAK,UAAU,uBAAuB,CAC3C,YAAoB,EACpB,gBAAwB,EACxB,OAAiB,EACjB,UAAoB,EACpB,OAA0B;IAE1B,MAAM,QAAQ,GAAa,EAAE,CAAC;IAC9B,MAAM,UAAU,GAAa,EAAE,CAAC;IAChC,MAAM,YAAY,GAAW,OAAO,CAAC,MAAM,CAAC;IAE5C,MAAM,QAAQ,GAAG,MAAM,WAAW,CAAC,YAAY,EAAE,QAAQ,CAAC,CAAC;IAC3D,IAAI,CAAC,QAAQ;QAAE,OAAO,EAAE,UAAU,EAAE,CAAC,gBAAgB,CAAC,EAAE,QAAQ,EAAE,QAAQ,EAAE,CAAC,EAAE,CAAC;IAEhF,MAAM,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAkB,CAAC;IACzD,MAAM,EAAE,QAAQ,EAAE,kBAAkB,EAAE,GAAG,MAAM,qBAAqB,CAAC,UAAU,CAAC,CAAC;IACjF,MAAM,QAAQ,GAAG,cAAc,CAAC,OAAO,CAAC,CAAC;IACzC,MAAM,WAAW,GAAG,qBAAqB,CAAC,UAAU,CAAC,CAAC;IACtD,MAAM,gBAAgB,GAAG,uBAAuB,EAAE,CAAC;IAEnD,qEAAqE;IACrE,MAAM,EAAE,KAAK,EAAE,aAAa,EAAE,QAAQ,EAAE,aAAa,EAAE,GAAG,MAAM,kBAAkB,CAAC,kBAAkB,EAAE,QAAQ,CAAC,CAAC;IACjH,QAAQ,CAAC,IAAI,CAAC,GAAG,aAAa,CAAC,CAAC;IAEhC,MAAM,OAAO,GAA8B;QACzC,QAAQ;QACR,WAAW,EAAE,kBAAkB;QAC/B,QAAQ;QACR,gBAAgB;QAChB,QAAQ;QACR,aAAa;KACd,CAAC;IAEF,IAAI,aAA4B,CAAC;IAEjC,IAAI,WAAW,KAAK,oBAAoB,EAAE,CAAC;QACzC,aAAa,GAAG,MAAM,qBAAqB,CAAC,UAAgC,EAAE,OAAO,CAAC,CAAC;IACzF,CAAC;SAAM,IAAI,WAAW,KAAK,kBAAkB,EAAE,CAAC;QAC9C,aAAa,GAAG,MAAM,mBAAmB,CAAC,UAAgC,EAAE,OAAO,CAAC,CAAC;IACvF,CAAC;SAAM,CAAC;QACN,MAAM,IAAI,KAAK,CACb,2GAA2G,CAC5G,CAAC;IACJ,CAAC;IAED,IAAI,aAAa,CAAC,SAAS,KAAK,CAAC,EAAE,CAAC;QAClC,QAAQ,CAAC,IAAI,CAAC,kGAAkG,CAAC,CAAC;IACpH,CAAC;IAED,MAAM,QAAQ,GAAG,aAAa,CAAC,UAAU,GAAG,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,YAAY,GAAG,aAAa,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC;IAE1G,MAAM,aAAa,GAAG,OAAO,EAAE,cAAc,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,cAAc,EAAE,OAAO,CAAC,cAAc,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;IAErH,KAAK,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,IAAI,QAAQ,CAAC,OAAO,EAAE,EAAE,CAAC;QACnD,MAAM,WAAW,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC;QACvC,MAAM,SAAS,GAAG,MAAM,sBAAsB,CAAC,gBAAgB,EAAE,WAAW,EAAE,MAAM,EAAE,YAAY,EAAE,aAAa,CAAC,CAAC;QACnH,UAAU,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IAC7B,CAAC;IAED,IAAI,OAAO,EAAE,WAAW,KAAK,SAAS,IAAI,QAAQ,GAAG,GAAG,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC;QAC/E,MAAM,IAAI,KAAK,CACb,eAAe,CAAC,QAAQ,GAAG,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,sCAAsC,OAAO,CAAC,WAAW,IAAI,CACxG,CAAC;IACJ,CAAC;IAED,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,QAAQ,EAAE,CAAC;AAC5C,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,KAAK,UAAU,WAAW,CAAC,IAAY,EAAE,QAAkB;IACzD,IAAI,CAAC;QACH,OAAO,MAAM,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IACvC,CAAC;IAAC,MAAM,CAAC;QACP,QAAQ,CAAC,IAAI,CAAC,kBAAkB,IAAI,wBAAwB,CAAC,CAAC;QAC9D,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,SAAS,cAAc,CAAC,OAAiB;IACvC,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,UAAU,CAAC,KAA6B;IAC/C,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;AAED,KAAK,UAAU,qBAAqB,CAClC,IAAwB,EACxB,OAAkC;IAElC,IAAI,SAAS,GAAG,CAAC,CAAC;IAClB,IAAI,UAAU,GAAG,CAAC,CAAC;IACnB,IAAI,YAAY,GAAG,CAAC,CAAC;IAErB,MAAM,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,OAAO,CAAC,gBAAgB,EAAE,KAAK,EAAE,QAAgB,EAAE,EAAE;QACrF,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC;QAChC,MAAM,aAAa,GAAG,QAAQ,CAAC,OAAO,CAAC,cAAc,EAAE,EAAE,CAAC,CAAC;QAC3D,MAAM,IAAI,GAAG,YAAY,CAAC,aAAa,EAAE,OAAO,CAAC,aAAa,CAAC,CAAC;QAEhE,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,iBAAiB,aAAa,0CAA0C,CAAC,CAAC;YAChG,OAAO;QACT,CAAC;QAED,MAAM,gBAAgB,GAAG,MAAM,eAAe,CAAC,IAAI,EAAE,OAAO,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC,EAAE,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC;QACjH,MAAM,YAAY,GAAG,gBAAgB,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC,gBAAgB,CAAC,YAAY,CAAC,CAAC,CAAC,gBAAgB,CAAC;QAC3G,MAAM,aAAa,GAAG,gBAAgB,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC,gBAAgB,CAAC,aAAa,CAAC,CAAC,CAAC,SAAS,CAAC;QACtG,QAAQ,CAAC,CAAC,GAAG,YAAY,CAAC;QAE1B,MAAM,MAAM,GAAG,UAAU,CAAC,YAAY,CAAC,CAAC;QACxC,UAAU,IAAI,MAAM,CAAC,UAAU,CAAC;QAChC,YAAY,IAAI,MAAM,CAAC,YAAY,CAAC;QAEpC,KAAK,MAAM,OAAO,IAAI,OAAO,CAAC,QAAQ,CAAC,MAAM,EAAE,EAAE,CAAC;YAChD,OAAO,CAAC,WAAW,CAAC,IAAI,EAAE,aAAa,EAAE,YAAY,EAAE,aAAa,CAAC,CAAC;QACxE,CAAC;QACD,SAAS,EAAE,CAAC;IACd,CAAC,CAAC,CAAC;IAEH,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,YAAY,EAAE,CAAC;AACjD,CAAC;AAED,KAAK,UAAU,mBAAmB,CAChC,IAAwB,EACxB,OAAkC;IAElC,IAAI,SAAS,GAAG,CAAC,CAAC;IAClB,IAAI,UAAU,GAAG,CAAC,CAAC;IACnB,IAAI,YAAY,GAAG,CAAC,CAAC;IAErB,MAAM,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC,gBAAgB,EAAE,KAAK,EAAE,KAAuB,EAAE,EAAE;QAC/E,MAAM,aAAa,GAAG,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,cAAc,EAAE,EAAE,CAAC,CAAC;QAC7D,MAAM,IAAI,GAAG,YAAY,CAAC,aAAa,EAAE,OAAO,CAAC,aAAa,CAAC,CAAC;QAEhE,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,iBAAiB,aAAa,0CAA0C,CAAC,CAAC;YAChG,OAAO;QACT,CAAC;QAED,MAAM,MAAM,GAAG,UAAU,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QACvC,UAAU,IAAI,MAAM,CAAC,UAAU,CAAC;QAChC,YAAY,IAAI,MAAM,CAAC,YAAY,CAAC;QAEpC,MAAM,aAAa,GAAG,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,cAAc,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;QACpH,KAAK,MAAM,OAAO,IAAI,OAAO,CAAC,QAAQ,CAAC,MAAM,EAAE,EAAE,CAAC;YAChD,OAAO,CAAC,WAAW,CAAC,IAAI,EAAE,aAAa,EAAE,KAAK,CAAC,KAAK,EAAE,aAAa,CAAC,CAAC;QACvE,CAAC;QACD,SAAS,EAAE,CAAC;IACd,CAAC,CAAC,CAAC;IAEH,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,YAAY,EAAE,CAAC;AACjD,CAAC"}
@@ -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"}
@@ -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.20.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.20.0",
5
5
  "dependencies": {
6
6
  "@oclif/core": "4.8.3",
7
7
  "@salesforce/core": "8.26.3",