apex-code-coverage-transformer 2.22.1 → 2.23.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 +14 -0
- package/README.md +148 -9
- package/lib/commands/acc-transformer/transform.d.ts +1 -1
- package/lib/commands/acc-transformer/transform.js +3 -2
- package/lib/commands/acc-transformer/transform.js.map +1 -1
- package/lib/handlers/BaseHandler.d.ts +1 -1
- package/lib/hooks/finally.js +1 -1
- package/lib/hooks/finally.js.map +1 -1
- package/lib/transformers/coverageDataMerger.d.ts +3 -0
- package/lib/transformers/coverageDataMerger.js +38 -0
- package/lib/transformers/coverageDataMerger.js.map +1 -0
- package/lib/transformers/coverageProcessor.d.ts +6 -0
- package/lib/transformers/coverageProcessor.js +87 -0
- package/lib/transformers/coverageProcessor.js.map +1 -0
- package/lib/transformers/coverageTransformer.d.ts +3 -6
- package/lib/transformers/coverageTransformer.js +22 -109
- package/lib/transformers/coverageTransformer.js.map +1 -1
- package/lib/transformers/reportGenerator.js +2 -2
- package/lib/transformers/reportGenerator.js.map +1 -1
- package/lib/utils/getPackageDirectories.js.map +1 -1
- package/lib/utils/getRepoRoot.js +3 -3
- package/lib/utils/getRepoRoot.js.map +1 -1
- package/lib/utils/readJson.d.ts +1 -0
- package/lib/utils/readJson.js +12 -0
- package/lib/utils/readJson.js.map +1 -0
- package/lib/utils/types.d.ts +13 -0
- package/messages/transformer.transform.md +2 -1
- package/oclif.manifest.json +5 -4
- package/package.json +97 -79
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.23.1](https://github.com/mcarvin8/apex-code-coverage-transformer/compare/v2.23.0...v2.23.1) (2026-06-29)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
### Bug Fixes
|
|
12
|
+
|
|
13
|
+
* **deps:** update all deps, drop Node 20 support ([#323](https://github.com/mcarvin8/apex-code-coverage-transformer/issues/323)) ([a172ba5](https://github.com/mcarvin8/apex-code-coverage-transformer/commit/a172ba53c3dd7dc4521cbf13f70392c0b6f29bd3))
|
|
14
|
+
|
|
15
|
+
## [2.23.0](https://github.com/mcarvin8/apex-code-coverage-transformer/compare/v2.22.1...v2.23.0) (2026-06-17)
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
### Features
|
|
19
|
+
|
|
20
|
+
* support multiple coverage JSON inputs with union merge ([#317](https://github.com/mcarvin8/apex-code-coverage-transformer/issues/317)) ([43ccda6](https://github.com/mcarvin8/apex-code-coverage-transformer/commit/43ccda6c2542cbb0be36faba37682a23b76758b8))
|
|
21
|
+
|
|
8
22
|
## [2.22.1](https://github.com/mcarvin8/apex-code-coverage-transformer/compare/v2.22.0...v2.22.1) (2026-06-15)
|
|
9
23
|
|
|
10
24
|
|
package/README.md
CHANGED
|
@@ -7,9 +7,7 @@
|
|
|
7
7
|
[](https://codecov.io/gh/mcarvin8/apex-code-coverage-transformer)
|
|
8
8
|
[](https://dashboard.stryker-mutator.io/reports/github.com/mcarvin8/apex-code-coverage-transformer/main)
|
|
9
9
|
|
|
10
|
-
A Salesforce CLI plugin that
|
|
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).
|
|
10
|
+
A Salesforce CLI plugin that transforms (and optionally merges) Apex code coverage JSON from deployments or test runs into formats used by SonarQube, Codecov, GitHub, GitLab, Azure DevOps, Bitbucket, and other tools, keeping coverage visible across pull requests, CI/CD pipelines, and code quality platforms.
|
|
13
11
|
|
|
14
12
|
<details>
|
|
15
13
|
<summary>Table of Contents</summary>
|
|
@@ -23,6 +21,8 @@ A Salesforce CLI plugin that converts Apex code coverage JSON (from deploy or te
|
|
|
23
21
|
- [CI/CD Integration](#cicd-integration)
|
|
24
22
|
- [Automatic Transformation (Hook)](#automatic-transformation-hook)
|
|
25
23
|
- [Troubleshooting](#troubleshooting)
|
|
24
|
+
- [Questions or Issues?](#questions-or-issues)
|
|
25
|
+
- [License](#license)
|
|
26
26
|
|
|
27
27
|
</details>
|
|
28
28
|
|
|
@@ -69,6 +69,9 @@ sf plugins install apex-code-coverage-transformer@latest
|
|
|
69
69
|
|
|
70
70
|
# Multiple formats at once
|
|
71
71
|
sf acc-transformer transform -j "coverage/test-result-codecoverage.json" -f "sonar" -f "cobertura" -f "jacoco"
|
|
72
|
+
|
|
73
|
+
# Merge multiple coverage JSONs of the same type (e.g. two deploy runs)
|
|
74
|
+
sf acc-transformer transform -j "coverage/coverage/coverage.json" -j "coverage2/coverage/coverage.json" -r "coverage.xml" -f "sonar"
|
|
72
75
|
```
|
|
73
76
|
|
|
74
77
|
3. **Upload to your tool** — see [CI/CD Integration](#cicd-integration).
|
|
@@ -111,11 +114,16 @@ Works with [sfdx-hardis](https://github.com/hardisgroupcom/sfdx-hardis):
|
|
|
111
114
|
|
|
112
115
|
```
|
|
113
116
|
USAGE
|
|
114
|
-
$ sf acc-transformer transform -j <value
|
|
115
|
-
|
|
117
|
+
$ sf acc-transformer transform -j <value>... [-r <value>] [-f <value>] [-i <value>] [-e <value>]
|
|
118
|
+
[--min-coverage <value>] [--max-annotations <value>] [--json]
|
|
116
119
|
|
|
117
120
|
FLAGS
|
|
118
|
-
-j, --coverage-json=<value
|
|
121
|
+
-j, --coverage-json=<value>... Path to a code coverage JSON from deploy or test. Repeat to merge
|
|
122
|
+
multiple files. When the same Apex file appears in more than one
|
|
123
|
+
input, covered lines are unioned across all inputs — if a line is
|
|
124
|
+
covered in any input it is counted as covered in the final report,
|
|
125
|
+
even if it is uncovered in others. All files must be the same type
|
|
126
|
+
(deploy or test).
|
|
119
127
|
-r, --output-report=<value> Output path (e.g. coverage.xml). Default: coverage.[xml|info] by format.
|
|
120
128
|
-f, --format=<value> Output format (repeat for multiple). Default: sonar.
|
|
121
129
|
Multiple formats append to filename, e.g. coverage-sonar.xml.
|
|
@@ -136,7 +144,7 @@ GLOBAL FLAGS
|
|
|
136
144
|
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`).
|
|
137
145
|
|
|
138
146
|
| Format | Description | Typical use | Example |
|
|
139
|
-
|
|
147
|
+
|----------------|----------------------------|-----------------------------------------|-----------------------------------------------------------------------------------------|
|
|
140
148
|
| sonar | SonarQube generic coverage | SonarQube, SonarCloud | `sf acc-transformer transform -j "coverage.json" -r "coverage.xml" -f "sonar"` |
|
|
141
149
|
| cobertura | Cobertura XML | Codecov, Azure, Jenkins, GitLab, GitHub | `sf acc-transformer transform -j "coverage.json" -r "coverage.xml" -f "cobertura"` |
|
|
142
150
|
| jacoco | JaCoCo XML | Codecov, Jenkins, Maven, Gradle | `sf acc-transformer transform -j "coverage.json" -r "coverage.xml" -f "jacoco"` |
|
|
@@ -264,6 +272,86 @@ The `github-actions` format emits one [`::warning`](https://docs.github.com/en/a
|
|
|
264
272
|
|
|
265
273
|
Pairs with [`sf-cat`](https://www.github.com/mcarvin8/sf-cat) for code quality annotations on the same diff if you use Salesforce Code Analyzer.
|
|
266
274
|
|
|
275
|
+
#### Merging coverage from parallel test suites
|
|
276
|
+
|
|
277
|
+
If you split Apex tests across parallel jobs (e.g. by test class grouping or suite), upload each run's JSON as an artifact and merge them in a final step. Covered lines are unioned — a line covered in any suite counts as covered in the final report.
|
|
278
|
+
|
|
279
|
+
```yaml
|
|
280
|
+
jobs:
|
|
281
|
+
test-suite-a:
|
|
282
|
+
runs-on: ubuntu-latest
|
|
283
|
+
steps:
|
|
284
|
+
- uses: actions/checkout@v4
|
|
285
|
+
with:
|
|
286
|
+
fetch-depth: 0
|
|
287
|
+
# ... shared setup steps (Node, SF CLI, auth) ...
|
|
288
|
+
- name: Run Suite A
|
|
289
|
+
run: sf apex run test --code-coverage --output-dir coverage-a --target-org ci-org
|
|
290
|
+
- name: Upload Suite A coverage
|
|
291
|
+
uses: actions/upload-artifact@v4
|
|
292
|
+
with:
|
|
293
|
+
name: coverage-a
|
|
294
|
+
path: coverage-a/test-result-codecoverage.json
|
|
295
|
+
|
|
296
|
+
test-suite-b:
|
|
297
|
+
runs-on: ubuntu-latest
|
|
298
|
+
steps:
|
|
299
|
+
- uses: actions/checkout@v4
|
|
300
|
+
with:
|
|
301
|
+
fetch-depth: 0
|
|
302
|
+
# ... shared setup steps ...
|
|
303
|
+
- name: Run Suite B
|
|
304
|
+
run: sf apex run test --code-coverage --output-dir coverage-b --target-org ci-org
|
|
305
|
+
- name: Upload Suite B coverage
|
|
306
|
+
uses: actions/upload-artifact@v4
|
|
307
|
+
with:
|
|
308
|
+
name: coverage-b
|
|
309
|
+
path: coverage-b/test-result-codecoverage.json
|
|
310
|
+
|
|
311
|
+
merge-coverage:
|
|
312
|
+
runs-on: ubuntu-latest
|
|
313
|
+
needs: [test-suite-a, test-suite-b]
|
|
314
|
+
steps:
|
|
315
|
+
- uses: actions/checkout@v4
|
|
316
|
+
with:
|
|
317
|
+
fetch-depth: 0
|
|
318
|
+
- uses: actions/setup-node@v4
|
|
319
|
+
with:
|
|
320
|
+
node-version: '20'
|
|
321
|
+
- run: npm install -g @salesforce/cli@latest
|
|
322
|
+
- run: echo y | sf plugins install apex-code-coverage-transformer
|
|
323
|
+
- name: Download Suite A coverage
|
|
324
|
+
uses: actions/download-artifact@v4
|
|
325
|
+
with:
|
|
326
|
+
name: coverage-a
|
|
327
|
+
path: coverage-a
|
|
328
|
+
- name: Download Suite B coverage
|
|
329
|
+
uses: actions/download-artifact@v4
|
|
330
|
+
with:
|
|
331
|
+
name: coverage-b
|
|
332
|
+
path: coverage-b
|
|
333
|
+
- name: Merge and transform coverage
|
|
334
|
+
run: |
|
|
335
|
+
sf acc-transformer transform \
|
|
336
|
+
-j "coverage-a/test-result-codecoverage.json" \
|
|
337
|
+
-j "coverage-b/test-result-codecoverage.json" \
|
|
338
|
+
-r "coverage.xml" \
|
|
339
|
+
-f "sonar"
|
|
340
|
+
- name: SonarCloud Scan
|
|
341
|
+
uses: SonarSource/sonarcloud-github-action@master
|
|
342
|
+
env:
|
|
343
|
+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
344
|
+
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
|
|
345
|
+
with:
|
|
346
|
+
args: >
|
|
347
|
+
-Dsonar.projectKey=your-project-key
|
|
348
|
+
-Dsonar.organization=your-org
|
|
349
|
+
-Dsonar.sources=force-app
|
|
350
|
+
-Dsonar.coverageReportPaths=coverage.xml
|
|
351
|
+
```
|
|
352
|
+
|
|
353
|
+
Swap the final upload step for any tool from the [Codecov](#codecov) or [GitHub Actions](#github-actions) examples above — the merge command stays the same regardless of destination.
|
|
354
|
+
|
|
267
355
|
### GitLab CI
|
|
268
356
|
|
|
269
357
|
```yaml
|
|
@@ -301,6 +389,45 @@ apex-tests:
|
|
|
301
389
|
path: coverage.xml
|
|
302
390
|
```
|
|
303
391
|
|
|
392
|
+
### Azure DevOps
|
|
393
|
+
|
|
394
|
+
```yaml
|
|
395
|
+
trigger:
|
|
396
|
+
- main
|
|
397
|
+
|
|
398
|
+
pool:
|
|
399
|
+
vmImage: ubuntu-latest
|
|
400
|
+
|
|
401
|
+
steps:
|
|
402
|
+
- task: NodeTool@0
|
|
403
|
+
inputs:
|
|
404
|
+
versionSpec: '20.x'
|
|
405
|
+
displayName: Set up Node.js
|
|
406
|
+
|
|
407
|
+
- script: npm install -g @salesforce/cli@latest
|
|
408
|
+
displayName: Install Salesforce CLI
|
|
409
|
+
|
|
410
|
+
- script: echo y | sf plugins install apex-code-coverage-transformer
|
|
411
|
+
displayName: Install Apex Code Coverage Transformer
|
|
412
|
+
|
|
413
|
+
- script: echo $(SFDX_AUTH_URL) | sf org login sfdx-url --sfdx-url-stdin --alias ci-org
|
|
414
|
+
displayName: Authenticate to Salesforce
|
|
415
|
+
|
|
416
|
+
- script: sf apex run test --code-coverage --output-dir coverage --target-org ci-org
|
|
417
|
+
displayName: Run Apex Tests
|
|
418
|
+
|
|
419
|
+
- script: sf acc-transformer transform -j "coverage/test-result-codecoverage.json" -r "coverage.xml" -f "cobertura"
|
|
420
|
+
displayName: Transform Coverage to Cobertura
|
|
421
|
+
|
|
422
|
+
- task: PublishCodeCoverageResults@2
|
|
423
|
+
inputs:
|
|
424
|
+
summaryFileLocation: coverage.xml
|
|
425
|
+
pathToSources: $(Build.SourcesDirectory)
|
|
426
|
+
displayName: Publish Coverage to Azure DevOps
|
|
427
|
+
```
|
|
428
|
+
|
|
429
|
+
Set `SFDX_AUTH_URL` as a secret pipeline variable. Coverage appears in the pipeline's **Code Coverage** tab.
|
|
430
|
+
|
|
304
431
|
## Automatic Transformation (Hook)
|
|
305
432
|
|
|
306
433
|
Create `.apexcodecovtransformer.config.json` in the project root to transform coverage automatically after:
|
|
@@ -311,10 +438,12 @@ Create `.apexcodecovtransformer.config.json` in the project root to transform co
|
|
|
311
438
|
- `sf hardis project deploy smart` (if sfdx-hardis installed and `COVERAGE_FORMATTER_JSON=true`)
|
|
312
439
|
- `sf hardis org test apex` (if sfdx-hardis installed)
|
|
313
440
|
|
|
441
|
+
> **Note:** The hook fires once per command and always processes a single coverage JSON. It cannot merge multiple inputs. If you need to merge coverage from multiple runs (e.g. split test batches), run the `sf acc-transformer transform` command manually with multiple `-j` flags after all runs complete.
|
|
442
|
+
|
|
314
443
|
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).
|
|
315
444
|
|
|
316
445
|
| Key | Required | Description |
|
|
317
|
-
|
|
446
|
+
|----------------------------|------------|----------------------------------------------------------------------------------------------------------------------------------------------|
|
|
318
447
|
| `deployCoverageJsonPath` | For deploy | Path to deploy coverage JSON. |
|
|
319
448
|
| `testCoverageJsonPath` | For test | Path to test coverage JSON. |
|
|
320
449
|
| `outputReportPath` | No | Output path (default: `coverage.[xml/info/json]` by format). |
|
|
@@ -346,6 +475,12 @@ Resolve by renaming one of the files or using `--ignore-package-directory` to ex
|
|
|
346
475
|
Warning: None of the files listed in the coverage JSON were processed. The coverage report will be empty.
|
|
347
476
|
```
|
|
348
477
|
|
|
478
|
+
**Mixed coverage types** — All `-j` inputs must be the same type (either all deploy or all test):
|
|
479
|
+
|
|
480
|
+
```
|
|
481
|
+
Error (1): All coverage JSON files must be the same type (deploy or test).
|
|
482
|
+
```
|
|
483
|
+
|
|
349
484
|
**Unknown JSON structure** — Input is not from deploy or test coverage:
|
|
350
485
|
|
|
351
486
|
```
|
|
@@ -386,6 +521,10 @@ The coverage report has been written to: coverage.xml
|
|
|
386
521
|
[16:10:20.826] DEBUG (sf:setCoveredLines): Remapping out-of-range covered line 190 to line 1 in force-app/main/default/triggers/AccountTrigger.trigger (file has 105 lines)
|
|
387
522
|
```
|
|
388
523
|
|
|
524
|
+
## Questions or Issues?
|
|
525
|
+
|
|
526
|
+
Questions, issues? Missing an output format via `--format`? Open an [issue](https://github.com/mcarvin8/apex-code-coverage-transformer/issues).
|
|
527
|
+
|
|
389
528
|
## License
|
|
390
529
|
|
|
391
|
-
[MIT](
|
|
530
|
+
[MIT](LICENSE.md)
|
|
@@ -5,7 +5,7 @@ export default class TransformerTransform extends SfCommand<TransformerTransform
|
|
|
5
5
|
static readonly description: string;
|
|
6
6
|
static readonly examples: string[];
|
|
7
7
|
static readonly flags: {
|
|
8
|
-
'coverage-json': import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
|
|
8
|
+
'coverage-json': import("@oclif/core/interfaces").OptionFlag<string[], import("@oclif/core/interfaces").CustomOptions>;
|
|
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>;
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
'use strict';
|
|
2
|
-
import { SfCommand, Flags } from '@salesforce/sf-plugins-core';
|
|
3
2
|
import { Messages } from '@salesforce/core';
|
|
3
|
+
import { Flags, SfCommand } from '@salesforce/sf-plugins-core';
|
|
4
4
|
import { transformCoverageReport } from '../../transformers/coverageTransformer.js';
|
|
5
|
-
import { formatOptions } from '../../utils/constants.js';
|
|
6
5
|
import { DEFAULT_MAX_ANNOTATIONS } from '../../transformers/generators/generateGitHubActions.js';
|
|
6
|
+
import { formatOptions } from '../../utils/constants.js';
|
|
7
7
|
Messages.importMessagesDirectoryFromMetaUrl(import.meta.url);
|
|
8
8
|
const messages = Messages.loadMessages('apex-code-coverage-transformer', 'transformer.transform');
|
|
9
9
|
export default class TransformerTransform extends SfCommand {
|
|
@@ -15,6 +15,7 @@ export default class TransformerTransform extends SfCommand {
|
|
|
15
15
|
summary: messages.getMessage('flags.coverage-json.summary'),
|
|
16
16
|
char: 'j',
|
|
17
17
|
required: true,
|
|
18
|
+
multiple: true,
|
|
18
19
|
}),
|
|
19
20
|
'output-report': Flags.file({
|
|
20
21
|
summary: messages.getMessage('flags.output-report.summary'),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"transform.js","sourceRoot":"","sources":["../../../src/commands/acc-transformer/transform.ts"],"names":[],"mappings":"AAAA,YAAY,CAAC;AAEb,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"transform.js","sourceRoot":"","sources":["../../../src/commands/acc-transformer/transform.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { CloverCoverageObject, CoberturaCoverageObject, CoverageHandler, GitHubActionsCoverageObject, HtmlCoverageObject, IstanbulCoverageObject, JaCoCoCoverageObject, JsonSummaryCoverageObject, LcovCoverageObject, MarkdownCoverageObject, OpenCoverCoverageObject, SimpleCovCoverageObject, SonarCoverageObject } 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.
|
package/lib/hooks/finally.js
CHANGED
|
@@ -60,7 +60,7 @@ export const hook = async function (options) {
|
|
|
60
60
|
const jsonString = await readFile(configPath, 'utf-8');
|
|
61
61
|
configFile = JSON.parse(jsonString);
|
|
62
62
|
}
|
|
63
|
-
catch
|
|
63
|
+
catch {
|
|
64
64
|
return;
|
|
65
65
|
}
|
|
66
66
|
const outputReport = configFile.outputReportPath || 'coverage.xml';
|
package/lib/hooks/finally.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"finally.js","sourceRoot":"","sources":["../../src/hooks/finally.ts"],"names":[],"mappings":"AAAA,YAAY,CAAC;AAEb,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAGpC,OAAO,oBAAoB,MAAM,0CAA0C,CAAC;
|
|
1
|
+
{"version":3,"file":"finally.js","sourceRoot":"","sources":["../../src/hooks/finally.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
export function mergeDeployCoverageData(inputs) {
|
|
3
|
+
const merged = {};
|
|
4
|
+
for (const input of inputs) {
|
|
5
|
+
for (const [className, fileInfo] of Object.entries(input)) {
|
|
6
|
+
if (!merged[className]) {
|
|
7
|
+
merged[className] = { ...fileInfo, s: { ...fileInfo.s } };
|
|
8
|
+
}
|
|
9
|
+
else {
|
|
10
|
+
for (const [line, hit] of Object.entries(fileInfo.s)) {
|
|
11
|
+
merged[className].s[line] = Math.max(merged[className].s[line] ?? 0, hit);
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
return merged;
|
|
17
|
+
}
|
|
18
|
+
export function mergeTestCoverageData(inputs) {
|
|
19
|
+
const byName = new Map();
|
|
20
|
+
for (const input of inputs) {
|
|
21
|
+
for (const entry of input) {
|
|
22
|
+
if (!byName.has(entry.name)) {
|
|
23
|
+
byName.set(entry.name, { ...entry, lines: { ...entry.lines } });
|
|
24
|
+
}
|
|
25
|
+
else {
|
|
26
|
+
const existing = byName.get(entry.name);
|
|
27
|
+
for (const [line, hit] of Object.entries(entry.lines)) {
|
|
28
|
+
existing.lines[line] = Math.max(existing.lines[line] ?? 0, hit);
|
|
29
|
+
}
|
|
30
|
+
existing.totalLines = Object.keys(existing.lines).length;
|
|
31
|
+
existing.totalCovered = Object.values(existing.lines).filter((v) => v === 1).length;
|
|
32
|
+
existing.coveredPercent = existing.totalLines > 0 ? (existing.totalCovered / existing.totalLines) * 100 : 0;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
return [...byName.values()];
|
|
37
|
+
}
|
|
38
|
+
//# sourceMappingURL=coverageDataMerger.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"coverageDataMerger.js","sourceRoot":"","sources":["../../src/transformers/coverageDataMerger.ts"],"names":[],"mappings":"AAAA,YAAY,CAAC;AAIb,MAAM,UAAU,uBAAuB,CAAC,MAA4B;IAClE,MAAM,MAAM,GAAuB,EAAE,CAAC;IACtC,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC3B,KAAK,MAAM,CAAC,SAAS,EAAE,QAAQ,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;YAC1D,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,EAAE,CAAC;gBACvB,MAAM,CAAC,SAAS,CAAC,GAAG,EAAE,GAAG,QAAQ,EAAE,CAAC,EAAE,EAAE,GAAG,QAAQ,CAAC,CAAC,EAAE,EAAE,CAAC;YAC5D,CAAC;iBAAM,CAAC;gBACN,KAAK,MAAM,CAAC,IAAI,EAAE,GAAG,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC;oBACrD,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,GAAG,CAAC,CAAC;gBAC5E,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,MAAM,UAAU,qBAAqB,CAAC,MAA4B;IAChE,MAAM,MAAM,GAAG,IAAI,GAAG,EAA4B,CAAC;IACnD,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC3B,KAAK,MAAM,KAAK,IAAI,KAAK,EAAE,CAAC;YAC1B,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;gBAC5B,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,EAAE,EAAE,GAAG,KAAK,EAAE,KAAK,EAAE,EAAE,GAAG,KAAK,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;YAClE,CAAC;iBAAM,CAAC;gBACN,MAAM,QAAQ,GAAG,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAE,CAAC;gBACzC,KAAK,MAAM,CAAC,IAAI,EAAE,GAAG,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC;oBACtD,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,GAAG,CAAC,CAAC;gBAClE,CAAC;gBACD,QAAQ,CAAC,UAAU,GAAG,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC;gBACzD,QAAQ,CAAC,YAAY,GAAG,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC;gBACpF,QAAQ,CAAC,cAAc,GAAG,QAAQ,CAAC,UAAU,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,YAAY,GAAG,QAAQ,CAAC,UAAU,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;YAC9G,CAAC;QACH,CAAC;IACH,CAAC;IACD,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC;AAC9B,CAAC"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { getCoverageHandler } from '../handlers/getHandler.js';
|
|
2
|
+
import { CoverageProcessingContext, DeployCoverageData, LineTotals, ProcessResult, TestCoverageData } from '../utils/types.js';
|
|
3
|
+
export declare function createHandlers(formats: string[]): Map<string, ReturnType<typeof getCoverageHandler>>;
|
|
4
|
+
export declare function countLines(lines: Record<string, number>): LineTotals;
|
|
5
|
+
export declare function processDeployCoverage(data: DeployCoverageData, context: CoverageProcessingContext): Promise<ProcessResult>;
|
|
6
|
+
export declare function processTestCoverage(data: TestCoverageData[], context: CoverageProcessingContext): Promise<ProcessResult>;
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
/* eslint-disable no-await-in-loop */
|
|
2
|
+
'use strict';
|
|
3
|
+
import { readFile } from 'node:fs/promises';
|
|
4
|
+
import { join } from 'node:path';
|
|
5
|
+
import { getCoverageHandler } from '../handlers/getHandler.js';
|
|
6
|
+
import { findFilePath } from '../utils/findFilePath.js';
|
|
7
|
+
import { matchesGlob } from '../utils/globMatcher.js';
|
|
8
|
+
import { mapLimit } from '../utils/mapLimit.js';
|
|
9
|
+
import { setCoveredLines } from '../utils/setCoveredLines.js';
|
|
10
|
+
export function createHandlers(formats) {
|
|
11
|
+
const handlers = new Map();
|
|
12
|
+
for (const format of formats) {
|
|
13
|
+
handlers.set(format, getCoverageHandler(format));
|
|
14
|
+
}
|
|
15
|
+
return handlers;
|
|
16
|
+
}
|
|
17
|
+
function hasSourceContent(result) {
|
|
18
|
+
return typeof result === 'object' && result !== null && 'sourceContent' in result;
|
|
19
|
+
}
|
|
20
|
+
async function readSourceFile(absolutePath) {
|
|
21
|
+
try {
|
|
22
|
+
return await readFile(absolutePath, 'utf-8');
|
|
23
|
+
}
|
|
24
|
+
catch {
|
|
25
|
+
return undefined;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
export function countLines(lines) {
|
|
29
|
+
const totalLines = Object.keys(lines).length;
|
|
30
|
+
const coveredLines = Object.values(lines).filter((v) => v === 1).length;
|
|
31
|
+
return { totalLines, coveredLines };
|
|
32
|
+
}
|
|
33
|
+
export async function processDeployCoverage(data, context) {
|
|
34
|
+
let processed = 0;
|
|
35
|
+
let totalLines = 0;
|
|
36
|
+
let coveredLines = 0;
|
|
37
|
+
await mapLimit(Object.keys(data), context.concurrencyLimit, async (fileName) => {
|
|
38
|
+
const fileInfo = data[fileName];
|
|
39
|
+
const formattedName = fileName.replace(/no-map[\\/]+/, '');
|
|
40
|
+
const path = findFilePath(formattedName, context.filePathCache);
|
|
41
|
+
if (!path) {
|
|
42
|
+
context.warnings.push(`The file name ${formattedName} was not found in any package directory.`);
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
if (context.excludePatterns.some((pattern) => matchesGlob(path, pattern, { matchBase: true }))) {
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
const setCoveredResult = await setCoveredLines(path, context.repoRoot, fileInfo.s, context.handlers.has('html'));
|
|
49
|
+
const updatedLines = hasSourceContent(setCoveredResult) ? setCoveredResult.updatedLines : setCoveredResult;
|
|
50
|
+
const sourceContent = hasSourceContent(setCoveredResult) ? setCoveredResult.sourceContent : undefined;
|
|
51
|
+
fileInfo.s = updatedLines;
|
|
52
|
+
const counts = countLines(updatedLines);
|
|
53
|
+
totalLines += counts.totalLines;
|
|
54
|
+
coveredLines += counts.coveredLines;
|
|
55
|
+
for (const handler of context.handlers.values()) {
|
|
56
|
+
handler.processFile(path, formattedName, updatedLines, sourceContent);
|
|
57
|
+
}
|
|
58
|
+
processed++;
|
|
59
|
+
});
|
|
60
|
+
return { processed, totalLines, coveredLines };
|
|
61
|
+
}
|
|
62
|
+
export async function processTestCoverage(data, context) {
|
|
63
|
+
let processed = 0;
|
|
64
|
+
let totalLines = 0;
|
|
65
|
+
let coveredLines = 0;
|
|
66
|
+
await mapLimit(data, context.concurrencyLimit, async (entry) => {
|
|
67
|
+
const formattedName = entry.name.replace(/no-map[\\/]+/, '');
|
|
68
|
+
const path = findFilePath(formattedName, context.filePathCache);
|
|
69
|
+
if (!path) {
|
|
70
|
+
context.warnings.push(`The file name ${formattedName} was not found in any package directory.`);
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
if (context.excludePatterns.some((pattern) => matchesGlob(path, pattern, { matchBase: true }))) {
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
const counts = countLines(entry.lines);
|
|
77
|
+
totalLines += counts.totalLines;
|
|
78
|
+
coveredLines += counts.coveredLines;
|
|
79
|
+
const sourceContent = context.handlers.has('html') ? await readSourceFile(join(context.repoRoot, path)) : undefined;
|
|
80
|
+
for (const handler of context.handlers.values()) {
|
|
81
|
+
handler.processFile(path, formattedName, entry.lines, sourceContent);
|
|
82
|
+
}
|
|
83
|
+
processed++;
|
|
84
|
+
});
|
|
85
|
+
return { processed, totalLines, coveredLines };
|
|
86
|
+
}
|
|
87
|
+
//# sourceMappingURL=coverageProcessor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"coverageProcessor.js","sourceRoot":"","sources":["../../src/transformers/coverageProcessor.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,9 +1,6 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
excludePatterns?: string[];
|
|
5
|
-
};
|
|
6
|
-
export declare function transformCoverageReport(jsonFilePath: string, outputReportPath: string, formats: string[], ignoreDirs: string[], options?: TransformOptions): Promise<{
|
|
1
|
+
import { TransformOptions } from '../utils/types.js';
|
|
2
|
+
export { TransformOptions };
|
|
3
|
+
export declare function transformCoverageReport(jsonFilePaths: string[], outputReportPath: string, formats: string[], ignoreDirs: string[], options?: TransformOptions): Promise<{
|
|
7
4
|
finalPaths: string[];
|
|
8
5
|
warnings: string[];
|
|
9
6
|
lineRate: number;
|
|
@@ -1,27 +1,33 @@
|
|
|
1
1
|
/* eslint-disable no-await-in-loop */
|
|
2
|
-
|
|
3
|
-
import { join } from 'node:path';
|
|
4
|
-
import { matchesGlob } from '../utils/globMatcher.js';
|
|
5
|
-
import { getCoverageHandler } from '../handlers/getHandler.js';
|
|
6
|
-
import { getPackageDirectories } from '../utils/getPackageDirectories.js';
|
|
7
|
-
import { findFilePath } from '../utils/findFilePath.js';
|
|
2
|
+
'use strict';
|
|
8
3
|
import { buildFilePathCache } from '../utils/buildFilePathCache.js';
|
|
9
|
-
import { setCoveredLines } from '../utils/setCoveredLines.js';
|
|
10
4
|
import { getConcurrencyThreshold } from '../utils/getConcurrencyThreshold.js';
|
|
5
|
+
import { getPackageDirectories } from '../utils/getPackageDirectories.js';
|
|
6
|
+
import { tryReadJson } from '../utils/readJson.js';
|
|
11
7
|
import { checkCoverageDataType } from '../utils/setCoverageDataType.js';
|
|
12
|
-
import {
|
|
8
|
+
import { mergeDeployCoverageData, mergeTestCoverageData } from './coverageDataMerger.js';
|
|
9
|
+
import { createHandlers, processDeployCoverage, processTestCoverage } from './coverageProcessor.js';
|
|
13
10
|
import { generateAndWriteReport } from './reportGenerator.js';
|
|
14
|
-
export async function transformCoverageReport(
|
|
11
|
+
export async function transformCoverageReport(jsonFilePaths, outputReportPath, formats, ignoreDirs, options) {
|
|
15
12
|
const warnings = [];
|
|
16
13
|
const finalPaths = [];
|
|
17
14
|
const formatAmount = formats.length;
|
|
18
|
-
const
|
|
19
|
-
|
|
15
|
+
const jsonDataItems = await Promise.all(jsonFilePaths.map((p) => tryReadJson(p, warnings)));
|
|
16
|
+
const validData = jsonDataItems.filter((d) => d !== null);
|
|
17
|
+
if (validData.length === 0)
|
|
20
18
|
return { finalPaths: [outputReportPath], warnings, lineRate: 0 };
|
|
21
|
-
const
|
|
19
|
+
const parsedItems = validData.map((d) => JSON.parse(d));
|
|
20
|
+
const types = parsedItems.map(checkCoverageDataType);
|
|
21
|
+
if (types.some((t) => t === 'Unknown')) {
|
|
22
|
+
throw new Error('The provided JSON does not match a known coverage data format from the Salesforce deploy or test command.');
|
|
23
|
+
}
|
|
24
|
+
const uniqueTypes = [...new Set(types)];
|
|
25
|
+
if (uniqueTypes.length > 1) {
|
|
26
|
+
throw new Error('All coverage JSON files must be the same type (deploy or test).');
|
|
27
|
+
}
|
|
28
|
+
const commandType = uniqueTypes[0];
|
|
22
29
|
const { repoRoot, packageDirectories } = await getPackageDirectories(ignoreDirs);
|
|
23
30
|
const handlers = createHandlers(formats);
|
|
24
|
-
const commandType = checkCoverageDataType(parsedData);
|
|
25
31
|
const concurrencyLimit = getConcurrencyThreshold();
|
|
26
32
|
// Build file path cache upfront to avoid O(n*m) directory traversals
|
|
27
33
|
const { cache: filePathCache, warnings: cacheWarnings } = await buildFilePathCache(packageDirectories, repoRoot);
|
|
@@ -35,16 +41,9 @@ export async function transformCoverageReport(jsonFilePath, outputReportPath, fo
|
|
|
35
41
|
filePathCache,
|
|
36
42
|
excludePatterns: options?.excludePatterns ?? [],
|
|
37
43
|
};
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
}
|
|
42
|
-
else if (commandType === 'TestCoverageData') {
|
|
43
|
-
processResult = await processTestCoverage(parsedData, context);
|
|
44
|
-
}
|
|
45
|
-
else {
|
|
46
|
-
throw new Error('The provided JSON does not match a known coverage data format from the Salesforce deploy or test command.');
|
|
47
|
-
}
|
|
44
|
+
const processResult = commandType === 'DeployCoverageData'
|
|
45
|
+
? await processDeployCoverage(mergeDeployCoverageData(parsedItems), context)
|
|
46
|
+
: await processTestCoverage(mergeTestCoverageData(parsedItems), context);
|
|
48
47
|
if (processResult.processed === 0) {
|
|
49
48
|
warnings.push('None of the files listed in the coverage JSON were processed. The coverage report will be empty.');
|
|
50
49
|
}
|
|
@@ -60,90 +59,4 @@ export async function transformCoverageReport(jsonFilePath, outputReportPath, fo
|
|
|
60
59
|
}
|
|
61
60
|
return { finalPaths, warnings, lineRate };
|
|
62
61
|
}
|
|
63
|
-
function hasSourceContent(result) {
|
|
64
|
-
return typeof result === 'object' && result !== null && 'sourceContent' in result;
|
|
65
|
-
}
|
|
66
|
-
async function readSourceFile(absolutePath) {
|
|
67
|
-
try {
|
|
68
|
-
return await readFile(absolutePath, 'utf-8');
|
|
69
|
-
}
|
|
70
|
-
catch {
|
|
71
|
-
return undefined;
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
async function tryReadJson(path, warnings) {
|
|
75
|
-
try {
|
|
76
|
-
return await readFile(path, 'utf-8');
|
|
77
|
-
}
|
|
78
|
-
catch {
|
|
79
|
-
warnings.push(`Failed to read ${path}. Confirm file exists.`);
|
|
80
|
-
return null;
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
function createHandlers(formats) {
|
|
84
|
-
const handlers = new Map();
|
|
85
|
-
for (const format of formats) {
|
|
86
|
-
handlers.set(format, getCoverageHandler(format));
|
|
87
|
-
}
|
|
88
|
-
return handlers;
|
|
89
|
-
}
|
|
90
|
-
function countLines(lines) {
|
|
91
|
-
const totalLines = Object.keys(lines).length;
|
|
92
|
-
const coveredLines = Object.values(lines).filter((v) => v === 1).length;
|
|
93
|
-
return { totalLines, coveredLines };
|
|
94
|
-
}
|
|
95
|
-
async function processDeployCoverage(data, context) {
|
|
96
|
-
let processed = 0;
|
|
97
|
-
let totalLines = 0;
|
|
98
|
-
let coveredLines = 0;
|
|
99
|
-
await mapLimit(Object.keys(data), context.concurrencyLimit, async (fileName) => {
|
|
100
|
-
const fileInfo = data[fileName];
|
|
101
|
-
const formattedName = fileName.replace(/no-map[\\/]+/, '');
|
|
102
|
-
const path = findFilePath(formattedName, context.filePathCache);
|
|
103
|
-
if (!path) {
|
|
104
|
-
context.warnings.push(`The file name ${formattedName} was not found in any package directory.`);
|
|
105
|
-
return;
|
|
106
|
-
}
|
|
107
|
-
if (context.excludePatterns.some((pattern) => matchesGlob(path, pattern, { matchBase: true }))) {
|
|
108
|
-
return;
|
|
109
|
-
}
|
|
110
|
-
const setCoveredResult = await setCoveredLines(path, context.repoRoot, fileInfo.s, context.handlers.has('html'));
|
|
111
|
-
const updatedLines = hasSourceContent(setCoveredResult) ? setCoveredResult.updatedLines : setCoveredResult;
|
|
112
|
-
const sourceContent = hasSourceContent(setCoveredResult) ? setCoveredResult.sourceContent : undefined;
|
|
113
|
-
fileInfo.s = updatedLines;
|
|
114
|
-
const counts = countLines(updatedLines);
|
|
115
|
-
totalLines += counts.totalLines;
|
|
116
|
-
coveredLines += counts.coveredLines;
|
|
117
|
-
for (const handler of context.handlers.values()) {
|
|
118
|
-
handler.processFile(path, formattedName, updatedLines, sourceContent);
|
|
119
|
-
}
|
|
120
|
-
processed++;
|
|
121
|
-
});
|
|
122
|
-
return { processed, totalLines, coveredLines };
|
|
123
|
-
}
|
|
124
|
-
async function processTestCoverage(data, context) {
|
|
125
|
-
let processed = 0;
|
|
126
|
-
let totalLines = 0;
|
|
127
|
-
let coveredLines = 0;
|
|
128
|
-
await mapLimit(data, context.concurrencyLimit, async (entry) => {
|
|
129
|
-
const formattedName = entry.name.replace(/no-map[\\/]+/, '');
|
|
130
|
-
const path = findFilePath(formattedName, context.filePathCache);
|
|
131
|
-
if (!path) {
|
|
132
|
-
context.warnings.push(`The file name ${formattedName} was not found in any package directory.`);
|
|
133
|
-
return;
|
|
134
|
-
}
|
|
135
|
-
if (context.excludePatterns.some((pattern) => matchesGlob(path, pattern, { matchBase: true }))) {
|
|
136
|
-
return;
|
|
137
|
-
}
|
|
138
|
-
const counts = countLines(entry.lines);
|
|
139
|
-
totalLines += counts.totalLines;
|
|
140
|
-
coveredLines += counts.coveredLines;
|
|
141
|
-
const sourceContent = context.handlers.has('html') ? await readSourceFile(join(context.repoRoot, path)) : undefined;
|
|
142
|
-
for (const handler of context.handlers.values()) {
|
|
143
|
-
handler.processFile(path, formattedName, entry.lines, sourceContent);
|
|
144
|
-
}
|
|
145
|
-
processed++;
|
|
146
|
-
});
|
|
147
|
-
return { processed, totalLines, coveredLines };
|
|
148
|
-
}
|
|
149
62
|
//# sourceMappingURL=coverageTransformer.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"coverageTransformer.js","sourceRoot":"","sources":["../../src/transformers/coverageTransformer.ts"],"names":[],"mappings":"AAAA,qCAAqC;AACrC,
|
|
1
|
+
{"version":3,"file":"coverageTransformer.js","sourceRoot":"","sources":["../../src/transformers/coverageTransformer.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { writeFile } from 'node:fs/promises';
|
|
2
|
-
import {
|
|
2
|
+
import { basename, dirname, extname, join } from 'node:path';
|
|
3
3
|
import XMLBuilder from 'fast-xml-builder';
|
|
4
4
|
import { HandlerRegistry } from '../handlers/HandlerRegistry.js';
|
|
5
5
|
import { builderOptions, XML_HEADER_CONFIG } from '../utils/constants.js';
|
|
6
|
+
import { generateGitHubActions } from './generators/generateGitHubActions.js';
|
|
6
7
|
import { generateHtml } from './generators/generateHtml.js';
|
|
7
8
|
import { generateMarkdown } from './generators/generateMarkdown.js';
|
|
8
|
-
import { generateGitHubActions } from './generators/generateGitHubActions.js';
|
|
9
9
|
function isXmlReportFormat(format) {
|
|
10
10
|
return format in XML_HEADER_CONFIG;
|
|
11
11
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"reportGenerator.js","sourceRoot":"","sources":["../../src/transformers/reportGenerator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC7C,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"reportGenerator.js","sourceRoot":"","sources":["../../src/transformers/reportGenerator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC7C,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAC7D,OAAO,UAAU,MAAM,kBAAkB,CAAC;AAC1C,OAAO,EAAE,eAAe,EAAE,MAAM,gCAAgC,CAAC;AACjE,OAAO,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAS1E,OAAO,EAAE,qBAAqB,EAAE,MAAM,uCAAuC,CAAC;AAC9E,OAAO,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AAC5D,OAAO,EAAE,gBAAgB,EAAE,MAAM,kCAAkC,CAAC;AAMpE,SAAS,iBAAiB,CAAC,MAAc;IACvC,OAAO,MAAM,IAAI,iBAAiB,CAAC;AACrC,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,uBAAuB,GAAmF;IAC9G,QAAQ,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,YAAY,CAAC,GAAyB,CAAC;IAC1D,IAAI,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,YAAY,CAAC,GAAyB,CAAC;IACtD,QAAQ,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,gBAAgB,CAAC,GAA6B,CAAC;IAClE,gBAAgB,EAAE,CAAC,GAAG,EAAE,IAAI,EAAE,EAAE,CAAC,qBAAqB,CAAC,GAAkC,EAAE,IAAI,EAAE,cAAc,CAAC;IAChH,IAAI,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,EAAE,IAAI,EAAE,CAAC,CAAC;IAC3C,cAAc,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,EAAE,IAAI,EAAE,CAAC,CAAC;IACrD,SAAS,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,EAAE,IAAI,EAAE,CAAC,CAAC;CACjD,CAAC;AAEF,MAAM,CAAC,KAAK,UAAU,sBAAsB,CAC1C,UAAkB,EAClB,WAA8B,EAC9B,MAAc,EACd,YAAoB,EACpB,OAA6B;IAE7B,MAAM,OAAO,GAAG,qBAAqB,CAAC,WAAW,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC;IACpE,MAAM,SAAS,GAAG,eAAe,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC;IAEvD,MAAM,IAAI,GAAG,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,mBAAmB;IAC3E,MAAM,GAAG,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;IAEhC,MAAM,MAAM,GAAG,YAAY,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IACpD,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,GAAG,MAAM,GAAG,SAAS,EAAE,CAAC,CAAC;IAE3D,MAAM,SAAS,CAAC,QAAQ,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;IAC5C,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,SAAS,qBAAqB,CAAC,WAA8B,EAAE,MAAc,EAAE,OAA6B;IAC1G,MAAM,QAAQ,GAAG,uBAAuB,CAAC,MAAM,CAAC,CAAC;IACjD,OAAO,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,kBAAkB,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC;AAC7F,CAAC;AAED,SAAS,kBAAkB,CAAC,WAA8B,EAAE,MAAc;IACxE,MAAM,UAAU,GAAG,iBAAiB,CAAC,MAAM,CAAC,CAAC;IAC7C,MAAM,OAAO,GAAG,IAAI,UAAU,CAAC,cAAc,CAAC,CAAC;IAC/C,IAAI,GAAG,GAAG,OAAO,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;IAErC,IAAI,UAAU,EAAE,CAAC;QACf,GAAG,GAAG,GAAG,CAAC,OAAO,CAAC,mBAAmB,EAAE,EAAE,CAAC,CAAC;IAC7C,CAAC;IAED,OAAO,gBAAgB,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC,OAAO,EAAE,CAAC;AACjD,CAAC;AAED,SAAS,YAAY,CAAC,WAA+B;IACnD,OAAO,WAAW,CAAC,KAAK;SACrB,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE;QACZ,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,MAAM,IAAI,CAAC,UAAU,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC/F,OAAO;YACL,KAAK;YACL,MAAM,IAAI,CAAC,UAAU,EAAE;YACvB,OAAO;YACP,OAAO;YACP,QAAQ;YACR,MAAM,IAAI,CAAC,UAAU,EAAE;YACvB,MAAM,IAAI,CAAC,YAAY,EAAE;YACzB,OAAO;YACP,OAAO;YACP,eAAe;SAChB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACf,CAAC,CAAC;SACD,IAAI,CAAC,IAAI,CAAC,CAAC;AAChB,CAAC;AAED,SAAS,gBAAgB,CAAC,GAAW,EAAE,MAAc;IACnD,0DAA0D;IAC1D,MAAM,QAAQ,GAAG,GAAG,CAAC,OAAO,CAAC,mBAAmB,EAAE,EAAE,CAAC,CAAC;IACtD,MAAM,MAAM,GAAG,iBAAiB,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,iBAAiB,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IAEjF,OAAO,CAAC,MAAM,EAAE,OAAO,IAAI,uBAAuB,EAAE,MAAM,EAAE,OAAO,EAAE,QAAQ,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC5G,CAAC;AAED,MAAM,UAAU,qBAAqB,CAAC,MAAc;IAClD,OAAO,eAAe,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC;AAC9C,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getPackageDirectories.js","sourceRoot":"","sources":["../../src/utils/getPackageDirectories.ts"],"names":[],"mappings":"AAAA,YAAY,CAAC;AAEb,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"getPackageDirectories.js","sourceRoot":"","sources":["../../src/utils/getPackageDirectories.ts"],"names":[],"mappings":"AAAA,YAAY,CAAC;AAEb,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAG/C,MAAM,CAAC,KAAK,UAAU,qBAAqB,CACzC,iBAA2B;IAE3B,MAAM,EAAE,QAAQ,EAAE,gBAAgB,EAAE,GAAG,CAAC,MAAM,WAAW,EAAE,CAG1D,CAAC;IAEF,MAAM,cAAc,GAAW,MAAM,QAAQ,CAAC,gBAAgB,EAAE,OAAO,CAAC,CAAC;IACzE,MAAM,WAAW,GAAgB,IAAI,CAAC,KAAK,CAAC,cAAc,CAAgB,CAAC;IAE3E,MAAM,kBAAkB,GAAG,WAAW,CAAC,kBAAkB;SACtD,MAAM,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC,iBAAiB,CAAC,QAAQ,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,4BAA4B;SAC/F,GAAG,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,OAAO,CAAC,QAAQ,EAAE,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC;IAEzD,OAAO,EAAE,QAAQ,EAAE,kBAAkB,EAAE,CAAC;AAC1C,CAAC"}
|
package/lib/utils/getRepoRoot.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
import { access } from 'node:fs/promises';
|
|
3
|
-
import {
|
|
3
|
+
import { dirname, join } from 'node:path';
|
|
4
4
|
async function findRepoRoot(dir) {
|
|
5
5
|
const filePath = join(dir, 'sfdx-project.json');
|
|
6
6
|
try {
|
|
@@ -8,11 +8,11 @@ async function findRepoRoot(dir) {
|
|
|
8
8
|
await access(filePath);
|
|
9
9
|
return { repoRoot: dir, dxConfigFilePath: filePath };
|
|
10
10
|
}
|
|
11
|
-
catch {
|
|
11
|
+
catch (error) {
|
|
12
12
|
const parentDir = dirname(dir);
|
|
13
13
|
if (dir === parentDir) {
|
|
14
14
|
// Reached the root without finding the file, throw an error
|
|
15
|
-
throw new Error('sfdx-project.json not found in any parent directory.');
|
|
15
|
+
throw new Error('sfdx-project.json not found in any parent directory.', { cause: error });
|
|
16
16
|
}
|
|
17
17
|
// Recursively search in the parent directory
|
|
18
18
|
return findRepoRoot(parentDir);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getRepoRoot.js","sourceRoot":"","sources":["../../src/utils/getRepoRoot.ts"],"names":[],"mappings":"AAAA,YAAY,CAAC;AACb,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAC1C,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"getRepoRoot.js","sourceRoot":"","sources":["../../src/utils/getRepoRoot.ts"],"names":[],"mappings":"AAAA,YAAY,CAAC;AACb,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAC1C,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAE1C,KAAK,UAAU,YAAY,CAAC,GAAW;IACrC,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,EAAE,mBAAmB,CAAC,CAAC;IAChD,IAAI,CAAC;QACH,6DAA6D;QAC7D,MAAM,MAAM,CAAC,QAAQ,CAAC,CAAC;QACvB,OAAO,EAAE,QAAQ,EAAE,GAAG,EAAE,gBAAgB,EAAE,QAAQ,EAAE,CAAC;IACvD,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,SAAS,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC;QAC/B,IAAI,GAAG,KAAK,SAAS,EAAE,CAAC;YACtB,4DAA4D;YAC5D,MAAM,IAAI,KAAK,CAAC,sDAAsD,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,CAAC;QAC5F,CAAC;QACD,6CAA6C;QAC7C,OAAO,YAAY,CAAC,SAAS,CAAC,CAAC;IACjC,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,WAAW;IAC/B,MAAM,UAAU,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;IACjC,OAAO,YAAY,CAAC,UAAU,CAAC,CAAC;AAClC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function tryReadJson(path: string, warnings: string[]): Promise<string | null>;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
import { readFile } from 'node:fs/promises';
|
|
3
|
+
export async function tryReadJson(path, warnings) {
|
|
4
|
+
try {
|
|
5
|
+
return await readFile(path, 'utf-8');
|
|
6
|
+
}
|
|
7
|
+
catch {
|
|
8
|
+
warnings.push(`Failed to read ${path}. Confirm file exists.`);
|
|
9
|
+
return null;
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
//# sourceMappingURL=readJson.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"readJson.js","sourceRoot":"","sources":["../../src/utils/readJson.ts"],"names":[],"mappings":"AAAA,YAAY,CAAC;AAEb,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAE5C,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,IAAY,EAAE,QAAkB;IAChE,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"}
|
package/lib/utils/types.d.ts
CHANGED
|
@@ -44,6 +44,19 @@ export type CoverageProcessingContext = {
|
|
|
44
44
|
filePathCache: Map<string, string>;
|
|
45
45
|
excludePatterns: string[];
|
|
46
46
|
};
|
|
47
|
+
export type CoverageInput = DeployCoverageData | TestCoverageData[];
|
|
48
|
+
export type LineTotals = {
|
|
49
|
+
totalLines: number;
|
|
50
|
+
coveredLines: number;
|
|
51
|
+
};
|
|
52
|
+
export type ProcessResult = {
|
|
53
|
+
processed: number;
|
|
54
|
+
} & LineTotals;
|
|
55
|
+
export type TransformOptions = {
|
|
56
|
+
minCoverage?: number;
|
|
57
|
+
maxAnnotations?: number;
|
|
58
|
+
excludePatterns?: string[];
|
|
59
|
+
};
|
|
47
60
|
type SonarLine = {
|
|
48
61
|
'@lineNumber': number;
|
|
49
62
|
'@covered': boolean;
|
|
@@ -15,10 +15,11 @@ Transform Salesforce Apex code coverage JSONs created during deployments and tes
|
|
|
15
15
|
- `sf acc-transformer transform -j "coverage.json" -r "coverage.md" -f "markdown"`
|
|
16
16
|
- `sf acc-transformer transform -j "coverage.json" -r "coverage.txt" -f "github-actions"`
|
|
17
17
|
- `sf acc-transformer transform -j "coverage.json" -i "force-app"`
|
|
18
|
+
- `sf acc-transformer transform -j "coverage1.json" -j "coverage2.json" -r "coverage.xml" -f "sonar"`
|
|
18
19
|
|
|
19
20
|
# flags.coverage-json.summary
|
|
20
21
|
|
|
21
|
-
Path to
|
|
22
|
+
Path to a code coverage JSON file created by the Salesforce CLI deploy or test command. Repeat the flag to merge multiple files. When the same Apex file appears in multiple inputs, covered lines are unioned across all inputs — if a line is covered in any input it is counted as covered in the final report, even if it is uncovered in others.
|
|
22
23
|
|
|
23
24
|
# flags.output-report.summary
|
|
24
25
|
|
package/oclif.manifest.json
CHANGED
|
@@ -11,7 +11,8 @@
|
|
|
11
11
|
"`sf acc-transformer transform -j \"coverage.json\" -r \"coverage.info\" -f \"lcovonly\"`",
|
|
12
12
|
"`sf acc-transformer transform -j \"coverage.json\" -r \"coverage.md\" -f \"markdown\"`",
|
|
13
13
|
"`sf acc-transformer transform -j \"coverage.json\" -r \"coverage.txt\" -f \"github-actions\"`",
|
|
14
|
-
"`sf acc-transformer transform -j \"coverage.json\" -i \"force-app\"`"
|
|
14
|
+
"`sf acc-transformer transform -j \"coverage.json\" -i \"force-app\"`",
|
|
15
|
+
"`sf acc-transformer transform -j \"coverage1.json\" -j \"coverage2.json\" -r \"coverage.xml\" -f \"sonar\"`"
|
|
15
16
|
],
|
|
16
17
|
"flags": {
|
|
17
18
|
"json": {
|
|
@@ -33,9 +34,9 @@
|
|
|
33
34
|
"char": "j",
|
|
34
35
|
"name": "coverage-json",
|
|
35
36
|
"required": true,
|
|
36
|
-
"summary": "Path to
|
|
37
|
+
"summary": "Path to a code coverage JSON file created by the Salesforce CLI deploy or test command. Repeat the flag to merge multiple files. When the same Apex file appears in multiple inputs, covered lines are unioned across all inputs — if a line is covered in any input it is counted as covered in the final report, even if it is uncovered in others.",
|
|
37
38
|
"hasDynamicHelp": false,
|
|
38
|
-
"multiple":
|
|
39
|
+
"multiple": true,
|
|
39
40
|
"type": "option"
|
|
40
41
|
},
|
|
41
42
|
"output-report": {
|
|
@@ -130,5 +131,5 @@
|
|
|
130
131
|
]
|
|
131
132
|
}
|
|
132
133
|
},
|
|
133
|
-
"version": "2.
|
|
134
|
+
"version": "2.23.1"
|
|
134
135
|
}
|
package/package.json
CHANGED
|
@@ -1,36 +1,35 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "apex-code-coverage-transformer",
|
|
3
|
-
"description": "Transform Salesforce Apex code coverage
|
|
4
|
-
"version": "2.
|
|
3
|
+
"description": "Transform Salesforce Apex code coverage JSON for SonarQube, SonarCloud, GitHub, GitLab, Azure, and Bitbucket",
|
|
4
|
+
"version": "2.23.1",
|
|
5
5
|
"dependencies": {
|
|
6
|
-
"@oclif/core": "4.
|
|
7
|
-
"@salesforce/core": "8.
|
|
8
|
-
"@salesforce/sf-plugins-core": "12.2.
|
|
6
|
+
"@oclif/core": "4.11.11",
|
|
7
|
+
"@salesforce/core": "8.31.4",
|
|
8
|
+
"@salesforce/sf-plugins-core": "12.2.25",
|
|
9
9
|
"fast-xml-builder": "1.2.0"
|
|
10
10
|
},
|
|
11
11
|
"devDependencies": {
|
|
12
|
-
"@
|
|
13
|
-
"@commitlint/
|
|
14
|
-
"@
|
|
15
|
-
"@salesforce/cli-plugins-testkit": "5.3.
|
|
12
|
+
"@biomejs/biome": "2.5.1",
|
|
13
|
+
"@commitlint/cli": "21.1.0",
|
|
14
|
+
"@commitlint/config-conventional": "21.1.0",
|
|
15
|
+
"@salesforce/cli-plugins-testkit": "5.3.62",
|
|
16
16
|
"@salesforce/dev-config": "4.3.3",
|
|
17
|
-
"@salesforce/prettier-config": "0.0.4",
|
|
18
17
|
"@stryker-mutator/core": "9.6.1",
|
|
19
18
|
"@stryker-mutator/vitest-runner": "9.6.1",
|
|
20
|
-
"@types/node": "
|
|
21
|
-
"@vitest/coverage-v8": "4.1.
|
|
22
|
-
"eslint-config-salesforce-typescript": "4.0.1",
|
|
23
|
-
"eslint-plugin-sf-plugin": "1.20.26",
|
|
19
|
+
"@types/node": "25.9.4",
|
|
20
|
+
"@vitest/coverage-v8": "4.1.9",
|
|
24
21
|
"husky": "9.1.7",
|
|
25
|
-
"
|
|
22
|
+
"knip": "6.23.0",
|
|
23
|
+
"lint-staged": "17.0.8",
|
|
24
|
+
"oclif": "4.23.24",
|
|
26
25
|
"shx": "0.4.0",
|
|
27
26
|
"ts-node": "10.9.2",
|
|
28
|
-
"typescript": "
|
|
29
|
-
"vitest": "4.1.
|
|
30
|
-
"wireit": "0.14.
|
|
27
|
+
"typescript": "6.0.3",
|
|
28
|
+
"vitest": "4.1.9",
|
|
29
|
+
"wireit": "0.14.13"
|
|
31
30
|
},
|
|
32
31
|
"engines": {
|
|
33
|
-
"node": ">=
|
|
32
|
+
"node": ">=22.0.0"
|
|
34
33
|
},
|
|
35
34
|
"files": [
|
|
36
35
|
"/lib",
|
|
@@ -40,36 +39,30 @@
|
|
|
40
39
|
"/CHANGELOG.md"
|
|
41
40
|
],
|
|
42
41
|
"keywords": [
|
|
43
|
-
"force",
|
|
44
42
|
"salesforce",
|
|
45
43
|
"salesforcedx",
|
|
46
44
|
"sf",
|
|
47
45
|
"sf-plugin",
|
|
48
46
|
"sfdx",
|
|
49
47
|
"sfdx-plugin",
|
|
50
|
-
"xml",
|
|
51
|
-
"json",
|
|
52
|
-
"sonarqube",
|
|
53
|
-
"sonarcloud",
|
|
54
48
|
"apex",
|
|
55
49
|
"coverage",
|
|
56
|
-
"
|
|
57
|
-
"
|
|
58
|
-
"clover",
|
|
50
|
+
"code-coverage",
|
|
51
|
+
"test-coverage",
|
|
59
52
|
"converter",
|
|
60
53
|
"transformer",
|
|
61
|
-
"
|
|
62
|
-
"
|
|
63
|
-
"
|
|
64
|
-
"
|
|
65
|
-
"gitlab",
|
|
66
|
-
"github",
|
|
67
|
-
"azure",
|
|
68
|
-
"bitbucket",
|
|
54
|
+
"xml",
|
|
55
|
+
"json",
|
|
56
|
+
"cobertura",
|
|
57
|
+
"clover",
|
|
69
58
|
"jacoco",
|
|
70
59
|
"lcov",
|
|
71
|
-
"
|
|
72
|
-
"
|
|
60
|
+
"sonarqube",
|
|
61
|
+
"sonarcloud",
|
|
62
|
+
"github",
|
|
63
|
+
"gitlab",
|
|
64
|
+
"azure",
|
|
65
|
+
"bitbucket"
|
|
73
66
|
],
|
|
74
67
|
"license": "MIT",
|
|
75
68
|
"oclif": {
|
|
@@ -90,27 +83,57 @@
|
|
|
90
83
|
"flexibleTaxonomy": true
|
|
91
84
|
},
|
|
92
85
|
"scripts": {
|
|
93
|
-
"command-docs": "oclif readme",
|
|
94
86
|
"build": "wireit",
|
|
95
|
-
"clean
|
|
87
|
+
"clean": "wireit",
|
|
88
|
+
"clean:build": "wireit",
|
|
89
|
+
"clean:package-manager": "wireit",
|
|
96
90
|
"compile": "wireit",
|
|
97
91
|
"format": "wireit",
|
|
98
92
|
"lint": "wireit",
|
|
93
|
+
"lint:dependencies": "wireit",
|
|
99
94
|
"postpack": "shx rm -f oclif.manifest.json oclif.lock",
|
|
100
95
|
"prepack": "wireit",
|
|
101
|
-
"prepare": "husky
|
|
96
|
+
"prepare": "husky",
|
|
102
97
|
"test": "wireit",
|
|
103
|
-
"test:compile": "wireit",
|
|
104
98
|
"test:mutation": "stryker run",
|
|
105
99
|
"test:mutation:incremental": "node scripts/incremental-mutation.mjs",
|
|
106
|
-
"test:nuts": "
|
|
107
|
-
"test:only": "wireit"
|
|
108
|
-
"version": "oclif readme"
|
|
100
|
+
"test:nuts": "wireit",
|
|
101
|
+
"test:only": "wireit"
|
|
109
102
|
},
|
|
110
103
|
"publishConfig": {
|
|
111
104
|
"access": "public"
|
|
112
105
|
},
|
|
113
106
|
"wireit": {
|
|
107
|
+
"clean": {
|
|
108
|
+
"command": "shx rm -rf 'reports/*' oclif.manifest.json oclif.lock package.tgz 'apex-code-coverage-transformer-*.tgz' 'stderr*.txt' 'stdout*.txt' '.stryker-tmp/*'",
|
|
109
|
+
"files": [
|
|
110
|
+
".stryker-tmp/*",
|
|
111
|
+
"lib",
|
|
112
|
+
"oclif.manifest.json",
|
|
113
|
+
"oclif.lock",
|
|
114
|
+
"package.tgz",
|
|
115
|
+
"reports/*",
|
|
116
|
+
"apex-code-coverage-transformer-v*.tgz",
|
|
117
|
+
"stderr*.txt",
|
|
118
|
+
"stdout*.txt"
|
|
119
|
+
],
|
|
120
|
+
"dependencies": [
|
|
121
|
+
"clean:build"
|
|
122
|
+
]
|
|
123
|
+
},
|
|
124
|
+
"clean:build": {
|
|
125
|
+
"command": "shx rm -rf lib .wireit",
|
|
126
|
+
"files": [
|
|
127
|
+
".wireit/*",
|
|
128
|
+
"lib/*"
|
|
129
|
+
]
|
|
130
|
+
},
|
|
131
|
+
"clean:package-manager": {
|
|
132
|
+
"command": "shx rm -rf node_modules tsconfig.tsbuildinfo",
|
|
133
|
+
"files": [
|
|
134
|
+
"node_modules/*"
|
|
135
|
+
]
|
|
136
|
+
},
|
|
114
137
|
"build": {
|
|
115
138
|
"dependencies": [
|
|
116
139
|
"compile",
|
|
@@ -131,27 +154,38 @@
|
|
|
131
154
|
"clean": "if-file-deleted"
|
|
132
155
|
},
|
|
133
156
|
"format": {
|
|
134
|
-
"command": "
|
|
157
|
+
"command": "biome format --write src test",
|
|
135
158
|
"files": [
|
|
136
159
|
"src/**/*.ts",
|
|
137
160
|
"test/**/*.ts",
|
|
138
|
-
"
|
|
139
|
-
"command-snapshot.json",
|
|
140
|
-
".prettier*"
|
|
161
|
+
"biome.json"
|
|
141
162
|
],
|
|
142
163
|
"output": []
|
|
143
164
|
},
|
|
144
165
|
"lint": {
|
|
145
|
-
"command": "
|
|
166
|
+
"command": "biome check src test",
|
|
146
167
|
"files": [
|
|
147
168
|
"src/**/*.ts",
|
|
148
169
|
"test/**/*.ts",
|
|
149
170
|
"messages/**",
|
|
150
|
-
"
|
|
171
|
+
"biome.json",
|
|
151
172
|
"**/tsconfig.json"
|
|
152
173
|
],
|
|
153
174
|
"output": []
|
|
154
175
|
},
|
|
176
|
+
"lint:dependencies": {
|
|
177
|
+
"command": "knip",
|
|
178
|
+
"files": [
|
|
179
|
+
"src/**/*.ts",
|
|
180
|
+
"test/**/*.ts",
|
|
181
|
+
"knip.config.ts",
|
|
182
|
+
"package.json"
|
|
183
|
+
],
|
|
184
|
+
"output": [],
|
|
185
|
+
"dependencies": [
|
|
186
|
+
"lint"
|
|
187
|
+
]
|
|
188
|
+
},
|
|
155
189
|
"prepack": {
|
|
156
190
|
"command": "oclif manifest && oclif readme",
|
|
157
191
|
"files": [
|
|
@@ -182,6 +216,19 @@
|
|
|
182
216
|
"lint"
|
|
183
217
|
]
|
|
184
218
|
},
|
|
219
|
+
"test:nuts": {
|
|
220
|
+
"command": "vitest run --config ./vitest.nut.config.ts && shx rm -f oclif.manifest.json oclif.lock *.tsbuildinfo",
|
|
221
|
+
"files": [
|
|
222
|
+
"test/**/*.nut.ts",
|
|
223
|
+
"**/tsconfig.json",
|
|
224
|
+
"vitest.nut.config.ts"
|
|
225
|
+
],
|
|
226
|
+
"output": [],
|
|
227
|
+
"dependencies": [
|
|
228
|
+
"build",
|
|
229
|
+
"prepack"
|
|
230
|
+
]
|
|
231
|
+
},
|
|
185
232
|
"test:only": {
|
|
186
233
|
"command": "vitest run --coverage",
|
|
187
234
|
"env": {
|
|
@@ -195,35 +242,6 @@
|
|
|
195
242
|
"!*.nut.ts"
|
|
196
243
|
],
|
|
197
244
|
"output": []
|
|
198
|
-
},
|
|
199
|
-
"test:command-reference": {
|
|
200
|
-
"command": "\"./bin/dev\" commandreference:generate --erroronwarnings",
|
|
201
|
-
"files": [
|
|
202
|
-
"src/**/*.ts",
|
|
203
|
-
"messages/**",
|
|
204
|
-
"package.json"
|
|
205
|
-
],
|
|
206
|
-
"output": [
|
|
207
|
-
"tmp/root"
|
|
208
|
-
]
|
|
209
|
-
},
|
|
210
|
-
"test:deprecation-policy": {
|
|
211
|
-
"command": "\"./bin/dev\" snapshot:compare",
|
|
212
|
-
"files": [
|
|
213
|
-
"src/**/*.ts"
|
|
214
|
-
],
|
|
215
|
-
"output": [],
|
|
216
|
-
"dependencies": [
|
|
217
|
-
"compile"
|
|
218
|
-
]
|
|
219
|
-
},
|
|
220
|
-
"test:json-schema": {
|
|
221
|
-
"command": "\"./bin/dev\" schema:compare",
|
|
222
|
-
"files": [
|
|
223
|
-
"src/**/*.ts",
|
|
224
|
-
"schemas"
|
|
225
|
-
],
|
|
226
|
-
"output": []
|
|
227
245
|
}
|
|
228
246
|
},
|
|
229
247
|
"exports": "./lib/index.js",
|