You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
To improve code organization and ease of maintenance, I think the TypeSpecValidation code should be refactored to have each logical rule in a separate class, like the following code sample.
Feel free to change the design as you see fit. Don't treat the interfaces below as the final word, they were just a rough sketch.
But I think the design should have some elements of:
A Rule base class / interface
A RuleResult with at least:
Success (boolean)
Output message
Always optional
Always displayed by rule engine on success or fail
Error message
If success, must be empty
If fail, must be non-null and displayed by rule engine
An ordered list of Rule instances that will be executed by the rule engine
interfaceRule{readonlyname: string;readonlydescription: string;execute(folder: string): Promise<RuleResult>;}interfaceRuleResult{readonlysuccess: boolean;readonlyoutput?: string;readonlyerror?: string;}classNpmPrefixRuleimplementsRule{readonlyname="NpmPrefix";readonlydescription="Verify spec is using root level package.json";asyncexecute(folder: string): Promise<RuleResult>{letexpected_npm_prefix=process.cwd();constactual_npm_prefix=(awaitrunCmd(`npm prefix`,folder)).trim();letsuccess=true;letoutput="Expected npm prefix: "+expected_npm_prefix+"\n"+"Actual npm prefix: "+actual_npm_prefix;leterror: string;if(expected_npm_prefix!==actual_npm_prefix){success=false;error="TypeSpec folders MUST NOT contain a package.json, and instead MUST rely on the package.json at repo root"}return{success: success,output: output,error: error}}}classCompileRuleimplementsRule{readonlyname="Compile";readonlydescription="Compile TypeSpec"asyncexecute(folder: string): Promise<RuleResult>{letsuccess=true;letoutput="";leterror: string;if(awaitcheckFileExists(path.join(folder,"main.tsp"))){output+=awaitrunCmd(`npx --no tsp compile . --warn-as-error`,folder);// TODO: If command returns nonzero exit, set success=false and append to error}if(awaitcheckFileExists(path.join(folder,"client.tsp"))){output+=awaitrunCmd(`npx --no tsp compile client.tsp --no-emit --warn-as-error`,folder);// TODO: Set success=false if command returns nonzero exit}return{success: success,output: output,error: error,}}}classGitDiffRuleimplementsRule{readonlyname="GitDiff";readonlydescription="Checks if previous rules resulted in a git diff"asyncexecute(folder: string): Promise<RuleResult>{constgit=simpleGit();letgitStatusIsClean=await(awaitgit.status(["--porcelain"])).isClean();letsuccess=true;leterror: string;if(!gitStatusIsClean){success=false;error+=awaitgit.status();error+=awaitgit.diff();}return{success: success,error: error}}}asyncfunctionmain(folder: string){letrules=[newNpmPrefixRule(),newCompileRule(),newGitDiffRule(),];letsuccess=true;for(leti=0;i<rules.length;i++){construle=rules[i];console.log("Executing rule: "+rule.name);constresult=awaitrule.execute(folder);console.log(result.output);if(!result.success){success=false;}}if(!success){exit(1);}}
The text was updated successfully, but these errors were encountered:
mikeharder
changed the title
[TypeSpecValidation] Refactor each rule into a separate "Rule" class
[TypeSpec Validation] Refactor each rule into a separate "Rule" class
Jul 26, 2023
To improve code organization and ease of maintenance, I think the TypeSpecValidation code should be refactored to have each logical rule in a separate class, like the following code sample.
Feel free to change the design as you see fit. Don't treat the interfaces below as the final word, they were just a rough sketch.
But I think the design should have some elements of:
Rule
base class / interfaceRuleResult
with at least:The text was updated successfully, but these errors were encountered: