You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

преди 10 години
преди 10 години
преди 10 години
преди 10 години
преди 10 години
преди 10 години
преди 11 години
преди 11 години
преди 10 години
преди 10 години
преди 10 години
преди 10 години
преди 10 години
преди 10 години
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. #!/usr/bin/env node
  2. var fs = require('fs'),
  3. path = require('path');
  4. var Mustache = require('..');
  5. var pkg = require('../package');
  6. var partials = {};
  7. var partialsPaths = [];
  8. var partialArgIndex = -1;
  9. while ((partialArgIndex = process.argv.indexOf('-p')) > -1) {
  10. partialsPaths.push(process.argv.splice(partialArgIndex, 2)[1]);
  11. }
  12. var viewArg = process.argv[2];
  13. var templateArg = process.argv[3];
  14. var outputArg = process.argv[4];
  15. if (hasVersionArg()) {
  16. return console.log(pkg.version);
  17. }
  18. if (!templateArg || !viewArg) {
  19. console.error('Syntax: mustache <view> <template> [output]');
  20. process.exit(1);
  21. }
  22. run(readPartials, readView, readTemplate, render, toStdout);
  23. /**
  24. * Runs a list of functions as a waterfall.
  25. * Functions are runned one after the other in order, providing each
  26. * function the returned values of all the previously invoked functions.
  27. * Each function is expected to exit the process if an error occurs.
  28. */
  29. function run (/*args*/) {
  30. var values = [];
  31. var fns = Array.prototype.slice.call(arguments);
  32. function invokeNextFn (val) {
  33. values.unshift(val);
  34. if (fns.length === 0) return;
  35. invoke(fns.shift());
  36. }
  37. function invoke (fn) {
  38. fn.apply(null, [invokeNextFn].concat(values));
  39. }
  40. invoke(fns.shift());
  41. }
  42. function readView (cb) {
  43. var view;
  44. if (isJsFile(viewArg)) {
  45. view = require(path.join(process.cwd(),viewArg));
  46. cb(view);
  47. } else {
  48. if (isStdin(viewArg)) {
  49. view = process.openStdin();
  50. } else {
  51. view = fs.createReadStream(viewArg);
  52. }
  53. streamToStr(view, function onDone (str) {
  54. cb(parseView(str));
  55. });
  56. }
  57. }
  58. function parseView (str) {
  59. try {
  60. return JSON.parse(str);
  61. } catch (ex) {
  62. console.error(
  63. 'Shooot, could not parse view as JSON.\n' +
  64. 'Tips: functions are not valid JSON and keys / values must be surround with double quotes.\n\n' +
  65. ex.stack);
  66. process.exit(1);
  67. }
  68. }
  69. function readPartials (cb) {
  70. if (!partialsPaths.length) return cb();
  71. var partialPath = partialsPaths.pop();
  72. var partial = fs.createReadStream(partialPath);
  73. streamToStr(partial, function onDone (str) {
  74. partials[getPartialName(partialPath)] = str;
  75. readPartials(cb);
  76. });
  77. }
  78. function readTemplate (cb) {
  79. var template = fs.createReadStream(templateArg);
  80. streamToStr(template, cb);
  81. }
  82. function render (cb, templateStr, jsonView) {
  83. cb(Mustache.render(templateStr, jsonView, partials));
  84. }
  85. function toStdout (cb, str) {
  86. if (outputArg) {
  87. cb(fs.writeFileSync(outputArg, str));
  88. } else {
  89. cb(process.stdout.write(str));
  90. }
  91. }
  92. function streamToStr (stream, cb) {
  93. var data = '';
  94. stream.on('data', function onData (chunk) {
  95. data += chunk;
  96. }).once('end', function onEnd () {
  97. cb(data.toString());
  98. }).on('error', function onError (err) {
  99. if (wasNotFound(err)) {
  100. console.error('Could not find file:', err.path);
  101. } else {
  102. console.error('Error while reading file:', err.message);
  103. }
  104. process.exit(1);
  105. });
  106. }
  107. function isStdin (view) {
  108. return view === '-';
  109. }
  110. function isJsFile (view) {
  111. var extension = path.extname(view);
  112. return extension === '.js' || extension === '.cjs';
  113. }
  114. function wasNotFound (err) {
  115. return err.code && err.code === 'ENOENT';
  116. }
  117. function hasVersionArg () {
  118. return ['--version', '-v'].some(function matchInArgs (opt) {
  119. return process.argv.indexOf(opt) > -1;
  120. });
  121. }
  122. function getPartialName (filename) {
  123. return path.basename(filename, '.mustache');
  124. }