UNPKG

3.94 kBJavaScriptView Raw
1var fs = require('graceful-fs')
2var crypto = require('crypto')
3var mm = require('minimatch')
4var isBinaryFile = require('isbinaryfile')
5var combineLists = require('combine-lists')
6
7var log = require('./logger').create('preprocess')
8
9var sha1 = function (data) {
10 var hash = crypto.createHash('sha1')
11 hash.update(data)
12 return hash.digest('hex')
13}
14
15var createNextProcessor = function (preprocessors, file, done) {
16 return function nextPreprocessor (error, content) {
17 // normalize B-C
18 if (arguments.length === 1 && typeof error === 'string') {
19 content = error
20 error = null
21 }
22
23 if (error) {
24 file.content = null
25 file.contentPath = null
26 return done(error)
27 }
28
29 if (!preprocessors.length) {
30 file.contentPath = null
31 file.content = content
32 file.sha = sha1(content)
33 return done()
34 }
35
36 preprocessors.shift()(content, file, nextPreprocessor)
37 }
38}
39
40var createPreprocessor = function (config, basePath, injector) {
41 var alreadyDisplayedErrors = {}
42 var instances = {}
43 var patterns = Object.keys(config)
44
45 var emitter = injector.get('emitter')
46
47 var instantiatePreprocessor = function (name) {
48 if (alreadyDisplayedErrors[name]) {
49 return
50 }
51
52 var p
53
54 try {
55 p = injector.get('preprocessor:' + name)
56 } catch (e) {
57 if (e.message.indexOf('No provider for "preprocessor:' + name + '"') !== -1) {
58 log.error('Can not load "%s", it is not registered!\n ' +
59 'Perhaps you are missing some plugin?', name)
60 } else {
61 log.error('Can not load "%s"!\n ' + e.stack, name)
62 }
63 alreadyDisplayedErrors[name] = true
64 emitter.emit('load_error', 'preprocessor', name)
65 }
66
67 return p
68 }
69
70 var allPreprocessors = []
71 patterns.forEach(function (pattern) {
72 allPreprocessors = combineLists(allPreprocessors, config[pattern])
73 })
74 allPreprocessors.forEach(instantiatePreprocessor)
75
76 return function preprocess (file, done) {
77 patterns = Object.keys(config)
78 var retryCount = 0
79 var maxRetries = 3
80 function readFileCallback (err, buffer) {
81 if (err) {
82 log.warn(err)
83 if (retryCount < maxRetries) {
84 retryCount++
85 log.warn('retrying ' + retryCount)
86 fs.readFile(file.originalPath, readFileCallback)
87 return
88 } else {
89 throw err
90 }
91 }
92
93 isBinaryFile(buffer, buffer.length, function (err, thisFileIsBinary) {
94 if (err) {
95 throw err
96 }
97
98 var preprocessorNames = []
99 for (var i = 0; i < patterns.length; i++) {
100 if (mm(file.originalPath, patterns[i], {dot: true})) {
101 if (thisFileIsBinary) {
102 log.warn('Ignoring preprocessing (%s) %s because it is a binary file.',
103 config[patterns[i]].join(', '), file.originalPath)
104 } else {
105 preprocessorNames = combineLists(preprocessorNames, config[patterns[i]])
106 }
107 }
108 }
109
110 var preprocessors = []
111 var nextPreprocessor = createNextProcessor(preprocessors, file, done)
112 preprocessorNames.forEach(function (name) {
113 var p = instances[name]
114 if (p == null) {
115 p = instantiatePreprocessor(name)
116 }
117
118 if (p == null) {
119 if (!alreadyDisplayedErrors[name]) {
120 alreadyDisplayedErrors[name] = true
121 log.error('Failed to instantiate preprocessor %s', name)
122 emitter.emit('load_error', 'preprocessor', name)
123 }
124 return
125 }
126
127 instances[name] = p
128 preprocessors.push(p)
129 })
130
131 nextPreprocessor(null, thisFileIsBinary ? buffer : buffer.toString())
132 })
133 }
134 return fs.readFile(file.originalPath, readFileCallback)
135 }
136}
137createPreprocessor.$inject = ['config.preprocessors', 'config.basePath', 'injector']
138
139exports.createPreprocessor = createPreprocessor