@@ -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,55 @@ async function readStdin() {
55
67
return Buffer . concat ( chunks ) . toString ( "utf8" ) ;
56
68
}
57
69
70
+ /**
71
+ * @param {string[] } files
72
+ * @param {string } bsc_exe
73
+ * @param {(x: string) => boolean } isSupportedFile
74
+ * @param {boolean } checkFormatting
75
+ */
76
+ async function formatFiles ( files , bsc_exe , isSupportedFile , checkFormatting ) {
77
+ var incorrectlyFormattedFiles = 0 ;
78
+ try {
79
+ const _promises = await Promise . all (
80
+ files . map ( async file => {
81
+ if ( isSupportedFile ( file ) ) {
82
+ const flags = checkFormatting
83
+ ? [ "-format" , file ]
84
+ : [ "-o" , file , "-format" , file ] ;
85
+ const { stdout } = await asyncExecFile ( bsc_exe , flags ) ;
86
+ if ( check . val ) {
87
+ const original = await asyncFs . readFile ( file , "utf-8" ) ;
88
+ if ( original != stdout ) {
89
+ console . error ( "[format check]" , file ) ;
90
+ incorrectlyFormattedFiles ++ ;
91
+ }
92
+ }
93
+ }
94
+ return null ;
95
+ } )
96
+ ) ;
97
+ } catch ( err ) {
98
+ console . error ( err ) ;
99
+ process . exit ( 2 ) ;
100
+ }
101
+ if ( incorrectlyFormattedFiles > 0 ) {
102
+ if ( incorrectlyFormattedFiles == 1 ) {
103
+ console . error ( "The file listed above needs formatting" ) ;
104
+ } else {
105
+ console . error (
106
+ `The ${ incorrectlyFormattedFiles } files listed above need formatting`
107
+ ) ;
108
+ }
109
+ process . exit ( 3 ) ;
110
+ }
111
+ }
112
+
58
113
/**
59
114
* @param {string[] } argv
60
115
* @param {string } rescript_exe
61
116
* @param {string } bsc_exe
62
117
*/
63
- function main ( argv , rescript_exe , bsc_exe ) {
118
+ async function main ( argv , rescript_exe , bsc_exe ) {
64
119
var isSupportedFile = hasExtension ( formattedFileExtensions ) ;
65
120
var isSupportedStd = hasExtension ( formattedStdExtensions ) ;
66
121
@@ -95,26 +150,12 @@ function main(argv, rescript_exe, bsc_exe) {
95
150
process . exit ( 2 ) ;
96
151
}
97
152
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 ;
109
- }
110
- }
111
- ) ;
112
- }
113
- }
114
- if ( hasError ) {
153
+ await formatFiles ( files , bsc_exe , isSupportedFile , check . val ) ;
154
+ } else if ( use_stdin ) {
155
+ if ( check . val ) {
156
+ console . error ( "format -stdin cannot be used with -check flag" ) ;
115
157
process . exit ( 2 ) ;
116
158
}
117
- } else if ( use_stdin ) {
118
159
if ( isSupportedStd ( use_stdin ) ) {
119
160
var crypto = require ( "crypto" ) ;
120
161
var os = require ( "os" ) ;
@@ -144,7 +185,7 @@ function main(argv, rescript_exe, bsc_exe) {
144
185
) ;
145
186
} ) ( ) ;
146
187
} else {
147
- console . error ( `Unsupported exetnsion ${ use_stdin } ` ) ;
188
+ console . error ( `Unsupported extension ${ use_stdin } ` ) ;
148
189
console . error ( `Supported extensions: ${ formattedStdExtensions } ` ) ;
149
190
process . exit ( 2 ) ;
150
191
}
@@ -163,24 +204,7 @@ function main(argv, rescript_exe, bsc_exe) {
163
204
process . exit ( 2 ) ;
164
205
}
165
206
}
166
- var hasError = false ;
167
- files . forEach ( file => {
168
- var write = isSupportedFile ( file ) ;
169
- 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 ) ;
174
- }
175
- } else {
176
- console . error ( stderr ) ;
177
- hasError = true ;
178
- }
179
- } ) ;
180
- } ) ;
181
- if ( hasError ) {
182
- process . exit ( 2 ) ;
183
- }
207
+ await formatFiles ( files , bsc_exe , isSupportedFile , check . val ) ;
184
208
}
185
209
} catch ( e ) {
186
210
if ( e instanceof arg . ArgError ) {
0 commit comments