UNPKG

4.1 kBPlain TextView Raw
1#!/usr/bin/env node
2
3var cli = require('cli').enable('glob', 'version'),
4 dust = require('../lib/server.js'),
5 fs = cli.native.fs,
6 path = cli.native.path,
7 eol = cli.native.os.EOL;
8
9cli.setApp('dustc', require('../package.json').version);
10
11cli.setUsage(cli.app + ' [options] [path1 [path2 path3...]]\n\n' +
12 ' Compile all .dust files in a directory tree:\n ' +
13 cli.app + ' --output=compiled.js tmpl/**/*.dust\n' +
14 ' Compile some files to AMD modules:\n ' +
15 cli.app + ' -as one.dust two.dust');
16
17cli.parse({
18 name: ['n', 'name to use when rendering the template (multiple inputs automatically use their paths)', 'string'],
19 output: ['o', 'concatenate all output to this file', 'path'],
20 split: ['s', 'create one output file per input file instead of concatenating them to --output' ],
21 pwd: [false, 'generate template names starting from this directory', 'string'],
22 whitespace: ['w', 'preserve whitespace in templates', ],
23 amd: ['a', 'register templates as AMD modules' ]
24});
25
26/**
27 * Handle input piped via stdin
28 */
29if (!cli.argc) {
30 if (!cli.options.name) {
31 cli.getUsage();
32 }
33 cli.info('No files to compile. Write template code and use ^D to exit');
34 cli.withStdin(function(data) {
35 output(compile(data, cli.options.name), cli.options.output);
36 });
37}
38
39/**
40 * Handle a list of paths passed as args
41 * Each path gets globbed in case the OS doesn't support it
42 */
43cli.args
44.map(function(arg) { return cli.glob.sync(arg); })
45.reduce(function(a, b) { return a.concat(b); }, [])
46.forEach(function(inputFile, index, filesToProcess) {
47 read(inputFile, function(err, data) {
48 if (err) {
49 cli.info('Couldn\'t open ' + inputFile + ' for reading');
50 return;
51 }
52
53 var outputFile = cli.options.output,
54 templateName = path.join(path.dirname(inputFile),
55 path.basename(inputFile, path.extname(inputFile))),
56 compiledData;
57
58 // Use the template's path as the output path if split-files is turned on
59 if (cli.options.split) {
60 outputFile = templateName + '.js';
61 }
62
63 // Allow override of template name as long as there's only one template
64 if (cli.options.name && filesToProcess.length === 1) {
65 templateName = cli.options.name;
66 }
67
68 // Optionally strip leading directories from a template name
69 // For example, if --pwd=tmpl, `tmpl/foo/a` becomes `foo/a`
70 if (cli.options.pwd) {
71 templateName = path.relative(cli.options.pwd, templateName);
72 }
73
74 compiledData = compile(data, templateName);
75 output(compiledData, outputFile);
76 });
77});
78
79/*** helper functions ***/
80
81function read(filename, cb) {
82 var data = '',
83 file = fs.createReadStream(filename);
84
85 file.on('error', cb);
86 file.on('data', function(chunk) {
87 data += chunk;
88 });
89 file.on('end', function() {
90 cb(null, data);
91 });
92}
93
94function compile(data, name) {
95 var compiled;
96
97 dust.config.whitespace = (cli.options.whitespace === true);
98 dust.config.amd = (cli.options.amd === true);
99
100 try {
101 compiled = dust.compile(data, name);
102 } catch(e) {
103 return cli.fatal('[' + name + '] ' + e);
104 }
105 return compiled;
106}
107
108var streams = {};
109function output(data, file) {
110 var output_stream;
111 try {
112 if (file) {
113 output_stream = streams[file] ? streams[file]
114 : streams[file] = cli.native.fs.createWriteStream(file);
115 } else {
116 output_stream = process.stdout;
117 }
118 output_stream.write(data + eol);
119 } catch (e) {
120 cli.fatal('Could not write to output stream');
121 }
122}