Compare commits

...

1 Commits

Author SHA1 Message Date
Christopher Schleiden db3896d0aa WIP 2023-04-05 15:17:12 -07:00
6 changed files with 102 additions and 8 deletions
+12 -1
View File
@@ -1,4 +1,4 @@
import {documentLinks, hover, validate, ValidationConfig} from "@actions/languageservice";
import {documentLinks, documentSymbols, hover, validate, ValidationConfig} from "@actions/languageservice";
import {registerLogger, setLogLevel} from "@actions/languageservice/log";
import {clearCache, clearCacheEntry} from "@actions/languageservice/utils/workflow-cache";
import {Octokit} from "@octokit/rest";
@@ -7,6 +7,8 @@ import {
Connection,
DocumentLink,
DocumentLinkParams,
DocumentSymbol,
DocumentSymbolParams,
ExecuteCommandParams,
Hover,
HoverParams,
@@ -72,6 +74,10 @@ export function initConnection(connection: Connection) {
hoverProvider: true,
documentLinkProvider: {
resolveProvider: false
},
documentSymbolProvider: {
label: "GitHub Actions",
workDoneProgress: false
}
}
};
@@ -158,6 +164,11 @@ export function initConnection(connection: Connection) {
return documentLinks(getDocument(documents, textDocument), repoContext?.workspaceUri);
});
connection.onDocumentSymbol(async ({textDocument}: DocumentSymbolParams): Promise<DocumentSymbol[] | null> => {
const repoContext = repos.find(repo => textDocument.uri.startsWith(repo.workspaceUri));
return documentSymbols(getDocument(documents, textDocument), repoContext?.workspaceUri);
});
// Make the text document manager listen on the connection
// for open, change and close text document events
documents.listen(connection);
+70
View File
@@ -0,0 +1,70 @@
import {ErrorPolicy} from "@actions/workflow-parser/model/convert";
import {File} from "@actions/workflow-parser/workflows/file";
import {TextDocument} from "vscode-languageserver-textdocument";
import {DocumentSymbol, SymbolKind} from "vscode-languageserver-types";
import {mapRange} from "./utils/range";
import {fetchOrConvertWorkflowTemplate, fetchOrParseWorkflow} from "./utils/workflow-cache";
export async function documentSymbols(
document: TextDocument,
workspace: string | undefined
): Promise<DocumentSymbol[]> {
const file: File = {
name: document.uri,
content: document.getText()
};
const parsedWorkflow = fetchOrParseWorkflow(file, document.uri);
if (!parsedWorkflow?.value) {
return [];
}
const template = await fetchOrConvertWorkflowTemplate(
parsedWorkflow.context,
parsedWorkflow.value,
document.uri,
undefined,
{
errorPolicy: ErrorPolicy.TryConversion
}
);
if (!template) {
return [];
}
const symbols: DocumentSymbol[] = [];
const onSymbol = DocumentSymbol.create(
"`on` Triggers",
undefined,
SymbolKind.Key,
mapRange(template.events.range),
mapRange(template.events.range)
);
symbols.push(onSymbol);
const jobsSymbol = DocumentSymbol.create(
"Jobs",
undefined,
SymbolKind.Namespace,
mapRange(template.jobs?.[0].id.range),
mapRange(template.jobs?.[0].id.range),
[]
);
symbols.push(jobsSymbol);
for (const job of template.jobs || []) {
const jobSymbol = DocumentSymbol.create(
`Job ${job.name?.toDisplayString() || job.id?.toString()}`,
"detail",
SymbolKind.Class,
mapRange(job.id.range),
mapRange(job.id.range)
);
jobsSymbol.children!.push(jobSymbol);
}
return symbols;
}
+3 -2
View File
@@ -1,7 +1,8 @@
export {complete} from "./complete";
export {ContextProviderConfig} from "./context-providers/config";
export {documentLinks} from "./document-links";
export {documentSymbols} from "./document-symbols";
export {hover} from "./hover";
export {Logger, LogLevel, registerLogger, setLogLevel} from "./log";
export {validate, ValidationConfig, ActionsMetadataProvider} from "./validate";
export {LogLevel, Logger, registerLogger, setLogLevel} from "./log";
export {ActionsMetadataProvider, ValidationConfig, validate} from "./validate";
export {ValueProviderConfig, ValueProviderKind} from "./value-providers/config";
+4 -2
View File
@@ -9,7 +9,7 @@ import {handleTemplateTokenErrors} from "./converter/handle-errors";
import {convertJobs} from "./converter/jobs";
import {convertReferencedWorkflow} from "./converter/referencedWorkflow";
import {isReusableWorkflowJob} from "./type-guards";
import {WorkflowTemplate} from "./workflow-template";
import {EventsConfig, WorkflowTemplate} from "./workflow-template";
export enum ErrorPolicy {
ReturnErrorsOnly,
@@ -73,7 +73,9 @@ export async function convertWorkflowTemplate(
switch (key.value) {
case "on":
result.events = handleTemplateTokenErrors(root, context, {}, () => convertOn(context, item.value));
result.events = handleTemplateTokenErrors(root, context, {range: item.key.range} as EventsConfig, () =>
convertOn(context, item.value)
);
break;
case "jobs":
+10 -3
View File
@@ -23,12 +23,15 @@ export function convertOn(context: TemplateContext, token: TemplateToken): Event
const event = token.assertString("on");
return {
range: token.range,
[event.value]: {}
} as EventsConfig;
}
if (isSequence(token)) {
const result = {} as EventsConfig;
const result = {
range: token.range
} as EventsConfig;
for (const item of token) {
const event = item.assertString("on");
@@ -39,7 +42,9 @@ export function convertOn(context: TemplateContext, token: TemplateToken): Event
}
if (isMapping(token)) {
const result = {} as EventsConfig;
const result = {
range: token.range
} as EventsConfig;
for (const item of token) {
const eventKey = item.key.assertString("event name");
@@ -77,7 +82,9 @@ export function convertOn(context: TemplateContext, token: TemplateToken): Event
}
context.error(token, "Invalid format for 'on'");
return {};
return {
range: token.range
} as EventsConfig;
}
function convertPatternFilter<T extends BranchFilterConfig & TagFilterConfig & PathFilterConfig>(
@@ -6,6 +6,7 @@ import {
StringToken,
TemplateToken
} from "../templates/tokens";
import {TokenRange} from "../templates/tokens/token-range";
export type WorkflowTemplate = {
events: EventsConfig;
@@ -99,6 +100,8 @@ export type ActionStep = BaseStep & {
};
export type EventsConfig = {
range: TokenRange;
schedule?: ScheduleConfig[];
workflow_dispatch?: WorkflowDispatchConfig;
workflow_call?: WorkflowCallConfig;