1- import { exec } from "child_process" ;
2- import debug from "debug" ;
3- import { access } from "fs/promises" ;
41import { parseArgs , ParseArgsConfig } from "node:util" ;
5- import path from "path" ;
6- import { simpleGit } from "simple-git" ;
7-
8- debug . enable ( "simple-git" ) ;
9-
10- async function runCmd ( cmd : string , cwd : string ) {
11- console . log ( `run command:${ cmd } ` ) ;
12- const { err, stdout, stderr } = ( await new Promise ( ( res ) =>
13- exec (
14- cmd ,
15- { encoding : "utf8" , maxBuffer : 1024 * 1024 * 64 , cwd : cwd } ,
16- ( err : unknown , stdout : unknown , stderr : unknown ) =>
17- res ( { err : err , stdout : stdout , stderr : stderr } )
18- )
19- ) ) as any ;
20- let resultString = stderr + stdout ;
21- console . log ( "Stdout output:" ) ;
22- console . log ( stdout ) ;
23- if ( stderr ) {
24- console . log ( "Stderr output:" ) ;
25- console . log ( stderr ) ;
26- }
27- if ( stderr || err ) {
28- throw new Error ( err ) ;
29- }
30- return resultString as string ;
31- }
32-
33- async function checkFileExists ( file : string ) {
34- return access ( file )
35- . then ( ( ) => true )
36- . catch ( ( ) => false ) ;
37- }
2+ import { CompileRule } from "./rules/compile.js" ;
3+ import { FormatRule } from "./rules/format.js" ;
4+ import { GitDiffRule } from "./rules/git-diff.js" ;
5+ import { NpmPrefixRule } from "./rules/npm-prefix.js" ;
386
397export async function main ( ) {
408 const args = process . argv . slice ( 2 ) ;
@@ -48,39 +16,22 @@ export async function main() {
4816 const folder = parsedArgs . positionals [ 0 ] ;
4917 console . log ( "Running TypeSpecValidation on folder:" , folder ) ;
5018
51- // Verify all specs are using root level pacakge.json
52- let expected_npm_prefix = process . cwd ( ) ;
53- const actual_npm_prefix = ( await runCmd ( `npm prefix` , folder ) ) . trim ( ) ;
54- if ( expected_npm_prefix !== actual_npm_prefix ) {
55- console . log (
56- "ERROR: TypeSpec folders MUST NOT contain a package.json, and instead MUST rely on the package.json at repo root."
57- ) ;
58- throw new Error (
59- "Expected npm prefix: " + expected_npm_prefix + "\nActual npm prefix: " + actual_npm_prefix
60- ) ;
61- }
62-
63- // Spec compilation check
64- if ( await checkFileExists ( path . join ( folder , "main.tsp" ) ) ) {
65- await runCmd ( `npx --no tsp compile . --warn-as-error` , folder ) ;
19+ let rules = [ new NpmPrefixRule ( ) , new CompileRule ( ) , new FormatRule ( ) , new GitDiffRule ( ) ] ;
20+ let success = true ;
21+ for ( let i = 0 ; i < rules . length ; i ++ ) {
22+ const rule = rules [ i ] ;
23+ console . log ( "\nExecuting rule: " + rule . name ) ;
24+ const result = await rule . execute ( folder ) ;
25+ if ( result . stdOutput ) console . log ( result . stdOutput ) ;
26+ if ( ! result . success ) {
27+ success = false ;
28+ console . log ( "Rule " + rule . name + " failed" ) ;
29+ if ( result . errorOutput ) console . log ( result . errorOutput ) ;
30+ }
6631 }
67- if ( await checkFileExists ( path . join ( folder , "client.tsp" ) ) ) {
68- await runCmd ( `npx --no tsp compile client.tsp --no-emit --warn-as-error` , folder ) ;
69- }
70-
71- // Format parent folder to include shared files
72- await runCmd ( `npx tsp format ../**/*.tsp` , folder ) ;
7332
74- // Verify generated swagger file is in sync with one on disk
75- const git = simpleGit ( ) ;
76- let gitStatusIsClean = await ( await git . status ( [ "--porcelain" ] ) ) . isClean ( ) ;
77- if ( ! gitStatusIsClean ) {
78- let gitStatus = await git . status ( ) ;
79- let gitDiff = await git . diff ( ) ;
80- console . log ( "git status" ) ;
81- console . log ( gitStatus ) ;
82- console . log ( "git diff" ) ;
83- console . log ( gitDiff ) ;
84- throw new Error ( "Generated swagger file does not match swagger file on disk" ) ;
33+ if ( ! success ) {
34+ return process . exit ( 1 ) ;
8535 }
36+ return ;
8637}
0 commit comments