script.js 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200
  1. 'use strict';
  2. Object.defineProperty(exports, "__esModule", {
  3. value: true
  4. });
  5. exports.requirer = requirer;
  6. exports.hasAccess = hasAccess;
  7. exports.getConfig = getConfig;
  8. exports.load = load;
  9. exports.describe = describe;
  10. exports.call = call;
  11. exports.main = main;
  12. var _path = require('path');
  13. var _path2 = _interopRequireDefault(_path);
  14. var _fs = require('fs');
  15. var _fs2 = _interopRequireDefault(_fs);
  16. var _chalk = require('chalk');
  17. var _chalk2 = _interopRequireDefault(_chalk);
  18. var _lodash = require('lodash.padend');
  19. var _lodash2 = _interopRequireDefault(_lodash);
  20. var _microcli = require('microcli');
  21. var _microcli2 = _interopRequireDefault(_microcli);
  22. var _omelette = require('omelette');
  23. var _omelette2 = _interopRequireDefault(_omelette);
  24. var _common = require('./common');
  25. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
  26. const DEFAULT_RUNFILE_PATH = './runfile.js';
  27. function requirer(filePath) {
  28. return require(_path2.default.resolve(filePath));
  29. }
  30. function hasAccess(filePath) {
  31. return _fs2.default.accessSync(_path2.default.resolve(filePath));
  32. }
  33. function getConfig(filePath) {
  34. let config;
  35. try {
  36. config = requirer(filePath).runjs || {};
  37. } catch (error) {
  38. config = {};
  39. }
  40. return config;
  41. }
  42. function load(config, logger, requirer, access) {
  43. const runfilePath = config['runfile'] || DEFAULT_RUNFILE_PATH;
  44. // Load requires if given in config
  45. if (Array.isArray(config['requires'])) {
  46. config['requires'].forEach(modulePath => {
  47. logger.log(_chalk2.default.gray(`Requiring ${modulePath}...`));
  48. requirer(modulePath);
  49. });
  50. }
  51. // Process runfile
  52. logger.log(_chalk2.default.gray(`Processing ${runfilePath}...`));
  53. try {
  54. access(runfilePath);
  55. } catch (error) {
  56. throw new _common.RunJSError(`No ${runfilePath} defined in ${process.cwd()}`);
  57. }
  58. const runfile = requirer(runfilePath);
  59. if (runfile.default) {
  60. return runfile.default;
  61. }
  62. return runfile;
  63. }
  64. function describe(obj, logger, namespace) {
  65. if (!namespace) {
  66. logger.log(_chalk2.default.yellow('Available tasks:'));
  67. }
  68. Object.keys(obj).forEach(key => {
  69. const value = obj[key];
  70. const nextNamespace = namespace ? `${namespace}:${key}` : key;
  71. const help = value.help;
  72. if (typeof value === 'function') {
  73. // Add task name
  74. const funcParams = help && help.params;
  75. let logArgs = [_chalk2.default.bold(nextNamespace)];
  76. // Add task params
  77. if (Array.isArray(funcParams) && funcParams.length) {
  78. logArgs[0] += ` [${funcParams.join(' ')}]`;
  79. }
  80. // Add description
  81. if (help && (help.description || typeof help === 'string')) {
  82. const description = help.description || help;
  83. logArgs[0] = (0, _lodash2.default)(logArgs[0], 40); // format
  84. logArgs.push('-', description.split('\n')[0]);
  85. }
  86. // Log
  87. logger.log(...logArgs);
  88. } else if (typeof value === 'object') {
  89. describe(value, logger, nextNamespace);
  90. }
  91. });
  92. if (!namespace) {
  93. logger.log('\n' + _chalk2.default.blue('Type "run [taskname] --help" to get more info if available.'));
  94. }
  95. }
  96. function tasks(obj, namespace) {
  97. let list = [];
  98. Object.keys(obj).forEach(key => {
  99. const value = obj[key];
  100. const nextNamespace = namespace ? `${namespace}:${key}` : key;
  101. if (typeof value === 'function') {
  102. list.push(nextNamespace);
  103. } else if (typeof value === 'object') {
  104. list = list.concat(tasks(value, nextNamespace));
  105. }
  106. });
  107. return list;
  108. }
  109. function call(obj, args, logger, subtaskName) {
  110. const taskName = subtaskName || args[2];
  111. if (typeof obj[taskName] === 'function') {
  112. const cli = (0, _microcli2.default)(args.slice(1), obj[taskName].help, null, logger);
  113. cli((options, ...params) => {
  114. obj[taskName].apply({ options }, params);
  115. });
  116. return obj[taskName];
  117. }
  118. let namespaces = taskName.split(':');
  119. const rootNamespace = namespaces.shift();
  120. const nextSubtaskName = namespaces.join(':');
  121. if (obj[rootNamespace]) {
  122. const calledTask = call(obj[rootNamespace], args, logger, nextSubtaskName);
  123. if (calledTask) {
  124. return calledTask;
  125. }
  126. }
  127. if (!subtaskName) {
  128. throw new _common.RunJSError(`Task ${taskName} not found`);
  129. }
  130. }
  131. function autocomplete(config) {
  132. const logger = new _common.SilentLogger();
  133. const completion = (0, _omelette2.default)('run <task>');
  134. completion.on('task', ({ reply }) => {
  135. const runfile = load(config, logger, requirer, hasAccess);
  136. reply(tasks(runfile));
  137. });
  138. completion.init();
  139. }
  140. function main() {
  141. try {
  142. const config = getConfig('./package.json');
  143. autocomplete(config);
  144. const runfile = load(config, _common.logger, requirer, hasAccess);
  145. const ARGV = process.argv.slice();
  146. if (ARGV.length > 2) {
  147. call(runfile, ARGV, _common.logger);
  148. } else {
  149. describe(runfile, _common.logger);
  150. }
  151. } catch (error) {
  152. if (error instanceof _common.RunJSError || error instanceof _microcli.CLIError) {
  153. _common.logger.error(error.message);
  154. process.exit(1);
  155. } else {
  156. _common.logger.log(error);
  157. process.exit(1);
  158. }
  159. }
  160. }