From 41655106c667515be6c9fb6bc51708c2399d93c9 Mon Sep 17 00:00:00 2001 From: Brett Saviano Date: Thu, 22 Feb 2024 09:48:28 -0500 Subject: [PATCH] Server-side source control improvements (#1314) --- package.json | 8 +-- src/api/atelier.d.ts | 11 ++++- src/commands/delete.ts | 3 +- src/commands/studio.ts | 49 ++++++++++--------- .../FileSystemProvider/FileSystemProvider.ts | 4 +- 5 files changed, 43 insertions(+), 32 deletions(-) diff --git a/package.json b/package.json index f568c0c5..a64bfa45 100644 --- a/package.json +++ b/package.json @@ -201,7 +201,7 @@ }, { "command": "vscode-objectscript.serverCommands.sourceControl", - "when": "vscode-objectscript.connectActive && resourceScheme == isfs || vscode-objectscript.connectActive && !editorIsOpen" + "when": "vscode-objectscript.connectActive && resourceScheme == isfs || (vscode-objectscript.connectActive && !editorIsOpen)" }, { "command": "vscode-objectscript.serverCommands.contextSourceControl", @@ -209,7 +209,7 @@ }, { "command": "vscode-objectscript.serverCommands.other", - "when": "vscode-objectscript.connectActive && resourceScheme =~ /^isfs(-readonly)?$/ || vscode-objectscript.connectActive && !editorIsOpen" + "when": "vscode-objectscript.connectActive && resourceScheme =~ /^isfs(-readonly)?$/ || (vscode-objectscript.connectActive && !editorIsOpen)" }, { "command": "vscode-objectscript.serverCommands.contextOther", @@ -575,12 +575,12 @@ }, { "command": "vscode-objectscript.serverCommands.contextSourceControl", - "when": "resourceScheme == isfs && vscode-objectscript.connectActive", + "when": "resourceScheme == isfs && vscode-objectscript.connectActive && resourcePath && !(resourcePath =~ /^\\/?$/) && !(explorerResourceIsFolder && resource =~ /\\?csp(%3D1|$)/)", "group": "objectscript_servercommand@1" }, { "command": "vscode-objectscript.serverCommands.contextOther", - "when": "resourceScheme =~ /^isfs(-readonly)?$/ && vscode-objectscript.connectActive", + "when": "resourceScheme =~ /^isfs(-readonly)?$/ && vscode-objectscript.connectActive && resourcePath && !(resourcePath =~ /^\\/?$/) && !(explorerResourceIsFolder && resource =~ /\\?csp(%3D1|$)/)", "group": "objectscript_servercommand@2" }, { diff --git a/src/api/atelier.d.ts b/src/api/atelier.d.ts index 0f95544f..c76ea9f5 100644 --- a/src/api/atelier.d.ts +++ b/src/api/atelier.d.ts @@ -24,6 +24,15 @@ interface ServerInfoFeature { enabled: string; } +export interface UserAction { + action: number; + target: string; + message: string; + reload: boolean; + doc: any; + errorText: string; +} + export interface Document { name: string; db: string; @@ -34,7 +43,7 @@ export interface Document { enc: boolean; flags: number; content: string[] | Buffer; - ext: string; + ext?: UserAction | UserAction[]; } export interface ServerInfo { diff --git a/src/commands/delete.ts b/src/commands/delete.ts index 9c1b8c39..36f70941 100644 --- a/src/commands/delete.ts +++ b/src/commands/delete.ts @@ -8,6 +8,7 @@ import { explorerProvider } from "../extension"; import { outputChannel } from "../utils"; import { OtherStudioAction, fireOtherStudioAction } from "./studio"; import { DocumentContentProvider } from "../providers/DocumentContentProvider"; +import { UserAction } from "../api/atelier"; function deleteList(items: string[], workspaceFolder: string, namespace: string): Promise { if (!items || !items.length) { @@ -20,7 +21,7 @@ function deleteList(items: string[], workspaceFolder: string, namespace: string) files.forEach((file) => { if (file.result.ext) { const uri = DocumentContentProvider.getUri(file.result.name); - fireOtherStudioAction(OtherStudioAction.DeletedDocument, uri, file.result.ext); + fireOtherStudioAction(OtherStudioAction.DeletedDocument, uri, file.result.ext); } }); outputChannel.appendLine(`Deleted items: ${files.filter((el) => el.result).length}`); diff --git a/src/commands/studio.ts b/src/commands/studio.ts index 76b4e8db..7783efde 100644 --- a/src/commands/studio.ts +++ b/src/commands/studio.ts @@ -9,6 +9,7 @@ import { RoutineNode } from "../explorer/models/routineNode"; import { importAndCompile } from "./compile"; import { ProjectNode } from "../explorer/models/projectNode"; import { openCustomEditors } from "../providers/RuleEditorProvider"; +import { UserAction } from "../api/atelier"; export let documentBeingProcessed: vscode.TextDocument = null; @@ -119,9 +120,8 @@ export class StudioActions { ); } - // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types - public processUserAction(userAction): Thenable { - const serverAction = parseInt(userAction.action || 0, 10); + public processUserAction(userAction: UserAction): Thenable { + const serverAction = userAction.action; const { target, errorText } = userAction; if (errorText !== "") { outputChannel.appendLine(errorText); @@ -295,14 +295,18 @@ export class StudioActions { ? [type.toString(), action.id, this.name, answer, msg] : [type.toString(), action.id, this.name, selectedText]; + if (config().studioActionDebugOutput) { + outputChannel.appendLine(`${query.slice(0, query.indexOf("("))}(${JSON.stringify(parameters).slice(1, -1)})`); + } + return vscode.window.withProgress( { cancellable: false, - location: vscode.ProgressLocation.Notification, - title: `Executing ${afterUserAction ? "AfterUserAction" : "UserAction"}: ${action.label}`, + location: vscode.ProgressLocation.Window, + title: `Executing ${afterUserAction ? "After" : ""}UserAction: ${action.label}`, }, - () => { - return new Promise((resolve, reject) => { + () => + new Promise((resolve, reject) => { this.api .actionQuery(query, parameters) .then(async (data) => { @@ -313,10 +317,11 @@ export class StudioActions { outputConsole(data.console); } if (!data.result.content.length) { - // nothing to-do, just ignore it + // Nothing to do. Most likely no source control class is enabled. + this.projectEditAnswer = "1"; return; } - const actionToProcess = data.result.content.pop(); + const actionToProcess: UserAction = data.result.content.pop(); if (actionToProcess.reload) { // Avoid the reload triggering the edit listener here @@ -324,11 +329,6 @@ export class StudioActions { await vscode.commands.executeCommand("workbench.action.files.revert", this.uri); } - // CSP pages should not have a progress bar - if (actionToProcess.action === 2) { - resolve(); - } - const attemptedEditLabel = getOtherStudioActionLabel(OtherStudioAction.AttemptedEdit); if (afterUserAction && actionToProcess.errorText !== "") { if (action.label === attemptedEditLabel) { @@ -342,7 +342,7 @@ export class StudioActions { } } outputChannel.appendLine(actionToProcess.errorText); - outputChannel.show(); + outputChannel.show(true); } if (actionToProcess && !afterUserAction) { const answer = await this.processUserAction(actionToProcess); @@ -377,11 +377,10 @@ export class StudioActions { if (err.errorText && err.errorText !== "") { outputChannel.appendLine("\n" + err.errorText); } - outputChannel.show(); + outputChannel.show(true); reject(); }); - }); - } + }) ); } @@ -438,8 +437,7 @@ export class StudioActions { .then((action) => this.userAction(action)); } - // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types - public fireOtherStudioAction(action: OtherStudioAction, userAction?): void { + public fireOtherStudioAction(action: OtherStudioAction, userAction?: UserAction): void { const actionObject = { id: action.toString(), label: getOtherStudioActionLabel(action), @@ -501,7 +499,8 @@ export class StudioActions { return this.api .actionQuery("SELECT %Atelier_v1_Utils.Extension_ExtensionEnabled() AS Enabled", []) .then((data) => data.result.content) - .then((content) => (content && content.length ? content[0].Enabled : false)); + .then((content) => (content && content.length ? content[0]?.Enabled ?? false : false)) + .catch(() => false); // Treat any errors as "no source control" } public getServerInfo(): { server: string; namespace: string } { @@ -568,15 +567,17 @@ export async function _contextMenu(sourceControl: boolean, node: PackageNode | C } } -// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types -export async function fireOtherStudioAction(action: OtherStudioAction, uri?: vscode.Uri, userAction?): Promise { +export async function fireOtherStudioAction( + action: OtherStudioAction, + uri?: vscode.Uri, + userAction?: UserAction +): Promise { if (vscode.workspace.getConfiguration("objectscript.serverSourceControl", uri)?.get("disableOtherActionTriggers")) { return; } const studioActions = new StudioActions(uri); return ( studioActions && - (await studioActions.isSourceControlEnabled()) && !openCustomEditors.includes(uri?.toString()) && // The custom editor will handle all server-side source control interactions studioActions.fireOtherStudioAction(action, userAction) ); diff --git a/src/providers/FileSystemProvider/FileSystemProvider.ts b/src/providers/FileSystemProvider/FileSystemProvider.ts index 9bee8bb6..346bbb33 100644 --- a/src/providers/FileSystemProvider/FileSystemProvider.ts +++ b/src/providers/FileSystemProvider/FileSystemProvider.ts @@ -16,7 +16,7 @@ import { import { config, intLangId, macLangId, workspaceState } from "../../extension"; import { addIsfsFileToProject, modifyProject } from "../../commands/project"; import { DocumentContentProvider } from "../DocumentContentProvider"; -import { Document } from "../../api/atelier"; +import { Document, UserAction } from "../../api/atelier"; declare function setTimeout(callback: (...args: any[]) => void, ms: number, ...args: any[]): NodeJS.Timeout; @@ -453,7 +453,7 @@ export class FileSystemProvider implements vscode.FileSystemProvider { const events: vscode.FileChangeEvent[] = []; try { if (doc.ext) { - fireOtherStudioAction(OtherStudioAction.DeletedDocument, uri, doc.ext); + fireOtherStudioAction(OtherStudioAction.DeletedDocument, uri, doc.ext); } // Remove entry from our cache, plus any now-empty ancestor entries let thisUri = vscode.Uri.parse(uri.toString(), true);