1010
1111'use strict' ;
1212
13- const dotslash = require ( 'fb-dotslash' ) ;
1413const { spawnSync} = require ( 'node:child_process' ) ;
1514const fs = require ( 'node:fs' ) ;
1615const path = require ( 'node:path' ) ;
1716const { globSync} = require ( 'tinyglobby' ) ;
1817
1918const REPO_ROOT = path . resolve ( __dirname , '..' ) ;
20- const CLANG_FORMAT = path . join ( __dirname , 'clang-format' ) ;
19+ const OSS_CLANG_FORMAT_DOTSLASH = path . join ( __dirname , 'clang-format' ) ;
2120const GENERATED_MARKER = Buffer . from ( '@' + 'generated' ) ;
21+ const IGNORE_FILE = path . join ( REPO_ROOT , '.clang-format-ignore' ) ;
2222const MAX_HEADER_BYTES = 4096 ;
2323const MAX_FILES_PER_PROCESS = 30 ;
2424
25+ const SOURCE_GLOB = '**/*.{c,cc,cpp,cu,cuh,cxx,h,hh,hpp,hxx,m,mm,proto,tcc}' ;
26+
27+ function findClangFormat ( ) {
28+ if ( process . env . CLANG_FORMAT != null && process . env . CLANG_FORMAT !== '' ) {
29+ return { command : process . env . CLANG_FORMAT , prefixArguments : [ ] } ;
30+ }
31+
32+ try {
33+ const metaClangFormat = require ( './clang-format.fb' ) . findMetaClangFormat ( ) ;
34+ if ( metaClangFormat != null ) {
35+ return metaClangFormat ;
36+ }
37+ } catch ( error ) {
38+ if (
39+ error == null ||
40+ error . code !== 'MODULE_NOT_FOUND' ||
41+ ! String ( error . message ) . includes ( "'./clang-format.fb'" )
42+ ) {
43+ throw error ;
44+ }
45+ }
46+
47+ return {
48+ command :
49+ process . env . DOTSLASH != null && process . env . DOTSLASH !== ''
50+ ? process . env . DOTSLASH
51+ : require ( 'fb-dotslash' ) ,
52+ prefixArguments : [ OSS_CLANG_FORMAT_DOTSLASH ] ,
53+ } ;
54+ }
55+
2556/** @param {string } file */
2657function isGenerated ( file ) {
2758 let fd ;
@@ -41,16 +72,33 @@ function isGenerated(file) {
4172}
4273
4374function main ( ) {
75+ const arguments_ = process . argv . slice ( 2 ) ;
76+ const check = arguments_ . includes ( '--check' ) ;
77+ const clangFormat = findClangFormat ( ) ;
78+ const positionalArguments = arguments_ . filter (
79+ argument => argument !== '--check' ,
80+ ) ;
81+ const ignore = fs
82+ . readFileSync ( IGNORE_FILE , 'utf8' )
83+ . split ( '\n' )
84+ . map ( line => line . trim ( ) )
85+ . filter ( line => line !== '' && ! line . startsWith ( '#' ) ) ;
86+ const discoveredFiles = globSync ( SOURCE_GLOB , { cwd : REPO_ROOT , ignore} ) ;
4487 const files =
45- process . argv . length > 2
46- ? process . argv . slice ( 2 )
47- : globSync ( '*/**/*.{h,cpp,m,mm}' , { cwd : REPO_ROOT } ) ;
88+ positionalArguments . length > 0
89+ ? positionalArguments . filter ( file => discoveredFiles . includes ( file ) )
90+ : discoveredFiles ;
4891 const sourceFiles = files . filter ( file => ! isGenerated ( file ) ) ;
92+ let exitStatus = 0 ;
4993
5094 for ( let i = 0 ; i < sourceFiles . length ; i += MAX_FILES_PER_PROCESS ) {
95+ const formatterArguments = [
96+ ...( check ? [ '--dry-run' , '--Werror' ] : [ '-i' ] ) ,
97+ ...sourceFiles . slice ( i , i + MAX_FILES_PER_PROCESS ) ,
98+ ] ;
5199 const result = spawnSync (
52- dotslash ,
53- [ CLANG_FORMAT , '-i' , ...sourceFiles . slice ( i , i + MAX_FILES_PER_PROCESS ) ] ,
100+ clangFormat . command ,
101+ [ ...clangFormat . prefixArguments , ... formatterArguments ] ,
54102 {
55103 cwd : REPO_ROOT ,
56104 stdio : 'inherit' ,
@@ -61,13 +109,13 @@ function main() {
61109 throw result . error ;
62110 }
63111 if ( result . signal != null ) {
64- process . kill ( process . pid , result . signal ) ;
65- return ;
112+ throw new Error ( `clang-format was terminated by ${ result . signal } ` ) ;
66113 }
67114 if ( result . status !== 0 ) {
68- process . exit ( result . status ?? 1 ) ;
115+ exitStatus = result . status ?? 1 ;
69116 }
70117 }
118+ process . exitCode = exitStatus ;
71119}
72120
73121main ( ) ;
0 commit comments