@@ -38,6 +38,11 @@ interface ConfigFilePatterns {
38
38
relativePathPattern ?: RegExp ;
39
39
}
40
40
41
+ interface RootFileMatcher {
42
+ tag : string ;
43
+ matcher : ( path : string ) => boolean ;
44
+ }
45
+
41
46
export async function collectWorkspaceStats ( folder : string , filter : string [ ] ) : Promise < WorkspaceStats > {
42
47
const configFilePatterns : ConfigFilePatterns [ ] = [
43
48
{ tag : 'grunt.js' , filePattern : / ^ g r u n t f i l e \. j s $ / i } ,
@@ -61,12 +66,83 @@ export async function collectWorkspaceStats(folder: string, filter: string[]): P
61
66
{ tag : 'dockerfile' , filePattern : / ^ ( d o c k e r f i l e | d o c k e r \- c o m p o s e \. y a ? m l ) $ / i }
62
67
] ;
63
68
69
+ let rootFileMatchers : RootFileMatcher [ ] ;
70
+
71
+ // Linux is omitted because few cloud sync clients support it, and for those who are available on Linux, there are multiple clients and they can be configured differently
72
+ const homeDir = osLib . homedir ( ) . toLowerCase ( ) ;
73
+ switch ( process . platform ) {
74
+ case 'win32' :
75
+ rootFileMatchers = [
76
+ {
77
+ tag : 'gdrive' , matcher : ( path ) => {
78
+ // File Streaming or Mirror Files mode
79
+ return / ^ [ a - z ] : \\ ( m y d r i v e | s h a r e d d r i v e s ) \\ / . test ( path ) || path . startsWith ( homeDir + '\\my drive\\' ) ;
80
+ }
81
+ } ,
82
+ {
83
+ tag : 'dropbox' , matcher : path => path . startsWith ( homeDir + '\\dropbox' ) // Ending in *
84
+ } ,
85
+ {
86
+ tag : 'onedrive' , matcher : path => path . startsWith ( homeDir + '\\onedrive' ) // Ending in *
87
+ } ,
88
+ {
89
+ tag : 'box' , matcher : path => path . startsWith ( homeDir + '\\box\\' )
90
+ } ,
91
+ {
92
+ tag : 'nextcloud' , matcher : path => path . startsWith ( homeDir + '\\nextcloud\\' )
93
+ } ,
94
+ {
95
+ tag : 'owncloud' , matcher : path => path . startsWith ( homeDir + '\\owncloud\\' )
96
+ } ,
97
+ ] ;
98
+ break ;
99
+
100
+ case 'darwin' :
101
+ rootFileMatchers = [
102
+ {
103
+ tag : 'gdrive' , matcher : ( path ) => {
104
+ // File Streaming mode
105
+ return path . startsWith ( '/volumes/googledrive/' ) || path . startsWith ( homeDir + '/my drive/' ) ;
106
+ }
107
+ } ,
108
+ {
109
+ tag : 'dropbox' , matcher : path => path . startsWith ( homeDir + '/dropbox' ) // Ending in *
110
+ } ,
111
+ {
112
+ tag : 'onedrive' , matcher : ( path ) => {
113
+ // Old vs new client
114
+ return path . startsWith ( homeDir + '/onedrive' ) || path . startsWith ( homeDir + '/library/cloudstorage/onedrive' ) ;
115
+ }
116
+ } ,
117
+ {
118
+ tag : 'icloud' , matcher : path => path . startsWith ( homeDir + '/library/mobile documents/' )
119
+ } ,
120
+ {
121
+ tag : 'box' , matcher : path => path . startsWith ( homeDir + '/box/' )
122
+ } ,
123
+ {
124
+ tag : 'nextcloud' , matcher : path => path . startsWith ( homeDir + '/nextcloud/' )
125
+ } ,
126
+ {
127
+ tag : 'owncloud' , matcher : path => path . startsWith ( homeDir + '/owncloud/' )
128
+ } ,
129
+ ] ;
130
+ break ;
131
+ }
132
+
64
133
const fileTypes = new Map < string , number > ( ) ;
65
134
const configFiles = new Map < string , number > ( ) ;
66
135
67
136
const MAX_FILES = 20000 ;
68
137
69
138
function collect ( root : string , dir : string , filter : string [ ] , token : { count : number , maxReached : boolean } ) : Promise < void > {
139
+ for ( const rootPath of rootFileMatchers ) {
140
+ const lowercaseRoot = root . toLowerCase ( ) ;
141
+ if ( rootPath . matcher ( lowercaseRoot ) ) {
142
+ configFiles . set ( rootPath . tag , 1 ) ;
143
+ }
144
+ }
145
+
70
146
const relativePath = dir . substring ( root . length + 1 ) ;
71
147
72
148
return Promises . withAsyncBody ( async resolve => {
0 commit comments