1
1
import * as vscode from 'vscode' ;
2
+
2
3
import {
3
4
BazelConfiguration ,
4
5
BzlConfiguration ,
7
8
} from './configuration' ;
8
9
import { CommandName } from './constants' ;
9
10
import { Settings } from './settings' ;
10
- import { LaunchableComponent , LaunchArgs , Status } from './status' ;
11
+ import { LaunchableComponent , LaunchArgs , Status , StatusError } from './status' ;
11
12
import { SocketDebugClient , LogLevel } from "node-debugprotocol-client" ;
13
+ import { isDefined } from 'vscode-common/out/types' ;
12
14
13
15
14
16
export class StarlarkDebugger
@@ -25,39 +27,34 @@ export class StarlarkDebugger
25
27
26
28
this . disposables . push ( vscode . debug . registerDebugAdapterDescriptorFactory ( 'starlark' , this ) ) ;
27
29
this . disposables . push ( vscode . debug . registerDebugConfigurationProvider ( 'starlark' , this ) ) ;
30
+
31
+ vscode . commands . registerCommand ( CommandName . AskForDebugTargetLabel , this . handleCommandAskForDebugTargetLabel , this . disposables ) ;
32
+ }
33
+
34
+ async handleCommandAskForDebugTargetLabel ( ) : Promise < string | undefined > {
35
+ return vscode . window . showInputBox ( {
36
+ placeHolder : 'Please enter the label of bazel build target for the debug session' ,
37
+ value : '//:your_build_target_here'
38
+ } ) ;
28
39
}
29
40
30
41
/**
31
- * Invoke is typically triggered from a 'debug' code action click. It tries to check
32
- * that the debug adapter is running and then starts a debug session.
42
+ * Invoke is typically triggered from a 'debug' code action click. It tries
43
+ * to check that the debug adapter is running and then starts a debug session.
33
44
* @param command
34
45
* @param label
35
46
* @returns
36
47
*/
37
48
async invoke ( command : string , label : string ) : Promise < boolean > {
38
- const bazelSettings = await this . bazelSettings . get ( ) ;
39
49
const debugSettings = await this . settings . get ( ) ;
40
50
41
- const action = await vscode . window . showInformationMessage ( debugInfoMessage ( ) , 'OK' , 'Cancel' ) ;
42
- if ( action !== 'OK' ) {
43
- return false ;
44
- }
45
-
46
- const args = [ command , label ] ;
47
- args . push ( ...bazelSettings . buildFlags , ...bazelSettings . starlarkDebugFlags ) ;
48
-
49
- if ( this . status !== Status . READY && this . status !== Status . DISABLED ) {
50
- await this . handleCommandLaunch ( ) ;
51
- }
52
-
53
- await vscode . commands . executeCommand ( CommandName . Invoke , args ) ;
54
-
55
51
return vscode . debug . startDebugging (
56
52
vscode . workspace . getWorkspaceFolder ( this . workspaceFolder ) ,
57
53
{
58
54
type : 'starlark' ,
59
- name : 'Attach to a Starlark Debug Session' ,
60
- request : 'attach' ,
55
+ name : 'Launch to a Starlark Debug Session for ' + label ,
56
+ request : 'launch' ,
57
+ targetLabel : label ,
61
58
debugServerHost : debugSettings . debugAdapterHost ,
62
59
debugServerPort : debugSettings . debugAdapterPort
63
60
} ,
@@ -69,7 +66,8 @@ export class StarlarkDebugger
69
66
* @override
70
67
*/
71
68
async shouldLaunch ( e : Error ) : Promise < boolean > {
72
- return false ;
69
+ const cfg = await this . settings . get ( ) ;
70
+ return cfg . autoLaunch ;
73
71
}
74
72
75
73
/**
@@ -89,7 +87,7 @@ export class StarlarkDebugger
89
87
await client . connectAdapter ( ) ;
90
88
} catch ( e ) {
91
89
if ( isTCPConnectionError ( e ) && e . code === 'ECONNREFUSED' ) {
92
- throw new Error ( `Debug Adapter is not running` ) ;
90
+ throw new StatusError ( `Debug Adapter is not running` , Status . STOPPED ) ;
93
91
} else {
94
92
throw e ;
95
93
}
@@ -118,7 +116,7 @@ export class StarlarkDebugger
118
116
119
117
return {
120
118
command : args . map ( a => a . replace ( '${workspaceFolder}' , this . workspaceFolder . fsPath ) ) ,
121
- showSuccessfulLaunchTerminal : true ,
119
+ showSuccessfulLaunchTerminal : false ,
122
120
showFailedLaunchTerminal : true ,
123
121
} ;
124
122
}
@@ -140,7 +138,7 @@ export class StarlarkDebugger
140
138
* Massage a debug configuration just before a debug session is being
141
139
* launched, e.g. add all missing attributes to the debug configuration.
142
140
*/
143
- resolveDebugConfiguration ( folder : vscode . WorkspaceFolder | undefined , config : vscode . DebugConfiguration , token ?: vscode . CancellationToken ) : vscode . ProviderResult < vscode . DebugConfiguration > {
141
+ async resolveDebugConfiguration ( folder : vscode . WorkspaceFolder | undefined , config : vscode . DebugConfiguration , token ?: vscode . CancellationToken ) : Promise < vscode . DebugConfiguration | null | undefined > {
144
142
return config ;
145
143
}
146
144
@@ -163,18 +161,36 @@ export class StarlarkDebugger
163
161
* @param token A cancellation token.
164
162
* @return The resolved debug configuration or undefined or null.
165
163
*/
166
- resolveDebugConfigurationWithSubstitutedVariables ( folder : vscode . WorkspaceFolder | undefined , debugConfiguration : vscode . DebugConfiguration , token ?: vscode . CancellationToken ) : vscode . ProviderResult < vscode . DebugConfiguration > {
167
- return debugConfiguration ;
168
- }
164
+ async resolveDebugConfigurationWithSubstitutedVariables ( folder : vscode . WorkspaceFolder | undefined , config : vscode . DebugConfiguration , token ?: vscode . CancellationToken ) : Promise < vscode . DebugConfiguration | undefined > {
165
+ let targetLabel = config . targetLabel ;
166
+ if ( ! targetLabel ) {
167
+ targetLabel = await this . handleCommandAskForDebugTargetLabel ( ) ;
168
+ }
169
+ if ( ! targetLabel ) {
170
+ vscode . window . showInformationMessage ( `A label for the "bazel build" command is required. Please add it to your launch configuration.` ) ;
171
+ return ;
172
+ }
169
173
170
- }
174
+ // launch the bazel debugger if this is a launch config
175
+ if ( config . request === 'launch' ) {
176
+ const bazelSettings = await this . bazelSettings . get ( ) ;
177
+ const flags = bazelSettings . starlarkDebugFlags || [ ] ;
178
+ const extraFlags = config . extraBazelFlags || [ ] ;
179
+
180
+ await vscode . commands . executeCommand ( CommandName . Invoke ,
181
+ [ 'build' , targetLabel , ...flags , ...extraFlags ] . filter ( arg => isDefined ( arg ) ) ) ;
182
+ }
183
+
184
+ // launch the debug adapter if it not already running
185
+ if ( this . status !== Status . READY && this . status !== Status . DISABLED ) {
186
+ // this needs to wait until the thing is actually running!
187
+ await this . handleCommandLaunch ( ) ;
188
+ this . restart ( ) ;
189
+ }
190
+
191
+ return config ;
192
+ }
171
193
172
- function debugInfoMessage ( ) : string {
173
- return (
174
- 'Running Bazel in debug mode blocks until the debug adapter client attaches. ' +
175
- "It is recommended to make changes to BUILD/bzl files in the area of interest to defeat Bazel's aggressive caching mechanism. " +
176
- 'Are you sure you want to continue?'
177
- ) ;
178
194
}
179
195
180
196
interface TCPConnectionError {
0 commit comments