Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for --stdin-filename for nested config #136

Merged
merged 1 commit into from
Jul 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 38 additions & 23 deletions src/features/helper/configuration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import * as path from "path";
import * as vscode from "vscode";
import { DiagnosticSeverity } from "vscode";

import SQLFluff from "../providers/sqlfluff";
import DiagnosticSetting from "./types/diagnosticSetting";
import EnvironmentVariable from "./types/environmentVariable";
import FormatLanguageSettings from "./types/formatLanguageSettings";
Expand Down Expand Up @@ -33,6 +34,14 @@ export default class Configuration {
});
}
});

vscode.workspace.onDidChangeConfiguration((event) => {
if (event.affectsConfiguration("sqlfluff.executablePath")) {
SQLFluff.getCLIVersion();
}
});

SQLFluff.getCLIVersion();
}

public static environmentVariables(env: NodeJS.ProcessEnv): NodeJS.ProcessEnv {
Expand Down Expand Up @@ -217,7 +226,7 @@ export default class Configuration {
public static noqaDisabledRules(): string[] {
const defaultDisabledRules = ["L015", "L017", "L019", "L030", "L032", "L034", "L035", "L037", "L038", "L040", "L041", "L042", "L043", "L044", "L054", "L058", "L063", "L064"];
const noqa = vscode.workspace
.getConfiguration("sqlfluff.codeActions")
.getConfiguration("sqlfluff.codeActions")
.get<string[] | boolean>("noqa", defaultDisabledRules);

if (typeof noqa === "boolean") return [];
Expand All @@ -235,18 +244,18 @@ export default class Configuration {

public static formatLanguages(): string[] {
const languageSettings: (FormatLanguageSettings | string)[] | undefined = vscode.workspace
.getConfiguration("sqlfluff.format")
.get("languages");
.getConfiguration("sqlfluff.format")
.get("languages");


const languages: string[] = [];
languageSettings?.forEach((languageSetting: FormatLanguageSettings | string) => {
if (typeof languageSetting === "string") {
languages.push(languageSetting);
} else {
languages.push(languageSetting.language)
}
})
if (typeof languageSetting === "string") {
languages.push(languageSetting);
} else {
languages.push(languageSetting.language);
}
});

return languages;
}
Expand All @@ -258,31 +267,31 @@ export default class Configuration {

const languages: string[] = [];
languageSettings?.forEach((languageSetting: FormatLanguageSettings | string) => {
if (typeof languageSetting === "string") {
languages.push(languageSetting);
} else if (languageSetting.contextMenuFormatOptions) {
languages.push(languageSetting.language);
}
})
if (typeof languageSetting === "string") {
languages.push(languageSetting);
} else if (languageSetting.contextMenuFormatOptions) {
languages.push(languageSetting.language);
}
});

return languages;
}

public static formatLanguageSetting(languageId: string): FormatLanguageSettings | undefined {
const languageSettings: (FormatLanguageSettings | string)[] | undefined = vscode.workspace
.getConfiguration("sqlfluff.format")
.get("languages");
.getConfiguration("sqlfluff.format")
.get("languages");

const setting = languageSettings?.find((languageSetting: FormatLanguageSettings | string) => {
if (typeof languageSettings === "string") return false;
if (typeof languageSettings === "string") return false;

const typedSetting = languageSetting as unknown as FormatLanguageSettings;
if (typedSetting.language === languageId) return true;
const typedSetting = languageSetting as unknown as FormatLanguageSettings;
if (typedSetting.language === languageId) return true;

return false;
});
return false;
});

if (typeof setting === "string") return undefined
if (typeof setting === "string") return undefined;
return setting;
}

Expand Down Expand Up @@ -378,6 +387,12 @@ export default class Configuration {

public static formatFileArguments(): string[] {
const extraArguments = [...this.fixArguments()];
if (
!SQLFluff.isForceDeprecated() &&
!extraArguments.some((x) => x == "--force")
) {
extraArguments.push("--force");
}

return extraArguments;
}
Expand Down
2 changes: 1 addition & 1 deletion src/features/providers/linter/lint.ts
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ export default class LintingProvider {
const workspaceFolder = vscode.workspace.workspaceFolders ? vscode.workspace.workspaceFolders[0].uri.fsPath : undefined;
const rootPath = workspaceFolder ? Utilities.normalizePath(workspaceFolder) : undefined;
const workingDirectory = workspacePath ?? Configuration.workingDirectory(rootPath);
const filePath = document ? Utilities.normalizePath(document.fileName) : workingDirectory;
const filePath = document && !document.isUntitled ? Utilities.normalizePath(document.fileName) : workingDirectory;

if (!filePath) {
Utilities.outputChannel.appendLine("ERROR: File path not found.");
Expand Down
143 changes: 99 additions & 44 deletions src/features/providers/sqlfluff.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,15 @@ import CommandType from "./types/commandType";

export default class SQLFluff {
static childProcesses: CProcess.ChildProcess[] = [];
static version: [major: number, minor: number, patch: number];

static isForceDeprecated = () => {
return SQLFluff.version >= [3, 0, 0];
};

static supportsStdinFilename = () => {
return SQLFluff.version > [3, 0, 5];
};

public static async run(
workingDirectory: string | undefined,
Expand Down Expand Up @@ -86,74 +95,107 @@ export default class SQLFluff {
const normalizedWorkingDirectory = workingDirectory ? Utilities.normalizePath(workingDirectory) : undefined;
const shouldUseStdin = !!options.fileContents?.length;
const finalArgs = [command, ...args, ...Configuration.extraArguments()];
const targetFileRelativePath = SQLFluff.getTargetFileRelativePath(options, normalizedWorkingDirectory);

Utilities.appendHyphenatedLine();
if (shouldUseStdin) {
Utilities.outputChannel.appendLine("Reading from stdin, not file, input may be dirty/partial");
if (SQLFluff.supportsStdinFilename() && targetFileRelativePath) {
finalArgs.push("--stdin-filename");
finalArgs.push(targetFileRelativePath);
}
finalArgs.push("-");
} else if (options.workspacePath) {
Utilities.outputChannel.appendLine("Reading from workspace, not stdin");
} else {
Utilities.outputChannel.appendLine("Reading from file, not stdin");
finalArgs.push(targetFileRelativePath!);
}

if (Configuration.dbtInterfaceEnabled() && command === CommandType.LINT) {
return await SQLFluff.runDbtInterface(shouldUseStdin, options);
}

return SQLFluff.runCommand(
finalArgs,
normalizedWorkingDirectory,
shouldUseStdin,
options,
command,
);
}

private static getTargetFileRelativePath(options: CommandOptions, normalizedWorkingDirectory: string | undefined) {
if (options.filePath) {
// We want to use relative path to the file so intermediate sqlfluff config files can be found
const normalizedFilePath = Utilities.normalizePath(options.filePath);
const targetFileRelativePath = normalizedWorkingDirectory
return normalizedWorkingDirectory
? Utilities.normalizePath(path.relative(normalizedWorkingDirectory, normalizedFilePath))
: normalizedFilePath;
finalArgs.push(targetFileRelativePath);
}
}

if (Configuration.dbtInterfaceEnabled() && command === CommandType.LINT) {
const dbtInterface = new DbtInterface(
shouldUseStdin ? options.fileContents : undefined,
options.workspacePath ?? options.filePath,
Configuration.config(),
);

Utilities.outputChannel.appendLine("\n--------------------Executing Command--------------------\n");
Utilities.outputChannel.appendLine(dbtInterface.getLintURL());
if (shouldUseStdin) {
Utilities.outputChannel.appendLine("\n-----Request Body-----\n");
if (options.fileContents) {
Utilities.outputChannel.appendLine(options.fileContents);
} else {
Utilities.outputChannel.appendLine("ERROR: File contents not found.");
}
private static async runDbtInterface(
shouldUseStdin: boolean,
options: CommandOptions,
): Promise<CommandOutput> {
const dbtInterface = new DbtInterface(
shouldUseStdin ? options.fileContents : undefined,
options.workspacePath ?? options.filePath,
Configuration.config(),
);

Utilities.outputChannel.appendLine("\n--------------------Executing Command--------------------\n");
Utilities.outputChannel.appendLine(dbtInterface.getLintURL());
if (shouldUseStdin) {
Utilities.outputChannel.appendLine("\n-----Request Body-----\n");
if (options.fileContents) {
Utilities.outputChannel.appendLine(options.fileContents);
} else {
Utilities.outputChannel.appendLine("ERROR: File contents not found.");
}
}

Utilities.appendHyphenatedLine();
Utilities.appendHyphenatedLine();

const response: any = await dbtInterface.lint();
const output: FilePath[] = [
{
filepath: options.filePath,
violations: response.result ?? [],
},
];
const response: any = await dbtInterface.lint();
const output: FilePath[] = [
{
filepath: options.filePath,
violations: response.result ?? [],
},
];

Utilities.outputChannel.appendLine("Raw dbt-omsosis /lint output:");
Utilities.appendHyphenatedLine();
Utilities.outputChannel.appendLine(JSON.stringify(response, undefined, 2));
Utilities.appendHyphenatedLine();
Utilities.outputChannel.appendLine("Raw dbt-omsosis /lint output:");
Utilities.appendHyphenatedLine();
Utilities.outputChannel.appendLine(JSON.stringify(response, undefined, 2));
Utilities.appendHyphenatedLine();

return new Promise<CommandOutput>((resolve) => {
const code = response?.error?.code ?? 0;
const succeeded = code === 0;
if (!succeeded && !Configuration.suppressNotifications()) {
const message = response?.error?.message ?? "DBT-Interface linting error.";
const detail = response?.error?.data?.error ?? "";
return new Promise<CommandOutput>((resolve) => {
const code = response?.error?.code ?? 0;
const succeeded = code === 0;
if (!succeeded && !Configuration.suppressNotifications()) {
const message = response?.error?.message ?? "DBT-Interface linting error.";
const detail = response?.error?.data?.error ?? "";

vscode.window.showErrorMessage([message, detail].join("\n"));
}
vscode.window.showErrorMessage([message, detail].join("\n"));
}

resolve({
resolve({
// 0 = all good, 1 = format passed but contains unfixable linting violations, 65 = lint passed but found errors
succeeded: succeeded,
lines: [JSON.stringify(output)],
});
succeeded: succeeded,
lines: [JSON.stringify(output)],
});
}
});
}

private static runCommand(
finalArgs: string[],
normalizedWorkingDirectory: string | undefined,
shouldUseStdin: boolean,
options: CommandOptions | undefined,
command: CommandType | undefined,
): Promise<CommandOutput> {
return new Promise<CommandOutput>((resolve) => {
const stdoutLint = new LineDecoder();
const stdoutFix: Buffer[] = [];
Expand Down Expand Up @@ -184,7 +226,7 @@ export default class SQLFluff {
childProcess.stdout.on("data", onStdoutDataEvent);
childProcess.stderr.on("data", onStderrDataEvent);
childProcess.on("close", (code, number) => onCloseEvent(code, number, childProcess));
if (shouldUseStdin) {
if (shouldUseStdin && options) {
childProcess.stdin.write(options.fileContents);
childProcess.stdin.end();
}
Expand Down Expand Up @@ -270,4 +312,17 @@ export default class SQLFluff {
}
});
}

static getCLIVersion() {
this.runCommand(["--version"], undefined, false, undefined, undefined).then(
(output) => {
const arr = output.lines[0]
.split("version ")[1]
.split(".", 3)
.map((s) => Number(s));
this.version = [arr[0], arr[1], arr[2]];
Utilities.outputChannel.appendLine(`sqlfluff version: ${this.version}`);
},
);
}
}
Loading