Skip to content

Add command to upgrade tests to comply with profile 24.2 validation #278

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

Merged
merged 22 commits into from
Apr 12, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
09b21c8
Fix launch configuration type for Launch Server to use debugpy
davelopez Apr 8, 2025
042ddad
Fix typos
davelopez Apr 8, 2025
ed44615
Fix command name for test generation
davelopez Apr 9, 2025
8ff69cc
Add WorkspaceEditResult class
davelopez Apr 9, 2025
3dff4a7
Add WorkspaceEditsGenerator class to generate workspace edits
davelopez Apr 9, 2025
f891d3c
Add DisplayableException for error handling in WorkspaceEditsGenerator
davelopez Apr 9, 2025
15c20b8
Add GalaxyToolTestUpdater class to update test cases in XML documents
davelopez Apr 9, 2025
41f1fb4
Add get_element_range method to XmlDocument
davelopez Apr 9, 2025
5732553
Add update_tests_profile command and integrate GalaxyToolTestUpdater
davelopez Apr 9, 2025
77e7073
Add update.tests command to the client
davelopez Apr 9, 2025
c002c5e
Format document after applying workspace edits
davelopez Apr 9, 2025
776e165
Fix typo
davelopez Apr 9, 2025
0dd8d43
Add GalaxyToolTestUpdater basic test
davelopez Apr 9, 2025
860cc5d
Refactor GalaxyToolTestUpdater
davelopez Apr 10, 2025
c343bdc
Refactor GalaxyToolTestUpdater
davelopez Apr 10, 2025
d257afd
Improve XmlElement representation and fix typo in docstring
davelopez Apr 10, 2025
8ae647d
Add await to activeEditor.edit in requestWorkspaceEdits for proper as…
davelopez Apr 11, 2025
b86039e
Adapt test result for update_profile_simple_01.xml
davelopez Apr 11, 2025
8c2406b
Add test for ancestor parsing
davelopez Apr 11, 2025
9e3110a
Add ParameterNode class and refactor test parameter handling in Galax…
davelopez Apr 11, 2025
732cdda
Refactor _remove_params method
davelopez Apr 11, 2025
8c7f782
Add update_profile_nested_01.xml tool file and corresponding test upd…
davelopez Apr 11, 2025
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
2 changes: 1 addition & 1 deletion .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
},
{
"name": "Launch Server",
"type": "python",
"type": "debugpy",
"console": "internalConsole",
"request": "launch",
"module": "galaxyls",
Expand Down
12 changes: 12 additions & 0 deletions client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,13 @@
"enablement": "galaxytools:isActive",
"icon": "$(test-view-icon)"
},
{
"command": "galaxytools.update.tests",
"title": "Update existing tests cases to comply with 24.2 profile validation",
"category": "Galaxy Tools",
"enablement": "galaxytools:isActive",
"icon": "$(test-view-icon)"
},
{
"command": "galaxytools.generate.command",
"title": "Generate boilerplate command section for current tool",
Expand Down Expand Up @@ -156,6 +163,11 @@
"key": "ctrl+alt+t",
"mac": "cmd+alt+t"
},
{
"command": "galaxytools.update.tests",
"key": "ctrl+alt+u",
"mac": "cmd+alt+u"
},
{
"command": "galaxytools.generate.command",
"key": "ctrl+alt+c",
Expand Down
56 changes: 51 additions & 5 deletions client/src/commands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,15 @@ import {
import { LanguageClient } from "vscode-languageclient/node";
import { Constants } from "./constants";
import { ICommand } from "./interfaces";
import { GalaxyToolsExpadedDocumentContentProvider } from "./providers/contentProvider";
import { GalaxyToolsExpandedDocumentContentProvider } from "./providers/contentProvider";
import { AutoCloseTagResult, activateTagClosing } from "./tagClosing";
import { changeUriScheme, cloneRange, getCommands } from "./utils";
import { DirectoryTreeItem } from "./views/common";

export namespace Commands {
export const AUTO_CLOSE_TAGS: ICommand = getCommands("completion.autoCloseTags");
export const GENERATE_TEST: ICommand = getCommands("generate.tests");
export const GENERATE_TESTS: ICommand = getCommands("generate.tests");
export const UPDATE_TESTS: ICommand = getCommands("update.tests");
export const GENERATE_COMMAND: ICommand = getCommands("generate.command");
export const SORT_SINGLE_PARAM_ATTRS: ICommand = getCommands("sort.singleParamAttributes");
export const SORT_DOCUMENT_PARAMS_ATTRS: ICommand = getCommands("sort.documentParamsAttributes");
Expand All @@ -43,6 +44,10 @@ interface GeneratedSnippetResult {
replace_range: Range | null;
error_message: string;
}
interface WorkspaceEditResult {
edits: ReplaceTextRangeResult[];
error_message: string;
}

interface ReplaceTextRangeResult {
text: string;
Expand All @@ -63,6 +68,8 @@ export function setupCommands(client: LanguageClient, context: ExtensionContext)

setupGenerateTestCases(client, context);

setupUpdateTestCases(client, context);

setupGenerateCommandSection(client, context);

setupSortSingleParamAttributes(client, context);
Expand Down Expand Up @@ -124,9 +131,16 @@ function setupGenerateCommandSection(client: LanguageClient, context: ExtensionC

function setupGenerateTestCases(client: LanguageClient, context: ExtensionContext) {
const generateTest = async () => {
requestInsertSnippet(client, Commands.GENERATE_TEST.external);
requestInsertSnippet(client, Commands.GENERATE_TESTS.external);
};
context.subscriptions.push(commands.registerCommand(Commands.GENERATE_TESTS.internal, generateTest));
}

function setupUpdateTestCases(client: LanguageClient, context: ExtensionContext) {
const updateTests = async () => {
requestWorkspaceEdits(client, Commands.UPDATE_TESTS.external);
};
context.subscriptions.push(commands.registerCommand(Commands.GENERATE_TEST.internal, generateTest));
context.subscriptions.push(commands.registerCommand(Commands.UPDATE_TESTS.internal, updateTests));
}

function setupInsertParamReference(client: LanguageClient, context: ExtensionContext) {
Expand Down Expand Up @@ -229,6 +243,38 @@ async function requestInsertSnippet(client: LanguageClient, command: string) {
}
}

async function requestWorkspaceEdits(client: LanguageClient, command: string) {
const activeEditor = window.activeTextEditor;
if (!activeEditor) return;
const isSaved = await ensureDocumentIsSaved(activeEditor);
if (!isSaved) return;
const document = activeEditor.document;
const param = client.code2ProtocolConverter.asTextDocumentIdentifier(document);
const response = (await commands.executeCommand(command, param)) as WorkspaceEditResult;

if (!response || response.error_message) {
if (response.error_message) {
window.showErrorMessage(response.error_message);
}
return;
}
try {
await activeEditor.edit((builder) => {
for (let index = 0; index < response.edits.length; index++) {
const element = response.edits[index];
const range = cloneRange(element.replace_range);
builder.replace(range, element.text);
}
});
// Format the document after the edits
await commands.executeCommand("editor.action.formatDocument");

}
catch (err: any) {
window.showErrorMessage(err);
}
}

async function pickParamReferenceToInsert(client: LanguageClient, command: string, pickerTitle: string = "Select a parameter reference to insert") {
const activeEditor = window.activeTextEditor;
if (!activeEditor) return;
Expand Down Expand Up @@ -311,7 +357,7 @@ async function previewExpandedDocument() {
return;
}
const expandedDocumentUri = convertToExpandedDocumentUri(document.uri);
GalaxyToolsExpadedDocumentContentProvider.getInstance().update(expandedDocumentUri);
GalaxyToolsExpandedDocumentContentProvider.getInstance().update(expandedDocumentUri);
const doc = await workspace.openTextDocument(expandedDocumentUri);
await window.showTextDocument(doc, { preview: false, viewColumn: ViewColumn.Beside });
}
8 changes: 4 additions & 4 deletions client/src/providers/contentProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,16 @@ import { Commands, GeneratedExpandedDocument } from "../commands";
import { Constants } from "../constants";
import { changeUriScheme } from "../utils";

export class GalaxyToolsExpadedDocumentContentProvider implements TextDocumentContentProvider {
private static instance: GalaxyToolsExpadedDocumentContentProvider;
export class GalaxyToolsExpandedDocumentContentProvider implements TextDocumentContentProvider {
private static instance: GalaxyToolsExpandedDocumentContentProvider;

private onDidChangeEmitter = new EventEmitter<Uri>();

private constructor() {}

public static getInstance(): GalaxyToolsExpadedDocumentContentProvider {
public static getInstance(): GalaxyToolsExpandedDocumentContentProvider {
if (!this.instance) {
this.instance = new GalaxyToolsExpadedDocumentContentProvider();
this.instance = new GalaxyToolsExpandedDocumentContentProvider();
}
return this.instance;
}
Expand Down
4 changes: 2 additions & 2 deletions client/src/providers/setup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { ExtensionContext, languages, workspace } from "vscode";
import { LanguageClient } from "vscode-languageclient/node";
import { Constants } from "../constants";
import { GalaxyToolsCodeActionProvider } from "./codeActions";
import { GalaxyToolsExpadedDocumentContentProvider } from "./contentProvider";
import { GalaxyToolsExpandedDocumentContentProvider } from "./contentProvider";

export function setupProviders(client: LanguageClient, context: ExtensionContext) {
const codeActionProvider = new GalaxyToolsCodeActionProvider();
Expand All @@ -12,7 +12,7 @@ export function setupProviders(client: LanguageClient, context: ExtensionContext
})
);

const expandedDocumentProvider = GalaxyToolsExpadedDocumentContentProvider.getInstance();
const expandedDocumentProvider = GalaxyToolsExpandedDocumentContentProvider.getInstance();
context.subscriptions.push(
workspace.registerTextDocumentContentProvider(Constants.EXPAND_DOCUMENT_SCHEMA, expandedDocumentProvider)
);
Expand Down
1 change: 1 addition & 0 deletions server/galaxyls/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
class Commands:
AUTO_CLOSE_TAGS = "gls.completion.autoCloseTags"
GENERATE_TESTS = "gls.generate.tests"
UPDATE_TESTS_PROFILE = "gls.update.tests"
GENERATE_COMMAND = "gls.generate.command"
SORT_SINGLE_PARAM_ATTRS = "gls.sort.singleParamAttributes"
SORT_DOCUMENT_PARAMS_ATTRS = "gls.sort.documentParamsAttributes"
Expand Down
13 changes: 13 additions & 0 deletions server/galaxyls/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@
ParamReferencesResult,
ReplaceTextRangeResult,
TestSuiteInfoResult,
WorkspaceEditResult,
)
from galaxyls.utils import convert_to
from galaxyls.version import GLS_VERSION
Expand Down Expand Up @@ -230,6 +231,18 @@ async def cmd_generate_test(
return None


@language_server.command(Commands.UPDATE_TESTS_PROFILE)
async def cmd_update_test_profile(
server: GalaxyToolsLanguageServer, parameters: CommandParameters
) -> Optional[WorkspaceEditResult]:
"""Updates the test cases to be compatible with the 24.2 profile validation."""
params = convert_to(parameters[0], TextDocumentIdentifier)
document = _get_valid_document(server, params.uri)
if document:
return server.service.update_tests_profile(document)
return None


@language_server.command(Commands.GENERATE_COMMAND)
async def cmd_generate_command(
server: GalaxyToolsLanguageServer, parameters: CommandParameters
Expand Down
10 changes: 9 additions & 1 deletion server/galaxyls/services/language.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
)
from galaxyls.services.tools.document import GalaxyToolXmlDocument
from galaxyls.services.tools.generators.command import GalaxyToolCommandSnippetGenerator
from galaxyls.services.tools.generators.tests import GalaxyToolTestSnippetGenerator
from galaxyls.services.tools.generators.tests import GalaxyToolTestSnippetGenerator, GalaxyToolTestUpdater
from galaxyls.services.tools.iuc import IUCToolParamAttributeSorter
from galaxyls.services.tools.linting import GalaxyToolLinter
from galaxyls.services.tools.macros import MacroDefinitionsProvider
Expand All @@ -48,6 +48,7 @@
from ..types import (
GeneratedSnippetResult,
ReplaceTextRangeResult,
WorkspaceEditResult,
)
from .completion import (
AutoCloseTagResult,
Expand Down Expand Up @@ -141,6 +142,13 @@ def generate_tests(self, document: Document) -> Optional[GeneratedSnippetResult]
generator = GalaxyToolTestSnippetGenerator(tool)
return generator.generate_snippet()

def update_tests_profile(self, document: Document) -> Optional[WorkspaceEditResult]:
"""Generates a workspace edit to update the test cases if they are not
compatible with the 24.2 profile validation."""
tool = GalaxyToolXmlDocument(document)
generator = GalaxyToolTestUpdater(tool)
return generator.generate_workspace_edit()

def generate_command(self, document: Document) -> Optional[GeneratedSnippetResult]:
"""Generates a boilerplate Cheetah code snippet based on the current inputs and outputs
of this tool wrapper."""
Expand Down
6 changes: 3 additions & 3 deletions server/galaxyls/services/tools/document.py
Original file line number Diff line number Diff line change
Expand Up @@ -155,9 +155,9 @@ def get_inputs(self) -> List[XmlElement]:
Returns:
List[XmlElement]: The outputs defined in the document.
"""
outputs = self.find_element(INPUTS)
if outputs:
return outputs.elements
inputs = self.find_element(INPUTS)
if inputs:
return inputs.elements
return []

def get_outputs(self) -> List[XmlElement]:
Expand Down
5 changes: 5 additions & 0 deletions server/galaxyls/services/tools/generators/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
class DisplayableException(Exception):
"""Exception class for displaying error messages in the UI."""

def __init__(self, message: str) -> None:
super().__init__(message)
29 changes: 28 additions & 1 deletion server/galaxyls/services/tools/generators/snippets.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,34 @@
UNDERSCORE,
)
from galaxyls.services.tools.document import GalaxyToolXmlDocument
from galaxyls.types import GeneratedSnippetResult
from galaxyls.services.tools.generators import DisplayableException
from galaxyls.types import GeneratedSnippetResult, ReplaceTextRangeResult, WorkspaceEditResult


class WorkspaceEditsGenerator(ABC):
"""This class is used to generate workspace edits using the information of the tool document."""

def __init__(self, tool_document: GalaxyToolXmlDocument, tabSize: int = 4) -> None:
self.tool_document = tool_document
self.expanded_document = tool_document.get_expanded_tool_document()
self.tabstop_count: int = 0
self.indent_spaces: str = " " * tabSize
super().__init__()

def generate_workspace_edit(self) -> WorkspaceEditResult:
"""Generates a workspace edit using this generator."""
try:
edits = self._build_workspace_edits()
return WorkspaceEditResult(edits)
except DisplayableException as e:
return WorkspaceEditResult.as_error(str(e))

@abstractmethod
def _build_workspace_edits(self) -> List[ReplaceTextRangeResult]:
"""This abstract function should return a list of ReplaceTextRangeResult
with the generated workspace edits.
"""
pass


class SnippetGenerator(ABC):
Expand Down
Loading