11// Copyright (c) Microsoft Corporation.
22// Licensed under the MIT License.
33
4- import { workspace } from 'vscode' ;
4+ import { inject , injectable } from 'inversify' ;
5+ import { workspace , CancellationToken } from 'vscode' ;
56import * as fs from 'fs' ;
6- import * as path from 'path' ;
7+ import * as path from '../../platform/vscode-path/ path' ;
78import type { DeepnoteProject } from './deepnoteTypes' ;
9+ import { ILogger } from '../../platform/logging/types' ;
810
911/**
1012 * Helper class for creating requirements.txt files from Deepnote project settings.
1113 */
14+ @injectable ( )
1215export class DeepnoteRequirementsHelper {
16+ constructor ( @inject ( ILogger ) private readonly logger : ILogger ) { }
17+
1318 /**
1419 * Extracts requirements from project settings and creates a local requirements.txt file.
1520 * @param project The Deepnote project data containing requirements in settings
21+ * @param token Cancellation token to abort the operation if needed
1622 */
17- static async createRequirementsFile ( project : DeepnoteProject ) : Promise < void > {
23+ async createRequirementsFile ( project : DeepnoteProject , token : CancellationToken ) : Promise < void > {
1824 try {
19- const requirements = project . project . settings ?. requirements ;
25+ // Check if the operation has been cancelled
26+ if ( token . isCancellationRequested ) {
27+ return ;
28+ }
29+
30+ const requirements = project . project . settings . requirements ;
2031 if ( ! requirements || ! Array . isArray ( requirements ) || requirements . length === 0 ) {
21- console . log ( `No requirements found in project ${ project . project . id } ` ) ;
32+ this . logger . info ( `No requirements found in project ${ project . project . id } ` ) ;
2233 return ;
2334 }
2435
2536 // Get the workspace folder to determine where to create the requirements.txt file
2637 const workspaceFolders = workspace . workspaceFolders ;
2738 if ( ! workspaceFolders || workspaceFolders . length === 0 ) {
28- console . log ( 'No workspace folder found, cannot create requirements.txt' ) ;
39+ this . logger . info ( 'No workspace folder found, cannot create requirements.txt' ) ;
40+ return ;
41+ }
42+
43+ // Check cancellation before performing I/O
44+ if ( token . isCancellationRequested ) {
2945 return ;
3046 }
3147
@@ -37,9 +53,23 @@ export class DeepnoteRequirementsHelper {
3753
3854 // Write the requirements.txt file
3955 await fs . promises . writeFile ( requirementsPath , requirementsText , 'utf8' ) ;
40- console . log ( `Created requirements.txt with ${ requirements . length } dependencies at ${ requirementsPath } ` ) ;
56+
57+ // Check cancellation after I/O operation
58+ if ( token . isCancellationRequested ) {
59+ this . logger . info ( 'Requirements file creation was cancelled after write' ) ;
60+ return ;
61+ }
62+
63+ this . logger . info (
64+ `Created requirements.txt with ${ requirements . length } dependencies at ${ requirementsPath } `
65+ ) ;
4166 } catch ( error ) {
42- console . error ( `Error creating requirements.txt:` , error ) ;
67+ this . logger . error ( `Error creating requirements.txt:` , error ) ;
4368 }
4469 }
4570}
71+
72+ export const IDeepnoteRequirementsHelper = Symbol ( 'IDeepnoteRequirementsHelper' ) ;
73+ export interface IDeepnoteRequirementsHelper {
74+ createRequirementsFile ( project : DeepnoteProject , token : CancellationToken ) : Promise < void > ;
75+ }
0 commit comments