Skip to content

Commit

Permalink
Merge pull request #63 from davelopez/add_wf_tests_document_support
Browse files Browse the repository at this point in the history
Add basic support for Workflow Test Files '*-test.yml'
  • Loading branch information
davelopez authored May 31, 2024
2 parents b9033c0 + 94de973 commit f82b850
Show file tree
Hide file tree
Showing 92 changed files with 13,810 additions and 620 deletions.
6 changes: 5 additions & 1 deletion .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,11 @@
"sourceMaps": true,
"preLaunchTask": {
"type": "npm",
"script": "compile"
"script": "watch"
},
"resolveSourceMapLocations": ["${workspaceFolder}/client/dist/**/*.js"],
"sourceMapPathOverrides": {
"webpack://?:*/*": "${workspaceFolder}/client/*"
}
},
{
Expand Down
15 changes: 10 additions & 5 deletions client/src/browser/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,11 @@ let gxFormat2LanguageClient: LanguageClient;

export function activate(context: ExtensionContext): void {
nativeLanguageClient = createWebWorkerLanguageClient(
Constants.NATIVE_WORKFLOW_LANGUAGE_ID,
[Constants.NATIVE_WORKFLOW_LANGUAGE_ID],
Uri.joinPath(context.extensionUri, "server/gx-workflow-ls-native/dist/web/nativeServer.js")
);
gxFormat2LanguageClient = createWebWorkerLanguageClient(
Constants.GXFORMAT2_WORKFLOW_LANGUAGE_ID,
[Constants.GXFORMAT2_WORKFLOW_LANGUAGE_ID, Constants.GXFORMAT2_WORKFLOW_TESTS_LANGUAGE_ID],
Uri.joinPath(context.extensionUri, "server/gx-workflow-ls-format2/dist/web/gxFormat2Server.js")
);

Expand All @@ -25,9 +25,14 @@ export async function deactivate(): Promise<void> {
await gxFormat2LanguageClient?.stop();
}

function createWebWorkerLanguageClient(languageId: string, serverUri: Uri): LanguageClient {
const documentSelector = [{ language: languageId }];
function createWebWorkerLanguageClient(languageIds: string[], serverUri: Uri): LanguageClient {
const documentSelector = languageIds.map((languageId) => ({ language: languageId }));
const clientOptions: LanguageClientOptions = buildBasicLanguageClientOptions(documentSelector);
const worker = new Worker(serverUri.toString());
return new LanguageClient(`${languageId}-language-client`, `Galaxy Workflows (${languageId})`, clientOptions, worker);
return new LanguageClient(
`${languageIds}-language-client`,
`Galaxy Workflows (${languageIds})`,
clientOptions,
worker
);
}
7 changes: 5 additions & 2 deletions client/src/commands/cleanWorkflow.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { window } from "vscode";
import { CleanWorkflowDocumentParams, CleanWorkflowDocumentRequest } from "../common/requestsDefinitions";
import { CustomCommand, getCommandFullIdentifier } from ".";
import { CleanWorkflowDocumentParams, CleanWorkflowDocumentResult, LSRequestIdentifiers } from "../languageTypes";

/**
* Command to 'clean' the selected workflow document.
Expand All @@ -17,7 +17,10 @@ export class CleanWorkflowCommand extends CustomCommand {
const { document } = window.activeTextEditor;

const params: CleanWorkflowDocumentParams = { uri: this.client.code2ProtocolConverter.asUri(document.uri) };
const result = await this.client.sendRequest(CleanWorkflowDocumentRequest.type, params);
const result = await this.client.sendRequest<CleanWorkflowDocumentResult>(
LSRequestIdentifiers.CLEAN_WORKFLOW_DOCUMENT,
params
);
if (!result) {
throw new Error("Cannot clean the requested document. The server returned no result.");
}
Expand Down
1 change: 1 addition & 0 deletions client/src/common/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,6 @@
export namespace Constants {
export const NATIVE_WORKFLOW_LANGUAGE_ID = "galaxyworkflow";
export const GXFORMAT2_WORKFLOW_LANGUAGE_ID = "gxformat2";
export const GXFORMAT2_WORKFLOW_TESTS_LANGUAGE_ID = "gxwftests";
export const CLEAN_WORKFLOW_DOCUMENT_SCHEME = "galaxy-clean-workflow";
}
3 changes: 3 additions & 0 deletions client/src/common/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { CleanWorkflowDocumentProvider } from "../providers/cleanWorkflowDocumen
import { CleanWorkflowProvider } from "../providers/cleanWorkflowProvider";
import { GitProvider } from "../providers/git";
import { BuiltinGitProvider } from "../providers/git/gitProvider";
import { setupRequests } from "../requests/gxworkflows";

export function buildBasicLanguageClientOptions(documentSelector: DocumentSelector): LanguageClientOptions {
// Options to control the language client
Expand All @@ -30,6 +31,8 @@ export function initExtension(

// Setup gxformat2 language features
startLanguageClient(context, gxFormat2Client);

setupRequests(context, nativeClient, gxFormat2Client);
}

function initGitProvider(context: ExtensionContext): BuiltinGitProvider {
Expand Down
37 changes: 0 additions & 37 deletions client/src/common/requestsDefinitions.ts

This file was deleted.

30 changes: 29 additions & 1 deletion client/src/common/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { OutputChannel, Uri, workspace } from "vscode";
* @returns true if the workspace is not mounted on a regular filesystem.
*/
export function isVirtualWorkspace(): boolean {
return workspace.workspaceFolders && workspace.workspaceFolders.every((f) => f.uri.scheme !== "file");
return (workspace.workspaceFolders ?? []).every((f) => f.uri.scheme !== "file");
}

/**
Expand Down Expand Up @@ -45,3 +45,31 @@ export function debugPrintCommandArgs(command: string, args: unknown[], outputCh
}
outputChannel.appendLine(`---\n`);
}

export function isWorkflowTestsDocument(uri: Uri): boolean {
return uri.path.endsWith("-test.yml") || uri.path.endsWith("-tests.yml");
}

export function isNativeWorkflowDocument(uri: Uri): boolean {
return uri.path.endsWith(".ga");
}

export async function getAssociatedWorkflowUriFromTestsUri(workflowTestsDocumentUri: Uri): Promise<Uri | undefined> {
const format2WorkflowUri = Uri.parse(
workflowTestsDocumentUri.toString().replace("-test.yml", ".gxwf.yml").replace("-tests.yml", ".gxwf.yml")
);
try {
await workspace.fs.stat(format2WorkflowUri);
return format2WorkflowUri;
} 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;
}
}
}
12 changes: 6 additions & 6 deletions client/src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,11 @@ let gxFormat2LanguageClient: LanguageClient;

export function activate(context: ExtensionContext): void {
nativeLanguageClient = buildNodeLanguageClient(
Constants.NATIVE_WORKFLOW_LANGUAGE_ID,
[Constants.NATIVE_WORKFLOW_LANGUAGE_ID],
buildNativeServerOptions(context)
);
gxFormat2LanguageClient = buildNodeLanguageClient(
Constants.GXFORMAT2_WORKFLOW_LANGUAGE_ID,
[Constants.GXFORMAT2_WORKFLOW_LANGUAGE_ID, Constants.GXFORMAT2_WORKFLOW_TESTS_LANGUAGE_ID],
buildGxFormat2ServerOptions(context)
);

Expand All @@ -26,12 +26,12 @@ export async function deactivate(): Promise<void> {
await gxFormat2LanguageClient?.stop();
}

function buildNodeLanguageClient(languageId: string, serverOptions: ServerOptions): LanguageClient {
const documentSelector = [{ language: languageId }];
function buildNodeLanguageClient(languageIds: string[], serverOptions: ServerOptions): LanguageClient {
const documentSelector = languageIds.map((languageId) => ({ language: languageId }));
const clientOptions: LanguageClientOptions = buildBasicLanguageClientOptions(documentSelector);
return new LanguageClient(
`${languageId}-language-client`,
`Galaxy Workflows (${languageId})`,
`${languageIds}-language-client`,
`Galaxy Workflows (${languageIds})`,
serverOptions,
clientOptions
);
Expand Down
21 changes: 21 additions & 0 deletions client/src/languageTypes.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import {
CleanWorkflowContentsParams,
CleanWorkflowContentsResult,
CleanWorkflowDocumentParams,
CleanWorkflowDocumentResult,
GetWorkflowInputsResult,
GetWorkflowOutputsResult,
LSRequestIdentifiers,
TargetWorkflowDocumentParams,
} from "../../shared/src/requestsDefinitions";

export {
CleanWorkflowContentsParams,
CleanWorkflowContentsResult,
CleanWorkflowDocumentParams,
CleanWorkflowDocumentResult,
GetWorkflowInputsResult,
GetWorkflowOutputsResult,
LSRequestIdentifiers,
TargetWorkflowDocumentParams,
};
7 changes: 5 additions & 2 deletions client/src/providers/cleanWorkflowProvider.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Uri, window, workspace } from "vscode";
import { BaseLanguageClient } from "vscode-languageclient";
import { CleanWorkflowContentsParams, CleanWorkflowContentsRequest } from "../common/requestsDefinitions";
import { getWorkspaceScheme, replaceUriScheme } from "../common/utils";
import { CleanWorkflowContentsParams, CleanWorkflowContentsResult, LSRequestIdentifiers } from "../languageTypes";
import { GitProvider } from "./git";

/**
Expand Down Expand Up @@ -56,7 +56,10 @@ export class CleanWorkflowProvider {
const params: CleanWorkflowContentsParams = {
contents: contents,
};
const result = await this.languageClient.sendRequest(CleanWorkflowContentsRequest.type, params);
const result = await this.languageClient.sendRequest<CleanWorkflowContentsResult>(
LSRequestIdentifiers.CLEAN_WORKFLOW_CONTENTS,
params
);
if (!result) {
throw new Error("Cannot clean the requested document contents. The server returned no content");
}
Expand Down
57 changes: 57 additions & 0 deletions client/src/requests/gxworkflows.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import { ExtensionContext, Uri, workspace } from "vscode";
import { BaseLanguageClient } from "vscode-languageclient";
import {
getAssociatedWorkflowUriFromTestsUri,
isNativeWorkflowDocument,
isWorkflowTestsDocument,
} from "../common/utils";
import {
GetWorkflowInputsResult,
GetWorkflowOutputsResult,
LSRequestIdentifiers,
TargetWorkflowDocumentParams,
} from "../languageTypes";

export function setupRequests(
context: ExtensionContext,
nativeWorkflowClient: BaseLanguageClient,
gxFormat2Client: BaseLanguageClient
): void {
function createRequestHandler<TResult>(requestIdentifier: string) {
return async (params: TargetWorkflowDocumentParams) => {
let targetUri: Uri | undefined = Uri.parse(params.uri);
if (isWorkflowTestsDocument(targetUri)) {
// If the target is a test file, we need to find the associated workflow file
targetUri = await getAssociatedWorkflowUriFromTestsUri(targetUri);
}
if (!targetUri) {
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);

let languageClient = gxFormat2Client;
if (isNativeWorkflowDocument(targetUri)) {
languageClient = nativeWorkflowClient;
}
const requestParams: TargetWorkflowDocumentParams = { uri: targetUri.toString() };
const result = await languageClient.sendRequest<TResult>(requestIdentifier, requestParams);
return result;
};
}

context.subscriptions.push(
gxFormat2Client.onRequest(
LSRequestIdentifiers.GET_WORKFLOW_INPUTS,
createRequestHandler<GetWorkflowInputsResult>(LSRequestIdentifiers.GET_WORKFLOW_INPUTS)
)
);

context.subscriptions.push(
gxFormat2Client.onRequest(
LSRequestIdentifiers.GET_WORKFLOW_OUTPUTS,
createRequestHandler<GetWorkflowOutputsResult>(LSRequestIdentifiers.GET_WORKFLOW_OUTPUTS)
)
);
}
Loading

0 comments on commit f82b850

Please sign in to comment.