@code-pushup/cli 0.51.0 → 0.53.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +20 -1
- package/index.js +329 -164
- package/package.json +7 -4
- package/src/lib/implementation/core-config.middleware.d.ts +3 -4
- package/src/lib/implementation/filter.middleware.d.ts +2 -0
- package/src/lib/implementation/filter.model.d.ts +9 -0
- package/src/lib/implementation/filter.options.d.ts +7 -0
- package/src/lib/implementation/validate-filter-options.utils.d.ts +13 -0
- package/src/lib/options.d.ts +2 -0
- package/src/lib/implementation/filter-plugins.middleware.d.ts +0 -3
- package/src/lib/implementation/only-plugins.model.d.ts +0 -6
- package/src/lib/implementation/only-plugins.options.d.ts +0 -4
- package/src/lib/implementation/skip-plugins.model.d.ts +0 -6
- package/src/lib/implementation/skip-plugins.options.d.ts +0 -4
- package/src/lib/implementation/validate-plugin-filter-options.utils.d.ts +0 -8
package/README.md
CHANGED
|
@@ -118,7 +118,26 @@ _If you're looking for programmatic usage, then refer to the underlying [@code-p
|
|
|
118
118
|
|
|
119
119
|
## Portal integration
|
|
120
120
|
|
|
121
|
-
If you have access to the Code PushUp portal,
|
|
121
|
+
If you have access to the Code PushUp portal, you can enable report uploads by installing the `@code-pushup/portal-client` package.
|
|
122
|
+
|
|
123
|
+
<details>
|
|
124
|
+
<summary>Installation command for <code>npm</code>, <code>yarn</code> and <code>pnpm</code></summary>
|
|
125
|
+
|
|
126
|
+
```sh
|
|
127
|
+
npm install --save-dev @code-pushup/portal-client
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
```sh
|
|
131
|
+
yarn add --dev @code-pushup/portal-client
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
```sh
|
|
135
|
+
pnpm add --save-dev @code-pushup/portal-client
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
</details>
|
|
139
|
+
|
|
140
|
+
Once the package is installed, update your configuration file to include your portal credentials:
|
|
122
141
|
|
|
123
142
|
```ts
|
|
124
143
|
const config: CoreConfig = {
|
package/index.js
CHANGED
|
@@ -1608,25 +1608,30 @@ import {
|
|
|
1608
1608
|
} from "build-md";
|
|
1609
1609
|
import { posix as pathPosix } from "node:path";
|
|
1610
1610
|
|
|
1611
|
-
// packages/utils/src/lib/reports/
|
|
1611
|
+
// packages/utils/src/lib/reports/types.ts
|
|
1612
|
+
var SUPPORTED_ENVIRONMENTS = [
|
|
1613
|
+
"vscode",
|
|
1614
|
+
"github",
|
|
1615
|
+
"gitlab",
|
|
1616
|
+
"other"
|
|
1617
|
+
];
|
|
1618
|
+
|
|
1619
|
+
// packages/utils/src/lib/reports/environment-type.ts
|
|
1620
|
+
var environmentChecks = {
|
|
1621
|
+
vscode: () => process.env["TERM_PROGRAM"] === "vscode",
|
|
1622
|
+
github: () => process.env["GITHUB_ACTIONS"] === "true",
|
|
1623
|
+
gitlab: () => process.env["GITLAB_CI"] === "true",
|
|
1624
|
+
other: () => true
|
|
1625
|
+
};
|
|
1612
1626
|
function getEnvironmentType() {
|
|
1613
|
-
|
|
1614
|
-
return "vscode";
|
|
1615
|
-
}
|
|
1616
|
-
if (isGitHub()) {
|
|
1617
|
-
return "github";
|
|
1618
|
-
}
|
|
1619
|
-
return "other";
|
|
1620
|
-
}
|
|
1621
|
-
function isVSCode() {
|
|
1622
|
-
return process.env["TERM_PROGRAM"] === "vscode";
|
|
1623
|
-
}
|
|
1624
|
-
function isGitHub() {
|
|
1625
|
-
return process.env["GITHUB_ACTIONS"] === "true";
|
|
1627
|
+
return SUPPORTED_ENVIRONMENTS.find((env) => environmentChecks[env]()) ?? "other";
|
|
1626
1628
|
}
|
|
1627
1629
|
function getGitHubBaseUrl() {
|
|
1628
1630
|
return `${process.env["GITHUB_SERVER_URL"]}/${process.env["GITHUB_REPOSITORY"]}/blob/${process.env["GITHUB_SHA"]}`;
|
|
1629
1631
|
}
|
|
1632
|
+
function getGitLabBaseUrl() {
|
|
1633
|
+
return `${process.env["CI_SERVER_URL"]}/${process.env["CI_PROJECT_PATH"]}/-/blob/${process.env["CI_COMMIT_SHA"]}`;
|
|
1634
|
+
}
|
|
1630
1635
|
|
|
1631
1636
|
// packages/utils/src/lib/reports/formatting.ts
|
|
1632
1637
|
function tableSection(tableData, options2) {
|
|
@@ -1692,6 +1697,15 @@ function formatGitHubLink(file, position) {
|
|
|
1692
1697
|
const lineRange = end && start !== end ? `${start}-${end}` : start;
|
|
1693
1698
|
return `${baseUrl}/${file}#${lineRange}`;
|
|
1694
1699
|
}
|
|
1700
|
+
function formatGitLabLink(file, position) {
|
|
1701
|
+
const baseUrl = getGitLabBaseUrl();
|
|
1702
|
+
if (!position) {
|
|
1703
|
+
return `${baseUrl}/${file}`;
|
|
1704
|
+
}
|
|
1705
|
+
const { startLine, endLine } = position;
|
|
1706
|
+
const lineRange = endLine && startLine !== endLine ? `${startLine}-${endLine}` : startLine;
|
|
1707
|
+
return `${baseUrl}/${file}#L${lineRange}`;
|
|
1708
|
+
}
|
|
1695
1709
|
function formatFileLink(file, position, outputDir) {
|
|
1696
1710
|
const relativePath = pathPosix.relative(outputDir, file);
|
|
1697
1711
|
const env = getEnvironmentType();
|
|
@@ -1700,6 +1714,8 @@ function formatFileLink(file, position, outputDir) {
|
|
|
1700
1714
|
return position ? `${relativePath}#L${position.startLine}` : relativePath;
|
|
1701
1715
|
case "github":
|
|
1702
1716
|
return formatGitHubLink(file, position);
|
|
1717
|
+
case "gitlab":
|
|
1718
|
+
return formatGitLabLink(file, position);
|
|
1703
1719
|
default:
|
|
1704
1720
|
return relativePath;
|
|
1705
1721
|
}
|
|
@@ -2345,11 +2361,11 @@ import { bold as bold4, cyan, cyanBright, green as green2, red } from "ansis";
|
|
|
2345
2361
|
function log(msg = "") {
|
|
2346
2362
|
ui().logger.log(msg);
|
|
2347
2363
|
}
|
|
2348
|
-
function logStdoutSummary(report) {
|
|
2364
|
+
function logStdoutSummary(report, verbose = false) {
|
|
2349
2365
|
const printCategories = report.categories.length > 0;
|
|
2350
2366
|
log(reportToHeaderSection(report));
|
|
2351
2367
|
log();
|
|
2352
|
-
logPlugins(report);
|
|
2368
|
+
logPlugins(report.plugins, verbose);
|
|
2353
2369
|
if (printCategories) {
|
|
2354
2370
|
logCategories(report);
|
|
2355
2371
|
}
|
|
@@ -2360,36 +2376,49 @@ function reportToHeaderSection(report) {
|
|
|
2360
2376
|
const { packageName, version: version3 } = report;
|
|
2361
2377
|
return `${bold4(REPORT_HEADLINE_TEXT)} - ${packageName}@${version3}`;
|
|
2362
2378
|
}
|
|
2363
|
-
function logPlugins(
|
|
2364
|
-
const { plugins } = report;
|
|
2379
|
+
function logPlugins(plugins, verbose) {
|
|
2365
2380
|
plugins.forEach((plugin) => {
|
|
2366
2381
|
const { title, audits } = plugin;
|
|
2382
|
+
const filteredAudits = verbose ? audits : audits.filter(({ score }) => score !== 1);
|
|
2383
|
+
const diff = audits.length - filteredAudits.length;
|
|
2384
|
+
logAudits(title, filteredAudits);
|
|
2385
|
+
if (diff > 0) {
|
|
2386
|
+
const notice = filteredAudits.length === 0 ? `... All ${diff} audits have perfect scores ...` : `... ${diff} audits with perfect scores omitted for brevity ...`;
|
|
2387
|
+
logRow(1, notice);
|
|
2388
|
+
}
|
|
2367
2389
|
log();
|
|
2368
|
-
log(bold4.magentaBright(`${title} audits`));
|
|
2369
|
-
log();
|
|
2370
|
-
audits.forEach((audit) => {
|
|
2371
|
-
ui().row([
|
|
2372
|
-
{
|
|
2373
|
-
text: applyScoreColor({ score: audit.score, text: "\u25CF" }),
|
|
2374
|
-
width: 2,
|
|
2375
|
-
padding: [0, 1, 0, 0]
|
|
2376
|
-
},
|
|
2377
|
-
{
|
|
2378
|
-
text: audit.title,
|
|
2379
|
-
// eslint-disable-next-line no-magic-numbers
|
|
2380
|
-
padding: [0, 3, 0, 0]
|
|
2381
|
-
},
|
|
2382
|
-
{
|
|
2383
|
-
text: cyanBright(audit.displayValue || `${audit.value}`),
|
|
2384
|
-
// eslint-disable-next-line no-magic-numbers
|
|
2385
|
-
width: 20,
|
|
2386
|
-
padding: [0, 0, 0, 0]
|
|
2387
|
-
}
|
|
2388
|
-
]);
|
|
2389
|
-
});
|
|
2390
|
-
log();
|
|
2391
2390
|
});
|
|
2392
2391
|
}
|
|
2392
|
+
function logAudits(pluginTitle, audits) {
|
|
2393
|
+
log();
|
|
2394
|
+
log(bold4.magentaBright(`${pluginTitle} audits`));
|
|
2395
|
+
log();
|
|
2396
|
+
audits.forEach(({ score, title, displayValue, value }) => {
|
|
2397
|
+
logRow(score, title, displayValue || `${value}`);
|
|
2398
|
+
});
|
|
2399
|
+
}
|
|
2400
|
+
function logRow(score, title, value) {
|
|
2401
|
+
ui().row([
|
|
2402
|
+
{
|
|
2403
|
+
text: applyScoreColor({ score, text: "\u25CF" }),
|
|
2404
|
+
width: 2,
|
|
2405
|
+
padding: [0, 1, 0, 0]
|
|
2406
|
+
},
|
|
2407
|
+
{
|
|
2408
|
+
text: title,
|
|
2409
|
+
// eslint-disable-next-line no-magic-numbers
|
|
2410
|
+
padding: [0, 3, 0, 0]
|
|
2411
|
+
},
|
|
2412
|
+
...value ? [
|
|
2413
|
+
{
|
|
2414
|
+
text: cyanBright(value),
|
|
2415
|
+
// eslint-disable-next-line no-magic-numbers
|
|
2416
|
+
width: 20,
|
|
2417
|
+
padding: [0, 0, 0, 0]
|
|
2418
|
+
}
|
|
2419
|
+
] : []
|
|
2420
|
+
]);
|
|
2421
|
+
}
|
|
2393
2422
|
function logCategories({ categories, plugins }) {
|
|
2394
2423
|
const hAlign = (idx) => idx === 0 ? "left" : "right";
|
|
2395
2424
|
const rows = categories.map(({ title, score, refs, isBinary }) => [
|
|
@@ -2535,7 +2564,7 @@ var verboseUtils = (verbose = false) => ({
|
|
|
2535
2564
|
|
|
2536
2565
|
// packages/core/package.json
|
|
2537
2566
|
var name = "@code-pushup/core";
|
|
2538
|
-
var version = "0.
|
|
2567
|
+
var version = "0.53.0";
|
|
2539
2568
|
|
|
2540
2569
|
// packages/core/src/lib/implementation/execute-plugin.ts
|
|
2541
2570
|
import { bold as bold5 } from "ansis";
|
|
@@ -2730,10 +2759,8 @@ var PersistError = class extends Error {
|
|
|
2730
2759
|
super(`fileName: ${reportPath} could not be saved.`);
|
|
2731
2760
|
}
|
|
2732
2761
|
};
|
|
2733
|
-
async function persistReport(report, options2) {
|
|
2762
|
+
async function persistReport(report, sortedScoredReport, options2) {
|
|
2734
2763
|
const { outputDir, filename, format } = options2;
|
|
2735
|
-
const sortedScoredReport = sortReport(scoreReport(report));
|
|
2736
|
-
logStdoutSummary(sortedScoredReport);
|
|
2737
2764
|
const results = format.map((reportType) => {
|
|
2738
2765
|
switch (reportType) {
|
|
2739
2766
|
case "json":
|
|
@@ -2779,7 +2806,13 @@ function logPersistedResults(persistResults) {
|
|
|
2779
2806
|
async function collectAndPersistReports(options2) {
|
|
2780
2807
|
const { exec } = verboseUtils(options2.verbose);
|
|
2781
2808
|
const report = await collect(options2);
|
|
2782
|
-
const
|
|
2809
|
+
const sortedScoredReport = sortReport(scoreReport(report));
|
|
2810
|
+
const persistResults = await persistReport(
|
|
2811
|
+
report,
|
|
2812
|
+
sortedScoredReport,
|
|
2813
|
+
options2.persist
|
|
2814
|
+
);
|
|
2815
|
+
logStdoutSummary(sortedScoredReport, options2.verbose);
|
|
2783
2816
|
exec(() => {
|
|
2784
2817
|
logPersistedResults(persistResults);
|
|
2785
2818
|
});
|
|
@@ -2791,10 +2824,6 @@ async function collectAndPersistReports(options2) {
|
|
|
2791
2824
|
// packages/core/src/lib/compare.ts
|
|
2792
2825
|
import { writeFile as writeFile2 } from "node:fs/promises";
|
|
2793
2826
|
import { join as join5 } from "node:path";
|
|
2794
|
-
import {
|
|
2795
|
-
PortalOperationError,
|
|
2796
|
-
getPortalComparisonLink
|
|
2797
|
-
} from "@code-pushup/portal-client";
|
|
2798
2827
|
|
|
2799
2828
|
// packages/core/src/lib/implementation/compare-scorables.ts
|
|
2800
2829
|
function compareCategories(reports) {
|
|
@@ -2930,6 +2959,18 @@ function selectMeta(meta) {
|
|
|
2930
2959
|
};
|
|
2931
2960
|
}
|
|
2932
2961
|
|
|
2962
|
+
// packages/core/src/lib/load-portal-client.ts
|
|
2963
|
+
async function loadPortalClient() {
|
|
2964
|
+
try {
|
|
2965
|
+
return await import("@code-pushup/portal-client");
|
|
2966
|
+
} catch {
|
|
2967
|
+
ui().logger.error(
|
|
2968
|
+
"Optional peer dependency @code-pushup/portal-client is not available. Make sure it is installed to enable upload functionality."
|
|
2969
|
+
);
|
|
2970
|
+
return null;
|
|
2971
|
+
}
|
|
2972
|
+
}
|
|
2973
|
+
|
|
2933
2974
|
// packages/core/src/lib/compare.ts
|
|
2934
2975
|
async function compareReportFiles(inputPaths, persistConfig, uploadConfig, label) {
|
|
2935
2976
|
const { outputDir, filename, format } = persistConfig;
|
|
@@ -2994,6 +3035,11 @@ function reportsDiffToFileContent(reportsDiff, format) {
|
|
|
2994
3035
|
}
|
|
2995
3036
|
async function fetchPortalComparisonLink(uploadConfig, commits) {
|
|
2996
3037
|
const { server, apiKey, organization, project } = uploadConfig;
|
|
3038
|
+
const portalClient = await loadPortalClient();
|
|
3039
|
+
if (!portalClient) {
|
|
3040
|
+
return;
|
|
3041
|
+
}
|
|
3042
|
+
const { PortalOperationError, getPortalComparisonLink } = portalClient;
|
|
2997
3043
|
try {
|
|
2998
3044
|
return await getPortalComparisonLink({
|
|
2999
3045
|
server,
|
|
@@ -3016,18 +3062,7 @@ async function fetchPortalComparisonLink(uploadConfig, commits) {
|
|
|
3016
3062
|
}
|
|
3017
3063
|
}
|
|
3018
3064
|
|
|
3019
|
-
// packages/core/src/lib/upload.ts
|
|
3020
|
-
import {
|
|
3021
|
-
uploadToPortal
|
|
3022
|
-
} from "@code-pushup/portal-client";
|
|
3023
|
-
|
|
3024
3065
|
// packages/core/src/lib/implementation/report-to-gql.ts
|
|
3025
|
-
import {
|
|
3026
|
-
CategoryConfigRefType as PortalCategoryRefType,
|
|
3027
|
-
IssueSeverity as PortalIssueSeverity,
|
|
3028
|
-
IssueSourceType as PortalIssueSourceType,
|
|
3029
|
-
TableAlignment as PortalTableAlignment
|
|
3030
|
-
} from "@code-pushup/portal-client";
|
|
3031
3066
|
function reportToGQL(report) {
|
|
3032
3067
|
return {
|
|
3033
3068
|
packageName: report.packageName,
|
|
@@ -3094,7 +3129,7 @@ function issueToGQL(issue) {
|
|
|
3094
3129
|
message: issue.message,
|
|
3095
3130
|
severity: issueSeverityToGQL(issue.severity),
|
|
3096
3131
|
...issue.source?.file && {
|
|
3097
|
-
sourceType:
|
|
3132
|
+
sourceType: safeEnum("SourceCode"),
|
|
3098
3133
|
sourceFilePath: issue.source.file,
|
|
3099
3134
|
sourceStartLine: issue.source.position?.startLine,
|
|
3100
3135
|
sourceStartColumn: issue.source.position?.startColumn,
|
|
@@ -3140,37 +3175,45 @@ function categoryToGQL(category) {
|
|
|
3140
3175
|
function categoryRefTypeToGQL(type) {
|
|
3141
3176
|
switch (type) {
|
|
3142
3177
|
case "audit":
|
|
3143
|
-
return
|
|
3178
|
+
return safeEnum("Audit");
|
|
3144
3179
|
case "group":
|
|
3145
|
-
return
|
|
3180
|
+
return safeEnum("Group");
|
|
3146
3181
|
}
|
|
3147
3182
|
}
|
|
3148
3183
|
function issueSeverityToGQL(severity) {
|
|
3149
3184
|
switch (severity) {
|
|
3150
3185
|
case "info":
|
|
3151
|
-
return
|
|
3186
|
+
return safeEnum("Info");
|
|
3152
3187
|
case "error":
|
|
3153
|
-
return
|
|
3188
|
+
return safeEnum("Error");
|
|
3154
3189
|
case "warning":
|
|
3155
|
-
return
|
|
3190
|
+
return safeEnum("Warning");
|
|
3156
3191
|
}
|
|
3157
3192
|
}
|
|
3158
3193
|
function tableAlignmentToGQL(alignment) {
|
|
3159
3194
|
switch (alignment) {
|
|
3160
3195
|
case "left":
|
|
3161
|
-
return
|
|
3196
|
+
return safeEnum("Left");
|
|
3162
3197
|
case "center":
|
|
3163
|
-
return
|
|
3198
|
+
return safeEnum("Center");
|
|
3164
3199
|
case "right":
|
|
3165
|
-
return
|
|
3200
|
+
return safeEnum("Right");
|
|
3166
3201
|
}
|
|
3167
3202
|
}
|
|
3203
|
+
function safeEnum(value) {
|
|
3204
|
+
return value;
|
|
3205
|
+
}
|
|
3168
3206
|
|
|
3169
3207
|
// packages/core/src/lib/upload.ts
|
|
3170
|
-
async function upload(options2
|
|
3208
|
+
async function upload(options2) {
|
|
3171
3209
|
if (options2.upload == null) {
|
|
3172
3210
|
throw new Error("Upload configuration is not set.");
|
|
3173
3211
|
}
|
|
3212
|
+
const portalClient = await loadPortalClient();
|
|
3213
|
+
if (!portalClient) {
|
|
3214
|
+
return;
|
|
3215
|
+
}
|
|
3216
|
+
const { uploadToPortal } = portalClient;
|
|
3174
3217
|
const { apiKey, server, organization, project, timeout } = options2.upload;
|
|
3175
3218
|
const report = await loadReport({
|
|
3176
3219
|
...options2.persist,
|
|
@@ -3185,7 +3228,7 @@ async function upload(options2, uploadFn = uploadToPortal) {
|
|
|
3185
3228
|
commit: report.commit.hash,
|
|
3186
3229
|
...reportToGQL(report)
|
|
3187
3230
|
};
|
|
3188
|
-
return
|
|
3231
|
+
return uploadToPortal({ apiKey, server, data, timeout });
|
|
3189
3232
|
}
|
|
3190
3233
|
|
|
3191
3234
|
// packages/core/src/lib/history.ts
|
|
@@ -3368,8 +3411,10 @@ function yargsAutorunCommandObject() {
|
|
|
3368
3411
|
renderConfigureCategoriesHint();
|
|
3369
3412
|
}
|
|
3370
3413
|
if (options2.upload) {
|
|
3371
|
-
const
|
|
3372
|
-
|
|
3414
|
+
const report = await upload(options2);
|
|
3415
|
+
if (report?.url) {
|
|
3416
|
+
uploadSuccessfulLog(report.url);
|
|
3417
|
+
}
|
|
3373
3418
|
} else {
|
|
3374
3419
|
ui().logger.warning("Upload skipped because configuration is not set.");
|
|
3375
3420
|
renderIntegratePortalHint();
|
|
@@ -3470,6 +3515,94 @@ function yargsCompareCommandObject() {
|
|
|
3470
3515
|
// packages/cli/src/lib/history/history-command.ts
|
|
3471
3516
|
import { bold as bold10, gray as gray7 } from "ansis";
|
|
3472
3517
|
|
|
3518
|
+
// packages/cli/src/lib/implementation/global.utils.ts
|
|
3519
|
+
import yargs from "yargs";
|
|
3520
|
+
|
|
3521
|
+
// packages/cli/src/lib/implementation/validate-filter-options.utils.ts
|
|
3522
|
+
var OptionValidationError = class extends Error {
|
|
3523
|
+
};
|
|
3524
|
+
function validateFilterOption(option, { plugins, categories }, { itemsToFilter, verbose }) {
|
|
3525
|
+
const itemsToFilterSet = new Set(itemsToFilter);
|
|
3526
|
+
const validItems = isCategoryOption(option) ? categories : isPluginOption(option) ? plugins : [];
|
|
3527
|
+
const invalidItems = itemsToFilter.filter(
|
|
3528
|
+
(item) => !validItems.some(({ slug }) => slug === item)
|
|
3529
|
+
);
|
|
3530
|
+
const message = createValidationMessage(option, invalidItems, validItems);
|
|
3531
|
+
if (isOnlyOption(option) && itemsToFilterSet.size > 0 && itemsToFilterSet.size === invalidItems.length) {
|
|
3532
|
+
throw new OptionValidationError(message);
|
|
3533
|
+
}
|
|
3534
|
+
if (invalidItems.length > 0) {
|
|
3535
|
+
ui().logger.warning(message);
|
|
3536
|
+
}
|
|
3537
|
+
if (isPluginOption(option) && categories.length > 0 && verbose) {
|
|
3538
|
+
const removedCategorySlugs = filterItemRefsBy(
|
|
3539
|
+
categories,
|
|
3540
|
+
({ plugin }) => isOnlyOption(option) ? !itemsToFilterSet.has(plugin) : itemsToFilterSet.has(plugin)
|
|
3541
|
+
).map(({ slug }) => slug);
|
|
3542
|
+
if (removedCategorySlugs.length > 0) {
|
|
3543
|
+
ui().logger.info(
|
|
3544
|
+
`The --${option} argument removed the following categories: ${removedCategorySlugs.join(
|
|
3545
|
+
", "
|
|
3546
|
+
)}.`
|
|
3547
|
+
);
|
|
3548
|
+
}
|
|
3549
|
+
}
|
|
3550
|
+
}
|
|
3551
|
+
function validateFinalState(filteredItems, originalItems) {
|
|
3552
|
+
const { categories: filteredCategories, plugins: filteredPlugins } = filteredItems;
|
|
3553
|
+
const { categories: originalCategories, plugins: originalPlugins } = originalItems;
|
|
3554
|
+
if (filteredCategories.length === 0 && filteredPlugins.length === 0 && (originalPlugins.length > 0 || originalCategories.length > 0)) {
|
|
3555
|
+
const availablePlugins = originalPlugins.map((p) => p.slug).join(", ") || "none";
|
|
3556
|
+
const availableCategories = originalCategories.map((c) => c.slug).join(", ") || "none";
|
|
3557
|
+
throw new OptionValidationError(
|
|
3558
|
+
`Nothing to report. No plugins or categories are available after filtering. Available plugins: ${availablePlugins}. Available categories: ${availableCategories}.`
|
|
3559
|
+
);
|
|
3560
|
+
}
|
|
3561
|
+
}
|
|
3562
|
+
function isCategoryOption(option) {
|
|
3563
|
+
return option.endsWith("Categories");
|
|
3564
|
+
}
|
|
3565
|
+
function isPluginOption(option) {
|
|
3566
|
+
return option.endsWith("Plugins");
|
|
3567
|
+
}
|
|
3568
|
+
function isOnlyOption(option) {
|
|
3569
|
+
return option.startsWith("only");
|
|
3570
|
+
}
|
|
3571
|
+
function getItemType(option, count) {
|
|
3572
|
+
const itemType = isCategoryOption(option) ? "category" : isPluginOption(option) ? "plugin" : "item";
|
|
3573
|
+
return pluralize(itemType, count);
|
|
3574
|
+
}
|
|
3575
|
+
function createValidationMessage(option, invalidItems, validItems) {
|
|
3576
|
+
const invalidItem = getItemType(option, invalidItems.length);
|
|
3577
|
+
const invalidItemText = invalidItems.length === 1 ? `a ${invalidItem} that does not exist:` : `${invalidItem} that do not exist:`;
|
|
3578
|
+
const invalidSlugs = invalidItems.join(", ");
|
|
3579
|
+
const validItem = getItemType(option, validItems.length);
|
|
3580
|
+
const validItemText = validItems.length === 1 ? `The only valid ${validItem} is` : `Valid ${validItem} are`;
|
|
3581
|
+
const validSlugs = validItems.map(({ slug }) => slug).join(", ");
|
|
3582
|
+
return `The --${option} argument references ${invalidItemText} ${invalidSlugs}. ${validItemText} ${validSlugs}.`;
|
|
3583
|
+
}
|
|
3584
|
+
function handleConflictingOptions(type, onlyItems, skipItems) {
|
|
3585
|
+
const conflictingItems = onlyItems.filter((item) => skipItems.includes(item));
|
|
3586
|
+
if (conflictingItems.length > 0) {
|
|
3587
|
+
const conflictSubject = () => {
|
|
3588
|
+
switch (type) {
|
|
3589
|
+
case "categories":
|
|
3590
|
+
return conflictingItems.length > 1 ? "categories are" : "category is";
|
|
3591
|
+
case "plugins":
|
|
3592
|
+
return conflictingItems.length > 1 ? "plugins are" : "plugin is";
|
|
3593
|
+
}
|
|
3594
|
+
};
|
|
3595
|
+
const conflictingSlugs = conflictingItems.join(", ");
|
|
3596
|
+
throw new OptionValidationError(
|
|
3597
|
+
`The following ${conflictSubject()} specified in both --only${capitalize(
|
|
3598
|
+
type
|
|
3599
|
+
)} and --skip${capitalize(
|
|
3600
|
+
type
|
|
3601
|
+
)}: ${conflictingSlugs}. Please choose one option.`
|
|
3602
|
+
);
|
|
3603
|
+
}
|
|
3604
|
+
}
|
|
3605
|
+
|
|
3473
3606
|
// packages/cli/src/lib/implementation/global.utils.ts
|
|
3474
3607
|
function filterKebabCaseKeys(obj) {
|
|
3475
3608
|
return Object.entries(obj).filter(([key]) => !key.includes("-")).reduce(
|
|
@@ -3485,9 +3618,15 @@ function logErrorBeforeThrow(fn) {
|
|
|
3485
3618
|
try {
|
|
3486
3619
|
return await fn(...args);
|
|
3487
3620
|
} catch (error) {
|
|
3488
|
-
|
|
3489
|
-
|
|
3490
|
-
|
|
3621
|
+
if (error instanceof OptionValidationError) {
|
|
3622
|
+
ui().logger.error(error.message);
|
|
3623
|
+
await new Promise((resolve) => process.stdout.write("", resolve));
|
|
3624
|
+
yargs().exit(1, error);
|
|
3625
|
+
} else {
|
|
3626
|
+
console.error(error);
|
|
3627
|
+
await new Promise((resolve) => process.stdout.write("", resolve));
|
|
3628
|
+
throw error;
|
|
3629
|
+
}
|
|
3491
3630
|
}
|
|
3492
3631
|
};
|
|
3493
3632
|
}
|
|
@@ -3495,21 +3634,19 @@ function coerceArray(param) {
|
|
|
3495
3634
|
return [...new Set(toArray(param).flatMap((f) => f.split(",")))];
|
|
3496
3635
|
}
|
|
3497
3636
|
|
|
3498
|
-
// packages/cli/src/lib/implementation/
|
|
3499
|
-
var
|
|
3500
|
-
describe: "List of
|
|
3637
|
+
// packages/cli/src/lib/implementation/filter.options.ts
|
|
3638
|
+
var skipCategoriesOption = {
|
|
3639
|
+
describe: "List of categories to skip. If not set all categories are run.",
|
|
3501
3640
|
type: "array",
|
|
3502
3641
|
default: [],
|
|
3503
|
-
coerce: coerceArray
|
|
3504
|
-
|
|
3642
|
+
coerce: coerceArray
|
|
3643
|
+
};
|
|
3644
|
+
var onlyCategoriesOption = {
|
|
3645
|
+
describe: "List of categories to run. If not set all categories are run.",
|
|
3646
|
+
type: "array",
|
|
3647
|
+
default: [],
|
|
3648
|
+
coerce: coerceArray
|
|
3505
3649
|
};
|
|
3506
|
-
function yargsOnlyPluginsOptionsDefinition() {
|
|
3507
|
-
return {
|
|
3508
|
-
onlyPlugins: onlyPluginsOption
|
|
3509
|
-
};
|
|
3510
|
-
}
|
|
3511
|
-
|
|
3512
|
-
// packages/cli/src/lib/implementation/skip-plugins.options.ts
|
|
3513
3650
|
var skipPluginsOption = {
|
|
3514
3651
|
describe: "List of plugins to skip. If not set all plugins are run.",
|
|
3515
3652
|
type: "array",
|
|
@@ -3517,9 +3654,19 @@ var skipPluginsOption = {
|
|
|
3517
3654
|
coerce: coerceArray,
|
|
3518
3655
|
alias: "P"
|
|
3519
3656
|
};
|
|
3520
|
-
|
|
3657
|
+
var onlyPluginsOption = {
|
|
3658
|
+
describe: "List of plugins to run. If not set all plugins are run.",
|
|
3659
|
+
type: "array",
|
|
3660
|
+
default: [],
|
|
3661
|
+
coerce: coerceArray,
|
|
3662
|
+
alias: "p"
|
|
3663
|
+
};
|
|
3664
|
+
function yargsFilterOptionsDefinition() {
|
|
3521
3665
|
return {
|
|
3522
|
-
|
|
3666
|
+
skipCategories: skipCategoriesOption,
|
|
3667
|
+
onlyCategories: onlyCategoriesOption,
|
|
3668
|
+
skipPlugins: skipPluginsOption,
|
|
3669
|
+
onlyPlugins: onlyPluginsOption
|
|
3523
3670
|
};
|
|
3524
3671
|
}
|
|
3525
3672
|
|
|
@@ -3630,17 +3777,16 @@ function yargsHistoryCommandObject() {
|
|
|
3630
3777
|
return {
|
|
3631
3778
|
command,
|
|
3632
3779
|
describe: "Collect reports for commit history",
|
|
3633
|
-
builder: (
|
|
3634
|
-
|
|
3780
|
+
builder: (yargs3) => {
|
|
3781
|
+
yargs3.options({
|
|
3635
3782
|
...yargsHistoryOptionsDefinition(),
|
|
3636
|
-
...
|
|
3637
|
-
...yargsSkipPluginsOptionsDefinition()
|
|
3783
|
+
...yargsFilterOptionsDefinition()
|
|
3638
3784
|
});
|
|
3639
|
-
|
|
3785
|
+
yargs3.group(
|
|
3640
3786
|
Object.keys(yargsHistoryOptionsDefinition()),
|
|
3641
3787
|
"History Options:"
|
|
3642
3788
|
);
|
|
3643
|
-
return
|
|
3789
|
+
return yargs3;
|
|
3644
3790
|
},
|
|
3645
3791
|
handler
|
|
3646
3792
|
};
|
|
@@ -3707,8 +3853,10 @@ function yargsUploadCommandObject() {
|
|
|
3707
3853
|
renderIntegratePortalHint();
|
|
3708
3854
|
throw new Error("Upload configuration not set");
|
|
3709
3855
|
}
|
|
3710
|
-
const
|
|
3711
|
-
|
|
3856
|
+
const report = await upload(options2);
|
|
3857
|
+
if (report?.url) {
|
|
3858
|
+
uploadSuccessfulLog(report.url);
|
|
3859
|
+
}
|
|
3712
3860
|
}
|
|
3713
3861
|
};
|
|
3714
3862
|
}
|
|
@@ -3765,80 +3913,99 @@ async function coreConfigMiddleware(processArgs) {
|
|
|
3765
3913
|
}
|
|
3766
3914
|
var normalizeFormats = (formats) => (formats ?? []).flatMap((format) => format.split(","));
|
|
3767
3915
|
|
|
3768
|
-
// packages/cli/src/lib/implementation/
|
|
3769
|
-
function
|
|
3770
|
-
plugins,
|
|
3771
|
-
categories
|
|
3772
|
-
}, {
|
|
3773
|
-
pluginsToFilter = [],
|
|
3774
|
-
verbose = false
|
|
3775
|
-
} = {}) {
|
|
3776
|
-
const pluginsToFilterSet = new Set(pluginsToFilter);
|
|
3777
|
-
const missingPlugins = pluginsToFilter.filter(
|
|
3778
|
-
(plugin) => !plugins.some(({ slug }) => slug === plugin)
|
|
3779
|
-
);
|
|
3780
|
-
const isSkipOption = filterOption === "skipPlugins";
|
|
3781
|
-
const filterFunction = (plugin) => isSkipOption ? pluginsToFilterSet.has(plugin) : !pluginsToFilterSet.has(plugin);
|
|
3782
|
-
if (missingPlugins.length > 0) {
|
|
3783
|
-
ui().logger.warning(
|
|
3784
|
-
`The --${filterOption} argument references ${missingPlugins.length === 1 ? "a plugin that does" : "plugins that do"} not exist: ${missingPlugins.join(", ")}. The valid plugin ${plugins.length === 1 ? "slug is" : "slugs are"} ${plugins.map(({ slug }) => slug).join(", ")}.`
|
|
3785
|
-
);
|
|
3786
|
-
}
|
|
3787
|
-
if (categories.length > 0 && verbose) {
|
|
3788
|
-
const removedCategorySlugs = filterItemRefsBy(
|
|
3789
|
-
categories,
|
|
3790
|
-
({ plugin }) => filterFunction(plugin)
|
|
3791
|
-
).map(({ slug }) => slug);
|
|
3792
|
-
ui().logger.info(
|
|
3793
|
-
`The --${filterOption} argument removed the following categories: ${removedCategorySlugs.join(
|
|
3794
|
-
", "
|
|
3795
|
-
)}.`
|
|
3796
|
-
);
|
|
3797
|
-
}
|
|
3798
|
-
}
|
|
3799
|
-
|
|
3800
|
-
// packages/cli/src/lib/implementation/filter-plugins.middleware.ts
|
|
3801
|
-
function filterPluginsMiddleware(originalProcessArgs) {
|
|
3916
|
+
// packages/cli/src/lib/implementation/filter.middleware.ts
|
|
3917
|
+
function filterMiddleware(originalProcessArgs) {
|
|
3802
3918
|
const {
|
|
3803
3919
|
plugins,
|
|
3804
3920
|
categories = [],
|
|
3921
|
+
skipCategories = [],
|
|
3922
|
+
onlyCategories = [],
|
|
3805
3923
|
skipPlugins = [],
|
|
3806
3924
|
onlyPlugins = [],
|
|
3807
|
-
verbose
|
|
3925
|
+
verbose = false
|
|
3808
3926
|
} = originalProcessArgs;
|
|
3809
|
-
if (skipPlugins.length === 0 && onlyPlugins.length === 0) {
|
|
3927
|
+
if (skipCategories.length === 0 && onlyCategories.length === 0 && skipPlugins.length === 0 && onlyPlugins.length === 0) {
|
|
3810
3928
|
return { ...originalProcessArgs, categories };
|
|
3811
3929
|
}
|
|
3812
|
-
|
|
3813
|
-
|
|
3814
|
-
|
|
3815
|
-
{
|
|
3816
|
-
|
|
3817
|
-
|
|
3818
|
-
|
|
3819
|
-
{ plugins, categories },
|
|
3820
|
-
{ pluginsToFilter: onlyPlugins, verbose }
|
|
3930
|
+
handleConflictingOptions("categories", onlyCategories, skipCategories);
|
|
3931
|
+
handleConflictingOptions("plugins", onlyPlugins, skipPlugins);
|
|
3932
|
+
const filteredCategories = applyCategoryFilters(
|
|
3933
|
+
{ categories, plugins },
|
|
3934
|
+
skipCategories,
|
|
3935
|
+
onlyCategories,
|
|
3936
|
+
verbose
|
|
3821
3937
|
);
|
|
3822
|
-
const
|
|
3823
|
-
|
|
3938
|
+
const filteredPlugins = applyPluginFilters(
|
|
3939
|
+
{ categories: filteredCategories, plugins },
|
|
3940
|
+
skipPlugins,
|
|
3941
|
+
onlyPlugins,
|
|
3942
|
+
verbose
|
|
3824
3943
|
);
|
|
3825
|
-
const
|
|
3826
|
-
|
|
3944
|
+
const finalCategories = filterItemRefsBy(
|
|
3945
|
+
filteredCategories,
|
|
3946
|
+
(ref) => filteredPlugins.some((plugin) => plugin.slug === ref.plugin)
|
|
3827
3947
|
);
|
|
3828
|
-
|
|
3829
|
-
|
|
3948
|
+
validateFinalState(
|
|
3949
|
+
{ categories: finalCategories, plugins: filteredPlugins },
|
|
3950
|
+
{ categories, plugins }
|
|
3830
3951
|
);
|
|
3831
|
-
const filteredPlugins = validOnlyPlugins.size > 0 ? pluginsAfterSkip.filter(({ slug }) => validOnlyPlugins.has(slug)) : pluginsAfterSkip;
|
|
3832
|
-
const filteredCategories = filteredPlugins.length > 0 ? filterItemRefsBy(
|
|
3833
|
-
categories,
|
|
3834
|
-
({ plugin }) => filteredPlugins.some(({ slug }) => slug === plugin)
|
|
3835
|
-
) : categories;
|
|
3836
3952
|
return {
|
|
3837
3953
|
...originalProcessArgs,
|
|
3838
3954
|
plugins: filteredPlugins,
|
|
3839
|
-
categories:
|
|
3955
|
+
categories: finalCategories
|
|
3840
3956
|
};
|
|
3841
3957
|
}
|
|
3958
|
+
function applyFilters(items, skipItems, onlyItems, key) {
|
|
3959
|
+
return items.filter((item) => {
|
|
3960
|
+
const itemKey = item[key];
|
|
3961
|
+
return !skipItems.includes(itemKey) && (onlyItems.length === 0 || onlyItems.includes(itemKey));
|
|
3962
|
+
});
|
|
3963
|
+
}
|
|
3964
|
+
function applyCategoryFilters({ categories, plugins }, skipCategories, onlyCategories, verbose) {
|
|
3965
|
+
if (skipCategories.length === 0 && onlyCategories.length === 0) {
|
|
3966
|
+
return categories;
|
|
3967
|
+
}
|
|
3968
|
+
validateFilterOption(
|
|
3969
|
+
"skipCategories",
|
|
3970
|
+
{ plugins, categories },
|
|
3971
|
+
{ itemsToFilter: skipCategories, verbose }
|
|
3972
|
+
);
|
|
3973
|
+
validateFilterOption(
|
|
3974
|
+
"onlyCategories",
|
|
3975
|
+
{ plugins, categories },
|
|
3976
|
+
{ itemsToFilter: onlyCategories, verbose }
|
|
3977
|
+
);
|
|
3978
|
+
return applyFilters(categories, skipCategories, onlyCategories, "slug");
|
|
3979
|
+
}
|
|
3980
|
+
function applyPluginFilters({ categories, plugins }, skipPlugins, onlyPlugins, verbose) {
|
|
3981
|
+
const filteredPlugins = filterPluginsFromCategories({
|
|
3982
|
+
categories,
|
|
3983
|
+
plugins
|
|
3984
|
+
});
|
|
3985
|
+
if (skipPlugins.length === 0 && onlyPlugins.length === 0) {
|
|
3986
|
+
return filteredPlugins;
|
|
3987
|
+
}
|
|
3988
|
+
validateFilterOption(
|
|
3989
|
+
"skipPlugins",
|
|
3990
|
+
{ plugins: filteredPlugins, categories },
|
|
3991
|
+
{ itemsToFilter: skipPlugins, verbose }
|
|
3992
|
+
);
|
|
3993
|
+
validateFilterOption(
|
|
3994
|
+
"onlyPlugins",
|
|
3995
|
+
{ plugins: filteredPlugins, categories },
|
|
3996
|
+
{ itemsToFilter: onlyPlugins, verbose }
|
|
3997
|
+
);
|
|
3998
|
+
return applyFilters(filteredPlugins, skipPlugins, onlyPlugins, "slug");
|
|
3999
|
+
}
|
|
4000
|
+
function filterPluginsFromCategories({
|
|
4001
|
+
categories,
|
|
4002
|
+
plugins
|
|
4003
|
+
}) {
|
|
4004
|
+
const validPluginSlugs = new Set(
|
|
4005
|
+
categories.flatMap((category) => category.refs.map((ref) => ref.plugin))
|
|
4006
|
+
);
|
|
4007
|
+
return categories.length > 0 ? plugins.filter((plugin) => validPluginSlugs.has(plugin.slug)) : plugins;
|
|
4008
|
+
}
|
|
3842
4009
|
|
|
3843
4010
|
// packages/cli/src/lib/middlewares.ts
|
|
3844
4011
|
var middlewares = [
|
|
@@ -3847,7 +4014,7 @@ var middlewares = [
|
|
|
3847
4014
|
applyBeforeValidation: false
|
|
3848
4015
|
},
|
|
3849
4016
|
{
|
|
3850
|
-
middlewareFunction:
|
|
4017
|
+
middlewareFunction: filterMiddleware,
|
|
3851
4018
|
applyBeforeValidation: false
|
|
3852
4019
|
}
|
|
3853
4020
|
];
|
|
@@ -3924,14 +4091,12 @@ function yargsGlobalOptionsDefinition() {
|
|
|
3924
4091
|
var options = {
|
|
3925
4092
|
...yargsGlobalOptionsDefinition(),
|
|
3926
4093
|
...yargsCoreConfigOptionsDefinition(),
|
|
3927
|
-
...
|
|
3928
|
-
...yargsSkipPluginsOptionsDefinition()
|
|
4094
|
+
...yargsFilterOptionsDefinition()
|
|
3929
4095
|
};
|
|
3930
4096
|
var groups = {
|
|
3931
4097
|
"Global Options:": [
|
|
3932
4098
|
...Object.keys(yargsGlobalOptionsDefinition()),
|
|
3933
|
-
...Object.keys(
|
|
3934
|
-
...Object.keys(yargsSkipPluginsOptionsDefinition())
|
|
4099
|
+
...Object.keys(yargsFilterOptionsDefinition())
|
|
3935
4100
|
],
|
|
3936
4101
|
"Persist Options:": Object.keys(yargsPersistConfigOptionsDefinition()),
|
|
3937
4102
|
"Upload Options:": Object.keys(yargsUploadConfigOptionsDefinition())
|
|
@@ -3939,10 +4104,10 @@ var groups = {
|
|
|
3939
4104
|
|
|
3940
4105
|
// packages/cli/src/lib/yargs-cli.ts
|
|
3941
4106
|
import { blue, dim as dim2, green as green4 } from "ansis";
|
|
3942
|
-
import
|
|
4107
|
+
import yargs2 from "yargs";
|
|
3943
4108
|
|
|
3944
4109
|
// packages/cli/package.json
|
|
3945
|
-
var version2 = "0.
|
|
4110
|
+
var version2 = "0.53.0";
|
|
3946
4111
|
|
|
3947
4112
|
// packages/cli/src/lib/implementation/formatting.ts
|
|
3948
4113
|
import { bold as bold13, dim, green as green3 } from "ansis";
|
|
@@ -3994,7 +4159,7 @@ function yargsCli(argv, cfg) {
|
|
|
3994
4159
|
const options2 = cfg.options ?? {};
|
|
3995
4160
|
const groups2 = cfg.groups ?? {};
|
|
3996
4161
|
const examples = cfg.examples ?? [];
|
|
3997
|
-
const cli2 =
|
|
4162
|
+
const cli2 = yargs2(argv);
|
|
3998
4163
|
cli2.updateLocale(yargsDecorator).wrap(Math.max(TERMINAL_WIDTH, cli2.terminalWidth())).help("help", descriptionStyle("Show help")).alias("h", "help").showHelpOnFail(false).version("version", dim2`Show version`, version2).check((args) => {
|
|
3999
4164
|
const persist = args["persist"];
|
|
4000
4165
|
return persist == null || validatePersistFormat(persist);
|
package/package.json
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@code-pushup/cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.53.0",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"description": "A CLI to run all kinds of code quality measurements to align your team with company goals",
|
|
6
6
|
"bin": {
|
|
7
7
|
"code-pushup": "index.js"
|
|
8
8
|
},
|
|
9
9
|
"dependencies": {
|
|
10
|
-
"@code-pushup/models": "0.
|
|
11
|
-
"@code-pushup/core": "0.
|
|
12
|
-
"@code-pushup/utils": "0.
|
|
10
|
+
"@code-pushup/models": "0.53.0",
|
|
11
|
+
"@code-pushup/core": "0.53.0",
|
|
12
|
+
"@code-pushup/utils": "0.53.0",
|
|
13
13
|
"yargs": "^17.7.2",
|
|
14
14
|
"ansis": "^3.3.0",
|
|
15
15
|
"simple-git": "^3.20.0"
|
|
@@ -23,6 +23,9 @@
|
|
|
23
23
|
"url": "git+https://github.com/code-pushup/cli.git",
|
|
24
24
|
"directory": "packages/cli"
|
|
25
25
|
},
|
|
26
|
+
"publishConfig": {
|
|
27
|
+
"access": "public"
|
|
28
|
+
},
|
|
26
29
|
"type": "module",
|
|
27
30
|
"main": "./index.js",
|
|
28
31
|
"types": "./src/index.d.ts"
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import { type CoreConfig, type Format } from '@code-pushup/models';
|
|
2
2
|
import type { CoreConfigCliOptions } from './core-config.model';
|
|
3
|
+
import type { FilterOptions } from './filter.model';
|
|
3
4
|
import type { GeneralCliOptions } from './global.model';
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
export type CoreConfigMiddlewareOptions = GeneralCliOptions & CoreConfigCliOptions & OnlyPluginsOptions & SkipPluginsOptions;
|
|
7
|
-
export declare function coreConfigMiddleware<T extends CoreConfigMiddlewareOptions>(processArgs: T): Promise<GeneralCliOptions & CoreConfig & OnlyPluginsOptions & SkipPluginsOptions>;
|
|
5
|
+
export type CoreConfigMiddlewareOptions = GeneralCliOptions & CoreConfigCliOptions & FilterOptions;
|
|
6
|
+
export declare function coreConfigMiddleware<T extends CoreConfigMiddlewareOptions>(processArgs: T): Promise<GeneralCliOptions & CoreConfig & FilterOptions>;
|
|
8
7
|
export declare const normalizeFormats: (formats?: string[]) => Format[];
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { GlobalOptions } from '@code-pushup/core';
|
|
2
|
+
import type { CategoryConfig, CoreConfig, PluginConfig } from '@code-pushup/models';
|
|
3
|
+
export type FilterOptions = Partial<GlobalOptions> & Pick<CoreConfig, 'categories' | 'plugins'> & FilterCliOptions;
|
|
4
|
+
export type FilterCliOptions = Partial<Record<FilterOptionType, string[]>>;
|
|
5
|
+
export type FilterOptionType = 'skipCategories' | 'onlyCategories' | 'skipPlugins' | 'onlyPlugins';
|
|
6
|
+
export type Filterables = {
|
|
7
|
+
categories: CategoryConfig[];
|
|
8
|
+
plugins: PluginConfig[];
|
|
9
|
+
};
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { Options } from 'yargs';
|
|
2
|
+
import type { FilterCliOptions } from './filter.model';
|
|
3
|
+
export declare const skipCategoriesOption: Options;
|
|
4
|
+
export declare const onlyCategoriesOption: Options;
|
|
5
|
+
export declare const skipPluginsOption: Options;
|
|
6
|
+
export declare const onlyPluginsOption: Options;
|
|
7
|
+
export declare function yargsFilterOptionsDefinition(): Record<keyof FilterCliOptions, Options>;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { CategoryConfig, PluginConfig } from '@code-pushup/models';
|
|
2
|
+
import type { FilterOptionType, Filterables } from './filter.model';
|
|
3
|
+
export declare class OptionValidationError extends Error {
|
|
4
|
+
}
|
|
5
|
+
export declare function validateFilterOption(option: FilterOptionType, { plugins, categories }: Filterables, { itemsToFilter, verbose }: {
|
|
6
|
+
itemsToFilter: string[];
|
|
7
|
+
verbose: boolean;
|
|
8
|
+
}): void;
|
|
9
|
+
export declare function validateFinalState(filteredItems: Filterables, originalItems: Filterables): void;
|
|
10
|
+
export declare function isOnlyOption(option: FilterOptionType): boolean;
|
|
11
|
+
export declare function getItemType(option: FilterOptionType, count: number): string;
|
|
12
|
+
export declare function createValidationMessage(option: FilterOptionType, invalidItems: string[], validItems: Pick<PluginConfig | CategoryConfig, 'slug'>[]): string;
|
|
13
|
+
export declare function handleConflictingOptions(type: 'categories' | 'plugins', onlyItems: string[], skipItems: string[]): void;
|
package/src/lib/options.d.ts
CHANGED
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
import type { GlobalOptions } from '@code-pushup/core';
|
|
2
|
-
import type { CoreConfig } from '@code-pushup/models';
|
|
3
|
-
export type OnlyPluginsCliOptions = {
|
|
4
|
-
onlyPlugins?: string[];
|
|
5
|
-
};
|
|
6
|
-
export type OnlyPluginsOptions = Partial<GlobalOptions> & Pick<CoreConfig, 'categories' | 'plugins'> & OnlyPluginsCliOptions;
|
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
import type { GlobalOptions } from '@code-pushup/core';
|
|
2
|
-
import type { CoreConfig } from '@code-pushup/models';
|
|
3
|
-
export type SkipPluginsCliOptions = {
|
|
4
|
-
skipPlugins?: string[];
|
|
5
|
-
};
|
|
6
|
-
export type SkipPluginsOptions = Partial<GlobalOptions> & Pick<CoreConfig, 'categories' | 'plugins'> & SkipPluginsCliOptions;
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
import type { CategoryConfig, PluginConfig } from '@code-pushup/models';
|
|
2
|
-
export declare function validatePluginFilterOption(filterOption: 'onlyPlugins' | 'skipPlugins', { plugins, categories, }: {
|
|
3
|
-
plugins: PluginConfig[];
|
|
4
|
-
categories: CategoryConfig[];
|
|
5
|
-
}, { pluginsToFilter, verbose, }?: {
|
|
6
|
-
pluginsToFilter?: string[];
|
|
7
|
-
verbose?: boolean;
|
|
8
|
-
}): void;
|