55
66'use strict' ;
77
8- import { readdirSync , statSync , existsSync , readFileSync } from 'fs' ;
8+ import { readdir , stat , exists , readFile } from 'fs' ;
99import { join } from 'path' ;
1010
1111export interface WorkspaceStatItem {
@@ -26,34 +26,43 @@ function asSortedItems(map: Map<string, number>): WorkspaceStatItem[] {
2626 return a . sort ( ( a , b ) => b . count - a . count ) ;
2727}
2828
29- export function collectLaunchConfigs ( folder : string ) : WorkspaceStatItem [ ] {
29+ export function collectLaunchConfigs ( folder : string ) : Promise < WorkspaceStatItem [ ] > {
3030 let launchConfigs = new Map < string , number > ( ) ;
3131
3232 let launchConfig = join ( folder , '.vscode' , 'launch.json' ) ;
33- if ( existsSync ( launchConfig ) ) {
34- try {
35- const contents = readFileSync ( launchConfig ) . toString ( ) ;
36- const json = JSON . parse ( contents ) ;
37- if ( json [ 'configurations' ] ) {
38- for ( const each of json [ 'configurations' ] ) {
39- const type = each [ 'type' ] ;
40- if ( type ) {
41- if ( launchConfigs . has ( type ) ) {
42- launchConfigs . set ( type , launchConfigs . get ( type ) + 1 ) ;
43- }
44- else {
45- launchConfigs . set ( type , 1 ) ;
33+ return new Promise ( ( resolve , reject ) => {
34+ exists ( launchConfig , ( doesExist ) => {
35+ if ( doesExist ) {
36+ readFile ( launchConfig , ( err , contents ) => {
37+ if ( err ) {
38+ return resolve ( [ ] ) ;
39+ }
40+
41+ const json = JSON . parse ( contents . toString ( ) ) ;
42+ if ( json [ 'configurations' ] ) {
43+ for ( const each of json [ 'configurations' ] ) {
44+ const type = each [ 'type' ] ;
45+ if ( type ) {
46+ if ( launchConfigs . has ( type ) ) {
47+ launchConfigs . set ( type , launchConfigs . get ( type ) + 1 ) ;
48+ }
49+ else {
50+ launchConfigs . set ( type , 1 ) ;
51+ }
52+ }
4653 }
4754 }
48- }
55+
56+ return resolve ( asSortedItems ( launchConfigs ) ) ;
57+ } ) ;
58+ } else {
59+ return resolve ( [ ] ) ;
4960 }
50- } catch {
51- }
52- }
53- return asSortedItems ( launchConfigs ) ;
61+ } ) ;
62+ } ) ;
5463}
5564
56- export function collectWorkspaceStats ( folder : string , filter : string [ ] ) : WorkspaceStats {
65+ export function collectWorkspaceStats ( folder : string , filter : string [ ] ) : Promise < WorkspaceStats > {
5766 const configFilePatterns = [
5867 { 'tag' : 'grunt.js' , 'pattern' : / ^ g r u n t f i l e \. j s $ / i } ,
5968 { 'tag' : 'gulp.js' , 'pattern' : / ^ g u l p f i l e \. j s $ / i } ,
@@ -78,35 +87,62 @@ export function collectWorkspaceStats(folder: string, filter: string[]): Workspa
7887
7988 const MAX_FILES = 20000 ;
8089
81- let walkSync = ( dir : string , acceptFile : ( fileName : string ) => void , filter : string [ ] , token ) => {
82- try {
83- let files = readdirSync ( dir ) ;
90+ function walk ( dir : string , filter : string [ ] , token , done : ( allFiles : string [ ] ) => void ) : void {
91+ let results = [ ] ;
92+ readdir ( dir , async ( err , files ) => {
93+ // Ignore folders that can't be read
94+ if ( err ) {
95+ return done ( results ) ;
96+ }
97+
98+ let pending = files . length ;
99+ if ( pending === 0 ) {
100+ return done ( results ) ;
101+ }
102+
84103 for ( const file of files ) {
85104 if ( token . maxReached ) {
86- return ;
105+ return done ( results ) ;
87106 }
88- try {
89- if ( statSync ( join ( dir , file ) ) . isDirectory ( ) ) {
90- if ( filter . indexOf ( file ) === - 1 ) {
91- walkSync ( join ( dir , file ) , acceptFile , filter , token ) ;
107+
108+ stat ( join ( dir , file ) , ( err , stats ) => {
109+ // Ignore files that can't be read
110+ if ( err ) {
111+ if ( -- pending === 0 ) {
112+ return done ( results ) ;
92113 }
93114 }
94- else {
115+
116+ if ( stats . isDirectory ( ) ) {
117+ if ( filter . indexOf ( file ) === - 1 ) {
118+ walk ( join ( dir , file ) , filter , token , ( res : string [ ] ) => {
119+ results = results . concat ( res ) ;
120+
121+ if ( -- pending === 0 ) {
122+ return done ( results ) ;
123+ }
124+ } ) ;
125+ } else {
126+ if ( -- pending === 0 ) {
127+ done ( results ) ;
128+ }
129+ }
130+ } else {
95131 if ( token . count >= MAX_FILES ) {
96132 token . maxReached = true ;
97- return ;
98133 }
134+
99135 token . count ++ ;
100- acceptFile ( file ) ;
136+ results . push ( file ) ;
137+
138+ if ( -- pending === 0 ) {
139+ done ( results ) ;
140+ }
101141 }
102- } catch {
103- // skip over files for which stat fails
104- }
142+ } ) ;
105143 }
106- } catch {
107- // skip over folders that cannot be read
108- }
109- } ;
144+ } ) ;
145+ }
110146
111147 let addFileType = ( fileType : string ) => {
112148 if ( fileTypes . has ( fileType ) ) {
@@ -140,13 +176,18 @@ export function collectWorkspaceStats(folder: string, filter: string[]): Workspa
140176 } ;
141177
142178 let token : { count : number , maxReached : boolean } = { count : 0 , maxReached : false } ;
143- walkSync ( folder , acceptFile , filter , token ) ;
144179
145- return {
146- configFiles : asSortedItems ( configFiles ) ,
147- fileTypes : asSortedItems ( fileTypes ) ,
148- fileCount : token . count ,
149- maxFilesReached : token . maxReached
180+ return new Promise ( ( resolve , reject ) => {
181+ walk ( folder , filter , token , ( files ) => {
182+ files . forEach ( acceptFile ) ;
150183
151- } ;
184+ resolve ( {
185+ configFiles : asSortedItems ( configFiles ) ,
186+ fileTypes : asSortedItems ( fileTypes ) ,
187+ fileCount : token . count ,
188+ maxFilesReached : token . maxReached
189+
190+ } ) ;
191+ } ) ;
192+ } ) ;
152193}
0 commit comments