@code-pushup/cli 0.4.5 → 0.5.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/README.md
CHANGED
|
@@ -144,6 +144,7 @@ Each example is fully tested to give demonstrate best practices for plugin testi
|
|
|
144
144
|
**Example for custom plugins:**
|
|
145
145
|
|
|
146
146
|
- [File Size](../../examples/plugins/src/file-size)
|
|
147
|
+
- [Package Json](../../examples/plugins/src/package-json)
|
|
147
148
|
|
|
148
149
|
## CLI commands and options
|
|
149
150
|
|
package/index.js
CHANGED
|
@@ -137,12 +137,14 @@ function scorableSchema(description, refSchema, duplicateCheckFn, duplicateMessa
|
|
|
137
137
|
return z.object(
|
|
138
138
|
{
|
|
139
139
|
slug: slugSchema('Human-readable unique ID, e.g. "performance"'),
|
|
140
|
-
refs: z.array(refSchema).refine(
|
|
140
|
+
refs: z.array(refSchema).min(1).refine(
|
|
141
141
|
(refs) => !duplicateCheckFn(refs),
|
|
142
142
|
(refs) => ({
|
|
143
143
|
message: duplicateMessageFn(refs)
|
|
144
144
|
})
|
|
145
|
-
)
|
|
145
|
+
).refine(hasWeightedRefsInCategories, () => ({
|
|
146
|
+
message: `In a category there has to be at least one ref with weight > 0`
|
|
147
|
+
}))
|
|
146
148
|
},
|
|
147
149
|
{ description }
|
|
148
150
|
);
|
|
@@ -151,6 +153,9 @@ var materialIconSchema = z.enum(
|
|
|
151
153
|
MATERIAL_ICONS,
|
|
152
154
|
{ description: "Icon from VSCode Material Icons extension" }
|
|
153
155
|
);
|
|
156
|
+
function hasWeightedRefsInCategories(categoryRefs) {
|
|
157
|
+
return categoryRefs.reduce((acc, { weight }) => weight + acc, 0) !== 0;
|
|
158
|
+
}
|
|
154
159
|
|
|
155
160
|
// packages/models/src/lib/category-config.ts
|
|
156
161
|
var categoryRefSchema = weightedRefSchema(
|
|
@@ -196,6 +201,23 @@ function getDuplicateRefsInCategoryMetrics(metrics) {
|
|
|
196
201
|
metrics.map(({ slug, type, plugin }) => `${type} :: ${plugin} / ${slug}`)
|
|
197
202
|
);
|
|
198
203
|
}
|
|
204
|
+
var categoriesSchema = z2.array(categoryConfigSchema, {
|
|
205
|
+
description: "Categorization of individual audits"
|
|
206
|
+
}).min(1).refine(
|
|
207
|
+
(categoryCfg) => !getDuplicateSlugCategories(categoryCfg),
|
|
208
|
+
(categoryCfg) => ({
|
|
209
|
+
message: duplicateSlugCategoriesErrorMsg(categoryCfg)
|
|
210
|
+
})
|
|
211
|
+
);
|
|
212
|
+
function duplicateSlugCategoriesErrorMsg(categories) {
|
|
213
|
+
const duplicateStringSlugs = getDuplicateSlugCategories(categories);
|
|
214
|
+
return `In the categories, the following slugs are duplicated: ${errorItems(
|
|
215
|
+
duplicateStringSlugs
|
|
216
|
+
)}`;
|
|
217
|
+
}
|
|
218
|
+
function getDuplicateSlugCategories(categories) {
|
|
219
|
+
return hasDuplicateStrings(categories.map(({ slug }) => slug));
|
|
220
|
+
}
|
|
199
221
|
|
|
200
222
|
// packages/models/src/lib/core-config.ts
|
|
201
223
|
import { z as z11 } from "zod";
|
|
@@ -204,10 +226,10 @@ import { z as z11 } from "zod";
|
|
|
204
226
|
import { z as z3 } from "zod";
|
|
205
227
|
var formatSchema = z3.enum(["json", "md"]);
|
|
206
228
|
var persistConfigSchema = z3.object({
|
|
207
|
-
outputDir: filePathSchema("Artifacts folder"),
|
|
208
|
-
filename: fileNameSchema(
|
|
209
|
-
"
|
|
210
|
-
),
|
|
229
|
+
outputDir: filePathSchema("Artifacts folder").optional(),
|
|
230
|
+
filename: fileNameSchema(
|
|
231
|
+
"Artifacts file name (without extension)"
|
|
232
|
+
).optional(),
|
|
211
233
|
format: z3.array(formatSchema).default(["json"]).optional()
|
|
212
234
|
// @TODO remove default or optional value and otherwise it will not set defaults.
|
|
213
235
|
});
|
|
@@ -443,17 +465,10 @@ var unrefinedCoreConfigSchema = z11.object({
|
|
|
443
465
|
description: "List of plugins to be used (official, community-provided, or custom)"
|
|
444
466
|
}),
|
|
445
467
|
/** portal configuration for persisting results */
|
|
446
|
-
persist: persistConfigSchema,
|
|
468
|
+
persist: persistConfigSchema.optional(),
|
|
447
469
|
/** portal configuration for uploading results */
|
|
448
470
|
upload: uploadConfigSchema.optional(),
|
|
449
|
-
categories:
|
|
450
|
-
description: "Categorization of individual audits"
|
|
451
|
-
}).refine(
|
|
452
|
-
(categoryCfg) => !getDuplicateSlugCategories(categoryCfg),
|
|
453
|
-
(categoryCfg) => ({
|
|
454
|
-
message: duplicateSlugCategoriesErrorMsg(categoryCfg)
|
|
455
|
-
})
|
|
456
|
-
)
|
|
471
|
+
categories: categoriesSchema
|
|
457
472
|
});
|
|
458
473
|
var coreConfigSchema = refineCoreConfig(unrefinedCoreConfigSchema);
|
|
459
474
|
function refineCoreConfig(schema) {
|
|
@@ -504,15 +519,11 @@ function getMissingRefsForCategories(coreCfg) {
|
|
|
504
519
|
}
|
|
505
520
|
return missingRefs.length ? missingRefs : false;
|
|
506
521
|
}
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
}
|
|
513
|
-
function getDuplicateSlugCategories(categories) {
|
|
514
|
-
return hasDuplicateStrings(categories.map(({ slug }) => slug));
|
|
515
|
-
}
|
|
522
|
+
|
|
523
|
+
// packages/models/src/lib/implementation/constants.ts
|
|
524
|
+
var PERSIST_OUTPUT_DIR = ".code-pushup";
|
|
525
|
+
var PERSIST_FORMAT = ["json"];
|
|
526
|
+
var PERSIST_FILENAME = "report";
|
|
516
527
|
|
|
517
528
|
// packages/models/src/lib/report.ts
|
|
518
529
|
import { z as z12 } from "zod";
|
|
@@ -1399,6 +1410,11 @@ function calculateScore(refs, scoreFn) {
|
|
|
1399
1410
|
},
|
|
1400
1411
|
{ numerator: 0, denominator: 0 }
|
|
1401
1412
|
);
|
|
1413
|
+
if (!numerator && !denominator) {
|
|
1414
|
+
throw new Error(
|
|
1415
|
+
"0 division for score. This can be caused by refs only weighted with 0 or empty refs"
|
|
1416
|
+
);
|
|
1417
|
+
}
|
|
1402
1418
|
return numerator / denominator;
|
|
1403
1419
|
}
|
|
1404
1420
|
function scoreReport(report) {
|
|
@@ -1481,11 +1497,8 @@ var PersistError = class extends Error {
|
|
|
1481
1497
|
super(`fileName: ${reportPath} could not be saved.`);
|
|
1482
1498
|
}
|
|
1483
1499
|
};
|
|
1484
|
-
async function persistReport(report,
|
|
1485
|
-
const {
|
|
1486
|
-
const outputDir = persist.outputDir;
|
|
1487
|
-
const filename = persist.filename;
|
|
1488
|
-
const format = persist.format ?? [];
|
|
1500
|
+
async function persistReport(report, options2) {
|
|
1501
|
+
const { outputDir, filename, format } = options2;
|
|
1489
1502
|
let scoredReport = scoreReport(report);
|
|
1490
1503
|
console.info(reportToStdout(scoredReport));
|
|
1491
1504
|
const results = [
|
|
@@ -1640,7 +1653,7 @@ function auditOutputsCorrelateWithPluginOutput(auditOutputs, pluginConfigAudits)
|
|
|
1640
1653
|
|
|
1641
1654
|
// packages/core/package.json
|
|
1642
1655
|
var name = "@code-pushup/core";
|
|
1643
|
-
var version = "0.
|
|
1656
|
+
var version = "0.5.1";
|
|
1644
1657
|
|
|
1645
1658
|
// packages/core/src/lib/implementation/collect.ts
|
|
1646
1659
|
async function collect(options2) {
|
|
@@ -1738,16 +1751,23 @@ function transformSeverity(severity) {
|
|
|
1738
1751
|
}
|
|
1739
1752
|
}
|
|
1740
1753
|
|
|
1754
|
+
// packages/core/src/lib/normalize.ts
|
|
1755
|
+
var normalizePersistConfig = (cfg) => ({
|
|
1756
|
+
outputDir: PERSIST_OUTPUT_DIR,
|
|
1757
|
+
filename: PERSIST_FILENAME,
|
|
1758
|
+
format: PERSIST_FORMAT,
|
|
1759
|
+
...cfg
|
|
1760
|
+
});
|
|
1761
|
+
|
|
1741
1762
|
// packages/core/src/lib/upload.ts
|
|
1742
1763
|
async function upload(options2, uploadFn = uploadToPortal) {
|
|
1743
|
-
|
|
1744
|
-
|
|
1764
|
+
const persist = normalizePersistConfig(options2?.persist);
|
|
1765
|
+
if (!options2?.upload) {
|
|
1766
|
+
throw new Error("upload config must be set");
|
|
1745
1767
|
}
|
|
1746
1768
|
const { apiKey, server, organization, project } = options2.upload;
|
|
1747
|
-
const { outputDir, filename } = options2.persist;
|
|
1748
1769
|
const report = await loadReport({
|
|
1749
|
-
|
|
1750
|
-
filename,
|
|
1770
|
+
...persist,
|
|
1751
1771
|
format: "json"
|
|
1752
1772
|
});
|
|
1753
1773
|
const commitData = await getLatestCommit();
|
|
@@ -1767,7 +1787,8 @@ async function upload(options2, uploadFn = uploadToPortal) {
|
|
|
1767
1787
|
async function collectAndPersistReports(options2) {
|
|
1768
1788
|
const { exec } = verboseUtils(options2.verbose);
|
|
1769
1789
|
const report = await collect(options2);
|
|
1770
|
-
const
|
|
1790
|
+
const persist = normalizePersistConfig(options2?.persist);
|
|
1791
|
+
const persistResults = await persistReport(report, persist);
|
|
1771
1792
|
exec(() => logPersistedResults(persistResults));
|
|
1772
1793
|
report.plugins.forEach((plugin) => {
|
|
1773
1794
|
pluginReportSchema.parse(plugin);
|
|
@@ -1791,7 +1812,7 @@ async function readCodePushupConfig(filepath) {
|
|
|
1791
1812
|
{
|
|
1792
1813
|
filepath
|
|
1793
1814
|
},
|
|
1794
|
-
coreConfigSchema.parse
|
|
1815
|
+
(d) => coreConfigSchema.parse(d)
|
|
1795
1816
|
);
|
|
1796
1817
|
}
|
|
1797
1818
|
|
|
@@ -1961,9 +1982,13 @@ async function configMiddleware(processArgs) {
|
|
|
1961
1982
|
...importedRc.upload,
|
|
1962
1983
|
...cliOptions.upload
|
|
1963
1984
|
},
|
|
1985
|
+
// we can't use a async rc file as yargs does not support it. see: https://github.com/yargs/yargs/issues/2234
|
|
1986
|
+
// therefore this can't live in option defaults as the order would be `config`->`provided options`->default
|
|
1987
|
+
// so we have to manually implement the order
|
|
1964
1988
|
persist: {
|
|
1965
|
-
|
|
1966
|
-
|
|
1989
|
+
outputDir: cliOptions?.persist?.outputDir || importedRc?.persist?.outputDir || PERSIST_OUTPUT_DIR,
|
|
1990
|
+
filename: cliOptions?.persist?.filename || importedRc?.persist?.filename || PERSIST_FILENAME,
|
|
1991
|
+
format: cliOptions?.persist?.format || importedRc?.persist?.format || PERSIST_FORMAT
|
|
1967
1992
|
},
|
|
1968
1993
|
plugins: filterPluginsByOnlyPluginsOption(importedRc.plugins, cliOptions),
|
|
1969
1994
|
categories: filterCategoryByOnlyPluginsOption(
|
|
@@ -1982,6 +2007,14 @@ var middlewares = [
|
|
|
1982
2007
|
|
|
1983
2008
|
// packages/cli/src/lib/implementation/core-config-options.ts
|
|
1984
2009
|
function yargsCoreConfigOptionsDefinition() {
|
|
2010
|
+
return {
|
|
2011
|
+
// persist
|
|
2012
|
+
...yargsPersistConfigOptionsDefinition(),
|
|
2013
|
+
// upload
|
|
2014
|
+
...yargsUploadConfigOptionsDefinition()
|
|
2015
|
+
};
|
|
2016
|
+
}
|
|
2017
|
+
function yargsPersistConfigOptionsDefinition() {
|
|
1985
2018
|
return {
|
|
1986
2019
|
// persist
|
|
1987
2020
|
"persist.outputDir": {
|
|
@@ -1995,7 +2028,11 @@ function yargsCoreConfigOptionsDefinition() {
|
|
|
1995
2028
|
"persist.format": {
|
|
1996
2029
|
describe: "Format of the report output. e.g. `md`, `json`",
|
|
1997
2030
|
type: "array"
|
|
1998
|
-
}
|
|
2031
|
+
}
|
|
2032
|
+
};
|
|
2033
|
+
}
|
|
2034
|
+
function yargsUploadConfigOptionsDefinition() {
|
|
2035
|
+
return {
|
|
1999
2036
|
// upload
|
|
2000
2037
|
"upload.organization": {
|
|
2001
2038
|
describe: "Organization slug from portal",
|
package/package.json
CHANGED
|
@@ -197,11 +197,6 @@ export declare function configMiddleware<T extends Partial<GeneralCliOptions & C
|
|
|
197
197
|
docsUrl?: string | undefined;
|
|
198
198
|
}[] | undefined;
|
|
199
199
|
}[];
|
|
200
|
-
persist: {
|
|
201
|
-
outputDir: string;
|
|
202
|
-
filename: string;
|
|
203
|
-
format?: ("json" | "md")[] | undefined;
|
|
204
|
-
};
|
|
205
200
|
categories: {
|
|
206
201
|
title: string;
|
|
207
202
|
slug: string;
|
|
@@ -215,6 +210,11 @@ export declare function configMiddleware<T extends Partial<GeneralCliOptions & C
|
|
|
215
210
|
docsUrl?: string | undefined;
|
|
216
211
|
isBinary?: boolean | undefined;
|
|
217
212
|
}[];
|
|
213
|
+
persist?: {
|
|
214
|
+
outputDir?: string | undefined;
|
|
215
|
+
filename?: string | undefined;
|
|
216
|
+
format?: ("json" | "md")[] | undefined;
|
|
217
|
+
} | undefined;
|
|
218
218
|
upload?: {
|
|
219
219
|
server: string;
|
|
220
220
|
apiKey: string;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Options } from 'yargs';
|
|
2
|
-
import { CoreConfigCliOptions } from './model';
|
|
3
|
-
|
|
4
|
-
export declare function
|
|
5
|
-
export
|
|
2
|
+
import { CoreConfigCliOptions, PersistConfigCliOptions, UploadConfigCliOptions } from './model';
|
|
3
|
+
export declare function yargsCoreConfigOptionsDefinition(): Record<keyof CoreConfigCliOptions, Options>;
|
|
4
|
+
export declare function yargsPersistConfigOptionsDefinition(): Record<keyof PersistConfigCliOptions, Options>;
|
|
5
|
+
export declare function yargsUploadConfigOptionsDefinition(): Record<keyof UploadConfigCliOptions, Options>;
|