11import { execFile as execFileCb , spawn } from "child_process" ;
2- import { ExtensionContext } from "vscode" ;
2+ import { ExtensionContext , window , commands } from "vscode" ;
33import { SyncDestinationMapper } from "../configuration/SyncDestination" ;
44import { workspaceConfigs } from "../vscode-objs/WorkspaceConfigs" ;
55import { promisify } from "node:util" ;
6+ import { withLogContext } from "@databricks/databricks-sdk/dist/logging" ;
7+ import { Loggers } from "../logger" ;
8+ import { Context , context } from "@databricks/databricks-sdk/dist/context" ;
69
710const execFile = promisify ( execFileCb ) ;
811
@@ -21,18 +24,26 @@ export interface ConfigEntry {
2124}
2225
2326export type SyncType = "full" | "incremental" ;
27+
28+ function getValidHost ( host : string ) {
29+ if ( host . match ( / ^ (?: (?: h t t p s ? ) : \/ \/ ) ? ( .(? ! : \/ \/ ) ) + $ / ) !== null ) {
30+ return new URL ( host ) ;
31+ } else {
32+ throw new TypeError ( "Invalid type for host" ) ;
33+ }
34+ }
2435/**
2536 * Entrypoint for all wrapped CLI commands
2637 *
2738 * Righ now this is a placeholder for a future implementation
2839 * of the bricks CLI
2940 */
3041export class CliWrapper {
31- constructor ( private context : ExtensionContext ) { }
42+ constructor ( private extensionContext : ExtensionContext ) { }
3243
3344 getTestBricksCommand ( ) : Command {
3445 return {
35- command : this . context . asAbsolutePath ( "./bin/bricks" ) ,
46+ command : this . extensionContext . asAbsolutePath ( "./bin/bricks" ) ,
3647 args : [ ] ,
3748 } ;
3849 }
@@ -44,7 +55,7 @@ export class CliWrapper {
4455 syncDestination : SyncDestinationMapper ,
4556 syncType : SyncType
4657 ) : Command {
47- const command = this . context . asAbsolutePath ( "./bin/bricks" ) ;
58+ const command = this . extensionContext . asAbsolutePath ( "./bin/bricks" ) ;
4859 const args = [
4960 "sync" ,
5061 "--remote-path" ,
@@ -62,13 +73,15 @@ export class CliWrapper {
6273
6374 private getListProfilesCommand ( ) : Command {
6475 return {
65- command : this . context . asAbsolutePath ( "./bin/bricks" ) ,
76+ command : this . extensionContext . asAbsolutePath ( "./bin/bricks" ) ,
6677 args : [ "auth" , "profiles" , "--skip-validate" ] ,
6778 } ;
6879 }
6980
81+ @withLogContext ( Loggers . Extension )
7082 public async listProfiles (
71- configfilePath ?: string
83+ configfilePath ?: string ,
84+ @context ctx ?: Context
7285 ) : Promise < Array < ConfigEntry > > {
7386 const cmd = await this . getListProfilesCommand ( ) ;
7487 const res = await execFile ( cmd . command , cmd . args , {
@@ -82,31 +95,55 @@ export class CliWrapper {
8295 } ) ;
8396 const profiles = JSON . parse ( res . stdout ) . profiles || [ ] ;
8497 const result = [ ] ;
98+
8599 for ( const profile of profiles ) {
86- result . push ( {
87- name : profile . name ,
88- host : new URL ( profile . host ) ,
89- accountId : profile . account_id ,
90- cloud : profile . cloud ,
91- authType : profile . auth_type ,
92- valid : profile . valid ,
93- } ) ;
100+ try {
101+ result . push ( {
102+ name : profile . name ,
103+ host : getValidHost ( profile . host ) ,
104+ accountId : profile . account_id ,
105+ cloud : profile . cloud ,
106+ authType : profile . auth_type ,
107+ valid : profile . valid ,
108+ } ) ;
109+ } catch ( e : unknown ) {
110+ let msg : string ;
111+ if ( e instanceof TypeError ) {
112+ msg = `Can't parse host for profile ${ profile . name } ` ;
113+ } else {
114+ msg = `Error parsing profile ${ profile . name } ` ;
115+ }
116+ ctx ?. logger ?. error ( msg , e ) ;
117+ window
118+ . showWarningMessage (
119+ msg ,
120+ "Open Databricks Config File" ,
121+ "Ignore"
122+ )
123+ . then ( ( choice ) => {
124+ if ( choice === "Open Databricks Config File" ) {
125+ commands . executeCommand (
126+ "databricks.connection.openDatabricksConfigFile"
127+ ) ;
128+ }
129+ } ) ;
130+ }
94131 }
95132 return result ;
96133 }
97134
98135 public async getBundleSchema ( ) : Promise < string > {
99136 const execFile = promisify ( execFileCb ) ;
100137 const { stdout} = await execFile (
101- this . context . asAbsolutePath ( "./bin/bricks" ) ,
138+ this . extensionContext . asAbsolutePath ( "./bin/bricks" ) ,
102139 [ "bundle" , "schema" ]
103140 ) ;
104141 return stdout ;
105142 }
106143
107144 getAddProfileCommand ( profile : string , host : URL ) : Command {
108145 return {
109- command : this . context . asAbsolutePath ( "./bin/bricks" ) ,
146+ command : this . extensionContext . asAbsolutePath ( "./bin/bricks" ) ,
110147 args : [
111148 "configure" ,
112149 "--no-interactive" ,
0 commit comments