packages/jsii-diff/lib/diagnostics.ts (85 lines of code) (raw):

import { Stability } from '@jsii/spec'; import { ApiMismatch, Mismatches } from './types'; export enum DiagLevel { Error = 0, Warning = 1, Skipped = 2, } const LEVEL_PREFIX = { [DiagLevel.Error]: 'err ', [DiagLevel.Warning]: 'warn', [DiagLevel.Skipped]: 'skip', }; export interface Diagnostic { level: DiagLevel; message: string; suppressionKey: string; } export function formatDiagnostic( diag: Diagnostic, includeSuppressionKey = false, ) { return [ LEVEL_PREFIX[diag.level], '-', diag.message, ...(includeSuppressionKey ? [`[${diag.suppressionKey}]`] : []), ].join(' '); } export function hasErrors(diags: Diagnostic[]) { return diags.some((diag) => diag.level === DiagLevel.Error); } export function onlyErrors(diags: Diagnostic[]) { return diags.filter((diag) => diag.level === DiagLevel.Error); } export function onlyWarnings(diags: Diagnostic[]) { return diags.filter((diag) => diag.level === DiagLevel.Warning); } export const ERROR_CLASSES = ['prod', 'non-experimental', 'all'] as const; export type ErrorClass = (typeof ERROR_CLASSES)[number]; export const ERROR_CLASSES_TO_STABILITIES: Record<ErrorClass, Stability[]> = { prod: [Stability.Stable, Stability.Deprecated], 'non-experimental': [ Stability.Stable, Stability.Deprecated, Stability.External, ], all: [ Stability.Stable, Stability.Experimental, Stability.External, Stability.Deprecated, ], }; export function treatAsError( errorClass: ErrorClass, deprecatedExperimentalErrors = false, ): Set<Stability> { const shouldError = new Set<Stability>(); for (const stability of ERROR_CLASSES_TO_STABILITIES[errorClass]) { shouldError.add(stability); } if (deprecatedExperimentalErrors) { shouldError.add(Stability.Experimental); } return shouldError; } /** * Classify API mismatches into a set of warnings and errors */ export function classifyDiagnostics( mismatches: Mismatches, shouldError: Set<Stability>, skipFilter: Set<string> = new Set(), ): Diagnostic[] { const ret = mismatches.mismatches.map((mis) => ({ level: level(mis), message: mis.message, suppressionKey: mis.violationKey, })); ret.sort((a, b) => a.level - b.level); return ret; function level(mis: ApiMismatch) { if (skipFilter.has(mis.violationKey)) { return DiagLevel.Skipped; } return shouldError.has(mis.stability) ? DiagLevel.Error : DiagLevel.Warning; } }