@@ -29,7 +29,7 @@ import { IModuleInstaller, InstallOptions, InterpreterUri, ModuleInstallFlags }
29
29
// --- Start Positron ---
30
30
// eslint-disable-next-line import/newline-after-import
31
31
import { IWorkspaceService } from '../application/types' ;
32
- class ExternallyManagedEnvironmentError extends Error { }
32
+ class ExternallyManagedEnvironmentError extends Error { }
33
33
// --- End Positron ---
34
34
35
35
@injectable ( )
@@ -42,7 +42,15 @@ export abstract class ModuleInstaller implements IModuleInstaller {
42
42
43
43
public abstract get type ( ) : ModuleInstallerType ;
44
44
45
- constructor ( protected serviceContainer : IServiceContainer ) { }
45
+ // --- Start Positron ---
46
+ // This is a temporary flag to allow for the installation to wait for
47
+ // completion. It can be used to override the behavior that the
48
+ // python.installModulesInTerminal setting typically controls. This is used
49
+ // when installing packages using the assistant to make sure it knows how
50
+ // the installation went.
51
+ private _waitForCompletion ?: boolean ;
52
+ // --- End Positron ---
53
+ constructor ( protected serviceContainer : IServiceContainer ) { }
46
54
47
55
public async installModule (
48
56
productOrModuleName : Product | string ,
@@ -53,6 +61,12 @@ export abstract class ModuleInstaller implements IModuleInstaller {
53
61
) : Promise < void > {
54
62
// --- Start Positron ---
55
63
const shouldExecuteInTerminal = this . installModulesInTerminal ( ) || ! options ?. installAsProcess ;
64
+ // Store the waitForCompletion option so that we can use it in the
65
+ // executeCommand method. This is temporary and is immediately unset
66
+ // (before any awaits) in the executeCommand method which takes place in
67
+ // a single call stack, thus it's not at risk for race conditions with
68
+ // other calls to installModule..
69
+ this . _waitForCompletion = options ?. waitForCompletion ;
56
70
// --- End Positron ---
57
71
const name =
58
72
typeof productOrModuleName === 'string'
@@ -159,7 +173,7 @@ export abstract class ModuleInstaller implements IModuleInstaller {
159
173
if ( ex instanceof ExternallyManagedEnvironmentError ) {
160
174
traceWarn (
161
175
`Failed to install ${ name } in ${ resource ?. path } because it is an ` +
162
- `externally-managed environment. Retrying with the --break-system-packages flag.` ,
176
+ `externally-managed environment. Retrying with the --break-system-packages flag.` ,
163
177
) ;
164
178
await _install ( token , ( flags ?? ModuleInstallFlags . none ) | ModuleInstallFlags . breakSystemPackages ) ;
165
179
} else {
@@ -259,13 +273,20 @@ export abstract class ModuleInstaller implements IModuleInstaller {
259
273
. getTerminalService ( options ) ;
260
274
261
275
// --- Start Positron ---
262
- // When running with the `python.installModulesInTerminal` setting enabled, we want to
263
- // ensure that the terminal command is fully executed before returning. Otherwise, the
264
- // calling code of the install will not be able to tell when the installation is complete.
265
- if ( this . installModulesInTerminal ( ) ) {
276
+ // When running with the `python.installModulesInTerminal` setting
277
+ // enabled or when the `waitForCompletion` option was set to true in
278
+ // the parent `installModule` call, we want to ensure that the
279
+ // terminal command is fully executed before returning. Otherwise,
280
+ // the calling code of the install will not be able to tell when the
281
+ // installation is complete.
282
+
283
+ if ( this . installModulesInTerminal ( ) || this . _waitForCompletion ) {
266
284
// Ensure we pass a cancellation token so that we await the full terminal command
267
285
// execution before returning.
268
286
const cancelToken = token ?? new CancellationTokenSource ( ) . token ;
287
+ // Unset the waitForCompletion flag so that future calls are not blocked if not desired.
288
+ // If a call needs to be blocked this will be set to true again in the installModule method.
289
+ this . _waitForCompletion = undefined ;
269
290
await terminalService . sendCommand ( command , args , token ?? cancelToken ) ;
270
291
return ;
271
292
}
0 commit comments