Skip to content

Commit d1ee9b6

Browse files
committed
feat(codeclimate): outputFormat for CodeClimate (IBM#512)
Signed-off-by: Matthias Blümel <[email protected]>
1 parent 2a5b905 commit d1ee9b6

File tree

6 files changed

+67
-5
lines changed

6 files changed

+67
-5
lines changed

README.md

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ The IBM OpenAPI Validator lets you validate OpenAPI 3.x documents according to t
5151
- [Validator Output](#validator-output)
5252
* [Text](#text)
5353
* [JSON](#json)
54+
* [CodeClimate](#codeclimate)
5455
- [Logging](#logging)
5556
- [Contributing](#contributing)
5657
- [License](#license)
@@ -125,6 +126,7 @@ Options:
125126
-e, --errors-only include only errors in the output and skip warnings (default is false)
126127
-i, --ignore <file> avoid validating <file> (e.g. -i /dir1/ignore-file1.json --ignore /dir2/ignore-file2.yaml ...) (default is []) (default: [])
127128
-j, --json produce JSON output (default is text)
129+
--codeclimate produce JSON output according to CodeClimate spec
128130
-l, --log-level <loglevel> set the log level for one or more loggers (e.g. -l root=info -l ibm-schema-description-exists=debug ...) (default: [])
129131
-n, --no-colors disable colorizing of the output (default is false)
130132
-r, --ruleset <file> use Spectral ruleset contained in `<file>` ("default" forces use of default IBM Cloud Validation Ruleset)
@@ -492,9 +494,9 @@ module.exports = {
492494
<td width=25%><b>Default</b></td>
493495
</tr>
494496
<tr>
495-
<td>You can set the <code>outputFormat</code> configuration property to either <code>text</code> or <code>json</code>
497+
<td>You can set the <code>outputFormat</code> configuration property to either <code>text</code>, <code>json</code> or <code>codeclimate</code>
496498
to indicate the type of output you want the validator to produce.
497-
This property corresponds to the <code>-j</code>/<code>--json</code> command-line option.</td>
499+
This property corresponds to the <code>-j</code>/<code>--json</code>/<code>--codeclimate</code> command-line option.</td>
498500
<td><code>text</code></td>
499501
</tr>
500502
</table>
@@ -631,7 +633,7 @@ module.exports = {
631633

632634
## Validator Output
633635
The validator can produce output in either text or JSON format. The default is `text` output, and this can be
634-
controlled with the `-j`/`--json` command-line option or `outputFormat` configuration property.
636+
controlled with the `-j`/`--json`/`--codeclimate` command-line option or `outputFormat` configuration property.
635637

636638
### Text
637639
Here is an example of text output:
@@ -763,6 +765,10 @@ Here is an example of JSON output:
763765
The JSON output is also affected by the `-s`/`--summary-only` and `-e`/`--errors-only` options as well as the `summaryOnly` and `errorsOnly`
764766
configuration properties.
765767

768+
### CodeClimate
769+
When displaying CodeClimate JSON output, the validator will produce a null-byte separated stream of JSON objects
770+
which complies with [the CodeClimate Output format](https://github.com/codeclimate/platform/blob/master/spec/analyzers/SPEC.md#output).
771+
766772
## Logging
767773
The validator uses a *logger* for displaying messages on the console.
768774
The core validator uses a single logger named `root`, while each of the rules contained in the

packages/validator/src/cli-validator/run-validator.js

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ const ext = require('./utils/file-extension-validator');
1818
const preprocessFile = require('./utils/preprocess-file');
1919
const print = require('./utils/print-results');
2020
const { printJson } = require('./utils/json-results');
21+
const { printCCJson } = require('./utils/codeclimate-results');
2122
const { runSpectral } = require('../spectral/spectral-validator');
2223
const getCopyrightString = require('./utils/get-copyright-string');
2324

@@ -72,7 +73,7 @@ async function runValidator(cliArgs, parseOptions = {}) {
7273

7374
context.chalk = chalk;
7475

75-
if (context.config.outputFormat !== 'json') {
76+
if (context.config.outputFormat === 'text') {
7677
console.log(getCopyrightString());
7778
}
7879

@@ -157,7 +158,7 @@ async function runValidator(cliArgs, parseOptions = {}) {
157158
let originalFile;
158159
let input;
159160

160-
if (context.config.outputFormat != 'json') {
161+
if (context.config.outputFormat === 'text') {
161162
console.log('');
162163
console.log(chalk.underline(`Validation Results for ${validFile}:\n`));
163164
}
@@ -219,6 +220,8 @@ async function runValidator(cliArgs, parseOptions = {}) {
219220
// Now print the results, either JSON or text.
220221
if (context.config.outputFormat === 'json') {
221222
printJson(context, results);
223+
} else if (context.config.outputFormat === 'codeclimate') {
224+
printCCJson(validFile, results);
222225
} else {
223226
if (results.hasResults) {
224227
print(context, results);

packages/validator/src/cli-validator/utils/cli-options.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ function createCLIOptions() {
5858
[]
5959
)
6060
.option('-j, --json', 'produce JSON output (default is text)')
61+
.option('--codeclimate', 'produce JSON output according to CodeClimate spec')
6162
.option(
6263
'-l, --log-level <loglevel>',
6364
'set the log level for one or more loggers (e.g. -l root=info -l ibm-schema-description-exists=debug ...) ',
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
/**
2+
* Copyright 2023 IBM Corporation, Matthias Blümel.
3+
* SPDX-License-Identifier: Apache2.0
4+
*/
5+
6+
const each = require('lodash/each');
7+
8+
function printCCJson(validFile, results) {
9+
const types = ['error', 'warning', 'info', 'hint'];
10+
const ccTypeMap = {
11+
error: 'critical',
12+
warning: 'major',
13+
info: 'minor',
14+
hint: 'info',
15+
};
16+
17+
types.forEach(type => {
18+
each(results[type].results, result => {
19+
let content;
20+
if (result.path.length !== 0) {
21+
let markdown = '';
22+
each(result.path, pathItem => {
23+
markdown += '* ' + pathItem + '\n';
24+
});
25+
content = { body: markdown };
26+
}
27+
const ccResult = {
28+
type: 'issue',
29+
check_name: result.rule,
30+
description: result.message,
31+
content: content,
32+
categories: ['Style'], // required by codeclimate, ignored by gitlab; has to be defined by the rule.
33+
location: {
34+
path: validFile,
35+
lines: {
36+
begin: result.line,
37+
end: result.line,
38+
},
39+
},
40+
severity: ccTypeMap[type],
41+
};
42+
console.log(JSON.stringify(ccResult) + '\0\n');
43+
});
44+
});
45+
}
46+
47+
module.exports.printCCJson = printCCJson;

packages/validator/src/cli-validator/utils/configuration-manager.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,10 @@ async function processArgs(args, cliParseOptions) {
224224
configObj.outputFormat = 'json';
225225
}
226226

227+
if ('codeclimate' in opts) {
228+
configObj.outputFormat = 'codeclimate';
229+
}
230+
227231
if ('ruleset' in opts) {
228232
configObj.ruleset = opts.ruleset;
229233
}

packages/validator/src/schemas/config-file.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ properties:
5959
type: string
6060
enum:
6161
- json
62+
- codeclimate
6263
- text
6364
default: text
6465
ruleset:

0 commit comments

Comments
 (0)