Skip to content

Commit

Permalink
fix mkdirp and use it more, #48527
Browse files Browse the repository at this point in the history
  • Loading branch information
jrieken committed Apr 26, 2018
1 parent 594b8b8 commit 84238e7
Showing 1 changed file with 36 additions and 32 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -412,14 +412,38 @@ export class RemoteFileService extends FileService {

// --- saving

private static async _mkdirp(provider: IFileSystemProvider, directory: URI): Promise<void> {

let basenames: string[] = [];
while (directory.path !== '/') {
try {
let stat = await provider.stat(directory);
if ((stat.type & FileType.Directory) === 0) {
throw new Error(`${directory.toString()} is not a directory`);
}
break; // we have hit a directory -> good
} catch (e) {
// ENOENT
basenames.push(posix.basename(directory.path));
directory = directory.with({ path: posix.dirname(directory.path) });
}
}
for (let i = basenames.length - 1; i >= 0; i--) {
directory = directory.with({ path: posix.join(directory.path, basenames[i]) });
await provider.mkdir(directory);
}
}

createFile(resource: URI, content?: string, options?: ICreateFileOptions): TPromise<IFileStat> {
if (resource.scheme === Schemas.file) {
return super.createFile(resource, content, options);
} else {
return this._withProvider(resource).then(provider => {

const encoding = this.encoding.getWriteEncoding(resource);
return this._writeFile(provider, resource, new StringSnapshot(content), encoding, { create: true, overwrite: Boolean(options && options.overwrite) });
return this._withProvider(resource).then(provider => {
return RemoteFileService._mkdirp(provider, resource.with({ path: posix.dirname(resource.path) })).then(() => {
const encoding = this.encoding.getWriteEncoding(resource);
return this._writeFile(provider, resource, new StringSnapshot(content), encoding, { create: true, overwrite: Boolean(options && options.overwrite) });
});

}).then(fileStat => {
this._onAfterOperation.fire(new FileOperationEvent(resource, FileOperation.CREATE, fileStat));
Expand All @@ -432,16 +456,15 @@ export class RemoteFileService extends FileService {
}
}

async updateContent(resource: URI, value: string | ITextSnapshot, options?: IUpdateContentOptions): TPromise<IFileStat> {
updateContent(resource: URI, value: string | ITextSnapshot, options?: IUpdateContentOptions): TPromise<IFileStat> {
if (resource.scheme === Schemas.file) {
return super.updateContent(resource, value, options);
} else {
if (options && options.mkdirp) {
await this._mkdirp(resource.with({ path: posix.dirname(resource.path) }));
}
return this._withProvider(resource).then(provider => {
const snapshot = typeof value === 'string' ? new StringSnapshot(value) : value;
return this._writeFile(provider, resource, snapshot, options && options.encoding, { create: false, overwrite: false });
return RemoteFileService._mkdirp(provider, resource.with({ path: posix.dirname(resource.path) })).then(() => {
const snapshot = typeof value === 'string' ? new StringSnapshot(value) : value;
return this._writeFile(provider, resource, snapshot, options && options.encoding, { create: true, overwrite: true });
});
});
}
}
Expand Down Expand Up @@ -476,27 +499,6 @@ export class RemoteFileService extends FileService {
});
}

private async _mkdirp(directory: URI): Promise<void> {
let basenames: string[] = [];
while (directory.path !== '/') {
try {
let stat = await this.resolveFile(directory);
if (!stat.isDirectory) {
throw new Error(`${directory.toString()} is not a directory`);
}
} catch (e) {
// ENOENT
basenames.push(posix.basename(directory.path));
directory = directory.with({ path: posix.dirname(directory.path) });
}
break;
}
for (let i = basenames.length - 1; i >= 0; i--) {
directory = directory.with({ path: posix.join(directory.path, basenames[i]) });
await this.createFolder(directory);
}
}

// --- delete

del(resource: URI, useTrash?: boolean): TPromise<void> {
Expand All @@ -516,8 +518,10 @@ export class RemoteFileService extends FileService {
return super.createFolder(resource);
} else {
return this._withProvider(resource).then(provider => {
return provider.mkdir(resource).then(() => {
return this.resolveFile(resource);
return RemoteFileService._mkdirp(provider, resource.with({ path: posix.dirname(resource.path) })).then(() => {
return provider.mkdir(resource).then(() => {
return this.resolveFile(resource);
});
});
}).then(fileStat => {
this._onAfterOperation.fire(new FileOperationEvent(resource, FileOperation.CREATE, fileStat));
Expand Down

0 comments on commit 84238e7

Please sign in to comment.