11import { globby } from "globby" ;
2+ import path from "path" ;
23import { Rule } from "../rule.js" ;
34import { RuleResult } from "../rule-result.js" ;
5+ import { checkFileExists } from "../utils.js" ;
46
57export class FolderStructureRule implements Rule {
68 readonly name = "FolderStructure" ;
@@ -18,6 +20,57 @@ export class FolderStructureRule implements Rule {
1820 }
1921 } ) ;
2022
23+ // Verify top level folder is lower case
24+ let folderStruct = folder . split ( "/" ) ;
25+ if ( folderStruct [ 1 ] . match ( / [ A - Z ] / g) ) {
26+ success = false ;
27+ errorOutput += `Invalid folder name. Folders under specification/ must be lower case.\n` ;
28+ }
29+
30+ let packageFolder = folderStruct [ folderStruct . length - 1 ] ;
31+
32+ // Verify package folder is at most 3 levels deep
33+ if ( folderStruct . length > 4 ) {
34+ success = false ;
35+ errorOutput += `Please limit TypeSpec folder depth to 3 levels or less` ;
36+ }
37+
38+ // Verify second level folder is capitalized after each '.'
39+ if (
40+ / ( ^ | \. * ) ( [ a - z ] ) / g. test ( packageFolder ) &&
41+ ! [ "data-plane" , "resource-manager" ] . includes ( packageFolder )
42+ ) {
43+ success = false ;
44+ errorOutput += `Invalid folder name. Folders under specification/${ folderStruct [ 1 ] } must be capitalized after each '.'\n` ;
45+ }
46+
47+ // Verify 'Shared' follows 'Management'
48+ if ( packageFolder . includes ( "Management" ) && packageFolder . includes ( "Shared" ) ) {
49+ if ( ! packageFolder . includes ( "Management.Shared" ) ) {
50+ success = false ;
51+ errorOutput += `Invalid folder name. For management libraries with a shared component, 'Shared' should follow 'Management'.` ;
52+ }
53+ }
54+
55+ // Verify tspconfig, main.tsp, examples/
56+ let containsMinStruct =
57+ ( await checkFileExists ( path . join ( folder , "main.tsp" ) ) ) ||
58+ ( await checkFileExists ( path . join ( folder , "client.tsp" ) ) ) ;
59+
60+ if ( await checkFileExists ( path . join ( folder , "main.tsp" ) ) ) {
61+ containsMinStruct =
62+ containsMinStruct && ( await checkFileExists ( path . join ( folder , "examples" ) ) ) ;
63+ }
64+
65+ if ( ! packageFolder . includes ( "Shared" ) ) {
66+ containsMinStruct =
67+ containsMinStruct && ( await checkFileExists ( path . join ( folder , "tspconfig.yaml" ) ) ) ;
68+ }
69+ if ( ! containsMinStruct ) {
70+ success = false ;
71+ errorOutput += `Invalid folder structure. Package must contain main.tsp or client.tsp, tspconfig.yaml, and examples folder if there's main.tsp.` ;
72+ }
73+
2174 return {
2275 success : success ,
2376 stdOutput : stdOutput ,
0 commit comments