diff --git a/actions-languageservice/src/complete.expressions.test.ts b/actions-languageservice/src/complete.expressions.test.ts index 8e18cba..274fb45 100644 --- a/actions-languageservice/src/complete.expressions.test.ts +++ b/actions-languageservice/src/complete.expressions.test.ts @@ -1,31 +1,19 @@ -import {data} from "@github/actions-expressions/."; +import {data} from "@github/actions-expressions"; import {complete, getExpressionInput} from "./complete"; import {ContextProviderConfig} from "./context-providers/config"; import {getPositionFromCursor} from "./test-utils/cursor-position"; const contextProviderConfig: ContextProviderConfig = { - async getContext(contexts: string[]): Promise { - const context = new data.Dictionary(); - - for (const contextName of contexts) { - switch (contextName) { - case "github": - context.add( - "github", - new data.Dictionary({ - key: "event", - value: new data.StringData("push") - }) - ); - break; - - default: - context.add(contextName, new data.Dictionary()); - break; - } + getContext: async (context: string) => { + switch (context) { + case "github": + return new data.Dictionary({ + key: "event", + value: new data.StringData("push") + }); } - return context; + return undefined; } }; @@ -102,5 +90,13 @@ describe("expressions", () => { expect(result.map(x => x.label)).toEqual(["event"]); }); + + it("using default context provider", async () => { + const input = + "on: push\njobs:\n build:\n runs-on: ubuntu-latest\n environment:\n url: ${{ runner.| }}\n steps:\n - run: echo"; + const result = await complete(...getPositionFromCursor(input), undefined, contextProviderConfig); + + expect(result.map(x => x.label)).toEqual(["arch", "name", "os", "temp", "tool_cache"]); + }); }); }); diff --git a/actions-languageservice/src/complete.ts b/actions-languageservice/src/complete.ts index 160b8a4..9722fa1 100644 --- a/actions-languageservice/src/complete.ts +++ b/actions-languageservice/src/complete.ts @@ -1,4 +1,4 @@ -import {complete as completeExpression, data} from "@github/actions-expressions"; +import {complete as completeExpression} from "@github/actions-expressions"; import {isSequence, isString, parseWorkflow} from "@github/actions-workflow-parser"; import {CLOSE_EXPRESSION, OPEN_EXPRESSION} from "@github/actions-workflow-parser/templates/template-constants"; import {TemplateToken} from "@github/actions-workflow-parser/templates/tokens/index"; @@ -9,6 +9,7 @@ import {File} from "@github/actions-workflow-parser/workflows/file"; import {Position, TextDocument} from "vscode-languageserver-textdocument"; import {CompletionItem} from "vscode-languageserver-types"; import {ContextProviderConfig} from "./context-providers/config"; +import {getContext} from "./context-providers/default"; import {nullTrace} from "./nulltrace"; import {findInnerTokenAndParent} from "./utils/find-token"; import {transform} from "./utils/transform"; @@ -61,8 +62,7 @@ export async function complete( const expressionInput = (getExpressionInput(currentInput, relCharPos) || "").trim(); - const context = - (await contextProviderConfig?.getContext(innerToken.definition!.readerContext)) || new data.Dictionary(); + const context = await getContext(innerToken.definition?.readerContext || [], contextProviderConfig); return completeExpression(expressionInput, context, []); } diff --git a/actions-languageservice/src/context-providers/config.ts b/actions-languageservice/src/context-providers/config.ts index 1b4e37e..49f61dd 100644 --- a/actions-languageservice/src/context-providers/config.ts +++ b/actions-languageservice/src/context-providers/config.ts @@ -2,9 +2,9 @@ import {data} from "@github/actions-expressions"; import {Dictionary} from "@github/actions-expressions/data/dictionary"; import {ExpressionData, Pair} from "@github/actions-expressions/data/expressiondata"; -export interface ContextProviderConfig { - getContext(contexts: string[]): Promise; -} +export type ContextProviderConfig = { + getContext: (name: string) => Promise; +}; /** * DynamicDictionary is a dictionary that returns an empty DynamicDictionary for diff --git a/actions-languageservice/src/context-providers/default.ts b/actions-languageservice/src/context-providers/default.ts new file mode 100644 index 0000000..cc964e9 --- /dev/null +++ b/actions-languageservice/src/context-providers/default.ts @@ -0,0 +1,48 @@ +import {data} from "@github/actions-expressions"; +import {ContextProviderConfig} from "./config"; + +export async function getContext(names: string[], config: ContextProviderConfig | undefined): Promise { + const context = new data.Dictionary(); + + for (const contextName of names) { + let value: data.Dictionary | undefined; + + value = await getDefaultContext(contextName); + + if (!value) { + value = await config?.getContext(contextName); + } + + if (!value) { + value = new data.Dictionary(); + } + + context.add(contextName, value); + } + + return context; +} + +async function getDefaultContext(name: string): Promise { + switch (name) { + case "runner": + return objectToDictionary({ + os: "Linux", + arch: "X64", + name: "GitHub Actions 2", + tool_cache: "/opt/hostedtoolcache", + temp: "/home/runner/work/_temp" + }); + } + + return undefined; +} + +function objectToDictionary(object: {[key: string]: string}): data.Dictionary { + const dictionary = new data.Dictionary(); + for (const key in object) { + dictionary.add(key, new data.StringData(object[key])); + } + + return dictionary; +} diff --git a/actions-languageservice/src/context-providers/runner.ts b/actions-languageservice/src/context-providers/runner.ts new file mode 100644 index 0000000..e69de29