fix: nested cloud sketch folder sync

Signed-off-by: Akos Kitta <a.kitta@arduino.cc>
This commit is contained in:
Akos Kitta 2024-02-21 12:32:41 +01:00
parent aa9b10d68e
commit 478c36c5bd
2 changed files with 57 additions and 37 deletions

View File

@ -1,35 +1,36 @@
import { inject, injectable } from '@theia/core/shared/inversify';
import URI from '@theia/core/lib/common/uri';
import { Event } from '@theia/core/lib/common/event';
import { FrontendApplicationContribution } from '@theia/core/lib/browser/frontend-application';
import {
Disposable,
DisposableCollection,
} from '@theia/core/lib/common/disposable';
import { FrontendApplicationContribution } from '@theia/core/lib/browser/frontend-application';
import {
Stat,
FileType,
FileChange,
FileWriteOptions,
FileDeleteOptions,
FileOverwriteOptions,
FileSystemProvider,
FileSystemProviderError,
FileSystemProviderErrorCode,
FileSystemProviderCapabilities,
WatchOptions,
} from '@theia/filesystem/lib/common/files';
import { Event } from '@theia/core/lib/common/event';
import URI from '@theia/core/lib/common/uri';
import { inject, injectable } from '@theia/core/shared/inversify';
import {
FileService,
FileServiceContribution,
} from '@theia/filesystem/lib/browser/file-service';
import {
FileChange,
FileDeleteOptions,
FileOverwriteOptions,
FileSystemProvider,
FileSystemProviderCapabilities,
FileSystemProviderError,
FileSystemProviderErrorCode,
FileType,
FileWriteOptions,
Stat,
WatchOptions,
createFileSystemProviderError,
} from '@theia/filesystem/lib/common/files';
import { SketchesService } from '../../common/protocol';
import { stringToUint8Array } from '../../common/utils';
import { ArduinoPreferences } from '../arduino-preferences';
import { AuthenticationClientService } from '../auth/authentication-client-service';
import { CreateApi } from './create-api';
import { CreateUri } from './create-uri';
import { SketchesService } from '../../common/protocol';
import { ArduinoPreferences } from '../arduino-preferences';
import { Create } from './typings';
import { stringToUint8Array } from '../../common/utils';
import { Create, isNotFound } from './typings';
@injectable()
export class CreateFsProvider
@ -90,14 +91,27 @@ export class CreateFsProvider
size: 0,
};
}
const resource = await this.getCreateApi.stat(uri.path.toString());
const mtime = Date.parse(resource.modified_at);
return {
type: this.toFileType(resource.type),
ctime: mtime,
mtime,
size: 0,
};
try {
const resource = await this.getCreateApi.stat(uri.path.toString());
const mtime = Date.parse(resource.modified_at);
return {
type: this.toFileType(resource.type),
ctime: mtime,
mtime,
size: 0,
};
} catch (err) {
let errToRethrow = err;
// Not Found (Create API) errors must be remapped to VS Code filesystem provider specific errors
// https://code.visualstudio.com/api/references/vscode-api#FileSystemError
if (isNotFound(err)) {
errToRethrow = createFileSystemProviderError(
err,
FileSystemProviderErrorCode.FileNotFound
);
}
throw errToRethrow;
}
}
async mkdir(uri: URI): Promise<void> {

View File

@ -389,15 +389,21 @@ export class CloudSketchbookTree extends SketchbookTree {
private async sync(source: URI, dest: URI): Promise<void> {
const { filesToWrite, filesToDelete } = await this.treeDiff(source, dest);
await Promise.all(
filesToWrite.map(async ({ source, dest }) => {
if ((await this.fileService.resolve(source)).isFile) {
const content = await this.fileService.read(source);
return this.fileService.write(dest, content.value);
}
return this.fileService.createFolder(dest);
})
// Sort by the URIs. The shortest comes first. It's to ensure creating the parent folder for nested resources, for example.
// When sorting the URIs, it does not matter whether on source or dest, only the URI path and its length matters; they're the same for a source+dest pair
filesToWrite.sort(
(left, right) =>
left.source.path.toString().length - right.source.path.toString().length
);
for (const { source, dest } of filesToWrite) {
const stat = await this.fileService.resolve(source);
if (stat.isFile) {
const content = await this.fileService.read(source);
await this.fileService.write(dest, content.value);
} else {
await this.fileService.createFolder(dest);
}
}
await Promise.all(
filesToDelete.map((file) =>