Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add basic support for Workflow Test Files '*-test.yml' #63

Merged
merged 98 commits into from
May 31, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
98 commits
Select commit Hold shift + click to select a range
bb77c29
Refactor WorkflowLanguageService + renamings
davelopez Oct 26, 2023
c747bad
Extract base and add WorkflowTestsDocument
davelopez Oct 26, 2023
1d76066
Refactor WorkflowDocuments into DocumentsCache
davelopez Oct 26, 2023
c83ee7c
Expose language id in document context
davelopez Oct 28, 2023
76eceb7
Add package for workflow tests language
davelopez Oct 28, 2023
5a3327f
Integrate workflow tests language service + refactor
davelopez Oct 28, 2023
19e796a
Register language for wf tests in extension
davelopez Oct 28, 2023
8ffc891
Refactor DocumentBase
davelopez Oct 29, 2023
2540012
Add Inversify IoC container + refactoring
davelopez Nov 10, 2023
6dde51c
Bump some dependencies
davelopez Nov 10, 2023
cd7f184
Fix schema import in native server
davelopez Nov 13, 2023
6650dfd
Remove unnecessary reference and import in
davelopez Nov 29, 2023
b670e17
Rever mapped path import for JSON schema
davelopez Nov 29, 2023
047fecb
Update @types/jest to version 29.5.8
davelopez Nov 29, 2023
a626397
Fix issue with jest and decorators
davelopez Nov 29, 2023
0dfe36c
Fix onConfigurationChanged event triggering
davelopez Dec 4, 2023
5df6adf
Add provisional schema for wf tests
davelopez Dec 8, 2023
9b17559
Add schema provider
davelopez Dec 8, 2023
a1af321
Add hover service interfaces
davelopez Dec 8, 2023
0544611
Setup services in IoC container
davelopez Dec 8, 2023
d3e27f8
Fix tsconfig for schema import
davelopez Dec 8, 2023
0c704da
Inject hover service
davelopez Dec 8, 2023
76afee5
Move schema provider under schema
davelopez Dec 10, 2023
14b816f
Update schema
davelopez Dec 23, 2023
2260d81
Vendorize JSON schema handling
davelopez Dec 25, 2023
ab99441
Refactor schema adapter
davelopez Dec 28, 2023
d890901
Add WorkflowTestsSchemaService + refactor hover
davelopez Dec 28, 2023
640818a
Add WorkflowTestsValidationService
davelopez Dec 28, 2023
475b87f
Use constants for language IDs
davelopez Jan 26, 2024
d75e1f2
Provide access to resolved schema from service
davelopez Jan 27, 2024
a803ef9
Add wf tests completion service (no-op for now)
davelopez Jan 28, 2024
ecdea4f
Expose internal document for compatibility
davelopez Feb 17, 2024
f0cd6c9
Add upstream methods to yaml language server
davelopez Feb 18, 2024
f5d74d4
Refactor imports in common languageTypes.ts
davelopez Feb 19, 2024
cb32200
Add getMatchingSchemas to WorkflowTestsSchemaService
davelopez Feb 19, 2024
98a0d44
Add YAML completion helper
davelopez Feb 22, 2024
d73e377
Add some unit tests for completion
davelopez Feb 22, 2024
c27f7fd
Refactor isVirtualWorkspace
davelopez Feb 22, 2024
540f784
Associate server instance with services
davelopez Feb 22, 2024
33e280b
Add isWorkflowInputType function to utils.ts
davelopez Feb 24, 2024
7f3fddd
Update workflow tests document to include workflow inputs
davelopez Feb 25, 2024
b605573
Fix tests config
davelopez Apr 27, 2024
d468597
Add property completions for inputs of class File
davelopez Apr 27, 2024
1084cf4
Add more completion tests
davelopez Apr 28, 2024
4e56e38
Fix some completion issues
davelopez Apr 28, 2024
038135c
Use resultText when no proposals match
davelopez Apr 28, 2024
d318fdc
Remove unused code
davelopez May 1, 2024
ef9ba78
Add tests for wf input completion
davelopez May 1, 2024
c40a074
Fix range check on new node contained in sequence element
davelopez May 1, 2024
dd1e6c8
Fix duplicate suggestion for existing nodes
davelopez May 1, 2024
018490d
Fix value completion by matching range
davelopez May 1, 2024
801d3fa
Add documentation for class completion
davelopez May 4, 2024
0962c8b
Add more tests
davelopez May 4, 2024
389b034
Improve File class suggestions
davelopez May 4, 2024
14c82d8
Implement WorkflowDataProvider.getWorkflowOutputs
davelopez May 5, 2024
18e7c75
Add workflow outputs autocompletion
davelopez May 5, 2024
29b5d3f
Refactor workflowDataProvider and reduce duplication
davelopez May 5, 2024
86aa6ec
Add tests for output completion
davelopez May 6, 2024
7251083
Handle both "-test.yml" and "-tests.yml" file extensions
davelopez May 6, 2024
2abe492
Fix completion with names including colon
davelopez May 7, 2024
6ca40af
Add test for input names containing colon
davelopez May 9, 2024
7ae8421
Refactor ASTNode types for yaml compatibility
davelopez May 9, 2024
b9ccdb1
Fix getParent for non-pair nodes
davelopez May 9, 2024
4397cec
Move input and output getters to native document
davelopez May 9, 2024
f0ee612
Fix associated workflow uri for format2 workflows
davelopez May 10, 2024
630d478
Refactor to remove RequestType dependency
davelopez May 10, 2024
5dc82da
Refactor move shared types
davelopez May 11, 2024
a642627
Implement getWorkflowInputs for format2 documents
davelopez May 11, 2024
71dfa85
Add test for getting format2 workflow inputs
davelopez May 12, 2024
15f2d24
Define input types from format2
davelopez May 12, 2024
beab66f
Fix input type parsing for format2 documents
davelopez May 12, 2024
b31245b
Adapt format1 input types to format2
davelopez May 12, 2024
2c9575f
Refactor rename WorkflowInputType to WorkflowDataType
davelopez May 12, 2024
3e69b47
Implement format2 wf output completion
davelopez May 15, 2024
f640096
Add test for native wf inputs
davelopez May 15, 2024
7fb7528
Fix getWorkflowInputs for .ga workflows
davelopez May 15, 2024
01995fe
Add tests for getting workflow outputs
davelopez May 24, 2024
9f86288
Fix getWorkflowOutputs for .ga workflows
davelopez May 24, 2024
7f13bb9
Add wf test language server support to browser extension
davelopez May 25, 2024
f074364
Add script to run extension in browser
davelopez May 25, 2024
7b3146c
Set pre-launch task to watch in Webworker launcher
davelopez May 25, 2024
26dbbc1
Cleanup some console logs
davelopez May 25, 2024
b6293b3
Tidy up some imports
davelopez May 26, 2024
5220456
Include missing parameter_input in workflow inputs
davelopez May 26, 2024
6ea4a52
Refactor completion helper
davelopez May 26, 2024
89d84b0
Add completion for input values
davelopez May 26, 2024
f217074
Refactor getWorkflowInputs test for .ga
davelopez May 26, 2024
a8251cd
Fix input name retrieval for .ga
davelopez May 26, 2024
e8c52f9
Add `color` as possible input type
davelopez May 26, 2024
5ded943
Increase test coverage for getWorkflowInputs in .ga workflows
davelopez May 26, 2024
f902f18
Fix typescript config for shared module
davelopez May 28, 2024
6789e3f
Add basic validation for inputs/outputs in test document
davelopez May 29, 2024
f181f52
Add tests for test document validation
davelopez May 29, 2024
8a7a63b
Cleanup comments
davelopez May 29, 2024
b65a4c9
Move parseTemplate function to common testHelpers module
davelopez May 30, 2024
dbdb074
Refactor tests to use the same fake WorkflowDataProvider
davelopez May 30, 2024
0368f78
Implement Hover for inputs and outputs in tests documents
davelopez May 30, 2024
94de973
Add tests for hover in test documents
davelopez May 30, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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