@@ -32,6 +32,10 @@ const PACKAGE_ARG_REGEX = /^package=/;
32
32
const EXCLUDE_DECLARATION_DIR_REGEX = / ^ e x c l u d e D e c l a r a t i o n D i r = / ;
33
33
const DECLARATION_FILE_REGEX = / \. d \. t s $ / ;
34
34
35
+ // Configuration for batching and fallback
36
+ const MAX_FILES_FOR_TARGETED_CHECK = 20 ; // Fallback to full check if more files
37
+ const BATCH_SIZE = 10 ; // Process files in batches of this size
38
+
35
39
void ( async ( ) => {
36
40
const args = process . argv . slice ( 2 ) ;
37
41
const {
@@ -45,27 +49,94 @@ void (async () => {
45
49
}
46
50
47
51
const packageRootDir = await getPackage ( packageArg ) ;
48
- const updatedArgs = removePackageSegment ( remainingArgs , packageRootDir ) ;
49
- const argsStr = updatedArgs . join ( " " ) ;
52
+ const changedFiles = removePackageSegment ( remainingArgs , packageRootDir ) ;
50
53
51
- const excludedDeclarationDirs = getExcludedDeclarationDirs (
52
- excludeDeclarationDirArg
54
+ // Filter to only TypeScript files
55
+ const tsFiles = changedFiles . filter ( file =>
56
+ / \. ( t s | t s x ) $ / . test ( file ) && ! DECLARATION_FILE_REGEX . test ( file )
53
57
) ;
58
+
59
+ console . log ( `Type checking ${ tsFiles . length } changed TypeScript files...` ) ;
60
+
61
+ if ( tsFiles . length === 0 ) {
62
+ console . log ( "No TypeScript files to check." ) ;
63
+ exit ( 0 ) ;
64
+ }
65
+
66
+ // Decide strategy based on number of files
67
+ if ( tsFiles . length > MAX_FILES_FOR_TARGETED_CHECK ) {
68
+ console . log ( `Too many files (${ tsFiles . length } > ${ MAX_FILES_FOR_TARGETED_CHECK } ), running full type check...` ) ;
69
+ await runFullTypeCheck ( packageRootDir , excludeDeclarationDirArg ) ;
70
+ } else {
71
+ console . log ( `Running targeted type check on ${ tsFiles . length } files...` ) ;
72
+ await runTargetedTypeCheck ( packageRootDir , tsFiles , excludeDeclarationDirArg ) ;
73
+ }
74
+ } ) ( ) ;
75
+
76
+ /**
77
+ * Run full type check on the entire project
78
+ */
79
+ async function runFullTypeCheck ( packageRootDir , excludeDeclarationDirArg ) {
80
+ const packageRootDirAbsolute = join ( SUPERSET_ROOT , packageRootDir ) ;
81
+ const tsConfig = getTsConfig ( packageRootDirAbsolute ) ;
82
+ // Use incremental compilation for better caching
83
+ const command = `--noEmit --allowJs --incremental --project ${ tsConfig } ` ;
84
+
85
+ await executeTypeCheck ( packageRootDirAbsolute , command ) ;
86
+ }
87
+
88
+ /**
89
+ * Run targeted type check on specific files, with batching
90
+ */
91
+ async function runTargetedTypeCheck ( packageRootDir , tsFiles , excludeDeclarationDirArg ) {
92
+ const excludedDeclarationDirs = getExcludedDeclarationDirs ( excludeDeclarationDirArg ) ;
54
93
let declarationFiles = await getFilesRecursively (
55
- packageRootDir ,
94
+ join ( SUPERSET_ROOT , packageRootDir ) ,
56
95
DECLARATION_FILE_REGEX ,
57
96
excludedDeclarationDirs
58
97
) ;
59
98
declarationFiles = removePackageSegment ( declarationFiles , packageRootDir ) ;
60
- const declarationFilesStr = declarationFiles . join ( " " ) ;
61
99
62
100
const packageRootDirAbsolute = join ( SUPERSET_ROOT , packageRootDir ) ;
63
101
const tsConfig = getTsConfig ( packageRootDirAbsolute ) ;
64
- const command = `--noEmit --allowJs --composite false --project ${ tsConfig } ${ argsStr } ${ declarationFilesStr } ` ;
65
102
103
+ // Process files in batches to avoid command line length limits
104
+ const batches = [ ] ;
105
+ for ( let i = 0 ; i < tsFiles . length ; i += BATCH_SIZE ) {
106
+ batches . push ( tsFiles . slice ( i , i + BATCH_SIZE ) ) ;
107
+ }
108
+
109
+ let hasErrors = false ;
110
+
111
+ for ( const [ batchIndex , batch ] of batches . entries ( ) ) {
112
+ if ( batches . length > 1 ) {
113
+ console . log ( `\nProcessing batch ${ batchIndex + 1 } /${ batches . length } (${ batch . length } files)...` ) ;
114
+ }
115
+
116
+ const argsStr = batch . join ( " " ) ;
117
+ const declarationFilesStr = declarationFiles . join ( " " ) ;
118
+ // For targeted checks, keep composite false since we're passing specific files
119
+ const command = `--noEmit --allowJs --composite false --project ${ tsConfig } ${ argsStr } ${ declarationFilesStr } ` ;
120
+
121
+ try {
122
+ await executeTypeCheck ( packageRootDirAbsolute , command ) ;
123
+ } catch ( error ) {
124
+ hasErrors = true ;
125
+ // Continue processing other batches to show all errors
126
+ }
127
+ }
128
+
129
+ if ( hasErrors ) {
130
+ exit ( 1 ) ;
131
+ }
132
+ }
133
+
134
+ /**
135
+ * Execute the TypeScript type check command
136
+ */
137
+ async function executeTypeCheck ( packageRootDirAbsolute , command ) {
66
138
try {
67
139
chdir ( packageRootDirAbsolute ) ;
68
- // Please ensure that tscw-config is installed in the package being type-checked.
69
140
const tscw = packageRequire ( "tscw-config" ) ;
70
141
const child = await tscw `${ command } ` ;
71
142
@@ -77,14 +148,16 @@ void (async () => {
77
148
console . error ( child . stderr ) ;
78
149
}
79
150
80
- exit ( child . exitCode ) ;
151
+ if ( child . exitCode !== 0 ) {
152
+ throw new Error ( `Type check failed with exit code ${ child . exitCode } ` ) ;
153
+ }
81
154
} catch ( e ) {
82
- console . error ( "Failed to execute type checking:" , e ) ;
83
- console . error ( "Package:" , packageRootDir ) ;
155
+ console . error ( "Failed to execute type checking:" , e . message ) ;
84
156
console . error ( "Command:" , `tscw ${ command } ` ) ;
85
- exit ( 1 ) ;
157
+ throw e ;
86
158
}
87
- } ) ( ) ;
159
+ }
160
+
88
161
89
162
/**
90
163
*
@@ -112,7 +185,6 @@ function shouldExcludeDir(fullPath, excludedDirs) {
112
185
*
113
186
* @returns {Promise<string[]> }
114
187
*/
115
-
116
188
async function getFilesRecursively ( dir , regex , excludedDirs ) {
117
189
try {
118
190
const files = await readdir ( dir , { withFileTypes : true } ) ;
@@ -186,7 +258,6 @@ function getExcludedDeclarationDirs(excludeDeclarationDirArg) {
186
258
* @param {RegExp[] } regexes
187
259
* @returns {{ matchedArgs: (string | undefined)[], remainingArgs: string[] } }
188
260
*/
189
-
190
261
function extractArgs ( args , regexes ) {
191
262
/**
192
263
* @type {(string | undefined)[] }
0 commit comments