Skip to content

Commit b32f3ae

Browse files
authored
feat(vscode): allow the lsp loaded to be specified (#5070)
1 parent 3555e73 commit b32f3ae

File tree

5 files changed

+294
-10
lines changed

5 files changed

+294
-10
lines changed

pnpm-lock.yaml

Lines changed: 17 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

vscode/extension/package.json

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,11 @@
3636
"type": "string",
3737
"default": "",
3838
"markdownDescription": "The path to the SQLMesh project. If not set, the extension will try to find the project root automatically. If set, the extension will use the project root as the workspace path, e.g. it will run `sqlmesh` and `sqlmesh_lsp` in the project root. The path can be absolute `/Users/sqlmesh_user/sqlmesh_project/sushi` or relative `./project_folder/sushi` to the workspace root."
39+
},
40+
"sqlmesh.lspEntrypoint": {
41+
"type": "string",
42+
"default": "",
43+
"markdownDescription": "The entry point for the SQLMesh LSP server. If not set the extension looks for the default lsp. If set, the extension will use the entry point as the LSP path, The path can be absolute `/Users/sqlmesh_user/sqlmesh_project/sushi/sqlmesh_lsp` or relative `./project_folder/sushi/sqlmesh_lsp` to the workspace root. It can also have arguments, e.g. `./project_folder/sushi/sqlmesh_lsp --port 5000`."
3944
}
4045
}
4146
},
@@ -136,8 +141,10 @@
136141
"dependencies": {
137142
"@duckdb/node-api": "1.3.2-alpha.25",
138143
"@types/fs-extra": "^11.0.4",
144+
"@types/shell-quote": "^1.7.5",
139145
"@vscode/python-extension": "^1.0.5",
140146
"fs-extra": "^11.3.0",
147+
"shell-quote": "^1.8.3",
141148
"vscode-jsonrpc": "^8.2.1",
142149
"vscode-languageclient": "^9.0.1",
143150
"zod": "^3.25.76"

vscode/extension/src/utilities/config.ts

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,24 +3,59 @@ import path from 'path'
33
import fs from 'fs'
44
import { Result, err, ok } from '@bus/result'
55
import { traceVerbose, traceInfo } from './common/log'
6+
import { parse } from 'shell-quote'
7+
import { z } from 'zod'
68

79
export interface SqlmeshConfiguration {
810
projectPath: string
11+
lspEntryPoint: string
912
}
1013

1114
/**
1215
* Get the SQLMesh configuration from VS Code settings.
1316
*
1417
* @returns The SQLMesh configuration
1518
*/
16-
export function getSqlmeshConfiguration(): SqlmeshConfiguration {
19+
function getSqlmeshConfiguration(): SqlmeshConfiguration {
1720
const config = workspace.getConfiguration('sqlmesh')
1821
const projectPath = config.get<string>('projectPath', '')
22+
const lspEntryPoint = config.get<string>('lspEntrypoint', '')
1923
return {
2024
projectPath,
25+
lspEntryPoint,
2126
}
2227
}
2328

29+
const stringsArray = z.array(z.string())
30+
31+
/**
32+
* Get the SQLMesh LSP entry point from VS Code settings. undefined if not set
33+
* it's expected to be a string in the format "command arg1 arg2 ...".
34+
*/
35+
export function getSqlmeshLspEntryPoint():
36+
| {
37+
entrypoint: string
38+
args: string[]
39+
}
40+
| undefined {
41+
const config = getSqlmeshConfiguration()
42+
if (config.lspEntryPoint === '') {
43+
return undefined
44+
}
45+
// Split the entry point into command and arguments
46+
const parts = parse(config.lspEntryPoint)
47+
const parsed = stringsArray.safeParse(parts)
48+
if (!parsed.success) {
49+
throw new Error(
50+
`Invalid lspEntrypoint configuration: ${config.lspEntryPoint}. Expected a
51+
string in the format "command arg1 arg2 ...".`,
52+
)
53+
}
54+
const entrypoint = parsed.data[0]
55+
const args = parsed.data.slice(1)
56+
return { entrypoint, args }
57+
}
58+
2459
/**
2560
* Validate and resolve the project path from configuration.
2661
* If no project path is configured, use the workspace folder.

vscode/extension/src/utilities/sqlmesh/sqlmesh.ts

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import { execAsync } from '../exec'
1111
import z from 'zod'
1212
import { ProgressLocation, window } from 'vscode'
1313
import { IS_WINDOWS } from '../isWindows'
14-
import { resolveProjectPath } from '../config'
14+
import { getSqlmeshLspEntryPoint, resolveProjectPath } from '../config'
1515
import { isSemVerGreaterThanOrEqual } from '../semver'
1616

1717
export interface SqlmeshExecInfo {
@@ -413,15 +413,7 @@ export const ensureSqlmeshLspDependenciesInstalled = async (): Promise<
413413
export const sqlmeshLspExec = async (): Promise<
414414
Result<SqlmeshExecInfo, ErrorType>
415415
> => {
416-
const sqlmeshLSP = IS_WINDOWS ? 'sqlmesh_lsp.exe' : 'sqlmesh_lsp'
417416
const projectRoot = await getProjectRoot()
418-
const envVariables = await getPythonEnvVariables()
419-
if (isErr(envVariables)) {
420-
return err({
421-
type: 'generic',
422-
message: envVariables.error,
423-
})
424-
}
425417
const resolvedPath = resolveProjectPath(projectRoot)
426418
if (isErr(resolvedPath)) {
427419
return err({
@@ -430,6 +422,26 @@ export const sqlmeshLspExec = async (): Promise<
430422
})
431423
}
432424
const workspacePath = resolvedPath.value
425+
426+
const configuredLSPExec = getSqlmeshLspEntryPoint()
427+
if (configuredLSPExec) {
428+
traceLog(`Using configured SQLMesh LSP entry point: ${configuredLSPExec.entrypoint} ${configuredLSPExec.args.join(' ')}`)
429+
return ok({
430+
bin: configuredLSPExec.entrypoint,
431+
workspacePath,
432+
env: process.env,
433+
args: configuredLSPExec.args,
434+
})
435+
}
436+
const sqlmeshLSP = IS_WINDOWS ? 'sqlmesh_lsp.exe' : 'sqlmesh_lsp'
437+
const envVariables = await getPythonEnvVariables()
438+
if (isErr(envVariables)) {
439+
return err({
440+
type: 'generic',
441+
message: envVariables.error,
442+
})
443+
}
444+
433445
const interpreterDetails = await getInterpreterDetails()
434446
traceLog(`Interpreter details: ${JSON.stringify(interpreterDetails)}`)
435447
if (interpreterDetails.path) {

0 commit comments

Comments
 (0)