Skip to content
Draft
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
1 change: 1 addition & 0 deletions packages/databricks-vscode/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -1201,6 +1201,7 @@
"minimatch": "^10.0.1",
"shell-quote": "^1.8.1",
"triple-beam": "^1.4.1",
"vscode-languageclient": "^9.0.1",
"winston": "^3.11.0",
"yaml": "^2.3.4"
},
Expand Down
93 changes: 93 additions & 0 deletions packages/databricks-vscode/src/bundle/BundleLSPClient.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
import {
LanguageClient,
LanguageClientOptions,
ServerOptions,
} from "vscode-languageclient/node";
import {Disposable, Uri, workspace} from "vscode";
import {CliWrapper} from "../cli/CliWrapper";

/**
* Manages the lifecycle of the DABs Language Server Protocol client.
* Spawns `databricks experimental bundle-lsp` and connects via stdio to provide
* deployment-aware features (document links, hover) for bundle YAML files.
*/
export class BundleLSPClient implements Disposable {
private client: LanguageClient | undefined;
private readonly cli: CliWrapper;

constructor(cli: CliWrapper) {
this.cli = cli;
}

async start(workspaceFolder: Uri, target?: string): Promise<void> {
// Stop existing client if running.
await this.stop();

const args = ["experimental", "bundle-lsp"];
if (target) {
args.push("--target", target);
}

const serverOptions: ServerOptions = {
command: this.cli.cliPath,
args: args,
options: {
cwd: workspaceFolder.fsPath,
},
};

const clientOptions: LanguageClientOptions = {
documentSelector: [
{
scheme: "file",
language: "yaml",
pattern: "**/databricks.yml",
},
{
scheme: "file",
language: "yaml",
pattern: "**/databricks.yaml",
},
{
scheme: "file",
language: "yaml",
pattern: "**/bundle.yml",
},
{
scheme: "file",
language: "yaml",
pattern: "**/bundle.yaml",
},
],
workspaceFolder: {
uri: workspaceFolder,
name: workspace.name ?? "workspace",
index: 0,
},
};

this.client = new LanguageClient(
"databricks-bundle-lsp",
"Databricks Experimental Bundle LSP",
serverOptions,
clientOptions
);

await this.client.start();
}

async stop(): Promise<void> {
if (this.client) {
try {
await this.client.stop();
} catch {
// Client may already be stopped.
}
this.client = undefined;
}
}

dispose(): void {
this.stop();
}
}
15 changes: 15 additions & 0 deletions packages/databricks-vscode/src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ import {
BundleFileSet,
registerBundleAutocompleteProvider,
} from "./bundle";
import {BundleLSPClient} from "./bundle/BundleLSPClient";
import {showWhatsNewPopup} from "./whatsNewPopup";
import {BundleValidateModel} from "./bundle/models/BundleValidateModel";
import {ConfigModel} from "./configuration/models/ConfigModel";
Expand Down Expand Up @@ -890,6 +891,20 @@ export async function activate(
);
});

// Start the DABs LSP client for deployment-aware features (document links, hover).
const bundleLSPClient = new BundleLSPClient(cli);
context.subscriptions.push(bundleLSPClient);

const workspaceFolder = workspace.workspaceFolders?.[0]?.uri;
if (workspaceFolder) {
bundleLSPClient.start(workspaceFolder).catch((e) => {
logging.NamedLogger.getOrCreate(Loggers.Extension).error(
"Failed to start bundle LSP: ",
e
);
});
}

setDbnbCellLimits(workspaceFolderManager, connectionManager).catch((e) => {
logging.NamedLogger.getOrCreate(Loggers.Extension).error(
"Error while setting jupyter configs for parsing databricks notebooks",
Expand Down
45 changes: 45 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -3799,6 +3799,7 @@ __metadata:
ts-node: ^10.9.2
typescript: ^5.3.3
vsce: ^2.15.0
vscode-languageclient: ^9.0.1
wdio-video-reporter: ^5.1.4
wdio-vscode-service: ^6.0.2
winston: ^3.11.0
Expand Down Expand Up @@ -9520,6 +9521,15 @@ __metadata:
languageName: node
linkType: hard

"semver@npm:^7.3.7":
version: 7.7.4
resolution: "semver@npm:7.7.4"
bin:
semver: bin/semver.js
checksum: 9b4a6a58e98b9723fafcafa393c9d4e8edefaa60b8dfbe39e30892a3604cf1f45f52df9cfb1ae1a22b44c8b3d57fec8a9bb7b3e1645431587cb272399ede152e
languageName: node
linkType: hard

"semver@npm:^7.5.2, semver@npm:^7.5.4":
version: 7.5.4
resolution: "semver@npm:7.5.4"
Expand Down Expand Up @@ -10840,6 +10850,41 @@ __metadata:
languageName: node
linkType: hard

"vscode-jsonrpc@npm:8.2.0":
version: 8.2.0
resolution: "vscode-jsonrpc@npm:8.2.0"
checksum: f302a01e59272adc1ae6494581fa31c15499f9278df76366e3b97b2236c7c53ebfc71efbace9041cfd2caa7f91675b9e56f2407871a1b3c7f760a2e2ee61484a
languageName: node
linkType: hard

"vscode-languageclient@npm:^9.0.1":
version: 9.0.1
resolution: "vscode-languageclient@npm:9.0.1"
dependencies:
minimatch: ^5.1.0
semver: ^7.3.7
vscode-languageserver-protocol: 3.17.5
checksum: ff30e5a9aac6726a88fe443fd631fe7e6130225299667c13162547f0a13ca2548d3f277d68cfb3ef6dc1810c048b2cf0e05024e1bcbd11982cd8acf681a67873
languageName: node
linkType: hard

"vscode-languageserver-protocol@npm:3.17.5":
version: 3.17.5
resolution: "vscode-languageserver-protocol@npm:3.17.5"
dependencies:
vscode-jsonrpc: 8.2.0
vscode-languageserver-types: 3.17.5
checksum: dfb42d276df5dfea728267885b99872ecff62f6c20448b8539fae71bb196b420f5351c5aca7c1047bf8fb1f89fa94a961dce2bc5bf7e726198f4be0bb86a1e71
languageName: node
linkType: hard

"vscode-languageserver-types@npm:3.17.5":
version: 3.17.5
resolution: "vscode-languageserver-types@npm:3.17.5"
checksum: 79b420e7576398d396579ca3a461c9ed70e78db4403cd28bbdf4d3ed2b66a2b4114031172e51fad49f0baa60a2180132d7cb2ea35aa3157d7af3c325528210ac
languageName: node
linkType: hard

"vscode-uri@npm:^3.0.8":
version: 3.0.8
resolution: "vscode-uri@npm:3.0.8"
Expand Down
Loading