Skip to content

Commit a23761d

Browse files
Update the code base to use IFileSystem instead of fs and fs-extra. (#7915)
(for #6911) This is a precursor to the actual fix. It ensures that we really do use the new FS API everywhere.
1 parent 9411e98 commit a23761d

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

46 files changed

+3330
-652
lines changed

src/client/common/editor.ts

Lines changed: 27 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
import { Diff, diff_match_patch } from 'diff-match-patch';
2-
import * as fs from 'fs-extra';
32
import { injectable } from 'inversify';
43
import * as md5 from 'md5';
54
import { EOL } from 'os';
65
import * as path from 'path';
76
import { Position, Range, TextDocument, TextEdit, Uri, WorkspaceEdit } from 'vscode';
7+
import { IFileSystem } from './platform/types';
88
import { IEditorUtils } from './types';
99

1010
// Code borrowed from goFormat.ts (Go Extension for VS Code)
@@ -80,7 +80,11 @@ export function getTextEditsFromPatch(before: string, patch: string): TextEdit[]
8080

8181
return textEdits;
8282
}
83-
export function getWorkspaceEditsFromPatch(filePatches: string[], workspaceRoot?: string): WorkspaceEdit {
83+
export function getWorkspaceEditsFromPatch(
84+
filePatches: string[],
85+
fs: IFileSystem,
86+
workspaceRoot?: string
87+
): WorkspaceEdit {
8488
const workspaceEdit = new WorkspaceEdit();
8589
filePatches.forEach(patch => {
8690
const indexOfAtAt = patch.indexOf('@@');
@@ -107,7 +111,7 @@ export function getWorkspaceEditsFromPatch(filePatches: string[], workspaceRoot?
107111

108112
let fileName = fileNameLines[0].substring(fileNameLines[0].indexOf(' a') + 3).trim();
109113
fileName = workspaceRoot && !path.isAbsolute(fileName) ? path.resolve(workspaceRoot, fileName) : fileName;
110-
if (!fs.existsSync(fileName)) {
114+
if (!fs.fileExistsSync(fileName)) {
111115
return;
112116
}
113117

@@ -123,7 +127,7 @@ export function getWorkspaceEditsFromPatch(filePatches: string[], workspaceRoot?
123127
throw new Error('Unable to parse Patch string');
124128
}
125129

126-
const fileSource = fs.readFileSync(fileName).toString('utf8');
130+
const fileSource = fs.readFileSync(fileName);
127131
const fileUri = Uri.file(fileName);
128132

129133
// Add line feeds and build the text edits
@@ -226,24 +230,25 @@ function getTextEditsInternal(before: string, diffs: [number, string][], startLi
226230
return edits;
227231
}
228232

229-
export function getTempFileWithDocumentContents(document: TextDocument): Promise<string> {
230-
return new Promise<string>((resolve, reject) => {
231-
const ext = path.extname(document.uri.fsPath);
232-
// Don't create file in temp folder since external utilities
233-
// look into configuration files in the workspace and are not able
234-
// to find custom rules if file is saved in a random disk location.
235-
// This means temp file has to be created in the same folder
236-
// as the original one and then removed.
237-
238-
// tslint:disable-next-line:no-require-imports
239-
const fileName = `${document.uri.fsPath}.${md5(document.uri.fsPath)}${ext}`;
240-
fs.writeFile(fileName, document.getText(), ex => {
241-
if (ex) {
242-
reject(`Failed to create a temporary file, ${ex.message}`);
243-
}
244-
resolve(fileName);
245-
});
246-
});
233+
export async function getTempFileWithDocumentContents(
234+
document: TextDocument,
235+
fs: IFileSystem
236+
): Promise<string> {
237+
// Don't create file in temp folder since external utilities
238+
// look into configuration files in the workspace and are not able
239+
// to find custom rules if file is saved in a random disk location.
240+
// This means temp file has to be created in the same folder
241+
// as the original one and then removed.
242+
243+
const ext = path.extname(document.uri.fsPath);
244+
const filename = `${document.uri.fsPath}.${md5(document.uri.fsPath)}${ext}`;
245+
await (
246+
fs.writeFile(filename, document.getText())
247+
.catch(err => {
248+
throw Error(`Failed to create a temporary file, ${err.message}`);
249+
})
250+
);
251+
return filename;
247252
}
248253

249254
/**

src/client/common/envFileParser.ts

Lines changed: 0 additions & 63 deletions
This file was deleted.

src/client/common/installer/moduleInstaller.ts

Lines changed: 11 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
// Copyright (c) Microsoft Corporation. All rights reserved.
22
// Licensed under the MIT License.
33

4-
import * as fs from 'fs';
54
import { injectable } from 'inversify';
65
import * as path from 'path';
76
import * as vscode from 'vscode';
@@ -10,15 +9,18 @@ import { IServiceContainer } from '../../ioc/types';
109
import { sendTelemetryEvent } from '../../telemetry';
1110
import { EventName } from '../../telemetry/constants';
1211
import { STANDARD_OUTPUT_CHANNEL } from '../constants';
12+
import { IFileSystem } from '../platform/types';
1313
import { ITerminalServiceFactory } from '../terminal/types';
1414
import { ExecutionInfo, IConfigurationService, IOutputChannel } from '../types';
15-
import { noop } from '../utils/misc';
1615

1716
@injectable()
1817
export abstract class ModuleInstaller {
1918
public abstract get name(): string;
2019
public abstract get displayName(): string
21-
constructor(protected serviceContainer: IServiceContainer) { }
20+
constructor(
21+
protected serviceContainer: IServiceContainer
22+
) { }
23+
2224
public async installModule(name: string, resource?: vscode.Uri): Promise<void> {
2325
sendTelemetryEvent(EventName.PYTHON_INSTALL_PACKAGE, undefined, { installer: this.displayName });
2426
const executionInfo = await this.getExecutionInfo(name, resource);
@@ -38,7 +40,10 @@ export abstract class ModuleInstaller {
3840
if (!currentInterpreter || currentInterpreter.type !== InterpreterType.Unknown) {
3941
await terminalService.sendCommand(pythonPath, args);
4042
} else if (settings.globalModuleInstallation) {
41-
if (await this.isPathWritableAsync(path.dirname(pythonPath))) {
43+
const dirname = path.dirname(pythonPath);
44+
const fs = this.serviceContainer.get<IFileSystem>(IFileSystem);
45+
const isWritable = ! await fs.isDirReadonly(dirname);
46+
if (isWritable) {
4247
await terminalService.sendCommand(pythonPath, args);
4348
} else {
4449
this.elevatedInstall(pythonPath, args);
@@ -50,8 +55,10 @@ export abstract class ModuleInstaller {
5055
await terminalService.sendCommand(executionInfo.execPath!, executionInfoArgs);
5156
}
5257
}
58+
5359
public abstract isSupported(resource?: vscode.Uri): Promise<boolean>;
5460
protected abstract getExecutionInfo(moduleName: string, resource?: vscode.Uri): Promise<ExecutionInfo>;
61+
5562
private async processInstallArgs(args: string[], resource?: vscode.Uri): Promise<string[]> {
5663
const indexOfPylint = args.findIndex(arg => arg.toUpperCase() === 'PYLINT');
5764
if (indexOfPylint === -1) {
@@ -69,19 +76,6 @@ export abstract class ModuleInstaller {
6976
}
7077
return args;
7178
}
72-
private async isPathWritableAsync(directoryPath: string): Promise<boolean> {
73-
const filePath = `${directoryPath}${path.sep}___vscpTest___`;
74-
return new Promise<boolean>(resolve => {
75-
fs.open(filePath, fs.constants.O_CREAT | fs.constants.O_RDWR, (error, fd) => {
76-
if (!error) {
77-
fs.close(fd, () => {
78-
fs.unlink(filePath, noop);
79-
});
80-
}
81-
return resolve(!error);
82-
});
83-
});
84-
}
8579

8680
private elevatedInstall(execPath: string, args: string[]) {
8781
const options = {

src/client/common/net/fileDownloader.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,11 @@
33

44
'use strict';
55

6-
import { WriteStream } from 'fs';
76
import { inject, injectable } from 'inversify';
87
import * as requestTypes from 'request';
98
import { Progress, ProgressLocation } from 'vscode';
109
import { IApplicationShell } from '../application/types';
11-
import { IFileSystem } from '../platform/types';
10+
import { IFileSystem, WriteStream } from '../platform/types';
1211
import { DownloadOptions, IFileDownloader, IHttpClient } from '../types';
1312
import { Http } from '../utils/localize';
1413
import { noop } from '../utils/misc';

0 commit comments

Comments
 (0)