mirror of
https://github.com/microsoft/vscode.git
synced 2026-09-04 10:22:17 +01:00
files - 💄 atomic support
This commit is contained in:
@@ -37,13 +37,13 @@ export enum RimRafMode {
|
||||
* - `UNLINK`: direct removal from disk
|
||||
* - `MOVE`: faster variant that first moves the target to temp dir and then
|
||||
* deletes it in the background without waiting for that to finish.
|
||||
* the optional `target` allows to override where to rename the
|
||||
* the optional `moveToPath` allows to override where to rename the
|
||||
* path to before deleting it.
|
||||
*/
|
||||
async function rimraf(path: string, mode: RimRafMode.UNLINK): Promise<void>;
|
||||
async function rimraf(path: string, mode: RimRafMode.MOVE, target?: string): Promise<void>;
|
||||
async function rimraf(path: string, mode?: RimRafMode, target?: string): Promise<void>;
|
||||
async function rimraf(path: string, mode = RimRafMode.UNLINK, target?: string): Promise<void> {
|
||||
async function rimraf(path: string, mode: RimRafMode.MOVE, moveToPath?: string): Promise<void>;
|
||||
async function rimraf(path: string, mode?: RimRafMode, moveToPath?: string): Promise<void>;
|
||||
async function rimraf(path: string, mode = RimRafMode.UNLINK, moveToPath?: string): Promise<void> {
|
||||
if (isRootOrDriveLetter(path)) {
|
||||
throw new Error('rimraf - will refuse to recursively delete root');
|
||||
}
|
||||
@@ -54,10 +54,10 @@ async function rimraf(path: string, mode = RimRafMode.UNLINK, target?: string):
|
||||
}
|
||||
|
||||
// delete: via move
|
||||
return rimrafMove(path, target);
|
||||
return rimrafMove(path, moveToPath);
|
||||
}
|
||||
|
||||
async function rimrafMove(path: string, target = randomPath(tmpdir())): Promise<void> {
|
||||
async function rimrafMove(path: string, moveToPath = randomPath(tmpdir())): Promise<void> {
|
||||
try {
|
||||
try {
|
||||
// Intentionally using `fs.promises` here to skip
|
||||
@@ -68,7 +68,7 @@ async function rimrafMove(path: string, target = randomPath(tmpdir())): Promise<
|
||||
// than necessary and we have a fallback to delete
|
||||
// via unlink.
|
||||
// https://github.com/microsoft/vscode/issues/139908
|
||||
await fs.promises.rename(path, target);
|
||||
await fs.promises.rename(path, moveToPath);
|
||||
} catch (error) {
|
||||
if (error.code === 'ENOENT') {
|
||||
return; // ignore - path to delete did not exist
|
||||
@@ -78,7 +78,7 @@ async function rimrafMove(path: string, target = randomPath(tmpdir())): Promise<
|
||||
}
|
||||
|
||||
// Delete but do not return as promise
|
||||
rimrafUnlink(target).catch(error => {/* ignore */ });
|
||||
rimrafUnlink(moveToPath).catch(error => {/* ignore */ });
|
||||
} catch (error) {
|
||||
if (error.code !== 'ENOENT') {
|
||||
throw error;
|
||||
|
||||
@@ -91,7 +91,7 @@ flakySuite('PFS', function () {
|
||||
assert.ok(!fs.existsSync(testDir));
|
||||
});
|
||||
|
||||
test('rimraf - simple - move (with target)', async () => {
|
||||
test('rimraf - simple - move (with moveToPath)', async () => {
|
||||
fs.writeFileSync(join(testDir, 'somefile.txt'), 'Contents');
|
||||
fs.writeFileSync(join(testDir, 'someOtherFile.txt'), 'Contents');
|
||||
|
||||
|
||||
@@ -987,6 +987,10 @@ export class FileService extends Disposable implements IFileService {
|
||||
throw new Error(localize('deleteFailedAtomicUnsupported', "Unable to delete file '{0}' atomically because provider does not support it.", this.resourceForError(resource)));
|
||||
}
|
||||
|
||||
if (useTrash && atomic) {
|
||||
throw new Error(localize('deleteFailedTrashAndAtomicUnsupported', "Unable to delete file '{0}' with option to use trash and atomic both enabled.", this.resourceForError(resource)));
|
||||
}
|
||||
|
||||
// Validate delete
|
||||
let stat: IStat | undefined = undefined;
|
||||
try {
|
||||
|
||||
@@ -317,7 +317,8 @@ export interface IFileAtomicDeleteOptions {
|
||||
/**
|
||||
* The optional `atomic` flag can be used to make sure
|
||||
* the `delete` method deletes the target atomically by
|
||||
* first renaming it to a temporary resource and then deleting it.
|
||||
* first renaming it to a temporary resource in the same
|
||||
* folder and then deleting it.
|
||||
*/
|
||||
readonly atomic: IFileAtomicOptions | false;
|
||||
}
|
||||
@@ -394,15 +395,19 @@ export interface IFileDeleteOptions {
|
||||
|
||||
/**
|
||||
* Set to `true` to attempt to move the file to trash
|
||||
* instead of deleting it permanently from disk. This
|
||||
* option maybe not be supported on all providers.
|
||||
* instead of deleting it permanently from disk.
|
||||
*
|
||||
* This option maybe not be supported on all providers.
|
||||
*/
|
||||
readonly useTrash: boolean;
|
||||
|
||||
/**
|
||||
* The optional `atomic` flag can be used to make sure
|
||||
* the `delete` method deletes the target atomically by
|
||||
* first renaming it to a temporary resource and then deleting it.
|
||||
* first renaming it to a temporary resource in the same
|
||||
* folder and then deleting it.
|
||||
*
|
||||
* This option maybe not be supported on all providers.
|
||||
*/
|
||||
readonly atomic: IFileAtomicOptions | false;
|
||||
}
|
||||
|
||||
@@ -589,7 +589,7 @@ flakySuite('Disk File Service', function () {
|
||||
const resource = URI.file(join(testDir, 'deep'));
|
||||
const source = await service.resolve(resource);
|
||||
|
||||
assert.strictEqual(await service.canDelete(source.resource, { recursive: true, useTrash }), true);
|
||||
assert.strictEqual(await service.canDelete(source.resource, { recursive: true, useTrash, atomic }), true);
|
||||
await service.del(source.resource, { recursive: true, useTrash, atomic });
|
||||
|
||||
assert.strictEqual(existsSync(source.resource.fsPath), false);
|
||||
|
||||
Reference in New Issue
Block a user