From 454563ccc5e122446e19127937e7fe11c47702da Mon Sep 17 00:00:00 2001 From: Francesco Stasi Date: Thu, 22 Jul 2021 18:37:49 +0200 Subject: [PATCH 1/8] wip --- .../cloud-sketchbook/cloud-sketchbook-tree.ts | 68 +++++++++++++++++++ 1 file changed, 68 insertions(+) diff --git a/arduino-ide-extension/src/browser/widgets/cloud-sketchbook/cloud-sketchbook-tree.ts b/arduino-ide-extension/src/browser/widgets/cloud-sketchbook/cloud-sketchbook-tree.ts index 6ecac6ddd..7a815b28d 100644 --- a/arduino-ide-extension/src/browser/widgets/cloud-sketchbook/cloud-sketchbook-tree.ts +++ b/arduino-ide-extension/src/browser/widgets/cloud-sketchbook/cloud-sketchbook-tree.ts @@ -127,6 +127,11 @@ export class CloudSketchbookTree extends SketchbookTree { const commandsCopy = node.commands; node.commands = []; + const localUri = await this.fileService.toUnderlyingResource( + LocalCacheUri.root.resolve(node.remoteUri.path) + ); + await this.treeDiff(node.remoteUri, localUri); + // check if the sketch dir already exist if (CloudSketchbookTree.CloudSketchTreeNode.isSynced(node)) { const filesToPull = ( @@ -225,6 +230,69 @@ export class CloudSketchbookTree extends SketchbookTree { }); } + async recursiveURIs(uri: URI): Promise { + const fileStat = await this.fileService.resolve(uri, { + resolveMetadata: false, + }); + + if (!fileStat.children || !fileStat.isDirectory) { + return [fileStat.resource]; + } + + let childrenUris: URI[] = []; + + for await (const child of fileStat.children) { + childrenUris = [ + ...childrenUris, + ...(await this.recursiveURIs(child.resource)), + ]; + } + + return [fileStat.resource, ...childrenUris]; + } + + private URIsToMap(uris: URI[], basepath: string): Record { + return uris.reduce((prev: Record, curr) => { + const path = curr.toString().split(basepath); + + if (path.length !== 2 || path[1].length === 0) { + return prev; + } + + return { ...prev, [path[1]]: curr }; + }, {}); + } + + async treeDiff(source: URI, dest: URI) { + const sourceBase = source.toString(); + const sourceExists = await this.fileService.exists(source); + const sourceURIs = + (sourceExists && + this.URIsToMap(await this.recursiveURIs(source), sourceBase)) || + {}; + + const destBase = dest.toString(); + const destExists = await this.fileService.exists(dest); + const destURIs = + (destExists && + this.URIsToMap(await this.recursiveURIs(dest), destBase)) || + {}; + + const toWrite: URI[][] = []; + + Object.keys(sourceURIs).forEach((path) => { + const destUri = destURIs[path] || new URI(destBase + path); + + toWrite.push([sourceURIs[path], destUri]); + delete destURIs[path]; + }); + + const toDelete = Object.values(destURIs); + + debugger; + return { toWrite, toDelete }; + } + async refresh( node?: CompositeTreeNode ): Promise { From 45ea687e7bfcb8d76f4eae04422a4b4bc86c2c5a Mon Sep 17 00:00:00 2001 From: Alberto Iannaccone Date: Thu, 22 Jul 2021 17:59:33 +0200 Subject: [PATCH 2/8] improve push/pull process --- .../cloud-sketchbook/cloud-sketchbook-tree.ts | 124 ++++++++++-------- 1 file changed, 70 insertions(+), 54 deletions(-) diff --git a/arduino-ide-extension/src/browser/widgets/cloud-sketchbook/cloud-sketchbook-tree.ts b/arduino-ide-extension/src/browser/widgets/cloud-sketchbook/cloud-sketchbook-tree.ts index 7a815b28d..8ac0e104b 100644 --- a/arduino-ide-extension/src/browser/widgets/cloud-sketchbook/cloud-sketchbook-tree.ts +++ b/arduino-ide-extension/src/browser/widgets/cloud-sketchbook/cloud-sketchbook-tree.ts @@ -17,7 +17,6 @@ import { PreferenceScope, } from '@theia/core/lib/browser/preferences/preference-service'; import { MessageService } from '@theia/core/lib/common/message-service'; -import { REMOTE_ONLY_FILES } from './../../create/create-fs-provider'; import { CreateApi } from '../../create/create-api'; import { CreateUri } from '../../create/create-uri'; import { CloudSketchbookTreeModel } from './cloud-sketchbook-tree-model'; @@ -37,6 +36,11 @@ import { WorkspaceNode } from '@theia/navigator/lib/browser/navigator-tree'; const MESSAGE_TIMEOUT = 5 * 1000; const deepmerge = require('deepmerge').default; +type FilesToWrite = { source: URI; dest: URI }; +type FilesToSync = { + filesToWrite: FilesToWrite[]; + filesToDelete: URI[]; +}; @injectable() export class CloudSketchbookTree extends SketchbookTree { @inject(FileService) @@ -94,7 +98,7 @@ export class CloudSketchbookTree extends SketchbookTree { async pull(arg: any): Promise { const { - model, + // model, node, }: { model: CloudSketchbookTreeModel; @@ -130,49 +134,46 @@ export class CloudSketchbookTree extends SketchbookTree { const localUri = await this.fileService.toUnderlyingResource( LocalCacheUri.root.resolve(node.remoteUri.path) ); - await this.treeDiff(node.remoteUri, localUri); + await this.sync(node.remoteUri, localUri); // check if the sketch dir already exist - if (CloudSketchbookTree.CloudSketchTreeNode.isSynced(node)) { - const filesToPull = ( - await this.createApi.readDirectory(node.remoteUri.path.toString()) - ).filter((file: any) => !REMOTE_ONLY_FILES.includes(file.name)); - - await Promise.all( - filesToPull.map((file: any) => { - const uri = CreateUri.toUri(file); - this.fileService.copy(uri, LocalCacheUri.root.resolve(uri.path), { - overwrite: true, - }); - }) - ); - - // open the pulled files in the current workspace - const currentSketch = await this.sketchServiceClient.currentSketch(); - - if ( - !CreateUri.is(node.uri) && - currentSketch && - currentSketch.uri === node.uri.toString() - ) { - filesToPull.forEach(async (file) => { - const localUri = LocalCacheUri.root.resolve( - CreateUri.toUri(file).path - ); - const underlying = await this.fileService.toUnderlyingResource( - localUri - ); - - model.open(underlying); - }); - } - } else { - await this.fileService.copy( - node.remoteUri, - LocalCacheUri.root.resolve(node.uri.path), - { overwrite: true } - ); - } + // if (CloudSketchbookTree.CloudSketchTreeNode.isSynced(node)) { + // const filesToPull = ( + // await this.createApi.readDirectory(node.remoteUri.path.toString()) + // ).filter((file: any) => !REMOTE_ONLY_FILES.includes(file.name)); + + // await Promise.all( + // filesToPull.map((file: any) => { + // const uri = CreateUri.toUri(file); + // return this.sync(uri, LocalCacheUri.root.resolve(uri.path)); + // }) + // ); + + // open the pulled files in the current workspace + // const currentSketch = await this.sketchServiceClient.currentSketch(); + + // if ( + // !CreateUri.is(node.uri) && + // currentSketch && + // currentSketch.uri === node.uri.toString() + // ) { + // filesToPull.forEach(async (file) => { + // const localUri = LocalCacheUri.root.resolve( + // CreateUri.toUri(file).path + // ); + // const underlying = await this.fileService.toUnderlyingResource( + // localUri + // ); + + // model.open(underlying); + // }); + // } + // } else { + // await this.sync( + // node.remoteUri, + // LocalCacheUri.root.resolve(node.uri.path) + // ); + // } node.commands = commandsCopy; this.messageService.info(`Done pulling ‘${node.fileStat.name}’.`, { @@ -219,12 +220,9 @@ export class CloudSketchbookTree extends SketchbookTree { } const commandsCopy = node.commands; node.commands = []; - // delete every first level file, then push everything - const result = await this.fileService.copy(node.uri, node.remoteUri, { - overwrite: true, - }); + await this.sync(node.uri, node.remoteUri); node.commands = commandsCopy; - this.messageService.info(`Done pushing ‘${result.name}’.`, { + this.messageService.info(`Done pushing ‘${node.name}’.`, { timeout: MESSAGE_TIMEOUT, }); }); @@ -263,7 +261,7 @@ export class CloudSketchbookTree extends SketchbookTree { }, {}); } - async treeDiff(source: URI, dest: URI) { + async treeDiff(source: URI, dest: URI): Promise { const sourceBase = source.toString(); const sourceExists = await this.fileService.exists(source); const sourceURIs = @@ -278,19 +276,18 @@ export class CloudSketchbookTree extends SketchbookTree { this.URIsToMap(await this.recursiveURIs(dest), destBase)) || {}; - const toWrite: URI[][] = []; + const filesToWrite: FilesToWrite[] = []; Object.keys(sourceURIs).forEach((path) => { const destUri = destURIs[path] || new URI(destBase + path); - toWrite.push([sourceURIs[path], destUri]); + filesToWrite.push({ source: sourceURIs[path], dest: destUri }); delete destURIs[path]; }); - const toDelete = Object.values(destURIs); + const filesToDelete = Object.values(destURIs); - debugger; - return { toWrite, toDelete }; + return { filesToWrite, filesToDelete }; } async refresh( @@ -334,6 +331,25 @@ export class CloudSketchbookTree extends SketchbookTree { } } + async sync(source: URI, dest: URI) { + debugger; + const { filesToWrite, filesToDelete } = await this.treeDiff(source, dest); + debugger; + 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); + }) + ); + + await Promise.all( + filesToDelete.map((file) => this.fileService.delete(file)) + ); + } + async resolveChildren(parent: CompositeTreeNode): Promise { return (await super.resolveChildren(parent)).sort((a, b) => { if ( From 187a9799c113148894061468a624f948eb88a4a0 Mon Sep 17 00:00:00 2001 From: Francesco Stasi Date: Fri, 23 Jul 2021 12:59:14 +0200 Subject: [PATCH 3/8] improved diff tree performance generation --- .../cloud-sketchbook/cloud-sketchbook-tree.ts | 38 ++++++++++++------- 1 file changed, 24 insertions(+), 14 deletions(-) diff --git a/arduino-ide-extension/src/browser/widgets/cloud-sketchbook/cloud-sketchbook-tree.ts b/arduino-ide-extension/src/browser/widgets/cloud-sketchbook/cloud-sketchbook-tree.ts index 8ac0e104b..b0d482907 100644 --- a/arduino-ide-extension/src/browser/widgets/cloud-sketchbook/cloud-sketchbook-tree.ts +++ b/arduino-ide-extension/src/browser/widgets/cloud-sketchbook/cloud-sketchbook-tree.ts @@ -32,6 +32,7 @@ import { ArduinoPreferences } from '../../arduino-preferences'; import { SketchesServiceClientImpl } from '../../../common/protocol/sketches-service-client-impl'; import { FileStat } from '@theia/filesystem/lib/common/files'; import { WorkspaceNode } from '@theia/navigator/lib/browser/navigator-tree'; +import { splitSketchPath } from '../../create/create-paths'; const MESSAGE_TIMEOUT = 5 * 1000; const deepmerge = require('deepmerge').default; @@ -229,6 +230,17 @@ export class CloudSketchbookTree extends SketchbookTree { } async recursiveURIs(uri: URI): Promise { + // remote resources can be fetched one-shot via api + if (CreateUri.is(uri)) { + const resources = await this.createApi.readDirectory( + uri.path.toString(), + { recursive: true } + ); + return resources.map((resource) => + CreateUri.toUri(splitSketchPath(resource.path)[1]) + ); + } + const fileStat = await this.fileService.resolve(uri, { resolveMetadata: false, }); @@ -261,21 +273,21 @@ export class CloudSketchbookTree extends SketchbookTree { }, {}); } + async getUrisMap(uri: URI) { + const basepath = uri.toString(); + const exists = await this.fileService.exists(uri); + const uris = + (exists && this.URIsToMap(await this.recursiveURIs(uri), basepath)) || {}; + return uris; + } + async treeDiff(source: URI, dest: URI): Promise { - const sourceBase = source.toString(); - const sourceExists = await this.fileService.exists(source); - const sourceURIs = - (sourceExists && - this.URIsToMap(await this.recursiveURIs(source), sourceBase)) || - {}; + const [sourceURIs, destURIs] = await Promise.all([ + this.getUrisMap(source), + this.getUrisMap(dest), + ]); const destBase = dest.toString(); - const destExists = await this.fileService.exists(dest); - const destURIs = - (destExists && - this.URIsToMap(await this.recursiveURIs(dest), destBase)) || - {}; - const filesToWrite: FilesToWrite[] = []; Object.keys(sourceURIs).forEach((path) => { @@ -332,9 +344,7 @@ export class CloudSketchbookTree extends SketchbookTree { } async sync(source: URI, dest: URI) { - debugger; const { filesToWrite, filesToDelete } = await this.treeDiff(source, dest); - debugger; await Promise.all( filesToWrite.map(async ({ source, dest }) => { if ((await this.fileService.resolve(source)).isFile) { From a8fc8be72ba7b5b204fcfe7234bd8ee2759f20f7 Mon Sep 17 00:00:00 2001 From: Francesco Stasi Date: Fri, 23 Jul 2021 14:22:35 +0200 Subject: [PATCH 4/8] skip some files to be synced --- .../src/browser/create/create-api.ts | 32 +++++++++++++------ .../src/browser/create/create-fs-provider.ts | 6 +--- .../src/browser/create/typings.ts | 2 +- .../cloud-sketchbook/cloud-sketchbook-tree.ts | 13 ++++++-- 4 files changed, 35 insertions(+), 18 deletions(-) diff --git a/arduino-ide-extension/src/browser/create/create-api.ts b/arduino-ide-extension/src/browser/create/create-api.ts index 0e81ecb90..55a5d6387 100644 --- a/arduino-ide-extension/src/browser/create/create-api.ts +++ b/arduino-ide-extension/src/browser/create/create-api.ts @@ -93,7 +93,11 @@ export class CreateApi { async readDirectory( posixPath: string, - options: { recursive?: boolean; match?: string } = {} + options: { + recursive?: boolean; + match?: string; + skipSketchCache?: boolean; + } = {} ): Promise { const url = new URL( `${this.domain()}/files/d/$HOME/sketches_v2${posixPath}` @@ -106,21 +110,29 @@ export class CreateApi { } const headers = await this.headers(); - return this.run(url, { - method: 'GET', - headers, - }) - .then(async (result) => { - // add arduino_secrets.h to the results, when reading a sketch main folder - if (posixPath.length && posixPath !== posix.sep) { - const sketch = this.sketchCache.getSketch(posixPath); + const cachedSketch = this.sketchCache.getSketch(posixPath); + const sketchPromise = options.skipSketchCache + ? (cachedSketch && this.sketch(cachedSketch.id)) || Promise.resolve(null) + : Promise.resolve(this.sketchCache.getSketch(posixPath)); + + return Promise.all([ + sketchPromise, + this.run(url, { + method: 'GET', + headers, + }), + ]) + .then(async ([sketch, result]) => { + if (posixPath.length && posixPath !== posix.sep) { if (sketch && sketch.secrets && sketch.secrets.length > 0) { result.push(this.getSketchSecretStat(sketch)); } } - return result; + return result.filter( + (res) => !Create.do_not_sync_files.includes(res.name) + ); }) .catch((reason) => { if (reason?.status === 404) return [] as Create.Resource[]; diff --git a/arduino-ide-extension/src/browser/create/create-fs-provider.ts b/arduino-ide-extension/src/browser/create/create-fs-provider.ts index 8199f693d..8f2a2751e 100644 --- a/arduino-ide-extension/src/browser/create/create-fs-provider.ts +++ b/arduino-ide-extension/src/browser/create/create-fs-provider.ts @@ -30,8 +30,6 @@ import { SketchesService } from '../../common/protocol'; import { ArduinoPreferences } from '../arduino-preferences'; import { Create } from './typings'; -export const REMOTE_ONLY_FILES = ['sketch.json']; - @injectable() export class CreateFsProvider implements @@ -109,9 +107,7 @@ export class CreateFsProvider const resources = await this.getCreateApi.readDirectory( uri.path.toString() ); - return resources - .filter((res) => !REMOTE_ONLY_FILES.includes(res.name)) - .map(({ name, type }) => [name, this.toFileType(type)]); + return resources.map(({ name, type }) => [name, this.toFileType(type)]); } async delete(uri: URI, opts: FileDeleteOptions): Promise { diff --git a/arduino-ide-extension/src/browser/create/typings.ts b/arduino-ide-extension/src/browser/create/typings.ts index e951ac794..b5fb0e2d3 100644 --- a/arduino-ide-extension/src/browser/create/typings.ts +++ b/arduino-ide-extension/src/browser/create/typings.ts @@ -21,7 +21,7 @@ export namespace Create { export type ResourceType = 'sketch' | 'folder' | 'file'; export const arduino_secrets_file = 'arduino_secrets.h'; - export const do_not_sync_files = ['.theia']; + export const do_not_sync_files = ['.theia', 'sketch.json']; export interface Resource { readonly name: string; /** diff --git a/arduino-ide-extension/src/browser/widgets/cloud-sketchbook/cloud-sketchbook-tree.ts b/arduino-ide-extension/src/browser/widgets/cloud-sketchbook/cloud-sketchbook-tree.ts index b0d482907..1f03b03df 100644 --- a/arduino-ide-extension/src/browser/widgets/cloud-sketchbook/cloud-sketchbook-tree.ts +++ b/arduino-ide-extension/src/browser/widgets/cloud-sketchbook/cloud-sketchbook-tree.ts @@ -32,7 +32,8 @@ import { ArduinoPreferences } from '../../arduino-preferences'; import { SketchesServiceClientImpl } from '../../../common/protocol/sketches-service-client-impl'; import { FileStat } from '@theia/filesystem/lib/common/files'; import { WorkspaceNode } from '@theia/navigator/lib/browser/navigator-tree'; -import { splitSketchPath } from '../../create/create-paths'; +import { posix, splitSketchPath } from '../../create/create-paths'; +import { Create } from '../../create/typings'; const MESSAGE_TIMEOUT = 5 * 1000; const deepmerge = require('deepmerge').default; @@ -234,7 +235,7 @@ export class CloudSketchbookTree extends SketchbookTree { if (CreateUri.is(uri)) { const resources = await this.createApi.readDirectory( uri.path.toString(), - { recursive: true } + { recursive: true, skipSketchCache: true } ); return resources.map((resource) => CreateUri.toUri(splitSketchPath(resource.path)[1]) @@ -269,6 +270,14 @@ export class CloudSketchbookTree extends SketchbookTree { return prev; } + // do not map "do_not_sync" files/directoris and their descendants + const segments = path[1].split(posix.sep) || []; + if ( + segments.some((segment) => Create.do_not_sync_files.includes(segment)) + ) { + return prev; + } + return { ...prev, [path[1]]: curr }; }, {}); } From c5e2c4a3a80f84b9b7803910244785a87544e70e Mon Sep 17 00:00:00 2001 From: Francesco Stasi Date: Fri, 23 Jul 2021 14:33:45 +0200 Subject: [PATCH 5/8] implementing push --- .../src/browser/create/create-fs-provider.ts | 2 - .../cloud-sketchbook/cloud-sketchbook-tree.ts | 50 ++++--------------- 2 files changed, 9 insertions(+), 43 deletions(-) diff --git a/arduino-ide-extension/src/browser/create/create-fs-provider.ts b/arduino-ide-extension/src/browser/create/create-fs-provider.ts index 8f2a2751e..091ebc979 100644 --- a/arduino-ide-extension/src/browser/create/create-fs-provider.ts +++ b/arduino-ide-extension/src/browser/create/create-fs-provider.ts @@ -111,8 +111,6 @@ export class CreateFsProvider } async delete(uri: URI, opts: FileDeleteOptions): Promise { - return; - if (!opts.recursive) { throw new Error( 'Arduino Create file-system provider does not support non-recursive deletion.' diff --git a/arduino-ide-extension/src/browser/widgets/cloud-sketchbook/cloud-sketchbook-tree.ts b/arduino-ide-extension/src/browser/widgets/cloud-sketchbook/cloud-sketchbook-tree.ts index 1f03b03df..812baf14b 100644 --- a/arduino-ide-extension/src/browser/widgets/cloud-sketchbook/cloud-sketchbook-tree.ts +++ b/arduino-ide-extension/src/browser/widgets/cloud-sketchbook/cloud-sketchbook-tree.ts @@ -138,45 +138,6 @@ export class CloudSketchbookTree extends SketchbookTree { ); await this.sync(node.remoteUri, localUri); - // check if the sketch dir already exist - // if (CloudSketchbookTree.CloudSketchTreeNode.isSynced(node)) { - // const filesToPull = ( - // await this.createApi.readDirectory(node.remoteUri.path.toString()) - // ).filter((file: any) => !REMOTE_ONLY_FILES.includes(file.name)); - - // await Promise.all( - // filesToPull.map((file: any) => { - // const uri = CreateUri.toUri(file); - // return this.sync(uri, LocalCacheUri.root.resolve(uri.path)); - // }) - // ); - - // open the pulled files in the current workspace - // const currentSketch = await this.sketchServiceClient.currentSketch(); - - // if ( - // !CreateUri.is(node.uri) && - // currentSketch && - // currentSketch.uri === node.uri.toString() - // ) { - // filesToPull.forEach(async (file) => { - // const localUri = LocalCacheUri.root.resolve( - // CreateUri.toUri(file).path - // ); - // const underlying = await this.fileService.toUnderlyingResource( - // localUri - // ); - - // model.open(underlying); - // }); - // } - // } else { - // await this.sync( - // node.remoteUri, - // LocalCacheUri.root.resolve(node.uri.path) - // ); - // } - node.commands = commandsCopy; this.messageService.info(`Done pulling ‘${node.fileStat.name}’.`, { timeout: MESSAGE_TIMEOUT, @@ -222,7 +183,12 @@ export class CloudSketchbookTree extends SketchbookTree { } const commandsCopy = node.commands; node.commands = []; - await this.sync(node.uri, node.remoteUri); + + const localUri = await this.fileService.toUnderlyingResource( + LocalCacheUri.root.resolve(node.remoteUri.path) + ); + await this.sync(localUri, node.remoteUri); + node.commands = commandsCopy; this.messageService.info(`Done pushing ‘${node.name}’.`, { timeout: MESSAGE_TIMEOUT, @@ -365,7 +331,9 @@ export class CloudSketchbookTree extends SketchbookTree { ); await Promise.all( - filesToDelete.map((file) => this.fileService.delete(file)) + filesToDelete.map((file) => + this.fileService.delete(file, { recursive: true }) + ) ); } From d322f96b178cd368de33faa335958d8b3b7c7d86 Mon Sep 17 00:00:00 2001 From: Francesco Stasi Date: Fri, 23 Jul 2021 18:46:45 +0200 Subject: [PATCH 6/8] update node sync status when local files change --- .../widgets/cloud-sketchbook/cloud-sketch-cache.ts | 8 ++++++++ .../widgets/cloud-sketchbook/cloud-sketchbook-tree.ts | 6 +++++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/arduino-ide-extension/src/browser/widgets/cloud-sketchbook/cloud-sketch-cache.ts b/arduino-ide-extension/src/browser/widgets/cloud-sketchbook/cloud-sketch-cache.ts index 09a9779f6..6c877e15a 100644 --- a/arduino-ide-extension/src/browser/widgets/cloud-sketchbook/cloud-sketch-cache.ts +++ b/arduino-ide-extension/src/browser/widgets/cloud-sketchbook/cloud-sketch-cache.ts @@ -22,6 +22,14 @@ export class SketchCache { return this.fileStats[path] || null; } + purgeByPath(path: string): void { + for (const itemPath in this.fileStats) { + if (itemPath.indexOf(path) === 0) { + delete this.fileStats[itemPath]; + } + } + } + addSketch(sketch: Create.Sketch): void { const { path } = sketch; const posixPath = toPosixPath(path); diff --git a/arduino-ide-extension/src/browser/widgets/cloud-sketchbook/cloud-sketchbook-tree.ts b/arduino-ide-extension/src/browser/widgets/cloud-sketchbook/cloud-sketchbook-tree.ts index 812baf14b..b7580f2cb 100644 --- a/arduino-ide-extension/src/browser/widgets/cloud-sketchbook/cloud-sketchbook-tree.ts +++ b/arduino-ide-extension/src/browser/widgets/cloud-sketchbook/cloud-sketchbook-tree.ts @@ -138,6 +138,8 @@ export class CloudSketchbookTree extends SketchbookTree { ); await this.sync(node.remoteUri, localUri); + this.sketchCache.purgeByPath(node.remoteUri.path.toString()); + node.commands = commandsCopy; this.messageService.info(`Done pulling ‘${node.fileStat.name}’.`, { timeout: MESSAGE_TIMEOUT, @@ -366,7 +368,7 @@ export class CloudSketchbookTree extends SketchbookTree { /** * Retrieve fileStats for the given node, merging the local and remote childrens - * Local children take prevedence over remote ones + * Local children take precedence over remote ones * @param node * @returns */ @@ -447,6 +449,7 @@ export class CloudSketchbookTree extends SketchbookTree { const node = this.getNode(id); if (fileStat.isDirectory) { if (DirNode.is(node)) { + node.uri = uri; node.fileStat = fileStat; return node; } @@ -462,6 +465,7 @@ export class CloudSketchbookTree extends SketchbookTree { } if (FileNode.is(node)) { node.fileStat = fileStat; + node.uri = uri; return node; } return { From 3c3530b757eb6014a1206cce7b190e21248c553a Mon Sep 17 00:00:00 2001 From: Alberto Iannaccone Date: Mon, 26 Jul 2021 09:51:23 +0200 Subject: [PATCH 7/8] fix push notification --- .../browser/widgets/cloud-sketchbook/cloud-sketchbook-tree.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arduino-ide-extension/src/browser/widgets/cloud-sketchbook/cloud-sketchbook-tree.ts b/arduino-ide-extension/src/browser/widgets/cloud-sketchbook/cloud-sketchbook-tree.ts index b7580f2cb..340cf04f5 100644 --- a/arduino-ide-extension/src/browser/widgets/cloud-sketchbook/cloud-sketchbook-tree.ts +++ b/arduino-ide-extension/src/browser/widgets/cloud-sketchbook/cloud-sketchbook-tree.ts @@ -192,7 +192,7 @@ export class CloudSketchbookTree extends SketchbookTree { await this.sync(localUri, node.remoteUri); node.commands = commandsCopy; - this.messageService.info(`Done pushing ‘${node.name}’.`, { + this.messageService.info(`Done pushing ‘${node.fileStat.name}’.`, { timeout: MESSAGE_TIMEOUT, }); }); From 1a7b201678156b2dd192f8166f8bab83c8b3ca57 Mon Sep 17 00:00:00 2001 From: Francesco Stasi Date: Tue, 27 Jul 2021 17:41:20 +0200 Subject: [PATCH 8/8] skip sync of hidden files & refresh tree on push --- .../widgets/cloud-sketchbook/cloud-sketchbook-tree.ts | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/arduino-ide-extension/src/browser/widgets/cloud-sketchbook/cloud-sketchbook-tree.ts b/arduino-ide-extension/src/browser/widgets/cloud-sketchbook/cloud-sketchbook-tree.ts index 340cf04f5..a315a8f32 100644 --- a/arduino-ide-extension/src/browser/widgets/cloud-sketchbook/cloud-sketchbook-tree.ts +++ b/arduino-ide-extension/src/browser/widgets/cloud-sketchbook/cloud-sketchbook-tree.ts @@ -191,6 +191,8 @@ export class CloudSketchbookTree extends SketchbookTree { ); await this.sync(localUri, node.remoteUri); + this.sketchCache.purgeByPath(node.remoteUri.path.toString()); + node.commands = commandsCopy; this.messageService.info(`Done pushing ‘${node.fileStat.name}’.`, { timeout: MESSAGE_TIMEOUT, @@ -246,6 +248,11 @@ export class CloudSketchbookTree extends SketchbookTree { return prev; } + // skip when the filename is a hidden file (starts with `.`) + if (segments[segments.length - 1].indexOf('.') === 0) { + return prev; + } + return { ...prev, [path[1]]: curr }; }, {}); }