@@ -5,8 +5,11 @@ var format_usage = `Usage: rescript format <options> [files]
5
5
\`rescript format\` formats the current directory
6
6
` ;
7
7
var child_process = require ( "child_process" ) ;
8
+ var util = require ( "node:util" ) ;
9
+ var asyncExecFile = util . promisify ( child_process . execFile ) ;
8
10
var path = require ( "path" ) ;
9
11
var fs = require ( "fs" ) ;
12
+ var asyncFs = fs . promises ;
10
13
/**
11
14
* @type {arg.stringref }
12
15
*/
@@ -17,6 +20,11 @@ var stdin = { val: undefined };
17
20
*/
18
21
var format = { val : undefined } ;
19
22
23
+ /**
24
+ * @type {arg.boolref }
25
+ */
26
+ var check = { val : undefined } ;
27
+
20
28
/**
21
29
* @type {arg.specs }
22
30
*/
@@ -27,12 +35,16 @@ var specs = [
27
35
`[.res|.resi|.ml|.mli] Read the code from stdin and print
28
36
the formatted code to stdout in ReScript syntax` ,
29
37
] ,
30
- // ml|mli
31
38
[
32
39
"-all" ,
33
40
{ kind : "Unit" , data : { kind : "Unit_set" , data : format } } ,
34
41
"Format the whole project " ,
35
42
] ,
43
+ [
44
+ "-check" ,
45
+ { kind : "Unit" , data : { kind : "Unit_set" , data : check } } ,
46
+ "Check formatting only" ,
47
+ ] ,
36
48
] ;
37
49
var formattedStdExtensions = [ ".res" , ".resi" , ".ml" , ".mli" ] ;
38
50
var formattedFileExtensions = [ ".res" , ".resi" ] ;
@@ -55,12 +67,33 @@ async function readStdin() {
55
67
return Buffer . concat ( chunks ) . toString ( "utf8" ) ;
56
68
}
57
69
70
+ /**
71
+ *
72
+ * @param {string } file
73
+ * @returns void
74
+ */
75
+ function printIncorrectlyFormattedFile ( file ) {
76
+ console . error ( "[format check]" , file ) ;
77
+ }
78
+
79
+ /**
80
+ *
81
+ * @param {number } incorrectlyFormattedFiles
82
+ * @returns void
83
+ */
84
+ function printFormatCheckResult ( incorrectlyFormattedFiles ) {
85
+ if ( incorrectlyFormattedFiles > 0 ) {
86
+ console . error ( `${ incorrectlyFormattedFiles } file${ incorrectlyFormattedFiles > 1 ? "s" :"" } listed above need${ incorrectlyFormattedFiles > 1 ? "" : "s" } formatting.` ) ;
87
+ process . exit ( 3 ) ;
88
+ }
89
+ }
90
+
58
91
/**
59
92
* @param {string[] } argv
60
93
* @param {string } rescript_exe
61
94
* @param {string } bsc_exe
62
95
*/
63
- function main ( argv , rescript_exe , bsc_exe ) {
96
+ async function main ( argv , rescript_exe , bsc_exe ) {
64
97
var isSupportedFile = hasExtension ( formattedFileExtensions ) ;
65
98
var isSupportedStd = hasExtension ( formattedStdExtensions ) ;
66
99
@@ -95,26 +128,33 @@ function main(argv, rescript_exe, bsc_exe) {
95
128
process . exit ( 2 ) ;
96
129
}
97
130
files = output . stdout . split ( "\n" ) . map ( x => x . trim ( ) ) ;
98
- var hasError = false ;
99
- for ( let arg of files ) {
100
- if ( isSupportedFile ( arg ) ) {
101
- // console.log(`processing ${arg}`);
102
- child_process . execFile (
103
- bsc_exe ,
104
- [ "-o" , arg , "-format" , arg ] ,
105
- ( error , _stdout , stderr ) => {
106
- if ( error !== null ) {
107
- console . error ( stderr ) ;
108
- hasError = true ;
131
+ var incorrectlyFormattedFiles = 0 ;
132
+ try {
133
+ const _promises = await Promise . all ( files . map ( async ( file ) => {
134
+ if ( isSupportedFile ( file ) ) {
135
+ // console.log(`processing ${arg}`);
136
+ const flags = check . val ? [ "-format" , file ] : [ "-o" , file , "-format" , file ] ;
137
+ const { stdout} = await asyncExecFile ( bsc_exe , flags ) ;
138
+ if ( check . val ) {
139
+ const original = await asyncFs . readFile ( file , 'utf-8' ) ;
140
+ if ( original != stdout ) {
141
+ printIncorrectlyFormattedFile ( file ) ;
142
+ incorrectlyFormattedFiles ++ ;
109
143
}
110
144
}
111
- ) ;
112
- }
113
- }
114
- if ( hasError ) {
145
+ }
146
+ return null ;
147
+ } ) ) ;
148
+ } catch ( err ) {
149
+ console . error ( err ) ;
115
150
process . exit ( 2 ) ;
116
151
}
152
+ printFormatCheckResult ( incorrectlyFormattedFiles ) ;
117
153
} else if ( use_stdin ) {
154
+ if ( check . val ) {
155
+ console . error ( "format -stdin cannot be used with -check flag" ) ;
156
+ process . exit ( 2 ) ;
157
+ }
118
158
if ( isSupportedStd ( use_stdin ) ) {
119
159
var crypto = require ( "crypto" ) ;
120
160
var os = require ( "os" ) ;
@@ -144,7 +184,7 @@ function main(argv, rescript_exe, bsc_exe) {
144
184
) ;
145
185
} ) ( ) ;
146
186
} else {
147
- console . error ( `Unsupported exetnsion ${ use_stdin } ` ) ;
187
+ console . error ( `Unsupported extension ${ use_stdin } ` ) ;
148
188
console . error ( `Supported extensions: ${ formattedStdExtensions } ` ) ;
149
189
process . exit ( 2 ) ;
150
190
}
@@ -164,20 +204,34 @@ function main(argv, rescript_exe, bsc_exe) {
164
204
}
165
205
}
166
206
var hasError = false ;
207
+ var incorrectlyFormattedFiles = 0 ;
167
208
files . forEach ( file => {
168
- var write = isSupportedFile ( file ) ;
209
+ var write = isSupportedFile ( file ) && ! check . val ;
169
210
var flags = write ? [ "-o" , file , "-format" , file ] : [ "-format" , file ] ;
170
- child_process . execFile ( bsc_exe , flags , ( error , stdout , stderr ) => {
171
- if ( error === null ) {
172
- if ( ! write ) {
173
- process . stdout . write ( stdout ) ;
211
+ try {
212
+ const formatted = child_process . execFileSync ( bsc_exe , flags ) ;
213
+ if ( ! write ) {
214
+ if ( check . val ) {
215
+ try {
216
+ const original = fs . readFileSync ( file , 'utf-8' ) ;
217
+ if ( original != formatted ) {
218
+ printIncorrectlyFormattedFile ( file ) ;
219
+ incorrectlyFormattedFiles ++ ;
220
+ }
221
+ } catch ( err ) {
222
+ console . error ( err ) ;
223
+ hasError = true ;
224
+ }
225
+ } else {
226
+ process . stdout . write ( formatted ) ;
174
227
}
175
- } else {
176
- console . error ( stderr ) ;
177
- hasError = true ;
178
228
}
179
- } ) ;
229
+ } catch ( err ) {
230
+ console . error ( err ) ;
231
+ hasError = true ;
232
+ }
180
233
} ) ;
234
+ printFormatCheckResult ( incorrectlyFormattedFiles ) ;
181
235
if ( hasError ) {
182
236
process . exit ( 2 ) ;
183
237
}
0 commit comments