apex-code-coverage-transformer 2.15.2 → 2.16.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/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.16.1](https://github.com/mcarvin8/apex-code-coverage-transformer/compare/v2.16.0...v2.16.1) (2026-02-02)
9
+
10
+
11
+ ### Bug Fixes
12
+
13
+ * **deps:** bump @salesforce/core from 8.24.0 to 8.25.0 ([#256](https://github.com/mcarvin8/apex-code-coverage-transformer/issues/256)) ([06ab8ea](https://github.com/mcarvin8/apex-code-coverage-transformer/commit/06ab8ead5d92dc1024fc6de5d6c2b78e78cfdcd7))
14
+
15
+ ## [2.16.0](https://github.com/mcarvin8/apex-code-coverage-transformer/compare/v2.15.2...v2.16.0) (2026-01-26)
16
+
17
+
18
+ ### Features
19
+
20
+ * add html as an output format ([#253](https://github.com/mcarvin8/apex-code-coverage-transformer/issues/253)) ([d7d4f54](https://github.com/mcarvin8/apex-code-coverage-transformer/commit/d7d4f54664ef3ab603e0b55b70b9c6883ec93b0f))
21
+
8
22
  ## [2.15.2](https://github.com/mcarvin8/apex-code-coverage-transformer/compare/v2.15.1...v2.15.2) (2026-01-03)
9
23
 
10
24
 
package/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # `apex-code-coverage-transformer`
1
+ # apex-code-coverage-transformer
2
2
 
3
3
  [![NPM](https://img.shields.io/npm/v/apex-code-coverage-transformer.svg?label=apex-code-coverage-transformer)](https://www.npmjs.com/package/apex-code-coverage-transformer)
4
4
  [![Downloads/week](https://img.shields.io/npm/dw/apex-code-coverage-transformer.svg)](https://npmjs.org/package/apex-code-coverage-transformer)
@@ -7,34 +7,41 @@
7
7
  [![Code Coverage](https://qlty.sh/badges/11057a07-84da-41af-91fb-b3476e404242/test_coverage.svg)](https://qlty.sh/gh/mcarvin8/projects/apex-code-coverage-transformer)
8
8
  [![Known Vulnerabilities](https://snyk.io//test/github/mcarvin8/apex-code-coverage-transformer/badge.svg?targetFile=package.json)](https://snyk.io//test/github/mcarvin8/apex-code-coverage-transformer?targetFile=package.json)
9
9
 
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. Use it to keep coverage in sync with your CI/CD and code quality pipelines.
11
+
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).
13
+
10
14
  <!-- TABLE OF CONTENTS -->
11
15
  <details>
12
16
  <summary>Table of Contents</summary>
13
17
 
18
+ - [Prerequisites](#prerequisites)
14
19
  - [Install](#install)
15
20
  - [Quick Start](#quick-start)
16
21
  - [Usage](#usage)
17
22
  - [Salesforce CLI](#salesforce-cli)
18
23
  - [SFDX Hardis](#sfdx-hardis)
19
- - [Fixes and Enhancements](#fixes-and-enhancements)
20
- - [Command](#command)
21
- - [`sf acc-transformer transform`](#sf-acc-transformer-transform)
24
+ - [What This Plugin Fixes and Adds](#what-this-plugin-fixes-and-adds)
25
+ - [Command Reference](#command-reference)
26
+ - [sf acc-transformer transform](#sf-acc-transformer-transform)
22
27
  - [Coverage Report Formats](#coverage-report-formats)
23
- - [CI/CD Integration Examples](#cicd-integration-examples)
28
+ - [CI/CD Integration](#cicd-integration)
24
29
  - [Codecov](#codecov)
25
30
  - [SonarQube](#sonarqube)
26
31
  - [GitHub Actions](#github-actions)
27
32
  - [GitLab CI](#gitlab-ci)
28
- - [Hook](#hook)
33
+ - [Automatic Transformation (Hook)](#automatic-transformation-hook)
29
34
  - [Troubleshooting](#troubleshooting)
30
- - [Issues](#issues)
31
35
  - [Contributing](#contributing)
32
36
  - [License](#license)
33
37
  </details>
34
38
 
35
- Transform the Salesforce Apex code coverage JSON files created during deployments and test runs into other [formats](#coverage-report-formats) accepted by SonarQube, Codecov, GitHub, GitLab, Azure, Bitbucket, etc.
39
+ ## Prerequisites
36
40
 
37
- > If there's a coverage format not yet supported by this plugin, feel free to provide a pull request or issue for the coverage format.
41
+ - [Salesforce CLI](https://developer.salesforce.com/tools/sfdxcli) (`sf`) installed
42
+ - Node.js 20.x or later
43
+ - A Salesforce DX project with `sfdx-project.json` and package directories
44
+ - Use only the **json** coverage formatter from the Salesforce CLI; other formatters are not supported
38
45
 
39
46
  ## Install
40
47
 
@@ -44,221 +51,144 @@ sf plugins install apex-code-coverage-transformer@x.y.z
44
51
 
45
52
  ## Quick Start
46
53
 
47
- 1. **Generate Salesforce code coverage in JSON format**:
48
-
49
- **Option A - Run Apex tests directly**:
54
+ 1. **Generate Apex code coverage (JSON)**
55
+ From tests:
50
56
 
51
57
  ```bash
52
58
  sf apex run test --code-coverage --output-dir "coverage"
53
59
  ```
54
60
 
55
- **Option B - Deploy/validate with coverage**:
61
+ Or from deploy/validate:
56
62
 
57
63
  ```bash
58
64
  sf project deploy start --coverage-formatters json --results-dir "coverage"
59
- # or for validation
60
- sf project deploy validate --coverage-formatters json --results-dir "coverage"
65
+ # or: sf project deploy validate --coverage-formatters json --results-dir "coverage"
61
66
  ```
62
67
 
63
- 2. **Transform the coverage to your desired format**:
64
-
65
- **For test command** (creates `coverage/test-result-codecoverage.json`):
68
+ 2. **Transform to your target format**
69
+ Test output → `coverage/test-result-codecoverage.json`. Deploy output → `coverage/coverage/coverage.json`.
66
70
 
67
71
  ```bash
68
- # For SonarQube
72
+ # SonarQube
69
73
  sf acc-transformer transform -j "coverage/test-result-codecoverage.json" -r "coverage.xml" -f "sonar"
70
74
 
71
- # For Codecov
75
+ # Codecov (Cobertura)
72
76
  sf acc-transformer transform -j "coverage/test-result-codecoverage.json" -r "coverage.xml" -f "cobertura"
73
77
 
74
- # For multiple formats at once
78
+ # Multiple formats
75
79
  sf acc-transformer transform -j "coverage/test-result-codecoverage.json" -f "sonar" -f "cobertura" -f "jacoco"
76
80
  ```
77
81
 
78
- **For deploy command** (creates `coverage/coverage/coverage.json`):
79
-
80
- ```bash
81
- # For SonarQube
82
- sf acc-transformer transform -j "coverage/coverage/coverage.json" -r "coverage.xml" -f "sonar"
83
-
84
- # For Codecov
85
- sf acc-transformer transform -j "coverage/coverage/coverage.json" -r "coverage.xml" -f "cobertura"
86
- ```
87
-
88
- 3. **Upload to your coverage tool** (see [CI/CD Integration Examples](#cicd-integration-examples) for platform-specific instructions).
82
+ 3. **Upload to your tool**
83
+ See [CI/CD Integration](#cicd-integration) for Codecov, SonarQube, GitHub Actions, and GitLab.
89
84
 
90
85
  ## Usage
91
86
 
92
- This plugin is designed for users deploying Apex or running Apex tests within Salesforce DX projects (`sfdx-project.json`). It transforms Salesforce CLI JSON coverage reports into formats recognized by external tools.
87
+ 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).
93
88
 
94
- The plugin ensures that coverage data is only reported for files found in your package directories, preventing mismatches in tools like SonarQube. If Apex files are missing from your project (i.e. Apex from managed or unlocked packages), they will be excluded from the transformed report with a [warning](#troubleshooting).
95
-
96
- To automate coverage transformation after deployments or test executions, see [Hook](#hook).
89
+ To run transformation automatically after deploy or test commands, use the [Hook](#automatic-transformation-hook).
97
90
 
98
91
  ### Salesforce CLI
99
92
 
100
- > This plugin will only support the "json" coverage format from the Salesforce CLI. Do not use other coverage formats from the Salesforce CLI.
101
-
102
- To create the code coverage JSON when deploying or validating, append `--coverage-formatters json --results-dir "coverage"` to the `sf project deploy` command. This will create a coverage JSON in this relative path - `coverage/coverage/coverage.json`.
93
+ **Deploy/validate** coverage path: `coverage/coverage/coverage.json`
103
94
 
104
- ```
105
- sf project deploy [start/validate/report/resume] --coverage-formatters json --results-dir "coverage"
95
+ ```bash
96
+ sf project deploy [start|validate|report|resume] --coverage-formatters json --results-dir "coverage"
106
97
  ```
107
98
 
108
- To create the code coverage JSON when running tests directly in the org, append `--code-coverage --output-dir "coverage"` to the `sf apex run test` or `sf apex get test` command. This will create the code coverage JSON in this relative path - `coverage/test-result-codecoverage.json`
99
+ **Run tests** coverage path: `coverage/test-result-codecoverage.json`
109
100
 
110
- ```
101
+ ```bash
111
102
  sf apex run test --code-coverage --output-dir "coverage"
112
- sf apex get test --test-run-id <test run id> --code-coverage --output-dir "coverage"
103
+ sf apex get test --test-run-id <id> --code-coverage --output-dir "coverage"
113
104
  ```
114
105
 
115
106
  ### SFDX Hardis
116
107
 
117
- This plugin can be used after running the below [sfdx-hardis](https://github.com/hardisgroupcom/sfdx-hardis) commands:
108
+ Works with [sfdx-hardis](https://github.com/hardisgroupcom/sfdx-hardis):
118
109
 
119
- - `sf hardis project deploy smart` (only if `COVERAGE_FORMATTER_JSON=true` environment variable is defined)
110
+ - `sf hardis project deploy smart` (when `COVERAGE_FORMATTER_JSON=true`)
120
111
  - `sf hardis org test apex`
121
112
 
122
- Both hardis commands will create the code coverage JSON to transform here: `hardis-report/apex-coverage-results.json`.
123
-
124
- ## Fixes and Enhancements
113
+ Coverage file: `hardis-report/apex-coverage-results.json`.
125
114
 
126
- - **Maps Apex file names** in the original coverage report (e.g., `no-map/AccountTriggerHandler`) to their corresponding relative file paths in the Salesforce DX project (e.g., `force-app/main/default/classes/AccountTriggerHandler.cls`).
127
- - **Normalizes coverage reports** across both deploy and test commands, improving compatibility with external tools.
128
- - **Adds additional coverage formats** not available in the default Salesforce CLI deploy and test commands.
129
- - **"Fixes" inaccuracies** in Salesforce CLI deploy command coverage reports, such as out-of-range covered lines (e.g., line 100 reported as "covered" in a 98-line Apex class) and incorrect total line counts (e.g., 120 lines reported for a 100-line Apex class).
130
- - To address these inaccuracies, the plugin includes a **re-numbering function** that only applies to deploy coverage reports. This function reassigns out-of-range `covered` lines to unused lines, ensuring reports are accepted by external tools.
131
- - The `uncovered` lines are always correctly reported by the deploy command.
132
- - Once Salesforce resolves the issue with the API that affects deploy command coverage reports, the re-numbering function will be removed in a future **breaking** release.
133
- - See issues [5511](https://github.com/forcedotcom/salesforcedx-vscode/issues/5511) and [1568](https://github.com/forcedotcom/cli/issues/1568) for more details.
134
- - **Note**: This does not affect coverage reports generated by the Salesforce CLI test commands.
115
+ ## What This Plugin Fixes and Adds
135
116
 
136
- ## Command
117
+ - **File mapping** — Maps names like `no-map/AccountTriggerHandler` to paths like `force-app/main/default/classes/AccountTriggerHandler.cls`.
118
+ - **Normalization** — Aligns deploy and test coverage structures so external tools can consume them.
119
+ - **Extra formats** — Outputs Sonar, Cobertura, JaCoCo, LCOV, Clover, and more (see [Coverage Report Formats](#coverage-report-formats)).
120
+ - **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.
137
121
 
138
- The `apex-code-coverage-transformer` has 1 command:
122
+ ## Command Reference
139
123
 
140
- - `sf acc-transformer transform`
124
+ Single command: `sf acc-transformer transform`.
141
125
 
142
- ## `sf acc-transformer transform`
126
+ ### sf acc-transformer transform
143
127
 
144
128
  ```
145
129
  USAGE
146
130
  $ sf acc-transformer transform -j <value> [-r <value>] [-f <value>] [-i <value>] [--json]
147
131
 
148
132
  FLAGS
149
- -j, --coverage-json=<value> Path to the code coverage JSON file created by the Salesforce CLI deploy or test command.
150
- -r, --output-report=<value> Path to the code coverage file that will be created by this plugin.
151
- [default: "coverage.[xml/info]"]
152
- -f, --format=<value> Output format for the code coverage format.
153
- Can be declared multiple times.
154
- If declared multiple times, the output report will have the format appended to the file-name, i.e. `coverage-sonar.xml`
155
- [default: "sonar"]
156
- -i, --ignore-package-directory=<value> Package directory to ignore when looking for matching files in the coverage report.
157
- Should be as they appear in the "sfdx-project.json".
158
- Can be declared multiple times.
133
+ -j, --coverage-json=<value> Path to the code coverage JSON from deploy or test.
134
+ -r, --output-report=<value> Output path (e.g. coverage.xml). Default: coverage.[xml|info] by format.
135
+ -f, --format=<value> Output format (repeat for multiple). Default: sonar.
136
+ Multiple formats append to filename, e.g. coverage-sonar.xml.
137
+ -i, --ignore-package-directory=<value> Package directory to ignore (as in sfdx-project.json). Repeatable.
159
138
 
160
139
  GLOBAL FLAGS
161
- --json Format output as json.
162
-
163
- EXAMPLES
164
- Transform the JSON into Sonar format:
165
-
166
- $ sf acc-transformer transform -j "coverage.json" -r "coverage.xml" -f "sonar"
167
-
168
- Transform the JSON into Cobertura format:
169
-
170
- $ sf acc-transformer transform -j "coverage.json" -r "coverage.xml" -f "cobertura"
171
-
172
- Transform the JSON into Clover format:
173
-
174
- $ sf acc-transformer transform -j "coverage.json" -r "coverage.xml" -f "clover"
175
-
176
- Transform the JSON into LCovOnly format:
177
-
178
- $ sf acc-transformer transform -j "coverage.json" -r "coverage.info" -f "lcovonly"
179
-
180
- Transform the JSON into JSON Summary format:
181
-
182
- $ sf acc-transformer transform -j "coverage.json" -r "coverage.json" -f "json-summary"
183
-
184
- Transform the JSON into SimpleCov format:
185
-
186
- $ sf acc-transformer transform -j "coverage.json" -r "coverage.json" -f "simplecov"
187
-
188
- Transform the JSON into OpenCover format:
189
-
190
- $ sf acc-transformer transform -j "coverage.json" -r "coverage.xml" -f "opencover"
191
-
192
- Transform the JSON into Sonar format, ignoring Apex in the "force-app" directory:
193
-
194
- $ sf acc-transformer transform -j "coverage.json" -i "force-app"
140
+ --json Output as JSON.
195
141
  ```
196
142
 
197
143
  ## Coverage Report Formats
198
144
 
199
- The `-f`/`--format` flag allows you to specify the format of the transformed coverage report.
200
-
201
- You can provide multiple `--format` flags in a single command to create multiple reports. If multiple `--format` flags are provided, each output report will have the format appended to the name. For example, if `--output-report` is set `coverage.xml` and you supply `--format sonar --format cobertura` to the command, the output reports will be `coverage-sonar.xml` and `coverage-cobertura.xml`.
145
+ Use `-f` / `--format` to choose the output format. Multiple `-f` values produce multiple files with the format in the name (e.g. `coverage-sonar.xml`, `coverage-cobertura.xml`).
202
146
 
203
- | Format | Description | Compatible Platforms/Tools |
204
- | ----------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------ | ---------------------------------------------------------- |
205
- | [sonar](https://raw.githubusercontent.com/mcarvin8/apex-code-coverage-transformer/main/baselines/sonar_baseline.xml) | Generates a SonarQube-compatible coverage report. This is the default option. | SonarQube, SonarCloud |
206
- | [cobertura](https://raw.githubusercontent.com/mcarvin8/apex-code-coverage-transformer/main/baselines/cobertura_baseline.xml) | Creates a Cobertura XML report, a widely used format for coverage reporting. | **Codecov**, Azure DevOps, Jenkins, GitLab, GitHub Actions |
207
- | [jacoco](https://raw.githubusercontent.com/mcarvin8/apex-code-coverage-transformer/main/baselines/jacoco_baseline.xml) | Creates a JaCoCo XML report, the standard for Java projects. | **Codecov**, Jenkins, Maven, Gradle |
208
- | [lcovonly](https://raw.githubusercontent.com/mcarvin8/apex-code-coverage-transformer/main/baselines/lcov_baseline.info) | Outputs coverage data in LCOV format, useful for integrating with LCOV-based tools. | Codecov, Coveralls, GitHub Actions |
209
- | [clover](https://raw.githubusercontent.com/mcarvin8/apex-code-coverage-transformer/main/baselines/clover_baseline.xml) | Produces a Clover XML report format, commonly used with Atlassian tools. | Bamboo, Bitbucket, Jenkins |
210
- | [json](https://raw.githubusercontent.com/mcarvin8/apex-code-coverage-transformer/main/baselines/json_baseline.json) | Generates a Istanbul JSON report compatible with Node.js tooling and coverage visualizers. | Istanbul/NYC, Codecov, custom tools |
211
- | [json-summary](https://raw.githubusercontent.com/mcarvin8/apex-code-coverage-transformer/main/baselines/json-summary_baseline.json) | Generates a concise JSON summary ideal for badges, PR comments, and quick analysis. | GitHub Actions, GitLab CI, Custom Dashboards |
212
- | [simplecov](https://raw.githubusercontent.com/mcarvin8/apex-code-coverage-transformer/main/baselines/simplecov_baseline.json) | Generates SimpleCov JSON format compatible with Ruby coverage tools. | Codecov, SimpleCov, Ruby Tools |
213
- | [opencover](https://raw.githubusercontent.com/mcarvin8/apex-code-coverage-transformer/main/baselines/opencover_baseline.xml) | Generates OpenCover XML format for .NET and Azure DevOps integration. | Azure DevOps, Visual Studio, Codecov, JetBrains Tools |
147
+ | Format | Description | Typical use | Example |
148
+ | ------------ | -------------------------- | --------------------------------------- | -------------------------------------------------------------------------------------- |
149
+ | sonar | SonarQube generic coverage | SonarQube, SonarCloud | `sf acc-transformer transform -j "coverage.json" -r "coverage.xml" -f "sonar"` |
150
+ | cobertura | Cobertura XML | Codecov, Azure, Jenkins, GitLab, GitHub | `sf acc-transformer transform -j "coverage.json" -r "coverage.xml" -f "cobertura"` |
151
+ | jacoco | JaCoCo XML | Codecov, Jenkins, Maven, Gradle | `sf acc-transformer transform -j "coverage.json" -r "coverage.xml" -f "jacoco"` |
152
+ | lcovonly | LCOV | Codecov, Coveralls, GitHub | `sf acc-transformer transform -j "coverage.json" -r "coverage.info" -f "lcovonly"` |
153
+ | clover | Clover XML | Bamboo, Bitbucket, Jenkins | `sf acc-transformer transform -j "coverage.json" -r "coverage.xml" -f "clover"` |
154
+ | json | Istanbul JSON | Istanbul/NYC, Codecov | `sf acc-transformer transform -j "coverage.json" -r "coverage.json" -f "json"` |
155
+ | json-summary | JSON summary | Badges, PR comments | `sf acc-transformer transform -j "coverage.json" -r "coverage.json" -f "json-summary"` |
156
+ | simplecov | SimpleCov JSON | Codecov, Ruby tools | `sf acc-transformer transform -j "coverage.json" -r "coverage.json" -f "simplecov"` |
157
+ | opencover | OpenCover XML | Azure DevOps, VS, Codecov | `sf acc-transformer transform -j "coverage.json" -r "coverage.xml" -f "opencover"` |
158
+ | html | HTML report | Browsers, CI artifacts | `sf acc-transformer transform -j "coverage.json" -r "coverage.html" -f "html"` |
214
159
 
215
- ## CI/CD Integration Examples
160
+ ## CI/CD Integration
216
161
 
217
162
  ### Codecov
218
163
 
219
- Codecov accepts multiple formats including Cobertura, JaCoCo, and LCOV. Cobertura is recommended for its wide compatibility.
220
-
221
- **Using Codecov CLI**:
164
+ Cobertura is a good default. **CLI upload:**
222
165
 
223
166
  ```bash
224
- # Generate Salesforce coverage
225
167
  sf apex run test --code-coverage --output-dir "coverage"
226
-
227
- # Transform to Cobertura format
228
168
  sf acc-transformer transform -j "coverage/test-result-codecoverage.json" -r "coverage.xml" -f "cobertura"
229
-
230
- # Upload to Codecov
231
169
  codecovcli upload-process --file coverage.xml
232
170
  ```
233
171
 
234
- **Using Codecov GitHub Action**:
172
+ **GitHub Action:**
235
173
 
236
174
  ```yaml
237
175
  name: Salesforce CI with Codecov
238
-
239
176
  on: [push, pull_request]
240
-
241
177
  jobs:
242
178
  test:
243
179
  runs-on: ubuntu-latest
244
180
  steps:
245
181
  - uses: actions/checkout@v4
246
-
247
182
  - name: Install Salesforce CLI
248
183
  run: npm install -g @salesforce/cli
249
-
250
184
  - name: Install Coverage Transformer Plugin
251
185
  run: sf plugins install apex-code-coverage-transformer
252
-
253
186
  - name: Authenticate to Salesforce
254
187
  run: sf org login sfdx-url --sfdx-url-file ${{ secrets.SFDX_AUTH_URL }} --alias ci-org
255
-
256
188
  - name: Run Apex Tests
257
189
  run: sf apex run test --code-coverage --output-dir coverage --target-org ci-org
258
-
259
190
  - name: Transform Coverage to Cobertura
260
191
  run: sf acc-transformer transform -j "coverage/test-result-codecoverage.json" -r "coverage.xml" -f "cobertura"
261
-
262
192
  - name: Upload to Codecov
263
193
  uses: codecov/codecov-action@v4
264
194
  with:
@@ -269,33 +199,28 @@ jobs:
269
199
 
270
200
  ### SonarQube
271
201
 
272
- SonarQube requires its own Generic Coverage format (Sonar format).
202
+ Use the **sonar** format and upload using SonarQube's generic test coverage report formatter, `sonar.coverageReportPaths`.
273
203
 
274
- **SonarQube Scanner Example**:
204
+ **Scanner:**
275
205
 
276
206
  ```bash
277
- # Generate and transform coverage
278
207
  sf apex run test --code-coverage --output-dir "coverage"
279
208
  sf acc-transformer transform -j "coverage/test-result-codecoverage.json" -r "coverage.xml" -f "sonar"
280
-
281
- # Run SonarQube scanner
282
209
  sonar-scanner \
283
210
  -Dsonar.projectKey=your-project-key \
284
211
  -Dsonar.sources=force-app \
285
212
  -Dsonar.tests=force-app \
286
213
  -Dsonar.test.inclusions=**/*Test.cls \
287
- -Dsonar.apex.coverage.reportPath=coverage.xml \
214
+ -Dsonar.coverageReportPaths=coverage.xml \
288
215
  -Dsonar.host.url=https://sonarqube.example.com \
289
216
  -Dsonar.login=$SONAR_TOKEN
290
217
  ```
291
218
 
292
- **SonarCloud GitHub Action**:
219
+ **SonarCloud GitHub Action:**
293
220
 
294
221
  ```yaml
295
222
  name: SonarCloud Analysis
296
-
297
223
  on: [push, pull_request]
298
-
299
224
  jobs:
300
225
  sonarcloud:
301
226
  runs-on: ubuntu-latest
@@ -303,22 +228,16 @@ jobs:
303
228
  - uses: actions/checkout@v4
304
229
  with:
305
230
  fetch-depth: 0
306
-
307
231
  - name: Install Salesforce CLI
308
232
  run: npm install -g @salesforce/cli
309
-
310
233
  - name: Install Coverage Transformer Plugin
311
234
  run: sf plugins install apex-code-coverage-transformer
312
-
313
235
  - name: Authenticate to Salesforce
314
236
  run: sf org login sfdx-url --sfdx-url-file ${{ secrets.SFDX_AUTH_URL }} --alias ci-org
315
-
316
237
  - name: Run Apex Tests
317
238
  run: sf apex run test --code-coverage --output-dir coverage --target-org ci-org
318
-
319
239
  - name: Transform Coverage to Sonar Format
320
240
  run: sf acc-transformer transform -j "coverage/test-result-codecoverage.json" -r "coverage.xml" -f "sonar"
321
-
322
241
  - name: SonarCloud Scan
323
242
  uses: SonarSource/sonarcloud-github-action@master
324
243
  env:
@@ -331,41 +250,31 @@ jobs:
331
250
  -Dsonar.sources=force-app
332
251
  -Dsonar.tests=force-app
333
252
  -Dsonar.test.inclusions=**/*Test.cls
334
- -Dsonar.apex.coverage.reportPath=coverage.xml
253
+ -Dsonar.coverageReportPaths=coverage.xml
335
254
  ```
336
255
 
337
256
  ### GitHub Actions
338
257
 
339
- GitHub Actions can display coverage using various formats. Use Cobertura or LCOV for best compatibility.
340
-
341
- **With Coverage Report Action**:
258
+ Use Cobertura (or LCOV) with a coverage summary action:
342
259
 
343
260
  ```yaml
344
261
  name: Salesforce CI with Coverage Report
345
-
346
262
  on: [push, pull_request]
347
-
348
263
  jobs:
349
264
  test:
350
265
  runs-on: ubuntu-latest
351
266
  steps:
352
267
  - uses: actions/checkout@v4
353
-
354
268
  - name: Install Salesforce CLI
355
269
  run: npm install -g @salesforce/cli
356
-
357
270
  - name: Install Coverage Transformer Plugin
358
271
  run: sf plugins install apex-code-coverage-transformer
359
-
360
272
  - name: Authenticate to Salesforce
361
273
  run: sf org login sfdx-url --sfdx-url-file ${{ secrets.SFDX_AUTH_URL }} --alias ci-org
362
-
363
274
  - name: Run Apex Tests
364
275
  run: sf apex run test --code-coverage --output-dir coverage --target-org ci-org
365
-
366
276
  - name: Transform Coverage to Cobertura
367
277
  run: sf acc-transformer transform -j "coverage/test-result-codecoverage.json" -r "coverage.xml" -f "cobertura"
368
-
369
278
  - name: Code Coverage Report
370
279
  uses: irongut/CodeCoverageSummary@v1.3.0
371
280
  with:
@@ -373,7 +282,6 @@ jobs:
373
282
  badge: true
374
283
  format: markdown
375
284
  output: both
376
-
377
285
  - name: Add Coverage PR Comment
378
286
  uses: marocchino/sticky-pull-request-comment@v2
379
287
  if: github.event_name == 'pull_request'
@@ -384,9 +292,7 @@ jobs:
384
292
 
385
293
  ### GitLab CI
386
294
 
387
- GitLab supports Cobertura format natively for coverage visualization.
388
-
389
- **`.gitlab-ci.yml` Example**:
295
+ Cobertura for coverage in the UI:
390
296
 
391
297
  ```yaml
392
298
  stages:
@@ -413,75 +319,62 @@ apex-tests:
413
319
  expire_in: 30 days
414
320
  ```
415
321
 
416
- ## Hook
322
+ ## Automatic Transformation (Hook)
417
323
 
418
- To enable automatic transformation after the below `sf` commands complete, create a `.apexcodecovtransformer.config.json` in your project’s root directory.
324
+ Create `.apexcodecovtransformer.config.json` in the project root to transform coverage automatically after:
419
325
 
420
- - `sf project deploy [start/validate/report/resume]`
326
+ - `sf project deploy [start|validate|report|resume]`
421
327
  - `sf apex run test`
422
328
  - `sf apex get test`
423
- - `sf hardis project deploy smart`
424
- - only if `sfdx-hardis` is installed
425
- - `COVERAGE_FORMATTER_JSON=true` must be set in the environment variables
426
- - `sf hardis org test apex`
427
- - only if `sfdx-hardis` is installed
428
-
429
- You can copy & update the sample [Salesforce CLI .apexcodecovtransformer.config.json](https://raw.githubusercontent.com/mcarvin8/apex-code-coverage-transformer/main/defaults/salesforce-cli/.apexcodecovtransformer.config.json), which assumes you are running the Salesforce CLI commands and specifying the `--results-dir`/`--output-dir` directory as "coverage".
329
+ - `sf hardis project deploy smart` (if sfdx-hardis installed and `COVERAGE_FORMATTER_JSON=true`)
330
+ - `sf hardis org test apex` (if sfdx-hardis installed)
430
331
 
431
- You can copy & update the sample [SFDX Hardis .apexcodecovtransformer.config.json](https://raw.githubusercontent.com/mcarvin8/apex-code-coverage-transformer/main/defaults/sfdx-hardis/.apexcodecovtransformer.config.json), which assumes you are running the SFDX Hardis commands.
332
+ Sample configs: [Salesforce CLI](https://raw.githubusercontent.com/mcarvin8/apex-code-coverage-transformer/main/defaults/salesforce-cli/.apexcodecovtransformer.config.json), [SFDX Hardis](https://raw.githubusercontent.com/mcarvin8/apex-code-coverage-transformer/main/defaults/sfdx-hardis/.apexcodecovtransformer.config.json).
432
333
 
433
- **`.apexcodecovtransformer.config.json` structure**
434
-
435
- | JSON Key | Required | Description |
436
- | -------------------------- | -------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
437
- | `deployCoverageJsonPath` | Yes (for deploy command) | Code coverage JSON created by the Salesforce CLI deploy commands. |
438
- | `testCoverageJsonPath` | Yes (for test command) | Code coverage JSON created by the Salesforce CLI test commands. |
439
- | `outputReportPath` | No (defaults to `coverage.[xml/info]`) | Transformed code coverage report path. |
440
- | `format` | No (defaults to `sonar`) | Transformed code coverage report [format(s)](#coverage-report-formats). If you're providing multiple formats, provide a comma-separated list, i.e. `sonar,cobertura,jacoco` |
441
- | `ignorePackageDirectories` | No | Comma-separated string of package directories to ignore when looking for matching Apex files. |
334
+ | Key | Required | Description |
335
+ | -------------------------- | ---------- | -------------------------------------------------------- |
336
+ | `deployCoverageJsonPath` | For deploy | Path to deploy coverage JSON. |
337
+ | `testCoverageJsonPath` | For test | Path to test coverage JSON. |
338
+ | `outputReportPath` | No | Output path (default: `coverage.[xml/info/json]` by format). |
339
+ | `format` | No | Format(s), comma-separated (default: `sonar`). |
340
+ | `ignorePackageDirectories` | No | Comma-separated package directories to ignore. |
442
341
 
443
342
  ## Troubleshooting
444
343
 
445
- If a file listed in the coverage JSON cannot be found in any package directory, a warning is displayed, and the file will not be included in the transformed report:
344
+ **File not in package directory** File is omitted from the report and a warning is shown:
446
345
 
447
346
  ```
448
347
  Warning: The file name AccountTrigger was not found in any package directory.
449
348
  ```
450
349
 
451
- If **none** of the files in the coverage JSON are found in a package directory, the plugin will print an additional warning, and the generated report will be empty:
350
+ **No files matched** Report will be empty:
452
351
 
453
352
  ```
454
- Warning: The file name AccountTrigger was not found in any package directory.
455
- Warning: The file name AccountProfile was not found in any package directory.
456
353
  Warning: None of the files listed in the coverage JSON were processed. The coverage report will be empty.
457
354
  ```
458
355
 
459
- Salesforce CLI generates code coverage JSONs in two different structures (deploy and test command formats). If the provided coverage JSON does not match one of these expected structures, the plugin will fail with:
356
+ **Unknown JSON structure** Input is not from deploy or test coverage:
460
357
 
461
358
  ```
462
359
  Error (1): The provided JSON does not match a known coverage data format from the Salesforce deploy or test command.
463
360
  ```
464
361
 
465
- If `sfdx-project.json` file is missing from the project root, the plugin will fail with:
362
+ **Missing project config** Run from a directory that has (or has a parent with) `sfdx-project.json`:
466
363
 
467
364
  ```
468
365
  Error (1): sfdx-project.json not found in any parent directory.
469
366
  ```
470
367
 
471
- If a package directory listed in `sfdx-project.json` cannot be found, the plugin will encounter a **ENOENT** error:
368
+ **Missing package directory** A path in `sfdx-project.json` does not exist:
472
369
 
473
370
  ```
474
371
  Error (1): ENOENT: no such file or directory: {packageDir}
475
372
  ```
476
373
 
477
- ## Issues
478
-
479
- If you encounter any issues or would like to suggest features, please create an [issue](https://github.com/mcarvin8/apex-code-coverage-transformer/issues).
480
-
481
374
  ## Contributing
482
375
 
483
- Contributions are welcome! See [Contributing](https://github.com/mcarvin8/apex-code-coverage-transformer/blob/main/CONTRIBUTING.md).
376
+ Contributions are welcome. See [CONTRIBUTING.md](https://github.com/mcarvin8/apex-code-coverage-transformer/blob/main/CONTRIBUTING.md) for setup, testing, and how to add new coverage formats.
484
377
 
485
378
  ## License
486
379
 
487
- This project is licensed under the MIT license. Please see the [LICENSE](https://raw.githubusercontent.com/mcarvin8/apex-code-coverage-transformer/main/LICENSE.md) file for details.
380
+ MIT. See [LICENSE](https://raw.githubusercontent.com/mcarvin8/apex-code-coverage-transformer/main/LICENSE.md).
@@ -1,4 +1,4 @@
1
- import { CoverageHandler, SonarCoverageObject, CoberturaCoverageObject, CloverCoverageObject, LcovCoverageObject, JaCoCoCoverageObject, IstanbulCoverageObject, JsonSummaryCoverageObject, SimpleCovCoverageObject, OpenCoverCoverageObject } from '../utils/types.js';
1
+ import { CoverageHandler, SonarCoverageObject, CoberturaCoverageObject, CloverCoverageObject, LcovCoverageObject, JaCoCoCoverageObject, IstanbulCoverageObject, JsonSummaryCoverageObject, SimpleCovCoverageObject, OpenCoverCoverageObject, HtmlCoverageObject } from '../utils/types.js';
2
2
  /**
3
3
  * Abstract base class for coverage handlers providing common utilities.
4
4
  * Reduces code duplication across different format handlers.
@@ -47,5 +47,5 @@ export declare abstract class BaseHandler implements CoverageHandler {
47
47
  '@name'?: string;
48
48
  }>(items: T[]): T[];
49
49
  abstract processFile(filePath: string, fileName: string, lines: Record<string, number>): void;
50
- abstract finalize(): SonarCoverageObject | CoberturaCoverageObject | CloverCoverageObject | LcovCoverageObject | JaCoCoCoverageObject | IstanbulCoverageObject | JsonSummaryCoverageObject | SimpleCovCoverageObject | OpenCoverCoverageObject;
50
+ abstract finalize(): SonarCoverageObject | CoberturaCoverageObject | CloverCoverageObject | LcovCoverageObject | JaCoCoCoverageObject | IstanbulCoverageObject | JsonSummaryCoverageObject | SimpleCovCoverageObject | OpenCoverCoverageObject | HtmlCoverageObject;
51
51
  }
@@ -1 +1 @@
1
- {"version":3,"file":"BaseHandler.js","sourceRoot":"","sources":["../../src/handlers/BaseHandler.ts"],"names":[],"mappings":"AAAA,YAAY,CAAC;AAeb;;;GAGG;AACH,MAAM,OAAgB,WAAW;IAC/B;;;;;OAKG;IACH,kDAAkD;IACxC,iBAAiB,CAAC,KAA6B;QAMvD,MAAM,cAAc,GAAG,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC;QAChF,MAAM,YAAY,GAAG,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC;QAC5E,MAAM,UAAU,GAAG,cAAc,GAAG,YAAY,CAAC;QACjD,MAAM,QAAQ,GAAG,UAAU,GAAG,CAAC,CAAC,CAAC,CAAC,YAAY,GAAG,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC;QAEhE,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,cAAc,EAAE,QAAQ,EAAE,CAAC;IAChE,CAAC;IAED;;;;;;OAMG;IACH,kDAAkD;IACxC,oBAAoB,CAAC,KAA6B,EAAE,OAAgB;QAC5E,OAAO,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC;aACzB,MAAM,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC;aACvD,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;aAC7B,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IAC3B,CAAC;IAED;;;;;OAKG;IACO,sBAAsB,CAAC,KAA6B;QAI5D,OAAO;YACL,OAAO,EAAE,IAAI,CAAC,oBAAoB,CAAC,KAAK,EAAE,IAAI,CAAC;YAC/C,SAAS,EAAE,IAAI,CAAC,oBAAoB,CAAC,KAAK,EAAE,KAAK,CAAC;SACnD,CAAC;IACJ,CAAC;IAED;;;;;;OAMG;IACH,kDAAkD;IACxC,UAAU,CAAyE,KAAU;QACrG,OAAO,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;YACzB,MAAM,KAAK,GAAG,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;YAC/D,MAAM,KAAK,GAAG,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;YAC/D,OAAO,KAAK,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;QACpC,CAAC,CAAC,CAAC;IACL,CAAC;CAcF"}
1
+ {"version":3,"file":"BaseHandler.js","sourceRoot":"","sources":["../../src/handlers/BaseHandler.ts"],"names":[],"mappings":"AAAA,YAAY,CAAC;AAgBb;;;GAGG;AACH,MAAM,OAAgB,WAAW;IAC/B;;;;;OAKG;IACH,kDAAkD;IACxC,iBAAiB,CAAC,KAA6B;QAMvD,MAAM,cAAc,GAAG,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC;QAChF,MAAM,YAAY,GAAG,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC;QAC5E,MAAM,UAAU,GAAG,cAAc,GAAG,YAAY,CAAC;QACjD,MAAM,QAAQ,GAAG,UAAU,GAAG,CAAC,CAAC,CAAC,CAAC,YAAY,GAAG,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC;QAEhE,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,cAAc,EAAE,QAAQ,EAAE,CAAC;IAChE,CAAC;IAED;;;;;;OAMG;IACH,kDAAkD;IACxC,oBAAoB,CAAC,KAA6B,EAAE,OAAgB;QAC5E,OAAO,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC;aACzB,MAAM,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC;aACvD,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;aAC7B,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IAC3B,CAAC;IAED;;;;;OAKG;IACO,sBAAsB,CAAC,KAA6B;QAI5D,OAAO;YACL,OAAO,EAAE,IAAI,CAAC,oBAAoB,CAAC,KAAK,EAAE,IAAI,CAAC;YAC/C,SAAS,EAAE,IAAI,CAAC,oBAAoB,CAAC,KAAK,EAAE,KAAK,CAAC;SACnD,CAAC;IACJ,CAAC;IAED;;;;;;OAMG;IACH,kDAAkD;IACxC,UAAU,CAAyE,KAAU;QACrG,OAAO,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;YACzB,MAAM,KAAK,GAAG,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;YAC/D,MAAM,KAAK,GAAG,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;YAC/D,OAAO,KAAK,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;QACpC,CAAC,CAAC,CAAC;IACL,CAAC;CAeF"}
@@ -8,6 +8,7 @@ import './istanbulJson.js';
8
8
  import './jsonSummary.js';
9
9
  import './simplecov.js';
10
10
  import './opencover.js';
11
+ import './html.js';
11
12
  /**
12
13
  * Get a coverage handler for the specified format.
13
14
  *
@@ -10,6 +10,7 @@ import './istanbulJson.js';
10
10
  import './jsonSummary.js';
11
11
  import './simplecov.js';
12
12
  import './opencover.js';
13
+ import './html.js';
13
14
  /**
14
15
  * Get a coverage handler for the specified format.
15
16
  *
@@ -1 +1 @@
1
- {"version":3,"file":"getHandler.js","sourceRoot":"","sources":["../../src/handlers/getHandler.ts"],"names":[],"mappings":"AAAA,YAAY,CAAC;AAGb,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAEvD,mDAAmD;AACnD,OAAO,YAAY,CAAC;AACpB,OAAO,gBAAgB,CAAC;AACxB,OAAO,aAAa,CAAC;AACrB,OAAO,WAAW,CAAC;AACnB,OAAO,aAAa,CAAC;AACrB,OAAO,mBAAmB,CAAC;AAC3B,OAAO,kBAAkB,CAAC;AAC1B,OAAO,gBAAgB,CAAC;AACxB,OAAO,gBAAgB,CAAC;AAExB;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,kBAAkB,CAAC,MAAc;IAC/C,OAAO,eAAe,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;AACrC,CAAC"}
1
+ {"version":3,"file":"getHandler.js","sourceRoot":"","sources":["../../src/handlers/getHandler.ts"],"names":[],"mappings":"AAAA,YAAY,CAAC;AAGb,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAEvD,mDAAmD;AACnD,OAAO,YAAY,CAAC;AACpB,OAAO,gBAAgB,CAAC;AACxB,OAAO,aAAa,CAAC;AACrB,OAAO,WAAW,CAAC;AACnB,OAAO,aAAa,CAAC;AACrB,OAAO,mBAAmB,CAAC;AAC3B,OAAO,kBAAkB,CAAC;AAC1B,OAAO,gBAAgB,CAAC;AACxB,OAAO,gBAAgB,CAAC;AACxB,OAAO,WAAW,CAAC;AAEnB;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,kBAAkB,CAAC,MAAc;IAC/C,OAAO,eAAe,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;AACrC,CAAC"}