Skip to content
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
11 changes: 11 additions & 0 deletions vscode/extension/src/utilities/errors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { traceInfo } from './common/log'
export type ErrorType =
| ErrorTypeGeneric
| { type: 'not_signed_in' }
| { type: 'sqlmesh_not_found' }
| { type: 'sqlmesh_lsp_not_found' }
// tcloud_bin_not_found is used when the tcloud executable is not found. This is likely to happen if the user
// opens a project that has a `tcloud.yaml` file but doesn't have tcloud installed.
Expand Down Expand Up @@ -85,6 +86,8 @@ export async function handleError(
return
case 'not_signed_in':
return handleNotSignedInError(authProvider)
case 'sqlmesh_not_found':
return handleSqlmeshNotFoundError()
case 'sqlmesh_lsp_not_found':
return handleSqlmeshLspNotFoundError()
case 'sqlmesh_lsp_dependencies_missing':
Expand Down Expand Up @@ -118,6 +121,14 @@ const handleNotSignedInError = async (
}
}

/**
* Handles the case where the sqlmesh executable is not found.
*/
const handleSqlmeshNotFoundError = async (): Promise<void> => {
traceInfo('handleSqlmeshNotFoundError')
await window.showErrorMessage('SQLMesh not found, please check installation')
}

/**
* Handles the case where the sqlmesh_lsp is not found.
*/
Expand Down
41 changes: 37 additions & 4 deletions vscode/extension/src/utilities/sqlmesh/sqlmesh.ts
Original file line number Diff line number Diff line change
Expand Up @@ -287,6 +287,12 @@ export const sqlmeshExec = async (): Promise<
args: [],
})
} else {
const exists = await doesExecutableExist(sqlmesh)
if (!exists) {
return err({
Comment thread
benfdking marked this conversation as resolved.
type: 'sqlmesh_not_found',
})
}
return ok({
bin: sqlmesh,
workspacePath,
Expand Down Expand Up @@ -384,22 +390,28 @@ export const sqlmeshLspExec = async (): Promise<
type: 'not_signed_in',
})
}
const exists = await doesExecutableExist(sqlmeshLSP)
if (!exists) {
return err({
type: 'sqlmesh_lsp_not_found',
})
}
const ensured = await ensureSqlmeshEnterpriseInstalled()
if (isErr(ensured)) {
return ensured
}
}
const ensuredDependencies = await ensureSqlmeshLspDependenciesInstalled()
if (isErr(ensuredDependencies)) {
return ensuredDependencies
}
const binPath = path.join(interpreterDetails.binPath!, sqlmeshLSP)
traceLog(`Bin path: ${binPath}`)
if (!fs.existsSync(binPath)) {
return err({
type: 'sqlmesh_lsp_not_found',
})
}
const ensuredDependencies = await ensureSqlmeshLspDependenciesInstalled()
if (isErr(ensuredDependencies)) {
return ensuredDependencies
}
return ok({
bin: binPath,
workspacePath,
Expand All @@ -411,6 +423,12 @@ export const sqlmeshLspExec = async (): Promise<
args: [],
})
} else {
const exists = await doesExecutableExist(sqlmeshLSP)
if (!exists) {
return err({
type: 'sqlmesh_lsp_not_found',
})
}
return ok({
bin: sqlmeshLSP,
workspacePath,
Expand All @@ -419,3 +437,18 @@ export const sqlmeshLspExec = async (): Promise<
})
}
}

async function doesExecutableExist(executable: string): Promise<boolean> {
Comment thread
benfdking marked this conversation as resolved.
const command = process.platform === 'win32' ? 'where.exe' : 'which'
traceLog(`Checking if ${executable} exists with ${command}`)
try {
const result = await execAsync(command, [executable])
traceLog(`Checked if ${executable} exists with ${command}, with result ${result.exitCode}`)
const exists = result.exitCode === 0
traceLog(`Checked if ${executable} exists with ${command}, with result ${exists}`)
return exists
} catch {
traceLog(`Checked if ${executable} exists with ${command}, errored, returning false`)
return false
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import os from 'os'
import path from 'path'
import {
createVirtualEnvironment,
openLineageView,
pipInstall,
REPO_ROOT,
startVSCode,
Expand Down Expand Up @@ -72,3 +73,41 @@ test('missing LSP dependencies shows install prompt', async ({}, testInfo) => {
await fs.remove(tempDir)
}
})

test('lineage, no sqlmesh found', async ({}) => {
const tempDir = await fs.mkdtemp(
path.join(os.tmpdir(), 'vscode-test-tcloud-'),
)
const pythonEnvDir = path.join(tempDir, '.venv')
const pythonDetails = await createVirtualEnvironment(pythonEnvDir)

try {
// Copy sushi project
await fs.copy(SUSHI_SOURCE_PATH, tempDir)

// Configure VS Code settings to use our Python environment
const settings = {
'python.defaultInterpreterPath': pythonDetails.pythonPath,
'sqlmesh.environmentPath': pythonEnvDir,
}
await fs.ensureDir(path.join(tempDir, '.vscode'))
await fs.writeJson(
path.join(tempDir, '.vscode', 'settings.json'),
settings,
{ spaces: 2 },
)

const { window, close } = await startVSCode(tempDir)

// Open lineage view
await openLineageView(window)

// Assert shows that sqlmesh is not installed
await window.waitForSelector('text=SQLMesh LSP not found')

await close()
} finally {
// Clean up
await fs.remove(tempDir)
}
})
9 changes: 2 additions & 7 deletions vscode/extension/tests/lineage.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,14 @@ import { test, expect, Page } from '@playwright/test'
import path from 'path'
import fs from 'fs-extra'
import os from 'os'
import { startVSCode, SUSHI_SOURCE_PATH } from './utils'
import { openLineageView, startVSCode, SUSHI_SOURCE_PATH } from './utils'
import { writeFileSync } from 'fs'

/**
* Helper function to launch VS Code and test lineage with given project path config
*/
async function testLineageWithProjectPath(window: Page): Promise<void> {
// Trigger lineage command
await window.keyboard.press(
process.platform === 'darwin' ? 'Meta+Shift+P' : 'Control+Shift+P',
)
await window.keyboard.type('Lineage: Focus On View')
await window.keyboard.press('Enter')
await openLineageView(window)

// Wait for "Loaded SQLMesh context" text to appear
const loadedContextText = window.locator('text=Loaded SQLMesh context')
Expand Down
22 changes: 22 additions & 0 deletions vscode/extension/tests/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -137,3 +137,25 @@ export const pipInstall = async (
throw new Error(`Failed to install package: ${stderr}`)
}
}

/**
* Open the lineage view in the given window.
*/
export const openLineageView = async (window: Page): Promise<void> => {
await window.keyboard.press(
process.platform === 'darwin' ? 'Meta+Shift+P' : 'Control+Shift+P',
)
await window.keyboard.type('Lineage: Focus On View')
await window.keyboard.press('Enter')
}

/**
* Restart the SQLMesh servers
*/
export const restartSqlmeshServers = async (window: Page): Promise<void> => {
await window.keyboard.press(
process.platform === 'darwin' ? 'Meta+Shift+P' : 'Control+Shift+P',
)
await window.keyboard.type('Restart SQLMesh servers')
await window.keyboard.press('Enter')
}