diff --git a/vscode/extension/package.json b/vscode/extension/package.json index c7285ad7c7..1db45abcf4 100644 --- a/vscode/extension/package.json +++ b/vscode/extension/package.json @@ -18,7 +18,8 @@ ], "activationEvents": [ "onLanguage:sql", - "onLanguage:python" + "onLanguage:python", + "onLanguage:yaml" ], "extensionKind": [ "workspace" diff --git a/vscode/extension/src/lsp/lsp.ts b/vscode/extension/src/lsp/lsp.ts index ccf3981eb2..8195876f48 100644 --- a/vscode/extension/src/lsp/lsp.ts +++ b/vscode/extension/src/lsp/lsp.ts @@ -96,7 +96,17 @@ export class LSPClient implements Disposable { }, } const clientOptions: LanguageClientOptions = { - documentSelector: [{ scheme: 'file', pattern: `**/*.sql` }], + documentSelector: [ + { scheme: 'file', pattern: `**/*.sql` }, + { + scheme: 'file', + pattern: '**/external_models.yaml', + }, + { + scheme: 'file', + pattern: '**/external_models.yml', + }, + ], diagnosticCollectionName: 'sqlmesh', outputChannel: outputChannel, } diff --git a/vscode/extension/tests/external_models.spec.ts b/vscode/extension/tests/external_models.spec.ts new file mode 100644 index 0000000000..dc087e836a --- /dev/null +++ b/vscode/extension/tests/external_models.spec.ts @@ -0,0 +1,68 @@ +import os from 'os' +import { openServerPage, SUSHI_SOURCE_PATH } from './utils' +import { createPythonInterpreterSettingsSpecifier } from './utils_code_server' +import { test, expect } from './fixtures' +import fs from 'fs-extra' +import path from 'path' + +test.describe('External model files trigger lsp', () => { + test('external_models.yaml', async ({ page, sharedCodeServer }) => { + const file = 'external_models.yaml' + + const tempDir = await fs.mkdtemp( + path.join(os.tmpdir(), 'vscode-test-sushi-'), + ) + await fs.copy(SUSHI_SOURCE_PATH, tempDir) + + // Assert external_models.yaml exists + const externalModelsYamlPath = path.join(tempDir, file) + expect(await fs.pathExists(externalModelsYamlPath)).toBe(true) + + await createPythonInterpreterSettingsSpecifier(tempDir) + await openServerPage(page, tempDir, sharedCodeServer) + + // Wait for the models folder to be visible + await page.waitForSelector('text=models') + + // Click on the external_models file (e.g., external_models.yaml or external_models.yml) + await page + .getByRole('treeitem', { name: file, exact: true }) + .locator('a') + .click() + + await page.waitForSelector('text=raw.demographics') + await page.waitForSelector('text=Loaded SQLMesh Context') + }) + + test('external_models.yml', async ({ page, sharedCodeServer }) => { + const file = 'external_models.yml' + + const tempDir = await fs.mkdtemp( + path.join(os.tmpdir(), 'vscode-test-sushi-'), + ) + await fs.copy(SUSHI_SOURCE_PATH, tempDir) + + // Move external_models.yaml to external_models.yml + const externalModelsYamlPath = path.join(tempDir, 'external_models.yaml') + const externalModelsYmlPath = path.join(tempDir, file) + await fs.rename(externalModelsYamlPath, externalModelsYmlPath) + + // Assert external_models.yml exists + expect(await fs.pathExists(externalModelsYmlPath)).toBe(true) + + await createPythonInterpreterSettingsSpecifier(tempDir) + await openServerPage(page, tempDir, sharedCodeServer) + + // Wait for the models folder to be visible + await page.waitForSelector('text=models') + + // Click on the external_models.yml file + await page + .getByRole('treeitem', { name: file, exact: true }) + .locator('a') + .click() + + await page.waitForSelector('text=raw.demographics') + await page.waitForSelector('text=Loaded SQLMesh Context') + }) +})