@@ -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,39 @@ 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 (
87
+ `${ incorrectlyFormattedFiles } file${
88
+ incorrectlyFormattedFiles > 1 ? "s" : ""
89
+ } listed above need${
90
+ incorrectlyFormattedFiles > 1 ? "" : "s"
91
+ } formatting.`
92
+ ) ;
93
+ process . exit ( 3 ) ;
94
+ }
95
+ }
96
+
58
97
/**
59
98
* @param {string[] } argv
60
99
* @param {string } rescript_exe
61
100
* @param {string } bsc_exe
62
101
*/
63
- function main ( argv , rescript_exe , bsc_exe ) {
102
+ async function main ( argv , rescript_exe , bsc_exe ) {
64
103
var isSupportedFile = hasExtension ( formattedFileExtensions ) ;
65
104
var isSupportedStd = hasExtension ( formattedStdExtensions ) ;
66
105
@@ -95,26 +134,37 @@ function main(argv, rescript_exe, bsc_exe) {
95
134
process . exit ( 2 ) ;
96
135
}
97
136
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 ;
137
+ var incorrectlyFormattedFiles = 0 ;
138
+ try {
139
+ const _promises = await Promise . all (
140
+ files . map ( async file => {
141
+ if ( isSupportedFile ( file ) ) {
142
+ // console.log(`processing ${arg}`);
143
+ const flags = check . val
144
+ ? [ "-format" , file ]
145
+ : [ "-o" , file , "-format" , file ] ;
146
+ const { stdout } = await asyncExecFile ( bsc_exe , flags ) ;
147
+ if ( check . val ) {
148
+ const original = await asyncFs . readFile ( file , "utf-8" ) ;
149
+ if ( original != stdout ) {
150
+ printIncorrectlyFormattedFile ( file ) ;
151
+ incorrectlyFormattedFiles ++ ;
152
+ }
109
153
}
110
154
}
111
- ) ;
112
- }
113
- }
114
- if ( hasError ) {
155
+ return null ;
156
+ } )
157
+ ) ;
158
+ } catch ( err ) {
159
+ console . error ( err ) ;
115
160
process . exit ( 2 ) ;
116
161
}
162
+ printFormatCheckResult ( incorrectlyFormattedFiles ) ;
117
163
} else if ( use_stdin ) {
164
+ if ( check . val ) {
165
+ console . error ( "format -stdin cannot be used with -check flag" ) ;
166
+ process . exit ( 2 ) ;
167
+ }
118
168
if ( isSupportedStd ( use_stdin ) ) {
119
169
var crypto = require ( "crypto" ) ;
120
170
var os = require ( "os" ) ;
@@ -144,7 +194,7 @@ function main(argv, rescript_exe, bsc_exe) {
144
194
) ;
145
195
} ) ( ) ;
146
196
} else {
147
- console . error ( `Unsupported exetnsion ${ use_stdin } ` ) ;
197
+ console . error ( `Unsupported extension ${ use_stdin } ` ) ;
148
198
console . error ( `Supported extensions: ${ formattedStdExtensions } ` ) ;
149
199
process . exit ( 2 ) ;
150
200
}
@@ -164,20 +214,34 @@ function main(argv, rescript_exe, bsc_exe) {
164
214
}
165
215
}
166
216
var hasError = false ;
217
+ var incorrectlyFormattedFiles = 0 ;
167
218
files . forEach ( file => {
168
- var write = isSupportedFile ( file ) ;
219
+ var write = isSupportedFile ( file ) && ! check . val ;
169
220
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 ) ;
221
+ try {
222
+ const formatted = child_process . execFileSync ( bsc_exe , flags ) ;
223
+ if ( ! write ) {
224
+ if ( check . val ) {
225
+ try {
226
+ const original = fs . readFileSync ( file , "utf-8" ) ;
227
+ if ( original != formatted ) {
228
+ printIncorrectlyFormattedFile ( file ) ;
229
+ incorrectlyFormattedFiles ++ ;
230
+ }
231
+ } catch ( err ) {
232
+ console . error ( err ) ;
233
+ hasError = true ;
234
+ }
235
+ } else {
236
+ process . stdout . write ( formatted ) ;
174
237
}
175
- } else {
176
- console . error ( stderr ) ;
177
- hasError = true ;
178
238
}
179
- } ) ;
239
+ } catch ( err ) {
240
+ console . error ( err ) ;
241
+ hasError = true ;
242
+ }
180
243
} ) ;
244
+ printFormatCheckResult ( incorrectlyFormattedFiles ) ;
181
245
if ( hasError ) {
182
246
process . exit ( 2 ) ;
183
247
}
0 commit comments