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