From bcdad65b894ac0c675513e126e81d142256f1932 Mon Sep 17 00:00:00 2001 From: Marcin Tojek Date: Fri, 28 Feb 2025 14:37:31 +0100 Subject: [PATCH 1/2] fix: locate Terraform entrypoint file --- .../TemplateVersionEditorPage.test.tsx | 107 +++++++++++++++++- .../TemplateVersionEditorPage.tsx | 29 ++++- 2 files changed, 132 insertions(+), 4 deletions(-) diff --git a/site/src/pages/TemplateVersionEditorPage/TemplateVersionEditorPage.test.tsx b/site/src/pages/TemplateVersionEditorPage/TemplateVersionEditorPage.test.tsx index 07b1485eef770..e10ed1067beaa 100644 --- a/site/src/pages/TemplateVersionEditorPage/TemplateVersionEditorPage.test.tsx +++ b/site/src/pages/TemplateVersionEditorPage/TemplateVersionEditorPage.test.tsx @@ -22,9 +22,12 @@ import { waitForLoaderToBeRemoved, } from "testHelpers/renderHelpers"; import { server } from "testHelpers/server"; +import type { FileTree } from "utils/filetree"; import type { MonacoEditorProps } from "./MonacoEditor"; import { Language } from "./PublishTemplateVersionDialog"; -import TemplateVersionEditorPage from "./TemplateVersionEditorPage"; +import TemplateVersionEditorPage, { + findEntrypointFile, +} from "./TemplateVersionEditorPage"; const { API } = apiModule; @@ -409,3 +412,105 @@ function renderEditorPage(queryClient: QueryClient) { , ); } + +describe("Find entrypoint", () => { + it("empty tree", () => { + const ft: FileTree = {}; + const mainFile = findEntrypointFile(ft); + expect(mainFile).toBeUndefined(); + }); + it("flat structure, main.tf in root", () => { + const ft: FileTree = { + "aaa.tf": "hello", + "bbb.tf": "world", + "main.tf": "foobar", + "nnn.tf": "foobaz", + }; + + const mainFile = findEntrypointFile(ft); + expect(mainFile).toBe("main.tf"); + }); + it("flat structure, no main.tf", () => { + const ft: FileTree = { + "aaa.tf": "hello", + "bbb.tf": "world", + "ccc.tf": "foobaz", + "nnn.tf": "foobaz", + }; + + const mainFile = findEntrypointFile(ft); + expect(mainFile).toBe("nnn.tf"); + }); + it("with dirs, single main.tf", () => { + const ft: FileTree = { + "aaa-dir": { + "aaa.tf": "hello", + "bbb.tf": "world", + }, + "bbb-dir": { + "aaa.tf": "hello", + "bbb.tf": "world", + }, + "main.tf": "foobar", + "nnn.tf": "foobaz", + }; + + const mainFile = findEntrypointFile(ft); + expect(mainFile).toBe("main.tf"); + }); + it("with dirs, multiple main.tf's", () => { + const ft: FileTree = { + "aaa-dir": { + "aaa.tf": "hello", + "bbb.tf": "world", + "main.tf": "foobar", + }, + "bbb-dir": { + "aaa.tf": "hello", + "bbb.tf": "world", + "main.tf": "foobar", + }, + "ccc-dir": { + "aaa.tf": "hello", + "bbb.tf": "world", + }, + "main.tf": "foobar", + "nnn.tf": "foobaz", + "zzz-dir": { + "aaa.tf": "hello", + "bbb.tf": "world", + "main.tf": "foobar", + }, + }; + + const mainFile = findEntrypointFile(ft); + expect(mainFile).toBe("main.tf"); + }); + it("with dirs, multiple main.tf, no main.tf in root", () => { + const ft: FileTree = { + "aaa-dir": { + "aaa.tf": "hello", + "bbb.tf": "world", + "main.tf": "foobar", + }, + "bbb-dir": { + "aaa.tf": "hello", + "bbb.tf": "world", + "main.tf": "foobar", + }, + "ccc-dir": { + "aaa.tf": "hello", + "bbb.tf": "world", + }, + "nnn.tf": "foobaz", + "zzz-dir": { + "aaa.tf": "hello", + "bbb.tf": "world", + "main.tf": "foobar", + }, + }; + + const mainFile = findEntrypointFile(ft); + expect(mainFile).toBe("aaa-dir/main.tf"); + }); +}); diff --git a/site/src/pages/TemplateVersionEditorPage/TemplateVersionEditorPage.tsx b/site/src/pages/TemplateVersionEditorPage/TemplateVersionEditorPage.tsx index b3090eb6d3f47..0158c872aed50 100644 --- a/site/src/pages/TemplateVersionEditorPage/TemplateVersionEditorPage.tsx +++ b/site/src/pages/TemplateVersionEditorPage/TemplateVersionEditorPage.tsx @@ -90,7 +90,7 @@ export const TemplateVersionEditorPage: FC = () => { // File navigation // It can be undefined when a selected file is deleted const activePath: string | undefined = - searchParams.get("path") ?? findInitialFile(fileTree ?? {}); + searchParams.get("path") ?? findEntrypointFile(fileTree ?? {}); const onActivePathChange = (path: string | undefined) => { if (path) { searchParams.set("path", path); @@ -357,10 +357,33 @@ const publishVersion = async (options: { return Promise.all(publishActions); }; -const findInitialFile = (fileTree: FileTree): string | undefined => { +const defaultMainTerraformFile = "main.tf"; + +// findEntrypointFile function locates the entrypoint file to open in the Editor. +// It browses the filetree following these steps: +// 1. If "main.tf" exists in root, return it. +// 2. Traverse through sub-directories. +// 3. If "main.tf" exists in a sub-directory, skip further browsing, and return the path. +// 4. If "main.tf" was not found, return the last reviewed "".tf" file. +export const findEntrypointFile = (fileTree: FileTree): string | undefined => { let initialFile: string | undefined; - traverse(fileTree, (content, filename, path) => { + if (Object.keys(fileTree).find((key) => key === defaultMainTerraformFile)) { + return defaultMainTerraformFile; + } + + let skip = false; + traverse(fileTree, (_, filename, path) => { + if (skip) { + return; + } + + if (filename === defaultMainTerraformFile) { + initialFile = path; + skip = true; + return; + } + if (filename.endsWith(".tf")) { initialFile = path; } From 86761b0da4858551ed7e5c946566396799980643 Mon Sep 17 00:00:00 2001 From: Marcin Tojek Date: Fri, 28 Feb 2025 15:05:29 +0100 Subject: [PATCH 2/2] sorting --- .../TemplateVersionEditorPage.test.tsx | 22 +++++++++++++++++++ site/src/utils/filetree.test.ts | 2 +- site/src/utils/filetree.ts | 4 +++- 3 files changed, 26 insertions(+), 2 deletions(-) diff --git a/site/src/pages/TemplateVersionEditorPage/TemplateVersionEditorPage.test.tsx b/site/src/pages/TemplateVersionEditorPage/TemplateVersionEditorPage.test.tsx index e10ed1067beaa..684272503d01a 100644 --- a/site/src/pages/TemplateVersionEditorPage/TemplateVersionEditorPage.test.tsx +++ b/site/src/pages/TemplateVersionEditorPage/TemplateVersionEditorPage.test.tsx @@ -510,6 +510,28 @@ describe("Find entrypoint", () => { }, }; + const mainFile = findEntrypointFile(ft); + expect(mainFile).toBe("aaa-dir/main.tf"); + }); + it("with dirs, multiple main.tf, unordered file tree", () => { + const ft: FileTree = { + "ccc-dir": { + "aaa.tf": "hello", + "bbb.tf": "world", + "main.tf": "foobar", + }, + "aaa-dir": { + "aaa.tf": "hello", + "bbb.tf": "world", + "main.tf": "foobar", + }, + "zzz-dir": { + "aaa.tf": "hello", + "bbb.tf": "world", + "main.tf": "foobar", + }, + }; + const mainFile = findEntrypointFile(ft); expect(mainFile).toBe("aaa-dir/main.tf"); }); diff --git a/site/src/utils/filetree.test.ts b/site/src/utils/filetree.test.ts index 21746baa6a54c..e4aadaabbe424 100644 --- a/site/src/utils/filetree.test.ts +++ b/site/src/utils/filetree.test.ts @@ -122,6 +122,6 @@ test("traverse() go trough all the file tree files", () => { traverse(fileTree, (_content, _filename, fullPath) => { filePaths.push(fullPath); }); - const expectedFilePaths = ["main.tf", "images", "images/java.Dockerfile"]; + const expectedFilePaths = ["images", "images/java.Dockerfile", "main.tf"]; expect(filePaths).toEqual(expectedFilePaths); }); diff --git a/site/src/utils/filetree.ts b/site/src/utils/filetree.ts index 757ed133e55f7..2f7d8ea84533b 100644 --- a/site/src/utils/filetree.ts +++ b/site/src/utils/filetree.ts @@ -96,7 +96,9 @@ export const traverse = ( ) => void, parent?: string, ) => { - for (const [filename, content] of Object.entries(fileTree)) { + for (const [filename, content] of Object.entries(fileTree).sort(([a], [b]) => + a.localeCompare(b), + )) { const fullPath = parent ? `${parent}/${filename}` : filename; callback(content, filename, fullPath); if (typeof content === "object") { pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy