UNPKG

10.1 kBJavaScriptView Raw
1#!/usr/bin/env node
2'use strict';
3
4var _commander = require('commander');
5
6var _commander2 = _interopRequireDefault(_commander);
7
8var _child_process = require('child_process');
9
10var _child_process2 = _interopRequireDefault(_child_process);
11
12var _fs = require('fs');
13
14var _fs2 = _interopRequireDefault(_fs);
15
16var _path = require('path');
17
18var _path2 = _interopRequireDefault(_path);
19
20var _tsort = require('tsort');
21
22var _tsort2 = _interopRequireDefault(_tsort);
23
24var _stream = require('stream');
25
26var _stream2 = _interopRequireDefault(_stream);
27
28var _maketConf = require('@eknkc/maket-conf');
29
30var _maketConf2 = _interopRequireDefault(_maketConf);
31
32var _flatten = require('./flatten');
33
34var _flatten2 = _interopRequireDefault(_flatten);
35
36var _lodash = require('lodash.template');
37
38var _lodash2 = _interopRequireDefault(_lodash);
39
40function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
41
42const json = require.resolve('.bin/json');
43const concurrently = require.resolve('.bin/concurrently');
44const nodemon = require.resolve('.bin/nodemon');
45const babel = require.resolve('.bin/babel');
46const stylus = require.resolve('.bin/stylus');
47const babelParams = ['-s', 'inline', '-D'];
48const cwd = process.cwd();
49
50const config = (0, _maketConf2.default)(cwd);
51
52if (!config) exit("No maket.yaml config found.");
53
54function resolve(path) {
55 let name = arguments.length <= 1 || arguments[1] === undefined ? path : arguments[1];
56
57 try {
58 let res = _child_process2.default.spawnSync('/usr/bin/env', ['node', '-e', 'process.stdout.write(require.resolve(process.argv[1]))', path], { cwd: cwd });
59
60 if (res.status !== 0) throw new Error();
61
62 return res.stdout.toString('utf8');
63 } catch (e) {
64 return exit(`Unable to resolve ${ name }`);
65 }
66}
67
68_commander2.default.command('browserify').option('-w, --watch', 'Watch mode').option('-u, --uglify', 'Uglify').description("Build browserify bundle").action(function () {
69 const browserify = require('browserify');
70 const watchify = require('watchify');
71 const browserifycss = require('browserify-css');
72 const babelify = require('babelify');
73 const envify = require('envify/custom');
74 const factor = require('factor-bundle');
75
76 if (!config.$browserify) return exit("No browserify configuration found.");
77
78 let cnf = config.$browserify;
79
80 if (!Array.isArray(cnf)) cnf = [cnf];
81
82 cnf.forEach(cf => {
83 if (!cf.add || !cf.dest) return exit("Browserify needs an add and dest field");
84 if (!Array.isArray(cf.add)) cf.add = [cf.add];
85 cf.add = cf.add.map(a => _path2.default.resolve(cwd, a));
86
87 var b = browserify(cf.add, {
88 extensions: [".js", ".jsx", ".json", ".css"],
89 cache: {},
90 packageCache: {},
91 debug: !this.uglify
92 }).transform(babelify, { presets: [require('babel-preset-es2015'), require('babel-preset-react')] }).transform(browserifycss, {
93 global: true,
94 onFlush: function onFlush(_ref, done) {
95 let data = _ref.data;
96
97 done(`
98 (function() {
99 var elem = document.createElement('style');
100 var css = ${ JSON.stringify(data) };
101 elem.setAttribute('type', 'text/css');
102
103 if ('textContent' in elem) {
104 elem.textContent = css;
105 } else {
106 elem.styleSheet.cssText = css;
107 }
108
109 var head = document.getElementsByTagName('head')[0];
110 head.appendChild(elem);
111 })();
112 `);
113 }
114 }).transform(envify({
115 NODE_ENV: this.watch ? 'development' : 'production'
116 }), {
117 global: true
118 }).transform((filename, opts) => {
119 if (this.watch || /\.min\./.test(filename) || /\.json$/.test(filename)) return new _stream2.default.PassThrough();
120
121 return new _stream2.default.PassThrough();
122
123 var uglifyjs = require('uglify-js');
124
125 var js = "";
126 var transform = new _stream2.default.Transform();
127
128 transform._transform = function (data, enc, next) {
129 js += data.toString('utf8');
130 next();
131 };
132
133 transform._flush = function (next) {
134 try {
135 js = uglifyjs.minify(js, { fromString: true }).code;
136 this.push(js);
137 next(null);
138 } catch (e) {
139 next(e);
140 }
141 };
142
143 return transform;
144 }, {
145 global: true
146 });
147
148 if (cf.factor && Array.isArray(cf.factor)) b.plugin(factor, { outputs: cf.factor.map(f => _path2.default.resolve(cwd, f)) });
149
150 bundle();
151
152 if (this.watch) {
153 b.plugin(watchify);
154 b.on('update', bundle);
155 }
156
157 function bundle() {
158 console.log('browserify', 'buildStart', cf.dest);
159
160 b.bundle().pipe(_fs2.default.createWriteStream(_path2.default.resolve(cwd, cf.dest))).on('close', () => {
161 console.log('browserify', 'buildEnd', cf.dest);
162 });
163 }
164 });
165});
166
167_commander2.default.command('stylus').option('-w, --watch', 'Watch mode').description("Build stylus").action(function () {
168 if (!config.$stylus) return exit("No stylus configuration found.");
169
170 let entry = config.$stylus.entry;
171 let dest = config.$stylus.dest;
172
173 if (!entry || !dest) return exit("Malformed stylus config.");
174
175 let params = ['-u', require.resolve('nib'), '-u', require.resolve('jeet'), '-u', require.resolve('rupture')];
176
177 if (this.watch) params.push('-w');else params.push('--compress');
178
179 if (config.$stylus.paths) {
180 config.$stylus.paths.forEach(p => params.push('-I', _path2.default.resolve(cwd, p)));
181 }
182
183 params.push('--out', _path2.default.resolve(cwd, dest));
184 params.push(_path2.default.resolve(cwd, entry));
185
186 console.log('stylus', this.watch ? 'watch' : 'buildStart', dest);
187 _child_process2.default.spawnSync(stylus, params, {
188 stdio: ['ignore', 'ignore', 'inherit'],
189 cwd: __dirname
190 });
191 console.log('stylus', 'buildEnd', dest);
192});
193
194_commander2.default.command('babel').option('-w, --watch', 'Watch mode').description("Build babel").action(function () {
195 if (!config.$babel) return exit("No babel configuration found.");
196
197 let source = config.$babel.source;
198 let dest = config.$babel.dest;
199
200 if (!source || !dest) return exit("Babel requires source and dest.");
201
202 let params = [...babelParams];
203
204 params.push('--presets', [require.resolve('babel-preset-es2015-node5'), require.resolve('babel-preset-stage-3')].join(','));
205
206 if (this.watch) params.push('--watch');
207
208 params.push('--out-dir', _path2.default.resolve(cwd, dest), _path2.default.resolve(cwd, source));
209
210 console.log('babel', this.watch ? 'watch' : 'buildStart', source, dest);
211 _child_process2.default.spawnSync(babel, params, {
212 stdio: ['ignore', 'ignore', 'inherit'],
213 cwd: __dirname
214 });
215 console.log('babel', 'buildEnd', source, dest);
216});
217
218_commander2.default.command('json [args...]').description("JSON helper").action(function (args) {
219 _child_process2.default.spawnSync(json, args, { stdio: 'inherit' });
220});
221
222_commander2.default.command('concurrent [args...]').description("Run multiple shell commands at once").action(function (args) {
223 _child_process2.default.spawnSync(concurrently, ['-k', ...args], { stdio: 'inherit' });
224});
225
226_commander2.default.command('nodemon -- [args...]').description("Nodemon proxy").action(function (args) {
227 _child_process2.default.spawnSync(nodemon, args, { stdio: 'inherit' });
228});
229
230_commander2.default.command('run <script> [args...]').description("Run a maket script").action(function (script, args) {
231 let scripts = {};
232 let graph = (0, _tsort2.default)();
233
234 addScript(script);
235
236 function addScript(name) {
237 if (scripts[name]) return;
238
239 let scr = getScript(name);
240 scripts[name] = scr;
241
242 graph.add(name);
243
244 if (scr.after.length) {
245 scr.after.forEach(addScript);
246 graph.add([...scr.after, name]);
247 }
248
249 if (scr.before.length) {
250 scr.before.forEach(addScript);
251 graph.add([name, ...scr.before]);
252 }
253 }
254
255 let queue;
256
257 try {
258 queue = graph.sort().map(s => scripts[s]);
259 } catch (e) {
260 return exit("There is a cycle in script order.");
261 }
262
263 let env = {
264 MAKET: __filename
265 };
266
267 let fconf = (0, _flatten2.default)(config);
268
269 Object.keys(fconf).forEach(k => {
270 if (k.indexOf('$') >= 0) return;
271
272 env[`MAKET_${ k.toUpperCase().replace(/[\.\[\]]/g, '_') }`] = fconf[k];
273 });
274
275 let proc = _child_process2.default.spawn('/usr/bin/env', ['bash'], {
276 stdio: ['pipe', 'inherit', 'inherit'],
277 env: Object.assign({}, process.env, env)
278 });
279
280 proc.stdin.write('set -e\n');
281
282 queue.forEach(q => {
283 q.commands.forEach(c => {
284 proc.stdin.write(c + '\n');
285 });
286 });
287
288 proc.stdin.end();
289});
290
291_commander2.default.command('tpl <filename>').description("Render template").action(function (filename) {
292 let tpl;
293
294 try {
295 tpl = _fs2.default.readFileSync(_path2.default.resolve(cwd, filename), { encoding: 'utf8' });
296 } catch (e) {
297 return exit("Unable to read file: " + filename);
298 }
299
300 process.stdout.write((0, _lodash2.default)(tpl)(Object.assign({ encode: encode }, config)));
301
302 function encode(value) {
303 return JSON.stringify(value).replace(/^"/, "").replace(/"$/, "");
304 }
305});
306
307_commander2.default.command('config [path]').description("Get maket configuration").action(function (cpath) {
308 let res = config;
309
310 if (cpath) res = res[cpath];
311
312 if (typeof res === 'string') return process.stdout.write(res);
313
314 process.stdout.write(JSON.stringify(res, null, " "));
315});
316
317_commander2.default.parse(process.argv);
318
319function exit(message) {
320 let code = arguments.length <= 1 || arguments[1] === undefined ? -1 : arguments[1];
321
322 console.error(message);
323 process.exit(code);
324}
325
326function getScript(name) {
327 let scripts = config.$scripts || {};
328 let scr = scripts[name];
329
330 if (!scr) return exit("Script not found.");
331
332 if (typeof scr === 'string') scr = { commands: [scr] };else if (Array.isArray(scr)) scr = { commands: scr };
333
334 scr.after = scr.run_after || [];
335 scr.before = scr.run_before || [];
336 scr.commands = scr.commands || scr.cmd || [];
337
338 if (!Array.isArray(scr.after)) scr.after = [scr.after];
339 if (!Array.isArray(scr.before)) scr.before = [scr.before];
340 if (!Array.isArray(scr.commands)) scr.commands = [scr.commands];
341
342 return scr;
343}
\No newline at end of file