Skip to content

Commit 7d96477

Browse files
committed
feat(core): readme documentation included
1 parent 6864e36 commit 7d96477

25 files changed

+233
-109
lines changed

docs/guides/2-cli.md

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ Other options include:
3939
--stdin-filepath path to a file to pretend that stdin comes from [string]
4040
--resolver path to custom json-ref-resolver instance [string]
4141
-r, --ruleset path/URL to a ruleset file [string]
42-
-s, --scoring-matrix path/URL to a scoring matrix config file [string]
42+
-s, --scoring-config path/URL to a scoring config file [string]
4343
-F, --fail-severity results of this level or above will trigger a failure exit code
4444
[string] [choices: "error", "warn", "info", "hint"] [default: "error"]
4545
-D, --display-only-failures only output results equal to or greater than --fail-severity [boolean] [default: false]
@@ -72,12 +72,12 @@ The scoring is produced in two different metrics:
7272

7373
Also it introduces a quality gate, were an API scoring below the specific threshold will fail in a pipeline.
7474

75-
Enabling scoring is done using a new parameter called --scoring-matrix or -s and the scoring matrix configuration file, where you can define how an error or a warning affects to the scoring
75+
Enabling scoring is done using a new parameter called --scoring-config or -s and the scoring configuration file, where you can define how an error or a warning affects to the scoring
7676

7777
Usage:
7878

7979
```bash
80-
spectral lint ./reference/**/*.oas*.{json,yml,yaml} --ruleset mycustomruleset.js --scoring-matrix ./scoringFile.json
80+
spectral lint ./reference/**/*.oas*.{json,yml,yaml} --ruleset mycustomruleset.js --scoring-config ./scoringFile.json
8181
```
8282
or
8383
```bash
@@ -123,7 +123,7 @@ Usage:
123123
```
124124

125125
Where:
126-
- scoringSubtract : An object with an array for every result level we want to subtract percentage, with the percentage to subtract from number of rewsults on every result type
126+
- scoringSubtract : An object with a key/value pair objects for every result level we want to subtract percentage, with the percentage to subtract from number of results on every result type
127127
- scoringLetter : An object with key/value pairs with scoring letter and scoring percentage, that the result must be greater , for this letter
128128
- threshold : A number with minimum percentage value to provide valid the file we are checking
129129
- warningsSubtract : A boolean to setup if accumulate the result types to less the scoring percentage or stop counting on most critical result types
@@ -135,6 +135,8 @@ Where:
135135

136136
1 error, the scoring is 45% and D
137137
2 errors, the scoring is 35% and E
138+
3 errors, the scoring is 25% and E
139+
4 errors, the scoring is 25% and E
138140
and so on
139141

140142
Output:

packages/cli/src/commands/__tests__/lint.test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -146,10 +146,10 @@ describe('lint', () => {
146146
);
147147
});
148148

149-
it('calls lint with document, ruleset and scoring matrix config file', async () => {
149+
it('calls lint with document, ruleset and scoring config file', async () => {
150150
const doc = './__fixtures__/empty-oas2-document.json';
151151
const ruleset = 'custom-ruleset.json';
152-
const configFile = 'scoring-matrix.json';
152+
const configFile = 'scoring-config.json';
153153
await run(`lint -r ${ruleset} -s ${configFile} ${doc}`);
154154
expect(lint).toBeCalledWith([doc], {
155155
encoding: 'utf8',

packages/cli/src/commands/lint.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import { formatOutput, writeOutput } from '../services/output';
1414
import { FailSeverity, ILintConfig, OutputFormat } from '../services/config';
1515

1616
import { CLIError } from '../errors';
17-
import { getScoringMatrix } from '../formatters/utils/getScoring';
17+
import { getScoringConfig } from '../formatters/utils/getScoring';
1818

1919
const formatOptions = Object.values(OutputFormat);
2020

@@ -128,9 +128,9 @@ const lintCommand: CommandModule = {
128128
description: 'path/URL to a ruleset file',
129129
type: 'string',
130130
},
131-
'scoring-matrix': {
131+
'scoring-config': {
132132
alias: 's',
133-
description: 'path/URL to a scoring matrix config file',
133+
description: 'path/URL to a scoring config file',
134134
type: 'string',
135135
},
136136
'fail-severity': {
@@ -174,7 +174,7 @@ const lintCommand: CommandModule = {
174174
failSeverity,
175175
displayOnlyFailures,
176176
ruleset,
177-
scoringMatrix,
177+
scoringConfig,
178178
stdinFilepath,
179179
format,
180180
output,
@@ -208,7 +208,7 @@ const lintCommand: CommandModule = {
208208
format.map(f => {
209209
const formattedOutput = formatOutput(results, f, {
210210
failSeverity: getDiagnosticSeverity(failSeverity),
211-
scoringMatrix: getScoringMatrix(scoringMatrix),
211+
scoringConfig: getScoringConfig(scoringConfig),
212212
});
213213
return writeOutput(formattedOutput, output?.[f] ?? '<stdout>');
214214
}),

packages/cli/src/formatters/json.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,12 @@ export const json: Formatter = (results: ISpectralDiagnostic[], options: Formatt
99
let spectralVersion = '';
1010
let groupedResults;
1111
let scoringText = '';
12-
if (options.scoringMatrix !== void 0) {
13-
if (options.scoringMatrix.customScoring !== undefined) {
14-
spectralVersion = `${options.scoringMatrix.customScoring} ${version as string}`;
12+
if (options.scoringConfig !== void 0) {
13+
if (options.scoringConfig.customScoring !== undefined) {
14+
spectralVersion = `${options.scoringConfig.customScoring} ${version as string}`;
1515
}
1616
groupedResults = groupBySource(uniqueErrors(results));
17-
scoringText = getScoringText(getCountsBySeverity(groupedResults), options.scoringMatrix);
17+
scoringText = getScoringText(getCountsBySeverity(groupedResults), options.scoringConfig);
1818
}
1919
const outputJson = results.map(result => {
2020
return {
@@ -27,12 +27,12 @@ export const json: Formatter = (results: ISpectralDiagnostic[], options: Formatt
2727
};
2828
});
2929
let objectOutput;
30-
if (options.scoringMatrix !== void 0) {
30+
if (options.scoringConfig !== void 0) {
3131
const scoring = +(scoringText !== null ? scoringText.replace('%', '').split(/[()]+/)[1] : 0);
3232
objectOutput = {
3333
version: spectralVersion,
3434
scoring: scoringText.replace('SCORING:', '').trim(),
35-
passed: scoring >= options.scoringMatrix.threshold,
35+
passed: scoring >= options.scoringConfig.threshold,
3636
results: outputJson,
3737
};
3838
} else {

packages/cli/src/formatters/pretty.ts

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -52,9 +52,9 @@ function formatRange(range?: IRange): string {
5252
export const pretty: Formatter = (results: ISpectralDiagnostic[], options: FormatterOptions) => {
5353
const cliui = require('cliui');
5454
let output = '\n';
55-
if (options.scoringMatrix !== void 0) {
56-
if (options.scoringMatrix.customScoring !== void 0) {
57-
output += `${options.scoringMatrix.customScoring}${version as string}\n`;
55+
if (options.scoringConfig !== void 0) {
56+
if (options.scoringConfig.customScoring !== void 0) {
57+
output += `${options.scoringConfig.customScoring}${version as string}\n`;
5858
}
5959
}
6060
output += '\n';
@@ -77,12 +77,12 @@ export const pretty: Formatter = (results: ISpectralDiagnostic[], options: Forma
7777
let scoringColor = '';
7878
let scoringText = null;
7979

80-
if (options.scoringMatrix !== void 0) {
81-
if (options.scoringMatrix.uniqueErrors) {
80+
if (options.scoringConfig !== void 0) {
81+
if (options.scoringConfig.uniqueErrors) {
8282
groupedUniqueResults = { ...groupBySource(uniqueResults) };
8383
}
8484
scoringColor = getColorForSeverity(DiagnosticSeverity.Information);
85-
scoringText = getScoringText(getCountsBySeverity(groupedUniqueResults), options.scoringMatrix);
85+
scoringText = getScoringText(getCountsBySeverity(groupedUniqueResults), options.scoringConfig);
8686
}
8787

8888
const uniqueIssues: IDiagnostic['code'][] = [];
@@ -114,10 +114,10 @@ export const pretty: Formatter = (results: ISpectralDiagnostic[], options: Forma
114114
output += ui.toString();
115115
output += chalk[summaryColor].bold(`${uniqueIssues.length} Unique Issue(s)\n`);
116116
output += chalk[summaryColor].bold(`\u2716${summaryText !== null ? ` ${summaryText}` : ''}\n`);
117-
if (options.scoringMatrix !== void 0) {
117+
if (options.scoringConfig !== void 0) {
118118
output += chalk[scoringColor].bold(`\u2716${scoringText !== null ? ` ${scoringText}` : ''}\n`);
119119
const scoring = +(scoringText !== null ? scoringText.replace('%', '').split(/[()]+/)[1] : 0);
120-
if (scoring >= options.scoringMatrix.threshold) {
120+
if (scoring >= options.scoringConfig.threshold) {
121121
output += chalk['green'].bold(`\u2716 PASSED!\n`);
122122
} else {
123123
output += chalk['red'].bold(`\u2716 NOT PASSED!\n`);

packages/cli/src/formatters/stylish.ts

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -70,9 +70,9 @@ function getMessageType(severity: DiagnosticSeverity): string {
7070

7171
export const stylish: Formatter = (results: ISpectralDiagnostic[], options: FormatterOptions) => {
7272
let output = '\n';
73-
if (options.scoringMatrix !== void 0) {
74-
if (options.scoringMatrix.customScoring !== void 0) {
75-
output += `${options.scoringMatrix.customScoring}${version as string}\n`;
73+
if (options.scoringConfig !== void 0) {
74+
if (options.scoringConfig.customScoring !== void 0) {
75+
output += `${options.scoringConfig.customScoring}${version as string}\n`;
7676
}
7777
}
7878
output += '\n';
@@ -85,12 +85,12 @@ export const stylish: Formatter = (results: ISpectralDiagnostic[], options: Form
8585
let scoringColor = '';
8686
let scoringText = null;
8787

88-
if (options.scoringMatrix !== void 0) {
89-
if (options.scoringMatrix.uniqueErrors) {
88+
if (options.scoringConfig !== void 0) {
89+
if (options.scoringConfig.uniqueErrors) {
9090
groupedUniqueResults = { ...groupBySource(uniqueResults) };
9191
}
9292
scoringColor = getColorForSeverity(DiagnosticSeverity.Information);
93-
scoringText = getScoringText(getCountsBySeverity(groupedUniqueResults), options.scoringMatrix);
93+
scoringText = getScoringText(getCountsBySeverity(groupedUniqueResults), options.scoringConfig);
9494
}
9595

9696
Object.keys(groupedResults).map(path => {
@@ -124,10 +124,10 @@ export const stylish: Formatter = (results: ISpectralDiagnostic[], options: Form
124124
}
125125

126126
output += chalk[summaryColor].bold(`\u2716 ${summaryText}\n`);
127-
if (options.scoringMatrix !== void 0) {
127+
if (options.scoringConfig !== void 0) {
128128
output += chalk[scoringColor].bold(`\u2716${scoringText !== null ? ` ${scoringText}` : ''}\n`);
129129
const scoring = +(scoringText !== null ? scoringText.replace('%', '').split(/[()]+/)[1] : 0);
130-
if (scoring >= options.scoringMatrix.threshold) {
130+
if (scoring >= options.scoringConfig.threshold) {
131131
output += chalk['green'].bold(`\u2716 PASSED!\n`);
132132
} else {
133133
output += chalk['red'].bold(`\u2716 NOT PASSED!\n`);

packages/cli/src/formatters/types.ts

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,15 @@ import type { HumanReadableDiagnosticSeverity } from '@stoplight/spectral-core';
33
import type { DiagnosticSeverity } from '@stoplight/types';
44

55
export type ScoringTable = {
6-
[key in HumanReadableDiagnosticSeverity]: number[];
6+
[key in HumanReadableDiagnosticSeverity]: ScoringSubtract[];
77
};
8+
export interface ScoringSubtract {
9+
[key: number]: number;
10+
}
811
export interface ScoringLevel {
912
[key: string]: number;
1013
}
11-
export type ScoringMatrix = {
14+
export type ScoringConfig = {
1215
customScoring?: string;
1316
scoringSubtract: ScoringTable[];
1417
scoringLetter: ScoringLevel[];
@@ -19,7 +22,7 @@ export type ScoringMatrix = {
1922

2023
export type FormatterOptions = {
2124
failSeverity: DiagnosticSeverity;
22-
scoringMatrix?: ScoringMatrix;
25+
scoringConfig?: ScoringConfig;
2326
};
2427

2528
export type Formatter = (results: ISpectralDiagnostic[], options: FormatterOptions) => string;

packages/cli/src/formatters/utils/getScoring.ts

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,19 @@
11
import { SEVERITY_MAP } from '@stoplight/spectral-core';
22
import { DiagnosticSeverity } from '@stoplight/types';
3-
import { ScoringMatrix } from '../types';
3+
import { ScoringConfig } from '../types';
44
import * as path from '@stoplight/path';
55
import fs from 'fs';
66

7-
export const getScoringMatrix = (scoringFile?: string): ScoringMatrix | undefined => {
7+
export const getScoringConfig = (scoringFile?: string): ScoringConfig | undefined => {
88
if (scoringFile === void 0) {
99
return undefined;
1010
} else if (!path.isAbsolute(scoringFile)) {
1111
scoringFile = path.join(process.cwd(), scoringFile);
1212
}
1313

14-
const scoringMatrix: ScoringMatrix = JSON.parse(fs.readFileSync(scoringFile, 'utf-8')) as ScoringMatrix;
14+
const scoringConfig: ScoringConfig = JSON.parse(fs.readFileSync(scoringFile, 'utf-8')) as ScoringConfig;
1515

16-
return scoringMatrix;
16+
return scoringConfig;
1717
};
1818

1919
export const getScoringText = (
@@ -23,15 +23,22 @@ export const getScoringText = (
2323
[DiagnosticSeverity.Information]: number;
2424
[DiagnosticSeverity.Hint]: number;
2525
},
26-
scoringMatrix: ScoringMatrix,
26+
scoringConfig: ScoringConfig,
2727
): string => {
28-
const { scoringSubtract, scoringLetter, warningsSubtract } = scoringMatrix;
28+
const { scoringSubtract, scoringLetter, warningsSubtract } = scoringConfig;
2929
let scoring = 100;
3030
Object.keys(issuesCount).forEach(key => {
31-
const scoringKey = Object.keys(SEVERITY_MAP).filter(mappedKey => SEVERITY_MAP[mappedKey])[0];
31+
const scoringKey = Object.keys(SEVERITY_MAP).filter(mappedKey => SEVERITY_MAP[mappedKey] == key)[0];
3232
if (scoringSubtract[scoringKey] !== void 0) {
3333
if (scoring < 100 && !warningsSubtract) return;
34-
scoring -= (scoringSubtract[scoringKey] as number[])[(issuesCount[key] >= 10 ? 10 : issuesCount[key]) as number];
34+
let subtractValue = 0;
35+
Object.keys(scoringSubtract[scoringKey]).forEach(
36+
subtractKey =>
37+
subtractValue = issuesCount[key] >= subtractKey ?
38+
scoringSubtract[scoringKey][subtractKey] :
39+
subtractValue
40+
);
41+
scoring -= subtractValue;
3542
}
3643
});
3744
let scoringLevel: string = Object.keys(scoringLetter)[Object.keys(scoringLetter).length - 1];
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
{
2+
"scoringSubtract":
3+
{
4+
"error":
5+
{
6+
"1":55,
7+
"2":65,
8+
"3":75,
9+
"6":85,
10+
"10":95
11+
},
12+
"warn":
13+
{
14+
"1":3,
15+
"2":7,
16+
"3":10,
17+
"6":15,
18+
"10":18
19+
}
20+
},
21+
"scoringLetter":
22+
{
23+
"A": 75,
24+
"B": 65,
25+
"C": 55,
26+
"D": 45,
27+
"E": 0
28+
},
29+
"threshold": 50,
30+
"warningsSubtract": true,
31+
"uniqueErrors": false
32+
}

packages/cli/src/services/__tests__/__fixtures__/scoring-matrix.json

Lines changed: 0 additions & 18 deletions
This file was deleted.

0 commit comments

Comments
 (0)