@code-pushup/cli 0.18.1 → 0.20.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -0
- package/index.js +152 -127
- package/package.json +3 -42
package/README.md
CHANGED
|
@@ -147,6 +147,10 @@ jobs:
|
|
|
147
147
|
- run: npx code-pushup autorun --upload.apiKey=${{ secrets.PORTAL_API_KEY }}
|
|
148
148
|
```
|
|
149
149
|
|
|
150
|
+
## Configuration
|
|
151
|
+
|
|
152
|
+
For a comprehensive list of all options available in the config file, refer to [`CoreConfig` docs](../models/docs/models-reference.md#coreconfig).
|
|
153
|
+
|
|
150
154
|
## Custom Plugins
|
|
151
155
|
|
|
152
156
|
We provide comprehensive documentation on [how to create a custom plugin](./docs/custom-plugins.md).
|
package/index.js
CHANGED
|
@@ -83,25 +83,15 @@ function executionMetaSchema(options2 = {
|
|
|
83
83
|
duration: z.number({ description: options2.descriptionDuration })
|
|
84
84
|
});
|
|
85
85
|
}
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
}
|
|
96
|
-
function docsUrlSchema(description = "Documentation site") {
|
|
97
|
-
return urlSchema(description).optional().or(z.string().max(0));
|
|
98
|
-
}
|
|
99
|
-
function urlSchema(description) {
|
|
100
|
-
return z.string({ description }).url();
|
|
101
|
-
}
|
|
102
|
-
function titleSchema(description = "Descriptive name") {
|
|
103
|
-
return z.string({ description }).max(MAX_TITLE_LENGTH);
|
|
104
|
-
}
|
|
86
|
+
var slugSchema = z.string({ description: "Unique ID (human-readable, URL-safe)" }).regex(slugRegex, {
|
|
87
|
+
message: "The slug has to follow the pattern [0-9a-z] followed by multiple optional groups of -[0-9a-z]. e.g. my-slug"
|
|
88
|
+
}).max(MAX_SLUG_LENGTH, {
|
|
89
|
+
message: `slug can be max ${MAX_SLUG_LENGTH} characters long`
|
|
90
|
+
});
|
|
91
|
+
var descriptionSchema = z.string({ description: "Description (markdown)" }).max(MAX_DESCRIPTION_LENGTH).optional();
|
|
92
|
+
var urlSchema = z.string().url();
|
|
93
|
+
var docsUrlSchema = urlSchema.optional().or(z.literal("")).describe("Documentation site");
|
|
94
|
+
var titleSchema = z.string({ description: "Descriptive name" }).max(MAX_TITLE_LENGTH);
|
|
105
95
|
function metaSchema(options2) {
|
|
106
96
|
const {
|
|
107
97
|
descriptionDescription,
|
|
@@ -111,24 +101,19 @@ function metaSchema(options2) {
|
|
|
111
101
|
} = options2 ?? {};
|
|
112
102
|
return z.object(
|
|
113
103
|
{
|
|
114
|
-
title: titleSchema(titleDescription),
|
|
115
|
-
description: descriptionSchema(descriptionDescription),
|
|
116
|
-
docsUrl: docsUrlSchema(docsUrlDescription)
|
|
104
|
+
title: titleDescription ? titleSchema.describe(titleDescription) : titleSchema,
|
|
105
|
+
description: descriptionDescription ? descriptionSchema.describe(descriptionDescription) : descriptionSchema,
|
|
106
|
+
docsUrl: docsUrlDescription ? docsUrlSchema.describe(docsUrlDescription) : docsUrlSchema
|
|
117
107
|
},
|
|
118
108
|
{ description }
|
|
119
109
|
);
|
|
120
110
|
}
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
}).min(1, { message: "file name is invalid" });
|
|
128
|
-
}
|
|
129
|
-
function positiveIntSchema(description) {
|
|
130
|
-
return z.number({ description }).int().nonnegative();
|
|
131
|
-
}
|
|
111
|
+
var filePathSchema = z.string().trim().min(1, { message: "path is invalid" });
|
|
112
|
+
var fileNameSchema = z.string().trim().regex(filenameRegex, {
|
|
113
|
+
message: `The filename has to be valid`
|
|
114
|
+
}).min(1, { message: "file name is invalid" });
|
|
115
|
+
var positiveIntSchema = z.number().int().positive();
|
|
116
|
+
var nonnegativeIntSchema = z.number().int().nonnegative();
|
|
132
117
|
function packageVersionSchema(options2) {
|
|
133
118
|
const { versionDescription = "NPM version of the package", required } = options2 ?? {};
|
|
134
119
|
const packageSchema = z.string({ description: "NPM package name" });
|
|
@@ -141,14 +126,14 @@ function packageVersionSchema(options2) {
|
|
|
141
126
|
{ description: "NPM package name and version of a published package" }
|
|
142
127
|
);
|
|
143
128
|
}
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
129
|
+
var weightSchema = nonnegativeIntSchema.describe(
|
|
130
|
+
"Coefficient for the given score (use weight 0 if only for display)"
|
|
131
|
+
);
|
|
147
132
|
function weightedRefSchema(description, slugDescription) {
|
|
148
133
|
return z.object(
|
|
149
134
|
{
|
|
150
|
-
slug: slugSchema(slugDescription),
|
|
151
|
-
weight: weightSchema("Weight used to calculate score")
|
|
135
|
+
slug: slugSchema.describe(slugDescription),
|
|
136
|
+
weight: weightSchema.describe("Weight used to calculate score")
|
|
152
137
|
},
|
|
153
138
|
{ description }
|
|
154
139
|
);
|
|
@@ -156,14 +141,14 @@ function weightedRefSchema(description, slugDescription) {
|
|
|
156
141
|
function scorableSchema(description, refSchema, duplicateCheckFn, duplicateMessageFn) {
|
|
157
142
|
return z.object(
|
|
158
143
|
{
|
|
159
|
-
slug: slugSchema('Human-readable unique ID, e.g. "performance"'),
|
|
144
|
+
slug: slugSchema.describe('Human-readable unique ID, e.g. "performance"'),
|
|
160
145
|
refs: z.array(refSchema).min(1).refine(
|
|
161
146
|
(refs) => !duplicateCheckFn(refs),
|
|
162
147
|
(refs) => ({
|
|
163
148
|
message: duplicateMessageFn(refs)
|
|
164
149
|
})
|
|
165
|
-
).refine(
|
|
166
|
-
message:
|
|
150
|
+
).refine(hasNonZeroWeightedRef, () => ({
|
|
151
|
+
message: "In a category there has to be at least one ref with weight > 0"
|
|
167
152
|
}))
|
|
168
153
|
},
|
|
169
154
|
{ description }
|
|
@@ -172,13 +157,13 @@ function scorableSchema(description, refSchema, duplicateCheckFn, duplicateMessa
|
|
|
172
157
|
var materialIconSchema = z.enum(MATERIAL_ICONS, {
|
|
173
158
|
description: "Icon from VSCode Material Icons extension"
|
|
174
159
|
});
|
|
175
|
-
function
|
|
176
|
-
return
|
|
160
|
+
function hasNonZeroWeightedRef(refs) {
|
|
161
|
+
return refs.reduce((acc, { weight }) => weight + acc, 0) !== 0;
|
|
177
162
|
}
|
|
178
163
|
|
|
179
164
|
// packages/models/src/lib/audit.ts
|
|
180
165
|
var auditSchema = z2.object({
|
|
181
|
-
slug: slugSchema("ID (unique within plugin)")
|
|
166
|
+
slug: slugSchema.describe("ID (unique within plugin)")
|
|
182
167
|
}).merge(
|
|
183
168
|
metaSchema({
|
|
184
169
|
titleDescription: "Descriptive name",
|
|
@@ -205,17 +190,20 @@ function getDuplicateSlugsInAudits(audits) {
|
|
|
205
190
|
return hasDuplicateStrings(audits.map(({ slug }) => slug));
|
|
206
191
|
}
|
|
207
192
|
|
|
208
|
-
// packages/models/src/lib/audit-
|
|
193
|
+
// packages/models/src/lib/audit-output.ts
|
|
194
|
+
import { z as z4 } from "zod";
|
|
195
|
+
|
|
196
|
+
// packages/models/src/lib/issue.ts
|
|
209
197
|
import { z as z3 } from "zod";
|
|
210
198
|
var sourceFileLocationSchema = z3.object(
|
|
211
199
|
{
|
|
212
|
-
file: filePathSchema("Relative path to source file in Git repo"),
|
|
200
|
+
file: filePathSchema.describe("Relative path to source file in Git repo"),
|
|
213
201
|
position: z3.object(
|
|
214
202
|
{
|
|
215
|
-
startLine: positiveIntSchema("Start line"),
|
|
216
|
-
startColumn: positiveIntSchema("Start column").optional(),
|
|
217
|
-
endLine: positiveIntSchema("End line").optional(),
|
|
218
|
-
endColumn: positiveIntSchema("End column").optional()
|
|
203
|
+
startLine: positiveIntSchema.describe("Start line"),
|
|
204
|
+
startColumn: positiveIntSchema.describe("Start column").optional(),
|
|
205
|
+
endLine: positiveIntSchema.describe("End line").optional(),
|
|
206
|
+
endColumn: positiveIntSchema.describe("End column").optional()
|
|
219
207
|
},
|
|
220
208
|
{ description: "Location in file" }
|
|
221
209
|
).optional()
|
|
@@ -235,21 +223,21 @@ var issueSchema = z3.object(
|
|
|
235
223
|
);
|
|
236
224
|
|
|
237
225
|
// packages/models/src/lib/audit-output.ts
|
|
238
|
-
|
|
226
|
+
var auditDetailsSchema = z4.object(
|
|
227
|
+
{
|
|
228
|
+
issues: z4.array(issueSchema, { description: "List of findings" })
|
|
229
|
+
},
|
|
230
|
+
{ description: "Detailed information" }
|
|
231
|
+
);
|
|
239
232
|
var auditOutputSchema = z4.object(
|
|
240
233
|
{
|
|
241
|
-
slug: slugSchema("Reference to audit"),
|
|
234
|
+
slug: slugSchema.describe("Reference to audit"),
|
|
242
235
|
displayValue: z4.string({ description: "Formatted value (e.g. '0.9 s', '2.1 MB')" }).optional(),
|
|
243
|
-
value:
|
|
236
|
+
value: nonnegativeIntSchema.describe("Raw numeric value"),
|
|
244
237
|
score: z4.number({
|
|
245
238
|
description: "Value between 0 and 1"
|
|
246
239
|
}).min(0).max(1),
|
|
247
|
-
details:
|
|
248
|
-
{
|
|
249
|
-
issues: z4.array(issueSchema, { description: "List of findings" })
|
|
250
|
-
},
|
|
251
|
-
{ description: "Detailed information" }
|
|
252
|
-
).optional()
|
|
240
|
+
details: auditDetailsSchema.optional()
|
|
253
241
|
},
|
|
254
242
|
{ description: "Audit information" }
|
|
255
243
|
);
|
|
@@ -279,7 +267,7 @@ var categoryRefSchema = weightedRefSchema(
|
|
|
279
267
|
type: z5.enum(["audit", "group"], {
|
|
280
268
|
description: "Discriminant for reference kind, affects where `slug` is looked up"
|
|
281
269
|
}),
|
|
282
|
-
plugin: slugSchema(
|
|
270
|
+
plugin: slugSchema.describe(
|
|
283
271
|
"Plugin slug (plugin should contain referenced audit or group)"
|
|
284
272
|
)
|
|
285
273
|
})
|
|
@@ -339,10 +327,8 @@ import { z as z11 } from "zod";
|
|
|
339
327
|
import { z as z6 } from "zod";
|
|
340
328
|
var formatSchema = z6.enum(["json", "md"]);
|
|
341
329
|
var persistConfigSchema = z6.object({
|
|
342
|
-
outputDir: filePathSchema("Artifacts folder").optional(),
|
|
343
|
-
filename: fileNameSchema(
|
|
344
|
-
"Artifacts file name (without extension)"
|
|
345
|
-
).optional(),
|
|
330
|
+
outputDir: filePathSchema.describe("Artifacts folder").optional(),
|
|
331
|
+
filename: fileNameSchema.describe("Artifacts file name (without extension)").optional(),
|
|
346
332
|
format: z6.array(formatSchema).optional()
|
|
347
333
|
});
|
|
348
334
|
|
|
@@ -403,7 +389,7 @@ var runnerConfigSchema = z8.object(
|
|
|
403
389
|
description: "Shell command to execute"
|
|
404
390
|
}),
|
|
405
391
|
args: z8.array(z8.string({ description: "Command arguments" })).optional(),
|
|
406
|
-
outputFile: filePathSchema("Output path"),
|
|
392
|
+
outputFile: filePathSchema.describe("Output path"),
|
|
407
393
|
outputTransform: outputTransformSchema.optional()
|
|
408
394
|
},
|
|
409
395
|
{
|
|
@@ -423,7 +409,7 @@ var pluginMetaSchema = packageVersionSchema().merge(
|
|
|
423
409
|
})
|
|
424
410
|
).merge(
|
|
425
411
|
z9.object({
|
|
426
|
-
slug: slugSchema("Unique plugin slug within core config"),
|
|
412
|
+
slug: slugSchema.describe("Unique plugin slug within core config"),
|
|
427
413
|
icon: materialIconSchema
|
|
428
414
|
})
|
|
429
415
|
);
|
|
@@ -456,12 +442,14 @@ function getMissingRefsFromGroups(pluginCfg) {
|
|
|
456
442
|
// packages/models/src/lib/upload-config.ts
|
|
457
443
|
import { z as z10 } from "zod";
|
|
458
444
|
var uploadConfigSchema = z10.object({
|
|
459
|
-
server: urlSchema("URL of deployed portal API"),
|
|
445
|
+
server: urlSchema.describe("URL of deployed portal API"),
|
|
460
446
|
apiKey: z10.string({
|
|
461
447
|
description: "API key with write access to portal (use `process.env` for security)"
|
|
462
448
|
}),
|
|
463
|
-
organization: slugSchema(
|
|
464
|
-
|
|
449
|
+
organization: slugSchema.describe(
|
|
450
|
+
"Organization slug from Code PushUp portal"
|
|
451
|
+
),
|
|
452
|
+
project: slugSchema.describe("Project slug from Code PushUp portal"),
|
|
465
453
|
timeout: z10.number({ description: "Request timeout in minutes (default is 5)" }).positive().int().optional()
|
|
466
454
|
});
|
|
467
455
|
|
|
@@ -971,16 +959,35 @@ function executeProcess(cfg) {
|
|
|
971
959
|
});
|
|
972
960
|
}
|
|
973
961
|
|
|
962
|
+
// packages/utils/src/lib/transform.ts
|
|
963
|
+
function toArray(val) {
|
|
964
|
+
return Array.isArray(val) ? val : [val];
|
|
965
|
+
}
|
|
966
|
+
function deepClone(obj) {
|
|
967
|
+
return obj == null || typeof obj !== "object" ? obj : structuredClone(obj);
|
|
968
|
+
}
|
|
969
|
+
function toUnixPath(path) {
|
|
970
|
+
return path.replace(/\\/g, "/");
|
|
971
|
+
}
|
|
972
|
+
|
|
974
973
|
// packages/utils/src/lib/git.ts
|
|
974
|
+
import { isAbsolute, join as join2, relative } from "node:path";
|
|
975
975
|
import { simpleGit } from "simple-git";
|
|
976
|
-
|
|
977
|
-
async function getLatestCommit() {
|
|
976
|
+
async function getLatestCommit(git = simpleGit()) {
|
|
978
977
|
const log = await git.log({
|
|
979
978
|
maxCount: 1,
|
|
980
979
|
format: { hash: "%H", message: "%s", author: "%an", date: "%ad" }
|
|
981
980
|
});
|
|
982
981
|
return log.latest;
|
|
983
982
|
}
|
|
983
|
+
function getGitRoot(git = simpleGit()) {
|
|
984
|
+
return git.revparse("--show-toplevel");
|
|
985
|
+
}
|
|
986
|
+
function formatGitPath(path, gitRoot) {
|
|
987
|
+
const absolutePath = isAbsolute(path) ? path : join2(process.cwd(), path);
|
|
988
|
+
const relativePath = relative(gitRoot, absolutePath);
|
|
989
|
+
return toUnixPath(relativePath);
|
|
990
|
+
}
|
|
984
991
|
function validateCommitData(commitData, options2 = {}) {
|
|
985
992
|
const { throwError = false } = options2;
|
|
986
993
|
if (!commitData) {
|
|
@@ -1003,18 +1010,24 @@ function groupByStatus(results) {
|
|
|
1003
1010
|
);
|
|
1004
1011
|
}
|
|
1005
1012
|
|
|
1006
|
-
// packages/utils/src/lib/
|
|
1013
|
+
// packages/utils/src/lib/logging.ts
|
|
1007
1014
|
import chalk2 from "chalk";
|
|
1015
|
+
function link(text) {
|
|
1016
|
+
return chalk2.underline(chalk2.blueBright(text));
|
|
1017
|
+
}
|
|
1018
|
+
|
|
1019
|
+
// packages/utils/src/lib/progress.ts
|
|
1020
|
+
import chalk3 from "chalk";
|
|
1008
1021
|
import { MultiProgressBars } from "multi-progress-bars";
|
|
1009
1022
|
var barStyles = {
|
|
1010
|
-
active: (s) =>
|
|
1011
|
-
done: (s) =>
|
|
1012
|
-
idle: (s) =>
|
|
1023
|
+
active: (s) => chalk3.green(s),
|
|
1024
|
+
done: (s) => chalk3.gray(s),
|
|
1025
|
+
idle: (s) => chalk3.gray(s)
|
|
1013
1026
|
};
|
|
1014
1027
|
var messageStyles = {
|
|
1015
|
-
active: (s) =>
|
|
1016
|
-
done: (s) =>
|
|
1017
|
-
idle: (s) =>
|
|
1028
|
+
active: (s) => chalk3.black(s),
|
|
1029
|
+
done: (s) => chalk3.green(chalk3.bold(s)),
|
|
1030
|
+
idle: (s) => chalk3.gray(s)
|
|
1018
1031
|
};
|
|
1019
1032
|
var mpb;
|
|
1020
1033
|
function getSingletonProgressBars(options2) {
|
|
@@ -1094,7 +1107,7 @@ function h3(text) {
|
|
|
1094
1107
|
}
|
|
1095
1108
|
|
|
1096
1109
|
// packages/utils/src/lib/reports/md/link.ts
|
|
1097
|
-
function
|
|
1110
|
+
function link2(href, text) {
|
|
1098
1111
|
return `[${text || href}](${href})`;
|
|
1099
1112
|
}
|
|
1100
1113
|
|
|
@@ -1145,7 +1158,7 @@ function generateMdReport(report, commitData) {
|
|
|
1145
1158
|
(printCategories ? reportToCategoriesSection(report) + NEW_LINE + NEW_LINE : "") + // audits section
|
|
1146
1159
|
reportToAuditsSection(report) + NEW_LINE + NEW_LINE + // about section
|
|
1147
1160
|
reportToAboutSection(report, commitData) + NEW_LINE + NEW_LINE + // footer section
|
|
1148
|
-
`${FOOTER_PREFIX} ${
|
|
1161
|
+
`${FOOTER_PREFIX} ${link2(README_LINK, "Code PushUp")}`
|
|
1149
1162
|
);
|
|
1150
1163
|
}
|
|
1151
1164
|
function reportToHeaderSection() {
|
|
@@ -1156,7 +1169,7 @@ function reportToOverviewSection(report) {
|
|
|
1156
1169
|
const tableContent = [
|
|
1157
1170
|
reportOverviewTableHeaders,
|
|
1158
1171
|
...categories.map(({ title, refs, score }) => [
|
|
1159
|
-
|
|
1172
|
+
link2(`#${slugify(title)}`, title),
|
|
1160
1173
|
`${getRoundScoreMarker(score)} ${style(formatReportScore(score))}`,
|
|
1161
1174
|
countCategoryAudits(refs, plugins).toString()
|
|
1162
1175
|
])
|
|
@@ -1188,7 +1201,7 @@ function reportToCategoriesSection(report) {
|
|
|
1188
1201
|
}
|
|
1189
1202
|
function auditItemToCategorySection(audit, plugins) {
|
|
1190
1203
|
const pluginTitle = getPluginNameFromSlug(audit.plugin, plugins);
|
|
1191
|
-
const auditTitle =
|
|
1204
|
+
const auditTitle = link2(
|
|
1192
1205
|
`#${slugify(audit.title)}-${slugify(pluginTitle)}`,
|
|
1193
1206
|
audit.title
|
|
1194
1207
|
);
|
|
@@ -1205,7 +1218,7 @@ function groupItemToCategorySection(group, plugins) {
|
|
|
1205
1218
|
`${getRoundScoreMarker(groupScore)} ${group.title} (_${pluginTitle}_)`
|
|
1206
1219
|
);
|
|
1207
1220
|
const groupAudits = group.audits.reduce((acc, audit) => {
|
|
1208
|
-
const auditTitle =
|
|
1221
|
+
const auditTitle = link2(
|
|
1209
1222
|
`#${slugify(audit.title)}-${slugify(pluginTitle)}`,
|
|
1210
1223
|
audit.title
|
|
1211
1224
|
);
|
|
@@ -1292,7 +1305,7 @@ function getDocsAndDescription({
|
|
|
1292
1305
|
description
|
|
1293
1306
|
}) {
|
|
1294
1307
|
if (docsUrl) {
|
|
1295
|
-
const docsLink =
|
|
1308
|
+
const docsLink = link2(docsUrl, "\u{1F4D6} Docs");
|
|
1296
1309
|
if (!description) {
|
|
1297
1310
|
return docsLink + NEW_LINE + NEW_LINE;
|
|
1298
1311
|
}
|
|
@@ -1313,7 +1326,7 @@ function getAuditResult(audit, isHtml = false) {
|
|
|
1313
1326
|
|
|
1314
1327
|
// packages/utils/src/lib/reports/generate-stdout-summary.ts
|
|
1315
1328
|
import cliui from "@isaacs/cliui";
|
|
1316
|
-
import
|
|
1329
|
+
import chalk4 from "chalk";
|
|
1317
1330
|
import CliTable3 from "cli-table3";
|
|
1318
1331
|
function addLine(line = "") {
|
|
1319
1332
|
return line + NEW_LINE;
|
|
@@ -1324,7 +1337,7 @@ function generateStdoutSummary(report) {
|
|
|
1324
1337
|
}
|
|
1325
1338
|
function reportToHeaderSection2(report) {
|
|
1326
1339
|
const { packageName, version: version2 } = report;
|
|
1327
|
-
return `${
|
|
1340
|
+
return `${chalk4.bold(reportHeadlineText)} - ${packageName}@${version2}`;
|
|
1328
1341
|
}
|
|
1329
1342
|
function reportToDetailSection(report) {
|
|
1330
1343
|
const { plugins } = report;
|
|
@@ -1344,13 +1357,13 @@ function reportToDetailSection(report) {
|
|
|
1344
1357
|
padding: [0, 3, 0, 0]
|
|
1345
1358
|
},
|
|
1346
1359
|
{
|
|
1347
|
-
text:
|
|
1360
|
+
text: chalk4.cyanBright(audit.displayValue || `${audit.value}`),
|
|
1348
1361
|
width: 10,
|
|
1349
1362
|
padding: [0, 0, 0, 0]
|
|
1350
1363
|
}
|
|
1351
1364
|
);
|
|
1352
1365
|
});
|
|
1353
|
-
return acc + addLine() + addLine(
|
|
1366
|
+
return acc + addLine() + addLine(chalk4.magentaBright.bold(`${title} audits`)) + addLine() + addLine(ui2.toString()) + addLine();
|
|
1354
1367
|
}, "");
|
|
1355
1368
|
}
|
|
1356
1369
|
function reportToOverviewSection2({
|
|
@@ -1373,11 +1386,11 @@ function reportToOverviewSection2({
|
|
|
1373
1386
|
countCategoryAudits(refs, plugins)
|
|
1374
1387
|
])
|
|
1375
1388
|
);
|
|
1376
|
-
return addLine(
|
|
1389
|
+
return addLine(chalk4.magentaBright.bold("Categories")) + addLine() + addLine(table.toString());
|
|
1377
1390
|
}
|
|
1378
1391
|
function withColor({ score, text }) {
|
|
1379
1392
|
const formattedScore = text ?? formatReportScore(score);
|
|
1380
|
-
const style2 = text ?
|
|
1393
|
+
const style2 = text ? chalk4 : chalk4.bold;
|
|
1381
1394
|
if (score >= SCORE_COLOR_RANGE.GREEN_MIN) {
|
|
1382
1395
|
return style2.green(formattedScore);
|
|
1383
1396
|
}
|
|
@@ -1387,14 +1400,6 @@ function withColor({ score, text }) {
|
|
|
1387
1400
|
return style2.red(formattedScore);
|
|
1388
1401
|
}
|
|
1389
1402
|
|
|
1390
|
-
// packages/utils/src/lib/transform.ts
|
|
1391
|
-
function toArray(val) {
|
|
1392
|
-
return Array.isArray(val) ? val : [val];
|
|
1393
|
-
}
|
|
1394
|
-
function deepClone(obj) {
|
|
1395
|
-
return obj == null || typeof obj !== "object" ? obj : structuredClone(obj);
|
|
1396
|
-
}
|
|
1397
|
-
|
|
1398
1403
|
// packages/utils/src/lib/reports/scoring.ts
|
|
1399
1404
|
var GroupRefInvalidError = class extends Error {
|
|
1400
1405
|
constructor(auditSlug, pluginSlug) {
|
|
@@ -1555,21 +1560,48 @@ var verboseUtils = (verbose = false) => ({
|
|
|
1555
1560
|
exec: getExecVerbose(verbose)
|
|
1556
1561
|
});
|
|
1557
1562
|
|
|
1558
|
-
// packages/utils/src/lib/logging.ts
|
|
1559
|
-
import chalk4 from "chalk";
|
|
1560
|
-
function link2(text) {
|
|
1561
|
-
return chalk4.underline(chalk4.blueBright(text));
|
|
1562
|
-
}
|
|
1563
|
-
|
|
1564
1563
|
// packages/core/package.json
|
|
1565
1564
|
var name = "@code-pushup/core";
|
|
1566
|
-
var version = "0.
|
|
1565
|
+
var version = "0.20.0";
|
|
1567
1566
|
|
|
1568
1567
|
// packages/core/src/lib/implementation/execute-plugin.ts
|
|
1569
1568
|
import chalk5 from "chalk";
|
|
1570
1569
|
|
|
1570
|
+
// packages/core/src/lib/normalize.ts
|
|
1571
|
+
function normalizePersistConfig(cfg) {
|
|
1572
|
+
return {
|
|
1573
|
+
outputDir: PERSIST_OUTPUT_DIR,
|
|
1574
|
+
filename: PERSIST_FILENAME,
|
|
1575
|
+
format: PERSIST_FORMAT,
|
|
1576
|
+
...cfg
|
|
1577
|
+
};
|
|
1578
|
+
}
|
|
1579
|
+
async function normalizeAuditOutputs(audits) {
|
|
1580
|
+
const gitRoot = await getGitRoot();
|
|
1581
|
+
return audits.map((audit) => {
|
|
1582
|
+
if (audit.details?.issues == null || audit.details.issues.every((issue) => issue.source == null)) {
|
|
1583
|
+
return audit;
|
|
1584
|
+
}
|
|
1585
|
+
return {
|
|
1586
|
+
...audit,
|
|
1587
|
+
details: {
|
|
1588
|
+
...audit.details,
|
|
1589
|
+
issues: audit.details.issues.map(
|
|
1590
|
+
(issue) => issue.source == null ? issue : {
|
|
1591
|
+
...issue,
|
|
1592
|
+
source: {
|
|
1593
|
+
...issue.source,
|
|
1594
|
+
file: formatGitPath(issue.source.file, gitRoot)
|
|
1595
|
+
}
|
|
1596
|
+
}
|
|
1597
|
+
)
|
|
1598
|
+
}
|
|
1599
|
+
};
|
|
1600
|
+
});
|
|
1601
|
+
}
|
|
1602
|
+
|
|
1571
1603
|
// packages/core/src/lib/implementation/runner.ts
|
|
1572
|
-
import { join as
|
|
1604
|
+
import { join as join3 } from "node:path";
|
|
1573
1605
|
async function executeRunnerConfig(cfg, onProgress) {
|
|
1574
1606
|
const { args, command, outputFile, outputTransform } = cfg;
|
|
1575
1607
|
const { duration, date } = await executeProcess({
|
|
@@ -1577,7 +1609,7 @@ async function executeRunnerConfig(cfg, onProgress) {
|
|
|
1577
1609
|
args,
|
|
1578
1610
|
observer: { onStdout: onProgress }
|
|
1579
1611
|
});
|
|
1580
|
-
const outputs = await readJsonFile(
|
|
1612
|
+
const outputs = await readJsonFile(join3(process.cwd(), outputFile));
|
|
1581
1613
|
const audits = outputTransform ? await outputTransform(outputs) : outputs;
|
|
1582
1614
|
return {
|
|
1583
1615
|
duration,
|
|
@@ -1615,7 +1647,8 @@ async function executePlugin(pluginConfig, onProgress) {
|
|
|
1615
1647
|
const { audits: unvalidatedAuditOutputs, ...executionMeta } = runnerResult;
|
|
1616
1648
|
const auditOutputs = auditOutputsSchema.parse(unvalidatedAuditOutputs);
|
|
1617
1649
|
auditOutputsCorrelateWithPluginOutput(auditOutputs, pluginConfigAudits);
|
|
1618
|
-
const
|
|
1650
|
+
const normalizedAuditOutputs = await normalizeAuditOutputs(auditOutputs);
|
|
1651
|
+
const auditReports = normalizedAuditOutputs.map(
|
|
1619
1652
|
(auditOutput) => ({
|
|
1620
1653
|
...auditOutput,
|
|
1621
1654
|
...pluginConfigAudits.find(
|
|
@@ -1693,7 +1726,7 @@ async function collect(options2) {
|
|
|
1693
1726
|
|
|
1694
1727
|
// packages/core/src/lib/implementation/persist.ts
|
|
1695
1728
|
import { mkdir as mkdir2, stat as stat2, writeFile } from "node:fs/promises";
|
|
1696
|
-
import { join as
|
|
1729
|
+
import { join as join4 } from "node:path";
|
|
1697
1730
|
var PersistDirError = class extends Error {
|
|
1698
1731
|
constructor(outputDir) {
|
|
1699
1732
|
super(`outPath: ${outputDir} is no directory.`);
|
|
@@ -1737,7 +1770,7 @@ async function persistReport(report, options2) {
|
|
|
1737
1770
|
return Promise.allSettled(
|
|
1738
1771
|
results.map(
|
|
1739
1772
|
(result) => persistResult(
|
|
1740
|
-
|
|
1773
|
+
join4(outputDir, `${filename}.${result.format}`),
|
|
1741
1774
|
result.content
|
|
1742
1775
|
)
|
|
1743
1776
|
)
|
|
@@ -1753,14 +1786,6 @@ function logPersistedResults(persistResults) {
|
|
|
1753
1786
|
logMultipleFileResults(persistResults, "Generated reports");
|
|
1754
1787
|
}
|
|
1755
1788
|
|
|
1756
|
-
// packages/core/src/lib/normalize.ts
|
|
1757
|
-
var normalizePersistConfig = (cfg) => ({
|
|
1758
|
-
outputDir: PERSIST_OUTPUT_DIR,
|
|
1759
|
-
filename: PERSIST_FILENAME,
|
|
1760
|
-
format: PERSIST_FORMAT,
|
|
1761
|
-
...cfg
|
|
1762
|
-
});
|
|
1763
|
-
|
|
1764
1789
|
// packages/core/src/lib/collect-and-persist.ts
|
|
1765
1790
|
async function collectAndPersistReports(options2) {
|
|
1766
1791
|
const { exec } = verboseUtils(options2.verbose);
|
|
@@ -1776,7 +1801,7 @@ async function collectAndPersistReports(options2) {
|
|
|
1776
1801
|
}
|
|
1777
1802
|
|
|
1778
1803
|
// packages/core/src/lib/implementation/read-rc-file.ts
|
|
1779
|
-
import { join as
|
|
1804
|
+
import { join as join5 } from "node:path";
|
|
1780
1805
|
var ConfigPathError = class extends Error {
|
|
1781
1806
|
constructor(configPath) {
|
|
1782
1807
|
super(`Provided path '${configPath}' is not valid.`);
|
|
@@ -1809,7 +1834,7 @@ async function autoloadRc() {
|
|
|
1809
1834
|
)}) present in ${process.cwd()}`
|
|
1810
1835
|
);
|
|
1811
1836
|
}
|
|
1812
|
-
return readRcByPath(
|
|
1837
|
+
return readRcByPath(join5(process.cwd(), `${CONFIG_FILE_NAME}.${ext}`));
|
|
1813
1838
|
}
|
|
1814
1839
|
|
|
1815
1840
|
// packages/core/src/lib/upload.ts
|
|
@@ -1961,7 +1986,7 @@ function ui() {
|
|
|
1961
1986
|
function renderConfigureCategoriesHint() {
|
|
1962
1987
|
ui().logger.info(
|
|
1963
1988
|
chalk6.gray(
|
|
1964
|
-
`\u{1F4A1} Configure categories to see the scores in an overview table. See: ${
|
|
1989
|
+
`\u{1F4A1} Configure categories to see the scores in an overview table. See: ${link(
|
|
1965
1990
|
"https://github.com/code-pushup/cli/blob/main/packages/cli/README.md"
|
|
1966
1991
|
)}`
|
|
1967
1992
|
)
|
|
@@ -1970,7 +1995,7 @@ function renderConfigureCategoriesHint() {
|
|
|
1970
1995
|
function uploadSuccessfulLog(options2, commit) {
|
|
1971
1996
|
ui().logger.success("Upload successful!");
|
|
1972
1997
|
ui().logger.success(
|
|
1973
|
-
|
|
1998
|
+
link(
|
|
1974
1999
|
// @TODO extend config to maintain baseUrl under upload
|
|
1975
2000
|
portalCommitDashboardLink(
|
|
1976
2001
|
{ ...options2, baseUrl: "<YOUR_PORTAL_URL>" },
|
|
@@ -1988,15 +2013,15 @@ function renderIntegratePortalHint() {
|
|
|
1988
2013
|
"npx code-pushup upload"
|
|
1989
2014
|
)}`
|
|
1990
2015
|
).add(
|
|
1991
|
-
` ${
|
|
2016
|
+
` ${link(
|
|
1992
2017
|
"https://github.com/code-pushup/cli/tree/main/packages/cli#upload-command"
|
|
1993
2018
|
)}`
|
|
1994
2019
|
).add(
|
|
1995
|
-
`${chalk6.gray("\u276F")} ${chalk6.gray("Portal Integration")} - ${
|
|
2020
|
+
`${chalk6.gray("\u276F")} ${chalk6.gray("Portal Integration")} - ${link(
|
|
1996
2021
|
"https://github.com/code-pushup/cli/blob/main/packages/cli/README.md#portal-integration"
|
|
1997
2022
|
)}`
|
|
1998
2023
|
).add(
|
|
1999
|
-
`${chalk6.gray("\u276F")} ${chalk6.gray("Upload Command")} - ${
|
|
2024
|
+
`${chalk6.gray("\u276F")} ${chalk6.gray("Upload Command")} - ${link(
|
|
2000
2025
|
"https://github.com/code-pushup/cli/blob/main/packages/cli/README.md#portal-integration"
|
|
2001
2026
|
)}`
|
|
2002
2027
|
).render();
|
|
@@ -2111,7 +2136,7 @@ function renderUploadAutorunHint() {
|
|
|
2111
2136
|
"Run upload to upload the created report to the server"
|
|
2112
2137
|
)}`
|
|
2113
2138
|
).add(
|
|
2114
|
-
` ${
|
|
2139
|
+
` ${link(
|
|
2115
2140
|
"https://github.com/code-pushup/cli/tree/main/packages/cli#upload-command"
|
|
2116
2141
|
)}`
|
|
2117
2142
|
).add(
|
|
@@ -2119,7 +2144,7 @@ function renderUploadAutorunHint() {
|
|
|
2119
2144
|
"Run collect & upload"
|
|
2120
2145
|
)}`
|
|
2121
2146
|
).add(
|
|
2122
|
-
` ${
|
|
2147
|
+
` ${link(
|
|
2123
2148
|
"https://github.com/code-pushup/cli/tree/main/packages/cli#autorun-command"
|
|
2124
2149
|
)}`
|
|
2125
2150
|
).render();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@code-pushup/cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.20.0",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"bin": {
|
|
6
6
|
"code-pushup": "index.js"
|
|
@@ -12,44 +12,5 @@
|
|
|
12
12
|
"chalk": "^5.3.0",
|
|
13
13
|
"@code-pushup/utils": "*",
|
|
14
14
|
"@poppinss/cliui": "^6.3.0"
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
"bugs": {
|
|
18
|
-
"url": "https://github.com/code-pushup/cli/issues"
|
|
19
|
-
},
|
|
20
|
-
"repository": {
|
|
21
|
-
"type": "git",
|
|
22
|
-
"url": "https://github.com/code-pushup/cli.git",
|
|
23
|
-
"directory": "packages/cli"
|
|
24
|
-
},
|
|
25
|
-
"contributors": [
|
|
26
|
-
{
|
|
27
|
-
"name": "Igor Katsuba",
|
|
28
|
-
"email": "igor@katsuba.dev",
|
|
29
|
-
"url": "https://katsuba.dev"
|
|
30
|
-
},
|
|
31
|
-
{
|
|
32
|
-
"name": "Kateřina Pilátová",
|
|
33
|
-
"email": "katerina.pilatova@flowup.cz",
|
|
34
|
-
"url": "https://github.com/Tlacenka"
|
|
35
|
-
},
|
|
36
|
-
{
|
|
37
|
-
"name": "Matěj Chalk",
|
|
38
|
-
"email": "matej.chalk@flowup.cz",
|
|
39
|
-
"url": "https://github.com/matejchalk"
|
|
40
|
-
},
|
|
41
|
-
{
|
|
42
|
-
"name": "Michael Hladky",
|
|
43
|
-
"email": "michael.hladky@push-based.io",
|
|
44
|
-
"url": "https://push-based.io"
|
|
45
|
-
},
|
|
46
|
-
{
|
|
47
|
-
"name": "Michael Seredenko",
|
|
48
|
-
"email": "misha.seredenko@push-based.io",
|
|
49
|
-
"url": "https://github.com/MishaSeredenkoPushBased"
|
|
50
|
-
}
|
|
51
|
-
],
|
|
52
|
-
"type": "module",
|
|
53
|
-
"main": "./index.js",
|
|
54
|
-
"types": "./src/index.d.ts"
|
|
55
|
-
}
|
|
15
|
+
}
|
|
16
|
+
}
|