@code-pushup/core 0.26.0 → 0.27.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/index.js +597 -225
- package/package.json +3 -2
- package/src/index.d.ts +2 -0
- package/src/lib/collect-and-persist.d.ts +1 -1
- package/src/lib/compare.d.ts +4 -0
- package/src/lib/history.d.ts +15 -0
- package/src/lib/implementation/collect.d.ts +1 -1
- package/src/lib/implementation/compare-scorables.d.ts +6 -0
- package/src/lib/implementation/execute-plugin.d.ts +1 -1
- package/src/lib/upload.d.ts +1 -1
package/index.js
CHANGED
|
@@ -84,6 +84,9 @@ var descriptionSchema = z.string({ description: "Description (markdown)" }).max(
|
|
|
84
84
|
var urlSchema = z.string().url();
|
|
85
85
|
var docsUrlSchema = urlSchema.optional().or(z.literal("")).describe("Documentation site");
|
|
86
86
|
var titleSchema = z.string({ description: "Descriptive name" }).max(MAX_TITLE_LENGTH);
|
|
87
|
+
var scoreSchema = z.number({
|
|
88
|
+
description: "Value between 0 and 1"
|
|
89
|
+
}).min(0).max(1);
|
|
87
90
|
function metaSchema(options) {
|
|
88
91
|
const {
|
|
89
92
|
descriptionDescription,
|
|
@@ -215,6 +218,8 @@ var issueSchema = z3.object(
|
|
|
215
218
|
);
|
|
216
219
|
|
|
217
220
|
// packages/models/src/lib/audit-output.ts
|
|
221
|
+
var auditValueSchema = nonnegativeIntSchema.describe("Raw numeric value");
|
|
222
|
+
var auditDisplayValueSchema = z4.string({ description: "Formatted value (e.g. '0.9 s', '2.1 MB')" }).optional();
|
|
218
223
|
var auditDetailsSchema = z4.object(
|
|
219
224
|
{
|
|
220
225
|
issues: z4.array(issueSchema, { description: "List of findings" })
|
|
@@ -224,11 +229,9 @@ var auditDetailsSchema = z4.object(
|
|
|
224
229
|
var auditOutputSchema = z4.object(
|
|
225
230
|
{
|
|
226
231
|
slug: slugSchema.describe("Reference to audit"),
|
|
227
|
-
displayValue:
|
|
228
|
-
value:
|
|
229
|
-
score:
|
|
230
|
-
description: "Value between 0 and 1"
|
|
231
|
-
}).min(0).max(1),
|
|
232
|
+
displayValue: auditDisplayValueSchema,
|
|
233
|
+
value: auditValueSchema,
|
|
234
|
+
score: scoreSchema,
|
|
232
235
|
details: auditDetailsSchema.optional()
|
|
233
236
|
},
|
|
234
237
|
{ description: "Audit information" }
|
|
@@ -555,6 +558,138 @@ var reportSchema = packageVersionSchema({
|
|
|
555
558
|
})
|
|
556
559
|
);
|
|
557
560
|
|
|
561
|
+
// packages/models/src/lib/reports-diff.ts
|
|
562
|
+
import { z as z14 } from "zod";
|
|
563
|
+
function makeComparisonSchema(schema) {
|
|
564
|
+
const sharedDescription = schema.description || "Result";
|
|
565
|
+
return z14.object({
|
|
566
|
+
before: schema.describe(`${sharedDescription} (source commit)`),
|
|
567
|
+
after: schema.describe(`${sharedDescription} (target commit)`)
|
|
568
|
+
});
|
|
569
|
+
}
|
|
570
|
+
function makeArraysComparisonSchema(diffSchema, resultSchema, description) {
|
|
571
|
+
return z14.object(
|
|
572
|
+
{
|
|
573
|
+
changed: z14.array(diffSchema),
|
|
574
|
+
unchanged: z14.array(resultSchema),
|
|
575
|
+
added: z14.array(resultSchema),
|
|
576
|
+
removed: z14.array(resultSchema)
|
|
577
|
+
},
|
|
578
|
+
{ description }
|
|
579
|
+
);
|
|
580
|
+
}
|
|
581
|
+
var scorableMetaSchema = z14.object({ slug: slugSchema, title: titleSchema });
|
|
582
|
+
var scorableWithPluginMetaSchema = scorableMetaSchema.merge(
|
|
583
|
+
z14.object({
|
|
584
|
+
plugin: pluginMetaSchema.pick({ slug: true, title: true }).describe("Plugin which defines it")
|
|
585
|
+
})
|
|
586
|
+
);
|
|
587
|
+
var scorableDiffSchema = scorableMetaSchema.merge(
|
|
588
|
+
z14.object({
|
|
589
|
+
scores: makeComparisonSchema(scoreSchema).merge(
|
|
590
|
+
z14.object({
|
|
591
|
+
diff: z14.number().min(-1).max(1).describe("Score change (`scores.after - scores.before`)")
|
|
592
|
+
})
|
|
593
|
+
).describe("Score comparison")
|
|
594
|
+
})
|
|
595
|
+
);
|
|
596
|
+
var scorableWithPluginDiffSchema = scorableDiffSchema.merge(
|
|
597
|
+
scorableWithPluginMetaSchema
|
|
598
|
+
);
|
|
599
|
+
var categoryDiffSchema = scorableDiffSchema;
|
|
600
|
+
var groupDiffSchema = scorableWithPluginDiffSchema;
|
|
601
|
+
var auditDiffSchema = scorableWithPluginDiffSchema.merge(
|
|
602
|
+
z14.object({
|
|
603
|
+
values: makeComparisonSchema(auditValueSchema).merge(
|
|
604
|
+
z14.object({
|
|
605
|
+
diff: z14.number().int().describe("Value change (`values.after - values.before`)")
|
|
606
|
+
})
|
|
607
|
+
).describe("Audit `value` comparison"),
|
|
608
|
+
displayValues: makeComparisonSchema(auditDisplayValueSchema).describe(
|
|
609
|
+
"Audit `displayValue` comparison"
|
|
610
|
+
)
|
|
611
|
+
})
|
|
612
|
+
);
|
|
613
|
+
var categoryResultSchema = scorableMetaSchema.merge(
|
|
614
|
+
z14.object({ score: scoreSchema })
|
|
615
|
+
);
|
|
616
|
+
var groupResultSchema = scorableWithPluginMetaSchema.merge(
|
|
617
|
+
z14.object({ score: scoreSchema })
|
|
618
|
+
);
|
|
619
|
+
var auditResultSchema = scorableWithPluginMetaSchema.merge(
|
|
620
|
+
auditOutputSchema.pick({ score: true, value: true, displayValue: true })
|
|
621
|
+
);
|
|
622
|
+
var reportsDiffSchema = z14.object({
|
|
623
|
+
commits: makeComparisonSchema(commitSchema).nullable().describe("Commits identifying compared reports"),
|
|
624
|
+
categories: makeArraysComparisonSchema(
|
|
625
|
+
categoryDiffSchema,
|
|
626
|
+
categoryResultSchema,
|
|
627
|
+
"Changes affecting categories"
|
|
628
|
+
),
|
|
629
|
+
groups: makeArraysComparisonSchema(
|
|
630
|
+
groupDiffSchema,
|
|
631
|
+
groupResultSchema,
|
|
632
|
+
"Changes affecting groups"
|
|
633
|
+
),
|
|
634
|
+
audits: makeArraysComparisonSchema(
|
|
635
|
+
auditDiffSchema,
|
|
636
|
+
auditResultSchema,
|
|
637
|
+
"Changes affecting audits"
|
|
638
|
+
)
|
|
639
|
+
}).merge(
|
|
640
|
+
packageVersionSchema({
|
|
641
|
+
versionDescription: "NPM version of the CLI (when `compare` was run)",
|
|
642
|
+
required: true
|
|
643
|
+
})
|
|
644
|
+
).merge(
|
|
645
|
+
executionMetaSchema({
|
|
646
|
+
descriptionDate: "Start date and time of the compare run",
|
|
647
|
+
descriptionDuration: "Duration of the compare run in ms"
|
|
648
|
+
})
|
|
649
|
+
);
|
|
650
|
+
|
|
651
|
+
// packages/utils/src/lib/diff.ts
|
|
652
|
+
function matchArrayItemsByKey({
|
|
653
|
+
before,
|
|
654
|
+
after,
|
|
655
|
+
key
|
|
656
|
+
}) {
|
|
657
|
+
const pairs = [];
|
|
658
|
+
const added = [];
|
|
659
|
+
const afterKeys = /* @__PURE__ */ new Set();
|
|
660
|
+
const keyFn = typeof key === "function" ? key : (item) => item[key];
|
|
661
|
+
for (const afterItem of after) {
|
|
662
|
+
const afterKey = keyFn(afterItem);
|
|
663
|
+
afterKeys.add(afterKey);
|
|
664
|
+
const match = before.find((beforeItem) => keyFn(beforeItem) === afterKey);
|
|
665
|
+
if (match) {
|
|
666
|
+
pairs.push({ before: match, after: afterItem });
|
|
667
|
+
} else {
|
|
668
|
+
added.push(afterItem);
|
|
669
|
+
}
|
|
670
|
+
}
|
|
671
|
+
const removed = before.filter(
|
|
672
|
+
(beforeItem) => !afterKeys.has(keyFn(beforeItem))
|
|
673
|
+
);
|
|
674
|
+
return {
|
|
675
|
+
pairs,
|
|
676
|
+
added,
|
|
677
|
+
removed
|
|
678
|
+
};
|
|
679
|
+
}
|
|
680
|
+
function comparePairs(pairs, equalsFn) {
|
|
681
|
+
return pairs.reduce(
|
|
682
|
+
(acc, pair) => ({
|
|
683
|
+
...acc,
|
|
684
|
+
...equalsFn(pair) ? { unchanged: [...acc.unchanged, pair.after] } : { changed: [...acc.changed, pair] }
|
|
685
|
+
}),
|
|
686
|
+
{
|
|
687
|
+
changed: [],
|
|
688
|
+
unchanged: []
|
|
689
|
+
}
|
|
690
|
+
);
|
|
691
|
+
}
|
|
692
|
+
|
|
558
693
|
// packages/utils/src/lib/execute-process.ts
|
|
559
694
|
import { spawn } from "node:child_process";
|
|
560
695
|
|
|
@@ -563,7 +698,7 @@ import { join } from "node:path";
|
|
|
563
698
|
|
|
564
699
|
// packages/utils/src/lib/file-system.ts
|
|
565
700
|
import { bundleRequire } from "bundle-require";
|
|
566
|
-
import
|
|
701
|
+
import chalk2 from "chalk";
|
|
567
702
|
import { mkdir, readFile, readdir, rm, stat } from "node:fs/promises";
|
|
568
703
|
|
|
569
704
|
// packages/utils/src/lib/formatting.ts
|
|
@@ -608,33 +743,103 @@ function isPromiseRejectedResult(result) {
|
|
|
608
743
|
return result.status === "rejected";
|
|
609
744
|
}
|
|
610
745
|
|
|
746
|
+
// packages/utils/src/lib/logging.ts
|
|
747
|
+
import isaacs_cliui from "@isaacs/cliui";
|
|
748
|
+
import { cliui } from "@poppinss/cliui";
|
|
749
|
+
import chalk from "chalk";
|
|
750
|
+
|
|
751
|
+
// packages/utils/src/lib/reports/constants.ts
|
|
752
|
+
var TERMINAL_WIDTH = 80;
|
|
753
|
+
var NEW_LINE = "\n";
|
|
754
|
+
var SCORE_COLOR_RANGE = {
|
|
755
|
+
GREEN_MIN: 0.9,
|
|
756
|
+
YELLOW_MIN: 0.5
|
|
757
|
+
};
|
|
758
|
+
var FOOTER_PREFIX = "Made with \u2764 by";
|
|
759
|
+
var CODE_PUSHUP_DOMAIN = "code-pushup.dev";
|
|
760
|
+
var README_LINK = "https://github.com/flowup/quality-metrics-cli#readme";
|
|
761
|
+
var reportHeadlineText = "Code PushUp Report";
|
|
762
|
+
var reportOverviewTableHeaders = [
|
|
763
|
+
"\u{1F3F7} Category",
|
|
764
|
+
"\u2B50 Score",
|
|
765
|
+
"\u{1F6E1} Audits"
|
|
766
|
+
];
|
|
767
|
+
var reportRawOverviewTableHeaders = ["Category", "Score", "Audits"];
|
|
768
|
+
var reportMetaTableHeaders = [
|
|
769
|
+
"Commit",
|
|
770
|
+
"Version",
|
|
771
|
+
"Duration",
|
|
772
|
+
"Plugins",
|
|
773
|
+
"Categories",
|
|
774
|
+
"Audits"
|
|
775
|
+
];
|
|
776
|
+
var pluginMetaTableHeaders = [
|
|
777
|
+
"Plugin",
|
|
778
|
+
"Audits",
|
|
779
|
+
"Version",
|
|
780
|
+
"Duration"
|
|
781
|
+
];
|
|
782
|
+
var detailsTableHeaders = [
|
|
783
|
+
"Severity",
|
|
784
|
+
"Message",
|
|
785
|
+
"Source file",
|
|
786
|
+
"Line(s)"
|
|
787
|
+
];
|
|
788
|
+
|
|
789
|
+
// packages/utils/src/lib/logging.ts
|
|
790
|
+
var singletonUiInstance;
|
|
791
|
+
function ui() {
|
|
792
|
+
if (singletonUiInstance === void 0) {
|
|
793
|
+
singletonUiInstance = cliui();
|
|
794
|
+
}
|
|
795
|
+
return {
|
|
796
|
+
...singletonUiInstance,
|
|
797
|
+
row: (args) => {
|
|
798
|
+
logListItem(args);
|
|
799
|
+
}
|
|
800
|
+
};
|
|
801
|
+
}
|
|
802
|
+
var singletonisaacUi;
|
|
803
|
+
function logListItem(args) {
|
|
804
|
+
if (singletonisaacUi === void 0) {
|
|
805
|
+
singletonisaacUi = isaacs_cliui({ width: TERMINAL_WIDTH });
|
|
806
|
+
}
|
|
807
|
+
singletonisaacUi.div(...args);
|
|
808
|
+
const content = singletonisaacUi.toString();
|
|
809
|
+
singletonisaacUi.rows = [];
|
|
810
|
+
singletonUiInstance?.logger.log(content);
|
|
811
|
+
}
|
|
812
|
+
|
|
611
813
|
// packages/utils/src/lib/log-results.ts
|
|
612
|
-
function logMultipleResults(results, messagePrefix,
|
|
613
|
-
if (
|
|
814
|
+
function logMultipleResults(results, messagePrefix, succeededTransform, failedTransform) {
|
|
815
|
+
if (succeededTransform) {
|
|
614
816
|
const succeededResults = results.filter(isPromiseFulfilledResult);
|
|
615
817
|
logPromiseResults(
|
|
616
818
|
succeededResults,
|
|
617
819
|
`${messagePrefix} successfully: `,
|
|
618
|
-
|
|
820
|
+
succeededTransform
|
|
619
821
|
);
|
|
620
822
|
}
|
|
621
|
-
if (
|
|
823
|
+
if (failedTransform) {
|
|
622
824
|
const failedResults = results.filter(isPromiseRejectedResult);
|
|
623
825
|
logPromiseResults(
|
|
624
826
|
failedResults,
|
|
625
827
|
`${messagePrefix} failed: `,
|
|
626
|
-
|
|
828
|
+
failedTransform
|
|
627
829
|
);
|
|
628
830
|
}
|
|
629
831
|
}
|
|
630
|
-
function logPromiseResults(results, logMessage,
|
|
832
|
+
function logPromiseResults(results, logMessage, getMsg) {
|
|
631
833
|
if (results.length > 0) {
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
}
|
|
635
|
-
|
|
636
|
-
}
|
|
637
|
-
|
|
834
|
+
const log2 = results[0]?.status === "fulfilled" ? (m) => {
|
|
835
|
+
ui().logger.success(m);
|
|
836
|
+
} : (m) => {
|
|
837
|
+
ui().logger.warning(m);
|
|
838
|
+
};
|
|
839
|
+
log2(logMessage);
|
|
840
|
+
results.forEach((result) => {
|
|
841
|
+
log2(getMsg(result));
|
|
842
|
+
});
|
|
638
843
|
}
|
|
639
844
|
}
|
|
640
845
|
|
|
@@ -668,26 +873,24 @@ async function ensureDirectoryExists(baseDir) {
|
|
|
668
873
|
await mkdir(baseDir, { recursive: true });
|
|
669
874
|
return;
|
|
670
875
|
} catch (error) {
|
|
671
|
-
|
|
876
|
+
ui().logger.error(error.message);
|
|
672
877
|
if (error.code !== "EEXIST") {
|
|
673
878
|
throw error;
|
|
674
879
|
}
|
|
675
880
|
}
|
|
676
881
|
}
|
|
677
882
|
function logMultipleFileResults(fileResults, messagePrefix) {
|
|
678
|
-
const
|
|
883
|
+
const succeededTransform = (result) => {
|
|
679
884
|
const [fileName, size] = result.value;
|
|
680
|
-
const formattedSize = size ? ` (${
|
|
681
|
-
|
|
682
|
-
};
|
|
683
|
-
const failedCallback = (result) => {
|
|
684
|
-
console.warn(`- ${chalk.bold(result.reason)}`);
|
|
885
|
+
const formattedSize = size ? ` (${chalk2.gray(formatBytes(size))})` : "";
|
|
886
|
+
return `- ${chalk2.bold(fileName)}${formattedSize}`;
|
|
685
887
|
};
|
|
888
|
+
const failedTransform = (result) => `- ${chalk2.bold(result.reason)}`;
|
|
686
889
|
logMultipleResults(
|
|
687
890
|
fileResults,
|
|
688
891
|
messagePrefix,
|
|
689
|
-
|
|
690
|
-
|
|
892
|
+
succeededTransform,
|
|
893
|
+
failedTransform
|
|
691
894
|
);
|
|
692
895
|
}
|
|
693
896
|
var NoExportError = class extends Error {
|
|
@@ -706,43 +909,83 @@ async function importEsmModule(options) {
|
|
|
706
909
|
return mod.default;
|
|
707
910
|
}
|
|
708
911
|
|
|
709
|
-
// packages/utils/src/lib/reports/
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
912
|
+
// packages/utils/src/lib/reports/md/details.ts
|
|
913
|
+
function details(title, content, cfg = { open: false }) {
|
|
914
|
+
return `<details${cfg.open ? " open" : ""}>
|
|
915
|
+
<summary>${title}</summary>
|
|
916
|
+
|
|
917
|
+
${content}
|
|
918
|
+
|
|
919
|
+
</details>
|
|
920
|
+
`;
|
|
921
|
+
}
|
|
922
|
+
|
|
923
|
+
// packages/utils/src/lib/reports/md/font-style.ts
|
|
924
|
+
var stylesMap = {
|
|
925
|
+
i: "_",
|
|
926
|
+
// italic
|
|
927
|
+
b: "**",
|
|
928
|
+
// bold
|
|
929
|
+
s: "~",
|
|
930
|
+
// strike through
|
|
931
|
+
c: "`"
|
|
932
|
+
// code
|
|
715
933
|
};
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
"
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
]
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
"
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
"
|
|
745
|
-
]
|
|
934
|
+
function style(text, styles = ["b"]) {
|
|
935
|
+
return styles.reduce((t, s) => `${stylesMap[s]}${t}${stylesMap[s]}`, text);
|
|
936
|
+
}
|
|
937
|
+
|
|
938
|
+
// packages/utils/src/lib/reports/md/headline.ts
|
|
939
|
+
function headline(text, hierarchy = 1) {
|
|
940
|
+
return `${"#".repeat(hierarchy)} ${text}`;
|
|
941
|
+
}
|
|
942
|
+
function h2(text) {
|
|
943
|
+
return headline(text, 2);
|
|
944
|
+
}
|
|
945
|
+
function h3(text) {
|
|
946
|
+
return headline(text, 3);
|
|
947
|
+
}
|
|
948
|
+
|
|
949
|
+
// packages/utils/src/lib/reports/md/link.ts
|
|
950
|
+
function link(href, text) {
|
|
951
|
+
return `[${text || href}](${href})`;
|
|
952
|
+
}
|
|
953
|
+
|
|
954
|
+
// packages/utils/src/lib/reports/md/list.ts
|
|
955
|
+
function li(text, order = "unordered") {
|
|
956
|
+
const style2 = order === "unordered" ? "-" : "- [ ]";
|
|
957
|
+
return `${style2} ${text}`;
|
|
958
|
+
}
|
|
959
|
+
|
|
960
|
+
// packages/utils/src/lib/reports/md/table.ts
|
|
961
|
+
var alignString = /* @__PURE__ */ new Map([
|
|
962
|
+
["l", ":--"],
|
|
963
|
+
["c", ":--:"],
|
|
964
|
+
["r", "--:"]
|
|
965
|
+
]);
|
|
966
|
+
function tableMd(data, align) {
|
|
967
|
+
if (data.length === 0) {
|
|
968
|
+
throw new Error("Data can't be empty");
|
|
969
|
+
}
|
|
970
|
+
const alignmentSetting = align ?? data[0]?.map(() => "c");
|
|
971
|
+
const tableContent = data.map((arr) => `|${arr.join("|")}|`);
|
|
972
|
+
const alignmentRow = `|${alignmentSetting?.map((s) => alignString.get(s)).join("|")}|`;
|
|
973
|
+
return tableContent[0] + NEW_LINE + alignmentRow + NEW_LINE + tableContent.slice(1).join(NEW_LINE);
|
|
974
|
+
}
|
|
975
|
+
function tableHtml(data) {
|
|
976
|
+
if (data.length === 0) {
|
|
977
|
+
throw new Error("Data can't be empty");
|
|
978
|
+
}
|
|
979
|
+
const tableContent = data.map((arr, index) => {
|
|
980
|
+
if (index === 0) {
|
|
981
|
+
const headerRow = arr.map((s) => `<th>${s}</th>`).join("");
|
|
982
|
+
return `<tr>${headerRow}</tr>`;
|
|
983
|
+
}
|
|
984
|
+
const row = arr.map((s) => `<td>${s}</td>`).join("");
|
|
985
|
+
return `<tr>${row}</tr>`;
|
|
986
|
+
});
|
|
987
|
+
return `<table>${tableContent.join("")}</table>`;
|
|
988
|
+
}
|
|
746
989
|
|
|
747
990
|
// packages/utils/src/lib/reports/utils.ts
|
|
748
991
|
function formatReportScore(score) {
|
|
@@ -939,7 +1182,7 @@ var ProcessError = class extends Error {
|
|
|
939
1182
|
}
|
|
940
1183
|
};
|
|
941
1184
|
function executeProcess(cfg) {
|
|
942
|
-
const { observer, cwd, command, args } = cfg;
|
|
1185
|
+
const { observer, cwd, command, args, alwaysResolve = false } = cfg;
|
|
943
1186
|
const { onStdout, onError, onComplete } = observer ?? {};
|
|
944
1187
|
const date = (/* @__PURE__ */ new Date()).toISOString();
|
|
945
1188
|
const start = performance.now();
|
|
@@ -959,7 +1202,7 @@ function executeProcess(cfg) {
|
|
|
959
1202
|
});
|
|
960
1203
|
process2.on("close", (code) => {
|
|
961
1204
|
const timings = { date, duration: calcDuration(start) };
|
|
962
|
-
if (code === 0) {
|
|
1205
|
+
if (code === 0 || alwaysResolve) {
|
|
963
1206
|
onComplete?.();
|
|
964
1207
|
resolve({ code, stdout, stderr, ...timings });
|
|
965
1208
|
} else {
|
|
@@ -985,14 +1228,14 @@ function toUnixPath(path) {
|
|
|
985
1228
|
|
|
986
1229
|
// packages/utils/src/lib/git.ts
|
|
987
1230
|
async function getLatestCommit(git = simpleGit()) {
|
|
988
|
-
const
|
|
1231
|
+
const log2 = await git.log({
|
|
989
1232
|
maxCount: 1,
|
|
990
1233
|
format: { hash: "%H", message: "%s", author: "%an", date: "%aI" }
|
|
991
1234
|
});
|
|
992
|
-
if (!
|
|
1235
|
+
if (!log2.latest) {
|
|
993
1236
|
return null;
|
|
994
1237
|
}
|
|
995
|
-
return commitSchema.parse(
|
|
1238
|
+
return commitSchema.parse(log2.latest);
|
|
996
1239
|
}
|
|
997
1240
|
function getGitRoot(git = simpleGit()) {
|
|
998
1241
|
return git.revparse("--show-toplevel");
|
|
@@ -1011,9 +1254,6 @@ function groupByStatus(results) {
|
|
|
1011
1254
|
);
|
|
1012
1255
|
}
|
|
1013
1256
|
|
|
1014
|
-
// packages/utils/src/lib/logging.ts
|
|
1015
|
-
import chalk2 from "chalk";
|
|
1016
|
-
|
|
1017
1257
|
// packages/utils/src/lib/progress.ts
|
|
1018
1258
|
import chalk3 from "chalk";
|
|
1019
1259
|
import { MultiProgressBars } from "multi-progress-bars";
|
|
@@ -1069,80 +1309,105 @@ function getProgressBar(taskName) {
|
|
|
1069
1309
|
};
|
|
1070
1310
|
}
|
|
1071
1311
|
|
|
1072
|
-
// packages/utils/src/lib/reports/
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
${content}
|
|
1077
|
-
</details>
|
|
1078
|
-
`;
|
|
1079
|
-
}
|
|
1080
|
-
|
|
1081
|
-
// packages/utils/src/lib/reports/md/font-style.ts
|
|
1082
|
-
var stylesMap = {
|
|
1083
|
-
i: "_",
|
|
1084
|
-
// italic
|
|
1085
|
-
b: "**",
|
|
1086
|
-
// bold
|
|
1087
|
-
s: "~",
|
|
1088
|
-
// strike through
|
|
1089
|
-
c: "`"
|
|
1090
|
-
// code
|
|
1091
|
-
};
|
|
1092
|
-
function style(text, styles = ["b"]) {
|
|
1093
|
-
return styles.reduce((t, s) => `${stylesMap[s]}${t}${stylesMap[s]}`, text);
|
|
1312
|
+
// packages/utils/src/lib/reports/log-stdout-summary.ts
|
|
1313
|
+
import chalk4 from "chalk";
|
|
1314
|
+
function log(msg = "") {
|
|
1315
|
+
ui().logger.log(msg);
|
|
1094
1316
|
}
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1317
|
+
function logStdoutSummary(report) {
|
|
1318
|
+
const printCategories = report.categories.length > 0;
|
|
1319
|
+
log(reportToHeaderSection(report));
|
|
1320
|
+
log();
|
|
1321
|
+
logPlugins(report);
|
|
1322
|
+
if (printCategories) {
|
|
1323
|
+
logCategories(report);
|
|
1324
|
+
}
|
|
1325
|
+
log(`${FOOTER_PREFIX} ${CODE_PUSHUP_DOMAIN}`);
|
|
1326
|
+
log();
|
|
1099
1327
|
}
|
|
1100
|
-
function
|
|
1101
|
-
|
|
1328
|
+
function reportToHeaderSection(report) {
|
|
1329
|
+
const { packageName, version: version2 } = report;
|
|
1330
|
+
return `${chalk4.bold(reportHeadlineText)} - ${packageName}@${version2}`;
|
|
1102
1331
|
}
|
|
1103
|
-
function
|
|
1104
|
-
|
|
1332
|
+
function logPlugins(report) {
|
|
1333
|
+
const { plugins } = report;
|
|
1334
|
+
plugins.forEach((plugin) => {
|
|
1335
|
+
const { title, audits } = plugin;
|
|
1336
|
+
log();
|
|
1337
|
+
log(chalk4.magentaBright.bold(`${title} audits`));
|
|
1338
|
+
log();
|
|
1339
|
+
audits.forEach((audit) => {
|
|
1340
|
+
ui().row([
|
|
1341
|
+
{
|
|
1342
|
+
text: applyScoreColor({ score: audit.score, text: "\u25CF" }),
|
|
1343
|
+
width: 2,
|
|
1344
|
+
padding: [0, 1, 0, 0]
|
|
1345
|
+
},
|
|
1346
|
+
{
|
|
1347
|
+
text: audit.title,
|
|
1348
|
+
// eslint-disable-next-line no-magic-numbers
|
|
1349
|
+
padding: [0, 3, 0, 0]
|
|
1350
|
+
},
|
|
1351
|
+
{
|
|
1352
|
+
text: chalk4.cyanBright(audit.displayValue || `${audit.value}`),
|
|
1353
|
+
width: 10,
|
|
1354
|
+
padding: [0, 0, 0, 0]
|
|
1355
|
+
}
|
|
1356
|
+
]);
|
|
1357
|
+
});
|
|
1358
|
+
log();
|
|
1359
|
+
});
|
|
1105
1360
|
}
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1361
|
+
function logCategories({ categories, plugins }) {
|
|
1362
|
+
const hAlign = (idx) => idx === 0 ? "left" : "right";
|
|
1363
|
+
const rows = categories.map(({ title, score, refs }) => [
|
|
1364
|
+
title,
|
|
1365
|
+
applyScoreColor({ score }),
|
|
1366
|
+
countCategoryAudits(refs, plugins)
|
|
1367
|
+
]);
|
|
1368
|
+
const table = ui().table();
|
|
1369
|
+
table.columnWidths([TERMINAL_WIDTH - 9 - 10 - 4, 9, 10]);
|
|
1370
|
+
table.head(
|
|
1371
|
+
reportRawOverviewTableHeaders.map((heading, idx) => ({
|
|
1372
|
+
content: chalk4.cyan(heading),
|
|
1373
|
+
hAlign: hAlign(idx)
|
|
1374
|
+
}))
|
|
1375
|
+
);
|
|
1376
|
+
rows.forEach(
|
|
1377
|
+
(row) => table.row(
|
|
1378
|
+
row.map((content, idx) => ({
|
|
1379
|
+
content: content.toString(),
|
|
1380
|
+
hAlign: hAlign(idx)
|
|
1381
|
+
}))
|
|
1382
|
+
)
|
|
1383
|
+
);
|
|
1384
|
+
log(chalk4.magentaBright.bold("Categories"));
|
|
1385
|
+
log();
|
|
1386
|
+
table.render();
|
|
1387
|
+
log();
|
|
1110
1388
|
}
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1389
|
+
function applyScoreColor({ score, text }) {
|
|
1390
|
+
const formattedScore = text ?? formatReportScore(score);
|
|
1391
|
+
const style2 = text ? chalk4 : chalk4.bold;
|
|
1392
|
+
if (score >= SCORE_COLOR_RANGE.GREEN_MIN) {
|
|
1393
|
+
return style2.green(formattedScore);
|
|
1394
|
+
}
|
|
1395
|
+
if (score >= SCORE_COLOR_RANGE.YELLOW_MIN) {
|
|
1396
|
+
return style2.yellow(formattedScore);
|
|
1397
|
+
}
|
|
1398
|
+
return style2.red(formattedScore);
|
|
1116
1399
|
}
|
|
1117
1400
|
|
|
1118
|
-
// packages/utils/src/lib/reports/
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
]);
|
|
1124
|
-
function tableMd(data, align) {
|
|
1125
|
-
if (data.length === 0) {
|
|
1126
|
-
throw new Error("Data can't be empty");
|
|
1127
|
-
}
|
|
1128
|
-
const alignmentSetting = align ?? data[0]?.map(() => "c");
|
|
1129
|
-
const tableContent = data.map((arr) => `|${arr.join("|")}|`);
|
|
1130
|
-
const alignmentRow = `|${alignmentSetting?.map((s) => alignString.get(s)).join("|")}|`;
|
|
1131
|
-
return tableContent[0] + NEW_LINE + alignmentRow + NEW_LINE + tableContent.slice(1).join(NEW_LINE);
|
|
1401
|
+
// packages/utils/src/lib/reports/flatten-plugins.ts
|
|
1402
|
+
function listGroupsFromAllPlugins(report) {
|
|
1403
|
+
return report.plugins.flatMap(
|
|
1404
|
+
(plugin) => plugin.groups?.map((group) => ({ plugin, group })) ?? []
|
|
1405
|
+
);
|
|
1132
1406
|
}
|
|
1133
|
-
function
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
const tableContent = data.map((arr, index) => {
|
|
1138
|
-
if (index === 0) {
|
|
1139
|
-
const headerRow = arr.map((s) => `<th>${s}</th>`).join("");
|
|
1140
|
-
return `<tr>${headerRow}</tr>`;
|
|
1141
|
-
}
|
|
1142
|
-
const row = arr.map((s) => `<td>${s}</td>`).join("");
|
|
1143
|
-
return `<tr>${row}</tr>`;
|
|
1144
|
-
});
|
|
1145
|
-
return `<table>${tableContent.join("")}</table>`;
|
|
1407
|
+
function listAuditsFromAllPlugins(report) {
|
|
1408
|
+
return report.plugins.flatMap(
|
|
1409
|
+
(plugin) => plugin.audits.map((audit) => ({ plugin, audit }))
|
|
1410
|
+
);
|
|
1146
1411
|
}
|
|
1147
1412
|
|
|
1148
1413
|
// packages/utils/src/lib/reports/generate-md-report.ts
|
|
@@ -1151,7 +1416,7 @@ function generateMdReport(report) {
|
|
|
1151
1416
|
return (
|
|
1152
1417
|
// header section
|
|
1153
1418
|
// eslint-disable-next-line prefer-template
|
|
1154
|
-
|
|
1419
|
+
reportToHeaderSection2() + NEW_LINE + // categories overview section
|
|
1155
1420
|
(printCategories ? reportToOverviewSection(report) + NEW_LINE + NEW_LINE : "") + // categories section
|
|
1156
1421
|
(printCategories ? reportToCategoriesSection(report) + NEW_LINE + NEW_LINE : "") + // audits section
|
|
1157
1422
|
reportToAuditsSection(report) + NEW_LINE + NEW_LINE + // about section
|
|
@@ -1159,7 +1424,7 @@ function generateMdReport(report) {
|
|
|
1159
1424
|
`${FOOTER_PREFIX} ${link(README_LINK, "Code PushUp")}`
|
|
1160
1425
|
);
|
|
1161
1426
|
}
|
|
1162
|
-
function
|
|
1427
|
+
function reportToHeaderSection2() {
|
|
1163
1428
|
return headline(reportHeadlineText) + NEW_LINE;
|
|
1164
1429
|
}
|
|
1165
1430
|
function reportToOverviewSection(report) {
|
|
@@ -1332,82 +1597,6 @@ function getAuditResult(audit, isHtml = false) {
|
|
|
1332
1597
|
return isHtml ? `<b>${displayValue || value}</b>` : style(String(displayValue || value));
|
|
1333
1598
|
}
|
|
1334
1599
|
|
|
1335
|
-
// packages/utils/src/lib/reports/generate-stdout-summary.ts
|
|
1336
|
-
import cliui from "@isaacs/cliui";
|
|
1337
|
-
import chalk4 from "chalk";
|
|
1338
|
-
import CliTable3 from "cli-table3";
|
|
1339
|
-
function addLine(line = "") {
|
|
1340
|
-
return line + NEW_LINE;
|
|
1341
|
-
}
|
|
1342
|
-
function generateStdoutSummary(report) {
|
|
1343
|
-
const printCategories = report.categories.length > 0;
|
|
1344
|
-
return addLine(reportToHeaderSection2(report)) + addLine() + addLine(reportToDetailSection(report)) + (printCategories ? addLine(reportToOverviewSection2(report)) : "") + addLine(`${FOOTER_PREFIX} ${CODE_PUSHUP_DOMAIN}`);
|
|
1345
|
-
}
|
|
1346
|
-
function reportToHeaderSection2(report) {
|
|
1347
|
-
const { packageName, version: version2 } = report;
|
|
1348
|
-
return `${chalk4.bold(reportHeadlineText)} - ${packageName}@${version2}`;
|
|
1349
|
-
}
|
|
1350
|
-
function reportToDetailSection(report) {
|
|
1351
|
-
const { plugins } = report;
|
|
1352
|
-
return plugins.reduce((acc, plugin) => {
|
|
1353
|
-
const { title, audits } = plugin;
|
|
1354
|
-
const ui = cliui({ width: TERMINAL_WIDTH });
|
|
1355
|
-
audits.forEach((audit) => {
|
|
1356
|
-
ui.div(
|
|
1357
|
-
{
|
|
1358
|
-
text: withColor({ score: audit.score, text: "\u25CF" }),
|
|
1359
|
-
width: 2,
|
|
1360
|
-
padding: [0, 1, 0, 0]
|
|
1361
|
-
},
|
|
1362
|
-
{
|
|
1363
|
-
text: audit.title,
|
|
1364
|
-
// eslint-disable-next-line no-magic-numbers
|
|
1365
|
-
padding: [0, 3, 0, 0]
|
|
1366
|
-
},
|
|
1367
|
-
{
|
|
1368
|
-
text: chalk4.cyanBright(audit.displayValue || `${audit.value}`),
|
|
1369
|
-
width: 10,
|
|
1370
|
-
padding: [0, 0, 0, 0]
|
|
1371
|
-
}
|
|
1372
|
-
);
|
|
1373
|
-
});
|
|
1374
|
-
return acc + addLine() + addLine(chalk4.magentaBright.bold(`${title} audits`)) + addLine() + addLine(ui.toString()) + addLine();
|
|
1375
|
-
}, "");
|
|
1376
|
-
}
|
|
1377
|
-
function reportToOverviewSection2({
|
|
1378
|
-
categories,
|
|
1379
|
-
plugins
|
|
1380
|
-
}) {
|
|
1381
|
-
const table = new CliTable3({
|
|
1382
|
-
// eslint-disable-next-line no-magic-numbers
|
|
1383
|
-
colWidths: [TERMINAL_WIDTH - 7 - 8 - 4, 7, 8],
|
|
1384
|
-
head: reportRawOverviewTableHeaders,
|
|
1385
|
-
colAligns: ["left", "right", "right"],
|
|
1386
|
-
style: {
|
|
1387
|
-
head: ["cyan"]
|
|
1388
|
-
}
|
|
1389
|
-
});
|
|
1390
|
-
table.push(
|
|
1391
|
-
...categories.map(({ title, score, refs }) => [
|
|
1392
|
-
title,
|
|
1393
|
-
withColor({ score }),
|
|
1394
|
-
countCategoryAudits(refs, plugins)
|
|
1395
|
-
])
|
|
1396
|
-
);
|
|
1397
|
-
return addLine(chalk4.magentaBright.bold("Categories")) + addLine() + addLine(table.toString());
|
|
1398
|
-
}
|
|
1399
|
-
function withColor({ score, text }) {
|
|
1400
|
-
const formattedScore = text ?? formatReportScore(score);
|
|
1401
|
-
const style2 = text ? chalk4 : chalk4.bold;
|
|
1402
|
-
if (score >= SCORE_COLOR_RANGE.GREEN_MIN) {
|
|
1403
|
-
return style2.green(formattedScore);
|
|
1404
|
-
}
|
|
1405
|
-
if (score >= SCORE_COLOR_RANGE.YELLOW_MIN) {
|
|
1406
|
-
return style2.yellow(formattedScore);
|
|
1407
|
-
}
|
|
1408
|
-
return style2.red(formattedScore);
|
|
1409
|
-
}
|
|
1410
|
-
|
|
1411
1600
|
// packages/utils/src/lib/reports/scoring.ts
|
|
1412
1601
|
var GroupRefInvalidError = class extends Error {
|
|
1413
1602
|
constructor(auditSlug, pluginSlug) {
|
|
@@ -1547,9 +1736,9 @@ function sortPlugins(plugins) {
|
|
|
1547
1736
|
|
|
1548
1737
|
// packages/utils/src/lib/verbose-utils.ts
|
|
1549
1738
|
function getLogVerbose(verbose = false) {
|
|
1550
|
-
return (
|
|
1739
|
+
return (msg) => {
|
|
1551
1740
|
if (verbose) {
|
|
1552
|
-
|
|
1741
|
+
ui().logger.info(msg);
|
|
1553
1742
|
}
|
|
1554
1743
|
};
|
|
1555
1744
|
}
|
|
@@ -1567,7 +1756,7 @@ var verboseUtils = (verbose = false) => ({
|
|
|
1567
1756
|
|
|
1568
1757
|
// packages/core/package.json
|
|
1569
1758
|
var name = "@code-pushup/core";
|
|
1570
|
-
var version = "0.
|
|
1759
|
+
var version = "0.27.1";
|
|
1571
1760
|
|
|
1572
1761
|
// packages/core/src/lib/implementation/execute-plugin.ts
|
|
1573
1762
|
import chalk5 from "chalk";
|
|
@@ -1680,11 +1869,9 @@ async function executePlugins(plugins, options) {
|
|
|
1680
1869
|
}
|
|
1681
1870
|
}, Promise.resolve([]));
|
|
1682
1871
|
progressBar?.endProgress("Done running plugins");
|
|
1683
|
-
const
|
|
1684
|
-
console.error(reason);
|
|
1685
|
-
};
|
|
1872
|
+
const errorsTransform = ({ reason }) => String(reason);
|
|
1686
1873
|
const results = await Promise.allSettled(pluginsResult);
|
|
1687
|
-
logMultipleResults(results, "Plugins", void 0,
|
|
1874
|
+
logMultipleResults(results, "Plugins", void 0, errorsTransform);
|
|
1688
1875
|
const { fulfilled, rejected } = groupByStatus(results);
|
|
1689
1876
|
if (rejected.length > 0) {
|
|
1690
1877
|
const errorMessages = rejected.map(({ reason }) => String(reason)).join(", ");
|
|
@@ -1739,7 +1926,7 @@ var PersistError = class extends Error {
|
|
|
1739
1926
|
async function persistReport(report, options) {
|
|
1740
1927
|
const { outputDir, filename, format } = options;
|
|
1741
1928
|
const sortedScoredReport = sortReport(scoreReport(report));
|
|
1742
|
-
|
|
1929
|
+
logStdoutSummary(sortedScoredReport);
|
|
1743
1930
|
const results = format.map((reportType) => {
|
|
1744
1931
|
switch (reportType) {
|
|
1745
1932
|
case "json":
|
|
@@ -1758,7 +1945,7 @@ async function persistReport(report, options) {
|
|
|
1758
1945
|
try {
|
|
1759
1946
|
await mkdir2(outputDir, { recursive: true });
|
|
1760
1947
|
} catch (error) {
|
|
1761
|
-
|
|
1948
|
+
ui().logger.warning(error.toString());
|
|
1762
1949
|
throw new PersistDirError(outputDir);
|
|
1763
1950
|
}
|
|
1764
1951
|
}
|
|
@@ -1773,7 +1960,7 @@ async function persistReport(report, options) {
|
|
|
1773
1960
|
}
|
|
1774
1961
|
async function persistResult(reportPath, content) {
|
|
1775
1962
|
return writeFile(reportPath, content).then(() => stat2(reportPath)).then((stats) => [reportPath, stats.size]).catch((error) => {
|
|
1776
|
-
|
|
1963
|
+
ui().logger.warning(error.toString());
|
|
1777
1964
|
throw new PersistError(reportPath);
|
|
1778
1965
|
});
|
|
1779
1966
|
}
|
|
@@ -1794,6 +1981,189 @@ async function collectAndPersistReports(options) {
|
|
|
1794
1981
|
});
|
|
1795
1982
|
}
|
|
1796
1983
|
|
|
1984
|
+
// packages/core/src/lib/compare.ts
|
|
1985
|
+
import { writeFile as writeFile2 } from "node:fs/promises";
|
|
1986
|
+
|
|
1987
|
+
// packages/core/src/lib/implementation/compare-scorables.ts
|
|
1988
|
+
function compareCategories(reports) {
|
|
1989
|
+
const { pairs, added, removed } = matchArrayItemsByKey({
|
|
1990
|
+
before: reports.before.categories,
|
|
1991
|
+
after: reports.after.categories,
|
|
1992
|
+
key: "slug"
|
|
1993
|
+
});
|
|
1994
|
+
const { changed, unchanged } = comparePairs(
|
|
1995
|
+
pairs,
|
|
1996
|
+
({ before, after }) => before.score === after.score
|
|
1997
|
+
);
|
|
1998
|
+
return {
|
|
1999
|
+
changed: changed.map(categoryPairToDiff),
|
|
2000
|
+
unchanged: unchanged.map(categoryToResult),
|
|
2001
|
+
added: added.map(categoryToResult),
|
|
2002
|
+
removed: removed.map(categoryToResult)
|
|
2003
|
+
};
|
|
2004
|
+
}
|
|
2005
|
+
function compareGroups(reports) {
|
|
2006
|
+
const { pairs, added, removed } = matchArrayItemsByKey({
|
|
2007
|
+
before: listGroupsFromAllPlugins(reports.before),
|
|
2008
|
+
after: listGroupsFromAllPlugins(reports.after),
|
|
2009
|
+
key: ({ plugin, group }) => `${plugin.slug}/${group.slug}`
|
|
2010
|
+
});
|
|
2011
|
+
const { changed, unchanged } = comparePairs(
|
|
2012
|
+
pairs,
|
|
2013
|
+
({ before, after }) => before.group.score === after.group.score
|
|
2014
|
+
);
|
|
2015
|
+
return {
|
|
2016
|
+
changed: changed.map(pluginGroupPairToDiff),
|
|
2017
|
+
unchanged: unchanged.map(pluginGroupToResult),
|
|
2018
|
+
added: added.map(pluginGroupToResult),
|
|
2019
|
+
removed: removed.map(pluginGroupToResult)
|
|
2020
|
+
};
|
|
2021
|
+
}
|
|
2022
|
+
function compareAudits2(reports) {
|
|
2023
|
+
const { pairs, added, removed } = matchArrayItemsByKey({
|
|
2024
|
+
before: listAuditsFromAllPlugins(reports.before),
|
|
2025
|
+
after: listAuditsFromAllPlugins(reports.after),
|
|
2026
|
+
key: ({ plugin, audit }) => `${plugin.slug}/${audit.slug}`
|
|
2027
|
+
});
|
|
2028
|
+
const { changed, unchanged } = comparePairs(
|
|
2029
|
+
pairs,
|
|
2030
|
+
({ before, after }) => before.audit.value === after.audit.value && before.audit.score === after.audit.score
|
|
2031
|
+
);
|
|
2032
|
+
return {
|
|
2033
|
+
changed: changed.map(pluginAuditPairToDiff),
|
|
2034
|
+
unchanged: unchanged.map(pluginAuditToResult),
|
|
2035
|
+
added: added.map(pluginAuditToResult),
|
|
2036
|
+
removed: removed.map(pluginAuditToResult)
|
|
2037
|
+
};
|
|
2038
|
+
}
|
|
2039
|
+
function categoryToResult(category) {
|
|
2040
|
+
return {
|
|
2041
|
+
slug: category.slug,
|
|
2042
|
+
title: category.title,
|
|
2043
|
+
score: category.score
|
|
2044
|
+
};
|
|
2045
|
+
}
|
|
2046
|
+
function categoryPairToDiff({
|
|
2047
|
+
before,
|
|
2048
|
+
after
|
|
2049
|
+
}) {
|
|
2050
|
+
return {
|
|
2051
|
+
slug: after.slug,
|
|
2052
|
+
title: after.title,
|
|
2053
|
+
scores: {
|
|
2054
|
+
before: before.score,
|
|
2055
|
+
after: after.score,
|
|
2056
|
+
diff: after.score - before.score
|
|
2057
|
+
}
|
|
2058
|
+
};
|
|
2059
|
+
}
|
|
2060
|
+
function pluginGroupToResult({ group, plugin }) {
|
|
2061
|
+
return {
|
|
2062
|
+
slug: group.slug,
|
|
2063
|
+
title: group.title,
|
|
2064
|
+
plugin: {
|
|
2065
|
+
slug: plugin.slug,
|
|
2066
|
+
title: plugin.title
|
|
2067
|
+
},
|
|
2068
|
+
score: group.score
|
|
2069
|
+
};
|
|
2070
|
+
}
|
|
2071
|
+
function pluginGroupPairToDiff({
|
|
2072
|
+
before,
|
|
2073
|
+
after
|
|
2074
|
+
}) {
|
|
2075
|
+
return {
|
|
2076
|
+
slug: after.group.slug,
|
|
2077
|
+
title: after.group.title,
|
|
2078
|
+
plugin: {
|
|
2079
|
+
slug: after.plugin.slug,
|
|
2080
|
+
title: after.plugin.title
|
|
2081
|
+
},
|
|
2082
|
+
scores: {
|
|
2083
|
+
before: before.group.score,
|
|
2084
|
+
after: after.group.score,
|
|
2085
|
+
diff: after.group.score - before.group.score
|
|
2086
|
+
}
|
|
2087
|
+
};
|
|
2088
|
+
}
|
|
2089
|
+
function pluginAuditToResult({ audit, plugin }) {
|
|
2090
|
+
return {
|
|
2091
|
+
slug: audit.slug,
|
|
2092
|
+
title: audit.title,
|
|
2093
|
+
plugin: {
|
|
2094
|
+
slug: plugin.slug,
|
|
2095
|
+
title: plugin.title
|
|
2096
|
+
},
|
|
2097
|
+
score: audit.score,
|
|
2098
|
+
value: audit.value,
|
|
2099
|
+
displayValue: audit.displayValue
|
|
2100
|
+
};
|
|
2101
|
+
}
|
|
2102
|
+
function pluginAuditPairToDiff({
|
|
2103
|
+
before,
|
|
2104
|
+
after
|
|
2105
|
+
}) {
|
|
2106
|
+
return {
|
|
2107
|
+
slug: after.audit.slug,
|
|
2108
|
+
title: after.audit.title,
|
|
2109
|
+
plugin: {
|
|
2110
|
+
slug: after.plugin.slug,
|
|
2111
|
+
title: after.plugin.title
|
|
2112
|
+
},
|
|
2113
|
+
scores: {
|
|
2114
|
+
before: before.audit.score,
|
|
2115
|
+
after: after.audit.score,
|
|
2116
|
+
diff: after.audit.score - before.audit.score
|
|
2117
|
+
},
|
|
2118
|
+
values: {
|
|
2119
|
+
before: before.audit.value,
|
|
2120
|
+
after: after.audit.value,
|
|
2121
|
+
diff: after.audit.value - before.audit.value
|
|
2122
|
+
},
|
|
2123
|
+
displayValues: {
|
|
2124
|
+
before: before.audit.displayValue,
|
|
2125
|
+
after: after.audit.displayValue
|
|
2126
|
+
}
|
|
2127
|
+
};
|
|
2128
|
+
}
|
|
2129
|
+
|
|
2130
|
+
// packages/core/src/lib/compare.ts
|
|
2131
|
+
async function compareReportFiles(inputPaths, outputPath) {
|
|
2132
|
+
const [reportBefore, reportAfter] = await Promise.all([
|
|
2133
|
+
readJsonFile(inputPaths.before),
|
|
2134
|
+
readJsonFile(inputPaths.after)
|
|
2135
|
+
]);
|
|
2136
|
+
const reports = {
|
|
2137
|
+
before: reportSchema.parse(reportBefore),
|
|
2138
|
+
after: reportSchema.parse(reportAfter)
|
|
2139
|
+
};
|
|
2140
|
+
const reportsDiff = compareReports(reports);
|
|
2141
|
+
await writeFile2(outputPath, JSON.stringify(reportsDiff, null, 2));
|
|
2142
|
+
}
|
|
2143
|
+
function compareReports(reports) {
|
|
2144
|
+
const start = performance.now();
|
|
2145
|
+
const date = (/* @__PURE__ */ new Date()).toISOString();
|
|
2146
|
+
const commits = reports.before.commit != null && reports.after.commit != null ? { before: reports.before.commit, after: reports.after.commit } : null;
|
|
2147
|
+
const scoredReports = {
|
|
2148
|
+
before: scoreReport(reports.before),
|
|
2149
|
+
after: scoreReport(reports.after)
|
|
2150
|
+
};
|
|
2151
|
+
const categories = compareCategories(scoredReports);
|
|
2152
|
+
const groups = compareGroups(scoredReports);
|
|
2153
|
+
const audits = compareAudits2(scoredReports);
|
|
2154
|
+
const duration = calcDuration(start);
|
|
2155
|
+
return {
|
|
2156
|
+
commits,
|
|
2157
|
+
categories,
|
|
2158
|
+
groups,
|
|
2159
|
+
audits,
|
|
2160
|
+
packageName: name,
|
|
2161
|
+
version,
|
|
2162
|
+
date,
|
|
2163
|
+
duration
|
|
2164
|
+
};
|
|
2165
|
+
}
|
|
2166
|
+
|
|
1797
2167
|
// packages/core/src/lib/implementation/read-rc-file.ts
|
|
1798
2168
|
import { join as join5 } from "node:path";
|
|
1799
2169
|
var ConfigPathError = class extends Error {
|
|
@@ -1969,6 +2339,8 @@ export {
|
|
|
1969
2339
|
autoloadRc,
|
|
1970
2340
|
collect,
|
|
1971
2341
|
collectAndPersistReports,
|
|
2342
|
+
compareReportFiles,
|
|
2343
|
+
compareReports,
|
|
1972
2344
|
executePlugin,
|
|
1973
2345
|
executePlugins,
|
|
1974
2346
|
persistReport,
|
package/package.json
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@code-pushup/core",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.27.1",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"dependencies": {
|
|
6
6
|
"@code-pushup/models": "*",
|
|
7
7
|
"@code-pushup/utils": "*",
|
|
8
8
|
"@code-pushup/portal-client": "^0.6.1",
|
|
9
|
-
"chalk": "^5.3.0"
|
|
9
|
+
"chalk": "^5.3.0",
|
|
10
|
+
"simple-git": "^3.20.0"
|
|
10
11
|
},
|
|
11
12
|
"type": "module",
|
|
12
13
|
"main": "./index.js",
|
package/src/index.d.ts
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
export { CollectAndPersistReportsOptions, collectAndPersistReports, } from './lib/collect-and-persist';
|
|
2
|
+
export { compareReportFiles, compareReports } from './lib/compare';
|
|
2
3
|
export { CollectOptions, collect } from './lib/implementation/collect';
|
|
4
|
+
export { ReportsToCompare } from './lib/implementation/compare-scorables';
|
|
3
5
|
export { PluginOutputMissingAuditError, executePlugin, executePlugins, } from './lib/implementation/execute-plugin';
|
|
4
6
|
export { PersistDirError, PersistError, persistReport, } from './lib/implementation/persist';
|
|
5
7
|
export { ConfigPathError, autoloadRc, readRcByPath, } from './lib/implementation/read-rc-file';
|
|
@@ -2,5 +2,5 @@ import { CoreConfig, PersistConfig } from '@code-pushup/models';
|
|
|
2
2
|
import { GlobalOptions } from './types';
|
|
3
3
|
export type CollectAndPersistReportsOptions = Required<Pick<CoreConfig, 'plugins' | 'categories'>> & {
|
|
4
4
|
persist: Required<PersistConfig>;
|
|
5
|
-
} & GlobalOptions
|
|
5
|
+
} & Partial<GlobalOptions>;
|
|
6
6
|
export declare function collectAndPersistReports(options: CollectAndPersistReportsOptions): Promise<void>;
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { Report, ReportsDiff } from '@code-pushup/models';
|
|
2
|
+
import { Diff } from '@code-pushup/utils';
|
|
3
|
+
export declare function compareReportFiles(inputPaths: Diff<string>, outputPath: string): Promise<void>;
|
|
4
|
+
export declare function compareReports(reports: Diff<Report>): ReportsDiff;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { LogOptions, LogResult } from 'simple-git';
|
|
2
|
+
import { CoreConfig, PersistConfig, UploadConfig } from '@code-pushup/models';
|
|
3
|
+
import { GlobalOptions } from './types';
|
|
4
|
+
export type HistoryOnlyOptions = {
|
|
5
|
+
targetBranch?: string;
|
|
6
|
+
skipUploads?: boolean;
|
|
7
|
+
forceCleanStatus?: boolean;
|
|
8
|
+
};
|
|
9
|
+
export type HistoryOptions = Required<Pick<CoreConfig, 'plugins' | 'categories'>> & {
|
|
10
|
+
persist: Required<PersistConfig>;
|
|
11
|
+
upload?: Required<UploadConfig>;
|
|
12
|
+
} & HistoryOnlyOptions & Partial<GlobalOptions>;
|
|
13
|
+
export declare function history(config: HistoryOptions, commits: string[]): Promise<string[]>;
|
|
14
|
+
export declare function getHashes(options: LogOptions, git?: import("simple-git").SimpleGit): Promise<string[]>;
|
|
15
|
+
export declare function prepareHashes(logs: LogResult): string[];
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { CoreConfig, Report } from '@code-pushup/models';
|
|
2
2
|
import { GlobalOptions } from '../types';
|
|
3
|
-
export type CollectOptions = Required<Pick<CoreConfig, 'plugins' | 'categories'>> & GlobalOptions
|
|
3
|
+
export type CollectOptions = Required<Pick<CoreConfig, 'plugins' | 'categories'>> & Partial<GlobalOptions>;
|
|
4
4
|
/**
|
|
5
5
|
* Run audits, collect plugin output and aggregate it into a JSON object
|
|
6
6
|
* @param options
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { ReportsDiff } from '@code-pushup/models';
|
|
2
|
+
import { Diff, ScoredReport } from '@code-pushup/utils';
|
|
3
|
+
export type ReportsToCompare = Diff<ScoredReport>;
|
|
4
|
+
export declare function compareCategories(reports: ReportsToCompare): ReportsDiff['categories'];
|
|
5
|
+
export declare function compareGroups(reports: ReportsToCompare): ReportsDiff['groups'];
|
|
6
|
+
export declare function compareAudits(reports: ReportsToCompare): ReportsDiff['audits'];
|