diff --git a/CHANGELOG.md b/CHANGELOG.md index 7dccd18..60eb55c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,10 @@ - Added the `DEBUG_FS` flag to allow enabling detailed conditional logging in `sshFileSystem` (#341) - This flag will auto-update when it changes in global flags, unless it's overriden in your SSH FS config - Mostly meant for internal debugging or helping with debugging specific user-reported issues +- Added the `DEBUG_FSR` flag to allow enabing detailed conditional logging for the `FileSystemRouter` + - Similar to `DEBUG_FS` this is mostly meant for internal debugging or when useful for user-reported issues + - This flag will also auto-update when it changes in global flags. + - This is a singleton flag and thus unaffected by overriding it in your SSH FS configs ## v1.25.0 (2022-06-01) diff --git a/src/config.ts b/src/config.ts index 8308722..c6e6d3b 100644 --- a/src/config.ts +++ b/src/config.ts @@ -5,7 +5,7 @@ import { parse as parseJsonc, ParseError } from 'jsonc-parser'; import * as semver from 'semver'; import * as vscode from 'vscode'; import { Logging } from './logging'; -import { toPromise } from './utils'; +import { catchingPromise, toPromise } from './utils'; // Logger scope with default warning/error options (which enables stacktraces) disabled const logging = Logging.scope(undefined, false); @@ -394,6 +394,10 @@ function parseFlagList(list: string[] | undefined, origin: string): Record { applyList(config.workspaceValue, 'Workspace Settings'); applyList(config.workspaceFolderValue, 'WorkspaceFolder Settings'); Logging.info`Calculated config flags: ${flags}`; + for (const listener of globalFlagsSubscribers) { + catchingPromise(listener).catch(e => Logging.error`onGlobalFlagsChanged listener errored: ${e}`); + } return cachedFlags = flags; } diff --git a/src/fileSystemRouter.ts b/src/fileSystemRouter.ts index 6058c28..489f806 100644 --- a/src/fileSystemRouter.ts +++ b/src/fileSystemRouter.ts @@ -1,12 +1,23 @@ import * as vscode from 'vscode'; +import { getFlag, subscribeToGlobalFlags } from './config'; import { Logging } from './logging'; import type { Manager } from './manager'; +const ALL_DEBUG_FLAGS = [ + 'stat', 'readDirectory', 'createDirectory', + 'readFile', 'writeFile', 'delete', 'rename', +].map(v => v.toLowerCase()); + export class FileSystemRouter implements vscode.FileSystemProvider { public onDidChangeFile: vscode.Event; protected onDidChangeFileEmitter = new vscode.EventEmitter(); + protected debugFlags: string[]; constructor(protected readonly manager: Manager) { this.onDidChangeFile = this.onDidChangeFileEmitter.event; + subscribeToGlobalFlags(() => { + this.debugFlags = `${getFlag('DEBUG_FSR')?.[0] || ''}`.toLowerCase().split(/,\s*|\s+/g); + if (this.debugFlags.includes('all')) this.debugFlags.push(...ALL_DEBUG_FLAGS); + }); } public async assertFs(uri: vscode.Uri): Promise { const fs = this.manager.getFs(uri); @@ -24,30 +35,41 @@ export class FileSystemRouter implements vscode.FileSystemProvider { return new vscode.Disposable(() => { }); } public async stat(uri: vscode.Uri): Promise { + if (this.debugFlags.includes('stat')) + Logging.debug`Performing stat for ${uri}`; return (await this.assertFs(uri)).stat(uri); } public async readDirectory(uri: vscode.Uri): Promise<[string, vscode.FileType][]> { + if (this.debugFlags.includes('readdirectory')) + Logging.debug`Reading directory ${uri}`; return (await this.assertFs(uri)).readDirectory(uri); } public async createDirectory(uri: vscode.Uri): Promise { + if (this.debugFlags.includes('createdirectory')) + Logging.debug`Creating directory ${uri}`; return (await this.assertFs(uri)).createDirectory(uri); } public async readFile(uri: vscode.Uri): Promise { - Logging.debug`Reading ${uri}`; + if (this.debugFlags.includes('readfile')) + Logging.debug`Reading ${uri}`; return (await this.assertFs(uri)).readFile(uri); } public async writeFile(uri: vscode.Uri, content: Uint8Array, options: { create: boolean; overwrite: boolean; }): Promise { - Logging.debug`Writing ${content.length} bytes to ${uri}`; + if (this.debugFlags.includes('writefile')) + Logging.debug`Writing ${content.length} bytes to ${uri} (options: ${options})`; return (await this.assertFs(uri)).writeFile(uri, content, options); } public async delete(uri: vscode.Uri, options: { recursive: boolean; }): Promise { - Logging.debug`Deleting ${uri}`; + if (this.debugFlags.includes('delete')) + Logging.debug`Deleting ${uri} (options: ${options})`; return (await this.assertFs(uri)).delete(uri, options); } public async rename(oldUri: vscode.Uri, newUri: vscode.Uri, options: { overwrite: boolean; }): Promise { - Logging.debug`Renaming ${oldUri} to ${newUri}`; + if (this.debugFlags.includes('rename')) + Logging.debug`Renaming ${oldUri} to ${newUri}`; const fs = await this.assertFs(oldUri); - if (fs !== (await this.assertFs(newUri))) throw new Error(`Can't rename between different SSH filesystems`); + if (fs !== (await this.assertFs(newUri))) + throw new Error(`Can't rename between different SSH filesystems`); return fs.rename(oldUri, newUri, options); } }