2
2
3
3
var fs = require ( 'fs' ) ;
4
4
var path = require ( 'path' ) ;
5
+ var mkdirpBulk = require ( 'mkdirp-bulk' ) ;
5
6
var mkdirp = require ( 'mkdirp' ) ;
6
7
var Promise = require ( 'rsvp' ) . Promise ;
7
8
var Plugin = require ( 'broccoli-plugin' ) ;
@@ -50,28 +51,65 @@ function Filter(inputTree, options) {
50
51
this . _destFilePathCache = Object . create ( null ) ;
51
52
}
52
53
54
+ Filter . prototype . _resetStats = function ( ) {
55
+ this . _stats = {
56
+ paths : 0 ,
57
+ stale : 0 ,
58
+ mkdirp : 0 ,
59
+ mkdirpCache : 0 ,
60
+ processed : 0 ,
61
+ unprocessed : 0 ,
62
+ hits : 0 ,
63
+ miss : 0 ,
64
+ prime : 0 ,
65
+ hash : 0 ,
66
+ processedTime : 0
67
+ } ;
68
+ } ;
69
+
53
70
Filter . prototype . build = function build ( ) {
54
71
var self = this ;
72
+ var start = new Date ( ) ;
73
+ this . _resetStats ( ) ;
55
74
var srcDir = this . inputPaths [ 0 ] ;
56
75
var destDir = this . outputPath ;
57
- var paths = walkSync ( srcDir ) ;
76
+ var paths = walkSync ( srcDir ) . filter ( Boolean ) ;
77
+
78
+ self . _stats . paths = paths . length ;
79
+ self . _stats . walkSyncTime = new Date ( ) - start ;
58
80
59
81
this . _cache . deleteExcept ( paths ) . forEach ( function ( key ) {
82
+ self . _stats . stale ++ ;
60
83
fs . unlinkSync ( this . cachePath + '/' + key ) ;
61
84
} , this ) ;
62
85
86
+ self . _stats . mkdirp += mkdirpBulk . sync ( paths . map ( function ( p ) {
87
+ return self . outputPath + '/' + p ;
88
+ } ) ) ;
89
+
90
+ if ( this . _cacheDirsPrimed === undefined ) {
91
+ this . _cacheDirsPrimed = true ;
92
+ self . _stats . mkdirp += mkdirpBulk . sync ( paths . map ( function ( p ) {
93
+ return self . cachePath + '/' + p ;
94
+ } ) ) ;
95
+ }
96
+
63
97
return mapSeries ( paths , function rebuildEntry ( relativePath ) {
64
98
var destPath = destDir + '/' + relativePath ;
65
99
if ( relativePath . slice ( - 1 ) === '/' ) {
66
- mkdirp . sync ( destPath ) ;
67
100
} else {
68
101
if ( self . canProcessFile ( relativePath ) ) {
102
+ self . _stats . processed ++ ;
69
103
return self . processAndCacheFile ( srcDir , destDir , relativePath ) ;
70
104
} else {
105
+ self . _stats . unprocessed ++ ;
71
106
var srcPath = srcDir + '/' + relativePath ;
72
107
symlinkOrCopySync ( srcPath , destPath ) ;
73
108
}
74
109
}
110
+ } ) . finally ( function ( ) {
111
+ self . _cacheDirsPrimed = false ;
112
+ self . _debug ( 'build %o in %dms' , self . _stats , new Date ( ) - start ) ;
75
113
} ) ;
76
114
} ;
77
115
@@ -98,29 +136,34 @@ Filter.prototype.getDestFilePath = function getDestFilePath(relativePath) {
98
136
99
137
Filter . prototype . processAndCacheFile =
100
138
function processAndCacheFile ( srcDir , destDir , relativePath ) {
139
+ var start = new Date ( ) ;
101
140
var self = this ;
102
141
var cacheEntry = this . _cache . get ( relativePath ) ;
142
+ var result ;
103
143
104
144
if ( cacheEntry ) {
145
+ this . _stats . hash ++ ;
105
146
var hashResult = hash ( srcDir , cacheEntry . inputFile ) ;
106
147
107
148
if ( cacheEntry . hash . hash === hashResult . hash ) {
108
- this . _debug ( 'cache hit: %s' , relativePath ) ;
149
+ this . _stats . hits ++ ;
109
150
110
- return symlinkOrCopyFromCache ( cacheEntry , destDir , relativePath ) ;
151
+ symlinkOrCopySync ( cacheEntry . cacheFile , destDir + '/' + relativePath ) ;
152
+ this . _stats . processedTime += new Date ( ) - start ;
153
+ return result ;
111
154
} else {
112
- this . _debug ( 'cache miss: %s \n - previous: %o \n - next: %o ' , relativePath , cacheEntry . hash . key , hashResult . key ) ;
155
+ this . _stats . miss ++ ;
113
156
}
114
157
115
158
} else {
116
- this . _debug ( 'cache prime: %s' , relativePath ) ;
159
+ this . _stats . prime ++ ;
117
160
}
118
161
119
162
return Promise . resolve ( ) .
120
163
then ( function asyncProcessFile ( ) {
121
164
return self . processFile ( srcDir , destDir , relativePath ) ;
122
165
} ) .
123
- then ( copyToCache ,
166
+ then ( linkFromCache ,
124
167
// TODO(@caitp): error wrapper is for API compat, but is not particularly
125
168
// useful.
126
169
// istanbul ignore next
@@ -129,23 +172,28 @@ Filter.prototype.processAndCacheFile =
129
172
e . file = relativePath ;
130
173
e . treeDir = srcDir ;
131
174
throw e ;
132
- } )
175
+ } ) . finally ( function ( ) {
176
+ self . _stats . processedTime += new Date ( ) - start ;
177
+ } ) ;
178
+
179
+ function linkFromCache ( ) {
180
+ self . _stats . hash ++ ;
133
181
134
- function copyToCache ( ) {
135
182
var entry = {
136
183
hash : hash ( srcDir , relativePath ) ,
137
184
inputFile : relativePath ,
138
185
outputFile : destDir + '/' + self . getDestFilePath ( relativePath ) ,
139
186
cacheFile : self . cachePath + '/' + relativePath
140
187
} ;
141
188
142
- if ( fs . existsSync ( entry . cacheFile ) ) {
143
- fs . unlinkSync ( entry . cacheFile ) ;
144
- } else {
189
+ if ( fs . existsSync ( entry . outputFile ) ) {
190
+ fs . unlinkSync ( entry . outputFile ) ;
191
+ } else if ( self . _cacheDirsPrimed === false ) {
192
+ self . _stats . mkdirpCache ++ ;
145
193
mkdirp . sync ( path . dirname ( entry . cacheFile ) ) ;
146
194
}
147
195
148
- copyDereferenceSync ( entry . outputFile , entry . cacheFile ) ;
196
+ symlinkOrCopySync ( entry . cacheFile , entry . outputFile ) ;
149
197
150
198
return self . _cache . set ( relativePath , entry ) ;
151
199
}
@@ -167,8 +215,7 @@ Filter.prototype.processFile =
167
215
if ( outputPath == null ) {
168
216
throw new Error ( 'canProcessFile("' + relativePath + '") is true, but getDestFilePath("' + relativePath + '") is null' ) ;
169
217
}
170
- outputPath = destDir + '/' + outputPath ;
171
- mkdirp . sync ( path . dirname ( outputPath ) ) ;
218
+ outputPath = self . cachePath + '/' + outputPath ;
172
219
fs . writeFileSync ( outputPath , outputString , {
173
220
encoding : outputEncoding
174
221
} ) ;
@@ -196,9 +243,3 @@ function hash(src, filePath) {
196
243
] )
197
244
} ;
198
245
}
199
-
200
- function symlinkOrCopyFromCache ( entry , dest , relativePath ) {
201
- mkdirp . sync ( path . dirname ( entry . outputFile ) ) ;
202
-
203
- symlinkOrCopySync ( entry . cacheFile , dest + '/' + relativePath ) ;
204
- }
0 commit comments