Skip to content

Commit

Permalink
Improve document detection
Browse files Browse the repository at this point in the history
Detect not only .yml but also .yaml document extensions.
  • Loading branch information
davelopez committed Jun 9, 2024
1 parent a492a62 commit f226f95
Show file tree
Hide file tree
Showing 5 changed files with 101 additions and 42 deletions.
13 changes: 12 additions & 1 deletion client/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
98 changes: 66 additions & 32 deletions client/src/common/utils.ts
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -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));
}

/**
Expand All @@ -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<URI | undefined> {
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<Uri | undefined> {
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<boolean> {
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;
}
}
25 changes: 19 additions & 6 deletions client/src/requests/gxworkflows.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,30 +12,43 @@ import {
TargetWorkflowDocumentParams,
} from "../languageTypes";

const TEST_DOCUMENT_TO_WORKFLOW_DOCUMENT_URI_MAP = new Map<string, Uri>();

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);
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<TResult>(requestIdentifier, requestParams);
return result;
};
Expand Down
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit f226f95

Please sign in to comment.