Skip to content

Update the code base to use IFileSystem instead of fs and fs-extra. #7915

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
58 commits
Select commit Hold shift + click to select a range
0eec1f3
Get some errant system tests working with the system Python on Ubuntu.
ericsnowcurrently Nov 21, 2019
72b2254
Do not depend on IFileSystem in the old debug adapter.
ericsnowcurrently Oct 22, 2019
8e3af6f
Excise IPlatformService from the old debug adapter.
ericsnowcurrently Oct 23, 2019
24abfc4
Group the FileSystem methods by category (and drop 2 unused methods).
ericsnowcurrently Oct 8, 2019
5326edf
fs -> fsextra.
ericsnowcurrently Oct 9, 2019
f0044ad
fileSystem -> fs.
ericsnowcurrently Oct 9, 2019
6f41c9f
objectExists() -> pathExists().
ericsnowcurrently Oct 9, 2019
dc0ee44
Drop appendFileSync().
ericsnowcurrently Oct 10, 2019
9dc2b06
Drop unneeded "options" param from writeFile().
ericsnowcurrently Oct 10, 2019
532d544
Add some type aliases.
ericsnowcurrently Oct 10, 2019
8f27657
Make methods properly async.
ericsnowcurrently Oct 10, 2019
352a175
Clean up formatting and parameter names.
ericsnowcurrently Oct 10, 2019
c7b7c5d
Add the isDirReadonly() method.
ericsnowcurrently Oct 10, 2019
f617d71
Use IFileSystem.pathExists() (almost) everywhere.
ericsnowcurrently Oct 10, 2019
aad400a
Stop using fs-extra outside of the FileSystem class.
ericsnowcurrently Oct 10, 2019
7ea1b4b
Stop using fs outside of the FileSystem class (mostly).
ericsnowcurrently Oct 10, 2019
de5f872
Drop IPlatformService as a dependency of FileSystem.
ericsnowcurrently Oct 21, 2019
e3b3623
Require strict mode.
ericsnowcurrently Oct 21, 2019
ad0f857
Fix some tests.
ericsnowcurrently Oct 21, 2019
2fdc481
Add a mock vscode enum.
ericsnowcurrently Oct 21, 2019
4a66d39
Factor out IRawFileSystem.
ericsnowcurrently Oct 21, 2019
a9fdb35
Factor out IFileSystemUtils.
ericsnowcurrently Oct 22, 2019
7dbb147
Drop an outdated tslint comment.
ericsnowcurrently Oct 23, 2019
db3b9ac
Drop an entire unused module.
ericsnowcurrently Oct 23, 2019
b32b054
Simplify lookForInterpretersInDirectory().
ericsnowcurrently Oct 23, 2019
9eb24f2
Drop an unused variable.
ericsnowcurrently Oct 23, 2019
1acf2ff
Make the existing filesystem tests "functional".
ericsnowcurrently Oct 23, 2019
71c1d54
Add unit tests (and make dependencies explicit).
ericsnowcurrently Oct 24, 2019
67eafb0
Add functional tests.
ericsnowcurrently Oct 28, 2019
36d41d7
Drop unnecessary error handling.
ericsnowcurrently Oct 28, 2019
957eb0f
Fix a shadowed name.
ericsnowcurrently Oct 28, 2019
00d8a50
Pass "path" to the RawFileSystem ctor.
ericsnowcurrently Oct 30, 2019
baa350b
Factor out TempFileSystem.
ericsnowcurrently Oct 31, 2019
d97b96b
Use TempFileSystem in FileSystemUtils.isDirReadonly().
ericsnowcurrently Oct 31, 2019
7b5562f
Update a log message.
ericsnowcurrently Oct 31, 2019
0100179
Make test setup more clear.
ericsnowcurrently Oct 31, 2019
39f7353
Drop a superfluous check in a test.
ericsnowcurrently Oct 31, 2019
030156e
Use the temp dir callback during test cleanup.
ericsnowcurrently Oct 31, 2019
aa00bc5
Use tmpDir.removeCallback() during test cleanup.
ericsnowcurrently Oct 31, 2019
97d190a
Use skips for platform-specific tests.
ericsnowcurrently Nov 4, 2019
7176ec1
Fix a typo.
ericsnowcurrently Nov 4, 2019
5bb137d
Simplify some test setup.
ericsnowcurrently Nov 4, 2019
826a9a2
Be more explicit about expected args in a mock.
ericsnowcurrently Nov 4, 2019
abce7e8
Fix the tmp FS tests.
ericsnowcurrently Nov 4, 2019
5a023b3
Add a test for reading bogus files.
ericsnowcurrently Nov 11, 2019
c8cb26f
Use assertions for checking if files exist (or don't).
ericsnowcurrently Nov 12, 2019
74564a7
Add missing doc comments.
ericsnowcurrently Nov 12, 2019
32243b6
Drop an unused interface method.
ericsnowcurrently Nov 12, 2019
1f8e46f
Do not provide defaults in the constructors.
ericsnowcurrently Nov 12, 2019
0f137f0
Make inversify happy about the FileSystem class.
ericsnowcurrently Nov 13, 2019
784a241
Drop dead comments.
ericsnowcurrently Nov 12, 2019
242c1ee
Use util.promisify() for glob().
ericsnowcurrently Nov 12, 2019
e3cf740
Drop a dead comment.
ericsnowcurrently Nov 12, 2019
97e5278
Drop some whitespace.
ericsnowcurrently Nov 12, 2019
bde62a3
Use normal import for chai-as-promised.
ericsnowcurrently Nov 12, 2019
7bbd06a
Fix how some tests are skipped.
ericsnowcurrently Nov 13, 2019
1dd4d09
Drop pathExistsSync().
ericsnowcurrently Nov 13, 2019
5eb00e1
Fix typos and clarify comments.
ericsnowcurrently Nov 26, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 27 additions & 22 deletions src/client/common/editor.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { Diff, diff_match_patch } from 'diff-match-patch';
import * as fs from 'fs-extra';
import { injectable } from 'inversify';
import * as md5 from 'md5';
import { EOL } from 'os';
import * as path from 'path';
import { Position, Range, TextDocument, TextEdit, Uri, WorkspaceEdit } from 'vscode';
import { IFileSystem } from './platform/types';
import { IEditorUtils } from './types';

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

return textEdits;
}
export function getWorkspaceEditsFromPatch(filePatches: string[], workspaceRoot?: string): WorkspaceEdit {
export function getWorkspaceEditsFromPatch(
filePatches: string[],
fs: IFileSystem,
workspaceRoot?: string
): WorkspaceEdit {
const workspaceEdit = new WorkspaceEdit();
filePatches.forEach(patch => {
const indexOfAtAt = patch.indexOf('@@');
Expand All @@ -107,7 +111,7 @@ export function getWorkspaceEditsFromPatch(filePatches: string[], workspaceRoot?

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

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

const fileSource = fs.readFileSync(fileName).toString('utf8');
const fileSource = fs.readFileSync(fileName);
const fileUri = Uri.file(fileName);

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

export function getTempFileWithDocumentContents(document: TextDocument): Promise<string> {
return new Promise<string>((resolve, reject) => {
const ext = path.extname(document.uri.fsPath);
// Don't create file in temp folder since external utilities
// look into configuration files in the workspace and are not able
// to find custom rules if file is saved in a random disk location.
// This means temp file has to be created in the same folder
// as the original one and then removed.

// tslint:disable-next-line:no-require-imports
const fileName = `${document.uri.fsPath}.${md5(document.uri.fsPath)}${ext}`;
fs.writeFile(fileName, document.getText(), ex => {
if (ex) {
reject(`Failed to create a temporary file, ${ex.message}`);
}
resolve(fileName);
});
});
export async function getTempFileWithDocumentContents(
document: TextDocument,
fs: IFileSystem
): Promise<string> {
// Don't create file in temp folder since external utilities
// look into configuration files in the workspace and are not able
// to find custom rules if file is saved in a random disk location.
// This means temp file has to be created in the same folder
// as the original one and then removed.

const ext = path.extname(document.uri.fsPath);
const filename = `${document.uri.fsPath}.${md5(document.uri.fsPath)}${ext}`;
await (
fs.writeFile(filename, document.getText())
.catch(err => {
throw Error(`Failed to create a temporary file, ${err.message}`);
})
);
return filename;
}

/**
Expand Down
63 changes: 0 additions & 63 deletions src/client/common/envFileParser.ts

This file was deleted.

28 changes: 11 additions & 17 deletions src/client/common/installer/moduleInstaller.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

import * as fs from 'fs';
import { injectable } from 'inversify';
import * as path from 'path';
import * as vscode from 'vscode';
Expand All @@ -10,15 +9,18 @@ import { IServiceContainer } from '../../ioc/types';
import { sendTelemetryEvent } from '../../telemetry';
import { EventName } from '../../telemetry/constants';
import { STANDARD_OUTPUT_CHANNEL } from '../constants';
import { IFileSystem } from '../platform/types';
import { ITerminalServiceFactory } from '../terminal/types';
import { ExecutionInfo, IConfigurationService, IOutputChannel } from '../types';
import { noop } from '../utils/misc';

@injectable()
export abstract class ModuleInstaller {
public abstract get name(): string;
public abstract get displayName(): string
constructor(protected serviceContainer: IServiceContainer) { }
constructor(
protected serviceContainer: IServiceContainer
) { }

public async installModule(name: string, resource?: vscode.Uri): Promise<void> {
sendTelemetryEvent(EventName.PYTHON_INSTALL_PACKAGE, undefined, { installer: this.displayName });
const executionInfo = await this.getExecutionInfo(name, resource);
Expand All @@ -38,7 +40,10 @@ export abstract class ModuleInstaller {
if (!currentInterpreter || currentInterpreter.type !== InterpreterType.Unknown) {
await terminalService.sendCommand(pythonPath, args);
} else if (settings.globalModuleInstallation) {
if (await this.isPathWritableAsync(path.dirname(pythonPath))) {
const dirname = path.dirname(pythonPath);
const fs = this.serviceContainer.get<IFileSystem>(IFileSystem);
const isWritable = ! await fs.isDirReadonly(dirname);
if (isWritable) {
await terminalService.sendCommand(pythonPath, args);
} else {
this.elevatedInstall(pythonPath, args);
Expand All @@ -50,8 +55,10 @@ export abstract class ModuleInstaller {
await terminalService.sendCommand(executionInfo.execPath!, executionInfoArgs);
}
}

public abstract isSupported(resource?: vscode.Uri): Promise<boolean>;
protected abstract getExecutionInfo(moduleName: string, resource?: vscode.Uri): Promise<ExecutionInfo>;

private async processInstallArgs(args: string[], resource?: vscode.Uri): Promise<string[]> {
const indexOfPylint = args.findIndex(arg => arg.toUpperCase() === 'PYLINT');
if (indexOfPylint === -1) {
Expand All @@ -69,19 +76,6 @@ export abstract class ModuleInstaller {
}
return args;
}
private async isPathWritableAsync(directoryPath: string): Promise<boolean> {
const filePath = `${directoryPath}${path.sep}___vscpTest___`;
return new Promise<boolean>(resolve => {
fs.open(filePath, fs.constants.O_CREAT | fs.constants.O_RDWR, (error, fd) => {
if (!error) {
fs.close(fd, () => {
fs.unlink(filePath, noop);
});
}
return resolve(!error);
});
});
}

private elevatedInstall(execPath: string, args: string[]) {
const options = {
Expand Down
3 changes: 1 addition & 2 deletions src/client/common/net/fileDownloader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,11 @@

'use strict';

import { WriteStream } from 'fs';
import { inject, injectable } from 'inversify';
import * as requestTypes from 'request';
import { Progress, ProgressLocation } from 'vscode';
import { IApplicationShell } from '../application/types';
import { IFileSystem } from '../platform/types';
import { IFileSystem, WriteStream } from '../platform/types';
import { DownloadOptions, IFileDownloader, IHttpClient } from '../types';
import { Http } from '../utils/localize';
import { noop } from '../utils/misc';
Expand Down
Loading