Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 6 additions & 6 deletions packages/core/src/lib/implementation/json-to-gql.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import {
CategoryConfigRefType,
IssueSeverity,
IssueSourceType,
IssueSeverity as PortalIssueSeverity,
SaveReportMutationVariables,
} from '@code-pushup/portal-client';
import { Issue, Report } from '@code-pushup/models';
import { IssueSeverity as CliIssueSeverity, Report } from '@code-pushup/models';

export function jsonToGql(report: Report) {
return {
Expand Down Expand Up @@ -71,13 +71,13 @@ export function jsonToGql(report: Report) {
>;
}

function transformSeverity(severity: Issue['severity']): IssueSeverity {
function transformSeverity(severity: CliIssueSeverity): PortalIssueSeverity {
switch (severity) {
case 'info':
return IssueSeverity.Info;
return PortalIssueSeverity.Info;
case 'error':
return IssueSeverity.Error;
return PortalIssueSeverity.Error;
case 'warning':
return IssueSeverity.Warning;
return PortalIssueSeverity.Warning;
}
}
8 changes: 7 additions & 1 deletion packages/models/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
export { CategoryConfig, categoryConfigSchema } from './lib/category-config';
export {
CategoryRef,
CategoryConfig,
categoryConfigSchema,
} from './lib/category-config';
export {
CoreConfig,
coreConfigSchema,
Expand All @@ -14,10 +18,12 @@ export {
} from './lib/persist-config';
export {
Audit,
AuditGroupRef,
AuditGroup,
AuditOutput,
AuditOutputs,
Issue,
IssueSeverity,
PluginConfig,
auditGroupSchema,
auditOutputsSchema,
Expand Down
33 changes: 19 additions & 14 deletions packages/models/src/lib/category-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,22 +13,26 @@ type _RefsList = {
plugin?: string;
}[];

const categoryRefSchema = weightedRefSchema(
'Weighted references to audits and/or groups for the category',
'Slug of an audit or group (depending on `type`)',
).merge(
z.object({
type: z.enum(['audit', 'group'], {
description:
'Discriminant for reference kind, affects where `slug` is looked up',
}),
plugin: slugSchema(
'Plugin slug (plugin should contain referenced audit or group)',
),
}),
);

export type CategoryRef = z.infer<typeof categoryRefSchema>;

export const categoryConfigSchema = scorableSchema(
'Category with a score calculated from audits and groups from various plugins',
weightedRefSchema(
'Weighted references to audits and/or groups for the category',
'Slug of an audit or group (depending on `type`)',
).merge(
z.object({
type: z.enum(['audit', 'group'], {
description:
'Discriminant for reference kind, affects where `slug` is looked up',
}),
plugin: slugSchema(
'Plugin slug (plugin should contain referenced audit or group)',
),
}),
),
categoryRefSchema,
getDuplicateRefsInCategoryMetrics,
duplicateRefsInCategoryMetricsErrorMsg,
)
Expand Down Expand Up @@ -60,6 +64,7 @@ export function duplicateRefsInCategoryMetricsErrorMsg(metrics: _RefsList) {
duplicateRefs,
)}`;
}

function getDuplicateRefsInCategoryMetrics(metrics: _RefsList) {
return hasDuplicateStrings(
metrics.map(({ slug, type, plugin }) => `${type} :: ${plugin} / ${slug}`),
Expand Down
24 changes: 14 additions & 10 deletions packages/models/src/lib/implementation/schemas.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,10 @@ export function titleSchema(description = 'Descriptive name') {
return z.string({ description }).max(256);
}

/**
* Used for categories, plugins and audits
* @param options
*/
export function metaSchema(options?: {
titleDescription?: string;
descriptionDescription?: string;
Expand Down Expand Up @@ -116,16 +120,6 @@ export function fileNameSchema(description: string) {
.min(1, { message: 'file name is invalid' });
}

/**
* Schema for a weight
* @param description
*/
export function weightSchema(
description = 'Coefficient for the given score (use weight 0 if only for display)',
) {
return positiveIntSchema(description);
}

/**
* Schema for a positiveInt
* @param description
Expand All @@ -152,6 +146,16 @@ export function packageVersionSchema(options?: {
);
}

/**
* Schema for a weight
* @param description
*/
export function weightSchema(
description = 'Coefficient for the given score (use weight 0 if only for display)',
) {
return positiveIntSchema(description);
}

export function weightedRefSchema(
description: string,
slugDescription: string,
Expand Down
18 changes: 11 additions & 7 deletions packages/models/src/lib/plugin-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,13 +70,15 @@ export const auditSchema = z

export type Audit = z.infer<typeof auditSchema>;

const auditGroupRef = weightedRefSchema(
'Weighted references to audits',
"Reference slug to an audit within this plugin (e.g. 'max-lines')",
);
export type AuditGroupRef = z.infer<typeof auditGroupRef>;
export const auditGroupSchema = scorableSchema(
'An audit group aggregates a set of audits into a single score which can be referenced from a category. ' +
'E.g. the group slug "performance" groups audits and can be referenced in a category as "[plugin-slug]#group:[group-slug]")',
weightedRefSchema(
'Weighted references to audits',
"Reference slug to an audit within this plugin (e.g. 'max-lines')",
),
auditGroupRef,
getDuplicateRefsInGroups,
duplicateRefsInGroupsErrorMsg,
).merge(
Expand Down Expand Up @@ -183,12 +185,14 @@ const sourceFileLocationSchema = z.object(
{ description: 'Source file location' },
);

export const issueSeveritySchema = z.enum(['info', 'warning', 'error'], {
description: 'Severity level',
});
export type IssueSeverity = z.infer<typeof issueSeveritySchema>;
export const issueSchema = z.object(
{
message: z.string({ description: 'Descriptive error message' }).max(128),
severity: z.enum(['info', 'warning', 'error'], {
description: 'Severity level',
}),
severity: issueSeveritySchema,
source: sourceFileLocationSchema.optional(),
},
{ description: 'Issue information' },
Expand Down
12 changes: 2 additions & 10 deletions packages/models/test/fixtures/eslint-plugin.mock.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,5 @@
import { join } from 'node:path';
import type {
Audit,
CategoryConfig,
PluginConfig,
PluginReport,
} from '../../src';
import type { Audit, CategoryRef, PluginConfig, PluginReport } from '../../src';
import { echoRunnerConfig } from './echo-runner-config.mock';
import { ESLINT_AUDITS_MAP } from './eslint-audits.mock';

Expand Down Expand Up @@ -48,10 +43,7 @@ export function eslintPluginReport(): PluginReport {

type ESLintAuditSlug = keyof typeof ESLINT_AUDITS_MAP;

export function eslintAuditRef(
slug: ESLintAuditSlug,
weight = 1,
): CategoryConfig['refs'][number] {
export function eslintAuditRef(slug: ESLintAuditSlug, weight = 1): CategoryRef {
return {
type: 'audit',
plugin: 'eslint',
Expand Down
3 changes: 2 additions & 1 deletion packages/plugin-eslint/src/lib/runner/transform.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import type { Linter } from 'eslint';
import type { AuditOutput, Issue } from '@code-pushup/models';
import { IssueSeverity } from '@code-pushup/models';
import {
compareIssueSeverity,
countOccurrences,
Expand Down Expand Up @@ -71,7 +72,7 @@ function convertIssue(issue: LintIssue): Issue {
};
}

function convertSeverity(severity: Linter.Severity): Issue['severity'] {
function convertSeverity(severity: Linter.Severity): IssueSeverity {
switch (severity) {
case 2:
return 'error';
Expand Down
10 changes: 5 additions & 5 deletions packages/utils/src/lib/report.spec.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { describe, expect } from 'vitest';
import { CategoryConfig, Issue } from '@code-pushup/models';
import { CategoryRef, IssueSeverity } from '@code-pushup/models';
import {
calcDuration,
compareIssueSeverity,
Expand Down Expand Up @@ -98,7 +98,7 @@ describe('formatCount', () => {

describe('countWeightedRefs', () => {
it('should calc weighted refs only', () => {
const refs: CategoryConfig['refs'] = [
const refs: CategoryRef[] = [
{
slug: 'a1',
weight: 0,
Expand All @@ -119,16 +119,16 @@ describe('countWeightedRefs', () => {
describe('compareIssueSeverity', () => {
it('should order severities in logically ascending order when used as compareFn with .sort()', () => {
expect(
(['error', 'info', 'warning'] satisfies Issue['severity'][]).sort(
(['error', 'info', 'warning'] satisfies IssueSeverity[]).sort(
compareIssueSeverity,
),
).toEqual(['info', 'warning', 'error'] satisfies Issue['severity'][]);
).toEqual(['info', 'warning', 'error'] satisfies IssueSeverity[]);
});
});

describe('sumRefs', () => {
it('should sum refs correctly', () => {
const refs: CategoryConfig['refs'] = [
const refs: CategoryRef[] = [
{
slug: 'a1',
weight: 0,
Expand Down
12 changes: 6 additions & 6 deletions packages/utils/src/lib/report.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { CategoryConfig, Issue } from '@code-pushup/models';
import { CategoryRef, IssueSeverity } from '@code-pushup/models';
import { pluralize } from './utils';

export const FOOTER_PREFIX = 'Made with ❤️ by';
Expand Down Expand Up @@ -34,17 +34,17 @@ export function formatCount(count: number, name: string) {
return `${count} ${text}`;
}

export function countWeightedRefs(refs: CategoryConfig['refs']) {
export function countWeightedRefs(refs: CategoryRef[]) {
return refs
.filter(({ weight }) => weight > 0)
.reduce((sum, { weight }) => sum + weight, 0);
}

export function compareIssueSeverity(
severity1: Issue['severity'],
severity2: Issue['severity'],
severity1: IssueSeverity,
severity2: IssueSeverity,
): number {
const levels: Record<Issue['severity'], number> = {
const levels: Record<IssueSeverity, number> = {
info: 0,
warning: 1,
error: 2,
Expand All @@ -53,6 +53,6 @@ export function compareIssueSeverity(
}

// @TODO replace with real scoring logic
export function sumRefs(refs: CategoryConfig['refs']) {
export function sumRefs(refs: CategoryRef[]) {
return refs.reduce((sum, { weight }) => sum + weight, 0);
}
8 changes: 5 additions & 3 deletions packages/utils/src/lib/scoring.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import {
AuditGroup,
AuditGroupRef,
AuditReport,
CategoryConfig,
CategoryRef,
PluginReport,
Report,
} from '@code-pushup/models';
Expand All @@ -20,7 +22,7 @@ export type ScoredReport = Omit<Report, 'plugins' | 'categories'> & {

function groupRefToScore(
audits: AuditReport[],
): (ref: AuditGroup['refs'][0]) => number {
): (ref: AuditGroupRef) => number {
return ref => {
const score = audits.find(audit => audit.slug === ref.slug)?.score;
if (score == null) {
Expand All @@ -35,8 +37,8 @@ function groupRefToScore(
function categoryRefToScore(
audits: EnrichedAuditReport[],
groups: EnrichedScoredAuditGroup[],
): (ref: CategoryConfig['refs'][0]) => number {
return (ref: CategoryConfig['refs'][0]): number => {
): (ref: CategoryRef) => number {
return (ref: CategoryRef): number => {
switch (ref.type) {
case 'audit':
// eslint-disable-next-line no-case-declarations
Expand Down
Empty file added tmp/.gitkeep
Empty file.