From f226f95da39a0d5d5f0ca48b198813e57137c2c1 Mon Sep 17 00:00:00 2001 From: davelopez <46503462+davelopez@users.noreply.github.com> Date: Sun, 9 Jun 2024 10:24:37 +0200 Subject: [PATCH] Improve document detection Detect not only .yml but also .yaml document extensions. --- client/package-lock.json | 13 +++- client/package.json | 3 +- client/src/common/utils.ts | 98 ++++++++++++++++++++---------- client/src/requests/gxworkflows.ts | 25 ++++++-- package-lock.json | 4 +- 5 files changed, 101 insertions(+), 42 deletions(-) diff --git a/client/package-lock.json b/client/package-lock.json index ad46de4..ac0b888 100644 --- a/client/package-lock.json +++ b/client/package-lock.json @@ -9,7 +9,8 @@ "version": "0.1.0", "license": "MIT", "dependencies": { - "vscode-languageclient": "^8.1.0" + "vscode-languageclient": "^8.1.0", + "vscode-uri": "^3.0.8" }, "engines": { "vscode": "^1.63.0" @@ -99,6 +100,11 @@ "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.17.3.tgz", "integrity": "sha512-SYU4z1dL0PyIMd4Vj8YOqFvHu7Hz/enbWtpfnVbJHU4Nd1YNYx8u0ennumc6h48GQNeOLxmwySmnADouT/AuZA==" }, + "node_modules/vscode-uri": { + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-3.0.8.tgz", + "integrity": "sha512-AyFQ0EVmsOZOlAnxoFOGOq1SQDWAB7C6aqMGS23svWAllfOaxbuFvcT8D1i8z3Gyn8fraVeZNNmN6e9bxxXkKw==" + }, "node_modules/yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", @@ -172,6 +178,11 @@ "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.17.3.tgz", "integrity": "sha512-SYU4z1dL0PyIMd4Vj8YOqFvHu7Hz/enbWtpfnVbJHU4Nd1YNYx8u0ennumc6h48GQNeOLxmwySmnADouT/AuZA==" }, + "vscode-uri": { + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-3.0.8.tgz", + "integrity": "sha512-AyFQ0EVmsOZOlAnxoFOGOq1SQDWAB7C6aqMGS23svWAllfOaxbuFvcT8D1i8z3Gyn8fraVeZNNmN6e9bxxXkKw==" + }, "yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", diff --git a/client/package.json b/client/package.json index fef8b52..b8b8e13 100644 --- a/client/package.json +++ b/client/package.json @@ -16,7 +16,8 @@ "vscode": "^1.63.0" }, "dependencies": { - "vscode-languageclient": "^8.1.0" + "vscode-languageclient": "^8.1.0", + "vscode-uri": "^3.0.8" }, "scripts": { "webpack": "webpack", diff --git a/client/src/common/utils.ts b/client/src/common/utils.ts index 1d69a51..c143596 100644 --- a/client/src/common/utils.ts +++ b/client/src/common/utils.ts @@ -1,4 +1,5 @@ -import { OutputChannel, Uri, workspace } from "vscode"; +import { workspace } from "vscode"; +import { URI } from "vscode-uri"; /** * Determines if the current workspace contains @@ -22,8 +23,8 @@ export function getWorkspaceScheme(): "file" | "vscode-vfs" { * @param targetScheme The new scheme. * @returns A new copy of the URI with the new scheme. */ -export function replaceUriScheme(uri: Uri, targetScheme: string): Uri { - return Uri.parse(uri.toString().replace(uri.scheme, targetScheme)); +export function replaceUriScheme(uri: URI, targetScheme: string): URI { + return URI.parse(uri.toString().replace(uri.scheme, targetScheme)); } /** @@ -32,44 +33,77 @@ export function replaceUriScheme(uri: Uri, targetScheme: string): Uri { * @param ref The git ref to add to the URI query * @returns The URI with a ref query value set */ -export function addRefToUri(uri: Uri, ref: string): Uri { - return Uri.parse(uri.toString() + `?ref=${ref}`); +export function addRefToUri(uri: URI, ref: string): URI { + return URI.parse(uri.toString() + `?ref=${ref}`); } -/** Just for debugging */ -export function debugPrintCommandArgs(command: string, args: unknown[], outputChannel: OutputChannel): void { - outputChannel.appendLine(`Command ${command} args:`); - for (let index = 0; index < args.length; index++) { - const element = args[index]; - outputChannel.appendLine(` [${index}] ${JSON.stringify(element)}`); - } - outputChannel.appendLine(`---\n`); +// Workflow tests document can end with -test.yml, -tests.yml, -test.yaml, -tests.yaml +const workflowTestsDocumentPattern = /(.*)-(test|tests)\.(yml|yaml)$/; + +// Workflow format1 documents can end with .ga +// Workflow format2 documents can end with .gxwf.yml or .gxwf.yaml +const format1WorkflowDocumentPattern = /\.ga$/; +const format2WorkflowDocumentPattern = /\.gxwf\.(yml|yaml)$/; + +export function isWorkflowTestsDocument(uri: URI): boolean { + return workflowTestsDocumentPattern.test(uri.path); +} + +export function isNativeWorkflowDocument(uri: URI): boolean { + return format1WorkflowDocumentPattern.test(uri.path); } -export function isWorkflowTestsDocument(uri: Uri): boolean { - return uri.path.endsWith("-test.yml") || uri.path.endsWith("-tests.yml"); +export function isFormat2WorkflowDocument(uri: URI): boolean { + return format2WorkflowDocumentPattern.test(uri.path); +} + +export async function getAssociatedWorkflowUriFromTestsUri(workflowTestsDocumentUri: URI): Promise { + if (!isWorkflowTestsDocument(workflowTestsDocumentUri)) { + return undefined; + } + + //Try to find a format1 workflow document first + let workflowDocumentUri = replaceUriPattern(workflowTestsDocumentUri, workflowTestsDocumentPattern, ".ga"); + if (await fileUriExistsInWorkspace(workflowDocumentUri)) { + return workflowDocumentUri; + } + //Try to find a format2 workflow document + workflowDocumentUri = replaceUriPattern(workflowTestsDocumentUri, workflowTestsDocumentPattern, ".gxwf.yaml"); + if (await fileUriExistsInWorkspace(workflowDocumentUri)) { + return workflowDocumentUri; + } + + workflowDocumentUri = replaceUriPattern(workflowTestsDocumentUri, workflowTestsDocumentPattern, ".gxwf.yml"); + if (await fileUriExistsInWorkspace(workflowDocumentUri)) { + return workflowDocumentUri; + } + return undefined; } -export function isNativeWorkflowDocument(uri: Uri): boolean { - return uri.path.endsWith(".ga"); +/** + * Replaces the matched pattern in the URI path with the replacement. + * @param uri The URI to be modified. + * @param pattern The pattern to match in the URI path. + * @param replacement The replacement string. + * @returns A new copy of the URI with the pattern replaced. + */ +export function replaceUriPattern(uri: URI, pattern: RegExp, replacement: string): URI { + const uriString = uri.toString(); + const newUriString = uriString.replace(pattern, `$1${replacement}`); + const result = URI.parse(newUriString); + return result; } -export async function getAssociatedWorkflowUriFromTestsUri(workflowTestsDocumentUri: Uri): Promise { - const format2WorkflowUri = Uri.parse( - workflowTestsDocumentUri.toString().replace("-test.yml", ".gxwf.yml").replace("-tests.yml", ".gxwf.yml") - ); +/** + * Determines if a file exists at the given URI in the workspace. + * @param uri The URI to check for existence. + * @returns true if the (virtual) file exists, false otherwise. + */ +export async function fileUriExistsInWorkspace(uri: URI): Promise { try { - await workspace.fs.stat(format2WorkflowUri); - return format2WorkflowUri; + await workspace.fs.stat(uri); + return true; } catch { - const nativeWorkflowUri = Uri.parse( - workflowTestsDocumentUri.toString().replace("-test.yml", ".ga").replace("-tests.yml", ".ga") - ); - try { - await workspace.fs.stat(nativeWorkflowUri); - return nativeWorkflowUri; - } catch { - return undefined; - } + return false; } } diff --git a/client/src/requests/gxworkflows.ts b/client/src/requests/gxworkflows.ts index baad2f4..42ec2a7 100644 --- a/client/src/requests/gxworkflows.ts +++ b/client/src/requests/gxworkflows.ts @@ -12,6 +12,8 @@ import { TargetWorkflowDocumentParams, } from "../languageTypes"; +const TEST_DOCUMENT_TO_WORKFLOW_DOCUMENT_URI_MAP = new Map(); + export function setupRequests( context: ExtensionContext, nativeWorkflowClient: BaseLanguageClient, @@ -19,23 +21,34 @@ export function setupRequests( ): void { function createRequestHandler(requestIdentifier: string) { return async (params: TargetWorkflowDocumentParams) => { - let targetUri: Uri | undefined = Uri.parse(params.uri); + const targetUri: Uri | undefined = Uri.parse(params.uri); + let resultUri: Uri | undefined = undefined; if (isWorkflowTestsDocument(targetUri)) { // If the target is a test file, we need to find the associated workflow file - targetUri = await getAssociatedWorkflowUriFromTestsUri(targetUri); + //Try cache first + const cacheKey = targetUri.toString(); + if (TEST_DOCUMENT_TO_WORKFLOW_DOCUMENT_URI_MAP.has(cacheKey)) { + resultUri = TEST_DOCUMENT_TO_WORKFLOW_DOCUMENT_URI_MAP.get(cacheKey)!; + } + if (!resultUri) { + resultUri = await getAssociatedWorkflowUriFromTestsUri(targetUri); + if (resultUri) { + TEST_DOCUMENT_TO_WORKFLOW_DOCUMENT_URI_MAP.set(cacheKey, resultUri); + } + } } - if (!targetUri) { + if (!resultUri) { console.debug("No associated workflow file found for:", params.uri); return undefined; } // Open the file to include it in the document cache - await workspace.openTextDocument(targetUri); + await workspace.openTextDocument(resultUri); let languageClient = gxFormat2Client; - if (isNativeWorkflowDocument(targetUri)) { + if (isNativeWorkflowDocument(resultUri)) { languageClient = nativeWorkflowClient; } - const requestParams: TargetWorkflowDocumentParams = { uri: targetUri.toString() }; + const requestParams: TargetWorkflowDocumentParams = { uri: resultUri.toString() }; const result = await languageClient.sendRequest(requestIdentifier, requestParams); return result; }; diff --git a/package-lock.json b/package-lock.json index fe78658..bc3ca55 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "galaxy-workflows", - "version": "0.3.1", + "version": "0.4.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "galaxy-workflows", - "version": "0.3.1", + "version": "0.4.0", "hasInstallScript": true, "license": "MIT", "devDependencies": {