mirror of
https://github.com/microsoft/pyright.git
synced 2024-09-11 16:06:39 +03:00
Added new 'outputjson' command-line option that formats output in JSON format.
This commit is contained in:
parent
d096acb5b2
commit
c0b6f99ae7
@ -7,6 +7,7 @@ Pyright can be run as either a VS Code extension or as a node-based command-line
|
|||||||
| --createstub IMPORT | Create type stub file(s) for import |
|
| --createstub IMPORT | Create type stub file(s) for import |
|
||||||
| --dependencies | Emit import dependency information |
|
| --dependencies | Emit import dependency information |
|
||||||
| -h, --help | Show help message |
|
| -h, --help | Show help message |
|
||||||
|
| --outputjson | Output results in JSON format |
|
||||||
| -p, --project FILE OR DIRECTORY | Use the configuration file at this location |
|
| -p, --project FILE OR DIRECTORY | Use the configuration file at this location |
|
||||||
| --stats | Print detailed performance stats |
|
| --stats | Print detailed performance stats |
|
||||||
| -t, --typeshed-path DIRECTORY | Use typeshed type stubs at this location (1) |
|
| -t, --typeshed-path DIRECTORY | Use typeshed type stubs at this location (1) |
|
||||||
|
@ -18,7 +18,8 @@ import * as process from 'process';
|
|||||||
|
|
||||||
import { AnalyzerService } from './analyzer/service';
|
import { AnalyzerService } from './analyzer/service';
|
||||||
import { CommandLineOptions as PyrightCommandLineOptions } from './common/commandLineOptions';
|
import { CommandLineOptions as PyrightCommandLineOptions } from './common/commandLineOptions';
|
||||||
import { DiagnosticCategory } from './common/diagnostic';
|
import { NullConsole } from './common/console';
|
||||||
|
import { DiagnosticCategory, DiagnosticTextRange } from './common/diagnostic';
|
||||||
import { FileDiagnostics } from './common/diagnosticSink';
|
import { FileDiagnostics } from './common/diagnosticSink';
|
||||||
import { combinePaths, normalizePath } from './common/pathUtils';
|
import { combinePaths, normalizePath } from './common/pathUtils';
|
||||||
|
|
||||||
@ -31,6 +32,27 @@ enum ExitStatus {
|
|||||||
ConfigFileParseError = 3
|
ConfigFileParseError = 3
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface PyrightJsonResults {
|
||||||
|
version: string;
|
||||||
|
time: string;
|
||||||
|
diagnostics: PyrightJsonDiagnostic[];
|
||||||
|
summary: PyrightJsonSummary;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface PyrightJsonDiagnostic {
|
||||||
|
file: string;
|
||||||
|
severity: 'error' | 'warning';
|
||||||
|
message: string;
|
||||||
|
range: DiagnosticTextRange;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface PyrightJsonSummary {
|
||||||
|
filesAnalyzed: number;
|
||||||
|
errorCount: number;
|
||||||
|
warningCount: number;
|
||||||
|
timeInSec: number;
|
||||||
|
}
|
||||||
|
|
||||||
interface DiagnosticResult {
|
interface DiagnosticResult {
|
||||||
errorCount: number;
|
errorCount: number;
|
||||||
warningCount: number;
|
warningCount: number;
|
||||||
@ -43,6 +65,7 @@ function processArgs() {
|
|||||||
{ name: 'dependencies', type: Boolean },
|
{ name: 'dependencies', type: Boolean },
|
||||||
{ name: 'files', type: String, multiple: true, defaultOption: true },
|
{ name: 'files', type: String, multiple: true, defaultOption: true },
|
||||||
{ name: 'help', alias: 'h', type: Boolean },
|
{ name: 'help', alias: 'h', type: Boolean },
|
||||||
|
{ name: 'outputjson', type: Boolean },
|
||||||
{ name: 'project', alias: 'p', type: String },
|
{ name: 'project', alias: 'p', type: String },
|
||||||
{ name: 'stats' },
|
{ name: 'stats' },
|
||||||
{ name: 'typeshed-path', alias: 't', type: String },
|
{ name: 'typeshed-path', alias: 't', type: String },
|
||||||
@ -77,6 +100,16 @@ function processArgs() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (args.outputjson) {
|
||||||
|
const incompatibleArgs = ['watch', 'stats', 'verbose', 'createstub', 'dependencies'];
|
||||||
|
for (const arg of incompatibleArgs) {
|
||||||
|
if (args[arg] !== undefined) {
|
||||||
|
console.error(`'outputjson' option cannot be used with '${ arg }' option`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const options = new PyrightCommandLineOptions(process.cwd(), false);
|
const options = new PyrightCommandLineOptions(process.cwd(), false);
|
||||||
|
|
||||||
// Assume any relative paths are relative to the working directory.
|
// Assume any relative paths are relative to the working directory.
|
||||||
@ -115,7 +148,8 @@ function processArgs() {
|
|||||||
const watch = args.watch !== undefined;
|
const watch = args.watch !== undefined;
|
||||||
options.watch = watch;
|
options.watch = watch;
|
||||||
|
|
||||||
const service = new AnalyzerService('<default>');
|
const service = new AnalyzerService('<default>', args.outputjson ?
|
||||||
|
new NullConsole() : undefined);
|
||||||
|
|
||||||
service.setCompletionCallback(results => {
|
service.setCompletionCallback(results => {
|
||||||
if (results.fatalErrorOccurred) {
|
if (results.fatalErrorOccurred) {
|
||||||
@ -128,8 +162,14 @@ function processArgs() {
|
|||||||
|
|
||||||
let errorCount = 0;
|
let errorCount = 0;
|
||||||
if (results.diagnostics.length > 0 && !args.createstub) {
|
if (results.diagnostics.length > 0 && !args.createstub) {
|
||||||
const report = reportDiagnostics(results.diagnostics);
|
if (args.outputjson) {
|
||||||
errorCount += report.errorCount;
|
const report = reportDiagnosticsAsJson(results.diagnostics,
|
||||||
|
results.filesInProgram, results.elapsedTime);
|
||||||
|
errorCount += report.errorCount;
|
||||||
|
} else {
|
||||||
|
const report = reportDiagnosticsAsText(results.diagnostics);
|
||||||
|
errorCount += report.errorCount;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (args.createstub && results.filesRequiringAnalysis === 0) {
|
if (args.createstub && results.filesRequiringAnalysis === 0) {
|
||||||
@ -190,6 +230,7 @@ function printUsage() {
|
|||||||
' --createstub IMPORT Create type stub file(s) for import\n' +
|
' --createstub IMPORT Create type stub file(s) for import\n' +
|
||||||
' --dependencies Emit import dependency information\n' +
|
' --dependencies Emit import dependency information\n' +
|
||||||
' -h,--help Show this help message\n' +
|
' -h,--help Show this help message\n' +
|
||||||
|
' --outputjson Output results in JSON format\n' +
|
||||||
' -p,--project FILE OR DIRECTORY Use the configuration file at this location\n' +
|
' -p,--project FILE OR DIRECTORY Use the configuration file at this location\n' +
|
||||||
' --stats Print detailed performance stats\n' +
|
' --stats Print detailed performance stats\n' +
|
||||||
' -t,--typeshed-path DIRECTORY Use typeshed type stubs at this location\n' +
|
' -t,--typeshed-path DIRECTORY Use typeshed type stubs at this location\n' +
|
||||||
@ -200,12 +241,65 @@ function printUsage() {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function printVersion() {
|
function getVersionString() {
|
||||||
const version = require('package.json').version;
|
const version = require('package.json').version;
|
||||||
console.log(`${ toolName } ${ version.toString() }`);
|
return version.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
function reportDiagnostics(fileDiagnostics: FileDiagnostics[]): DiagnosticResult {
|
function printVersion() {
|
||||||
|
console.log(`${ toolName } ${ getVersionString() }`);
|
||||||
|
}
|
||||||
|
|
||||||
|
function reportDiagnosticsAsJson(fileDiagnostics: FileDiagnostics[], filesInProgram: number,
|
||||||
|
timeInSec: number): DiagnosticResult {
|
||||||
|
|
||||||
|
const report: PyrightJsonResults = {
|
||||||
|
version: getVersionString(),
|
||||||
|
time: Date.now().toString(),
|
||||||
|
diagnostics: [],
|
||||||
|
summary: {
|
||||||
|
filesAnalyzed: filesInProgram,
|
||||||
|
errorCount: 0,
|
||||||
|
warningCount: 0,
|
||||||
|
timeInSec
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let errorCount = 0;
|
||||||
|
let warningCount = 0;
|
||||||
|
|
||||||
|
fileDiagnostics.forEach(fileDiag => {
|
||||||
|
fileDiag.diagnostics.forEach(diag => {
|
||||||
|
if (diag.category === DiagnosticCategory.Error || diag.category === DiagnosticCategory.Warning) {
|
||||||
|
report.diagnostics.push({
|
||||||
|
file: fileDiag.filePath,
|
||||||
|
severity: diag.category === DiagnosticCategory.Error ? 'error' : 'warning',
|
||||||
|
message: diag.message,
|
||||||
|
range: diag.range
|
||||||
|
});
|
||||||
|
|
||||||
|
if (diag.category === DiagnosticCategory.Error) {
|
||||||
|
errorCount++;
|
||||||
|
} else {
|
||||||
|
warningCount++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
report.summary.errorCount = errorCount;
|
||||||
|
report.summary.warningCount = warningCount;
|
||||||
|
|
||||||
|
console.log(JSON.stringify(report, undefined, 4));
|
||||||
|
|
||||||
|
return {
|
||||||
|
errorCount,
|
||||||
|
warningCount,
|
||||||
|
diagnosticCount: errorCount + warningCount
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function reportDiagnosticsAsText(fileDiagnostics: FileDiagnostics[]): DiagnosticResult {
|
||||||
let errorCount = 0;
|
let errorCount = 0;
|
||||||
let warningCount = 0;
|
let warningCount = 0;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user