forked from fabiocaseri/dashing-js
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathscaffold.js
136 lines (119 loc) · 4.27 KB
/
scaffold.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
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
/**
* scaffold.js
*
* [Forked from hardhat (https://github.com/cpsubrian/hardhat/)]
* Copy files and directorys from `in` to `out`, applying templating and data.
*/
var fs = require('fs')
, utils = require('./utils')
, async = require('async')
, cons = require('consolidate')
, walker = require('walker');
var Array = {
unique: function(array){
var a = [];
for(var i = 0, l = array.length; i < l; i++) {
for(var j = i + 1; j < l; j++) {
// If this[i] is found later in the array
if (array[i] === array[j]) j = ++i;
}
a.push(array[i]);
}
return a;
}
};
// `options` can be omitted to fallback to the defaults.
// If you are using templates, set the template data on `options.data`.
module.exports = function(dirIn, dirOut, options, callback) {
if (typeof options === 'function') {
callback = options;
options = {};
}
// Which consolidate-supported templating engine to use.
options.engine = options.engine || 'handlebars';
options.engine_opts = options.engine_opts || {};
// Which extension hardhat should apply templating to.
// HardHat will run '*.[ext]'' files through the templating engine and
// remove '.[ext]' from the resulting file.
//
// For example: 'index.html.tpl' will run through the engine and be copied to
// the destination as 'index.html'.
options.ext = options.ext || 'tpl';
// The data option is passed to consolidate for templating.
options.data = options.data || {};
// All templatable files are assumed to be utf8 by default.
options.encoding = 'utf8';
options.namepre = options.namepre || '{{';
options.namesuf = options.namesuf || '}}';
options.filterFile = options.filterFile || function(){return true};
for (var key in options.engine_opts) {
options.data[key] = options.engine_opts[key];
}
// Ensure dirIn exists.
if (!fs.existsSync(dirIn)) {
return callback(new Error('The input directory does not exist (' + dirIn + ').'));
}
// If dirOut does not exist, try to create it.
if (!fs.existsSync(dirOut)) {
if (!utils.mkdir.sync(dirOut)) {
return callback(new Error('Could not create the output directory (' + dirOut + ').'));
}
}
// Ensure the caller has chosen a real templating engine.
if (!cons[options.engine]) {
return callback(new Error('The templating engine `' + options.engine + '` does not exist.'));
}
function evalFileName(name, data) {
var matches = name.match(new RegExp(options.namepre + '\\w+' + options.namesuf, 'g'));
if (matches) {
matches = Array.unique(matches);
for (var i in matches) {
var val = matches[i].substring(1, matches[i].length - 1);
if (data[val]) {
name = name.replace(new RegExp(matches[i], 'g'), data[val]);
}
}
}
return name;
}
var files = [];
// Recurse through dirIn. Create any directories found and build an array of
// file paths to copy over.
walker(dirIn)
.on('error', function(err, entry, stat) {
console.log('Got error ' + err + ' on entry ' + entry);
})
.on('dir', function(dir, stat) {
dir = evalFileName(dir, options.data);
utils.mkdir.sync(dir.replace(dirIn, dirOut));
})
.on('file', function(file, stat) {
if (options.filterFile(file, stat)) {
files.push(file);
}
})
.on('end', function() {
// Now copy over all the files, applying templating where necessary.
var tasks = [];
for (var i in files) {
(function(file) {
var dest = file.replace(dirIn, dirOut);
tasks.push(function(done) {
dest = evalFileName(dest, options.data);
// If the file does not end with `.[ext]`, just copy it.
if (!file.match(new RegExp('.*\.' + options.ext + '$'))) {
utils.copy(file, dest, done);
} else {
// Otherwise, we need to run this file through the templating engine.
dest = dest.replace('.' + options.ext, '');
cons[options.engine](file, options.data, function(err, templated) {
if (err) return done(err);
utils.write(dest, templated, {encoding: options.encoding}, done);
});
}
});
})(files[i]);
}
async.parallel(tasks, callback);
});
};