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
34 changes: 31 additions & 3 deletions packages/databricks-vscode/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,10 @@
"onCommand:databricks.connection.configureProject",
"onCommand:databricks.connection.openDatabricksConfigFile",
"onCommand:databricks.connection.attachCluster",
"onCommand:databricks.connection.attachClusterQuickPick",
"onCommand:databricks.connection.detachCluster",
"onCommand:databricks.connection.attachSyncDestination",
"onCommand:databricks.connection.detachSyncDestination",
"onCommand:databricks.cli.startSync",
"onCommand:databricks.cli.startSyncFull",
"onCommand:databricks.cli.stopSync",
Expand Down Expand Up @@ -79,6 +82,11 @@
"title": "Attach cluster",
"icon": "$(plug)"
},
{
"command": "databricks.connection.attachClusterQuickPick",
"title": "Attach cluster",
"icon": "$(plug)"
},
{
"command": "databricks.connection.detachCluster",
"title": "Detach cluster",
Expand Down Expand Up @@ -113,6 +121,16 @@
"icon": "$(refresh)",
"title": "Refresh"
},
{
"command": "databricks.connection.attachSyncDestination",
"title": "Attach workspace",
"icon": "$(plug)"
},
{
"command": "databricks.connection.detachSyncDestination",
"title": "Detach workspace",
"icon": "$(debug-disconnect)"
},
{
"command": "databricks.run.runEditorContentsAsWorkflow",
"title": "Run File as Workflow on Databricks",
Expand Down Expand Up @@ -184,13 +202,23 @@
"group": "inline@0"
},
{
"command": "databricks.connection.detachCluster",
"when": "view == configurationView && viewItem == clusterRunning",
"command": "databricks.connection.attachClusterQuickPick",
"when": "view == configurationView && viewItem == clusterDetached",
"group": "inline@0"
},
{
"command": "databricks.connection.detachCluster",
"when": "view == configurationView && viewItem == clusterStopped",
"when": "view == configurationView && viewItem == clusterAttached",
"group": "inline@0"
},
{
"command": "databricks.connection.attachSyncDestination",
"when": "view == configurationView && viewItem == syncDestinationDetached",
"group": "inline@0"
},
{
"command": "databricks.connection.detachSyncDestination",
"when": "view == configurationView && viewItem == syncDestinationAttached",
"group": "inline@0"
}
],
Expand Down
6 changes: 3 additions & 3 deletions packages/databricks-vscode/src/cli/CliCommands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ export class CliCommands {
return async () => {
const workspacePath = workspace.rootPath;
const me = this.connection.me;
const pathMapper = this.connection.pathMapper;
const syncDestination = this.connection.syncDestination;
const profile = this.connection.profile;

if (!workspacePath) {
Expand All @@ -47,7 +47,7 @@ export class CliCommands {
);
return;
}
if (!pathMapper) {
if (!syncDestination) {
window.showErrorMessage(
"Can't start sync: Databricks synchronization destination not configured!"
);
Expand All @@ -61,7 +61,7 @@ export class CliCommands {
const {command, args} = this.cli.getSyncCommand(
profile,
me,
pathMapper,
syncDestination,
syncType
);

Expand Down
6 changes: 3 additions & 3 deletions packages/databricks-vscode/src/cli/CliWrapper.test.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import * as assert from "assert";
import {Uri} from "vscode";
import {PathMapper} from "../configuration/PathMapper";
import {SyncDestination} from "../configuration/SyncDestination";

import {CliWrapper} from "./CliWrapper";

describe(__filename, () => {
it("should create sync command", () => {
const cli = new CliWrapper();
const mapper = new PathMapper(
const mapper = new SyncDestination(
Uri.file(
"/Workspace/Repos/fabian.jakobs@databricks.com/notebook-best-practices"
),
Expand All @@ -29,7 +29,7 @@ describe(__filename, () => {

it("should create full sync command", () => {
const cli = new CliWrapper();
const mapper = new PathMapper(
const mapper = new SyncDestination(
Uri.file(
"/Workspace/Repos/fabian.jakobs@databricks.com/notebook-best-practices"
),
Expand Down
6 changes: 3 additions & 3 deletions packages/databricks-vscode/src/cli/CliWrapper.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import {spawn} from "child_process";
import {PathMapper} from "../configuration/PathMapper";
import {SyncDestination} from "../configuration/SyncDestination";

interface Command {
command: string;
Expand All @@ -21,7 +21,7 @@ export class CliWrapper {
getSyncCommand(
profile: string,
me: string,
pathMapper: PathMapper,
syncDestination: SyncDestination,
syncType: "full" | "incremental"
): Command {
const command = "dbx";
Expand All @@ -33,7 +33,7 @@ export class CliWrapper {
"--user",
me,
"--dest-repo",
pathMapper.remoteWorkspaceName,
syncDestination.name,
];

if (syncType === "full") {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,29 +7,46 @@ import {ConfigurationDataProvider} from "./ConfigurationDataProvider";
import {ApiClient, Cluster} from "@databricks/databricks-sdk";
import {ConnectionManager} from "./ConnectionManager";
import {resolveProviderResult} from "../test/utils";
import {SyncDestination} from "./SyncDestination";

describe(__filename, () => {
let mockedConnectionManager: ConnectionManager;
let disposables: Array<Disposable>;
let onChangeClusterListener: (e: Cluster) => void;
let onChangeSyncDestinationListener: (e: SyncDestination) => void;

beforeEach(() => {
disposables = [];
mockedConnectionManager = mock(ConnectionManager);
onChangeClusterListener = () => {};
onChangeSyncDestinationListener = () => {};

when(mockedConnectionManager.onChangeState).thenReturn((_handler) => {
return {
dispose() {},
};
});
when(mockedConnectionManager.onChangeCluster).thenReturn((_handler) => {
onChangeClusterListener = _handler;
return {
dispose() {},
};
});
when(mockedConnectionManager.onChangeSyncDestination).thenReturn(
(_handler) => {
onChangeSyncDestinationListener = _handler;
return {
dispose() {},
};
}
);
});

afterEach(() => {
disposables.forEach((d) => d.dispose());
});

it("should reload tree on model change", async () => {
it("should reload tree on cluster change", async () => {
let connectionManager = instance(mockedConnectionManager);
let provider = new ConfigurationDataProvider(connectionManager);
disposables.push(provider);
Expand All @@ -46,6 +63,23 @@ describe(__filename, () => {
assert(called);
});

it("should reload tree on sync destination change", async () => {
let connectionManager = instance(mockedConnectionManager);
let provider = new ConfigurationDataProvider(connectionManager);
disposables.push(provider);

let called = false;
disposables.push(
provider.onDidChangeTreeData(() => {
called = true;
})
);

assert(!called);
onChangeSyncDestinationListener(instance(mock(SyncDestination)));
assert(called);
});

it("should get empty roots", async () => {
let connectionManager = instance(mockedConnectionManager);
let provider = new ConfigurationDataProvider(connectionManager);
Expand Down Expand Up @@ -76,24 +110,33 @@ describe(__filename, () => {
let children = await resolveProviderResult(provider.getChildren());
assert.deepEqual(children, [
{
collapsibleState: 0,
id: "CONNECTION",
label: "Profile: null",
collapsibleState: 2,
iconPath: {
color: undefined,
id: "tools",
},
id: "PROFILE",
label: "Profile",
},
{
collapsibleState: 2,
contextValue: "clusterStopped",
contextValue: "clusterAttached",
iconPath: {
color: undefined,
id: "debug-stop",
id: "server",
},
id: "CLUSTER",
label: "Cluster: cluster-name-2",
label: "Cluster",
},
{
collapsibleState: 2,
contextValue: "syncDestinationDetached",
iconPath: {
color: undefined,
id: "repo",
},
id: "WORKSPACE",
label: "Workspace",
label: 'Workspace - "None attached"',
},
]);
});
Expand Down
Loading