@@ -5,8 +5,11 @@ var format_usage = `Usage: rescript format <options> [files]
55\`rescript format\` formats the current directory
66` ;
77var child_process = require ( "child_process" ) ;
8+ var util = require ( "node:util" ) ;
9+ var asyncExecFile = util . promisify ( child_process . execFile ) ;
810var path = require ( "path" ) ;
911var fs = require ( "fs" ) ;
12+ var asyncFs = fs . promises ;
1013/**
1114 * @type {arg.stringref }
1215 */
@@ -17,6 +20,11 @@ var stdin = { val: undefined };
1720 */
1821var format = { val : undefined } ;
1922
23+ /**
24+ * @type {arg.boolref }
25+ */
26+ var check = { val : undefined } ;
27+
2028/**
2129 * @type {arg.specs }
2230 */
@@ -27,12 +35,16 @@ var specs = [
2735 `[.res|.resi|.ml|.mli] Read the code from stdin and print
2836the formatted code to stdout in ReScript syntax` ,
2937 ] ,
30- // ml|mli
3138 [
3239 "-all" ,
3340 { kind : "Unit" , data : { kind : "Unit_set" , data : format } } ,
3441 "Format the whole project " ,
3542 ] ,
43+ [
44+ "-check" ,
45+ { kind : "Unit" , data : { kind : "Unit_set" , data : check } } ,
46+ "Check formatting only" ,
47+ ] ,
3648] ;
3749var formattedStdExtensions = [ ".res" , ".resi" , ".ml" , ".mli" ] ;
3850var formattedFileExtensions = [ ".res" , ".resi" ] ;
@@ -55,12 +67,39 @@ async function readStdin() {
5567 return Buffer . concat ( chunks ) . toString ( "utf8" ) ;
5668}
5769
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+
5897/**
5998 * @param {string[] } argv
6099 * @param {string } rescript_exe
61100 * @param {string } bsc_exe
62101 */
63- function main ( argv , rescript_exe , bsc_exe ) {
102+ async function main ( argv , rescript_exe , bsc_exe ) {
64103 var isSupportedFile = hasExtension ( formattedFileExtensions ) ;
65104 var isSupportedStd = hasExtension ( formattedStdExtensions ) ;
66105
@@ -95,26 +134,37 @@ function main(argv, rescript_exe, bsc_exe) {
95134 process . exit ( 2 ) ;
96135 }
97136 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+ }
109153 }
110154 }
111- ) ;
112- }
113- }
114- if ( hasError ) {
155+ return null ;
156+ } )
157+ ) ;
158+ } catch ( err ) {
159+ console . error ( err ) ;
115160 process . exit ( 2 ) ;
116161 }
162+ printFormatCheckResult ( incorrectlyFormattedFiles ) ;
117163 } else if ( use_stdin ) {
164+ if ( check . val ) {
165+ console . error ( "format -stdin cannot be used with -check flag" ) ;
166+ process . exit ( 2 ) ;
167+ }
118168 if ( isSupportedStd ( use_stdin ) ) {
119169 var crypto = require ( "crypto" ) ;
120170 var os = require ( "os" ) ;
@@ -144,7 +194,7 @@ function main(argv, rescript_exe, bsc_exe) {
144194 ) ;
145195 } ) ( ) ;
146196 } else {
147- console . error ( `Unsupported exetnsion ${ use_stdin } ` ) ;
197+ console . error ( `Unsupported extension ${ use_stdin } ` ) ;
148198 console . error ( `Supported extensions: ${ formattedStdExtensions } ` ) ;
149199 process . exit ( 2 ) ;
150200 }
@@ -164,20 +214,34 @@ function main(argv, rescript_exe, bsc_exe) {
164214 }
165215 }
166216 var hasError = false ;
217+ var incorrectlyFormattedFiles = 0 ;
167218 files . forEach ( file => {
168- var write = isSupportedFile ( file ) ;
219+ var write = isSupportedFile ( file ) && ! check . val ;
169220 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 ) ;
174237 }
175- } else {
176- console . error ( stderr ) ;
177- hasError = true ;
178238 }
179- } ) ;
239+ } catch ( err ) {
240+ console . error ( err ) ;
241+ hasError = true ;
242+ }
180243 } ) ;
244+ printFormatCheckResult ( incorrectlyFormattedFiles ) ;
181245 if ( hasError ) {
182246 process . exit ( 2 ) ;
183247 }
0 commit comments