From 9c45b78d74a7ee71927a66603e1836519cb262f0 Mon Sep 17 00:00:00 2001 From: Albert Date: Fri, 25 Aug 2023 12:46:55 -0700 Subject: [PATCH 1/4] folder structure --- .../src/rules/folder-structure.ts | 33 +++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/eng/tools/TypeSpecValidation/src/rules/folder-structure.ts b/eng/tools/TypeSpecValidation/src/rules/folder-structure.ts index 785458077e58..225be60c0c1c 100644 --- a/eng/tools/TypeSpecValidation/src/rules/folder-structure.ts +++ b/eng/tools/TypeSpecValidation/src/rules/folder-structure.ts @@ -1,6 +1,8 @@ import { globby } from "globby"; +import path from "path"; import { Rule } from "../rule.js"; import { RuleResult } from "../rule-result.js"; +import { checkFileExists } from "../utils.js"; export class FolderStructureRule implements Rule { readonly name = "FolderStructure"; @@ -18,6 +20,37 @@ export class FolderStructureRule implements Rule { } }); + // Verify top level folder is lower case + let folderStruct = folder.split(path.sep) + if (folderStruct[1].match(/[A-Z]/g)) { + success = false; + errorOutput += `Invalid folder name. Folders under specification/ must be lower case.\n` + } + + // Verify second level folder is capitalized after each '.' + if (/(^|\. *)([a-z])/g.test(folderStruct[2]) && !["data-plane", "resource-manager"].includes(folderStruct[2])) { + success = false; + errorOutput += `Invalid folder name. Folders under specification/${folderStruct[1]} must be capitalized after each '.'\n` + } + + // Verify 'Shared' follows 'Management' + if (folderStruct[2].includes("Management") && folderStruct[2].includes("Shared")) { + if (!folderStruct[2].includes("Management.Shared")) { + success = false; + errorOutput += `Invalid folder name. For management libraries with a shared component, 'Shared' should follow 'Management'.` + } + } + + // Verify tspconfig, main.tsp, examples/ + let containsMinStruct = await checkFileExists(path.join(folder, "main.tsp")) && await checkFileExists(path.join(folder, "examples")) + if (!folderStruct[2].includes("Shared")) { + containsMinStruct = containsMinStruct && await checkFileExists(path.join(folder, "tspconfig.yaml")) + } + if (!containsMinStruct) { + success = false; + errorOutput += `Invalid folder structure. Package must contain tspconfig.yaml, main.tsp, and examples folder.` + } + return { success: success, stdOutput: stdOutput, From fef875814860d19f9586cab2236f8340e77bfb9d Mon Sep 17 00:00:00 2001 From: Albert Date: Tue, 12 Sep 2023 14:05:26 -0700 Subject: [PATCH 2/4] typespec folder depth limit --- .../src/rules/folder-structure.ts | 38 +++++++++++++------ 1 file changed, 26 insertions(+), 12 deletions(-) diff --git a/eng/tools/TypeSpecValidation/src/rules/folder-structure.ts b/eng/tools/TypeSpecValidation/src/rules/folder-structure.ts index 225be60c0c1c..bc6f8959e544 100644 --- a/eng/tools/TypeSpecValidation/src/rules/folder-structure.ts +++ b/eng/tools/TypeSpecValidation/src/rules/folder-structure.ts @@ -21,34 +21,48 @@ export class FolderStructureRule implements Rule { }); // Verify top level folder is lower case - let folderStruct = folder.split(path.sep) + let folderStruct = folder.split(path.sep); if (folderStruct[1].match(/[A-Z]/g)) { success = false; - errorOutput += `Invalid folder name. Folders under specification/ must be lower case.\n` + errorOutput += `Invalid folder name. Folders under specification/ must be lower case.\n`; } - + + let packageFolder = folderStruct[folderStruct.length - 1]; + + // Verify package folder is at most 3 levels deep + if (folderStruct.length > 4) { + success = false; + errorOutput += `Please limit TypeSpec folder depth to 3 levels or less`; + } + // Verify second level folder is capitalized after each '.' - if (/(^|\. *)([a-z])/g.test(folderStruct[2]) && !["data-plane", "resource-manager"].includes(folderStruct[2])) { + if ( + /(^|\. *)([a-z])/g.test(packageFolder) && + !["data-plane", "resource-manager"].includes(packageFolder) + ) { success = false; - errorOutput += `Invalid folder name. Folders under specification/${folderStruct[1]} must be capitalized after each '.'\n` + errorOutput += `Invalid folder name. Folders under specification/${folderStruct[1]} must be capitalized after each '.'\n`; } // Verify 'Shared' follows 'Management' - if (folderStruct[2].includes("Management") && folderStruct[2].includes("Shared")) { - if (!folderStruct[2].includes("Management.Shared")) { + if (packageFolder.includes("Management") && packageFolder.includes("Shared")) { + if (!packageFolder.includes("Management.Shared")) { success = false; - errorOutput += `Invalid folder name. For management libraries with a shared component, 'Shared' should follow 'Management'.` + errorOutput += `Invalid folder name. For management libraries with a shared component, 'Shared' should follow 'Management'.`; } } // Verify tspconfig, main.tsp, examples/ - let containsMinStruct = await checkFileExists(path.join(folder, "main.tsp")) && await checkFileExists(path.join(folder, "examples")) - if (!folderStruct[2].includes("Shared")) { - containsMinStruct = containsMinStruct && await checkFileExists(path.join(folder, "tspconfig.yaml")) + let containsMinStruct = + (await checkFileExists(path.join(folder, "main.tsp"))) && + (await checkFileExists(path.join(folder, "examples"))); + if (!packageFolder.includes("Shared")) { + containsMinStruct = + containsMinStruct && (await checkFileExists(path.join(folder, "tspconfig.yaml"))); } if (!containsMinStruct) { success = false; - errorOutput += `Invalid folder structure. Package must contain tspconfig.yaml, main.tsp, and examples folder.` + errorOutput += `Invalid folder structure. Package must contain tspconfig.yaml, main.tsp, and examples folder.`; } return { From 4155a398e97c709a20c743a1bc4b72e22b5fa674 Mon Sep 17 00:00:00 2001 From: Albert Date: Tue, 12 Sep 2023 14:18:55 -0700 Subject: [PATCH 3/4] main.tsp and client.tsp --- .../TypeSpecValidation/src/rules/folder-structure.ts | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/eng/tools/TypeSpecValidation/src/rules/folder-structure.ts b/eng/tools/TypeSpecValidation/src/rules/folder-structure.ts index bc6f8959e544..01cb0c0c077f 100644 --- a/eng/tools/TypeSpecValidation/src/rules/folder-structure.ts +++ b/eng/tools/TypeSpecValidation/src/rules/folder-structure.ts @@ -54,15 +54,21 @@ export class FolderStructureRule implements Rule { // Verify tspconfig, main.tsp, examples/ let containsMinStruct = - (await checkFileExists(path.join(folder, "main.tsp"))) && - (await checkFileExists(path.join(folder, "examples"))); + (await checkFileExists(path.join(folder, "main.tsp"))) || + (await checkFileExists(path.join(folder, "client.tsp"))); + + if (await checkFileExists(path.join(folder, "main.tsp"))) { + containsMinStruct = + containsMinStruct && (await checkFileExists(path.join(folder, "examples"))); + } + if (!packageFolder.includes("Shared")) { containsMinStruct = containsMinStruct && (await checkFileExists(path.join(folder, "tspconfig.yaml"))); } if (!containsMinStruct) { success = false; - errorOutput += `Invalid folder structure. Package must contain tspconfig.yaml, main.tsp, and examples folder.`; + errorOutput += `Invalid folder structure. Package must contain main.tsp or client.tsp, tspconfig.yaml, and examples folder if there's main.tsp.`; } return { From 5047e15e9fbba0d2e4252d989f17152d3468bd46 Mon Sep 17 00:00:00 2001 From: Albert Date: Tue, 19 Sep 2023 15:28:12 -0700 Subject: [PATCH 4/4] fix windows separator issue --- eng/tools/TypeSpecValidation/src/rules/folder-structure.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/eng/tools/TypeSpecValidation/src/rules/folder-structure.ts b/eng/tools/TypeSpecValidation/src/rules/folder-structure.ts index 01cb0c0c077f..da149bc53f16 100644 --- a/eng/tools/TypeSpecValidation/src/rules/folder-structure.ts +++ b/eng/tools/TypeSpecValidation/src/rules/folder-structure.ts @@ -21,7 +21,7 @@ export class FolderStructureRule implements Rule { }); // Verify top level folder is lower case - let folderStruct = folder.split(path.sep); + let folderStruct = folder.split("/"); if (folderStruct[1].match(/[A-Z]/g)) { success = false; errorOutput += `Invalid folder name. Folders under specification/ must be lower case.\n`;