Skip to content

Commit

Permalink
Allow custom databricks hosts
Browse files Browse the repository at this point in the history
  • Loading branch information
kartikgupta-db committed Sep 20, 2023
1 parent deaaaf7 commit 1efe2a9
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 100 deletions.
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import {commands, QuickPickItem, QuickPickItemKind} from "vscode";
import {CliWrapper, ConfigEntry} from "../cli/CliWrapper";
import {MultiStepInput} from "../ui/wizard";
import {MultiStepInput, ValidationMessageType} from "../ui/wizard";
import {
isAwsHost,
isAzureHost,
Expand Down Expand Up @@ -220,9 +220,20 @@ async function listProfiles(cliWrapper: CliWrapper) {

async function validateDatabricksHost(
host: string
): Promise<string | undefined> {
): Promise<string | undefined | ValidationMessageType> {
try {
normalizeHost(host);
const url = normalizeHost(host);
if (
!url.hostname.match(
/(\.databricks\.azure\.us|\.databricks\.azure\.cn|\.azuredatabricks\.net|\.gcp\.databricks\.com|\.cloud\.databricks\.com|\.dev\.databricks\.com)$/
)
) {
return {
message:
"This is not a standard Databricks URL. Some features may not work as expected.",
type: "warning",
};
}
} catch (e: any) {
return e.message;
}
Expand Down
107 changes: 17 additions & 90 deletions packages/databricks-vscode/src/ui/wizard.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,19 @@ interface EditItem {
}

type InputStep = (input: MultiStepInput) => Thenable<InputStep | void>;
export type ValidationMessageType = {
message: string;
type: "error" | "warning";
};

interface QuickAutoCompleteParameters {
title: string;
step: number;
totalSteps: number;
prompt: string;
validate: (value: string) => Promise<string | undefined>;
validate: (
value: string
) => Promise<string | undefined | ValidationMessageType>;
buttons?: QuickInputButton[];
shouldResume: () => Thenable<boolean>;
items: Array<QuickPickItem>;
Expand All @@ -50,17 +56,6 @@ interface QuickPickParameters<T extends QuickPickItem> {
shouldResume: () => Thenable<boolean>;
}

interface InputBoxParameters {
title: string;
step: number;
totalSteps: number;
value: string;
prompt: string;
validate: (value: string) => Promise<string | undefined>;
buttons?: QuickInputButton[];
shouldResume: () => Thenable<boolean>;
}

export class MultiStepInput {
static async run(start: InputStep) {
const input = new MultiStepInput();
Expand Down Expand Up @@ -156,18 +151,25 @@ export class MultiStepInput {
) {
input.items = [...items];
} else if (input.value !== "") {
const validationMessage = validate
let validationMessage = validate
? await validate(input.value)
: undefined;

if (typeof validationMessage === "string") {
validationMessage = {
message: validationMessage,
type: "error",
};
}

input.items = [
{
label: input.value,
detail: validationMessage
? `$(error) ${validationMessage}`
? `$(${validationMessage.type}) ${validationMessage.message}`
: undefined,
edit: true,
error: !!validationMessage,
error: validationMessage?.type === "error",
} as EditItem,
...items,
];
Expand Down Expand Up @@ -278,79 +280,4 @@ export class MultiStepInput {
disposables.forEach((d) => d.dispose());
}
}

async showInputBox<P extends InputBoxParameters>({
title,
step,
totalSteps,
value,
prompt,
validate,
buttons,
shouldResume,
}: P) {
const disposables: Disposable[] = [];
try {
return await new Promise<
string | (P extends {buttons: (infer I)[]} ? I : never)
>((resolve, reject) => {
const input = window.createInputBox();
input.title = title;
input.step = step;
input.totalSteps = totalSteps;
input.value = value || "";
input.prompt = prompt;
input.ignoreFocusOut = true;
input.buttons = [
...(this.steps.length > 1 ? [QuickInputButtons.Back] : []),
...(buttons || []),
];
let validating = validate("");
disposables.push(
input.onDidTriggerButton((item) => {
if (item === QuickInputButtons.Back) {
reject(InputFlowAction.back);
} else {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
resolve(<any>item);
}
}),
input.onDidAccept(async () => {
const value = input.value;
input.enabled = false;
input.busy = true;
if (!(await validate(value))) {
resolve(value);
}
input.enabled = true;
input.busy = false;
}),
input.onDidChangeValue(async (text) => {
const current = validate(text);
validating = current;
const validationMessage = await current;
if (current === validating) {
input.validationMessage = validationMessage;
}
}),
input.onDidHide(() => {
(async () => {
reject(
shouldResume && (await shouldResume())
? InputFlowAction.resume
: InputFlowAction.cancel
);
})().catch(reject);
})
);
if (this.current) {
this.current.dispose();
}
this.current = input;
this.current.show();
});
} finally {
disposables.forEach((d) => d.dispose());
}
}
}
7 changes: 0 additions & 7 deletions packages/databricks-vscode/src/utils/urlUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,6 @@ export function normalizeHost(host: string): URL {
if (url.protocol !== "https:") {
throw new Error("Invalid protocol");
}
if (
!url.hostname.match(
/(\.databricks\.azure\.us|\.databricks\.azure\.cn|\.azuredatabricks\.net|\.gcp\.databricks\.com|\.cloud\.databricks\.com|\.dev\.databricks\.com)$/
)
) {
throw new Error("Not a Databricks host");
}

return new URL(`https://${url.hostname}`);
}
Expand Down

0 comments on commit 1efe2a9

Please sign in to comment.