未验证 提交 4fcd3127 编写于 作者: B Benjamin Pasero 提交者: GitHub

Adopt recursive fs.mkdir from node.js 12 (fix #82617) (#83831)

* Adopt recursive fs.mkdir from node.js 12 (fix #82617)

* fix tests
上级 3859385c
......@@ -153,34 +153,14 @@ exports.writeFile = function (file, content) {
});
};
/**
* @param {string} dir
* @returns {Promise<string>}
*/
function mkdir(dir) {
const fs = require('fs');
return new Promise((c, e) => fs.mkdir(dir, err => (err && err.code !== 'EEXIST') ? e(err) : c(dir)));
}
/**
* @param {string} dir
* @returns {Promise<string>}
*/
exports.mkdirp = function mkdirp(dir) {
const path = require('path');
return mkdir(dir).then(null, err => {
if (err && err.code === 'ENOENT') {
const parent = path.dirname(dir);
if (parent !== dir) { // if not arrived at root
return mkdirp(parent).then(() => mkdir(dir));
}
}
const fs = require('fs');
throw err;
});
return new Promise((c, e) => fs.mkdir(dir, { recursive: true }, err => (err && err.code !== 'EEXIST') ? e(err) : c(dir)));
};
//#endregion
......
......@@ -50,8 +50,8 @@ function factory(nodeRequire, path, fs, perf) {
* @param {string} dir
* @returns {Promise<string>}
*/
function mkdir(dir) {
return new Promise((c, e) => fs.mkdir(dir, err => (err && err.code !== 'EEXIST') ? e(err) : c(dir)));
function mkdirp(dir) {
return new Promise((c, e) => fs.mkdir(dir, { recursive: true }, err => (err && err.code !== 'EEXIST') ? e(err) : c(dir)));
}
/**
......@@ -91,24 +91,6 @@ function factory(nodeRequire, path, fs, perf) {
});
}
/**
* @param {string} dir
* @returns {Promise<string>}
*/
function mkdirp(dir) {
return mkdir(dir).then(null, err => {
if (err && err.code === 'ENOENT') {
const parent = path.dirname(dir);
if (parent !== dir) { // if not arrived at root
return mkdirp(parent).then(() => mkdir(dir));
}
}
throw err;
});
}
function readFile(file) {
return new Promise(function (resolve, reject) {
fs.readFile(file, 'utf8', function (err, data) {
......
......@@ -3,7 +3,7 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { join, dirname } from 'vs/base/common/path';
import { join } from 'vs/base/common/path';
import { Queue } from 'vs/base/common/async';
import * as fs from 'fs';
import * as os from 'os';
......@@ -11,7 +11,6 @@ import * as platform from 'vs/base/common/platform';
import { Event } from 'vs/base/common/event';
import { endsWith } from 'vs/base/common/strings';
import { promisify } from 'util';
import { CancellationToken } from 'vs/base/common/cancellation';
import { isRootOrDriveLetter } from 'vs/base/common/extpath';
import { generateUuid } from 'vs/base/common/uuid';
import { normalizeNFC } from 'vs/base/common/normalization';
......@@ -633,58 +632,8 @@ async function doCopyFile(source: string, target: string, mode: number): Promise
});
}
export async function mkdirp(path: string, mode?: number, token?: CancellationToken): Promise<void> {
const mkdir = async () => {
try {
await promisify(fs.mkdir)(path, mode);
} catch (error) {
// ENOENT: a parent folder does not exist yet
if (error.code === 'ENOENT') {
throw error;
}
// Any other error: check if folder exists and
// return normally in that case if its a folder
let targetIsFile = false;
try {
const fileStat = await stat(path);
targetIsFile = !fileStat.isDirectory();
} catch (statError) {
throw error; // rethrow original error if stat fails
}
if (targetIsFile) {
throw new Error(`'${path}' exists and is not a directory.`);
}
}
};
// stop at root
if (path === dirname(path)) {
return;
}
try {
await mkdir();
} catch (error) {
// Respect cancellation
if (token && token.isCancellationRequested) {
return Promise.resolve();
}
// ENOENT: a parent folder does not exist yet, continue
// to create the parent folder and then try again.
if (error.code === 'ENOENT') {
await mkdirp(dirname(path), mode);
return mkdir();
}
// Any other error
throw error;
}
export async function mkdirp(path: string, mode?: number): Promise<void> {
return promisify(fs.mkdir)(path, { mode, recursive: true });
}
// See https://github.com/Microsoft/vscode/issues/30180
......
......@@ -86,7 +86,7 @@ function extractEntry(stream: Readable, fileName: string, mode: number, targetPa
}
});
return Promise.resolve(mkdirp(targetDirName, undefined, token)).then(() => new Promise<void>((c, e) => {
return Promise.resolve(mkdirp(targetDirName)).then(() => new Promise<void>((c, e) => {
if (token.isCancellationRequested) {
return;
}
......@@ -149,7 +149,7 @@ function extractZip(zipfile: ZipFile, targetPath: string, options: IOptions, tok
// directory file names end with '/'
if (/\/$/.test(fileName)) {
const targetFileName = path.join(targetPath, fileName);
last = createCancelablePromise(token => mkdirp(targetFileName, undefined, token).then(() => readNextEntry(token)).then(undefined, e));
last = createCancelablePromise(token => mkdirp(targetFileName).then(() => readNextEntry(token)).then(undefined, e));
return;
}
......
......@@ -12,7 +12,6 @@ import * as uuid from 'vs/base/common/uuid';
import * as pfs from 'vs/base/node/pfs';
import { timeout } from 'vs/base/common/async';
import { getPathFromAmdModule } from 'vs/base/common/amd';
import { CancellationTokenSource } from 'vs/base/common/cancellation';
import { isWindows, isLinux } from 'vs/base/common/platform';
import { canNormalize } from 'vs/base/common/normalization';
import { VSBuffer } from 'vs/base/common/buffer';
......@@ -306,23 +305,6 @@ suite('PFS', () => {
return pfs.rimraf(parentDir, pfs.RimRafMode.MOVE);
});
test('mkdirp cancellation', async () => {
const id = uuid.generateUuid();
const parentDir = path.join(os.tmpdir(), 'vsctests', id);
const newDir = path.join(parentDir, 'pfs', id);
const source = new CancellationTokenSource();
const mkdirpPromise = pfs.mkdirp(newDir, 493, source.token);
source.cancel();
await mkdirpPromise;
assert.ok(!fs.existsSync(newDir));
return pfs.rimraf(parentDir, pfs.RimRafMode.MOVE);
});
test('readDirsInDir', async () => {
const id = uuid.generateUuid();
const parentDir = path.join(os.tmpdir(), 'vsctests', id);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册