script.js 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. "use strict";
  2. var __importDefault = (this && this.__importDefault) || function (mod) {
  3. return (mod && mod.__esModule) ? mod : { "default": mod };
  4. };
  5. Object.defineProperty(exports, "__esModule", { value: true });
  6. // @flow
  7. const chalk_1 = __importDefault(require("chalk"));
  8. const fs_1 = __importDefault(require("fs"));
  9. const lodash_padend_1 = __importDefault(require("lodash.padend"));
  10. const microcli_1 = __importDefault(require("microcli"));
  11. // @ts-ignore
  12. const omelette_1 = __importDefault(require("omelette"));
  13. const path_1 = __importDefault(require("path"));
  14. const CLIError = microcli_1.default.CliError;
  15. const common_1 = require("./common");
  16. const DEFAULT_RUNFILE_PATH = "./runfile.js";
  17. function requirer(filePath) {
  18. return require(path_1.default.resolve(filePath));
  19. }
  20. exports.requirer = requirer;
  21. function hasAccess(filePath) {
  22. return fs_1.default.accessSync(path_1.default.resolve(filePath));
  23. }
  24. exports.hasAccess = hasAccess;
  25. function getConfig(filePath) {
  26. let config;
  27. try {
  28. config = requirer(filePath).runjs || {};
  29. }
  30. catch (error) {
  31. config = {};
  32. }
  33. return config;
  34. }
  35. exports.getConfig = getConfig;
  36. function load(config, logger, requirer, access) {
  37. const runfilePath = config.runfile || DEFAULT_RUNFILE_PATH;
  38. // Load requires if given in config
  39. if (Array.isArray(config.requires)) {
  40. config.requires.forEach(modulePath => {
  41. logger.log(chalk_1.default.gray(`Requiring ${modulePath}...`));
  42. requirer(modulePath);
  43. });
  44. }
  45. // Process runfile
  46. logger.log(chalk_1.default.gray(`Processing ${runfilePath}...`));
  47. try {
  48. access(runfilePath);
  49. }
  50. catch (error) {
  51. throw new common_1.RunJSError(`No ${runfilePath} defined in ${process.cwd()}`);
  52. }
  53. const runfile = requirer(runfilePath);
  54. if (runfile.default) {
  55. return runfile.default;
  56. }
  57. return runfile;
  58. }
  59. exports.load = load;
  60. function describe(obj, logger, namespace) {
  61. if (!namespace) {
  62. logger.log(chalk_1.default.yellow("Available tasks:"));
  63. }
  64. Object.keys(obj).forEach(key => {
  65. const value = obj[key];
  66. const nextNamespace = namespace ? `${namespace}:${key}` : key;
  67. const help = value.help;
  68. if (typeof value === "function") {
  69. // Add task name
  70. const funcParams = help && help.params;
  71. const logArgs = [chalk_1.default.bold(nextNamespace)];
  72. // Add task params
  73. if (Array.isArray(funcParams) && funcParams.length) {
  74. logArgs[0] += ` [${funcParams.join(" ")}]`;
  75. }
  76. // Add description
  77. if (help && (help.description || typeof help === "string")) {
  78. const description = help.description || help;
  79. logArgs[0] = lodash_padend_1.default(logArgs[0], 40); // format
  80. logArgs.push("-", description.split("\n")[0]);
  81. }
  82. // Log
  83. logger.log(...logArgs);
  84. }
  85. else if (typeof value === "object") {
  86. describe(value, logger, nextNamespace);
  87. }
  88. });
  89. if (!namespace) {
  90. logger.log("\n" +
  91. chalk_1.default.blue('Type "run [taskname] --help" to get more info if available.'));
  92. }
  93. }
  94. exports.describe = describe;
  95. function tasks(obj, namespace) {
  96. let list = [];
  97. Object.keys(obj).forEach(key => {
  98. const value = obj[key];
  99. const nextNamespace = namespace ? `${namespace}:${key}` : key;
  100. if (typeof value === "function") {
  101. list.push(nextNamespace);
  102. }
  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 = microcli_1.default(args.slice(1), obj[taskName].help, undefined, logger);
  113. cli((options, ...params) => {
  114. obj[taskName].apply({ options }, params);
  115. });
  116. return obj[taskName];
  117. }
  118. const 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_1.RunJSError(`Task ${taskName} not found`);
  129. }
  130. }
  131. exports.call = call;
  132. function autocomplete(config) {
  133. const logger = new common_1.SilentLogger();
  134. const completion = omelette_1.default("run <task>");
  135. completion.on("task", ({ reply }) => {
  136. const runfile = load(config, logger, requirer, hasAccess);
  137. reply(tasks(runfile));
  138. });
  139. completion.init();
  140. }
  141. function main() {
  142. try {
  143. const config = getConfig("./package.json");
  144. autocomplete(config);
  145. const runfile = load(config, common_1.logger, requirer, hasAccess);
  146. const ARGV = process.argv.slice();
  147. if (ARGV.length > 2) {
  148. call(runfile, ARGV, common_1.logger);
  149. }
  150. else {
  151. describe(runfile, common_1.logger);
  152. }
  153. }
  154. catch (error) {
  155. if (error instanceof common_1.RunJSError || error instanceof CLIError) {
  156. common_1.logger.error(error.message);
  157. process.exit(1);
  158. }
  159. else {
  160. common_1.logger.log(error);
  161. process.exit(1);
  162. }
  163. }
  164. }
  165. exports.main = main;
  166. //# sourceMappingURL=script.js.map