forked from UltCombo/gulp-buster
-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.js
107 lines (89 loc) · 2.8 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
'use strict';
var PLUGIN_NAME = 'gulp-buster',
crypto = require('crypto'),
path = require('path'),
es = require('event-stream'),
gutil = require('gulp-util'),
File = gutil.File,
PluginError = gutil.PluginError,
defaultConfig = {
algo: 'md5',
mode: 'file',
length: 0,
fileName: 'busters.json',
formatter: JSON.stringify
},
config = extend({}, defaultConfig),
hashes = {};
// a simple, shallow object extend function
function extend(dest, src) {
Object.keys(src).forEach(function(key) {
dest[key] = src[key];
});
return dest;
}
function hash(str) {
var ret = crypto.createHash(config.algo).update(str).digest('hex');
return config.length ? ret.substr(0, config.length) : ret;
}
function path_relative_to_project(projectPath, filePath) {
return path.relative(projectPath, filePath).replace(/\\/g, '/');
}
module.exports = function(fileName) {
fileName = fileName || config.fileName;
hashes[fileName] = hashes[fileName] || {};
var isDirectoryMode = config.mode === 'dir',
combinedFileContents = {};
function bufferContents(file) {
if (file.isNull()) return; // ignore
if (file.isStream()) return this.emit('error', new PluginError(PLUGIN_NAME, 'Streaming not supported'));
if(isDirectoryMode) {
combinedFileContents[path_relative_to_project(file.cwd, file.base)] = (combinedFileContents[path_relative_to_project(file.cwd, file.base)] || '') + file.contents;
} else {
hashes[fileName][path_relative_to_project(file.cwd, file.path)] = hash(file.contents.toString('utf8'));
}
}
function endStream() {
var key, file, content;
if (isDirectoryMode) {
for (key in combinedFileContents) {
hashes[fileName][key] = hash(combinedFileContents[key]);
}
}
content = config.formatter(hashes[fileName]);
if (typeof content !== 'string') {
return this.emit('error', new PluginError(PLUGIN_NAME, 'Result of `config.formatter` should be a string'));
}
file = new File({
path: path.join(process.cwd(), fileName),
contents: new Buffer(content)
});
this.emit('data', file);
this.emit('end');
}
return es.through(bufferContents, endStream);
};
module.exports.config = function(key, value) {
if (!arguments.length) return config;
if ({}.toString.call(key) === '[object Object]') {
extend(config, key);
} else if (typeof key === 'string') {
if (arguments.length > 1) {
config[key] = value;
} else {
return config[key];
}
} else {
throw new PluginError(PLUGIN_NAME, PLUGIN_NAME + ': Invalid first argument for .config(), must be object or string');
}
};
module.exports.hashes = function() {
return hashes;
};
// for testing. Don't use, may be removed or changed at anytime
module.exports._hash = hash;
module.exports._path_relative_to_project = path_relative_to_project;
module.exports._reset = function() {
config = extend({}, defaultConfig);
hashes = {};
};