function runLinter()

in server/src/server.ts [160:309]


function runLinter(document: TextDocument): void {
	let uri = document.uri;

	if (isRunningLinterOn[uri]) {
		connection.sendNotification('cfn/busy');
		return;
	}

	let file_to_lint = URI.parse(uri).fsPath;

	let is_cfn = isCloudFormation(document.getText(), uri.toString());

	connection.sendNotification('cfn/isPreviewable', is_cfn);

	let build_graph = isPreviewing[uri];

	if (is_cfn) {
		let args = ['--format', 'json'];
		if (build_graph) {
			args.push('--build-graph');
		}

		if (IgnoreRules.length > 0) {
			for (var ignoreRule of IgnoreRules) {
				args.push('--ignore-checks');
				args.push(ignoreRule);
			}
		}

		if (AppendRules.length > 0) {
			for (var appendRule of AppendRules) {
				args.push('--append-rules');
				args.push(appendRule);
			}
		}

		if (OverrideSpecPath !== "") {
			args.push('--override-spec', OverrideSpecPath);
		}

		args.push('--', `"${file_to_lint}"`);

		connection.console.log(`Running... ${Path} ${args}`);

		isRunningLinterOn[uri] = true;
		let child = spawn(
			Path,
			args,
			{
				cwd: workspaceRoot,
				shell: true
			}
		);

		let diagnostics: Diagnostic[] = [];
		let filename = uri.toString();
		let start = 0;
		let end = Number.MAX_VALUE;

		child.on('error', function (err) {
			let errorMessage = `Unable to start cfn-lint (${err}). Is cfn-lint installed correctly?`;
			connection.console.log(errorMessage);
			let lineNumber = 0;
			let diagnostic: Diagnostic = {
				range: {
					start: { line: lineNumber, character: start },
					end: { line: lineNumber, character: end }
				},
				severity: DiagnosticSeverity.Error,
				message: '[cfn-lint] ' + errorMessage
			};
			diagnostics.push(diagnostic);
			return;
		});

		child.stderr.on("data", (data: Buffer) => {
			let err = data.toString();
			connection.console.log(err);
			let lineNumber = 0;
			let diagnostic: Diagnostic = {
				range: {
					start: { line: lineNumber, character: start },
					end: { line: lineNumber, character: end }
				},
				severity: DiagnosticSeverity.Warning,
				message: '[cfn-lint] ' + err + '\nGo to https://github.com/aws-cloudformation/cfn-python-lint/#install for more help'
			};
			diagnostics.push(diagnostic);
			return;
		});

		let stdout = "";
		child.stdout.on("data", (data: Buffer) => {
			stdout = stdout.concat(data.toString());
		});

		child.on('exit', function (code, signal) {
			connection.console.log('child process exited with ' +
				`code ${code} and signal ${signal}`);
			let tmp = stdout.toString();
			let obj;
			try {
				obj = JSON.parse(tmp);
			} catch (err) {
				let lineNumber = 0;
				let diagnostic: Diagnostic = {
					range: {
						start: { line: lineNumber, character: start },
						end: { line: lineNumber, character: end }
					},
					severity: DiagnosticSeverity.Warning,
					message: '[cfn-lint] ' + err + '\nGo to https://github.com/aws-cloudformation/cfn-python-lint/#install for more help'
				};
				diagnostics.push(diagnostic);
				return;
			}
			for (let element of obj) {
				let lineNumber = (Number.parseInt(element.Location.Start.LineNumber) - 1);
				let columnNumber = (Number.parseInt(element.Location.Start.ColumnNumber) - 1);
				let lineNumberEnd = (Number.parseInt(element.Location.End.LineNumber) - 1);
				let columnNumberEnd = (Number.parseInt(element.Location.End.ColumnNumber) - 1);
				let diagnostic: Diagnostic = {
					range: {
						start: { line: lineNumber, character: columnNumber },
						end: { line: lineNumberEnd, character: columnNumberEnd }
					},
					severity: convertSeverity(element.Level),
					message: '[cfn-lint] ' + element.Rule.Id + ': ' + element.Message
				};

				diagnostics.push(diagnostic);
			};
		});

		child.on("close", () => {
			//connection.console.log(`Validation finished for(code:${code}): ${Files.uriToFilePath(uri)}`);
			connection.sendDiagnostics({ uri: filename, diagnostics });
			isRunningLinterOn[uri] = false;

			if (build_graph) {
				connection.console.log('preview file is available');
				connection.sendNotification('cfn/previewIsAvailable', uri);
			}
		});
	} else {
		connection.console.log("Don't believe this is a CloudFormation template. " + uri.toString() +
			". If it is please add AWSTemplateFormatVersion: '2010-09-09' (YAML) or " +
			" \"AWSTemplateFormatVersion\": \"2010-09-09\" (JSON) into the root level of the document.");
	}
}